如何在 tikzset 中使用 \ExplSyntaxOn 和 \ExplSyntaxOff?

如何在 tikzset 中使用 \ExplSyntaxOn 和 \ExplSyntaxOff?

如果将ExplSyntaxon/off 放在 内部tikzset,则 内部的代码(预期可以工作)ExplSyntax会产生错误。但是,如果将 放在ExplSyntax外部tikzset(包含tikzset),则会产生tikzset意外行为。我该如何使用ExplSyntax内部tikzset?或者我需要(再次令人失望地)寻找解决方法吗?

内的块ExplSyntax在内部生成错误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}

虽然 ExplSyntax 中的块不会产生错误,但它不会增加\myCounter,导致其中的标签和定位命令(谁知道还有什么)tikzset产生错误,并阻止标准计数器(myStandardCounter)增加:

\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}

答案1

首先,catcode 更改(\ExplSyntaxOn/ \makeatletter\ExplSyntaxOff/\makeatother等)在宏参数中不起作用。TeX 将输入字符转换为所谓的令牌当它第一次看到该字符时。当你这样做时:

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

\tikzset宏抓取{和之间的所有内容}作为参数,此时,TeX“看到”这些字符,它们使用当前 catcode 机制(使用\ExplSyntaxOff)转换为标记,因此\int_incr:N \myCounter被标记为\int _ i n c r : N \myCounter,并且这种标记化是“冻结”的,这意味着你不能改变它。

此后,/utils/exec密钥发挥作用并被\ExplSyntaxOn执行,但此时已经太晚了,所以它不起作用。


其次,使用您最后的代码,在\ExplSyntaxOn外面。请记住,在expl3语法中空格会被忽略,因此every node/.style关键实际上是everynode/.style。而在 Ti 中Z 空间事。你需要every~node/.style

最后,您在tikzpicture环境中执行节点代码,这会创建一堆分组级别,因此当\end{tikzpicture}达到时,任何本地分配都会丢失。您需要使用\int_gincr:N才能使其工作(LaTeX\stepcounter使用全局分配)。

输出:

在此处输入图片描述

工作代码:

\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}

相关内容