This Lua filter is used to create images with or without captions from code blocks. Currently PlantUML, Graphviz, TikZ, Asymptote, and Python can be processed. This document also serves as a test document, which is why the subsequent test diagrams are integrated in every supported language.
To be able to use this Lua filter, the respective external tools must be installed. However, it is sufficient if the tools to be used are installed. If you only want to use PlantUML, you don't need LaTeX or Python, etc.
To use PlantUML, you must install PlantUML itself. See the PlantUML website for more details. It should be noted that PlantUML is a Java program and therefore Java must also be installed.
By default, this filter expects the plantuml.jar file to be in the
working directory. Alternatively, the environment variable
PLANTUML
can be set with a path. If, for example, a specific
PlantUML version is to be used per pandoc document, the
plantuml_path
meta variable can be set.
Furthermore, this filter assumes that Java is located in the
system or user path. This means that from any place of the system
the java
command is understood. Alternatively, the JAVA_HOME
environment variable gets used. To use a specific Java version per
pandoc document, use the java_path
meta variable. Please notice
that JAVA_HOME
must be set to the java's home directory e.g.
c:\Program Files\Java\jre1.8.0_201\
whereas java_path
must be
set to the absolute path of java.exe
e.g.
c:\Program Files\Java\jre1.8.0_201\bin\java.exe
.
Example usage:
@startuml
Alice -> Bob: Authentication Request Bob --> Alice: Authentication Response
Alice -> Bob: Another authentication Request Alice <-- Bob: another Response
@enduml
To use Graphviz you only need to install Graphviz, as you can read on its website. There are no other dependencies.
This filter assumes that the dot
command is located in the path
and therefore can be used from any location. Alternatively, you can
set the environment variable DOT
or use the pandoc's meta variable
dot_path
.
Example usage from the Graphviz gallery:
digraph finite_state_machine {
rankdir=LR;
node [shape = doublecircle]; LR_0 LR_3 LR_4 LR_8;
node [shape = circle];
LR_0 -> LR_2 [ label = "SS(B)" ];
LR_0 -> LR_1 [ label = "SS(S)" ];
LR_1 -> LR_3 [ label = "S($end)" ];
LR_2 -> LR_6 [ label = "SS(b)" ];
LR_2 -> LR_5 [ label = "SS(a)" ];
LR_2 -> LR_4 [ label = "S(A)" ];
LR_5 -> LR_7 [ label = "S(b)" ];
LR_5 -> LR_5 [ label = "S(a)" ];
LR_6 -> LR_6 [ label = "S(b)" ];
LR_6 -> LR_5 [ label = "S(a)" ];
LR_7 -> LR_8 [ label = "S(b)" ];
LR_7 -> LR_5 [ label = "S(a)" ];
LR_8 -> LR_6 [ label = "S(b)" ];
LR_8 -> LR_5 [ label = "S(a)" ];
}
TikZ (cf. Wikipedia) is a description language for graphics of any kind that can be used within LaTeX (cf. Wikipedia).
Therefore a LaTeX system must be installed on the system. The TikZ code is
embedded into a dynamic LaTeX document. This temporary document gets
translated into a PDF document using LaTeX (pdflatex
). Finally,
Inkscape is used to convert the PDF file to the desired format.
Note: We are using Inkscape here to use a stable solution for the convertion. Formerly ImageMagick was used instead. ImageMagick is not able to convert PDF files. Hence, it uses Ghostscript to do so, cf. 1. Unfortunately, Ghostscript behaves unpredictable during Windows and Linux tests cases, cf. 2, 3, 4, 5, 6, etc. By using Inkscape, we need one dependency less and get rid of unexpected Ghostscript issues.
Due to this more complicated process, the use of TikZ is also more complicated overall. The process is error-prone: An insufficiently configured LaTeX installation or an insufficiently configured Inkscape installation can lead to errors. Overall, this results in the following dependencies:
-
Any LaTeX installation. This should be configured so that missing packages are installed automatically. This filter uses the
pdflatex
command which is available by the system's path. Alternatively, you can set thePDFLATEX
environment variable. In case you have to use a specific LaTeX version on a pandoc document basis, you might set thepdflatex_path
meta variable. -
An installation of Inkscape. It is assumed that the
inkscape
command is in the path and can be executed from any location. Alternatively, the environment variableINKSCAPE
can be set with a path. If a specific version per pandoc document is to be used, theinkscape_path
meta-variable can be set.
In order to use additional LaTeX packages, use the optional
additionalPackages
attribute in your document, as in the
example below.
Example usage from TikZ examples by Kjell Magne Fauske:
additionalPackages="\usepackage{adjustbox}"}
\usetikzlibrary{arrows}
\tikzstyle{int}=[draw, fill=blue!20, minimum size=2em]
\tikzstyle{init} = [pin edge={to-,thin,black}]
\resizebox{16cm}{!}{%
\trimbox{3.5cm 0cm 0cm 0cm}{
\begin{tikzpicture}[node distance=2.5cm,auto,>=latex']
\node [int, pin={[init]above:$v_0$}] (a) {$\frac{1}{s}$};
\node (b) [left of=a,node distance=2cm, coordinate] {a};
\node [int, pin={[init]above:$p_0$}] at (0,0) (c)
[right of=a] {$\frac{1}{s}$};
\node [coordinate] (end) [right of=c, node distance=2cm]{};
\path[->] (b) edge node {$a$} (a);
\path[->] (a) edge node {$v$} (c);
\draw[->] (c) edge node {$p$} (end) ;
\end{tikzpicture}
}
}
In order to use Python to generate an diagram, your Python code must store the final image data in a temporary file with the correct format. In case you use matplotlib for a diagram, add the following line to do so:
plt.savefig("$DESTINATION$", dpi=300, format="$FORMAT$")
The placeholder $FORMAT$
gets replace by the necessary format. Most of the
time, this will be png
or svg
. The second placeholder, $DESTINATION$
gets replaced by the path and file name of the destination. Both placeholders
can be used as many times as you want. Example usage from the Matplotlib
examples:
import matplotlib
matplotlib.use('Agg')
import sys
import numpy as np
import matplotlib.pyplot as plt
# Fixing random state for reproducibility
np.random.seed(19680801)
dt = 0.01
t = np.arange(0, 30, dt)
nse1 = np.random.randn(len(t)) # white noise 1
nse2 = np.random.randn(len(t)) # white noise 2
# Two signals with a coherent part at 10Hz and a random part
s1 = np.sin(2 * np.pi * 10 * t) + nse1
s2 = np.sin(2 * np.pi * 10 * t) + nse2
fig, axs = plt.subplots(2, 1)
axs[0].plot(t, s1, t, s2)
axs[0].set_xlim(0, 2)
axs[0].set_xlabel('time')
axs[0].set_ylabel('s1 and s2')
axs[0].grid(True)
cxy, f = axs[1].cohere(s1, s2, 256, 1. / dt)
axs[1].set_ylabel('coherence')
fig.tight_layout()
plt.savefig("$DESTINATION$", dpi=300, format="$FORMAT$")
Precondition to use Python is a Python environment which contains all necessary libraries you want to use. To use, for example, the standard Anaconda Python environment on a Microsoft Windows system ...
-
set the environment variable
PYTHON
or the meta keypythonPath
toc:\ProgramData\Anaconda3\python.exe
-
set the environment variable
PYTHON_ACTIVATE
or the meta keyactivate_python_path
toc:\ProgramData\Anaconda3\Scripts\activate.bat
.
Pandoc will activate this Python environment and starts Python with your code.
Asymptote is a graphics language inspired by Metapost. To use Asymptote, you will need to install the software itself, a TeX distribution such as TeX Live, and dvisvgm, which may be included in the TeX distribution.
If png output is required (such as for the docx
, pptx
and rtf
output formats) Inkscape must be installed. See the TikZ section
for details.
Ensure that the Asymptote asy
binary is in the path, or point
the environment variable ASYMPTOTE
or the metadata variable
asymptotePath
to the full path name. Asymptote calls the various
TeX utilities and dvipdfm, so you will need to configure Asymptote
so that it finds them.
size(5cm);
include graph;
pair circumcenter(pair A, pair B, pair C)
{
pair P, Q, R, S;
P = (A+B)/2;
Q = (B+C)/2;
R = rotate(90, P) * A;
S = rotate(90, Q) * B;
return extension(P, R, Q, S);
}
pair incenter(pair A, pair B, pair C)
{
real a = abs(angle(C-A)-angle(B-A)),
b = abs(angle(C-B)-angle(A-B)),
c = abs(angle(A-C)-angle(B-C));
return (sin(a)*A + sin(b)*B + sin(c)*C) / (sin(a)+sin(b)+sin(c));
}
real dist_A_BC(pair A, pair B, pair C)
{
real det = cross(B-A, C-A);
return abs(det/abs(B-C));
}
pair A = (0, 0), B = (5, 0), C = (3.5, 4),
O = circumcenter(A, B, C),
I = incenter(A, B, C);
dot(A); dot(B); dot(C); dot(O, blue); dot(I, magenta);
draw(A--B--C--cycle, linewidth(2));
draw(Circle(O, abs(A-O)), blue+linewidth(1.5));
draw(Circle(I, dist_A_BC(I, A, B)), magenta+linewidth(1.5));
label("$A$", A, SW);
label("$B$", B, SE);
label("$C$", C, NE);
label("$O$", O, W);
label("$I$", I, E);
Mermaid is a diagramming and charting tool.
mmdc is a cli to mermaid.
Your distribution may have a package called mermaid-cli
or mmdc
.
gitGraph
commit
commit
branch develop
checkout develop
commit
commit
checkout main
merge develop
commit
commit
graph TB;
A((10))-->B((3))
A-->C((12));
B-->E((1))
B-->F((7))
C-->H((11))
C-->I((4))
This section will show, how to call Pandoc in order to use this filter with
meta keys. The following command assume, that the filters are stored in the
subdirectory filters
. Further, this is a example for a Microsoft Windows
system.
Command to use PlantUML (a single line):
pandoc.exe README.md -f markdown -t docx --self-contained --standalone --lua-filter=filters\diagram-generator.lua --metadata=plantumlPath:"c:\ProgramData\chocolatey\lib\plantuml\tools\plantuml.jar" --metadata=javaPath:"c:\Program Files\Java\jre1.8.0_201\bin\java.exe" -o README.docx
All available environment variables:
PLANTUML
e.g.c:\ProgramData\chocolatey\lib\plantuml\tools\plantuml.jar
; Default:plantuml.jar
INKSCAPE
e.g.c:\Program Files\Inkscape\inkscape.exe
; Default:inkscape
PYTHON
e.g.c:\ProgramData\Anaconda3\python.exe
; Default: n/aPYTHON_ACTIVATE
e.g.c:\ProgramData\Anaconda3\Scripts\activate.bat
; Default: n/aJAVA_HOME
e.g.c:\Program Files\Java\jre1.8.0_201
; Default: n/aDOT
e.g.c:\ProgramData\chocolatey\bin\dot.exe
; Default:dot
PDFLATEX
e.g.c:\Program Files\MiKTeX 2.9\miktex\bin\x64\pdflatex.exe
; Default:pdflatex
ASYMPTOTE
e.g.c:\Program Files\Asymptote\asy
; Default:asy
All available meta keys:
plantuml_path
inkscape_path
python_path
activate_python_path
java_path
dot_path
pdflatex_path
asymptote_path