3

Using a solution to adjust spacing in my document with LuaLaTeX, I run into the problem, that the semicolons are also replaced in a TikZ environments:


MWE:

\documentclass{scrbook}

\usepackage{tikz}
\usepackage{luacode}
\usepackage{etoolbox}
\newrobustcmd\dblpnct[1]{%
  \ifincsname\else
    \ifmmode\else
      \ifhmode
        \unskip
      \fi
      \nolinebreak\hspace{#1}%
    \fi
  \fi
}

\begin{luacode}
function dosub(s)
    s = string.gsub(s, ';', '\\dblpnct{1.08334em}:')
    return(s)
end
\end{luacode}

\makeatletter
\AtBeginDocument{%
    \luaexec{luatexbase.add_to_callback("process_input_buffer", dosub, "dosub")}%
    \ifpatchable*\NR@sanitize@labelname
    {\pretocmd\NR@sanitize@labelname{\let\dblpnct\@gobble}{}{\failed}}
    {}
}
\makeatother

\begin{document}

\begin{tikzpicture}
\node{test};
\end{tikzpicture}

\end{document}
2
  • 1
    I guess you have to add \let\dblpnct\@gobble to the initializations of tikzpicture. However I have no problem with this example, as you're changing the colon, not the semicolon.
    – egreg
    Commented Oct 27, 2016 at 21:29
  • @egreg: edited! Commented Oct 28, 2016 at 13:04

1 Answer 1

2

The problem is the limitation of the chosen method. At the time, the input buffer is processed, the context and meaning of the semicolon is not available. For example, a line could look like:

\tikz\node{abc; def};

The first semicolon belongs to typeset text, but the second semicolon is used as syntax character. Maybe, some quite small subset of cases can be caught by regular expressions, but TeX's language is too powerful (Turing complete) for catching all cases.

A workaround is using something different than the syntactic semicolon and replace it to a semicolon in the Lua function, e.g. (base of the example is the example of the question, but with colon replaced by semicolon).

The syntactic semicolons are written as SEMICOLON. After processing by dosub it becomes ;:

\documentclass{scrbook}

\usepackage{tikz}
\usepackage{luacode}
\usepackage{etoolbox}
\newrobustcmd\dblpnct[1]{%
  \ifincsname\else
    \ifmmode\else
      \ifhmode
        \unskip
      \fi
      \nolinebreak\hspace{#1}%
    \fi
  \fi
}

\begin{luacode}
function dosub(s)
    s = string.gsub(s, ';', '\\dblpnct{1.08334em};')
    s = string.gsub(s, 'SEMICOLON', ';')
    return(s)
end
\end{luacode}

\makeatletter
\AtBeginDocument{%
    \luaexec{luatexbase.add_to_callback("process_input_buffer", dosub, "dosub")}
    \ifpatchable*\NR@sanitize@labelname
    {\pretocmd\NR@sanitize@labelname{\let\dblpnct\@gobble}{}{\failed}}
    {}
}
\makeatother

\begin{document}

\begin{tikzpicture}
\node{test}SEMICOLON
\end{tikzpicture}

\end{document}

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .