git.iko.soy/typeable/pandoc
on master help sign in
App: extract command line options to separate module
commitfd3c8cd8c792e6dfe3b19c10cc65152034dd4f30 authorAlbert Krewinkel <albert@zeitkraut.de> dateSat 21 Oct 2017, 23:00 (9 years ago) parentb826fe7
3 files changed+1101−1036
pandoc.cabal+2−1 src/Text/Pandoc/App.hs+8−1035 src/Text/Pandoc/App/CommandLineOptions.hs+1091
pandoc.cabal+2−1
@@ -514,7 +514,8 @@ library
514514 Text.Pandoc.ImageSize,
515515 Text.Pandoc.BCP47,
516516 Text.Pandoc.Class
517− other-modules: Text.Pandoc.Filter.JSON,
517+ other-modules: Text.Pandoc.App.CommandLineOptions,
518+ Text.Pandoc.Filter.JSON,
518519 Text.Pandoc.Filter.Lua,
519520 Text.Pandoc.Filter.Path,
520521 Text.Pandoc.Readers.Docx.Lists,
src/Text/Pandoc/App.hs+8−1035
@@ -1,8 +1,6 @@
11{-# LANGUAGE NoImplicitPrelude #-}
22{-# LANGUAGE CPP #-}
3−{-# LANGUAGE DeriveGeneric #-}
43{-# LANGUAGE ScopedTypeVariables #-}
5−{-# LANGUAGE TemplateHaskell #-}
64{-# LANGUAGE TupleSections #-}
75{-
86Copyright (C) 2006-2018 John MacFarlane <jgm@berkeley.edu>
@@ -48,13 +46,10 @@ import qualified Control.Exception as E
4846import Control.Monad
4947import Control.Monad.Except (catchError, throwError)
5048import Control.Monad.Trans
51−import Data.Aeson (defaultOptions)
52−import Data.Aeson.TH (deriveJSON)
5349import qualified Data.ByteString as BS
5450import qualified Data.ByteString.Lazy as B
55−import Data.Char (toLower, toUpper)
56−import Data.List (find, intercalate, isPrefixOf, isSuffixOf, sort)
57−import qualified Data.Map as M
51+import Data.Char (toLower)
52+import Data.List (find, isPrefixOf, isSuffixOf)
5853import Data.Maybe (fromMaybe, isJust, isNothing)
5954import qualified Data.Set as Set
6055import Data.Text (Text)
@@ -63,85 +58,31 @@ import qualified Data.Text.Lazy as TL
6358import qualified Data.Text.Lazy.Encoding as TE
6459import qualified Data.Text.Encoding.Error as TE
6560import qualified Data.YAML as YAML
66−import GHC.Generics
6761import Network.URI (URI (..), parseURI)
68−#ifdef EMBED_DATA_FILES
69−import Text.Pandoc.Data (dataFiles)
70−#else
71−import System.Directory (getDirectoryContents)
72−import Paths_pandoc (getDataDir)
73−#endif
74−import Data.Aeson.Encode.Pretty (encodePretty', Config(..), keyOrder,
75− defConfig, Indent(..), NumberFormat(..))
76−import Skylighting (Style, Syntax (..), defaultSyntaxMap, parseTheme,
77− pygments)
62+import Skylighting (defaultSyntaxMap)
7863import Skylighting.Parser (addSyntaxDefinition, parseSyntaxDefinition)
79−import System.Console.GetOpt
8064import System.Directory (getAppUserDataDirectory)
81−import System.Environment (getArgs, getProgName)
8265import System.Exit (exitSuccess)
8366import System.FilePath
8467import System.IO (nativeNewline, stdout)
8568import qualified System.IO as IO (Newline (..))
8669import Text.Pandoc
70+import Text.Pandoc.App.CommandLineOptions (Opt (..), LineEnding (..),
71+ defaultOpts, engines, parseOptions, options)
8772import Text.Pandoc.BCP47 (Lang (..), parseBCP47)
8873import Text.Pandoc.Builder (setMeta, deleteMeta)
8974import Text.Pandoc.Filter (Filter (JSONFilter, LuaFilter), applyFilters)
90−import Text.Pandoc.Highlighting (highlightingStyles)
9175import Text.Pandoc.PDF (makePDF)
9276import Text.Pandoc.Readers.Markdown (yamlToMeta)
9377import Text.Pandoc.SelfContained (makeDataURI, makeSelfContained)
9478import Text.Pandoc.Shared (eastAsianLineBreakFilter, stripEmptyParagraphs,
95− headerShift, isURI, ordNub, safeRead, tabFilter, uriPathToPath)
79+ headerShift, isURI, tabFilter, uriPathToPath)
9680import qualified Text.Pandoc.UTF8 as UTF8
97−import Text.Pandoc.Writers.Math (defaultKaTeXURL, defaultMathJaxURL)
98−import Text.Printf
9981#ifndef _WINDOWS
10082import System.Posix.IO (stdOutput)
10183import System.Posix.Terminal (queryTerminal)
10284#endif
10385
104−data LineEnding = LF | CRLF | Native deriving (Show, Generic)
105−
106−parseOptions :: [OptDescr (Opt -> IO Opt)] -> Opt -> IO Opt
107−parseOptions options' defaults = do
108− rawArgs <- map UTF8.decodeArg <$> getArgs
109− prg <- getProgName
110−
111− let (actions, args, unrecognizedOpts, errors) =
112− getOpt' Permute options' rawArgs
113−
114− let unknownOptionErrors =
115− foldr (handleUnrecognizedOption . takeWhile (/= '=')) []
116− unrecognizedOpts
117−
118− unless (null errors && null unknownOptionErrors) $
119− E.throwIO $ PandocOptionError $
120− concat errors ++ unlines unknownOptionErrors ++
121− ("Try " ++ prg ++ " --help for more information.")
122−
123− -- thread option data structure through all supplied option actions
124− opts <- foldl (>>=) (return defaults) actions
125− return (opts{ optInputFiles = args })
126−
127−latexEngines :: [String]
128−latexEngines = ["pdflatex", "lualatex", "xelatex"]
129−
130−htmlEngines :: [String]
131−htmlEngines = ["wkhtmltopdf", "weasyprint", "prince"]
132−
133−engines :: [(String, String)]
134−engines = map ("html",) htmlEngines ++
135− map ("html5",) htmlEngines ++
136− map ("latex",) latexEngines ++
137− map ("beamer",) latexEngines ++
138− [ ("ms", "pdfroff")
139− , ("context", "context")
140− ]
141−
142−pdfEngines :: [String]
143−pdfEngines = ordNub $ map snd engines
144−
14586pdfIsNoWriterErrorMsg :: String
14687pdfIsNoWriterErrorMsg =
14788 "To create a pdf using pandoc, use " ++
@@ -264,7 +205,6 @@ convertWithOpts opts = do
264205 let standalone = optStandalone opts || not (isTextFormat format) || pdfOutput
265206 let addStringAsVariable varname s vars = return $ (varname, s) : vars
266207
267− highlightStyle <- lookupHighlightStyle $ optHighlightStyle opts
268208 let addSyntaxMap existingmap f = do
269209 res <- parseSyntaxDefinition f
270210 case res of
@@ -374,7 +314,7 @@ convertWithOpts opts = do
374314 return $ ("dzslides-core", dzcore) : vars
375315 else return vars)
376316
377− abbrevs <- (Set.fromList . filter (not . null) . lines) <$>
317+ abbrevs <- Set.fromList . filter (not . null) . lines <$>
378318 case optAbbreviations opts of
379319 Nothing -> UTF8.toString <$> readDataFile "abbreviations"
380320 Just f -> UTF8.toString <$> readFileStrict f
@@ -438,7 +378,7 @@ convertWithOpts opts = do
438378 , writerTopLevelDivision = optTopLevelDivision opts
439379 , writerListings = optListings opts
440380 , writerSlideLevel = optSlideLevel opts
441− , writerHighlightStyle = highlightStyle
381+ , writerHighlightStyle = optHighlightStyle opts
442382 , writerSetextHeaders = optSetextHeaders opts
443383 , writerEpubSubdirectory = optEpubSubdirectory opts
444384 , writerEpubMetadata = epubMetadata
@@ -540,151 +480,6 @@ type Transform = Pandoc -> Pandoc
540480isTextFormat :: String -> Bool
541481isTextFormat s = s `notElem` ["odt","docx","epub2","epub3","epub","pptx"]
542482
543−-- | Data structure for command line options.
544−data Opt = Opt
545− { optTabStop :: Int -- ^ Number of spaces per tab
546− , optPreserveTabs :: Bool -- ^ Preserve tabs instead of converting to spaces
547− , optStandalone :: Bool -- ^ Include header, footer
548− , optReader :: Maybe String -- ^ Reader format
549− , optWriter :: Maybe String -- ^ Writer format
550− , optTableOfContents :: Bool -- ^ Include table of contents
551− , optBaseHeaderLevel :: Int -- ^ Base header level
552− , optTemplate :: Maybe FilePath -- ^ Custom template
553− , optVariables :: [(String,String)] -- ^ Template variables to set
554− , optMetadata :: [(String, String)] -- ^ Metadata fields to set
555− , optMetadataFile :: Maybe FilePath -- ^ Name of YAML metadata file
556− , optOutputFile :: Maybe FilePath -- ^ Name of output file
557− , optInputFiles :: [FilePath] -- ^ Names of input files
558− , optNumberSections :: Bool -- ^ Number sections in LaTeX
559− , optNumberOffset :: [Int] -- ^ Starting number for sections
560− , optSectionDivs :: Bool -- ^ Put sections in div tags in HTML
561− , optIncremental :: Bool -- ^ Use incremental lists in Slidy/Slideous/S5
562− , optSelfContained :: Bool -- ^ Make HTML accessible offline
563− , optHtmlQTags :: Bool -- ^ Use <q> tags in HTML
564− , optHighlightStyle :: Maybe String -- ^ Style to use for highlighted code
565− , optSyntaxDefinitions :: [FilePath] -- ^ xml syntax defs to load
566− , optTopLevelDivision :: TopLevelDivision -- ^ Type of the top-level divisions
567− , optHTMLMathMethod :: HTMLMathMethod -- ^ Method to print HTML math
568− , optAbbreviations :: Maybe FilePath -- ^ Path to abbrevs file
569− , optReferenceDoc :: Maybe FilePath -- ^ Path of reference doc
570− , optEpubSubdirectory :: String -- ^ EPUB subdir in OCF container
571− , optEpubMetadata :: Maybe FilePath -- ^ EPUB metadata
572− , optEpubFonts :: [FilePath] -- ^ EPUB fonts to embed
573− , optEpubChapterLevel :: Int -- ^ Header level at which to split chapters
574− , optEpubCoverImage :: Maybe FilePath -- ^ Cover image for epub
575− , optTOCDepth :: Int -- ^ Number of levels to include in TOC
576− , optDumpArgs :: Bool -- ^ Output command-line arguments
577− , optIgnoreArgs :: Bool -- ^ Ignore command-line arguments
578− , optVerbosity :: Verbosity -- ^ Verbosity of diagnostic output
579− , optTrace :: Bool -- ^ Enable tracing
580− , optLogFile :: Maybe FilePath -- ^ File to write JSON log output
581− , optFailIfWarnings :: Bool -- ^ Fail on warnings
582− , optReferenceLinks :: Bool -- ^ Use reference links in writing markdown, rst
583− , optReferenceLocation :: ReferenceLocation -- ^ location for footnotes and link references in markdown output
584− , optDpi :: Int -- ^ Dpi
585− , optWrapText :: WrapOption -- ^ Options for wrapping text
586− , optColumns :: Int -- ^ Line length in characters
587− , optFilters :: [Filter] -- ^ Filters to apply
588− , optEmailObfuscation :: ObfuscationMethod
589− , optIdentifierPrefix :: String
590− , optStripEmptyParagraphs :: Bool -- ^ Strip empty paragraphs
591− , optIndentedCodeClasses :: [String] -- ^ Default classes for indented code blocks
592− , optDataDir :: Maybe FilePath
593− , optCiteMethod :: CiteMethod -- ^ Method to output cites
594− , optListings :: Bool -- ^ Use listings package for code blocks
595− , optPdfEngine :: Maybe String -- ^ Program to use for latex/html -> pdf
596− , optPdfEngineArgs :: [String] -- ^ Flags to pass to the engine
597− , optSlideLevel :: Maybe Int -- ^ Header level that creates slides
598− , optSetextHeaders :: Bool -- ^ Use atx headers for markdown level 1-2
599− , optAscii :: Bool -- ^ Prefer ascii output
600− , optDefaultImageExtension :: String -- ^ Default image extension
601− , optExtractMedia :: Maybe FilePath -- ^ Path to extract embedded media
602− , optTrackChanges :: TrackChanges -- ^ Accept or reject MS Word track-changes.
603− , optFileScope :: Bool -- ^ Parse input files before combining
604− , optTitlePrefix :: Maybe String -- ^ Prefix for title
605− , optCss :: [FilePath] -- ^ CSS files to link to
606− , optIncludeBeforeBody :: [FilePath] -- ^ Files to include before
607− , optIncludeAfterBody :: [FilePath] -- ^ Files to include after body
608− , optIncludeInHeader :: [FilePath] -- ^ Files to include in header
609− , optResourcePath :: [FilePath] -- ^ Path to search for images etc
610− , optRequestHeaders :: [(String, String)] -- ^ Headers for HTTP requests
611− , optEol :: LineEnding -- ^ Style of line-endings to use
612− , optStripComments :: Bool -- ^ Skip HTML comments
613− } deriving (Generic, Show)
614−
615−-- | Defaults for command-line options.
616−defaultOpts :: Opt
617−defaultOpts = Opt
618− { optTabStop = 4
619− , optPreserveTabs = False
620− , optStandalone = False
621− , optReader = Nothing
622− , optWriter = Nothing
623− , optTableOfContents = False
624− , optBaseHeaderLevel = 1
625− , optTemplate = Nothing
626− , optVariables = []
627− , optMetadata = []
628− , optMetadataFile = Nothing
629− , optOutputFile = Nothing
630− , optInputFiles = []
631− , optNumberSections = False
632− , optNumberOffset = [0,0,0,0,0,0]
633− , optSectionDivs = False
634− , optIncremental = False
635− , optSelfContained = False
636− , optHtmlQTags = False
637− , optHighlightStyle = Just "pygments"
638− , optSyntaxDefinitions = []
639− , optTopLevelDivision = TopLevelDefault
640− , optHTMLMathMethod = PlainMath
641− , optAbbreviations = Nothing
642− , optReferenceDoc = Nothing
643− , optEpubSubdirectory = "EPUB"
644− , optEpubMetadata = Nothing
645− , optEpubFonts = []
646− , optEpubChapterLevel = 1
647− , optEpubCoverImage = Nothing
648− , optTOCDepth = 3
649− , optDumpArgs = False
650− , optIgnoreArgs = False
651− , optVerbosity = WARNING
652− , optTrace = False
653− , optLogFile = Nothing
654− , optFailIfWarnings = False
655− , optReferenceLinks = False
656− , optReferenceLocation = EndOfDocument
657− , optDpi = 96
658− , optWrapText = WrapAuto
659− , optColumns = 72
660− , optFilters = []
661− , optEmailObfuscation = NoObfuscation
662− , optIdentifierPrefix = ""
663− , optStripEmptyParagraphs = False
664− , optIndentedCodeClasses = []
665− , optDataDir = Nothing
666− , optCiteMethod = Citeproc
667− , optListings = False
668− , optPdfEngine = Nothing
669− , optPdfEngineArgs = []
670− , optSlideLevel = Nothing
671− , optSetextHeaders = True
672− , optAscii = False
673− , optDefaultImageExtension = ""
674− , optExtractMedia = Nothing
675− , optTrackChanges = AcceptChanges
676− , optFileScope = False
677− , optTitlePrefix = Nothing
678− , optCss = []
679− , optIncludeBeforeBody = []
680− , optIncludeAfterBody = []
681− , optIncludeInHeader = []
682− , optResourcePath = ["."]
683− , optRequestHeaders = []
684− , optEol = Native
685− , optStripComments = False
686− }
687−
688483addNonPresentMetadata :: Text.Pandoc.Meta -> Pandoc -> Pandoc
689484addNonPresentMetadata newmeta (Pandoc meta bs) = Pandoc (meta <> newmeta) bs
690485
@@ -800,828 +595,6 @@ writerFn :: MonadIO m => IO.Newline -> FilePath -> Text -> m ()
800595writerFn eol "-" = liftIO . UTF8.putStrWith eol . T.unpack
801596writerFn eol f = liftIO . UTF8.writeFileWith eol f . T.unpack
802597
803−lookupHighlightStyle :: Maybe String -> IO (Maybe Style)
804−lookupHighlightStyle Nothing = return Nothing
805−lookupHighlightStyle (Just s)
806− | takeExtension s == ".theme" = -- attempt to load KDE theme
807− do contents <- B.readFile s
808− case parseTheme contents of
809− Left _ -> E.throwIO $ PandocOptionError $
810− "Could not read highlighting theme " ++ s
811− Right sty -> return (Just sty)
812− | otherwise =
813− case lookup (map toLower s) highlightingStyles of
814− Just sty -> return (Just sty)
815− Nothing -> E.throwIO $ PandocOptionError $
816− "Unknown highlight-style " ++ s
817−
818−-- | A list of functions, each transforming the options data structure
819−-- in response to a command-line option.
820−options :: [OptDescr (Opt -> IO Opt)]
821−options =
822− [ Option "fr" ["from","read"]
823− (ReqArg
824− (\arg opt -> return opt { optReader =
825− Just (map toLower arg) })
826− "FORMAT")
827− ""
828−
829− , Option "tw" ["to","write"]
830− (ReqArg
831− (\arg opt -> return opt { optWriter = Just arg })
832− "FORMAT")
833− ""
834−
835− , Option "o" ["output"]
836− (ReqArg
837− (\arg opt -> return opt { optOutputFile = Just arg })
838− "FILE")
839− "" -- "Name of output file"
840−
841− , Option "" ["data-dir"]
842− (ReqArg
843− (\arg opt -> return opt { optDataDir = Just arg })
844− "DIRECTORY") -- "Directory containing pandoc data files."
845− ""
846−
847− , Option "" ["base-header-level"]
848− (ReqArg
849− (\arg opt ->
850− case safeRead arg of
851− Just t | t > 0 && t < 6 ->
852− return opt{ optBaseHeaderLevel = t }
853− _ -> E.throwIO $ PandocOptionError
854− "base-header-level must be 1-5")
855− "NUMBER")
856− "" -- "Headers base level"
857−
858− , Option "" ["strip-empty-paragraphs"]
859− (NoArg
860− (\opt -> do
861− deprecatedOption "--stripEmptyParagraphs"
862− "Use +empty_paragraphs extension."
863− return opt{ optStripEmptyParagraphs = True }))
864− "" -- "Strip empty paragraphs"
865−
866− , Option "" ["indented-code-classes"]
867− (ReqArg
868− (\arg opt -> return opt { optIndentedCodeClasses = words $
869− map (\c -> if c == ',' then ' ' else c) arg })
870− "STRING")
871− "" -- "Classes (whitespace- or comma-separated) to use for indented code-blocks"
872−
873− , Option "F" ["filter"]
874− (ReqArg
875− (\arg opt -> return opt { optFilters =
876− JSONFilter arg : optFilters opt })
877− "PROGRAM")
878− "" -- "External JSON filter"
879−
880− , Option "" ["lua-filter"]
881− (ReqArg
882− (\arg opt -> return opt { optFilters =
883− LuaFilter arg : optFilters opt })
884− "SCRIPTPATH")
885− "" -- "Lua filter"
886−
887− , Option "p" ["preserve-tabs"]
888− (NoArg
889− (\opt -> return opt { optPreserveTabs = True }))
890− "" -- "Preserve tabs instead of converting to spaces"
891−
892− , Option "" ["tab-stop"]
893− (ReqArg
894− (\arg opt ->
895− case safeRead arg of
896− Just t | t > 0 -> return opt { optTabStop = t }
897− _ -> E.throwIO $ PandocOptionError
898− "tab-stop must be a number greater than 0")
899− "NUMBER")
900− "" -- "Tab stop (default 4)"
901−
902− , Option "" ["track-changes"]
903− (ReqArg
904− (\arg opt -> do
905− action <- case arg of
906− "accept" -> return AcceptChanges
907− "reject" -> return RejectChanges
908− "all" -> return AllChanges
909− _ -> E.throwIO $ PandocOptionError
910− ("Unknown option for track-changes: " ++ arg)
911− return opt { optTrackChanges = action })
912− "accept|reject|all")
913− "" -- "Accepting or reject MS Word track-changes.""
914−
915− , Option "" ["file-scope"]
916− (NoArg
917− (\opt -> return opt { optFileScope = True }))
918− "" -- "Parse input files before combining"
919−
920− , Option "" ["extract-media"]
921− (ReqArg
922− (\arg opt ->
923− return opt { optExtractMedia = Just arg })
924− "PATH")
925− "" -- "Directory to which to extract embedded media"
926−
927− , Option "s" ["standalone"]
928− (NoArg
929− (\opt -> return opt { optStandalone = True }))
930− "" -- "Include needed header and footer on output"
931−
932− , Option "" ["template"]
933− (ReqArg
934− (\arg opt ->
935− return opt{ optTemplate = Just arg,
936− optStandalone = True })
937− "FILE")
938− "" -- "Use custom template"
939−
940− , Option "M" ["metadata"]
941− (ReqArg
942− (\arg opt -> do
943− let (key, val) = splitField arg
944− return opt{ optMetadata = (key, val) : optMetadata opt })
945− "KEY[:VALUE]")
946− ""
947−
948− , Option "" ["metadata-file"]
949− (ReqArg
950− (\arg opt -> return opt{ optMetadataFile = Just arg })
951− "FILE")
952− ""
953−
954− , Option "V" ["variable"]
955− (ReqArg
956− (\arg opt -> do
957− let (key, val) = splitField arg
958− return opt{ optVariables = (key, val) : optVariables opt })
959− "KEY[:VALUE]")
960− ""
961−
962− , Option "D" ["print-default-template"]
963− (ReqArg
964− (\arg _ -> do
965− templ <- runIO $ do
966− setUserDataDir Nothing
967− getDefaultTemplate arg
968− case templ of
969− Right "" -> do -- e.g. for docx, odt, json:
970− E.throwIO $ PandocCouldNotFindDataFileError
971− ("templates/default." ++ arg)
972− Right t -> UTF8.hPutStr stdout t
973− Left e -> E.throwIO e
974− exitSuccess)
975− "FORMAT")
976− "" -- "Print default template for FORMAT"
977−
978− , Option "" ["print-default-data-file"]
979− (ReqArg
980− (\arg _ -> do
981− runIOorExplode $
982− readDefaultDataFile arg >>= liftIO . BS.hPutStr stdout
983− exitSuccess)
984− "FILE")
985− "" -- "Print default data file"
986−
987− , Option "" ["print-highlight-style"]
988− (ReqArg
989− (\arg _ -> do
990− sty <- fromMaybe pygments <$>
991− lookupHighlightStyle (Just arg)
992− B.putStr $ encodePretty'
993− defConfig{confIndent = Spaces 4
994− ,confCompare = keyOrder
995− (map T.pack
996− ["text-color"
997− ,"background-color"
998− ,"line-number-color"
999− ,"line-number-background-color"
1000− ,"bold"
1001− ,"italic"
1002− ,"underline"
1003− ,"text-styles"])
1004− ,confNumFormat = Generic
1005− ,confTrailingNewline = True} sty
1006− exitSuccess)
1007− "STYLE|FILE")
1008− "" -- "Print default template for FORMAT"
1009−
1010− , Option "" ["dpi"]
1011− (ReqArg
1012− (\arg opt ->
1013− case safeRead arg of
1014− Just t | t > 0 -> return opt { optDpi = t }
1015− _ -> E.throwIO $ PandocOptionError
1016− "dpi must be a number greater than 0")
1017− "NUMBER")
1018− "" -- "Dpi (default 96)"
1019−
1020− , Option "" ["eol"]
1021− (ReqArg
1022− (\arg opt ->
1023− case toLower <$> arg of
1024− "crlf" -> return opt { optEol = CRLF }
1025− "lf" -> return opt { optEol = LF }
1026− "native" -> return opt { optEol = Native }
1027− -- mac-syntax (cr) is not supported in ghc-base.
1028− _ -> E.throwIO $ PandocOptionError
1029− "--eol must be crlf, lf, or native")
1030− "crlf|lf|native")
1031− "" -- "EOL (default OS-dependent)"
1032−
1033− , Option "" ["wrap"]
1034− (ReqArg
1035− (\arg opt ->
1036− case safeRead ("Wrap" ++ uppercaseFirstLetter arg) of
1037− Just o -> return opt { optWrapText = o }
1038− Nothing -> E.throwIO $ PandocOptionError
1039− "--wrap must be auto, none, or preserve")
1040− "auto|none|preserve")
1041− "" -- "Option for wrapping text in output"
1042−
1043− , Option "" ["columns"]
1044− (ReqArg
1045− (\arg opt ->
1046− case safeRead arg of
1047− Just t | t > 0 -> return opt { optColumns = t }
1048− _ -> E.throwIO $ PandocOptionError
1049− "columns must be a number greater than 0")
1050− "NUMBER")
1051− "" -- "Length of line in characters"
1052−
1053− , Option "" ["strip-comments"]
1054− (NoArg
1055− (\opt -> return opt { optStripComments = True }))
1056− "" -- "Strip HTML comments"
1057−
1058− , Option "" ["toc", "table-of-contents"]
1059− (NoArg
1060− (\opt -> return opt { optTableOfContents = True }))
1061− "" -- "Include table of contents"
1062−
1063− , Option "" ["toc-depth"]
1064− (ReqArg
1065− (\arg opt ->
1066− case safeRead arg of
1067− Just t | t >= 1 && t <= 6 ->
1068− return opt { optTOCDepth = t }
1069− _ -> E.throwIO $ PandocOptionError
1070− "TOC level must be a number between 1 and 6")
1071− "NUMBER")
1072− "" -- "Number of levels to include in TOC"
1073−
1074− , Option "" ["no-highlight"]
1075− (NoArg
1076− (\opt -> return opt { optHighlightStyle = Nothing }))
1077− "" -- "Don't highlight source code"
1078−
1079− , Option "" ["highlight-style"]
1080− (ReqArg
1081− (\arg opt -> return opt{ optHighlightStyle = Just arg })
1082− "STYLE|FILE")
1083− "" -- "Style for highlighted code"
1084−
1085− , Option "" ["syntax-definition"]
1086− (ReqArg
1087− (\arg opt -> do
1088− let tr c d = map (\x -> if x == c then d else x)
1089− let arg' = case arg of -- see #4836
1090− -- HXT confuses Windows path with URI
1091− _:':':'\\':_ ->
1092− "file:///" ++ tr '\\' '/' arg
1093− _ -> arg
1094− return opt{ optSyntaxDefinitions = arg' :
1095− optSyntaxDefinitions opt })
1096− "FILE")
1097− "" -- "Syntax definition (xml) file"
1098−
1099− , Option "H" ["include-in-header"]
1100− (ReqArg
1101− (\arg opt -> return opt{ optIncludeInHeader =
1102− arg : optIncludeInHeader opt,
1103− optStandalone = True })
1104− "FILE")
1105− "" -- "File to include at end of header (implies -s)"
1106−
1107− , Option "B" ["include-before-body"]
1108− (ReqArg
1109− (\arg opt -> return opt{ optIncludeBeforeBody =
1110− arg : optIncludeBeforeBody opt,
1111− optStandalone = True })
1112− "FILE")
1113− "" -- "File to include before document body"
1114−
1115− , Option "A" ["include-after-body"]
1116− (ReqArg
1117− (\arg opt -> return opt{ optIncludeAfterBody =
1118− arg : optIncludeAfterBody opt,
1119− optStandalone = True })
1120− "FILE")
1121− "" -- "File to include after document body"
1122−
1123− , Option "" ["resource-path"]
1124− (ReqArg
1125− (\arg opt -> return opt { optResourcePath =
1126− splitSearchPath arg })
1127− "SEARCHPATH")
1128− "" -- "Paths to search for images and other resources"
1129−
1130− , Option "" ["request-header"]
1131− (ReqArg
1132− (\arg opt -> do
1133− let (key, val) = splitField arg
1134− return opt{ optRequestHeaders =
1135− (key, val) : optRequestHeaders opt })
1136− "NAME:VALUE")
1137− ""
1138−
1139− , Option "" ["self-contained"]
1140− (NoArg
1141− (\opt -> return opt { optSelfContained = True,
1142− optStandalone = True }))
1143− "" -- "Make slide shows include all the needed js and css"
1144−
1145− , Option "" ["html-q-tags"]
1146− (NoArg
1147− (\opt ->
1148− return opt { optHtmlQTags = True }))
1149− "" -- "Use <q> tags for quotes in HTML"
1150−
1151− , Option "" ["ascii"]
1152− (NoArg
1153− (\opt -> return opt { optAscii = True }))
1154− "" -- "Prefer ASCII output"
1155−
1156− , Option "" ["reference-links"]
1157− (NoArg
1158− (\opt -> return opt { optReferenceLinks = True } ))
1159− "" -- "Use reference links in parsing HTML"
1160−
1161− , Option "" ["reference-location"]
1162− (ReqArg
1163− (\arg opt -> do
1164− action <- case arg of
1165− "block" -> return EndOfBlock
1166− "section" -> return EndOfSection
1167− "document" -> return EndOfDocument
1168− _ -> E.throwIO $ PandocOptionError
1169− ("Unknown option for reference-location: " ++ arg)
1170− return opt { optReferenceLocation = action })
1171− "block|section|document")
1172− "" -- "Accepting or reject MS Word track-changes.""
1173−
1174− , Option "" ["atx-headers"]
1175− (NoArg
1176− (\opt -> return opt { optSetextHeaders = False } ))
1177− "" -- "Use atx-style headers for markdown"
1178−
1179− , Option "" ["top-level-division"]
1180− (ReqArg
1181− (\arg opt -> do
1182− let tldName = "TopLevel" ++ uppercaseFirstLetter arg
1183− case safeRead tldName of
1184− Just tlDiv -> return opt { optTopLevelDivision = tlDiv }
1185− _ -> E.throwIO $ PandocOptionError
1186− ("Top-level division must be " ++
1187− "section, chapter, part, or default"))
1188− "section|chapter|part")
1189− "" -- "Use top-level division type in LaTeX, ConTeXt, DocBook"
1190−
1191− , Option "N" ["number-sections"]
1192− (NoArg
1193− (\opt -> return opt { optNumberSections = True }))
1194− "" -- "Number sections in LaTeX"
1195−
1196− , Option "" ["number-offset"]
1197− (ReqArg
1198− (\arg opt ->
1199− case safeRead ('[':arg ++ "]") of
1200− Just ns -> return opt { optNumberOffset = ns,
1201− optNumberSections = True }
1202− _ -> E.throwIO $ PandocOptionError
1203− "could not parse number-offset")
1204− "NUMBERS")
1205− "" -- "Starting number for sections, subsections, etc."
1206−
1207− , Option "" ["listings"]
1208− (NoArg
1209− (\opt -> return opt { optListings = True }))
1210− "" -- "Use listings package for LaTeX code blocks"
1211−
1212− , Option "i" ["incremental"]
1213− (NoArg
1214− (\opt -> return opt { optIncremental = True }))
1215− "" -- "Make list items display incrementally in Slidy/Slideous/S5"
1216−
1217− , Option "" ["slide-level"]
1218− (ReqArg
1219− (\arg opt ->
1220− case safeRead arg of
1221− Just t | t >= 1 && t <= 6 ->
1222− return opt { optSlideLevel = Just t }
1223− _ -> E.throwIO $ PandocOptionError
1224− "slide level must be a number between 1 and 6")
1225− "NUMBER")
1226− "" -- "Force header level for slides"
1227−
1228− , Option "" ["section-divs"]
1229− (NoArg
1230− (\opt -> return opt { optSectionDivs = True }))
1231− "" -- "Put sections in div tags in HTML"
1232−
1233− , Option "" ["default-image-extension"]
1234− (ReqArg
1235− (\arg opt -> return opt { optDefaultImageExtension = arg })
1236− "extension")
1237− "" -- "Default extension for extensionless images"
1238−
1239− , Option "" ["email-obfuscation"]
1240− (ReqArg
1241− (\arg opt -> do
1242− method <- case arg of
1243− "references" -> return ReferenceObfuscation
1244− "javascript" -> return JavascriptObfuscation
1245− "none" -> return NoObfuscation
1246− _ -> E.throwIO $ PandocOptionError
1247− ("Unknown obfuscation method: " ++ arg)
1248− return opt { optEmailObfuscation = method })
1249− "none|javascript|references")
1250− "" -- "Method for obfuscating email in HTML"
1251−
1252− , Option "" ["id-prefix"]
1253− (ReqArg
1254− (\arg opt -> return opt { optIdentifierPrefix = arg })
1255− "STRING")
1256− "" -- "Prefix to add to automatically generated HTML identifiers"
1257−
1258− , Option "T" ["title-prefix"]
1259− (ReqArg
1260− (\arg opt -> do
1261− let newvars = ("title-prefix", arg) : optVariables opt
1262− return opt { optVariables = newvars,
1263− optStandalone = True })
1264− "STRING")
1265− "" -- "String to prefix to HTML window title"
1266−
1267− , Option "c" ["css"]
1268− (ReqArg
1269− (\arg opt -> return opt{ optCss = arg : optCss opt })
1270− -- add new link to end, so it is included in proper order
1271− "URL")
1272− "" -- "Link to CSS style sheet"
1273−
1274− , Option "" ["reference-doc"]
1275− (ReqArg
1276− (\arg opt ->
1277− return opt { optReferenceDoc = Just arg })
1278− "FILE")
1279− "" -- "Path of custom reference doc"
1280−
1281− , Option "" ["epub-subdirectory"]
1282− (ReqArg
1283− (\arg opt ->
1284− return opt { optEpubSubdirectory = arg })
1285− "DIRNAME")
1286− "" -- "Name of subdirectory for epub content in OCF container"
1287−
1288− , Option "" ["epub-cover-image"]
1289− (ReqArg
1290− (\arg opt ->
1291− return opt { optVariables =
1292− ("epub-cover-image", arg) : optVariables opt })
1293− "FILE")
1294− "" -- "Path of epub cover image"
1295−
1296− , Option "" ["epub-metadata"]
1297− (ReqArg
1298− (\arg opt -> return opt { optEpubMetadata = Just arg })
1299− "FILE")
1300− "" -- "Path of epub metadata file"
1301−
1302− , Option "" ["epub-embed-font"]
1303− (ReqArg
1304− (\arg opt ->
1305− return opt{ optEpubFonts = arg : optEpubFonts opt })
1306− "FILE")
1307− "" -- "Directory of fonts to embed"
1308−
1309− , Option "" ["epub-chapter-level"]
1310− (ReqArg
1311− (\arg opt ->
1312− case safeRead arg of
1313− Just t | t >= 1 && t <= 6 ->
1314− return opt { optEpubChapterLevel = t }
1315− _ -> E.throwIO $ PandocOptionError
1316− "chapter level must be a number between 1 and 6")
1317− "NUMBER")
1318− "" -- "Header level at which to split chapters in EPUB"
1319−
1320− , Option "" ["pdf-engine"]
1321− (ReqArg
1322− (\arg opt -> do
1323− let b = takeBaseName arg
1324− if b `elem` pdfEngines
1325− then return opt { optPdfEngine = Just arg }
1326− else E.throwIO $ PandocOptionError $ "pdf-engine must be one of "
1327− ++ intercalate ", " pdfEngines)
1328− "PROGRAM")
1329− "" -- "Name of program to use in generating PDF"
1330−
1331− , Option "" ["pdf-engine-opt"]
1332− (ReqArg
1333− (\arg opt -> do
1334− let oldArgs = optPdfEngineArgs opt
1335− return opt { optPdfEngineArgs = oldArgs ++ [arg]})
1336− "STRING")
1337− "" -- "Flags to pass to the PDF-engine, all instances of this option are accumulated and used"
1338−
1339− , Option "" ["bibliography"]
1340− (ReqArg
1341− (\arg opt -> return opt{ optMetadata =
1342− ("bibliography", arg) : optMetadata opt })
1343− "FILE")
1344− ""
1345−
1346− , Option "" ["csl"]
1347− (ReqArg
1348− (\arg opt ->
1349− return opt{ optMetadata =
1350− ("csl", arg) : optMetadata opt })
1351− "FILE")
1352− ""
1353−
1354− , Option "" ["citation-abbreviations"]
1355− (ReqArg
1356− (\arg opt ->
1357− return opt{ optMetadata =
1358− ("citation-abbreviations", arg): optMetadata opt })
1359− "FILE")
1360− ""
1361−
1362− , Option "" ["natbib"]
1363− (NoArg
1364− (\opt -> return opt { optCiteMethod = Natbib }))
1365− "" -- "Use natbib cite commands in LaTeX output"
1366−
1367− , Option "" ["biblatex"]
1368− (NoArg
1369− (\opt -> return opt { optCiteMethod = Biblatex }))
1370− "" -- "Use biblatex cite commands in LaTeX output"
1371−
1372− , Option "" ["mathml"]
1373− (NoArg
1374− (\opt ->
1375− return opt { optHTMLMathMethod = MathML }))
1376− "" -- "Use mathml for HTML math"
1377−
1378− , Option "" ["webtex"]
1379− (OptArg
1380− (\arg opt -> do
1381− let url' = fromMaybe "https://latex.codecogs.com/png.latex?" arg
1382− return opt { optHTMLMathMethod = WebTeX url' })
1383− "URL")
1384− "" -- "Use web service for HTML math"
1385−
1386− , Option "" ["mathjax"]
1387− (OptArg
1388− (\arg opt -> do
1389− let url' = fromMaybe (defaultMathJaxURL ++
1390− "MathJax.js?config=TeX-AMS_CHTML-full") arg
1391− return opt { optHTMLMathMethod = MathJax url'})
1392− "URL")
1393− "" -- "Use MathJax for HTML math"
1394−
1395− , Option "" ["katex"]
1396− (OptArg
1397− (\arg opt ->
1398− return opt
1399− { optHTMLMathMethod = KaTeX $
1400− fromMaybe defaultKaTeXURL arg })
1401− "URL")
1402− "" -- Use KaTeX for HTML Math
1403−
1404− , Option "" ["gladtex"]
1405− (NoArg
1406− (\opt ->
1407− return opt { optHTMLMathMethod = GladTeX }))
1408− "" -- "Use gladtex for HTML math"
1409−
1410− , Option "" ["abbreviations"]
1411− (ReqArg
1412− (\arg opt -> return opt { optAbbreviations = Just arg })
1413− "FILE")
1414− "" -- "Specify file for custom abbreviations"
1415−
1416− , Option "" ["trace"]
1417− (NoArg
1418− (\opt -> return opt { optTrace = True }))
1419− "" -- "Turn on diagnostic tracing in readers."
1420−
1421− , Option "" ["dump-args"]
1422− (NoArg
1423− (\opt -> return opt { optDumpArgs = True }))
1424− "" -- "Print output filename and arguments to stdout."
1425−
1426− , Option "" ["ignore-args"]
1427− (NoArg
1428− (\opt -> return opt { optIgnoreArgs = True }))
1429− "" -- "Ignore command-line arguments."
1430−
1431− , Option "" ["verbose"]
1432− (NoArg
1433− (\opt -> return opt { optVerbosity = INFO }))
1434− "" -- "Verbose diagnostic output."
1435−
1436− , Option "" ["quiet"]
1437− (NoArg
1438− (\opt -> return opt { optVerbosity = ERROR }))
1439− "" -- "Suppress warnings."
1440−
1441− , Option "" ["fail-if-warnings"]
1442− (NoArg
1443− (\opt -> return opt { optFailIfWarnings = True }))
1444− "" -- "Exit with error status if there were warnings."
1445−
1446− , Option "" ["log"]
1447− (ReqArg
1448− (\arg opt -> return opt{ optLogFile = Just arg })
1449− "FILE")
1450− "" -- "Log messages in JSON format to this file."
1451−
1452− , Option "" ["bash-completion"]
1453− (NoArg
1454− (\_ -> do
1455− datafiles <- getDataFileNames
1456− tpl <- runIOorExplode $
1457− UTF8.toString <$>
1458− readDefaultDataFile "bash_completion.tpl"
1459− let optnames (Option shorts longs _ _) =
1460− map (\c -> ['-',c]) shorts ++
1461− map ("--" ++) longs
1462− let allopts = unwords (concatMap optnames options)
1463− UTF8.hPutStrLn stdout $ printf tpl allopts
1464− (unwords readersNames)
1465− (unwords writersNames)
1466− (unwords $ map fst highlightingStyles)
1467− (unwords datafiles)
1468− exitSuccess ))
1469− "" -- "Print bash completion script"
1470−
1471− , Option "" ["list-input-formats"]
1472− (NoArg
1473− (\_ -> do
1474− mapM_ (UTF8.hPutStrLn stdout) readersNames
1475− exitSuccess ))
1476− ""
1477−
1478− , Option "" ["list-output-formats"]
1479− (NoArg
1480− (\_ -> do
1481− mapM_ (UTF8.hPutStrLn stdout) writersNames
1482− exitSuccess ))
1483− ""
1484−
1485− , Option "" ["list-extensions"]
1486− (OptArg
1487− (\arg _ -> do
1488− let exts = getDefaultExtensions (fromMaybe "markdown" arg)
1489− let showExt x = (if extensionEnabled x exts
1490− then '+'
1491− else '-') : drop 4 (show x)
1492− mapM_ (UTF8.hPutStrLn stdout . showExt)
1493− ([minBound..maxBound] :: [Extension])
1494− exitSuccess )
1495− "FORMAT")
1496− ""
1497−
1498− , Option "" ["list-highlight-languages"]
1499− (NoArg
1500− (\_ -> do
1501− let langs = [ T.unpack (T.toLower (sShortname s))
1502− | s <- M.elems defaultSyntaxMap
1503− , sShortname s `notElem`
1504− [T.pack "Alert", T.pack "Alert_indent"]
1505− ]
1506− mapM_ (UTF8.hPutStrLn stdout) langs
1507− exitSuccess ))
1508− ""
1509−
1510− , Option "" ["list-highlight-styles"]
1511− (NoArg
1512− (\_ -> do
1513− mapM_ (UTF8.hPutStrLn stdout . fst) highlightingStyles
1514− exitSuccess ))
1515− ""
1516−
1517− , Option "v" ["version"]
1518− (NoArg
1519− (\_ -> do
1520− prg <- getProgName
1521− defaultDatadir <- E.catch
1522− (getAppUserDataDirectory "pandoc")
1523− (\e -> let _ = (e :: E.SomeException)
1524− in return "")
1525− UTF8.hPutStrLn stdout (prg ++ " " ++ pandocVersion ++
1526− compileInfo ++ "\nDefault user data directory: " ++
1527− defaultDatadir ++ copyrightMessage)
1528− exitSuccess ))
1529− "" -- "Print version"
1530−
1531− , Option "h" ["help"]
1532− (NoArg
1533− (\_ -> do
1534− prg <- getProgName
1535− UTF8.hPutStr stdout (usageMessage prg options)
1536− exitSuccess ))
1537− "" -- "Show help"
1538−
1539− ]
1540−
1541−getDataFileNames :: IO [FilePath]
1542−getDataFileNames = do
1543−#ifdef EMBED_DATA_FILES
1544− let allDataFiles = map fst dataFiles
1545−#else
1546− allDataFiles <- filter (\x -> x /= "." && x /= "..") <$>
1547− (getDataDir >>= getDirectoryContents)
1548−#endif
1549− return $ "reference.docx" : "reference.odt" : "reference.pptx" : allDataFiles
1550−
1551−-- Returns usage message
1552−usageMessage :: String -> [OptDescr (Opt -> IO Opt)] -> String
1553−usageMessage programName = usageInfo (programName ++ " [OPTIONS] [FILES]")
1554−
1555−copyrightMessage :: String
1556−copyrightMessage = intercalate "\n" [
1557− "",
1558− "Copyright (C) 2006-2018 John MacFarlane",
1559− "Web: http://pandoc.org",
1560− "This is free software; see the source for copying conditions.",
1561− "There is no warranty, not even for merchantability or fitness",
1562− "for a particular purpose." ]
1563−
1564−compileInfo :: String
1565−compileInfo =
1566− "\nCompiled with pandoc-types " ++ VERSION_pandoc_types ++ ", texmath " ++
1567− VERSION_texmath ++ ", skylighting " ++ VERSION_skylighting
1568−
1569−handleUnrecognizedOption :: String -> [String] -> [String]
1570−handleUnrecognizedOption "--smart" =
1571− (("--smart/-S has been removed. Use +smart or -smart extension instead.\n" ++
1572− "For example: pandoc -f markdown+smart -t markdown-smart.") :)
1573−handleUnrecognizedOption "--normalize" =
1574− ("--normalize has been removed. Normalization is now automatic." :)
1575−handleUnrecognizedOption "-S" = handleUnrecognizedOption "--smart"
1576−handleUnrecognizedOption "--old-dashes" =
1577− ("--old-dashes has been removed. Use +old_dashes extension instead." :)
1578−handleUnrecognizedOption "--no-wrap" =
1579− ("--no-wrap has been removed. Use --wrap=none instead." :)
1580−handleUnrecognizedOption "--latex-engine" =
1581− ("--latex-engine has been removed. Use --pdf-engine instead." :)
1582−handleUnrecognizedOption "--latex-engine-opt" =
1583− ("--latex-engine-opt has been removed. Use --pdf-engine-opt instead." :)
1584−handleUnrecognizedOption "--chapters" =
1585− ("--chapters has been removed. Use --top-level-division=chapter instead." :)
1586−handleUnrecognizedOption "--reference-docx" =
1587− ("--reference-docx has been removed. Use --reference-doc instead." :)
1588−handleUnrecognizedOption "--reference-odt" =
1589− ("--reference-odt has been removed. Use --reference-doc instead." :)
1590−handleUnrecognizedOption "--parse-raw" =
1591− ("--parse-raw/-R has been removed. Use +raw_html or +raw_tex extension.\n" :)
1592−handleUnrecognizedOption "--epub-stylesheet" =
1593− ("--epub-stylesheet has been removed. Use --css instead.\n" :)
1594−handleUnrecognizedOption "-R" = handleUnrecognizedOption "--parse-raw"
1595−handleUnrecognizedOption x =
1596− (("Unknown option " ++ x ++ ".") :)
1597−
1598−uppercaseFirstLetter :: String -> String
1599−uppercaseFirstLetter (c:cs) = toUpper c : cs
1600−uppercaseFirstLetter [] = []
1601−
1602−readersNames :: [String]
1603−readersNames = sort (map fst (readers :: [(String, Reader PandocIO)]))
1604−
1605−writersNames :: [String]
1606−writersNames = sort (map fst (writers :: [(String, Writer PandocIO)]))
1607−
1608−splitField :: String -> (String, String)
1609−splitField s =
1610− case break (`elem` ":=") s of
1611− (k,_:v) -> (k,v)
1612− (k,[]) -> (k,"true")
1613598
1614599baseWriterName :: String -> String
1615600baseWriterName = takeWhile (\c -> c /= '+' && c /= '-')
1616−
1617−deprecatedOption :: String -> String -> IO ()
1618−deprecatedOption o msg =
1619− runIO (report $ Deprecated o msg) >>=
1620− \r -> case r of
1621− Right () -> return ()
1622− Left e -> E.throwIO e
1623−
1624−-- see https://github.com/jgm/pandoc/pull/4083
1625−-- using generic deriving caused long compilation times
1626−$(deriveJSON defaultOptions ''LineEnding)
1627−$(deriveJSON defaultOptions ''Opt)
src/Text/Pandoc/App/CommandLineOptions.hsnew file+1091
@@ -0,0 +1,1091 @@
1+{-# LANGUAGE NoImplicitPrelude #-}
2+{-# LANGUAGE CPP #-}
3+{-# LANGUAGE DeriveGeneric #-}
4+{-# LANGUAGE ScopedTypeVariables #-}
5+{-# LANGUAGE TemplateHaskell #-}
6+{-# LANGUAGE TupleSections #-}
7+{-
8+Copyright (C) 2006-2018 John MacFarlane <jgm@berkeley.edu>
9+
10+This program is free software; you can redistribute it and/or modify
11+it under the terms of the GNU General Public License as published by
12+the Free Software Foundation; either version 2 of the License, or
13+(at your option) any later version.
14+
15+This program is distributed in the hope that it will be useful,
16+but WITHOUT ANY WARRANTY; without even the implied warranty of
17+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18+GNU General Public License for more details.
19+
20+You should have received a copy of the GNU General Public License
21+along with this program; if not, write to the Free Software
22+Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
23+-}
24+
25+{- |
26+ Module : Text.Pandoc.App.CommandLineOptions
27+ Copyright : Copyright (C) 2006-2018 John MacFarlane
28+ License : GNU GPL, version 2 or above
29+
30+ Maintainer : John MacFarlane <jgm@berkeley@edu>
31+ Stability : alpha
32+ Portability : portable
33+
34+Does a pandoc conversion based on command-line options.
35+-}
36+module Text.Pandoc.App.CommandLineOptions (
37+ Opt(..)
38+ , LineEnding (..)
39+ , defaultOpts
40+ , parseOptions
41+ , options
42+ , engines
43+ ) where
44+import Prelude
45+import Control.Monad
46+import Control.Monad.Trans
47+import Data.Aeson.Encode.Pretty (encodePretty', Config(..), keyOrder,
48+ defConfig, Indent(..), NumberFormat(..))
49+import Data.Aeson.TH (deriveJSON, defaultOptions)
50+import Data.Char (toLower, toUpper)
51+import Data.List (intercalate, sort)
52+import Data.Maybe (fromMaybe)
53+import GHC.Generics
54+import Skylighting (Style, Syntax (..), defaultSyntaxMap, parseTheme,
55+ pygments)
56+import System.Console.GetOpt
57+import System.Environment (getArgs, getProgName)
58+import System.Exit (exitSuccess)
59+import System.FilePath
60+import System.IO (stdout)
61+import Text.Pandoc
62+import Text.Pandoc.Filter (Filter (..))
63+import Text.Pandoc.Highlighting (highlightingStyles)
64+import Text.Pandoc.Writers.Math (defaultMathJaxURL, defaultKaTeXURL)
65+import Text.Pandoc.Shared (ordNub, safeRead)
66+import Text.Printf
67+
68+#ifdef EMBED_DATA_FILES
69+import Text.Pandoc.Data (dataFiles)
70+import System.Directory (getAppUserDataDirectory)
71+#else
72+import Paths_pandoc (getDataDir)
73+import System.Directory (getAppUserDataDirectory, getDirectoryContents)
74+#endif
75+
76+import qualified Control.Exception as E
77+import qualified Data.ByteString as BS
78+import qualified Data.ByteString.Lazy as B
79+import qualified Data.Map as M
80+import qualified Data.Text as T
81+import qualified Text.Pandoc.UTF8 as UTF8
82+
83+-- | The type of line-endings to be used when writing plain-text.
84+data LineEnding = LF | CRLF | Native deriving (Show, Generic)
85+
86+parseOptions :: [OptDescr (Opt -> IO Opt)] -> Opt -> IO Opt
87+parseOptions options' defaults = do
88+ rawArgs <- map UTF8.decodeArg <$> getArgs
89+ prg <- getProgName
90+
91+ let (actions, args, unrecognizedOpts, errors) =
92+ getOpt' Permute options' rawArgs
93+
94+ let unknownOptionErrors =
95+ foldr (handleUnrecognizedOption . takeWhile (/= '=')) []
96+ unrecognizedOpts
97+
98+ unless (null errors && null unknownOptionErrors) $
99+ E.throwIO $ PandocOptionError $
100+ concat errors ++ unlines unknownOptionErrors ++
101+ ("Try " ++ prg ++ " --help for more information.")
102+
103+ -- thread option data structure through all supplied option actions
104+ opts <- foldl (>>=) (return defaults) actions
105+ return (opts{ optInputFiles = args })
106+
107+latexEngines :: [String]
108+latexEngines = ["pdflatex", "lualatex", "xelatex"]
109+
110+htmlEngines :: [String]
111+htmlEngines = ["wkhtmltopdf", "weasyprint", "prince"]
112+
113+engines :: [(String, String)]
114+engines = map ("html",) htmlEngines ++
115+ map ("html5",) htmlEngines ++
116+ map ("latex",) latexEngines ++
117+ map ("beamer",) latexEngines ++
118+ [ ("ms", "pdfroff")
119+ , ("context", "context")
120+ ]
121+
122+pdfEngines :: [String]
123+pdfEngines = ordNub $ map snd engines
124+
125+
126+-- | Data structure for command line options.
127+data Opt = Opt
128+ { optTabStop :: Int -- ^ Number of spaces per tab
129+ , optPreserveTabs :: Bool -- ^ Preserve tabs instead of converting to spaces
130+ , optStandalone :: Bool -- ^ Include header, footer
131+ , optReader :: Maybe String -- ^ Reader format
132+ , optWriter :: Maybe String -- ^ Writer format
133+ , optTableOfContents :: Bool -- ^ Include table of contents
134+ , optBaseHeaderLevel :: Int -- ^ Base header level
135+ , optTemplate :: Maybe FilePath -- ^ Custom template
136+ , optVariables :: [(String,String)] -- ^ Template variables to set
137+ , optMetadata :: [(String, String)] -- ^ Metadata fields to set
138+ , optMetadataFile :: Maybe FilePath -- ^ Name of YAML metadata file
139+ , optOutputFile :: Maybe FilePath -- ^ Name of output file
140+ , optInputFiles :: [FilePath] -- ^ Names of input files
141+ , optNumberSections :: Bool -- ^ Number sections in LaTeX
142+ , optNumberOffset :: [Int] -- ^ Starting number for sections
143+ , optSectionDivs :: Bool -- ^ Put sections in div tags in HTML
144+ , optIncremental :: Bool -- ^ Use incremental lists in Slidy/Slideous/S5
145+ , optSelfContained :: Bool -- ^ Make HTML accessible offline
146+ , optHtmlQTags :: Bool -- ^ Use <q> tags in HTML
147+ , optHighlightStyle :: Maybe Style -- ^ Style to use for highlighted code
148+ , optSyntaxDefinitions :: [FilePath] -- ^ xml syntax defs to load
149+ , optTopLevelDivision :: TopLevelDivision -- ^ Type of the top-level divisions
150+ , optHTMLMathMethod :: HTMLMathMethod -- ^ Method to print HTML math
151+ , optAbbreviations :: Maybe FilePath -- ^ Path to abbrevs file
152+ , optReferenceDoc :: Maybe FilePath -- ^ Path of reference doc
153+ , optEpubSubdirectory :: String -- ^ EPUB subdir in OCF container
154+ , optEpubMetadata :: Maybe FilePath -- ^ EPUB metadata
155+ , optEpubFonts :: [FilePath] -- ^ EPUB fonts to embed
156+ , optEpubChapterLevel :: Int -- ^ Header level at which to split chapters
157+ , optEpubCoverImage :: Maybe FilePath -- ^ Cover image for epub
158+ , optTOCDepth :: Int -- ^ Number of levels to include in TOC
159+ , optDumpArgs :: Bool -- ^ Output command-line arguments
160+ , optIgnoreArgs :: Bool -- ^ Ignore command-line arguments
161+ , optVerbosity :: Verbosity -- ^ Verbosity of diagnostic output
162+ , optTrace :: Bool -- ^ Enable tracing
163+ , optLogFile :: Maybe FilePath -- ^ File to write JSON log output
164+ , optFailIfWarnings :: Bool -- ^ Fail on warnings
165+ , optReferenceLinks :: Bool -- ^ Use reference links in writing markdown, rst
166+ , optReferenceLocation :: ReferenceLocation -- ^ location for footnotes and link references in markdown output
167+ , optDpi :: Int -- ^ Dpi
168+ , optWrapText :: WrapOption -- ^ Options for wrapping text
169+ , optColumns :: Int -- ^ Line length in characters
170+ , optFilters :: [Filter] -- ^ Filters to apply
171+ , optEmailObfuscation :: ObfuscationMethod
172+ , optIdentifierPrefix :: String
173+ , optStripEmptyParagraphs :: Bool -- ^ Strip empty paragraphs
174+ , optIndentedCodeClasses :: [String] -- ^ Default classes for indented code blocks
175+ , optDataDir :: Maybe FilePath
176+ , optCiteMethod :: CiteMethod -- ^ Method to output cites
177+ , optListings :: Bool -- ^ Use listings package for code blocks
178+ , optPdfEngine :: Maybe String -- ^ Program to use for latex/html -> pdf
179+ , optPdfEngineArgs :: [String] -- ^ Flags to pass to the engine
180+ , optSlideLevel :: Maybe Int -- ^ Header level that creates slides
181+ , optSetextHeaders :: Bool -- ^ Use atx headers for markdown level 1-2
182+ , optAscii :: Bool -- ^ Prefer ascii output
183+ , optDefaultImageExtension :: String -- ^ Default image extension
184+ , optExtractMedia :: Maybe FilePath -- ^ Path to extract embedded media
185+ , optTrackChanges :: TrackChanges -- ^ Accept or reject MS Word track-changes.
186+ , optFileScope :: Bool -- ^ Parse input files before combining
187+ , optTitlePrefix :: Maybe String -- ^ Prefix for title
188+ , optCss :: [FilePath] -- ^ CSS files to link to
189+ , optIncludeBeforeBody :: [FilePath] -- ^ Files to include before
190+ , optIncludeAfterBody :: [FilePath] -- ^ Files to include after body
191+ , optIncludeInHeader :: [FilePath] -- ^ Files to include in header
192+ , optResourcePath :: [FilePath] -- ^ Path to search for images etc
193+ , optRequestHeaders :: [(String, String)] -- ^ Headers for HTTP requests
194+ , optEol :: LineEnding -- ^ Style of line-endings to use
195+ , optStripComments :: Bool -- ^ Skip HTML comments
196+ } deriving (Generic, Show)
197+
198+-- | Defaults for command-line options.
199+defaultOpts :: Opt
200+defaultOpts = Opt
201+ { optTabStop = 4
202+ , optPreserveTabs = False
203+ , optStandalone = False
204+ , optReader = Nothing
205+ , optWriter = Nothing
206+ , optTableOfContents = False
207+ , optBaseHeaderLevel = 1
208+ , optTemplate = Nothing
209+ , optVariables = []
210+ , optMetadata = []
211+ , optMetadataFile = Nothing
212+ , optOutputFile = Nothing
213+ , optInputFiles = []
214+ , optNumberSections = False
215+ , optNumberOffset = [0,0,0,0,0,0]
216+ , optSectionDivs = False
217+ , optIncremental = False
218+ , optSelfContained = False
219+ , optHtmlQTags = False
220+ , optHighlightStyle = Just pygments
221+ , optSyntaxDefinitions = []
222+ , optTopLevelDivision = TopLevelDefault
223+ , optHTMLMathMethod = PlainMath
224+ , optAbbreviations = Nothing
225+ , optReferenceDoc = Nothing
226+ , optEpubSubdirectory = "EPUB"
227+ , optEpubMetadata = Nothing
228+ , optEpubFonts = []
229+ , optEpubChapterLevel = 1
230+ , optEpubCoverImage = Nothing
231+ , optTOCDepth = 3
232+ , optDumpArgs = False
233+ , optIgnoreArgs = False
234+ , optVerbosity = WARNING
235+ , optTrace = False
236+ , optLogFile = Nothing
237+ , optFailIfWarnings = False
238+ , optReferenceLinks = False
239+ , optReferenceLocation = EndOfDocument
240+ , optDpi = 96
241+ , optWrapText = WrapAuto
242+ , optColumns = 72
243+ , optFilters = []
244+ , optEmailObfuscation = NoObfuscation
245+ , optIdentifierPrefix = ""
246+ , optStripEmptyParagraphs = False
247+ , optIndentedCodeClasses = []
248+ , optDataDir = Nothing
249+ , optCiteMethod = Citeproc
250+ , optListings = False
251+ , optPdfEngine = Nothing
252+ , optPdfEngineArgs = []
253+ , optSlideLevel = Nothing
254+ , optSetextHeaders = True
255+ , optAscii = False
256+ , optDefaultImageExtension = ""
257+ , optExtractMedia = Nothing
258+ , optTrackChanges = AcceptChanges
259+ , optFileScope = False
260+ , optTitlePrefix = Nothing
261+ , optCss = []
262+ , optIncludeBeforeBody = []
263+ , optIncludeAfterBody = []
264+ , optIncludeInHeader = []
265+ , optResourcePath = ["."]
266+ , optRequestHeaders = []
267+ , optEol = Native
268+ , optStripComments = False
269+ }
270+
271+lookupHighlightStyle :: Maybe String -> IO (Maybe Style)
272+lookupHighlightStyle Nothing = return Nothing
273+lookupHighlightStyle (Just s)
274+ | takeExtension s == ".theme" = -- attempt to load KDE theme
275+ do contents <- B.readFile s
276+ case parseTheme contents of
277+ Left _ -> E.throwIO $ PandocOptionError $
278+ "Could not read highlighting theme " ++ s
279+ Right sty -> return (Just sty)
280+ | otherwise =
281+ case lookup (map toLower s) highlightingStyles of
282+ Just sty -> return (Just sty)
283+ Nothing -> E.throwIO $ PandocOptionError $
284+ "Unknown highlight-style " ++ s
285+
286+-- | A list of functions, each transforming the options data structure
287+-- in response to a command-line option.
288+options :: [OptDescr (Opt -> IO Opt)]
289+options =
290+ [ Option "fr" ["from","read"]
291+ (ReqArg
292+ (\arg opt -> return opt { optReader =
293+ Just (map toLower arg) })
294+ "FORMAT")
295+ ""
296+
297+ , Option "tw" ["to","write"]
298+ (ReqArg
299+ (\arg opt -> return opt { optWriter = Just arg })
300+ "FORMAT")
301+ ""
302+
303+ , Option "o" ["output"]
304+ (ReqArg
305+ (\arg opt -> return opt { optOutputFile = Just arg })
306+ "FILE")
307+ "" -- "Name of output file"
308+
309+ , Option "" ["data-dir"]
310+ (ReqArg
311+ (\arg opt -> return opt { optDataDir = Just arg })
312+ "DIRECTORY") -- "Directory containing pandoc data files."
313+ ""
314+
315+ , Option "" ["base-header-level"]
316+ (ReqArg
317+ (\arg opt ->
318+ case safeRead arg of
319+ Just t | t > 0 && t < 6 ->
320+ return opt{ optBaseHeaderLevel = t }
321+ _ -> E.throwIO $ PandocOptionError
322+ "base-header-level must be 1-5")
323+ "NUMBER")
324+ "" -- "Headers base level"
325+
326+ , Option "" ["strip-empty-paragraphs"]
327+ (NoArg
328+ (\opt -> do
329+ deprecatedOption "--stripEmptyParagraphs"
330+ "Use +empty_paragraphs extension."
331+ return opt{ optStripEmptyParagraphs = True }))
332+ "" -- "Strip empty paragraphs"
333+
334+ , Option "" ["indented-code-classes"]
335+ (ReqArg
336+ (\arg opt -> return opt { optIndentedCodeClasses = words $
337+ map (\c -> if c == ',' then ' ' else c) arg })
338+ "STRING")
339+ "" -- "Classes (whitespace- or comma-separated) to use for indented code-blocks"
340+
341+ , Option "F" ["filter"]
342+ (ReqArg
343+ (\arg opt -> return opt { optFilters =
344+ JSONFilter arg : optFilters opt })
345+ "PROGRAM")
346+ "" -- "External JSON filter"
347+
348+ , Option "" ["lua-filter"]
349+ (ReqArg
350+ (\arg opt -> return opt { optFilters =
351+ LuaFilter arg : optFilters opt })
352+ "SCRIPTPATH")
353+ "" -- "Lua filter"
354+
355+ , Option "p" ["preserve-tabs"]
356+ (NoArg
357+ (\opt -> return opt { optPreserveTabs = True }))
358+ "" -- "Preserve tabs instead of converting to spaces"
359+
360+ , Option "" ["tab-stop"]
361+ (ReqArg
362+ (\arg opt ->
363+ case safeRead arg of
364+ Just t | t > 0 -> return opt { optTabStop = t }
365+ _ -> E.throwIO $ PandocOptionError
366+ "tab-stop must be a number greater than 0")
367+ "NUMBER")
368+ "" -- "Tab stop (default 4)"
369+
370+ , Option "" ["track-changes"]
371+ (ReqArg
372+ (\arg opt -> do
373+ action <- case arg of
374+ "accept" -> return AcceptChanges
375+ "reject" -> return RejectChanges
376+ "all" -> return AllChanges
377+ _ -> E.throwIO $ PandocOptionError
378+ ("Unknown option for track-changes: " ++ arg)
379+ return opt { optTrackChanges = action })
380+ "accept|reject|all")
381+ "" -- "Accepting or reject MS Word track-changes.""
382+
383+ , Option "" ["file-scope"]
384+ (NoArg
385+ (\opt -> return opt { optFileScope = True }))
386+ "" -- "Parse input files before combining"
387+
388+ , Option "" ["extract-media"]
389+ (ReqArg
390+ (\arg opt ->
391+ return opt { optExtractMedia = Just arg })
392+ "PATH")
393+ "" -- "Directory to which to extract embedded media"
394+
395+ , Option "s" ["standalone"]
396+ (NoArg
397+ (\opt -> return opt { optStandalone = True }))
398+ "" -- "Include needed header and footer on output"
399+
400+ , Option "" ["template"]
401+ (ReqArg
402+ (\arg opt ->
403+ return opt{ optTemplate = Just arg,
404+ optStandalone = True })
405+ "FILE")
406+ "" -- "Use custom template"
407+
408+ , Option "M" ["metadata"]
409+ (ReqArg
410+ (\arg opt -> do
411+ let (key, val) = splitField arg
412+ return opt{ optMetadata = (key, val) : optMetadata opt })
413+ "KEY[:VALUE]")
414+ ""
415+
416+ , Option "" ["metadata-file"]
417+ (ReqArg
418+ (\arg opt -> return opt{ optMetadataFile = Just arg })
419+ "FILE")
420+ ""
421+
422+ , Option "V" ["variable"]
423+ (ReqArg
424+ (\arg opt -> do
425+ let (key, val) = splitField arg
426+ return opt{ optVariables = (key, val) : optVariables opt })
427+ "KEY[:VALUE]")
428+ ""
429+
430+ , Option "D" ["print-default-template"]
431+ (ReqArg
432+ (\arg _ -> do
433+ templ <- runIO $ do
434+ setUserDataDir Nothing
435+ getDefaultTemplate arg
436+ case templ of
437+ Right "" -> -- e.g. for docx, odt, json:
438+ E.throwIO $ PandocCouldNotFindDataFileError
439+ ("templates/default." ++ arg)
440+ Right t -> UTF8.hPutStr stdout t
441+ Left e -> E.throwIO e
442+ exitSuccess)
443+ "FORMAT")
444+ "" -- "Print default template for FORMAT"
445+
446+ , Option "" ["print-default-data-file"]
447+ (ReqArg
448+ (\arg _ -> do
449+ runIOorExplode $
450+ readDefaultDataFile arg >>= liftIO . BS.hPutStr stdout
451+ exitSuccess)
452+ "FILE")
453+ "" -- "Print default data file"
454+
455+ , Option "" ["print-highlight-style"]
456+ (ReqArg
457+ (\arg _ -> do
458+ sty <- fromMaybe pygments <$> lookupHighlightStyle arg
459+ B.putStr $ encodePretty'
460+ defConfig{confIndent = Spaces 4
461+ ,confCompare = keyOrder
462+ (map T.pack
463+ ["text-color"
464+ ,"background-color"
465+ ,"line-number-color"
466+ ,"line-number-background-color"
467+ ,"bold"
468+ ,"italic"
469+ ,"underline"
470+ ,"text-styles"])
471+ ,confNumFormat = Generic
472+ ,confTrailingNewline = True} sty
473+ exitSuccess)
474+ "STYLE|FILE")
475+ "" -- "Print default template for FORMAT"
476+
477+ , Option "" ["dpi"]
478+ (ReqArg
479+ (\arg opt ->
480+ case safeRead arg of
481+ Just t | t > 0 -> return opt { optDpi = t }
482+ _ -> E.throwIO $ PandocOptionError
483+ "dpi must be a number greater than 0")
484+ "NUMBER")
485+ "" -- "Dpi (default 96)"
486+
487+ , Option "" ["eol"]
488+ (ReqArg
489+ (\arg opt ->
490+ case toLower <$> arg of
491+ "crlf" -> return opt { optEol = CRLF }
492+ "lf" -> return opt { optEol = LF }
493+ "native" -> return opt { optEol = Native }
494+ -- mac-syntax (cr) is not supported in ghc-base.
495+ _ -> E.throwIO $ PandocOptionError
496+ "--eol must be crlf, lf, or native")
497+ "crlf|lf|native")
498+ "" -- "EOL (default OS-dependent)"
499+
500+ , Option "" ["wrap"]
501+ (ReqArg
502+ (\arg opt ->
503+ case safeRead ("Wrap" ++ uppercaseFirstLetter arg) of
504+ Just o -> return opt { optWrapText = o }
505+ Nothing -> E.throwIO $ PandocOptionError
506+ "--wrap must be auto, none, or preserve")
507+ "auto|none|preserve")
508+ "" -- "Option for wrapping text in output"
509+
510+ , Option "" ["columns"]
511+ (ReqArg
512+ (\arg opt ->
513+ case safeRead arg of
514+ Just t | t > 0 -> return opt { optColumns = t }
515+ _ -> E.throwIO $ PandocOptionError
516+ "columns must be a number greater than 0")
517+ "NUMBER")
518+ "" -- "Length of line in characters"
519+
520+ , Option "" ["strip-comments"]
521+ (NoArg
522+ (\opt -> return opt { optStripComments = True }))
523+ "" -- "Strip HTML comments"
524+
525+ , Option "" ["toc", "table-of-contents"]
526+ (NoArg
527+ (\opt -> return opt { optTableOfContents = True }))
528+ "" -- "Include table of contents"
529+
530+ , Option "" ["toc-depth"]
531+ (ReqArg
532+ (\arg opt ->
533+ case safeRead arg of
534+ Just t | t >= 1 && t <= 6 ->
535+ return opt { optTOCDepth = t }
536+ _ -> E.throwIO $ PandocOptionError
537+ "TOC level must be a number between 1 and 6")
538+ "NUMBER")
539+ "" -- "Number of levels to include in TOC"
540+
541+ , Option "" ["no-highlight"]
542+ (NoArg
543+ (\opt -> return opt { optHighlightStyle = Nothing }))
544+ "" -- "Don't highlight source code"
545+
546+ , Option "" ["highlight-style"]
547+ (ReqArg
548+ (\arg opt -> lookupHighlightStyle arg >>= \style ->
549+ return opt{ optHighlightStyle = style })
550+ "STYLE|FILE")
551+ "" -- "Style for highlighted code"
552+
553+ , Option "" ["syntax-definition"]
554+ (ReqArg
555+ (\arg opt -> do
556+ let tr c d = map (\x -> if x == c then d else x)
557+ let arg' = case arg of -- see #4836
558+ -- HXT confuses Windows path with URI
559+ _:':':'\\':_ ->
560+ "file:///" ++ tr '\\' '/' arg
561+ _ -> arg
562+ return opt{ optSyntaxDefinitions = arg' :
563+ optSyntaxDefinitions opt })
564+ "FILE")
565+ "" -- "Syntax definition (xml) file"
566+
567+ , Option "H" ["include-in-header"]
568+ (ReqArg
569+ (\arg opt -> return opt{ optIncludeInHeader =
570+ arg : optIncludeInHeader opt,
571+ optStandalone = True })
572+ "FILE")
573+ "" -- "File to include at end of header (implies -s)"
574+
575+ , Option "B" ["include-before-body"]
576+ (ReqArg
577+ (\arg opt -> return opt{ optIncludeBeforeBody =
578+ arg : optIncludeBeforeBody opt,
579+ optStandalone = True })
580+ "FILE")
581+ "" -- "File to include before document body"
582+
583+ , Option "A" ["include-after-body"]
584+ (ReqArg
585+ (\arg opt -> return opt{ optIncludeAfterBody =
586+ arg : optIncludeAfterBody opt,
587+ optStandalone = True })
588+ "FILE")
589+ "" -- "File to include after document body"
590+
591+ , Option "" ["resource-path"]
592+ (ReqArg
593+ (\arg opt -> return opt { optResourcePath =
594+ splitSearchPath arg })
595+ "SEARCHPATH")
596+ "" -- "Paths to search for images and other resources"
597+
598+ , Option "" ["request-header"]
599+ (ReqArg
600+ (\arg opt -> do
601+ let (key, val) = splitField arg
602+ return opt{ optRequestHeaders =
603+ (key, val) : optRequestHeaders opt })
604+ "NAME:VALUE")
605+ ""
606+
607+ , Option "" ["self-contained"]
608+ (NoArg
609+ (\opt -> return opt { optSelfContained = True,
610+ optStandalone = True }))
611+ "" -- "Make slide shows include all the needed js and css"
612+
613+ , Option "" ["html-q-tags"]
614+ (NoArg
615+ (\opt ->
616+ return opt { optHtmlQTags = True }))
617+ "" -- "Use <q> tags for quotes in HTML"
618+
619+ , Option "" ["ascii"]
620+ (NoArg
621+ (\opt -> return opt { optAscii = True }))
622+ "" -- "Prefer ASCII output"
623+
624+ , Option "" ["reference-links"]
625+ (NoArg
626+ (\opt -> return opt { optReferenceLinks = True } ))
627+ "" -- "Use reference links in parsing HTML"
628+
629+ , Option "" ["reference-location"]
630+ (ReqArg
631+ (\arg opt -> do
632+ action <- case arg of
633+ "block" -> return EndOfBlock
634+ "section" -> return EndOfSection
635+ "document" -> return EndOfDocument
636+ _ -> E.throwIO $ PandocOptionError
637+ ("Unknown option for reference-location: " ++ arg)
638+ return opt { optReferenceLocation = action })
639+ "block|section|document")
640+ "" -- "Accepting or reject MS Word track-changes.""
641+
642+ , Option "" ["atx-headers"]
643+ (NoArg
644+ (\opt -> return opt { optSetextHeaders = False } ))
645+ "" -- "Use atx-style headers for markdown"
646+
647+ , Option "" ["top-level-division"]
648+ (ReqArg
649+ (\arg opt -> do
650+ let tldName = "TopLevel" ++ uppercaseFirstLetter arg
651+ case safeRead tldName of
652+ Just tlDiv -> return opt { optTopLevelDivision = tlDiv }
653+ _ -> E.throwIO $ PandocOptionError
654+ ("Top-level division must be " ++
655+ "section, chapter, part, or default"))
656+ "section|chapter|part")
657+ "" -- "Use top-level division type in LaTeX, ConTeXt, DocBook"
658+
659+ , Option "N" ["number-sections"]
660+ (NoArg
661+ (\opt -> return opt { optNumberSections = True }))
662+ "" -- "Number sections in LaTeX"
663+
664+ , Option "" ["number-offset"]
665+ (ReqArg
666+ (\arg opt ->
667+ case safeRead ('[':arg ++ "]") of
668+ Just ns -> return opt { optNumberOffset = ns,
669+ optNumberSections = True }
670+ _ -> E.throwIO $ PandocOptionError
671+ "could not parse number-offset")
672+ "NUMBERS")
673+ "" -- "Starting number for sections, subsections, etc."
674+
675+ , Option "" ["listings"]
676+ (NoArg
677+ (\opt -> return opt { optListings = True }))
678+ "" -- "Use listings package for LaTeX code blocks"
679+
680+ , Option "i" ["incremental"]
681+ (NoArg
682+ (\opt -> return opt { optIncremental = True }))
683+ "" -- "Make list items display incrementally in Slidy/Slideous/S5"
684+
685+ , Option "" ["slide-level"]
686+ (ReqArg
687+ (\arg opt ->
688+ case safeRead arg of
689+ Just t | t >= 1 && t <= 6 ->
690+ return opt { optSlideLevel = Just t }
691+ _ -> E.throwIO $ PandocOptionError
692+ "slide level must be a number between 1 and 6")
693+ "NUMBER")
694+ "" -- "Force header level for slides"
695+
696+ , Option "" ["section-divs"]
697+ (NoArg
698+ (\opt -> return opt { optSectionDivs = True }))
699+ "" -- "Put sections in div tags in HTML"
700+
701+ , Option "" ["default-image-extension"]
702+ (ReqArg
703+ (\arg opt -> return opt { optDefaultImageExtension = arg })
704+ "extension")
705+ "" -- "Default extension for extensionless images"
706+
707+ , Option "" ["email-obfuscation"]
708+ (ReqArg
709+ (\arg opt -> do
710+ method <- case arg of
711+ "references" -> return ReferenceObfuscation
712+ "javascript" -> return JavascriptObfuscation
713+ "none" -> return NoObfuscation
714+ _ -> E.throwIO $ PandocOptionError
715+ ("Unknown obfuscation method: " ++ arg)
716+ return opt { optEmailObfuscation = method })
717+ "none|javascript|references")
718+ "" -- "Method for obfuscating email in HTML"
719+
720+ , Option "" ["id-prefix"]
721+ (ReqArg
722+ (\arg opt -> return opt { optIdentifierPrefix = arg })
723+ "STRING")
724+ "" -- "Prefix to add to automatically generated HTML identifiers"
725+
726+ , Option "T" ["title-prefix"]
727+ (ReqArg
728+ (\arg opt -> do
729+ let newvars = ("title-prefix", arg) : optVariables opt
730+ return opt { optVariables = newvars,
731+ optStandalone = True })
732+ "STRING")
733+ "" -- "String to prefix to HTML window title"
734+
735+ , Option "c" ["css"]
736+ (ReqArg
737+ (\arg opt -> return opt{ optCss = arg : optCss opt })
738+ -- add new link to end, so it is included in proper order
739+ "URL")
740+ "" -- "Link to CSS style sheet"
741+
742+ , Option "" ["reference-doc"]
743+ (ReqArg
744+ (\arg opt ->
745+ return opt { optReferenceDoc = Just arg })
746+ "FILE")
747+ "" -- "Path of custom reference doc"
748+
749+ , Option "" ["epub-subdirectory"]
750+ (ReqArg
751+ (\arg opt ->
752+ return opt { optEpubSubdirectory = arg })
753+ "DIRNAME")
754+ "" -- "Name of subdirectory for epub content in OCF container"
755+
756+ , Option "" ["epub-cover-image"]
757+ (ReqArg
758+ (\arg opt ->
759+ return opt { optVariables =
760+ ("epub-cover-image", arg) : optVariables opt })
761+ "FILE")
762+ "" -- "Path of epub cover image"
763+
764+ , Option "" ["epub-metadata"]
765+ (ReqArg
766+ (\arg opt -> return opt { optEpubMetadata = Just arg })
767+ "FILE")
768+ "" -- "Path of epub metadata file"
769+
770+ , Option "" ["epub-embed-font"]
771+ (ReqArg
772+ (\arg opt ->
773+ return opt{ optEpubFonts = arg : optEpubFonts opt })
774+ "FILE")
775+ "" -- "Directory of fonts to embed"
776+
777+ , Option "" ["epub-chapter-level"]
778+ (ReqArg
779+ (\arg opt ->
780+ case safeRead arg of
781+ Just t | t >= 1 && t <= 6 ->
782+ return opt { optEpubChapterLevel = t }
783+ _ -> E.throwIO $ PandocOptionError
784+ "chapter level must be a number between 1 and 6")
785+ "NUMBER")
786+ "" -- "Header level at which to split chapters in EPUB"
787+
788+ , Option "" ["pdf-engine"]
789+ (ReqArg
790+ (\arg opt -> do
791+ let b = takeBaseName arg
792+ if b `elem` pdfEngines
793+ then return opt { optPdfEngine = Just arg }
794+ else E.throwIO $ PandocOptionError $ "pdf-engine must be one of "
795+ ++ intercalate ", " pdfEngines)
796+ "PROGRAM")
797+ "" -- "Name of program to use in generating PDF"
798+
799+ , Option "" ["pdf-engine-opt"]
800+ (ReqArg
801+ (\arg opt -> do
802+ let oldArgs = optPdfEngineArgs opt
803+ return opt { optPdfEngineArgs = oldArgs ++ [arg]})
804+ "STRING")
805+ "" -- "Flags to pass to the PDF-engine, all instances of this option are accumulated and used"
806+
807+ , Option "" ["bibliography"]
808+ (ReqArg
809+ (\arg opt -> return opt{ optMetadata =
810+ ("bibliography", arg) : optMetadata opt })
811+ "FILE")
812+ ""
813+
814+ , Option "" ["csl"]
815+ (ReqArg
816+ (\arg opt ->
817+ return opt{ optMetadata =
818+ ("csl", arg) : optMetadata opt })
819+ "FILE")
820+ ""
821+
822+ , Option "" ["citation-abbreviations"]
823+ (ReqArg
824+ (\arg opt ->
825+ return opt{ optMetadata =
826+ ("citation-abbreviations", arg): optMetadata opt })
827+ "FILE")
828+ ""
829+
830+ , Option "" ["natbib"]
831+ (NoArg
832+ (\opt -> return opt { optCiteMethod = Natbib }))
833+ "" -- "Use natbib cite commands in LaTeX output"
834+
835+ , Option "" ["biblatex"]
836+ (NoArg
837+ (\opt -> return opt { optCiteMethod = Biblatex }))
838+ "" -- "Use biblatex cite commands in LaTeX output"
839+
840+ , Option "" ["mathml"]
841+ (NoArg
842+ (\opt ->
843+ return opt { optHTMLMathMethod = MathML }))
844+ "" -- "Use mathml for HTML math"
845+
846+ , Option "" ["webtex"]
847+ (OptArg
848+ (\arg opt -> do
849+ let url' = fromMaybe "https://latex.codecogs.com/png.latex?" arg
850+ return opt { optHTMLMathMethod = WebTeX url' })
851+ "URL")
852+ "" -- "Use web service for HTML math"
853+
854+ , Option "" ["mathjax"]
855+ (OptArg
856+ (\arg opt -> do
857+ let url' = fromMaybe (defaultMathJaxURL ++
858+ "MathJax.js?config=TeX-AMS_CHTML-full") arg
859+ return opt { optHTMLMathMethod = MathJax url'})
860+ "URL")
861+ "" -- "Use MathJax for HTML math"
862+
863+ , Option "" ["katex"]
864+ (OptArg
865+ (\arg opt ->
866+ return opt
867+ { optHTMLMathMethod = KaTeX $
868+ fromMaybe defaultKaTeXURL arg })
869+ "URL")
870+ "" -- Use KaTeX for HTML Math
871+
872+ , Option "" ["gladtex"]
873+ (NoArg
874+ (\opt ->
875+ return opt { optHTMLMathMethod = GladTeX }))
876+ "" -- "Use gladtex for HTML math"
877+
878+ , Option "" ["abbreviations"]
879+ (ReqArg
880+ (\arg opt -> return opt { optAbbreviations = Just arg })
881+ "FILE")
882+ "" -- "Specify file for custom abbreviations"
883+
884+ , Option "" ["trace"]
885+ (NoArg
886+ (\opt -> return opt { optTrace = True }))
887+ "" -- "Turn on diagnostic tracing in readers."
888+
889+ , Option "" ["dump-args"]
890+ (NoArg
891+ (\opt -> return opt { optDumpArgs = True }))
892+ "" -- "Print output filename and arguments to stdout."
893+
894+ , Option "" ["ignore-args"]
895+ (NoArg
896+ (\opt -> return opt { optIgnoreArgs = True }))
897+ "" -- "Ignore command-line arguments."
898+
899+ , Option "" ["verbose"]
900+ (NoArg
901+ (\opt -> return opt { optVerbosity = INFO }))
902+ "" -- "Verbose diagnostic output."
903+
904+ , Option "" ["quiet"]
905+ (NoArg
906+ (\opt -> return opt { optVerbosity = ERROR }))
907+ "" -- "Suppress warnings."
908+
909+ , Option "" ["fail-if-warnings"]
910+ (NoArg
911+ (\opt -> return opt { optFailIfWarnings = True }))
912+ "" -- "Exit with error status if there were warnings."
913+
914+ , Option "" ["log"]
915+ (ReqArg
916+ (\arg opt -> return opt{ optLogFile = Just arg })
917+ "FILE")
918+ "" -- "Log messages in JSON format to this file."
919+
920+ , Option "" ["bash-completion"]
921+ (NoArg
922+ (\_ -> do
923+ datafiles <- getDataFileNames
924+ tpl <- runIOorExplode $
925+ UTF8.toString <$>
926+ readDefaultDataFile "bash_completion.tpl"
927+ let optnames (Option shorts longs _ _) =
928+ map (\c -> ['-',c]) shorts ++
929+ map ("--" ++) longs
930+ let allopts = unwords (concatMap optnames options)
931+ UTF8.hPutStrLn stdout $ printf tpl allopts
932+ (unwords readersNames)
933+ (unwords writersNames)
934+ (unwords $ map fst highlightingStyles)
935+ (unwords datafiles)
936+ exitSuccess ))
937+ "" -- "Print bash completion script"
938+
939+ , Option "" ["list-input-formats"]
940+ (NoArg
941+ (\_ -> do
942+ mapM_ (UTF8.hPutStrLn stdout) readersNames
943+ exitSuccess ))
944+ ""
945+
946+ , Option "" ["list-output-formats"]
947+ (NoArg
948+ (\_ -> do
949+ mapM_ (UTF8.hPutStrLn stdout) writersNames
950+ exitSuccess ))
951+ ""
952+
953+ , Option "" ["list-extensions"]
954+ (OptArg
955+ (\arg _ -> do
956+ let exts = getDefaultExtensions (fromMaybe "markdown" arg)
957+ let showExt x = (if extensionEnabled x exts
958+ then '+'
959+ else '-') : drop 4 (show x)
960+ mapM_ (UTF8.hPutStrLn stdout . showExt)
961+ ([minBound..maxBound] :: [Extension])
962+ exitSuccess )
963+ "FORMAT")
964+ ""
965+
966+ , Option "" ["list-highlight-languages"]
967+ (NoArg
968+ (\_ -> do
969+ let langs = [ T.unpack (T.toLower (sShortname s))
970+ | s <- M.elems defaultSyntaxMap
971+ , sShortname s `notElem`
972+ [T.pack "Alert", T.pack "Alert_indent"]
973+ ]
974+ mapM_ (UTF8.hPutStrLn stdout) langs
975+ exitSuccess ))
976+ ""
977+
978+ , Option "" ["list-highlight-styles"]
979+ (NoArg
980+ (\_ -> do
981+ mapM_ (UTF8.hPutStrLn stdout . fst) highlightingStyles
982+ exitSuccess ))
983+ ""
984+
985+ , Option "v" ["version"]
986+ (NoArg
987+ (\_ -> do
988+ prg <- getProgName
989+ defaultDatadir <- E.catch
990+ (getAppUserDataDirectory "pandoc")
991+ (\e -> let _ = (e :: E.SomeException)
992+ in return "")
993+ UTF8.hPutStrLn stdout (prg ++ " " ++ pandocVersion ++
994+ compileInfo ++ "\nDefault user data directory: " ++
995+ defaultDatadir ++ copyrightMessage)
996+ exitSuccess ))
997+ "" -- "Print version"
998+
999+ , Option "h" ["help"]
1000+ (NoArg
1001+ (\_ -> do
1002+ prg <- getProgName
1003+ UTF8.hPutStr stdout (usageMessage prg options)
1004+ exitSuccess ))
1005+ "" -- "Show help"
1006+ ]
1007+
1008+getDataFileNames :: IO [FilePath]
1009+getDataFileNames = do
1010+#ifdef EMBED_DATA_FILES
1011+ let allDataFiles = map fst dataFiles
1012+#else
1013+ allDataFiles <- filter (\x -> x /= "." && x /= "..") <$>
1014+ (getDataDir >>= getDirectoryContents)
1015+#endif
1016+ return $ "reference.docx" : "reference.odt" : "reference.pptx" : allDataFiles
1017+
1018+-- Returns usage message
1019+usageMessage :: String -> [OptDescr (Opt -> IO Opt)] -> String
1020+usageMessage programName = usageInfo (programName ++ " [OPTIONS] [FILES]")
1021+
1022+copyrightMessage :: String
1023+copyrightMessage = intercalate "\n" [
1024+ "",
1025+ "Copyright (C) 2006-2018 John MacFarlane",
1026+ "Web: http://pandoc.org",
1027+ "This is free software; see the source for copying conditions.",
1028+ "There is no warranty, not even for merchantability or fitness",
1029+ "for a particular purpose." ]
1030+
1031+compileInfo :: String
1032+compileInfo =
1033+ "\nCompiled with pandoc-types " ++ VERSION_pandoc_types ++ ", texmath " ++
1034+ VERSION_texmath ++ ", skylighting " ++ VERSION_skylighting
1035+
1036+handleUnrecognizedOption :: String -> [String] -> [String]
1037+handleUnrecognizedOption "--smart" =
1038+ (("--smart/-S has been removed. Use +smart or -smart extension instead.\n" ++
1039+ "For example: pandoc -f markdown+smart -t markdown-smart.") :)
1040+handleUnrecognizedOption "--normalize" =
1041+ ("--normalize has been removed. Normalization is now automatic." :)
1042+handleUnrecognizedOption "-S" = handleUnrecognizedOption "--smart"
1043+handleUnrecognizedOption "--old-dashes" =
1044+ ("--old-dashes has been removed. Use +old_dashes extension instead." :)
1045+handleUnrecognizedOption "--no-wrap" =
1046+ ("--no-wrap has been removed. Use --wrap=none instead." :)
1047+handleUnrecognizedOption "--latex-engine" =
1048+ ("--latex-engine has been removed. Use --pdf-engine instead." :)
1049+handleUnrecognizedOption "--latex-engine-opt" =
1050+ ("--latex-engine-opt has been removed. Use --pdf-engine-opt instead." :)
1051+handleUnrecognizedOption "--chapters" =
1052+ ("--chapters has been removed. Use --top-level-division=chapter instead." :)
1053+handleUnrecognizedOption "--reference-docx" =
1054+ ("--reference-docx has been removed. Use --reference-doc instead." :)
1055+handleUnrecognizedOption "--reference-odt" =
1056+ ("--reference-odt has been removed. Use --reference-doc instead." :)
1057+handleUnrecognizedOption "--parse-raw" =
1058+ ("--parse-raw/-R has been removed. Use +raw_html or +raw_tex extension.\n" :)
1059+handleUnrecognizedOption "--epub-stylesheet" =
1060+ ("--epub-stylesheet has been removed. Use --css instead.\n" :)
1061+handleUnrecognizedOption "-R" = handleUnrecognizedOption "--parse-raw"
1062+handleUnrecognizedOption x =
1063+ (("Unknown option " ++ x ++ ".") :)
1064+
1065+uppercaseFirstLetter :: String -> String
1066+uppercaseFirstLetter (c:cs) = toUpper c : cs
1067+uppercaseFirstLetter [] = []
1068+
1069+readersNames :: [String]
1070+readersNames = sort (map fst (readers :: [(String, Reader PandocIO)]))
1071+
1072+writersNames :: [String]
1073+writersNames = sort (map fst (writers :: [(String, Writer PandocIO)]))
1074+
1075+splitField :: String -> (String, String)
1076+splitField s =
1077+ case break (`elem` ":=") s of
1078+ (k,_:v) -> (k,v)
1079+ (k,[]) -> (k,"true")
1080+
1081+deprecatedOption :: String -> String -> IO ()
1082+deprecatedOption o msg =
1083+ runIO (report $ Deprecated o msg) >>=
1084+ \r -> case r of
1085+ Right () -> return ()
1086+ Left e -> E.throwIO e
1087+
1088+-- see https://github.com/jgm/pandoc/pull/4083
1089+-- using generic deriving caused long compilation times
1090+$(deriveJSON defaultOptions ''LineEnding)
1091+$(deriveJSON defaultOptions ''Opt)