考虑一下这个MWE:
\documentclass[varwidth,tightpage,border=1bp]{standalone}
\usepackage{tikz}
\begin{document}
\begin{tikzpicture}
\makeatletter
\gdef\getMyInfoString{%
\let\trfm\relax % ! Undefined control sequence.
\pgfgettransform{\trfm}% with previous commented: ! Undefined control sequence. <argument> \trfm
\edef\tout{%
pgfgettransform: \trfm ; %
pgf@pt@aa, pgf@pt@ba, pgf@pt@ab, pgf@pt@bb: \pgf@pt@aa, \pgf@pt@ba, \pgf@pt@ab, \pgf@pt@bb %
}
\tout % output tout
}
\makeatother
\pgfgettransform{\trfmX}%
\makeatletter
\typeout{Manually check: %
pgfgettransform: \trfmX ; %
pgf@pt@aa, pgf@pt@ba, pgf@pt@ab, pgf@pt@bb: \pgf@pt@aa, \pgf@pt@ba, \pgf@pt@ab, \pgf@pt@bb %
}
\makeatother
\typeout{This is via macro function: \getMyInfoString}%
\end{tikzpicture}
\end{document}
如果你编译它,首先\typeout
会将以下内容打印到标准输出:
Manually: pgfgettransform: {1.0}{0.0}{0.0}{1.0}{0.0pt}{0.0pt}; pgf@pt@aa, pgf@p
t@ba, pgf@pt@ab, pgf@pt@bb: 1.0, 0.0, 0.0, 1.0
...而第二个\typeout
引发了一个错误:
! Undefined control sequence.
\getMyInfoString ->\let \trfm
\relax \pgfgettransform {\trfm }\edef \tout {p...
l.30 \typeout{This is: \getMyInfoString}
%
?
显然,latex
想要执行控制\trfm
序列/命令/标记/宏 - 虽然我打算将其作为一个“局部变量”,但它将用作“参数” \pgfgettransform
(然后用数据填充它)。
有没有办法“保护”这个\trfm
宏 - 以便\getMyInfoString
正确执行,并在调用时返回一个字符串(我猜是以可扩展的方式,因为意图是在中使用它\typeout
)?
答案1
如果要获取日志文件中的当前转换数据,只需执行 之前的命令即可\typeout
。
\documentclass{article}
\usepackage{tikz}
\makeatletter
\def\getMyInfoString{%
\pgfgettransform{\trfm}%
\edef\tout{%
\space\space pgfgettransform: \trfm ;^^J%
\space\space pgf@pt@aa: \pgf@pt@aa;^^J%
\space\space pgf@pt@ba: \pgf@pt@ba;^^J%
\space\space pgf@pt@ab: \pgf@pt@ab;^^J%
\space\space pgf@pt@bb: \pgf@pt@bb
}%
\typeout{Here's the current transform:^^J\tout} % output tout
}
\makeatother
\begin{document}
\begin{tikzpicture}
\getMyInfoString
\end{tikzpicture}
\end{document}
日志文件中的输出是
Here's the current transform:
pgfgettransform: {1.0}{0.0}{0.0}{1.0}{0.0pt}{0.0pt};
pgf@pt@aa: 1.0;
pgf@pt@ba: 0.0;
pgf@pt@ab: 0.0;
pgf@pt@bb: 1.0
您不能在 中执行赋值\typeout
;定义就是赋值。
答案2
怎么样:
\documentclass{scrartcl}
\usepackage{tikz}
\begin{document}
\begin{tikzpicture}
\pgfgettransformentries{ \a }{\b }{ \c }{ \d }{ \sx }{ \sy }
\typeout{a=\a, b=\b, c=\c, d=\d, sx=\sx, sy=\sy}
\end{tikzpicture}
\end{document}
哪个会产生a=1.0, b=0.0, c=0.0, d=1.0, sx=0.0pt, sy=0.0pt
并避免令人讨厌的普通 TeX 黑客?
编辑:好的,看了你的评论后,我明白你又陷入了什么命令在什么时候被展开的困境。看来 typeout 在这里相当糟糕。不幸的是,我无法给你一些\expandafter
解决这种情况的魔法,但一个简单的解决方法是将设置变量和产生输出分开,例如
\documentclass{scrartcl}
\usepackage{tikz}
\newcommand\setVars{\pgfgettransformentries{\a}{\b}{\c}{\d}{\sx}{\sy}}
\newcommand\printVars{a=\a, b=\b, c=\c, d=\d, sx=\sx, sy=\sy}
\begin{document}
\setVars\typeout{\printVars}
\end{document}
答案3
我会将其作为答案发布,因为它确实有一定的帮助 - 如果崩溃的“本地选项”宏是预先“预定义”的\gdef
(这里只是相关的代码片段):
\makeatletter
\gdef\tout{}\gdef\trfm{} % ** this
\gdef\getMyInfoString{%
\let\trfm\relax % ! Undefined control sequence.
\pgfgettransform{\trfm}% with previous commented: ! Undefined control sequence. <argument> \trfm
\edef\tout{%
pgfgettransform: \trfm ; %
pgf@pt@aa, pgf@pt@ba, pgf@pt@ab, pgf@pt@bb: \pgf@pt@aa, \pgf@pt@ba, \pgf@pt@ab, \pgf@pt@bb %
}
\tout % output tout
}
\makeatother
...然后 MWE 似乎通过了,没有编译错误;并且它打印出:
Manually check: pgfgettransform: {1.0}{0.0}{0.0}{1.0}{0.0pt}{0.0pt}; pgf@pt@aa,
pgf@pt@ba, pgf@pt@ab, pgf@pt@bb: 1.0, 0.0, 0.0, 1.0
This is via macro function: \let \relax \edef {{1.0}{0.0}{0.0}{1.0}{0.0pt}{0.0p
t}} \edef {pgfgettransform: ; pgf@pt@aa, pgf@pt@ba, pgf@pt@ab, pgf@pt@bb: 1.0,
0.0, 0.0, 1.0}
显然,通过宏打印出来的结果并不完全符合预期 - 这就是为什么最好有一个正确的答案;但至少在这种情况下,所需的信息泄漏到标准输出 - 这对我来说已经足够了:)