👨💻 about me home CV/Resume 🖊️ Contact Github LinkedIn I’m a Haskeller 🏆 Best of panda upp Haskell abp pp hCalc bl todo pwd TPG
30 January 2021
Panda is a Pandoc Lua filter that works on internal Pandoc’s AST.
It provides several interesting features:
Panda is heavily inspired by abp reimplemented as a Pandoc Lua filter.
If you need a more generic text preprocessor, UPP may be a better choice.
Panda is an Open source software. Anybody can contribute on GitHub to:
git clone https://github.com/CDSoft/panda
.make test
to run tests.make install
to install panda
and panda.lua
to ~/.local/bin
(see INSTALL_PATH
in Makefile
).panda
and panda.lua
can also be installed anywhere. Nothing else is required (except from Pandoc obviously).
panda.lua
is a Pandoc Lua filter and is not meant to be called directly. panda
is just a shell script that calls pandoc -L panda.lua ...
.
pandoc -L panda.lua ... $
or
panda ... $
A complete example is given as a Makefile in the doc directory.
Syntactic item | Class | Attributes | Description |
---|---|---|---|
any string | {{var}} is replaced by the value of var if it is defined (variables can be environment variables or Lua variables) |
||
div block | comment |
commented block | |
div block | include=file |
replaces the div block with the content of file (rendered according to its format) |
|
div block | shift=n |
adds n to header levels in an imported div block |
|
div block, code block | pattern="Lua string pattern" format="output format" |
applies a Lua string pattern to the content of the file. The emitted text is format . format may contain captures from pattern . |
|
code block | meta |
definitions for the string expansion (Lua script), defined in the code block | |
any block | ifdef=name |
block emitted only if name is defined |
|
any block | ifdef=name value=val |
block emitted only if name is defined and its value is value |
|
any block | ifndef=name |
block emitted only if name is not defined |
|
code block, inline code | include=file |
replaces the code block content with the content of file |
|
code block, inline code | fromline=n |
includes a file from line number n |
|
code block, inline code | toline=n |
includes a file up to line number n |
|
code block, inline code | cmd="shell command" |
replaces the code block by the result of the shell command | |
code block | render="command" |
replaces the code block by a link to the image produced by the command (%i is the input file name, its content is the content of the code block, %o is the output file name) |
|
code block | img="image path" |
URL of the image produced by render |
|
code block | out="image path" |
path of the image produced by render (optional, the default value is img ) |
Div blocks with the comment
class are commented:
::: comment
This block is a comment and is discarded by panda. :::
panda
stores variables in an environment used to expand strings. Variables can be defined by a Lua script with the meta
class. The include
attribute can also be used to point to an external file. Variables can only contain inline elements, not blocks.
The initial environment contains:
Variable names are enclosed between double curly brackets.
E.g.:
```meta
foo = "bar (note: this is parsed as **Markdown**)"
```
foo is {{foo}}.
```{.meta include=foo.lua}
This text is ignored, definitions are in foo.lua.
```
`foo.lua` and is {{foo}}. foo is defined in
Blocks can be conditionally kept or omitted. The condition is described with attributes.
:::{ifdef="name" value="value"}
This block is emitted only if the variable "name" is defined
and its value is "value" :::
:::{ifdef="name"}
This block is emitted only if the variable "name" is defined
(whatever its value) :::
:::{ifndef="name"}
This block is emitted only if the variable "name" is **not** defined :::
Fragments of documents can be imported from external files. The include
attribute contains the name of the file to include. The content of the file is parsed according to its format (deduced from its name) and replaces the div block content.
:::{include=file.md shift=n}
This text is optional and will be replaced by the content of file.md.
Section title levels are shifted by n (0 if not specified). :::
The included file can be in a different format (e.g. a markdown file can include a reStructuredText file).
Code examples can be imported from external files. The include
attribute contains the name of the file to include. The content of the file replaces the code block content.
```{.c include=foo.c fromline=3 toline=10 pattern="Lua string pattern" format="%1"}
This text is optional and will be replaced by the content of foo.c.
```
The optional fromline
and toline
defines the first and last lines to be included.
The optional pattern describes the part of the text that will be rendered. The format uses the captures defined by the pattern to format the content of the block ("%1"
if not defined).
Scripts can be executed by inline or code blocks. The cmd
attribute defines the command to execute. The content of the block is in a temporary file which name is added to the command. If the command contains the %s
char, it is replaced by the temporary file name. If the command does not contain any %s
, the file name is appended to the command. The result replaces the content of the code block.
Source | Result |
---|---|
|
|
|
Python says Hello from Python! |
Code blocks containing diagrams are replaced with an image resulting from the diagram source code.
The render command is the render
field. The output image can be a hash computed from the diagram source code or the value of the img
field. The optional out
field overloads img
to change the output directory when rendering the diagram.
In the render
command, %i
is replaced by the name of the input document (generated from the content of the code block) and %o
by the name of the output image file (generated from the img
field).
The file format (extension) must be in the render
field, after the %o
tag (e.g.: %o.png
), not in the img
field.
Source | Result |
---|---|
|
Some render commands are predefined:
Diagram | Predefined variable | Render command |
---|---|---|
GraphViz | dot |
dot -Tsvg -o %o.svg %i |
dot.svg |
dot -Tsvg -o %o.svg %i |
|
dot.png |
dot -Tpng -o %o.png %i |
|
dot.pdf |
dot -Tpdf -o %o.pdf %i |
|
PlantUML | plantuml |
java -jar plantuml.jar -pipe -charset UTF-8 -tsvg < %i > %o.svg |
plantuml.svg |
java -jar plantuml.jar -pipe -charset UTF-8 -tsvg < %i > %o.svg |
|
plantuml.png |
java -jar plantuml.jar -pipe -charset UTF-8 -tpng < %i > %o.png |
|
plantuml.pdf |
java -jar plantuml.jar -pipe -charset UTF-8 -tpdf < %i > %o.pdf |
|
Asymptote | asy |
asy -f svg -o %o.svg %i |
asy.svg |
asy -f svg -o %o.svg %i |
|
asy.png |
asy -f png -o %o.png %i |
|
asy.pdf |
asy -f pdf -o %o.pdf %i |
|
blockdiag | blockdiag |
blockdiag -a -Tsvg -o %o.svg %i |
blockdiag.svg |
blockdiag -a -Tsvg -o %o.svg %i |
|
blockdiag.png |
blockdiag -a -Tpng -o %o.png %i |
|
blockdiag.pdf |
blockdiag -a -Tpdf -o %o.pdf %i |
|
mermaid | mmdc |
mmdc -i %i -o %i |
mmdc.svg |
mmdc -i %i -o %i |
|
mmdc.png |
mmdc -i %i -o %i |
|
mmdc.pdf |
mmdc -i %i -o %i |
|
ditaa | ditaa |
java -jar ditaa.jar --svg -o -e UTF-8 %i %o.svg |
ditaa.svg |
java -jar ditaa.jar --svg -o -e UTF-8 %i %o.svg |
|
ditaa.png |
java -jar ditaa.jar -o -e UTF-8 %i %o.png |
|
gnuplot | gnuplot |
gnuplot -e 'set terminal svg' -e 'set output "%o.svg"' -c %i |
gnuplot.svg |
gnuplot -e 'set terminal svg' -e 'set output "%o.svg"' -c %i |
|
gnuplot.png |
gnuplot -e 'set terminal png' -e 'set output "%o.png"' -c %i |
Notes:
dot
: GraphViz support also includes dot
, neato
, twopi
, circo
, fdp
, sfdp
, patchwork
and osage
.
plantuml
: PLANTUML
can be defined as an environment variable. Its default value is the directory of the panda.lua
script appended with "plantuml.jar"
.
ditaa
: DITAA
can be defined as an environment variable. Its default value is the directory of the panda.lua
script appended with "ditaa.jar"
.
blockdiag
: Blockdiag support also includes actdiag
, blockdiag
, nwdiag
, packetdiag
, rackdiag
and seqdiag
.
renderers without an explicit image format are built differently according to the output document format.
img
fieldE.g.:
Source | Result |
---|---|
|
|
|
Filters can be combined. E.g.: a diagram can be stored in an external file, included and rendered by panda
.
Source | Result |
---|---|
|
The file
|
|
and is rendered as: |
It is sometimes useful to build a dependency list on the fly. panda
can generate a dependency list for make, in the same vein than the gcc -M
option. The environment variable PANDA_TARGET
must be defined with the target name. panda
will generate a file named ${PANDA_TARGET}.d
containing the dependencies of ${PANDA_TARGET}
.
E.g.:
PANDA_TARGET=index.html panda index.md -o index.html
This will produce a file named index.html.d
containing index.html: ...
.
Panda is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
Panda is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with Panda. If not, see <https://www.gnu.org/licenses/>.
For further information about Panda you can visit
http://cdelord.fr/panda
Your feedback and contributions are welcome. You can contact me at cdelord.fr.