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}
  • 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 Oct 27 '16 at 21:29
  • @egreg: edited! – Kyle_the_hacker Oct 28 '16 at 13:04
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}

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.