publish 2.2.2 → 2.2.3
raw patch · 7 files changed
+115/−106 lines, 7 filesdep ~core-programdep ~core-text
Dependency ranges changed: core-program, core-text
Files
- publish.cabal +16/−11
- src/FormatDocument.hs +4/−4
- src/FormatMain.hs +1/−1
- src/ParseBookfile.hs +34/−32
- src/RenderDocument.hs +14/−13
- src/RenderMain.hs +1/−1
- src/Utilities.hs +45/−44
publish.cabal view
@@ -4,16 +4,21 @@ -- -- see: https://github.com/sol/hpack ----- hash: a4cc52f72afe6fb6f773a9c3b2fc7579f2146eb3a1367a22926f2c3519f6f897+-- hash: bdc6778c7664e65e93e74b73702eef01ef70d5f056eaeca667c9ff73a6e095bd name: publish-version: 2.2.2+version: 2.2.3 synopsis: Publishing tools for papers, books, and presentations-description: Tools for rendering markdown-centric documents into PDFs.+description: Tools for rendering markdown-centric documents into PDFs. There are two+ programs: .+ [/render/]for generating PDFs from Markdown and LaTeX input; and+ .+ [/format/]for word-wrapping and nicely formatting Markdown files.+ . A description of this package, a list of features, and some background to its design is contained in the- <https://github.com/aesiniath/publish/blob/master/README.md README>+ <https://github.com/aesiniath/publish/blob/main/README.md README> on GitHub. category: Text stability: experimental@@ -25,7 +30,7 @@ license: MIT license-file: LICENSE tested-with:- GHC == 8.10+ GHC == 8.10.7 build-type: Simple source-repository head@@ -45,8 +50,8 @@ , bytestring , chronologique , core-data- , core-program >=0.2.7- , core-text >=0.3.0+ , core-program >=0.2.12+ , core-text >=0.3.4 , deepseq , directory , filepath@@ -78,8 +83,8 @@ , bytestring , chronologique , core-data- , core-program >=0.2.7- , core-text >=0.3.0+ , core-program >=0.2.12+ , core-text >=0.3.4 , deepseq , directory , filepath@@ -113,8 +118,8 @@ , bytestring , chronologique , core-data- , core-program >=0.2.7- , core-text >=0.3.0+ , core-program >=0.2.12+ , core-text >=0.3.4 , deepseq , directory , filepath
src/FormatDocument.hs view
@@ -28,16 +28,16 @@ program :: Program None () program = do- event "Identify document fragment"+ info "Identify document fragment" file <- getFragmentName - event "Load to Pandoc internal representation"+ info "Load to Pandoc internal representation" parsed <- loadFragment file - event "Write to Markdown format"+ info "Write to Markdown format" writeResult file parsed - event "Complete"+ info "Complete" getFragmentName :: Program None FilePath getFragmentName = do
src/FormatMain.hs view
@@ -23,7 +23,7 @@ configure version None- ( simple+ ( simpleConfig [ Option "inplace" (Just 'i')
src/ParseBookfile.hs view
@@ -15,48 +15,50 @@ parseMagicLine :: Parser Int parseMagicLine = do- void (char '%') <?> "first line to begin with % character"- void spaceChar <?> "a space character"- void (string "publish")- void spaceChar <?> "a space character"- void (char 'v') <?> "the character v and then a number"- v <- L.decimal <?> "the bookfile schema version number"- unless (v == __VERSION__) (fail ("currently recognized bookfile schema version is v" ++ show __VERSION__))- void newline- return v+ void (char '%') <?> "first line to begin with % character"+ void spaceChar <?> "a space character"+ void (string "publish")+ void spaceChar <?> "a space character"+ void (char 'v') <?> "the character v and then a number"+ v <- L.decimal <?> "the bookfile schema version number"+ unless (v == __VERSION__) (fail ("currently recognized bookfile schema version is v" ++ show __VERSION__))+ void newline+ return v parseBeginLine :: Parser ()-parseBeginLine = try $ label "begin marker" $ do- void (string "% begin")- void newline+parseBeginLine = try $+ label "begin marker" $ do+ void (string "% begin")+ void newline parseFileLine :: Parser FilePath parseFileLine = do- notFollowedBy (char '%')- file <- takeWhile1P (Just "line containing a filename") (/= '\n')- return file+ notFollowedBy (char '%')+ file <- takeWhile1P (Just "line containing a filename") (/= '\n')+ return file parseEndLine :: Parser ()-parseEndLine = try $ label "end marker" $ do- void (string "% end")- void newline+parseEndLine = try $+ label "end marker" $ do+ void (string "% end")+ void newline parseBlank :: Parser () parseBlank = do- void (hidden (many newline))+ void (hidden (many newline)) parseBookfile :: Parser Bookfile parseBookfile = do- version <- parseMagicLine- preambles <- many (parseBlank *> parseFileLine <* parseBlank)- parseBeginLine- fragments <- many (parseBlank *> parseFileLine <* parseBlank)- parseEndLine- trailers <- many (parseBlank *> parseFileLine <* parseBlank)- return- Bookfile- { versionFrom = version,- preamblesFrom = preambles,- fragmentsFrom = fragments,- trailersFrom = trailers- }+ version <- parseMagicLine+ preambles <- many (parseBlank *> parseFileLine <* parseBlank)+ parseBeginLine+ fragments <- many (parseBlank *> parseFileLine <* parseBlank)+ parseEndLine+ trailers <- many (parseBlank *> parseFileLine <* parseBlank)+ return+ Bookfile+ { versionFrom = version+ , preamblesFrom = preambles+ , fragmentsFrom = fragments+ , trailersFrom = trailers+ }
src/RenderDocument.hs view
@@ -61,7 +61,7 @@ params <- getCommandLine (mode, copy) <- extractMode params - event "Identify .book file"+ info "Identify .book file" bookfile <- extractBookFile params case mode of@@ -74,10 +74,10 @@ renderDocument :: (Mode, Copy) -> FilePath -> Program Env [FilePath] renderDocument (mode, copy) file = do- event "Read .book file"+ info "Read .book file" book <- processBookFile file - event "Setup temporary directory"+ info "Setup temporary directory" setupTargetFile file setupPreambleFile validatePreamble book@@ -86,21 +86,21 @@ let fragments = fragmentsFrom book let trailers = trailersFrom book - event "Convert preamble fragments and begin marker to LaTeX"+ info "Convert preamble fragments and begin marker to LaTeX" mapM_ processFragment preambles setupBeginningFile - event "Convert document fragments to LaTeX"+ info "Convert document fragments to LaTeX" mapM_ processFragment fragments - event "Convert end marker and trailing fragments to LaTeX"+ info "Convert end marker and trailing fragments to LaTeX" setupEndingFile mapM_ processFragment trailers - event "Write intermediate LaTeX file"+ info "Write intermediate LaTeX file" produceResult - event "Render document to PDF"+ info "Render document to PDF" catch ( do renderPDF@@ -313,6 +313,7 @@ case probe of True -> return True False -> do+ warn "Fragment not found" write ("warning: Fragment \"" <> intoRope fragment <> "\" not found, skipping") return False @@ -432,7 +433,7 @@ case exit of ExitFailure _ -> do- event "Image processing failed"+ info "Image processing failed" debug "stderr" (intoRope err) debug "stdout" (intoRope out) write ("error: Unable to convert " <> intoRope file <> " from SVG to PDF")@@ -512,7 +513,7 @@ (exit, out, err) <- execProcess latexmk case exit of ExitFailure _ -> do- event "Render failed"+ info "Render failed" debug "stderr" (intoRope err) debug "stdout" (intoRope out) write (parseOutputForError tmpdir out)@@ -528,11 +529,11 @@ changed <- isNewer result final case changed of True -> do- event "Copy resultant PDF to starting directory"+ info "Copy resultant PDF to starting directory" debugS "result" result debugS "final" final liftIO $ do copyFileWithMetadata result final- event "Complete"+ info "Complete" False -> do- event "Result unchanged"+ info "Result unchanged"
src/RenderMain.hs view
@@ -25,7 +25,7 @@ configure version env- ( simple+ ( simpleConfig [ Option "builtin-preamble" (Just 'p')
src/Utilities.hs view
@@ -2,13 +2,12 @@ {-# LANGUAGE OverloadedStrings #-} {-# LANGUAGE ScopedTypeVariables #-} -module Utilities- ( ensureDirectory,+module Utilities (+ ensureDirectory, execProcess, ifNewer, isNewer,- )-where+) where import Chrono.Compat (convertToUTC) import Control.Monad (when)@@ -16,12 +15,12 @@ import Core.System import Core.Text import qualified Data.List as List (intercalate)-import System.Directory- ( createDirectoryIfMissing,+import System.Directory (+ createDirectoryIfMissing, doesDirectoryExist, doesFileExist, getModificationTime,- )+ ) import System.Exit (ExitCode (..)) import System.FilePath.Posix (takeDirectory) import System.Process.Typed (closed, proc, readProcess, setStdin)@@ -32,11 +31,11 @@ -} ensureDirectory :: FilePath -> Program t () ensureDirectory target =- let subdir = takeDirectory target- in liftIO $ do- probe <- doesDirectoryExist subdir- when (not probe) $ do- createDirectoryIfMissing True subdir+ let subdir = takeDirectory target+ in liftIO $ do+ probe <- doesDirectoryExist subdir+ when (not probe) $ do+ createDirectoryIfMissing True subdir {- Thin wrapper around **typed-process**'s `readProcess` so that the command@@ -49,43 +48,45 @@ execProcess :: [String] -> Program t (ExitCode, Rope, Rope) execProcess [] = error "No command provided" execProcess (cmd : args) =- let task = proc cmd args- task' = setStdin closed task- command = List.intercalate " " (cmd : args)- in do- debugS "command" command+ let task = proc cmd args+ task' = setStdin closed task+ command = List.intercalate " " (cmd : args)+ in do+ debugS "command" command - (exit, out, err) <- liftIO $ do- readProcess task'+ (exit, out, err) <- liftIO $ do+ readProcess task' - return (exit, intoRope out, intoRope err)+ return (exit, intoRope out, intoRope err) --- |--- If the source file is newer than the target file, then run an action. For--- example, if you want to install a file but only do so if the file has been--- rebuilt, then you could do this:------ @--- copyFileIfNewer :: 'FilePath' -> 'FilePath' -> 'Program' τ ()--- copyFileIfNewer source target = do--- 'ifNewer' source target $ do--- 'liftIO' ('copyFileWithMetadata' source target)--- @------ This is basically a build system in a box, although the usual caveats--- about the brittleness of timestamps apply.------ TODO this could potentially move to the **unbeliever** library+{- |+ If the source file is newer than the target file, then run an action. For+ example, if you want to install a file but only do so if the file has been+ rebuilt, then you could do this:++ @+ copyFileIfNewer :: 'FilePath' -> 'FilePath' -> 'Program' τ ()+ copyFileIfNewer source target = do+ 'ifNewer' source target $ do+ 'liftIO' ('copyFileWithMetadata' source target)+ @++ This is basically a build system in a box, although the usual caveats+ about the brittleness of timestamps apply.++ TODO this could potentially move to the **unbeliever** library+-} ifNewer :: FilePath -> FilePath -> Program t () -> Program t () ifNewer source target program = do- changed <- isNewer source target- when changed $ do- program+ changed <- isNewer source target+ when changed $ do+ program isNewer :: FilePath -> FilePath -> Program t Bool isNewer source target = liftIO $ do- time1 <- getModificationTime source- time2 <- doesFileExist target >>= \case- True -> getModificationTime target- False -> return (convertToUTC 0) -- the epoch- return (time1 > time2)+ time1 <- getModificationTime source+ time2 <-+ doesFileExist target >>= \case+ True -> getModificationTime target+ False -> return (convertToUTC 0) -- the epoch+ return (time1 > time2)