dev:Hledger.Utils.IO: inputToHandle -> textToHandle; set utf8 not utf8_bom

This commit is contained in:
Simon Michael 2025-09-26 01:04:03 -10:00
parent 5db4ee7420
commit a2af816611
4 changed files with 12 additions and 12 deletions

View File

@ -132,7 +132,7 @@ module Hledger.Read (
--- ** imports --- ** imports
import qualified Control.Exception as C import qualified Control.Exception as C
import Control.Monad (unless, when, forM, (<=<)) import Control.Monad (unless, when, forM, (>=>))
import "mtl" Control.Monad.Except (ExceptT(..), runExceptT, liftEither) import "mtl" Control.Monad.Except (ExceptT(..), runExceptT, liftEither)
import Control.Monad.IO.Class (MonadIO, liftIO) import Control.Monad.IO.Class (MonadIO, liftIO)
import Data.Default (def) import Data.Default (def)
@ -346,7 +346,7 @@ readJournal' = orDieTrying . readJournal definputopts Nothing
-- | An even easier version of readJournal' which takes a 'Text' instead of a 'Handle'. -- | An even easier version of readJournal' which takes a 'Text' instead of a 'Handle'.
readJournal'' :: Text -> IO Journal readJournal'' :: Text -> IO Journal
readJournal'' = readJournal' <=< inputToHandle readJournal'' = textToHandle >=> readJournal'
-- | An easy version of 'readJournalFile' which assumes default options, and fails -- | An easy version of 'readJournalFile' which assumes default options, and fails
-- in the IO monad. -- in the IO monad.

View File

@ -48,7 +48,7 @@ module Hledger.Utils.IO (
readFilePortably, readFilePortably,
hGetContentsPortably, hGetContentsPortably,
-- hereFileRelative, -- hereFileRelative,
inputToHandle, textToHandle,
-- * Command line parsing -- * Command line parsing
progArgs, progArgs,
@ -153,7 +153,7 @@ import System.Exit (exitFailure)
import System.FilePath (isRelative, (</>)) import System.FilePath (isRelative, (</>))
import "Glob" System.FilePath.Glob (glob) import "Glob" System.FilePath.Glob (glob)
import System.Info (os) import System.Info (os)
import System.IO (Handle, IOMode (..), hClose, hGetEncoding, hIsTerminalDevice, hPutStr, hPutStrLn, hSetNewlineMode, hSetEncoding, openFile, stderr, stdin, stdout, universalNewlineMode, utf8_bom) import System.IO (Handle, IOMode (..), hClose, hGetEncoding, hIsTerminalDevice, hPutStr, hPutStrLn, hSetNewlineMode, hSetEncoding, openFile, stderr, stdin, stdout, universalNewlineMode, utf8_bom, utf8)
import qualified System.IO.Encoding as Enc import qualified System.IO.Encoding as Enc
import System.IO.Unsafe (unsafePerformIO) import System.IO.Unsafe (unsafePerformIO)
import System.Process (CreateProcess(..), StdStream(CreatePipe), createPipe, shell, waitForProcess, withCreateProcess) import System.Process (CreateProcess(..), StdStream(CreatePipe), createPipe, shell, waitForProcess, withCreateProcess)
@ -465,13 +465,12 @@ hGetContentsPortably (Just e) h =
-- convert newlines manually, because Enc.hGetContents uses bytestring's hGetContents -- convert newlines manually, because Enc.hGetContents uses bytestring's hGetContents
T.replace "\r\n" "\n" . T.pack <$> let ?enc = e in Enc.hGetContents h T.replace "\r\n" "\n" . T.pack <$> let ?enc = e in Enc.hGetContents h
-- | Create a handle from which the given text can be read. -- | Create a handle from which the given text can be read. Its encoding will be UTF-8.
-- Its encoding will be UTF-8BOM. textToHandle :: T.Text -> IO Handle
inputToHandle :: T.Text -> IO Handle textToHandle t = do
inputToHandle t = do
(r, w) <- createPipe (r, w) <- createPipe
hSetEncoding r utf8_bom hSetEncoding r utf8
hSetEncoding w utf8_bom hSetEncoding w utf8
-- use a separate thread so that we don't deadlock if we can't write all of the text at once -- use a separate thread so that we don't deadlock if we can't write all of the text at once
forkIO $ T.hPutStr w t >> hClose w forkIO $ T.hPutStr w t >> hClose w
return r return r

View File

@ -38,6 +38,7 @@ import Hledger.Cli.Utils (writeFileWithBackupIfChanged)
import Hledger.Web.Settings (manualurl) import Hledger.Web.Settings (manualurl)
import qualified Hledger.Query as Query import qualified Hledger.Query as Query
journalFile404 :: FilePath -> Journal -> HandlerFor m (FilePath, Text) journalFile404 :: FilePath -> Journal -> HandlerFor m (FilePath, Text)
journalFile404 f j = journalFile404 f j =
case find ((== f) . fst) (jfiles j) of case find ((== f) . fst) (jfiles j) of
@ -66,7 +67,7 @@ writeJournalTextIfValidAndChanged f t = mapExceptT liftIO $ do
-- formatdirectivep, #1194) writeFileWithBackupIfChanged require them. -- formatdirectivep, #1194) writeFileWithBackupIfChanged require them.
-- XXX klunky. Any equivalent of "hSetNewlineMode h universalNewlineMode" for form posts ? -- XXX klunky. Any equivalent of "hSetNewlineMode h universalNewlineMode" for form posts ?
let t' = T.replace "\r" "" t let t' = T.replace "\r" "" t
j <- readJournal definputopts (Just f) =<< liftIO (inputToHandle t') j <- readJournal definputopts (Just f) =<< liftIO (textToHandle t')
_ <- liftIO $ j `seq` writeFileWithBackupIfChanged f t' -- Only write backup if the journal didn't error _ <- liftIO $ j `seq` writeFileWithBackupIfChanged f t' -- Only write backup if the journal didn't error
return () return ()

View File

@ -269,5 +269,5 @@ withJournalCached defaultJournalOverride cliopts cmd = do
dbg1IO "readStdin reading and caching stdin" "-" dbg1IO "readStdin reading and caching stdin" "-"
stdinContent <- readFileOrStdinPortably "-" stdinContent <- readFileOrStdinPortably "-"
return (Just stdinContent, stdinContent) return (Just stdinContent, stdinContent)
hndl <- liftIO $ inputToHandle stdinContent hndl <- liftIO $ textToHandle stdinContent
readJournal iopts Nothing hndl readJournal iopts Nothing hndl