@@ -309,14 +309,6 @@ For further documentation, see the `pandoc(1)` man page.
309309 repeatedly to include multiple files. They will be included in the
310310 order specified.
311311
312−`-P` *MODULE[,MODULE...]*, `--plugins`*=MODULE[,MODULE...]*
313−: specifies plugins to load, by module name or source file pathname.
314− Plugins should export a function `transform` of type `a -> a`
315− or `a -> IO a`, where `a` is `Inline`, `Block`, `Pandoc`,
316− `[Inline]`, or `[Block]`. This function will be used to transform
317− the pandoc document after it is parsed by the reader and before it
318− is written out by the writer. (See below on [Plugins](#plugins).)
319−
320312`-T` or `--title-prefix` *string*
321313: includes *string* as a prefix at the beginning of the title that
322314 appears in the HTML header (but not in the title as it appears at
@@ -1124,212 +1116,3 @@ ordinary HTML (without bird tracks).
11241116writes HTML with the Haskell code in bird tracks, so it can be copied
11251117and pasted as literate Haskell source.
11261118
1127−Plugins
1128−=======
1129−
1130−Pandoc's plugin system allows users to modify pandoc's behavior by writing
1131−short Haskell programs. To how this works, and why it is useful, we
1132− need to understand that pandoc transforms one format (the source
1133−format) into another (the target format) by first converting from the
1134−source format into a Haskell data structure representing the document,
1135−and then converting this data structure into the target format. For
1136−example:
1137−
1138− -------------------------------------------------------------------------------
1139− Document Format Contents
1140− ------------ --------- -----------------------------------------------------
1141− source markdown `Hello *world*.`
1142−
1143− ↓ ↓ ↓
1144−
1145− intermediate native `Pandoc (Meta [] [] "")
1146− [Para [Str "Hello",Space,Emph [Str "world"],Str "."]]`
1147−
1148− ↓ ↓ ↓
1149−
1150− target HTML `<p>Hello <em>world</em>.</p>`
1151− -------------------------------------------------------------------------------
1152−
1153−We can use standard text-processing tools (`perl`, `sed`, `awk`, etc.)
1154−to modify the source or target documents. But what if we want to modify
1155−the intermediate representation -- the parsed document -- before it is
1156−written to the target format? That's where plugins are needed.
1157−A plugin is a Haskell module that exports a function `transform`, which
1158−will be used to transform the native representation, after it is generated
1159−by the reader, but before it has been transformed by the writer.
1160−
1161−An example will help make this clearer. Suppose we want to use pandoc with
1162−the WordPress blog engine. WordPress provides support for LaTeX math, but
1163−instead of `$e = mc^2$`, WordPress wants `$LaTeX e = mc^2$`. Prior to plugins,
1164−there was no good way to make pandoc do this. We could have tried using
1165−regex replacements on the markdown input or HTML output, but this would have
1166−been error-prone: if someone writes `$e = mc^2$` in a code block, for
1167−example, we wouldn't want to insert `LaTeX` there. There's no good way to
1168−identify the math chunks without parsing the whole document. And pandoc
1169−is already doing that, so why not make use of this work? By writing a
1170−plugin, we can. Here's the whole plugin:
1171−
1172−~~~ {.haskell}
1173−-- WordPressPlugin.hs
1174−module WordPressPlugin (transform) where
1175−import Text.Pandoc
1176−
1177−transform :: Inline -> Inline
1178−transform (Math x y) = Math x $ "LaTeX " ++ y
1179−transform x = x
1180−~~~
1181−
1182−This is a Haskell program, but a very short one. The lines
1183−
1184−~~~ {.haskell}
1185−module WordPressPlugin (transform) where
1186−import Text.Pandoc
1187−~~~
1188−
1189−just define the name of the module (`WordPressPlugin`), the names of any
1190−exported functions (for a plugin, this will always just be `transform`),
1191−and the modules that will be used in the program itself (`Text.Pandoc`).
1192−Every plugin must export a function named `transform`.
1193−
1194−The real meat of the program is the three-line definition of `transform`:
1195−
1196−~~~ {.haskell}
1197−transform :: Inline -> Inline
1198−transform (Math x y) = Math x $ "LaTeX " ++ y
1199−transform x = x
1200−~~~
1201−
1202−The first line defines the type of the function: it is a function that
1203−takes an `Inline` element and returns an `Inline` element. (For the definition
1204−of `Inline`, see the module `Text.Pandoc.Definition`.) The `transform`
1205−function in a plugin need not be `Inline -> Inline`, but it must have
1206−type `a -> a` or `a -> IO a`, where `a` is `Pandoc`, `Block`, `Inline`,
1207−`[Block]`, or `[Inline]`.
1208−
1209−The next line says that when the input matches the pattern `Math x y`,
1210−the string `LaTeX ` should be inserted at the beginning of `y`. (The `x`
1211−just specifies whether the math element is inline or display math, so
1212−we leave it alone.) The last line says, in effect, that the `transform`
1213−function has no effect on any other kind of `Inline` element -- it just
1214−passes it through. When the plugin is applied, this transformation will
1215−be used on every `Inline` element in the document, and `LaTeX ` will be
1216−inserted where needed in math elements.
1217−
1218−To use this plugin, we just specify the module (or alternatively the filename)
1219−with the `--plugins` option:
1220−
1221− % echo "Hello, $e=mc^2$." | pandoc -m --plugins=WordPressPlugin.hs
1222− <p
1223− >Hello, <span class="LaTeX"
1224− >$LaTeX e=mc^2$</span
1225− >.</p
1226− >
1227−
1228−Let's look at a more complex example, involving IO. Suppose we want to include
1229−some [graphviz](http://www.graphviz.org/) diagrams in our document.
1230−Of course, we could use a Makefile to generate the diagrams, then use
1231−regular images in our document. But wouldn't it be nicer just to include
1232−the graphviz code in the document itself, perhaps in a specially marked
1233−delimited code block?
1234−
1235− ~~~ {.dot name="diagram1"}
1236− graph G {
1237− e
1238− subgraph clusterA {
1239− a -- b;
1240− subgraph clusterC {
1241− C -- D;
1242− }
1243− }
1244− subgraph clusterB {
1245− d -- f
1246− }
1247− d -- D
1248− e -- clusterB
1249− clusterC -- clusterB
1250− }
1251− ~~~
1252−
1253−This can be accomplished by a plugin:
1254−
1255−~~~ {.haskell}
1256−-- DotPlugin.hs
1257−module DotPlugin (transform) where
1258−import Text.Pandoc
1259−import Text.Pandoc.Shared
1260−import System.Process (readProcess)
1261−import Data.Char (ord)
1262−-- from the utf8-string package on HackageDB:
1263−import Data.ByteString.Lazy.UTF8 (fromString)
1264−-- from the SHA package on HackageDB:
1265−import Data.Digest.Pure.SHA
1266−
1267−transform :: Block -> IO Block
1268−transform (CodeBlock (id, classes, namevals) contents) | "dot" `elem` classes = do
1269− let (name, outfile) = case lookup "name" namevals of
1270− Just fn -> ([Str fn], fn ++ ".png")
1271− Nothing -> ([], uniqueName contents ++ ".png")
1272− result <- readProcess "dot" ["-Tpng"] contents
1273− writeFile outfile result
1274− return $ Para [Image name (outfile, "")]
1275−transform x = return x
1276−
1277−-- | Generate a unique filename given the file's contents.
1278−uniqueName :: String -> String
1279−uniqueName = showDigest . sha1 . fromString
1280−~~~
1281−
1282−The heart of this plugin is the `transform` function, which converts a `Block`
1283−to a `Block`. Again, there are two clauses, one for code blocks that are marked
1284−with the "dot" class, one for all other blocks. Code blocks with ".dot" are
1285−replaced with links to an image file; this file is generated by running
1286−`dot -Tpng` on the contents of the code block.
1287−
1288−Because `transform` performs file reads and writes, it needs to be in the
1289−IO monad, hence the type: `Block -> IO Block`.
1290−
1291−One more example. Suppose we want emphasized text to be CAPITALIZED
1292−instead of italicized. We could use a plugin:
1293−
1294−~~~ {.haskell}
1295−module CapitalizeEmphasisPlugin (transform) where
1296−import Text.Pandoc
1297−import Data.Char (toUpper)
1298−
1299−transform :: [Inline] -> [Inline]
1300−transform (Emph xs : ys) = processWith capStr xs ++ transform ys
1301−transform (x : ys) = x : transform ys
1302−transform [] = []
1303−
1304−capStr :: Inline -> Inline
1305−capStr (Str x) = Str (map toUpper x)
1306−capStr x = x
1307−~~~
1308−
1309−Here `transform` converts a whole list of `Inline` elements to another
1310−such list. The key clause is
1311−
1312−~~~ {.haskell}
1313−transform (Emph xs : ys) = processWith capStr xs ++ transform ys
1314−~~~
1315−
1316−This applies the `capStr` function recursively to all inlines in the
1317−list of emphasized inlines and puts the transformed list in place
1318−of the original. `capStr` is a simple `Inline` transformation that
1319−capitalizes `Str` elements and leaves everything else alone. The
1320−function `processWith`, defined in `Text.Pandoc.Definition`, uses some
1321−`Data.Generics` magic to apply its argument (here `capStr`) to every
1322−`Inline` element in a list, including elements that are deeply buried in
1323−other elements. Thus
1324−
1325− processWith captStr [Str "one", Strong [Str "two", Space]] ==>
1326− [Str "ONE", Strong [Str "TWO", Space]]
1327−
1328−There are other sample plugins in the `plugins` subdirectory of the
1329−pandoc source code.
1330−
1331−**Note:** Do not attempt to use plugins when running pandoc in the
1332−directory containing pandoc's source code. The interpreter will try to
1333−load the files directly from the source code, rather than reading the compiled
1334−versions, and pandoc will hang.
1335−