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
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 Control.Monad.IO.Class (MonadIO, liftIO)
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'.
readJournal'' :: Text -> IO Journal
readJournal'' = readJournal' <=< inputToHandle
readJournal'' = textToHandle >=> readJournal'
-- | An easy version of 'readJournalFile' which assumes default options, and fails
-- in the IO monad.

View File

@ -48,7 +48,7 @@ module Hledger.Utils.IO (
readFilePortably,
hGetContentsPortably,
-- hereFileRelative,
inputToHandle,
textToHandle,
-- * Command line parsing
progArgs,
@ -153,7 +153,7 @@ import System.Exit (exitFailure)
import System.FilePath (isRelative, (</>))
import "Glob" System.FilePath.Glob (glob)
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 System.IO.Unsafe (unsafePerformIO)
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
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.
-- Its encoding will be UTF-8BOM.
inputToHandle :: T.Text -> IO Handle
inputToHandle t = do
-- | Create a handle from which the given text can be read. Its encoding will be UTF-8.
textToHandle :: T.Text -> IO Handle
textToHandle t = do
(r, w) <- createPipe
hSetEncoding r utf8_bom
hSetEncoding w utf8_bom
hSetEncoding r utf8
hSetEncoding w utf8
-- 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
return r

View File

@ -38,6 +38,7 @@ import Hledger.Cli.Utils (writeFileWithBackupIfChanged)
import Hledger.Web.Settings (manualurl)
import qualified Hledger.Query as Query
journalFile404 :: FilePath -> Journal -> HandlerFor m (FilePath, Text)
journalFile404 f j =
case find ((== f) . fst) (jfiles j) of
@ -66,7 +67,7 @@ writeJournalTextIfValidAndChanged f t = mapExceptT liftIO $ do
-- formatdirectivep, #1194) writeFileWithBackupIfChanged require them.
-- XXX klunky. Any equivalent of "hSetNewlineMode h universalNewlineMode" for form posts ?
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
return ()

View File

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