Skip to content

Commit

Permalink
Lua: deprecate classic custom writers.
Browse files Browse the repository at this point in the history
  • Loading branch information
tarleb authored and jgm committed Oct 3, 2022
1 parent 309163f commit 921d7dd
Showing 1 changed file with 61 additions and 47 deletions.
108 changes: 61 additions & 47 deletions doc/custom-writers.md
Original file line number Diff line number Diff line change
Expand Up @@ -16,16 +16,61 @@ install any additional software to do this.
[Lua]: https://www.lua.org

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.
document. Writers must define just a single function named
`Writer`, which gets passed the document and writer options, and
then handles the conversion of the document, rendering it into a
string. This interface was introduced in pandoc 2.17.2.

Pandoc also supports "classic" custom writers, where a Lua
function must be defined for each AST element type. Classic style
writers are *deprecated* and should be replaced with new-style
writers if possible.

# Writers

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
UTF-8 encoded 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

# Classic style

A writer using the classic style defines rendering functions for
each element of the pandoc AST.
each element of the pandoc AST. Note that this style is
*deprecated* and may be removed in later versions.

For example,

Expand Down Expand Up @@ -76,50 +121,19 @@ function Doc (body, meta, vars)
end
```

# New style
## Changes in pandoc 3.0

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
UTF-8 encoded string.
Custom writers were reworked in pandoc 3.0. For technical reasons,
the global variables `PANDOC_DOCUMENT` and `PANDOC_WRITER_OPTIONS`
are set to the empty document and default values, respectively.
The old behavior can be restored by adding the following snippet,
which turns a classic into a new style writer.

``` lua
function Writer (doc, opts)
-- ...
PANDOC_DOCUMENT = doc
PANDOC_WRITER_OPTIONS = opts
loadfile(PANDOC_SCRIPT_FILE)()
return pandoc.write_classic(doc, opts)
end
```

Writers that do not return text but binary data should define a
function with name `BinaryWriter` instead. The function must still
return a string, but it does not have to be UTF-8 encoded and can
contain arbitrary binary data.

If both `Writer` and `BinaryWriter` functions are defined, then
only the `Writer` function will be used.

## 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

0 comments on commit 921d7dd

Please sign in to comment.