Example
watermark

4  TikZ Figures

4.1 TODO:

  • Move tikzarabic filter YAML options to within arabicsupport section

4.2 Introduction

I sometimes need to use TikZ figures with Arabic text in my document. This chapter describes how to do that.

In order to render TikZ figures in Quarto we will use a Pandoc Lua filter. I have modified a Pandoc Lua filter that was originally published here: https://github.com/danmackinlay/quarto_tikz

The modified filter tikzarabic.lua is part of my arabic-support extension.

4.3 Filter options

The filter needs some options that I’ve set globally in _quarto.yml:

tikzarabic:
  cache: true
  format: svg
  embed_mode: link
  engine: lualatex
  template_html: srctex/tikz-template-html.tex
  template_pdf: srctex/tikz-template-pdf.tex
  libgs: /usr/local/Cellar/ghostscript/10.04.0/lib/libgs.dylib

Despite being named tikzarabic you can use this filter for regular TikZ diagrams as well. There is an example at the end of this chapter.

There is also an official filter that handles TikZ (and other formats) here: https://github.com/pandoc-ext/diagram. But unfortunately, I wasn’t able to get it to work with Arabic text. Probably something I was doing incorrectly.

Here is an explanation of the options:

  • cache: Uses a cache on the system in order to not have to build the TikZ code for every render. When cache is enabled then, if you modify the TikZ code, the figure is rebuilt. But if you modify the template or the filter, then the figures don’t seem to be rebuilt. So in this case you may temporarily have to set cache to false in order to rebuild the figures. Default value: false.

  • format: SVG preserves vector information for optimal rendering. Default value: svg.

  • embed_mode: Only affects HTML output. If set to link then the HTML includes the figure as a link. If set to inline then the HTML encodes the figure inline as ASCII text. Default value: inline.

  • engine: The Arabic typesetting I’m using within the figures uses the package arabluatex which needs the LuaTex engine. This is specified using the text lualatex. Ideally, I should use xelatex to be consistent with the rest of the document but I haven’t yet figured out how to do that. There may be some incompatibility between the babel package and TikZ which would need to be resolved. Default value: latex.

  • template_html: Common TikZ template code for HTML output. Here’s what I’m using in my srctex/tikz-template-html.tex:

    \RequirePackage{luatex85}
    \documentclass{article}
    \usepackage[luatex,active,tightpage]{preview}
    \usepackage{amsmath}
    \usepackage{tikz}
    \usepackage{xcolor}
    \definecolor{mydarkgray}{RGB}{52, 58, 64}
    
    
    \usepackage{fontspec}
    \defaultfontfeatures{Scale=MatchLowercase}
    \defaultfontfeatures[\rmfamily]{Ligatures=TeX,Scale=1.27978125}
    \setmainfont{Charis SIL}
    
    \usetikzlibrary{%s}
    \usetikzlibrary{matrix}
    \usepackage{arabluatex}
    \newfontfamily{\arabicfont}[Script=Arabic,Scale=1.2]{Vazirmatn-Regular}
    
    \begin{document}
    \begin{preview}
    \color{mydarkgray}
    %s
    \end{preview}
    \end{document}

    Note the use of the color mydarkgray to match the body text of the HTML theme. The color definition was obtained by inspecting this very page in a web browser, looking up the color specification from the stylesheet, and converting the HTML hexadecimal color code 343a40 to the decimal RGB values {52, 58, 64}.

    Also note that the font is scaled by a factor of 1.27978125. This number has been arrived at using the following reasoning: The default font size for the Tex documentclass is 10pt. Inspecting the stylesheet for the this web page shows us that the body text font size is 17px. Using the ratio of 96px = 72.27pt, we calculate that we need to have a font size of 12.7978125pt. So we apply a scale factor of 1.27978125 to the default 10pt font size.

    The code block in the .qmd file will be inserted in the second %s’s location. Additional TikZ libraries may be inserted in the first %s’s location using the YAML option libraries.

    Default template:

    \documentclass[tikz]{standalone}
    \usepackage{amsmath}
    \usetikzlibrary{%s}
    \begin{document}
    %s
    \end{document}
    ]]
  • template_pdf: Common TikZ template code for PDF output. Here’s what I’m using in my srctex/tikz-template-pdf.tex:

    \RequirePackage{luatex85}
    \documentclass{article}
    \usepackage[luatex,active,tightpage]{preview}
    \usepackage{amsmath}
    \usepackage{tikz}
    
    \usepackage{fontspec}
    \defaultfontfeatures{Scale=MatchLowercase}
    \defaultfontfeatures[\rmfamily]{Ligatures=TeX,Scale=1}
    \setmainfont{Charis SIL}
    
    \usetikzlibrary{%s}
    \usetikzlibrary{matrix}
    \usepackage{arabluatex}
    \newfontfamily{\arabicfont}[Script=Arabic,Scale=1.0]{Vazirmatn-Light}
    
    \begin{document}
    \begin{preview}
    %s
    \end{preview}
    \end{document}

    It is identical to template_html except for:

    • a different weight for the Arabic font: “light” instead of “regular” to match the main document
    • the absence of the dark gray color for the text,
    • no scale applied to the Roman font.

    The default template is the same as the default for template_html.

  • libgs: In order to use this filter for HTML output, you need to make sure that the utlities dvisvgm and Ghostscript are installed on your system. This can be verified using the commands: which dvisvgm and which gs. If dvisvgm was not compiled with Ghostscript then you may need to link the location of the Ghostscript library on your system using the option libgs. Default value: "".

4.4 Example TikZ figure with Arabic text

Here is an example of a TikZ diagram with Arabic text:

This is the source code for the figure in the source .qmd file:

```{.tikzarabic}
\usetikzlibrary{decorations.text, decorations.pathreplacing}
\begin{tikzpicture}[nodes={text depth=0.25ex,text height=2.0ex}]
\path [decoration={text effects along path,
  text=.\txarb{كَبِيرٌ} \txarb{ٱَلْبَيْتُ},
  text effects/.cd,
    path from text, text along path,
    group letters, word count=\w,
    every word/.style={name=word-\w, execute at begin node=\strut}},
  decorate] (0,0);

\draw [decoration={brace, mirror}, decorate]
  (word-1.south west) -- (word-1.south east)
    node [midway, rotate=90, anchor=south, left=0ex, align=left] 
      {\scriptsize predicate};

\draw [decoration={brace, mirror}, decorate]
  (word-2.south west) -- (word-2.south east)
    node [midway, rotate=90, anchor=south, left=0ex, align=left] 
      {\scriptsize subject};

\path (0,0) 
  node [midway, below=13.5ex, right=0ex, align=left] 
    {``The house is big.''};

\end{tikzpicture}
```

4.5 Overriding global options

If you wish to override any of the global parameters back to their default values, or to other values, you can do so inline using the comment-pipe (%%| option: value) format. Here is an example:

Source code:

```{.tikzarabic}
%%| embed_mode: inline
%%| engine: default
%%| template_html: default
%%| template_pdf: default
\begin{tikzpicture}[nodes={text depth=0.25ex,text height=2.0ex}]
\node[draw, circle] (A) at (0,0) {A};
\node[draw, circle] (B) at (2,2) {$\phi$};
\node[draw, circle] (C) at (4,0) {C};
\node[draw, circle] (seven) at (5,1) {888888};
\draw[->] (A) -- (B);
\draw[->] (B) -- (C);
\draw[->] (C) -- (A);
\end{tikzpicture}
```