Custom writer: support new-style Writer function.
This commit is contained in:
parent
f738c451d7
commit
0f0b042139
2 changed files with 76 additions and 8 deletions
|
@ -15,8 +15,17 @@ install any additional software to do this.
|
||||||
|
|
||||||
[Lua]: https://www.lua.org
|
[Lua]: https://www.lua.org
|
||||||
|
|
||||||
A custom writer is a Lua file that defines functions for
|
A custom writer is a Lua file that defines how to render the
|
||||||
rendering each element of a pandoc AST.
|
document. Two styles of custom writers are supported: classic
|
||||||
|
custom writers must define rendering functions for each AST
|
||||||
|
element. New style writers, available since pandoc 2.17.2, must
|
||||||
|
define just a single function `Writer`, which gets passed the
|
||||||
|
document and writer options, and then does all rendering.
|
||||||
|
|
||||||
|
# Classic style
|
||||||
|
|
||||||
|
A writer using the classic style defines rendering functions for
|
||||||
|
all elements of pandoc's AST.
|
||||||
|
|
||||||
For example,
|
For example,
|
||||||
|
|
||||||
|
@ -26,15 +35,15 @@ function Para(s)
|
||||||
end
|
end
|
||||||
```
|
```
|
||||||
|
|
||||||
The best way to go about creating a custom writer is to modify
|
The best way to go about creating a classic custom writer is to
|
||||||
the example that comes with pandoc. To get the example, you
|
modify the example that comes with pandoc. To get the example,
|
||||||
can do
|
you can do
|
||||||
|
|
||||||
```
|
```
|
||||||
pandoc --print-default-data-file sample.lua > sample.lua
|
pandoc --print-default-data-file sample.lua > sample.lua
|
||||||
```
|
```
|
||||||
|
|
||||||
# A custom HTML writer
|
## A custom HTML writer
|
||||||
|
|
||||||
`sample.lua` is a full-features HTML writer, with explanatory
|
`sample.lua` is a full-features HTML writer, with explanatory
|
||||||
comments. To use it, just use the path to the custom writer as
|
comments. To use it, just use the path to the custom writer as
|
||||||
|
@ -51,7 +60,7 @@ the functions in `sample.lua` according to your needs.
|
||||||
``` {.lua include="sample.lua"}
|
``` {.lua include="sample.lua"}
|
||||||
```
|
```
|
||||||
|
|
||||||
# Template variables
|
## Template variables
|
||||||
|
|
||||||
New template variables can be added, or existing ones
|
New template variables can be added, or existing ones
|
||||||
modified, by returning a second value from function `Doc`.
|
modified, by returning a second value from function `Doc`.
|
||||||
|
@ -66,3 +75,43 @@ function Doc (body, meta, vars)
|
||||||
return body, vars
|
return body, vars
|
||||||
end
|
end
|
||||||
```
|
```
|
||||||
|
|
||||||
|
# New style
|
||||||
|
|
||||||
|
Custom writers using the new style must contain a global function
|
||||||
|
named `Writer`. Pandoc calls this function with the document and
|
||||||
|
writer options as arguments, and expects the function to return a
|
||||||
|
string.
|
||||||
|
|
||||||
|
``` lua
|
||||||
|
function Writer (doc, opts)
|
||||||
|
-- ...
|
||||||
|
end
|
||||||
|
```
|
||||||
|
|
||||||
|
## Example: modified Markdown writer
|
||||||
|
|
||||||
|
Writers have access to all modules described in the [Lua filters
|
||||||
|
documentation][]. This includes `pandoc.write`, which can be used
|
||||||
|
to render a document in a format already supported by pandoc. The
|
||||||
|
document can be modified before this conversion, as demonstrated
|
||||||
|
in the following short example. It renders a document as GitHub
|
||||||
|
Flavored Markdown, but always uses fenced code blocks, never
|
||||||
|
indented code.
|
||||||
|
|
||||||
|
``` lua
|
||||||
|
function Writer (doc, opts)
|
||||||
|
local filter = {
|
||||||
|
CodeBlock = function (cb)
|
||||||
|
-- only modify if code block has no attributes
|
||||||
|
if cb.attr == pandoc.Attr() then
|
||||||
|
local delimited = '```\n' .. cb.text .. '\n```'
|
||||||
|
return pandoc.RawBlock('markdown', delimited)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
}
|
||||||
|
return pandoc.write(doc:walk(filter), 'gfm', opts)
|
||||||
|
end
|
||||||
|
```
|
||||||
|
|
||||||
|
[Lua filters documentation]: https://pandoc.org/lua-filters.html
|
||||||
|
|
|
@ -33,4 +33,23 @@ writeCustom luaFile opts doc = either throw pure <=< runLua $ do
|
||||||
dofileTrace luaFile >>= \case
|
dofileTrace luaFile >>= \case
|
||||||
OK -> pure ()
|
OK -> pure ()
|
||||||
_ -> throwErrorAsException
|
_ -> throwErrorAsException
|
||||||
|
-- Most classic writers contain code that throws an error if a global
|
||||||
|
-- is not present. This would break our check for the existence of a
|
||||||
|
-- "Writer" function. We resort to raw access for that reason, but
|
||||||
|
-- could also catch the error instead.
|
||||||
|
let rawgetglobal x = do
|
||||||
|
pushglobaltable
|
||||||
|
pushName x
|
||||||
|
rawget (nth 2) <* remove (nth 2) -- remove global table
|
||||||
|
|
||||||
|
rawgetglobal "Writer" >>= \case
|
||||||
|
TypeNil -> do
|
||||||
|
pop 1 -- remove nil
|
||||||
Classic.runCustom opts doc
|
Classic.runCustom opts doc
|
||||||
|
_ -> do
|
||||||
|
-- Writer on top of the stack. Call it with document and writer
|
||||||
|
-- options as arguments.
|
||||||
|
push doc
|
||||||
|
push opts
|
||||||
|
call 2 1
|
||||||
|
forcePeek $ peekText top
|
||||||
|
|
Loading…
Add table
Reference in a new issue