{-# LANGUAGE TupleSections       #-}
{-# LANGUAGE LambdaCase          #-}
{-# LANGUAGE OverloadedStrings   #-}
{-# LANGUAGE CPP                 #-}
{-# LANGUAGE ScopedTypeVariables #-}
{- |
   Module      : Text.Pandoc.App
   Copyright   : Copyright (C) 2006-2022 John MacFarlane
   License     : GNU GPL, version 2 or above

   Maintainer  : John MacFarlane <jgm@berkeley@edu>
   Stability   : alpha
   Portability : portable

Does a pandoc conversion based on command-line options.
-}
module Text.Pandoc.App (
            convertWithOpts
          , Opt(..)
          , LineEnding(..)
          , Filter(..)
          , defaultOpts
          , parseOptions
          , parseOptionsFromArgs
          , options
          , applyFilters
          ) where
import qualified Control.Exception as E
import Control.Monad ( (>=>), when, forM_ )
import Control.Monad.Trans ( MonadIO(..) )
import Control.Monad.Except (throwError, catchError)
import qualified Data.ByteString as BS
import qualified Data.ByteString.Char8 as B8
import qualified Data.ByteString.Lazy as BL
import Data.Char (toLower)
import Data.Maybe (fromMaybe, isJust, isNothing)
import qualified Data.Set as Set
import Data.Text (Text)
import qualified Data.Text as T
import qualified Data.Text.Lazy as TL
import qualified Data.Text.Lazy.Encoding as TE
import qualified Data.Text.Encoding as TSE
import qualified Data.Text.Encoding.Error as TE
import qualified Data.Text.Encoding.Error as TSE
import Network.URI (URI (..), parseURI)
import System.Directory (doesDirectoryExist)
import System.Exit (exitSuccess)
import System.FilePath ( takeBaseName, takeExtension)
import System.IO (nativeNewline, stdout)
import qualified System.IO as IO (Newline (..))
import Text.Pandoc
import Text.Pandoc.Builder (setMeta)
import Text.Pandoc.MediaBag (mediaItems)
import Text.Pandoc.MIME (getCharset, MimeType)
import Text.Pandoc.Image (svgToPng)
import Text.Pandoc.App.FormatHeuristics (formatFromFilePaths)
import Text.Pandoc.App.Opt (Opt (..), LineEnding (..), defaultOpts,
                            IpynbOutput (..))
import Text.Pandoc.App.CommandLineOptions (parseOptions, parseOptionsFromArgs,
                                           options)
import Text.Pandoc.App.OutputSettings (OutputSettings (..), optToOutputSettings)
import Text.Collate.Lang (Lang (..), parseLang)
import Text.Pandoc.Filter (Filter (JSONFilter, LuaFilter), Environment (..),
                           applyFilters)
import Text.Pandoc.PDF (makePDF)
import Text.Pandoc.SelfContained (makeSelfContained)
import Text.Pandoc.Shared (eastAsianLineBreakFilter, stripEmptyParagraphs,
         headerShift, isURI, tabFilter, uriPathToPath, filterIpynbOutput,
         defaultUserDataDir, tshow)
import Text.Pandoc.Writers.Shared (lookupMetaString)
import Text.Pandoc.Readers.Markdown (yamlToMeta)
import Text.Pandoc.Readers.Custom (readCustom)
import qualified Text.Pandoc.UTF8 as UTF8
#ifndef _WINDOWS
import System.Posix.IO (stdOutput)
import System.Posix.Terminal (queryTerminal)
#endif

convertWithOpts :: Opt -> IO ()
convertWithOpts :: Opt -> IO ()
convertWithOpts opts :: Opt
opts = do
  Maybe FilePath
datadir <- case Opt -> Maybe FilePath
optDataDir Opt
opts of
                  Nothing   -> do
                    FilePath
d <- IO FilePath
defaultUserDataDir
                    Bool
exists <- FilePath -> IO Bool
doesDirectoryExist FilePath
d
                    Maybe FilePath -> IO (Maybe FilePath)
forall (m :: * -> *) a. Monad m => a -> m a
return (Maybe FilePath -> IO (Maybe FilePath))
-> Maybe FilePath -> IO (Maybe FilePath)
forall a b. (a -> b) -> a -> b
$ if Bool
exists
                                then FilePath -> Maybe FilePath
forall a. a -> Maybe a
Just FilePath
d
                                else Maybe FilePath
forall a. Maybe a
Nothing
                  Just _    -> Maybe FilePath -> IO (Maybe FilePath)
forall (m :: * -> *) a. Monad m => a -> m a
return (Maybe FilePath -> IO (Maybe FilePath))
-> Maybe FilePath -> IO (Maybe FilePath)
forall a b. (a -> b) -> a -> b
$ Opt -> Maybe FilePath
optDataDir Opt
opts

  let outputFile :: FilePath
outputFile = FilePath -> Maybe FilePath -> FilePath
forall a. a -> Maybe a -> a
fromMaybe "-" (Opt -> Maybe FilePath
optOutputFile Opt
opts)
  let filters :: [Filter]
filters = Opt -> [Filter]
optFilters Opt
opts
  let verbosity :: Verbosity
verbosity = Opt -> Verbosity
optVerbosity Opt
opts

  Bool -> IO () -> IO ()
forall (f :: * -> *). Applicative f => Bool -> f () -> f ()
when (Opt -> Bool
optDumpArgs Opt
opts) (IO () -> IO ()) -> IO () -> IO ()
forall a b. (a -> b) -> a -> b
$
    do Handle -> Text -> IO ()
UTF8.hPutStrLn Handle
stdout (FilePath -> Text
T.pack FilePath
outputFile)
       (FilePath -> IO ()) -> [FilePath] -> IO ()
forall (t :: * -> *) (m :: * -> *) a b.
(Foldable t, Monad m) =>
(a -> m b) -> t a -> m ()
mapM_ (Handle -> Text -> IO ()
UTF8.hPutStrLn Handle
stdout (Text -> IO ()) -> (FilePath -> Text) -> FilePath -> IO ()
forall b c a. (b -> c) -> (a -> b) -> a -> c
. FilePath -> Text
T.pack)
             ([FilePath] -> Maybe [FilePath] -> [FilePath]
forall a. a -> Maybe a -> a
fromMaybe ["-"] (Maybe [FilePath] -> [FilePath]) -> Maybe [FilePath] -> [FilePath]
forall a b. (a -> b) -> a -> b
$ Opt -> Maybe [FilePath]
optInputFiles Opt
opts)
       IO ()
forall a. IO a
exitSuccess

  let sources :: [FilePath]
sources = case Opt -> Maybe [FilePath]
optInputFiles Opt
opts of
                     Just xs :: [FilePath]
xs | Bool -> Bool
not (Opt -> Bool
optIgnoreArgs Opt
opts) -> [FilePath]
xs
                     _ -> ["-"]
#ifdef _WINDOWS
  let istty = True
#else
  Bool
istty <- IO Bool -> IO Bool
forall (m :: * -> *) a. MonadIO m => IO a -> m a
liftIO (IO Bool -> IO Bool) -> IO Bool -> IO Bool
forall a b. (a -> b) -> a -> b
$ Fd -> IO Bool
queryTerminal Fd
stdOutput
#endif

  Either PandocError (PandocOutput, [LogMessage])
res <- PandocIO (PandocOutput, [LogMessage])
-> IO (Either PandocError (PandocOutput, [LogMessage]))
forall a. PandocIO a -> IO (Either PandocError a)
runIO (PandocIO (PandocOutput, [LogMessage])
 -> IO (Either PandocError (PandocOutput, [LogMessage])))
-> PandocIO (PandocOutput, [LogMessage])
-> IO (Either PandocError (PandocOutput, [LogMessage]))
forall a b. (a -> b) -> a -> b
$ do

    Bool -> PandocIO ()
forall (m :: * -> *). PandocMonad m => Bool -> m ()
setTrace (Opt -> Bool
optTrace Opt
opts)
    Verbosity -> PandocIO ()
forall (m :: * -> *). PandocMonad m => Verbosity -> m ()
setVerbosity Verbosity
verbosity
    Maybe FilePath -> PandocIO ()
forall (m :: * -> *). PandocMonad m => Maybe FilePath -> m ()
setUserDataDir Maybe FilePath
datadir
    [FilePath] -> PandocIO ()
forall (m :: * -> *). PandocMonad m => [FilePath] -> m ()
setResourcePath (Opt -> [FilePath]
optResourcePath Opt
opts)

    [FilePath] -> PandocIO ()
forall (m :: * -> *). PandocMonad m => [FilePath] -> m ()
setInputFiles ([FilePath] -> Maybe [FilePath] -> [FilePath]
forall a. a -> Maybe a -> a
fromMaybe ["-"] (Opt -> Maybe [FilePath]
optInputFiles Opt
opts))
    Maybe FilePath -> PandocIO ()
forall (m :: * -> *). PandocMonad m => Maybe FilePath -> m ()
setOutputFile (Opt -> Maybe FilePath
optOutputFile Opt
opts)

    -- assign reader and writer based on options and filenames
    Text
readerName <- case Opt -> Maybe Text
optFrom Opt
opts of
                       Just f :: Text
f  -> Text -> PandocIO Text
forall (m :: * -> *) a. Monad m => a -> m a
return Text
f
                       Nothing -> case [FilePath] -> Maybe Text
formatFromFilePaths [FilePath]
sources of
                           Just f' :: Text
f' -> Text -> PandocIO Text
forall (m :: * -> *) a. Monad m => a -> m a
return Text
f'
                           Nothing | [FilePath]
sources [FilePath] -> [FilePath] -> Bool
forall a. Eq a => a -> a -> Bool
== ["-"] -> Text -> PandocIO Text
forall (m :: * -> *) a. Monad m => a -> m a
return "markdown"
                                   | (FilePath -> Bool) -> [FilePath] -> Bool
forall (t :: * -> *) a. Foldable t => (a -> Bool) -> t a -> Bool
any (Text -> Bool
isURI (Text -> Bool) -> (FilePath -> Text) -> FilePath -> Bool
forall b c a. (b -> c) -> (a -> b) -> a -> c
. FilePath -> Text
T.pack) [FilePath]
sources -> Text -> PandocIO Text
forall (m :: * -> *) a. Monad m => a -> m a
return "html"
                                   | Bool
otherwise -> do
                             LogMessage -> PandocIO ()
forall (m :: * -> *). PandocMonad m => LogMessage -> m ()
report (LogMessage -> PandocIO ()) -> LogMessage -> PandocIO ()
forall a b. (a -> b) -> a -> b
$ [Text] -> Text -> LogMessage
CouldNotDeduceFormat
                                 ((FilePath -> Text) -> [FilePath] -> [Text]
forall a b. (a -> b) -> [a] -> [b]
map (FilePath -> Text
T.pack (FilePath -> Text) -> (FilePath -> FilePath) -> FilePath -> Text
forall b c a. (b -> c) -> (a -> b) -> a -> c
. FilePath -> FilePath
takeExtension) [FilePath]
sources) "markdown"
                             Text -> PandocIO Text
forall (m :: * -> *) a. Monad m => a -> m a
return "markdown"

    let readerNameBase :: Text
readerNameBase = (Char -> Bool) -> Text -> Text
T.takeWhile (\c :: Char
c -> Char
c Char -> Char -> Bool
forall a. Eq a => a -> a -> Bool
/= '+' Bool -> Bool -> Bool
&& Char
c Char -> Char -> Bool
forall a. Eq a => a -> a -> Bool
/= '-') Text
readerName
    let pdfOutput :: Bool
pdfOutput = (Char -> Char) -> FilePath -> FilePath
forall a b. (a -> b) -> [a] -> [b]
map Char -> Char
toLower (FilePath -> FilePath
takeExtension FilePath
outputFile) FilePath -> FilePath -> Bool
forall a. Eq a => a -> a -> Bool
== ".pdf"

    Bool -> PandocIO () -> PandocIO ()
forall (f :: * -> *). Applicative f => Bool -> f () -> f ()
when (Bool
pdfOutput Bool -> Bool -> Bool
&& Text
readerNameBase Text -> Text -> Bool
forall a. Eq a => a -> a -> Bool
== "latex") (PandocIO () -> PandocIO ()) -> PandocIO () -> PandocIO ()
forall a b. (a -> b) -> a -> b
$
      case Opt -> Maybe [FilePath]
optInputFiles Opt
opts of
        Just (inputFile :: FilePath
inputFile:_) -> LogMessage -> PandocIO ()
forall (m :: * -> *). PandocMonad m => LogMessage -> m ()
report (LogMessage -> PandocIO ()) -> LogMessage -> PandocIO ()
forall a b. (a -> b) -> a -> b
$ Text -> LogMessage
UnusualConversion (Text -> LogMessage) -> Text -> LogMessage
forall a b. (a -> b) -> a -> b
$ FilePath -> Text
T.pack (FilePath -> Text) -> FilePath -> Text
forall a b. (a -> b) -> a -> b
$
          "to convert a .tex file to PDF, you get better results by using pdflatex "
            FilePath -> FilePath -> FilePath
forall a. Semigroup a => a -> a -> a
<> "(or lualatex or xelatex) directly, try `pdflatex " FilePath -> FilePath -> FilePath
forall a. Semigroup a => a -> a -> a
<> FilePath
inputFile
            FilePath -> FilePath -> FilePath
forall a. Semigroup a => a -> a -> a
<> "` instead of `pandoc " FilePath -> FilePath -> FilePath
forall a. Semigroup a => a -> a -> a
<> FilePath
inputFile FilePath -> FilePath -> FilePath
forall a. Semigroup a => a -> a -> a
<> " -o " FilePath -> FilePath -> FilePath
forall a. Semigroup a => a -> a -> a
<> FilePath
outputFile FilePath -> FilePath -> FilePath
forall a. Semigroup a => a -> a -> a
<> "`."
        _ -> () -> PandocIO ()
forall (m :: * -> *) a. Monad m => a -> m a
return ()


    let makeSandboxed :: Reader PandocPure -> Reader m
makeSandboxed pureReader :: Reader PandocPure
pureReader =
          let files :: [FilePath]
files = ([FilePath] -> [FilePath])
-> (FilePath -> [FilePath] -> [FilePath])
-> Maybe FilePath
-> [FilePath]
-> [FilePath]
forall b a. b -> (a -> b) -> Maybe a -> b
maybe [FilePath] -> [FilePath]
forall a. a -> a
id (:) (Opt -> Maybe FilePath
optReferenceDoc Opt
opts) ([FilePath] -> [FilePath])
-> ([FilePath] -> [FilePath]) -> [FilePath] -> [FilePath]
forall b c a. (b -> c) -> (a -> b) -> a -> c
.
                      ([FilePath] -> [FilePath])
-> (FilePath -> [FilePath] -> [FilePath])
-> Maybe FilePath
-> [FilePath]
-> [FilePath]
forall b a. b -> (a -> b) -> Maybe a -> b
maybe [FilePath] -> [FilePath]
forall a. a -> a
id (:) (Opt -> Maybe FilePath
optEpubMetadata Opt
opts) ([FilePath] -> [FilePath])
-> ([FilePath] -> [FilePath]) -> [FilePath] -> [FilePath]
forall b c a. (b -> c) -> (a -> b) -> a -> c
.
                      ([FilePath] -> [FilePath])
-> (FilePath -> [FilePath] -> [FilePath])
-> Maybe FilePath
-> [FilePath]
-> [FilePath]
forall b a. b -> (a -> b) -> Maybe a -> b
maybe [FilePath] -> [FilePath]
forall a. a -> a
id (:) (Opt -> Maybe FilePath
optEpubCoverImage Opt
opts) ([FilePath] -> [FilePath])
-> ([FilePath] -> [FilePath]) -> [FilePath] -> [FilePath]
forall b c a. (b -> c) -> (a -> b) -> a -> c
.
                      ([FilePath] -> [FilePath])
-> (FilePath -> [FilePath] -> [FilePath])
-> Maybe FilePath
-> [FilePath]
-> [FilePath]
forall b a. b -> (a -> b) -> Maybe a -> b
maybe [FilePath] -> [FilePath]
forall a. a -> a
id (:) (Opt -> Maybe FilePath
optCSL Opt
opts) ([FilePath] -> [FilePath])
-> ([FilePath] -> [FilePath]) -> [FilePath] -> [FilePath]
forall b c a. (b -> c) -> (a -> b) -> a -> c
.
                      ([FilePath] -> [FilePath])
-> (FilePath -> [FilePath] -> [FilePath])
-> Maybe FilePath
-> [FilePath]
-> [FilePath]
forall b a. b -> (a -> b) -> Maybe a -> b
maybe [FilePath] -> [FilePath]
forall a. a -> a
id (:) (Opt -> Maybe FilePath
optCitationAbbreviations Opt
opts) ([FilePath] -> [FilePath]) -> [FilePath] -> [FilePath]
forall a b. (a -> b) -> a -> b
$
                      Opt -> [FilePath]
optEpubFonts Opt
opts [FilePath] -> [FilePath] -> [FilePath]
forall a. [a] -> [a] -> [a]
++
                      Opt -> [FilePath]
optBibliography Opt
opts
           in  case Reader PandocPure
pureReader of
                 TextReader r :: forall a. ToSources a => ReaderOptions -> a -> PandocPure Pandoc
r -> (forall a. ToSources a => ReaderOptions -> a -> m Pandoc)
-> Reader m
forall (m :: * -> *).
(forall a. ToSources a => ReaderOptions -> a -> m Pandoc)
-> Reader m
TextReader ((forall a. ToSources a => ReaderOptions -> a -> m Pandoc)
 -> Reader m)
-> (forall a. ToSources a => ReaderOptions -> a -> m Pandoc)
-> Reader m
forall a b. (a -> b) -> a -> b
$ \o :: ReaderOptions
o t :: a
t -> [FilePath] -> PandocPure Pandoc -> m Pandoc
forall (m :: * -> *) a.
(PandocMonad m, MonadIO m) =>
[FilePath] -> PandocPure a -> m a
sandbox [FilePath]
files (ReaderOptions -> a -> PandocPure Pandoc
forall a. ToSources a => ReaderOptions -> a -> PandocPure Pandoc
r ReaderOptions
o a
t)
                 ByteStringReader r :: ReaderOptions -> ByteString -> PandocPure Pandoc
r
                            -> (ReaderOptions -> ByteString -> m Pandoc) -> Reader m
forall (m :: * -> *).
(ReaderOptions -> ByteString -> m Pandoc) -> Reader m
ByteStringReader ((ReaderOptions -> ByteString -> m Pandoc) -> Reader m)
-> (ReaderOptions -> ByteString -> m Pandoc) -> Reader m
forall a b. (a -> b) -> a -> b
$ \o :: ReaderOptions
o t :: ByteString
t -> [FilePath] -> PandocPure Pandoc -> m Pandoc
forall (m :: * -> *) a.
(PandocMonad m, MonadIO m) =>
[FilePath] -> PandocPure a -> m a
sandbox [FilePath]
files (ReaderOptions -> ByteString -> PandocPure Pandoc
r ReaderOptions
o ByteString
t)

    (reader :: Reader PandocIO
reader, readerExts :: Extensions
readerExts) <-
      if ".lua" Text -> Text -> Bool
`T.isSuffixOf` Text
readerName
         then (Reader PandocIO, Extensions)
-> PandocIO (Reader PandocIO, Extensions)
forall (m :: * -> *) a. Monad m => a -> m a
return ((forall a. ToSources a => ReaderOptions -> a -> PandocIO Pandoc)
-> Reader PandocIO
forall (m :: * -> *).
(forall a. ToSources a => ReaderOptions -> a -> m Pandoc)
-> Reader m
TextReader (FilePath -> ReaderOptions -> a -> PandocIO Pandoc
forall (m :: * -> *) s.
(PandocMonad m, MonadIO m, ToSources s) =>
FilePath -> ReaderOptions -> s -> m Pandoc
readCustom (Text -> FilePath
T.unpack Text
readerName)), Extensions
forall a. Monoid a => a
mempty)
         else if Opt -> Bool
optSandbox Opt
opts
                 then case PandocPure (Reader PandocPure, Extensions)
-> Either PandocError (Reader PandocPure, Extensions)
forall a. PandocPure a -> Either PandocError a
runPure (Text -> PandocPure (Reader PandocPure, Extensions)
forall (m :: * -> *).
PandocMonad m =>
Text -> m (Reader m, Extensions)
getReader Text
readerName) of
                        Left e :: PandocError
e -> PandocError -> PandocIO (Reader PandocIO, Extensions)
forall e (m :: * -> *) a. MonadError e m => e -> m a
throwError PandocError
e
                        Right (r :: Reader PandocPure
r, rexts :: Extensions
rexts) -> (Reader PandocIO, Extensions)
-> PandocIO (Reader PandocIO, Extensions)
forall (m :: * -> *) a. Monad m => a -> m a
return (Reader PandocPure -> Reader PandocIO
forall (m :: * -> *).
(PandocMonad m, MonadIO m) =>
Reader PandocPure -> Reader m
makeSandboxed Reader PandocPure
r, Extensions
rexts)
                 else Text -> PandocIO (Reader PandocIO, Extensions)
forall (m :: * -> *).
PandocMonad m =>
Text -> m (Reader m, Extensions)
getReader Text
readerName

    OutputSettings PandocIO
outputSettings <- Opt -> PandocIO (OutputSettings PandocIO)
forall (m :: * -> *).
(PandocMonad m, MonadIO m) =>
Opt -> m (OutputSettings m)
optToOutputSettings Opt
opts
    let format :: Text
format = OutputSettings PandocIO -> Text
forall (m :: * -> *). OutputSettings m -> Text
outputFormat OutputSettings PandocIO
outputSettings
    let writer :: Writer PandocIO
writer = OutputSettings PandocIO -> Writer PandocIO
forall (m :: * -> *). OutputSettings m -> Writer m
outputWriter OutputSettings PandocIO
outputSettings
    let writerName :: Text
writerName = OutputSettings PandocIO -> Text
forall (m :: * -> *). OutputSettings m -> Text
outputWriterName OutputSettings PandocIO
outputSettings
    let writerNameBase :: Text
writerNameBase = (Char -> Bool) -> Text -> Text
T.takeWhile (\c :: Char
c -> Char
c Char -> Char -> Bool
forall a. Eq a => a -> a -> Bool
/= '+' Bool -> Bool -> Bool
&& Char
c Char -> Char -> Bool
forall a. Eq a => a -> a -> Bool
/= '-') Text
writerName
    let writerOptions :: WriterOptions
writerOptions = OutputSettings PandocIO -> WriterOptions
forall (m :: * -> *). OutputSettings m -> WriterOptions
outputWriterOptions OutputSettings PandocIO
outputSettings

    let bibOutput :: Bool
bibOutput = Text
writerNameBase Text -> Text -> Bool
forall a. Eq a => a -> a -> Bool
== "bibtex" Bool -> Bool -> Bool
||
                    Text
writerNameBase Text -> Text -> Bool
forall a. Eq a => a -> a -> Bool
== "biblatex" Bool -> Bool -> Bool
||
                    Text
writerNameBase Text -> Text -> Bool
forall a. Eq a => a -> a -> Bool
== "csljson"

    let standalone :: Bool
standalone = Opt -> Bool
optStandalone Opt
opts Bool -> Bool -> Bool
||
                     Bool -> Bool
not (Text -> Bool
isTextFormat Text
format) Bool -> Bool -> Bool
||
                     Bool
pdfOutput Bool -> Bool -> Bool
||
                     Bool
bibOutput

    -- We don't want to send output to the terminal if the user
    -- does 'pandoc -t docx input.txt'; though we allow them to
    -- force this with '-o -'.  On posix systems, we detect
    -- when stdout is being piped and allow output to stdout
    -- in that case, but on Windows we can't.
    Bool -> PandocIO () -> PandocIO ()
forall (f :: * -> *). Applicative f => Bool -> f () -> f ()
when ((Bool
pdfOutput Bool -> Bool -> Bool
|| Bool -> Bool
not (Text -> Bool
isTextFormat Text
format)) Bool -> Bool -> Bool
&&
             Bool
istty Bool -> Bool -> Bool
&& Maybe FilePath -> Bool
forall a. Maybe a -> Bool
isNothing ( Opt -> Maybe FilePath
optOutputFile Opt
opts)) (PandocIO () -> PandocIO ()) -> PandocIO () -> PandocIO ()
forall a b. (a -> b) -> a -> b
$
      PandocError -> PandocIO ()
forall e (m :: * -> *) a. MonadError e m => e -> m a
throwError (PandocError -> PandocIO ()) -> PandocError -> PandocIO ()
forall a b. (a -> b) -> a -> b
$ Text -> PandocError
PandocAppError (Text -> PandocError) -> Text -> PandocError
forall a b. (a -> b) -> a -> b
$
              "Cannot write " Text -> Text -> Text
forall a. Semigroup a => a -> a -> a
<> Text
format Text -> Text -> Text
forall a. Semigroup a => a -> a -> a
<> " output to terminal.\n" Text -> Text -> Text
forall a. Semigroup a => a -> a -> a
<>
              "Specify an output file using the -o option, or " Text -> Text -> Text
forall a. Semigroup a => a -> a -> a
<>
              "use '-o -' to force output to stdout."


    Set Text
abbrevs <- [Text] -> Set Text
forall a. Ord a => [a] -> Set a
Set.fromList ([Text] -> Set Text)
-> (ByteString -> [Text]) -> ByteString -> Set Text
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (Text -> Bool) -> [Text] -> [Text]
forall a. (a -> Bool) -> [a] -> [a]
filter (Bool -> Bool
not (Bool -> Bool) -> (Text -> Bool) -> Text -> Bool
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Text -> Bool
T.null) ([Text] -> [Text])
-> (ByteString -> [Text]) -> ByteString -> [Text]
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Text -> [Text]
T.lines (Text -> [Text]) -> (ByteString -> Text) -> ByteString -> [Text]
forall b c a. (b -> c) -> (a -> b) -> a -> c
. ByteString -> Text
UTF8.toText (ByteString -> Set Text)
-> PandocIO ByteString -> PandocIO (Set Text)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$>
               case Opt -> Maybe FilePath
optAbbreviations Opt
opts of
                    Nothing -> FilePath -> PandocIO ByteString
forall (m :: * -> *). PandocMonad m => FilePath -> m ByteString
readDataFile "abbreviations"
                    Just f :: FilePath
f  -> FilePath -> PandocIO ByteString
forall (m :: * -> *). PandocMonad m => FilePath -> m ByteString
readFileStrict FilePath
f

    case Text -> Meta -> Text
lookupMetaString "lang" (Opt -> Meta
optMetadata Opt
opts) of
           ""      -> Lang -> PandocIO ()
forall (m :: * -> *). PandocMonad m => Lang -> m ()
setTranslations (Lang -> PandocIO ()) -> Lang -> PandocIO ()
forall a b. (a -> b) -> a -> b
$ Text
-> Maybe Text
-> Maybe Text
-> [Text]
-> [(Text, [(Text, Text)])]
-> [Text]
-> Lang
Lang "en" Maybe Text
forall a. Maybe a
Nothing (Text -> Maybe Text
forall a. a -> Maybe a
Just "US") [] [] []
           l :: Text
l       -> case Text -> Either FilePath Lang
parseLang Text
l of
                           Left _   -> LogMessage -> PandocIO ()
forall (m :: * -> *). PandocMonad m => LogMessage -> m ()
report (LogMessage -> PandocIO ()) -> LogMessage -> PandocIO ()
forall a b. (a -> b) -> a -> b
$ Text -> LogMessage
InvalidLang Text
l
                           Right l' :: Lang
l' -> Lang -> PandocIO ()
forall (m :: * -> *). PandocMonad m => Lang -> m ()
setTranslations Lang
l'

    let readerOpts :: ReaderOptions
readerOpts = ReaderOptions
forall a. Default a => a
def{
            readerStandalone :: Bool
readerStandalone = Bool
standalone
          , readerColumns :: Int
readerColumns = Opt -> Int
optColumns Opt
opts
          , readerTabStop :: Int
readerTabStop = Opt -> Int
optTabStop Opt
opts
          , readerIndentedCodeClasses :: [Text]
readerIndentedCodeClasses = Opt -> [Text]
optIndentedCodeClasses Opt
opts
          , readerDefaultImageExtension :: Text
readerDefaultImageExtension =
             Opt -> Text
optDefaultImageExtension Opt
opts
          , readerTrackChanges :: TrackChanges
readerTrackChanges = Opt -> TrackChanges
optTrackChanges Opt
opts
          , readerAbbreviations :: Set Text
readerAbbreviations = Set Text
abbrevs
          , readerExtensions :: Extensions
readerExtensions = Extensions
readerExts
          , readerStripComments :: Bool
readerStripComments = Opt -> Bool
optStripComments Opt
opts
          }

    Meta
metadataFromFile <-
      case Opt -> [FilePath]
optMetadataFiles Opt
opts of
        []    -> Meta -> PandocIO Meta
forall (m :: * -> *) a. Monad m => a -> m a
return Meta
forall a. Monoid a => a
mempty
        paths :: [FilePath]
paths -> [Meta] -> Meta
forall a. Monoid a => [a] -> a
mconcat ([Meta] -> Meta) -> PandocIO [Meta] -> PandocIO Meta
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$>
           (FilePath -> PandocIO Meta) -> [FilePath] -> PandocIO [Meta]
forall (t :: * -> *) (m :: * -> *) a b.
(Traversable t, Monad m) =>
(a -> m b) -> t a -> m (t b)
mapM (\path :: FilePath
path -> do ByteString
raw <- FilePath -> PandocIO ByteString
forall (m :: * -> *). PandocMonad m => FilePath -> m ByteString
readMetadataFile FilePath
path
                             ReaderOptions -> Maybe FilePath -> ByteString -> PandocIO Meta
forall (m :: * -> *).
PandocMonad m =>
ReaderOptions -> Maybe FilePath -> ByteString -> m Meta
yamlToMeta ReaderOptions
readerOpts (FilePath -> Maybe FilePath
forall a. a -> Maybe a
Just FilePath
path) ByteString
raw) [FilePath]
paths

    let transforms :: [Pandoc -> Pandoc]
transforms = (case Opt -> Int
optShiftHeadingLevelBy Opt
opts of
                          0             -> [Pandoc -> Pandoc] -> [Pandoc -> Pandoc]
forall a. a -> a
id
                          x :: Int
x             -> (Int -> Pandoc -> Pandoc
headerShift Int
x (Pandoc -> Pandoc) -> [Pandoc -> Pandoc] -> [Pandoc -> Pandoc]
forall a. a -> [a] -> [a]
:)) ([Pandoc -> Pandoc] -> [Pandoc -> Pandoc])
-> ([Pandoc -> Pandoc] -> [Pandoc -> Pandoc])
-> [Pandoc -> Pandoc]
-> [Pandoc -> Pandoc]
forall b c a. (b -> c) -> (a -> b) -> a -> c
.
                     (if Opt -> Bool
optStripEmptyParagraphs Opt
opts
                         then (Pandoc -> Pandoc
stripEmptyParagraphs (Pandoc -> Pandoc) -> [Pandoc -> Pandoc] -> [Pandoc -> Pandoc]
forall a. a -> [a] -> [a]
:)
                         else [Pandoc -> Pandoc] -> [Pandoc -> Pandoc]
forall a. a -> a
id) ([Pandoc -> Pandoc] -> [Pandoc -> Pandoc])
-> ([Pandoc -> Pandoc] -> [Pandoc -> Pandoc])
-> [Pandoc -> Pandoc]
-> [Pandoc -> Pandoc]
forall b c a. (b -> c) -> (a -> b) -> a -> c
.
                     (if Extension -> Extensions -> Bool
extensionEnabled Extension
Ext_east_asian_line_breaks
                            Extensions
readerExts Bool -> Bool -> Bool
&&
                         Bool -> Bool
not (Extension -> Extensions -> Bool
extensionEnabled Extension
Ext_east_asian_line_breaks
                              (WriterOptions -> Extensions
writerExtensions WriterOptions
writerOptions) Bool -> Bool -> Bool
&&
                              WriterOptions -> WrapOption
writerWrapText WriterOptions
writerOptions WrapOption -> WrapOption -> Bool
forall a. Eq a => a -> a -> Bool
== WrapOption
WrapPreserve)
                         then (Pandoc -> Pandoc
eastAsianLineBreakFilter (Pandoc -> Pandoc) -> [Pandoc -> Pandoc] -> [Pandoc -> Pandoc]
forall a. a -> [a] -> [a]
:)
                         else [Pandoc -> Pandoc] -> [Pandoc -> Pandoc]
forall a. a -> a
id) ([Pandoc -> Pandoc] -> [Pandoc -> Pandoc])
-> ([Pandoc -> Pandoc] -> [Pandoc -> Pandoc])
-> [Pandoc -> Pandoc]
-> [Pandoc -> Pandoc]
forall b c a. (b -> c) -> (a -> b) -> a -> c
.
                     (case Opt -> IpynbOutput
optIpynbOutput Opt
opts of
                       _ | Text
readerNameBase Text -> Text -> Bool
forall a. Eq a => a -> a -> Bool
/= "ipynb" -> [Pandoc -> Pandoc] -> [Pandoc -> Pandoc]
forall a. a -> a
id
                       IpynbOutputAll  -> [Pandoc -> Pandoc] -> [Pandoc -> Pandoc]
forall a. a -> a
id
                       IpynbOutputNone -> (Maybe Format -> Pandoc -> Pandoc
filterIpynbOutput Maybe Format
forall a. Maybe a
Nothing (Pandoc -> Pandoc) -> [Pandoc -> Pandoc] -> [Pandoc -> Pandoc]
forall a. a -> [a] -> [a]
:)
                       IpynbOutputBest -> (Maybe Format -> Pandoc -> Pandoc
filterIpynbOutput (Format -> Maybe Format
forall a. a -> Maybe a
Just (Format -> Maybe Format) -> Format -> Maybe Format
forall a b. (a -> b) -> a -> b
$
                                     if Text -> Bool
htmlFormat Text
format
                                        then Text -> Format
Format "html"
                                        else
                                          case Text
format of
                                            "latex"  -> Text -> Format
Format "latex"
                                            "beamer" -> Text -> Format
Format "latex"
                                            _        -> Text -> Format
Format Text
format) (Pandoc -> Pandoc) -> [Pandoc -> Pandoc] -> [Pandoc -> Pandoc]
forall a. a -> [a] -> [a]
:))
                     ([Pandoc -> Pandoc] -> [Pandoc -> Pandoc])
-> [Pandoc -> Pandoc] -> [Pandoc -> Pandoc]
forall a b. (a -> b) -> a -> b
$ []

    let convertTabs :: Text -> Text
convertTabs = Int -> Text -> Text
tabFilter (if Opt -> Bool
optPreserveTabs Opt
opts Bool -> Bool -> Bool
||
                                      Text
readerNameBase Text -> Text -> Bool
forall a. Eq a => a -> a -> Bool
== "t2t" Bool -> Bool -> Bool
||
                                      Text
readerNameBase Text -> Text -> Bool
forall a. Eq a => a -> a -> Bool
== "man"
                                    then 0
                                    else Opt -> Int
optTabStop Opt
opts)


    Bool -> PandocIO () -> PandocIO ()
forall (f :: * -> *). Applicative f => Bool -> f () -> f ()
when (Text
readerNameBase Text -> Text -> Bool
forall a. Eq a => a -> a -> Bool
== "markdown_github" Bool -> Bool -> Bool
||
          Text
writerNameBase Text -> Text -> Bool
forall a. Eq a => a -> a -> Bool
== "markdown_github") (PandocIO () -> PandocIO ()) -> PandocIO () -> PandocIO ()
forall a b. (a -> b) -> a -> b
$
      LogMessage -> PandocIO ()
forall (m :: * -> *). PandocMonad m => LogMessage -> m ()
report (LogMessage -> PandocIO ()) -> LogMessage -> PandocIO ()
forall a b. (a -> b) -> a -> b
$ Text -> Text -> LogMessage
Deprecated "markdown_github" "Use gfm instead."

    ((Text, Text) -> PandocIO ()) -> [(Text, Text)] -> PandocIO ()
forall (t :: * -> *) (m :: * -> *) a b.
(Foldable t, Monad m) =>
(a -> m b) -> t a -> m ()
mapM_ ((Text -> Text -> PandocIO ()) -> (Text, Text) -> PandocIO ()
forall a b c. (a -> b -> c) -> (a, b) -> c
uncurry Text -> Text -> PandocIO ()
forall (m :: * -> *). PandocMonad m => Text -> Text -> m ()
setRequestHeader) (Opt -> [(Text, Text)]
optRequestHeaders Opt
opts)

    Bool -> PandocIO ()
forall (m :: * -> *). PandocMonad m => Bool -> m ()
setNoCheckCertificate (Opt -> Bool
optNoCheckCertificate Opt
opts)

    let isPandocCiteproc :: Filter -> Bool
isPandocCiteproc (JSONFilter f :: FilePath
f) = FilePath -> FilePath
takeBaseName FilePath
f FilePath -> FilePath -> Bool
forall a. Eq a => a -> a -> Bool
== "pandoc-citeproc"
        isPandocCiteproc _              = Bool
False

    Bool -> PandocIO () -> PandocIO ()
forall (f :: * -> *). Applicative f => Bool -> f () -> f ()
when ((Filter -> Bool) -> [Filter] -> Bool
forall (t :: * -> *) a. Foldable t => (a -> Bool) -> t a -> Bool
any Filter -> Bool
isPandocCiteproc [Filter]
filters) (PandocIO () -> PandocIO ()) -> PandocIO () -> PandocIO ()
forall a b. (a -> b) -> a -> b
$
      LogMessage -> PandocIO ()
forall (m :: * -> *). PandocMonad m => LogMessage -> m ()
report (LogMessage -> PandocIO ()) -> LogMessage -> PandocIO ()
forall a b. (a -> b) -> a -> b
$ Text -> Text -> LogMessage
Deprecated "pandoc-citeproc filter"
               "Use --citeproc instead."

    let cslMetadata :: Meta
cslMetadata =
          (Meta -> Meta)
-> (FilePath -> Meta -> Meta) -> Maybe FilePath -> Meta -> Meta
forall b a. b -> (a -> b) -> Maybe a -> b
maybe Meta -> Meta
forall a. a -> a
id (Text -> FilePath -> Meta -> Meta
forall a b. (HasMeta a, ToMetaValue b) => Text -> b -> a -> a
setMeta "csl") (Opt -> Maybe FilePath
optCSL Opt
opts) (Meta -> Meta) -> (Meta -> Meta) -> Meta -> Meta
forall b c a. (b -> c) -> (a -> b) -> a -> c
.
          (case Opt -> [FilePath]
optBibliography Opt
opts of
             [] -> Meta -> Meta
forall a. a -> a
id
             xs :: [FilePath]
xs -> Text -> [FilePath] -> Meta -> Meta
forall a b. (HasMeta a, ToMetaValue b) => Text -> b -> a -> a
setMeta "bibliography" [FilePath]
xs) (Meta -> Meta) -> (Meta -> Meta) -> Meta -> Meta
forall b c a. (b -> c) -> (a -> b) -> a -> c
.
          (Meta -> Meta)
-> (FilePath -> Meta -> Meta) -> Maybe FilePath -> Meta -> Meta
forall b a. b -> (a -> b) -> Maybe a -> b
maybe Meta -> Meta
forall a. a -> a
id (Text -> FilePath -> Meta -> Meta
forall a b. (HasMeta a, ToMetaValue b) => Text -> b -> a -> a
setMeta "citation-abbreviations")
                         (Opt -> Maybe FilePath
optCitationAbbreviations Opt
opts) (Meta -> Meta) -> Meta -> Meta
forall a b. (a -> b) -> a -> b
$ Meta
forall a. Monoid a => a
mempty

    let filterEnv :: Environment
filterEnv = ReaderOptions -> WriterOptions -> Environment
Environment ReaderOptions
readerOpts WriterOptions
writerOptions

    [(FilePath, (ByteString, Maybe Text))]
inputs <- [FilePath] -> PandocIO [(FilePath, (ByteString, Maybe Text))]
forall (m :: * -> *).
(PandocMonad m, MonadIO m) =>
[FilePath] -> m [(FilePath, (ByteString, Maybe Text))]
readSources [FilePath]
sources

    Pandoc
doc <- (case Reader PandocIO
reader of
             TextReader r :: forall a. ToSources a => ReaderOptions -> a -> PandocIO Pandoc
r
               | Text
readerNameBase Text -> Text -> Bool
forall a. Eq a => a -> a -> Bool
== "json" ->
                   [Pandoc] -> Pandoc
forall a. Monoid a => [a] -> a
mconcat ([Pandoc] -> Pandoc) -> PandocIO [Pandoc] -> PandocIO Pandoc
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$>
                      ((FilePath, (ByteString, Maybe Text)) -> PandocIO Pandoc)
-> [(FilePath, (ByteString, Maybe Text))] -> PandocIO [Pandoc]
forall (t :: * -> *) (m :: * -> *) a b.
(Traversable t, Monad m) =>
(a -> m b) -> t a -> m (t b)
mapM ((Text -> Text)
-> (FilePath, (ByteString, Maybe Text))
-> PandocIO (FilePath, Text)
forall (m :: * -> *).
PandocMonad m =>
(Text -> Text)
-> (FilePath, (ByteString, Maybe Text)) -> m (FilePath, Text)
inputToText Text -> Text
convertTabs
                             ((FilePath, (ByteString, Maybe Text)) -> PandocIO (FilePath, Text))
-> ((FilePath, Text) -> PandocIO Pandoc)
-> (FilePath, (ByteString, Maybe Text))
-> PandocIO Pandoc
forall (m :: * -> *) a b c.
Monad m =>
(a -> m b) -> (b -> m c) -> a -> m c
>=> ReaderOptions -> [(FilePath, Text)] -> PandocIO Pandoc
forall a. ToSources a => ReaderOptions -> a -> PandocIO Pandoc
r ReaderOptions
readerOpts ([(FilePath, Text)] -> PandocIO Pandoc)
-> ((FilePath, Text) -> [(FilePath, Text)])
-> (FilePath, Text)
-> PandocIO Pandoc
forall b c a. (b -> c) -> (a -> b) -> a -> c
. ((FilePath, Text) -> [(FilePath, Text)] -> [(FilePath, Text)]
forall a. a -> [a] -> [a]
:[])) [(FilePath, (ByteString, Maybe Text))]
inputs
               | Opt -> Bool
optFileScope Opt
opts  ->
                   [Pandoc] -> Pandoc
forall a. Monoid a => [a] -> a
mconcat ([Pandoc] -> Pandoc) -> PandocIO [Pandoc] -> PandocIO Pandoc
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> ((FilePath, (ByteString, Maybe Text)) -> PandocIO Pandoc)
-> [(FilePath, (ByteString, Maybe Text))] -> PandocIO [Pandoc]
forall (t :: * -> *) (m :: * -> *) a b.
(Traversable t, Monad m) =>
(a -> m b) -> t a -> m (t b)
mapM
                      ((Text -> Text)
-> (FilePath, (ByteString, Maybe Text))
-> PandocIO (FilePath, Text)
forall (m :: * -> *).
PandocMonad m =>
(Text -> Text)
-> (FilePath, (ByteString, Maybe Text)) -> m (FilePath, Text)
inputToText Text -> Text
convertTabs
                             ((FilePath, (ByteString, Maybe Text)) -> PandocIO (FilePath, Text))
-> ((FilePath, Text) -> PandocIO Pandoc)
-> (FilePath, (ByteString, Maybe Text))
-> PandocIO Pandoc
forall (m :: * -> *) a b c.
Monad m =>
(a -> m b) -> (b -> m c) -> a -> m c
>=> ReaderOptions -> [(FilePath, Text)] -> PandocIO Pandoc
forall a. ToSources a => ReaderOptions -> a -> PandocIO Pandoc
r ReaderOptions
readerOpts ([(FilePath, Text)] -> PandocIO Pandoc)
-> ((FilePath, Text) -> [(FilePath, Text)])
-> (FilePath, Text)
-> PandocIO Pandoc
forall b c a. (b -> c) -> (a -> b) -> a -> c
. ((FilePath, Text) -> [(FilePath, Text)] -> [(FilePath, Text)]
forall a. a -> [a] -> [a]
:[]))
                      [(FilePath, (ByteString, Maybe Text))]
inputs
               | Bool
otherwise -> ((FilePath, (ByteString, Maybe Text)) -> PandocIO (FilePath, Text))
-> [(FilePath, (ByteString, Maybe Text))]
-> PandocIO [(FilePath, Text)]
forall (t :: * -> *) (m :: * -> *) a b.
(Traversable t, Monad m) =>
(a -> m b) -> t a -> m (t b)
mapM ((Text -> Text)
-> (FilePath, (ByteString, Maybe Text))
-> PandocIO (FilePath, Text)
forall (m :: * -> *).
PandocMonad m =>
(Text -> Text)
-> (FilePath, (ByteString, Maybe Text)) -> m (FilePath, Text)
inputToText Text -> Text
convertTabs) [(FilePath, (ByteString, Maybe Text))]
inputs
                                PandocIO [(FilePath, Text)]
-> ([(FilePath, Text)] -> PandocIO Pandoc) -> PandocIO Pandoc
forall (m :: * -> *) a b. Monad m => m a -> (a -> m b) -> m b
>>= ReaderOptions -> [(FilePath, Text)] -> PandocIO Pandoc
forall a. ToSources a => ReaderOptions -> a -> PandocIO Pandoc
r ReaderOptions
readerOpts
             ByteStringReader r :: ReaderOptions -> ByteString -> PandocIO Pandoc
r ->
               [Pandoc] -> Pandoc
forall a. Monoid a => [a] -> a
mconcat ([Pandoc] -> Pandoc) -> PandocIO [Pandoc] -> PandocIO Pandoc
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> ((FilePath, (ByteString, Maybe Text)) -> PandocIO Pandoc)
-> [(FilePath, (ByteString, Maybe Text))] -> PandocIO [Pandoc]
forall (t :: * -> *) (m :: * -> *) a b.
(Traversable t, Monad m) =>
(a -> m b) -> t a -> m (t b)
mapM (ReaderOptions -> ByteString -> PandocIO Pandoc
r ReaderOptions
readerOpts (ByteString -> PandocIO Pandoc)
-> ((FilePath, (ByteString, Maybe Text)) -> ByteString)
-> (FilePath, (ByteString, Maybe Text))
-> PandocIO Pandoc
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (FilePath, (ByteString, Maybe Text)) -> ByteString
inputToLazyByteString) [(FilePath, (ByteString, Maybe Text))]
inputs)
            PandocIO Pandoc -> (Pandoc -> PandocIO Pandoc) -> PandocIO Pandoc
forall (m :: * -> *) a b. Monad m => m a -> (a -> m b) -> m b
>>=
              (   (if Bool -> Bool
not (Opt -> Bool
optSandbox Opt
opts) Bool -> Bool -> Bool
&&
                      (Maybe FilePath -> Bool
forall a. Maybe a -> Bool
isJust (Opt -> Maybe FilePath
optExtractMedia Opt
opts)
                       Bool -> Bool -> Bool
|| Text
writerNameBase Text -> Text -> Bool
forall a. Eq a => a -> a -> Bool
== "docx") -- for fallback pngs
                      then Pandoc -> PandocIO Pandoc
forall (m :: * -> *). PandocMonad m => Pandoc -> m Pandoc
fillMediaBag
                      else Pandoc -> PandocIO Pandoc
forall (m :: * -> *) a. Monad m => a -> m a
return)
              (Pandoc -> PandocIO Pandoc)
-> (Pandoc -> PandocIO Pandoc) -> Pandoc -> PandocIO Pandoc
forall (m :: * -> *) a b c.
Monad m =>
(a -> m b) -> (b -> m c) -> a -> m c
>=> Pandoc -> PandocIO Pandoc
forall (m :: * -> *) a. Monad m => a -> m a
return (Pandoc -> PandocIO Pandoc)
-> (Pandoc -> Pandoc) -> Pandoc -> PandocIO Pandoc
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (Meta -> Meta) -> Pandoc -> Pandoc
adjustMetadata (Meta
metadataFromFile Meta -> Meta -> Meta
forall a. Semigroup a => a -> a -> a
<>)
              (Pandoc -> PandocIO Pandoc)
-> (Pandoc -> PandocIO Pandoc) -> Pandoc -> PandocIO Pandoc
forall (m :: * -> *) a b c.
Monad m =>
(a -> m b) -> (b -> m c) -> a -> m c
>=> Pandoc -> PandocIO Pandoc
forall (m :: * -> *) a. Monad m => a -> m a
return (Pandoc -> PandocIO Pandoc)
-> (Pandoc -> Pandoc) -> Pandoc -> PandocIO Pandoc
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (Meta -> Meta) -> Pandoc -> Pandoc
adjustMetadata (Meta -> Meta -> Meta
forall a. Semigroup a => a -> a -> a
<> Opt -> Meta
optMetadata Opt
opts)
              (Pandoc -> PandocIO Pandoc)
-> (Pandoc -> PandocIO Pandoc) -> Pandoc -> PandocIO Pandoc
forall (m :: * -> *) a b c.
Monad m =>
(a -> m b) -> (b -> m c) -> a -> m c
>=> Pandoc -> PandocIO Pandoc
forall (m :: * -> *) a. Monad m => a -> m a
return (Pandoc -> PandocIO Pandoc)
-> (Pandoc -> Pandoc) -> Pandoc -> PandocIO Pandoc
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (Meta -> Meta) -> Pandoc -> Pandoc
adjustMetadata (Meta -> Meta -> Meta
forall a. Semigroup a => a -> a -> a
<> Meta
cslMetadata)
              (Pandoc -> PandocIO Pandoc)
-> (Pandoc -> PandocIO Pandoc) -> Pandoc -> PandocIO Pandoc
forall (m :: * -> *) a b c.
Monad m =>
(a -> m b) -> (b -> m c) -> a -> m c
>=> [Pandoc -> Pandoc] -> Pandoc -> PandocIO Pandoc
forall (m :: * -> *).
Monad m =>
[Pandoc -> Pandoc] -> Pandoc -> m Pandoc
applyTransforms [Pandoc -> Pandoc]
transforms
              (Pandoc -> PandocIO Pandoc)
-> (Pandoc -> PandocIO Pandoc) -> Pandoc -> PandocIO Pandoc
forall (m :: * -> *) a b c.
Monad m =>
(a -> m b) -> (b -> m c) -> a -> m c
>=> Environment -> [Filter] -> [FilePath] -> Pandoc -> PandocIO Pandoc
forall (m :: * -> *).
(PandocMonad m, MonadIO m) =>
Environment -> [Filter] -> [FilePath] -> Pandoc -> m Pandoc
applyFilters Environment
filterEnv [Filter]
filters [Text -> FilePath
T.unpack Text
format]
              (Pandoc -> PandocIO Pandoc)
-> (Pandoc -> PandocIO Pandoc) -> Pandoc -> PandocIO Pandoc
forall (m :: * -> *) a b c.
Monad m =>
(a -> m b) -> (b -> m c) -> a -> m c
>=> (Pandoc -> PandocIO Pandoc)
-> (FilePath -> Pandoc -> PandocIO Pandoc)
-> Maybe FilePath
-> Pandoc
-> PandocIO Pandoc
forall b a. b -> (a -> b) -> Maybe a -> b
maybe Pandoc -> PandocIO Pandoc
forall (m :: * -> *) a. Monad m => a -> m a
return FilePath -> Pandoc -> PandocIO Pandoc
forall (m :: * -> *).
(PandocMonad m, MonadIO m) =>
FilePath -> Pandoc -> m Pandoc
extractMedia (Opt -> Maybe FilePath
optExtractMedia Opt
opts)
              )

    Bool -> PandocIO () -> PandocIO ()
forall (f :: * -> *). Applicative f => Bool -> f () -> f ()
when (Text
writerNameBase Text -> Text -> Bool
forall a. Eq a => a -> a -> Bool
== "docx" Bool -> Bool -> Bool
&& Bool -> Bool
not (Opt -> Bool
optSandbox Opt
opts)) (PandocIO () -> PandocIO ()) -> PandocIO () -> PandocIO ()
forall a b. (a -> b) -> a -> b
$ do
      -- create fallback pngs for svgs
      [(FilePath, Text, ByteString)]
items <- MediaBag -> [(FilePath, Text, ByteString)]
mediaItems (MediaBag -> [(FilePath, Text, ByteString)])
-> PandocIO MediaBag -> PandocIO [(FilePath, Text, ByteString)]
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> PandocIO MediaBag
forall (m :: * -> *). PandocMonad m => m MediaBag
getMediaBag
      [(FilePath, Text, ByteString)]
-> ((FilePath, Text, ByteString) -> PandocIO ()) -> PandocIO ()
forall (t :: * -> *) (m :: * -> *) a b.
(Foldable t, Monad m) =>
t a -> (a -> m b) -> m ()
forM_ [(FilePath, Text, ByteString)]
items (((FilePath, Text, ByteString) -> PandocIO ()) -> PandocIO ())
-> ((FilePath, Text, ByteString) -> PandocIO ()) -> PandocIO ()
forall a b. (a -> b) -> a -> b
$ \(fp :: FilePath
fp, mt :: Text
mt, bs :: ByteString
bs) ->
        case (Char -> Bool) -> Text -> Text
T.takeWhile (Char -> Char -> Bool
forall a. Eq a => a -> a -> Bool
/=';') Text
mt of
          "image/svg+xml" -> do
            Either Text ByteString
res <- Int -> ByteString -> PandocIO (Either Text ByteString)
forall (m :: * -> *).
MonadIO m =>
Int -> ByteString -> m (Either Text ByteString)
svgToPng (WriterOptions -> Int
writerDpi WriterOptions
writerOptions) ByteString
bs
            case Either Text ByteString
res of
              Right bs' :: ByteString
bs' -> do
                let fp' :: FilePath
fp' = FilePath
fp FilePath -> FilePath -> FilePath
forall a. Semigroup a => a -> a -> a
<> ".png"
                FilePath -> Maybe Text -> ByteString -> PandocIO ()
forall (m :: * -> *).
PandocMonad m =>
FilePath -> Maybe Text -> ByteString -> m ()
insertMedia FilePath
fp' (Text -> Maybe Text
forall a. a -> Maybe a
Just "image/png") ByteString
bs'
              Left e :: Text
e -> LogMessage -> PandocIO ()
forall (m :: * -> *). PandocMonad m => LogMessage -> m ()
report (LogMessage -> PandocIO ()) -> LogMessage -> PandocIO ()
forall a b. (a -> b) -> a -> b
$ Text -> Text -> LogMessage
CouldNotConvertImage (FilePath -> Text
T.pack FilePath
fp) (Text -> Text
forall a. Show a => a -> Text
tshow Text
e)
          _ -> () -> PandocIO ()
forall (m :: * -> *) a. Monad m => a -> m a
return ()

    PandocOutput
output <- case Writer PandocIO
writer of
      ByteStringWriter f :: WriterOptions -> Pandoc -> PandocIO ByteString
f -> ByteString -> PandocOutput
BinaryOutput (ByteString -> PandocOutput)
-> PandocIO ByteString -> PandocIO PandocOutput
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> WriterOptions -> Pandoc -> PandocIO ByteString
f WriterOptions
writerOptions Pandoc
doc
      TextWriter f :: WriterOptions -> Pandoc -> PandocIO Text
f -> case OutputSettings PandocIO -> Maybe FilePath
forall (m :: * -> *). OutputSettings m -> Maybe FilePath
outputPdfProgram OutputSettings PandocIO
outputSettings of
        Just pdfProg :: FilePath
pdfProg -> do
                Either ByteString ByteString
res <- FilePath
-> [FilePath]
-> (WriterOptions -> Pandoc -> PandocIO Text)
-> WriterOptions
-> Pandoc
-> PandocIO (Either ByteString ByteString)
forall (m :: * -> *).
(PandocMonad m, MonadIO m, MonadMask m) =>
FilePath
-> [FilePath]
-> (WriterOptions -> Pandoc -> m Text)
-> WriterOptions
-> Pandoc
-> m (Either ByteString ByteString)
makePDF FilePath
pdfProg (Opt -> [FilePath]
optPdfEngineOpts Opt
opts) WriterOptions -> Pandoc -> PandocIO Text
f
                        WriterOptions
writerOptions Pandoc
doc
                case Either ByteString ByteString
res of
                     Right pdf :: ByteString
pdf -> PandocOutput -> PandocIO PandocOutput
forall (m :: * -> *) a. Monad m => a -> m a
return (PandocOutput -> PandocIO PandocOutput)
-> PandocOutput -> PandocIO PandocOutput
forall a b. (a -> b) -> a -> b
$ ByteString -> PandocOutput
BinaryOutput ByteString
pdf
                     Left err' :: ByteString
err' -> PandocError -> PandocIO PandocOutput
forall e (m :: * -> *) a. MonadError e m => e -> m a
throwError (PandocError -> PandocIO PandocOutput)
-> PandocError -> PandocIO PandocOutput
forall a b. (a -> b) -> a -> b
$ Text -> PandocError
PandocPDFError (Text -> PandocError) -> Text -> PandocError
forall a b. (a -> b) -> a -> b
$
                                     Text -> Text
TL.toStrict (OnDecodeError -> ByteString -> Text
TE.decodeUtf8With OnDecodeError
TE.lenientDecode ByteString
err')

        Nothing -> do
                let ensureNl :: Text -> Text
ensureNl t :: Text
t
                      | Bool
standalone = Text
t
                      | Text -> Bool
T.null Text
t Bool -> Bool -> Bool
|| Text -> Char
T.last Text
t Char -> Char -> Bool
forall a. Eq a => a -> a -> Bool
/= '\n' = Text
t Text -> Text -> Text
forall a. Semigroup a => a -> a -> a
<> Char -> Text
T.singleton '\n'
                      | Bool
otherwise = Text
t
                Text
textOutput <- Text -> Text
ensureNl (Text -> Text) -> PandocIO Text -> PandocIO Text
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> WriterOptions -> Pandoc -> PandocIO Text
f WriterOptions
writerOptions Pandoc
doc
                if Opt -> Bool
optSelfContained Opt
opts Bool -> Bool -> Bool
&& Text -> Bool
htmlFormat Text
format
                   then Text -> PandocOutput
TextOutput (Text -> PandocOutput) -> PandocIO Text -> PandocIO PandocOutput
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Text -> PandocIO Text
forall (m :: * -> *). PandocMonad m => Text -> m Text
makeSelfContained Text
textOutput
                   else PandocOutput -> PandocIO PandocOutput
forall (m :: * -> *) a. Monad m => a -> m a
return (PandocOutput -> PandocIO PandocOutput)
-> PandocOutput -> PandocIO PandocOutput
forall a b. (a -> b) -> a -> b
$ Text -> PandocOutput
TextOutput Text
textOutput
    [LogMessage]
reports <- PandocIO [LogMessage]
forall (m :: * -> *). PandocMonad m => m [LogMessage]
getLog
    (PandocOutput, [LogMessage])
-> PandocIO (PandocOutput, [LogMessage])
forall (m :: * -> *) a. Monad m => a -> m a
return (PandocOutput
output, [LogMessage]
reports)

  case Either PandocError (PandocOutput, [LogMessage])
res of
    Left e :: PandocError
e -> PandocError -> IO ()
forall e a. Exception e => e -> IO a
E.throwIO PandocError
e
    Right (output :: PandocOutput
output, reports :: [LogMessage]
reports) -> do
      case Opt -> Maybe FilePath
optLogFile Opt
opts of
           Nothing      -> () -> IO ()
forall (m :: * -> *) a. Monad m => a -> m a
return ()
           Just logfile :: FilePath
logfile -> FilePath -> ByteString -> IO ()
BL.writeFile FilePath
logfile ([LogMessage] -> ByteString
encodeLogMessages [LogMessage]
reports)
      let isWarning :: LogMessage -> Bool
isWarning msg :: LogMessage
msg = LogMessage -> Verbosity
messageVerbosity LogMessage
msg Verbosity -> Verbosity -> Bool
forall a. Eq a => a -> a -> Bool
== Verbosity
WARNING
      Bool -> IO () -> IO ()
forall (f :: * -> *). Applicative f => Bool -> f () -> f ()
when (Opt -> Bool
optFailIfWarnings Opt
opts Bool -> Bool -> Bool
&& (LogMessage -> Bool) -> [LogMessage] -> Bool
forall (t :: * -> *) a. Foldable t => (a -> Bool) -> t a -> Bool
any LogMessage -> Bool
isWarning [LogMessage]
reports) (IO () -> IO ()) -> IO () -> IO ()
forall a b. (a -> b) -> a -> b
$
          PandocError -> IO ()
forall e a. Exception e => e -> IO a
E.throwIO PandocError
PandocFailOnWarningError
      let eol :: Newline
eol = case Opt -> LineEnding
optEol Opt
opts of
                     CRLF   -> Newline
IO.CRLF
                     LF     -> Newline
IO.LF
                     Native -> Newline
nativeNewline
      case PandocOutput
output of
        TextOutput t :: Text
t    -> Newline -> FilePath -> Text -> IO ()
writerFn Newline
eol FilePath
outputFile Text
t
        BinaryOutput bs :: ByteString
bs -> FilePath -> ByteString -> IO ()
writeFnBinary FilePath
outputFile ByteString
bs

data PandocOutput = TextOutput Text | BinaryOutput BL.ByteString
  deriving (Int -> PandocOutput -> FilePath -> FilePath
[PandocOutput] -> FilePath -> FilePath
PandocOutput -> FilePath
(Int -> PandocOutput -> FilePath -> FilePath)
-> (PandocOutput -> FilePath)
-> ([PandocOutput] -> FilePath -> FilePath)
-> Show PandocOutput
forall a.
(Int -> a -> FilePath -> FilePath)
-> (a -> FilePath) -> ([a] -> FilePath -> FilePath) -> Show a
showList :: [PandocOutput] -> FilePath -> FilePath
$cshowList :: [PandocOutput] -> FilePath -> FilePath
show :: PandocOutput -> FilePath
$cshow :: PandocOutput -> FilePath
showsPrec :: Int -> PandocOutput -> FilePath -> FilePath
$cshowsPrec :: Int -> PandocOutput -> FilePath -> FilePath
Show)

type Transform = Pandoc -> Pandoc

htmlFormat :: Text -> Bool
htmlFormat :: Text -> Bool
htmlFormat = (Text -> [Text] -> Bool
forall (t :: * -> *) a. (Foldable t, Eq a) => a -> t a -> Bool
`elem` ["html","html4","html5","s5","slidy",
                      "slideous","dzslides","revealjs"])

isTextFormat :: Text -> Bool
isTextFormat :: Text -> Bool
isTextFormat s :: Text
s = Text
s Text -> [Text] -> Bool
forall (t :: * -> *) a. (Foldable t, Eq a) => a -> t a -> Bool
`notElem` ["odt","docx","epub2","epub3","epub","pptx"]

adjustMetadata :: (Meta -> Meta) -> Pandoc -> Pandoc
adjustMetadata :: (Meta -> Meta) -> Pandoc -> Pandoc
adjustMetadata f :: Meta -> Meta
f (Pandoc meta :: Meta
meta bs :: [Block]
bs) = Meta -> [Block] -> Pandoc
Pandoc (Meta -> Meta
f Meta
meta) [Block]
bs

-- Transformations of a Pandoc document post-parsing:

applyTransforms :: Monad m => [Transform] -> Pandoc -> m Pandoc
applyTransforms :: [Pandoc -> Pandoc] -> Pandoc -> m Pandoc
applyTransforms transforms :: [Pandoc -> Pandoc]
transforms d :: Pandoc
d = Pandoc -> m Pandoc
forall (m :: * -> *) a. Monad m => a -> m a
return (Pandoc -> m Pandoc) -> Pandoc -> m Pandoc
forall a b. (a -> b) -> a -> b
$ ((Pandoc -> Pandoc) -> Pandoc -> Pandoc)
-> Pandoc -> [Pandoc -> Pandoc] -> Pandoc
forall (t :: * -> *) a b.
Foldable t =>
(a -> b -> b) -> b -> t a -> b
foldr (Pandoc -> Pandoc) -> Pandoc -> Pandoc
forall a b. (a -> b) -> a -> b
($) Pandoc
d [Pandoc -> Pandoc]
transforms

readSources :: (PandocMonad m, MonadIO m)
            => [FilePath] -> m [(FilePath, (BS.ByteString, Maybe MimeType))]
readSources :: [FilePath] -> m [(FilePath, (ByteString, Maybe Text))]
readSources srcs :: [FilePath]
srcs =
  (FilePath -> m (FilePath, (ByteString, Maybe Text)))
-> [FilePath] -> m [(FilePath, (ByteString, Maybe Text))]
forall (t :: * -> *) (m :: * -> *) a b.
(Traversable t, Monad m) =>
(a -> m b) -> t a -> m (t b)
mapM (\fp :: FilePath
fp -> do (ByteString, Maybe Text)
t <- FilePath -> m (ByteString, Maybe Text)
forall (m :: * -> *).
(PandocMonad m, MonadIO m) =>
FilePath -> m (ByteString, Maybe Text)
readSource FilePath
fp
                  (FilePath, (ByteString, Maybe Text))
-> m (FilePath, (ByteString, Maybe Text))
forall (m :: * -> *) a. Monad m => a -> m a
return (if FilePath
fp FilePath -> FilePath -> Bool
forall a. Eq a => a -> a -> Bool
== "-" then "" else FilePath
fp, (ByteString, Maybe Text)
t)) [FilePath]
srcs

readSource :: (PandocMonad m, MonadIO m)
           => FilePath -> m (BS.ByteString, Maybe MimeType)
readSource :: FilePath -> m (ByteString, Maybe Text)
readSource "-" = (,Maybe Text
forall a. Maybe a
Nothing) (ByteString -> (ByteString, Maybe Text))
-> m ByteString -> m (ByteString, Maybe Text)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> m ByteString
forall (m :: * -> *). PandocMonad m => m ByteString
readStdinStrict
readSource src :: FilePath
src =
  case FilePath -> Maybe URI
parseURI FilePath
src of
    Just u :: URI
u | URI -> FilePath
uriScheme URI
u FilePath -> [FilePath] -> Bool
forall (t :: * -> *) a. (Foldable t, Eq a) => a -> t a -> Bool
`elem` ["http:","https:"] -> Text -> m (ByteString, Maybe Text)
forall (m :: * -> *).
PandocMonad m =>
Text -> m (ByteString, Maybe Text)
openURL (FilePath -> Text
T.pack FilePath
src)
           | URI -> FilePath
uriScheme URI
u FilePath -> FilePath -> Bool
forall a. Eq a => a -> a -> Bool
== "file:" ->
               (,Maybe Text
forall a. Maybe a
Nothing) (ByteString -> (ByteString, Maybe Text))
-> m ByteString -> m (ByteString, Maybe Text)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$>
                 FilePath -> m ByteString
forall (m :: * -> *). PandocMonad m => FilePath -> m ByteString
readFileStrict (Text -> FilePath
uriPathToPath (Text -> FilePath) -> Text -> FilePath
forall a b. (a -> b) -> a -> b
$ FilePath -> Text
T.pack (FilePath -> Text) -> FilePath -> Text
forall a b. (a -> b) -> a -> b
$ URI -> FilePath
uriPath URI
u)
    _       -> (,Maybe Text
forall a. Maybe a
Nothing) (ByteString -> (ByteString, Maybe Text))
-> m ByteString -> m (ByteString, Maybe Text)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> FilePath -> m ByteString
forall (m :: * -> *). PandocMonad m => FilePath -> m ByteString
readFileStrict FilePath
src

utf8ToText :: PandocMonad m => FilePath -> BS.ByteString -> m Text
utf8ToText :: FilePath -> ByteString -> m Text
utf8ToText fp :: FilePath
fp bs :: ByteString
bs =
  case ByteString -> Either UnicodeException Text
TSE.decodeUtf8' (ByteString -> Either UnicodeException Text)
-> (ByteString -> ByteString)
-> ByteString
-> Either UnicodeException Text
forall b c a. (b -> c) -> (a -> b) -> a -> c
. ByteString -> ByteString
dropBOM (ByteString -> Either UnicodeException Text)
-> ByteString -> Either UnicodeException Text
forall a b. (a -> b) -> a -> b
$ ByteString
bs of
    Left (TSE.DecodeError _ (Just w :: Word8
w)) ->
      case Word8 -> ByteString -> Maybe Int
BS.elemIndex Word8
w ByteString
bs of
        Just offset :: Int
offset -> PandocError -> m Text
forall e (m :: * -> *) a. MonadError e m => e -> m a
throwError (PandocError -> m Text) -> PandocError -> m Text
forall a b. (a -> b) -> a -> b
$ Text -> Int -> Word8 -> PandocError
PandocUTF8DecodingError (FilePath -> Text
T.pack FilePath
fp) Int
offset Word8
w
        Nothing -> PandocError -> m Text
forall e (m :: * -> *) a. MonadError e m => e -> m a
throwError (PandocError -> m Text) -> PandocError -> m Text
forall a b. (a -> b) -> a -> b
$ Text -> Int -> Word8 -> PandocError
PandocUTF8DecodingError (FilePath -> Text
T.pack FilePath
fp) 0 Word8
w
    Left e :: UnicodeException
e -> PandocError -> m Text
forall e (m :: * -> *) a. MonadError e m => e -> m a
throwError (PandocError -> m Text) -> PandocError -> m Text
forall a b. (a -> b) -> a -> b
$ Text -> PandocError
PandocAppError (UnicodeException -> Text
forall a. Show a => a -> Text
tshow UnicodeException
e)
    Right t :: Text
t -> Text -> m Text
forall (m :: * -> *) a. Monad m => a -> m a
return Text
t
 where
   dropBOM :: ByteString -> ByteString
dropBOM bs' :: ByteString
bs' =
     if "\xEF\xBB\xBF" ByteString -> ByteString -> Bool
`BS.isPrefixOf` ByteString
bs'
        then Int -> ByteString -> ByteString
BS.drop 3 ByteString
bs'
        else ByteString
bs'


inputToText :: PandocMonad m
            => (Text -> Text)
            -> (FilePath, (BS.ByteString, Maybe MimeType))
            -> m (FilePath, Text)
inputToText :: (Text -> Text)
-> (FilePath, (ByteString, Maybe Text)) -> m (FilePath, Text)
inputToText convTabs :: Text -> Text
convTabs (fp :: FilePath
fp, (bs :: ByteString
bs,mt :: Maybe Text
mt)) =
  (FilePath
fp,) (Text -> (FilePath, Text))
-> (Text -> Text) -> Text -> (FilePath, Text)
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Text -> Text
convTabs (Text -> Text) -> (Text -> Text) -> Text -> Text
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (Char -> Bool) -> Text -> Text
T.filter (Char -> Char -> Bool
forall a. Eq a => a -> a -> Bool
/='\r') (Text -> (FilePath, Text)) -> m Text -> m (FilePath, Text)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$>
  case Maybe Text
mt Maybe Text -> (Text -> Maybe Text) -> Maybe Text
forall (m :: * -> *) a b. Monad m => m a -> (a -> m b) -> m b
>>= Text -> Maybe Text
getCharset of
    Just "UTF-8"      -> FilePath -> ByteString -> m Text
forall (m :: * -> *).
PandocMonad m =>
FilePath -> ByteString -> m Text
utf8ToText FilePath
fp ByteString
bs
    Just "ISO-8859-1" -> Text -> m Text
forall (m :: * -> *) a. Monad m => a -> m a
return (Text -> m Text) -> Text -> m Text
forall a b. (a -> b) -> a -> b
$ FilePath -> Text
T.pack (FilePath -> Text) -> FilePath -> Text
forall a b. (a -> b) -> a -> b
$ ByteString -> FilePath
B8.unpack ByteString
bs
    Just charset :: Text
charset      -> PandocError -> m Text
forall e (m :: * -> *) a. MonadError e m => e -> m a
throwError (PandocError -> m Text) -> PandocError -> m Text
forall a b. (a -> b) -> a -> b
$ Text -> PandocError
PandocUnsupportedCharsetError Text
charset
    Nothing           -> m Text -> (PandocError -> m Text) -> m Text
forall e (m :: * -> *) a.
MonadError e m =>
m a -> (e -> m a) -> m a
catchError
                           (FilePath -> ByteString -> m Text
forall (m :: * -> *).
PandocMonad m =>
FilePath -> ByteString -> m Text
utf8ToText FilePath
fp ByteString
bs)
                           (\case
                              PandocUTF8DecodingError{} -> do
                                LogMessage -> m ()
forall (m :: * -> *). PandocMonad m => LogMessage -> m ()
report (LogMessage -> m ()) -> LogMessage -> m ()
forall a b. (a -> b) -> a -> b
$ FilePath -> LogMessage
NotUTF8Encoded
                                  (if FilePath -> Bool
forall (t :: * -> *) a. Foldable t => t a -> Bool
null FilePath
fp
                                      then "input"
                                      else FilePath
fp)
                                Text -> m Text
forall (m :: * -> *) a. Monad m => a -> m a
return (Text -> m Text) -> Text -> m Text
forall a b. (a -> b) -> a -> b
$ FilePath -> Text
T.pack (FilePath -> Text) -> FilePath -> Text
forall a b. (a -> b) -> a -> b
$ ByteString -> FilePath
B8.unpack ByteString
bs
                              e :: PandocError
e -> PandocError -> m Text
forall e (m :: * -> *) a. MonadError e m => e -> m a
throwError PandocError
e)

inputToLazyByteString :: (FilePath, (BS.ByteString, Maybe MimeType))
                      -> BL.ByteString
inputToLazyByteString :: (FilePath, (ByteString, Maybe Text)) -> ByteString
inputToLazyByteString (_, (bs :: ByteString
bs,_)) = ByteString -> ByteString
BL.fromStrict ByteString
bs

writeFnBinary :: FilePath -> BL.ByteString -> IO ()
writeFnBinary :: FilePath -> ByteString -> IO ()
writeFnBinary "-" = ByteString -> IO ()
BL.putStr
writeFnBinary f :: FilePath
f   = FilePath -> ByteString -> IO ()
BL.writeFile (FilePath -> FilePath
UTF8.encodePath FilePath
f)

writerFn :: IO.Newline -> FilePath -> Text -> IO ()
writerFn :: Newline -> FilePath -> Text -> IO ()
writerFn eol :: Newline
eol "-" = Newline -> Text -> IO ()
UTF8.putStrWith Newline
eol
writerFn eol :: Newline
eol f :: FilePath
f   = Newline -> FilePath -> Text -> IO ()
UTF8.writeFileWith Newline
eol FilePath
f