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
|
||||
|
||||
A custom writer is a Lua file that defines functions for
|
||||
rendering each element of a pandoc AST.
|
||||
A custom writer is a Lua file that defines how to render the
|
||||
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,
|
||||
|
||||
|
@ -26,15 +35,15 @@ function Para(s)
|
|||
end
|
||||
```
|
||||
|
||||
The best way to go about creating a custom writer is to modify
|
||||
the example that comes with pandoc. To get the example, you
|
||||
can do
|
||||
The best way to go about creating a classic custom writer is to
|
||||
modify the example that comes with pandoc. To get the example,
|
||||
you can do
|
||||
|
||||
```
|
||||
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
|
||||
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"}
|
||||
```
|
||||
|
||||
# Template variables
|
||||
## Template variables
|
||||
|
||||
New template variables can be added, or existing ones
|
||||
modified, by returning a second value from function `Doc`.
|
||||
|
@ -66,3 +75,43 @@ function Doc (body, meta, vars)
|
|||
return body, vars
|
||||
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
|
||||
OK -> pure ()
|
||||
_ -> 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
|
||||
_ -> 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…
Reference in a new issue