Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

tikz_latex_preamble does not escape backslash characters #19

Open
doyougnu opened this issue Mar 29, 2024 · 2 comments
Open

tikz_latex_preamble does not escape backslash characters #19

doyougnu opened this issue Mar 29, 2024 · 2 comments

Comments

@doyougnu
Copy link

doyougnu commented Mar 29, 2024

behavior

consider this setting in conf.py where I'm just trying to define a macro

...
tikz_latex_preamble = "\newcommand\\Foo[1]{Z}"
...

Then using one of the examples:

.. tikz:: [>=latex',dotted,thick] \draw[->] (0,0) -- (1,1) -- (1,0)
   -- (2,0);
   :libs: arrows

note that I am not even using the macro, this yields:

System Message: WARNING/2 ([>=latex',dotted,thick] \draw[->] (0,0) -- (1,1) -- (1,0) -- (2,0);)

! LaTeX Error: Missing \begin{document}. See the LaTeX manual or LaTeX Companion for explanation. Type H <return> for immediate help. ... l.9 e wcommand\Foo[1]{Z} ! Undefined control sequence. l.9 ewcommand\Foo [1]{Z} (/nix/store/2kqi4kak6rgpzr5s2kh1fsv3ynz9s3xd-texlive-2022-env-texmfdist/tex/lat ex/l3backend/l3backend-pdftex.def) No file tikz-9623d8fec8222981fc4dda796d12608e10225c41.aux. (/nix/store/2kqi4kak6rgpzr5s2kh1fsv3ynz9s3xd-texlive-2022-env-texmfdist/tex/con text/base/mkii/supp-pdf.mkii [Loading MPS to PDF converter (version 2006.09.02).] ) (/nix/store/2kqi4kak6rgpzr5s2kh1fsv3ynz9s3xd-texlive-2022-env-

because the \n in \newcommand is interpreted as a newline, not as latex code.

Expected behavior

tikz_latex_preamble is interpreted as latex code or automatically escapes backslashes.

Workaround

manually escape the newline like:

tikz_latex_preamble = "\\newcommand\Foo[1]{Z}"

or use a raw string:

tikz_latex_preamble = r"\newcommand\Foo[1]{Z}"

A more complicated example

Consider this preamble:

tikz_latex_preamble = """
\\newcommand\MemoryLayout[1]{
  \begin{tikzpicture}[scale=0.3]
     \draw[thick](0,0)--++(0,3)node[above]{$0$};
     \foreach \pt/\col/\lab [remember=\pt as \tp (initially 0)] in {#1} {
       \foreach \a in {\tp,...,\pt-1} {
          \draw[fill=\col](-\a,0) rectangle ++(-1,2);
       }
       \draw[thick](-\pt,0)--++(0,3)node[above]{$\pt$};
       \if\lab\relax\relax\else
         \draw[thick,decorate, decoration={brace,amplitude=4mm}]
            (-\tp,-0.2)--node[below=4mm]{\lab} (-\pt,-0.2);
       \fi
     }
  \end{tikzpicture}
}
"""

note the \r in \relax and \t in \tp and the \f in \foreach and \fi. Each of these will need to be escaped as well

@philexander
Copy link
Collaborator

Thank you for opening this issue.

Rationale

Imho this is a question of correct usage of Python. In Python, a literal string "\newcommand" starts with a newline. A literal string r"\newcommand" starts with a backslash.

This leaves the choice of how to provide literal strings to tikz_latex_preamble up to the user.

Adding escaping magic to tikz_latex_preamble would be an interface change and would break code that uses escapes on purpose. See example 1 below.

Example 1: Deliberatly use newlines as "\n":

\tikz_latex_preamble = "\\newcommand\\Foo{First line\n\nSecond line}"

Example 2: Use raw multiline strings:

\tikz_latex_preamble = r"""
\newcommand\Foo{
  First line

  Second line
}
"""

@doyougnu
Copy link
Author

doyougnu commented Apr 1, 2024

Yes I agree. I didn't realize python had raw multiline strings until I did some searching. Perhaps just a documentation update is needed then?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants