pgf 内部宏

pgf 内部宏

我正在尝试创建一个宏,有条件地打印作为参数给出的任何内容。但是,当这样的参数是带有函数定义的 tikzpicture 时,我得到

Paragraph ended before pgfmath@local@@functions was complete

以及其他缺失的 \endgroup(如果我尝试使用该函数,情况会更糟)。我在内联 foreach 中遇到了同样的问题,但我通过使用 {} 正确分隔 foreach 块解决了这个问题。

这是一个 MWE:

\documentclass[a4paper,11pt]{article}

\usepackage[utf8x]{inputenc}
\usepackage[T1]{fontenc}
\usepackage{lmodern}
\usepackage[frenchb]{babel}
\usepackage{tikz}
\usetikzlibrary{babel}%compatibility babel & pgf
\usepackage{pgfplots}
\pgfplotsset{compat=1.12}

\newcommand{\mymacro}[1]{%
#1
}

\begin{document}
\mymacro{%If I remove this macro, no errors.
\begin{tikzpicture}[declare function={myfun(\x)=\x;}]
\begin{axis}[
    axis lines=center,/pgf/number format/.cd,
    use comma,
    enlargelimits=upper,
    samples=50
]
    \addplot [thick, smooth, domain=-3:3] {myfun(x)};
\end{axis}
\end{tikzpicture}
}

\end{document}

有办法解决此类问题吗?

编辑:仍然对“干净”的修复感兴趣(因为这看起来像是我可能会再次遇到的 babel/pgf 错误),但我最终选择了不同的路线,所以不需要肮脏的东西。在 MWE 中添加了情节,因为它也会引发错误。

答案1

如果您在这里搜索babeltikz您会发现很多有关这些包一起使用时引起的问题的信息。人们投入了大量工作来使它们很好地协同工作,最终形成了babeltikz 库。

tikz 库的工作方式babel是暂时暂停 tikzpicture 中的 babel 快捷方式。这可确保所有“特殊”字符恢复到其通常含义,因此 tikz 和 pgf 内部的各种机制不会混淆。它通过在启动 tikzpicture 环境时调用特定命令来实现这一点。这里的关键是调用该命令其余环境的任何部分都已被解析。

你所做的事情的问题在于,通过将 tikzpicture 放在宏参数中,你迫使 TeX 在检查代码之前读取整个代码。因此,当启动 tikzpicture 并调用魔法时,tikzpicture 的内容已经冻结,魔法没有效果[1]。

最便宜的解决方法可能是确保您的命令过早冻结 tikzpicture,或者至少在读取 tikzpicture 之前自己调用魔术命令。以下是执行此操作的一种方法:

\documentclass[a4paper,11pt]{article}
%\url{http://tex.stackexchange.com/q/254955/86}
\usepackage[utf8x]{inputenc}
\usepackage[T1]{fontenc}
\usepackage{lmodern}
\usepackage[frenchb]{babel}
\usepackage{tikz}
\usetikzlibrary{babel}%compatibility babel & pgf
\usepackage{pgfplots}
\pgfplotsset{compat=1.11}


\newcommand{\mymacro}{%
  \begingroup
  \shorthandoff{;}
  \myrealmacro
}

\newcommand{\myrealmacro}[1]{%
  #1
  \endgroup
}


\begin{document}

\mymacro{%If I remove this macro, no errors.
  \begin{tikzpicture}[declare function={myfun(\x)=\x;}]
\begin{axis}[
    axis lines=center,/pgf/number format/.cd,
    use comma,
    enlargelimits=upper,
    samples=50
]
    \addplot [thick, smooth, domain=-3:3] {myfun(x)};
\end{axis}
\end{tikzpicture}
}
\end{document}

[1] 众所周知,魔法无法影响冻结的物体。

答案2

这似乎是特定的问题declare function,因为

\documentclass[a4paper,11pt]{article}

\usepackage[T1]{fontenc}
\usepackage[utf8]{inputenc}
\usepackage[frenchb]{babel}
\usepackage{lmodern}

\usepackage{tikz}
\usetikzlibrary{babel}%compatibility babel & pgf
\usepackage{pgfplots}
\pgfplotsset{compat=1.12}

\newcommand{\mymacro}[1]{%
  #1%
}

\begin{document}

\mymacro{%
  \begin{tikzpicture}
  \draw (1,1) -- (2,2);
  \end{tikzpicture}%
}

\end{document}

运行正常。您的问题不依赖于\mymacro,因为可以用 替换 来重现\mbox

糟糕的解决方法:

\documentclass[a4paper,11pt]{article}

\usepackage[T1]{fontenc}
\usepackage[utf8]{inputenc}
\usepackage[frenchb]{babel}
\usepackage{lmodern}

\usepackage{tikz}
\usetikzlibrary{babel}%compatibility babel & pgf
\usepackage{pgfplots}
\pgfplotsset{compat=1.12}

\newcommand{\mymacro}[1]{%
  #1%
}

\begin{document}

\mymacro{%
  \begingroup\let\begin\relax\let\x\relax\edef\x{\endgroup
    \begin{tikzpicture}[declare function={myfun(\x)=\x\string;}]}\x
  \draw (1,1) -- (2,2);
  \end{tikzpicture}%
}

\end{document}

相关内容