# How to use \ExplSyntaxOn and \ExplSyntaxOff inside tikzset?

If you place ExplSyntax on/off inside tikzset, code (that is expected to work) within ExplSyntax would generate errors. But if you bring ExplSyntax outside of tikzset (enclosing the tikzset), it makes tikzset behave unexpectedly. How can I use ExplSyntax inside tikzset? Or do I need to (disappointingly, yet again) search for work arounds?

## Block within ExplSyntax generates an error inside tikzset:

\documentclass[varwidth]{standalone}

\usepackage{expl3}
\usepackage{tikz}

\ExplSyntaxOn
\int_new:N\myCounter
\int_set:Nn\myCounter{0}
\ExplSyntaxOff

\tikzset
{ every node/.style=
{ /utils/exec=
{ \ExplSyntaxOn
% following line generates an error
% \int_incr:N\myCounter
\ExplSyntaxOff
}
}
}

\begin{document}

\begin{tikzpicture}
\path node{some text};
\end{tikzpicture}

\end{document}


## Although block within ExplSyntax does not generate an error, it does not increment \myCounter, causes labels and positioning commands (who knows what else) within tikzset to generate errors, and prevents a standard counter (myStandardCounter) from being incremented:

\documentclass[varwidth]{standalone}

\usepackage{expl3}
\usepackage{tikz}

\newcounter{myStandardCounter}

% let's bring ExplSyntax outside of tikzset and try again
\ExplSyntaxOn
\int_new:N\myCounter
\int_set:Nn\myCounter{0}
\tikzset
{ every node/.style=
{ /utils/exec=
{ % neither of the counters below are incremented
\int_incr:N\myCounter
\stepcounter{myStandardCounter}
}
}
}
\ExplSyntaxOff

\begin{document}

\begin{tikzpicture}
\path node{some text};
\end{tikzpicture}

% both counters are at their initial values (zero)

\ExplSyntaxOn
expl3~counter:~\int_use:N\myCounter
\ExplSyntaxOff

standard counter: \the\value{myStandardCounter}

\end{document}

• It won't work inside. You have to set the catcodes (i.e., \ExplSyntaxOn) before the command (\tikzset) reads its argument. – Phelype Oleinik May 17 '19 at 0:35

First, catcode changes (\ExplSyntaxOn/\makeatletter, \ExplSyntaxOff/\makeatother, and the like) will not work inside macro arguments. TeX turns a input character into a so-called token when it first sees that character. When you do:

\tikzset
{
/utils/exec=
{
\ExplSyntaxOn
\int_incr:N \myCounter
\ExplSyntaxOff
}
}


The \tikzset macro grabs everything between { and } as argument and, at this point, TeX “sees” those characters, which are turned into tokens using the current catcode regime (with \ExplSyntaxOff), so \int_incr:N \myCounter is tokenized as \int _ i n c r : N \myCounter, and this tokenization is “frozen”, which means you can't change it.

After that the /utils/exec key does its thing and \ExplSyntaxOn is executed, but at this point it's too late, so it won't work.

Second, using your last code with \ExplSyntaxOn outside. Remember that in the expl3 syntax spaces are ignored, so the every node/.style key is actually everynode/.style. And in TikZ spaces do matter. You need every~node/.style.

And last, you execute the node code inside a tikzpicture environment, and this creates a bunch of grouping levels, so any local assignment is lost when the \end{tikzpicture} is reached. You need to use \int_gincr:N to make it work (LaTeX's \stepcounter uses global assignments).

Output:

Working code:

\documentclass[varwidth]{standalone}

\usepackage{expl3}
\usepackage{tikz}

\newcounter{myStandardCounter}

% let's bring ExplSyntax outside of tikzset and try again
\ExplSyntaxOn
\int_new:N \myCounter
\int_gset:Nn \myCounter {0}
\tikzset
{ every~node/.style=
{ /utils/exec=
{ % neither of the counters below are incremented
\int_gincr:N \myCounter
\stepcounter{myStandardCounter}
}
}
}
\ExplSyntaxOff

\begin{document}

\begin{tikzpicture}
\path node{some text};
\end{tikzpicture}

% both counters are at their initial values (zero)

\ExplSyntaxOn
expl3~counter:~\int_use:N\myCounter
\ExplSyntaxOff

standard counter: \the\value{myStandardCounter}

\end{document}