packages feed

document-build-0.1.0.0: src/Document/Build/Pandoc.hs

{-# OPTIONS_GHC -Wall #-}

-- | Commands that convert documents with @pandoc@.
module Document.Build.Pandoc (
  pandoc,
  xelatex,
  markdownToPdf,
  markdownToHtml,
  markdownToDocx,
  markdownToOdt,
) where

import Control.Monad.Trans.Class (lift)
import Document.Build.Build (Command, createParentDirectory, expectOutput, process, requireInput)
import Document.Build.Error (CommandLine (..), ReviewBuildError)
import System.FilePath (takeBaseName, (<.>), (</>))

{- | Convert the file being operated on with @pandoc@ and its options, writing
to a file path, and return the file path. Unless the options say otherwise,
pandoc chooses the output format from the extension of the file path.

@since 0.1.0.0
-}
pandoc :: (ReviewBuildError e) => [String] -> FilePath -> Command e FilePath
pandoc opts o =
  do
    i <- requireInput
    let c = CommandLine "pandoc" (opts <> [i, "-o", o])
    lift (createParentDirectory o *> process c *> expectOutput c o)

{- | The option to produce PDF with XeLaTeX, which supports Unicode and system
fonts, such as with @-M mainfont=...@.

@since 0.1.0.0
-}
xelatex :: [String]
xelatex =
  ["--pdf-engine=xelatex"]

markdownTo :: (ReviewBuildError e) => [String] -> String -> [String] -> FilePath -> Command e FilePath
markdownTo base ext opts d =
  requireInput >>= \i -> pandoc (base <> opts) (d </> takeBaseName i <.> ext)

{- | Convert the markdown file being operated on to PDF, with 'xelatex' and
pandoc options, into a directory.

@since 0.1.0.0
-}
markdownToPdf :: (ReviewBuildError e) => [String] -> FilePath -> Command e FilePath
markdownToPdf =
  markdownTo xelatex "pdf"
{-# INLINE markdownToPdf #-}

{- | Convert the markdown file being operated on to HTML, with pandoc
options, into a directory.

@since 0.1.0.0
-}
markdownToHtml :: (ReviewBuildError e) => [String] -> FilePath -> Command e FilePath
markdownToHtml =
  markdownTo [] "html"
{-# INLINE markdownToHtml #-}

{- | Convert the markdown file being operated on to Word, with pandoc options,
into a directory.

@since 0.1.0.0
-}
markdownToDocx :: (ReviewBuildError e) => [String] -> FilePath -> Command e FilePath
markdownToDocx =
  markdownTo [] "docx"
{-# INLINE markdownToDocx #-}

{- | Convert the markdown file being operated on to OpenDocument text, with
pandoc options, into a directory.

@since 0.1.0.0
-}
markdownToOdt :: (ReviewBuildError e) => [String] -> FilePath -> Command e FilePath
markdownToOdt =
  markdownTo [] "odt"
{-# INLINE markdownToOdt #-}