git.iko.soy/typeable/pandoc
on master help sign in
Revert "Revert "Added `--filter` option.""

This reverts commit 2e5edbb27837372f658b1abbe05371be57415847.

commit2677e8466311e2becdd7f65f1f6c23d559db14aa authorJohn MacFarlane <jgm@berkeley.edu> dateThu 8 Aug 2013, 11:09 (13 years ago) parent9aa9d5c
3 files changed+30−4
README+8 pandoc.cabal+1 pandoc.hs+21−4
README+8
@@ -259,6 +259,14 @@ Reader options
259259 require different kinds of images. Currently this option only affects
260260 the markdown and LaTeX readers.
261261
262+`--filter=`*PATH*
263+: Specify an executable to be used as a filter transforming the
264+ Pandoc AST after the input is parsed and before the output is
265+ written. The executable should read JSON from stdin and write
266+ JSON to stdout. The JSON must be formatted like pandoc's own
267+ JSON input and output. Filters may be most easily created in Haskell,
268+ using the utility function `toJsonFilter` from `Text.Pandoc`.
269+
262270`--normalize`
263271: Normalize the document after reading: merge adjacent
264272 `Str` or `Emph` elements, for example, and remove repeated `Space`s.
pandoc.cabal+1
@@ -352,6 +352,7 @@ Executable pandoc
352352 extensible-exceptions >= 0.1 && < 0.2,
353353 highlighting-kate >= 0.5.5 && < 0.6,
354354 HTTP >= 4000.0.5 && < 4000.3,
355+ process >= 1 && < 1.2,
355356 citeproc-hs >= 0.3.7 && < 0.4
356357 Ghc-Options: -rtsopts -with-rtsopts=-K16m -Wall -fno-warn-unused-do-bind
357358 Ghc-Prof-Options: -auto-all -caf-all -rtsopts -with-rtsopts=-K16m
pandoc.hs+21−4
@@ -43,6 +43,7 @@ import System.Environment ( getArgs, getProgName )
4343import System.Exit ( exitWith, ExitCode (..) )
4444import System.FilePath
4545import System.Console.GetOpt
46+import System.Process (readProcess)
4647import Data.Char ( toLower )
4748import Data.List ( intercalate, isPrefixOf, sort )
4849import System.Directory ( getAppUserDataDirectory, doesFileExist, findExecutable )
@@ -53,6 +54,7 @@ import Control.Exception.Extensible ( throwIO )
5354import qualified Text.Pandoc.UTF8 as UTF8
5455import qualified Text.CSL as CSL
5556import Control.Monad (when, unless, liftM)
57+import Data.Foldable (foldrM)
5658import Network.HTTP (simpleHTTP, mkRequest, getResponseBody, RequestMethod(..))
5759import Network.URI (parseURI, isURI, URI(..))
5860import qualified Data.ByteString.Lazy as B
@@ -86,6 +88,12 @@ wrapWords indent c = wrap' (c - indent) (c - indent)
8688isTextFormat :: String -> Bool
8789isTextFormat s = takeWhile (`notElem` "+-") s `notElem` ["odt","docx","epub","epub3"]
8890
91+externalFilter :: FilePath -> Pandoc -> IO Pandoc
92+externalFilter f d = E.catch
93+ (readJSON def `fmap` readProcess f [] (writeJSON def d))
94+ (\e -> let _ = (e :: E.SomeException)
95+ in err 83 $ "Error running filter `" ++ f ++ "'")
96+
8997-- | Data structure for command line options.
9098data Opt = Opt
9199 { optTabStop :: Int -- ^ Number of spaces per tab
@@ -272,6 +280,13 @@ options =
272280 "STRING")
273281 "" -- "Classes (whitespace- or comma-separated) to use for indented code-blocks"
274282
283+ , Option "" ["filter"]
284+ (ReqArg
285+ (\arg opt -> return opt { optPlugins = externalFilter arg :
286+ optPlugins opt })
287+ "PROGRAM")
288+ "" -- "External JSON filter"
289+
275290 , Option "" ["normalize"]
276291 (NoArg
277292 (\opt -> return opt { optTransforms =
@@ -876,6 +891,7 @@ main = do
876891 , optReferenceLinks = referenceLinks
877892 , optWrapText = wrap
878893 , optColumns = columns
894+ , optPlugins = plugins
879895 , optEmailObfuscation = obfuscationMethod
880896 , optIdentifierPrefix = idPrefix
881897 , optIndentedCodeClasses = codeBlockClasses
@@ -1099,6 +1115,7 @@ main = do
10991115 reader readerOpts
11001116
11011117 let doc0 = foldr ($) doc transforms
1118+ doc1 <- foldrM ($) doc0 plugins
11021119
11031120 let writeBinary :: B.ByteString -> IO ()
11041121 writeBinary = B.writeFile (UTF8.encodePath outputFile)
@@ -1109,15 +1126,15 @@ main = do
11091126
11101127 case getWriter writerName' of
11111128 Left e -> err 9 e
1112− Right (IOStringWriter f) -> f writerOptions doc0 >>= writerFn outputFile
1113− Right (IOByteStringWriter f) -> f writerOptions doc0 >>= writeBinary
1129+ Right (IOStringWriter f) -> f writerOptions doc1 >>= writerFn outputFile
1130+ Right (IOByteStringWriter f) -> f writerOptions doc1 >>= writeBinary
11141131 Right (PureStringWriter f)
11151132 | pdfOutput -> do
1116− res <- makePDF latexEngine f writerOptions doc0
1133+ res <- makePDF latexEngine f writerOptions doc1
11171134 case res of
11181135 Right pdf -> writeBinary pdf
11191136 Left err' -> err 43 $ UTF8.toStringLazy err'
1120− | otherwise -> selfcontain (f writerOptions doc0 ++
1137+ | otherwise -> selfcontain (f writerOptions doc1 ++
11211138 ['\n' | not standalone'])
11221139 >>= writerFn outputFile . handleEntities
11231140 where htmlFormat = writerName' `elem`