@@ -1120,21 +1120,46 @@ Plugins
11201120=======
11211121
11221122Pandoc's plugin system allows users to modify pandoc's behavior by writing
1123−short Haskell programs. A plugin is a Haskell module that exports a function
1124−`transform`, of type `a -> a` or `a -> IO a`, where `a` is `Pandoc`,
1125−`Block`, `Inline`, `[Block]`, or `[Inline]`. The `transform` function will
1126−be used to transform the pandoc document generated by the reader, before
1127−it is transformed by the writer.
1123+short Haskell programs. To how this works, and why it is useful, we
1124+ need to understand that pandoc transforms one format (the source
1125+format) into another (the target format) by first converting from the
1126+source format into a Haskell data structure representing the document,
1127+and then converting this data structure into the target format. For
1128+example:
1129+
1130+ -------------------------------------------------------------------------------
1131+ Document Format Contents
1132+ ------------ --------- -----------------------------------------------------
1133+ source markdown `Hello *world*.`
1134+
1135+ ↓ ↓ ↓
1136+
1137+ intermediate native `Pandoc (Meta [] [] "")
1138+ [Para [Str "Hello",Space,Emph [Str "world"],Str "."]]`
1139+
1140+ ↓ ↓ ↓
1141+
1142+ target HTML `<p>Hello <em>world</em>.</p>`
1143+ -------------------------------------------------------------------------------
1144+
1145+We can use standard text-processing tools (`perl`, `sed`, `awk`, etc.)
1146+to modify the source or target documents. But what if we want to modify
1147+the intermediate representation -- the parsed document -- before it is
1148+written to the target format? That's where plugins are needed.
1149+A plugin is a Haskell module that exports a function `transform`, which
1150+will be used to transform the native representation, after it is generated
1151+by the reader, but before it has been transformed by the writer.
11281152
11291153An example will help make this clearer. Suppose we want to use pandoc with
11301154the WordPress blog engine. WordPress provides support for LaTeX math, but
11311155instead of `$e = mc^2$`, WordPress wants `$LaTeX e = mc^2$`. Prior to plugins,
11321156there was no good way to make pandoc do this. We could have tried using
11331157regex replacements on the markdown input or HTML output, but this would have
1134−been error-prone: we'd have to make sure we weren't capturing non-math text
1135−between dollar signs (for example, text inside a code block). Besides,
1136−pandoc's markdown reader has already identified the math bits; why not
1137−make use of that? By writing a plugin, we can:
1158+been error-prone: if someone writes `$e = mc^2$` in a code block, for
1159+example, we wouldn't want to insert `LaTeX` there. There's no good way to
1160+identify the math chunks without parsing the whole document. And pandoc
1161+is already doing that, so why not make use of this work? By writing a
1162+plugin, we can. Here's the whole plugin:
11381163
11391164~~~ {.haskell}
11401165-- WordPressPlugin.hs
@@ -1156,6 +1181,8 @@ import Text.Pandoc
11561181just define the name of the module (`WordPressPlugin`), the names of any
11571182exported functions (for a plugin, this will always just be `transform`),
11581183and the modules that will be used in the program itself (`Text.Pandoc`).
1184+Every plugin must export a function named `transform`.
1185+
11591186The real meat of the program is the three-line definition of `transform`:
11601187
11611188~~~ {.haskell}
@@ -1166,14 +1193,19 @@ transform x = x
11661193
11671194The first line defines the type of the function: it is a function that
11681195takes an `Inline` element and returns an `Inline` element. (For the definition
1169−of `Inline`, see the module `Text.Pandoc.Definition`.) The next line says
1170−that when the input matches the pattern `Math x y`, the string `LaTeX `
1171−should be inserted at the beginning of `y`. (`x` just specifies whether the
1172−math element is inline or display math, so we leave it alone.) The last
1173−line says, in effect, that the `transform` function has no effect on any
1174−other kind of `Inline` element -- it just passes it through. When the plugin
1175−is applied, this transformation will be used on every `Inline` element in
1176−the document, and `LaTeX ` will be inserted where needed in math elements.
1196+of `Inline`, see the module `Text.Pandoc.Definition`.) The `transform`
1197+function in a plugin need not be `Inline -> Inline`, but it must have
1198+type `a -> a` or `a -> IO a`, where `a` is `Pandoc`, `Block`, `Inline`,
1199+`[Block]`, or `[Inline]`.
1200+
1201+The next line says that when the input matches the pattern `Math x y`,
1202+the string `LaTeX ` should be inserted at the beginning of `y`. (The `x`
1203+just specifies whether the math element is inline or display math, so
1204+we leave it alone.) The last line says, in effect, that the `transform`
1205+function has no effect on any other kind of `Inline` element -- it just
1206+passes it through. When the plugin is applied, this transformation will
1207+be used on every `Inline` element in the document, and `LaTeX ` will be
1208+inserted where needed in math elements.
11771209
11781210To use this plugin, we just specify the module (or alternatively the filename)
11791211with the `--plugins` option:
@@ -1186,13 +1218,28 @@ with the `--plugins` option:
11861218 >
11871219
11881220Let's look at a more complex example, involving IO. Suppose we want to include
1189−some graphviz diagrams in our document. Of course, we could use a Makefile to
1190−generate the diagrams, then use regular images in our document. But wouldn't it
1191−be nicer just to include the graphviz code in the document itself, perhaps in
1192−a specially marked delimited code block?
1221+some [graphviz](http://www.graphviz.org/) diagrams in our document.
1222+Of course, we could use a Makefile to generate the diagrams, then use
1223+regular images in our document. But wouldn't it be nicer just to include
1224+the graphviz code in the document itself, perhaps in a specially marked
1225+delimited code block?
11931226
11941227 ~~~ {.dot name="diagram1"}
1195− digraph G {Hello->World}
1228+ graph G {
1229+ e
1230+ subgraph clusterA {
1231+ a -- b;
1232+ subgraph clusterC {
1233+ C -- D;
1234+ }
1235+ }
1236+ subgraph clusterB {
1237+ d -- f
1238+ }
1239+ d -- D
1240+ e -- clusterB
1241+ clusterC -- clusterB
1242+ }
11961243 ~~~
11971244
11981245This can be accomplished by a plugin: