在这篇文章的帮助下(有没有办法使用“pgfkeys”设置*全局*键值?),我找到了一种更简单的方法来解决我自己的问题(如何在具有表格的自定义环境中使用 pgfkeys 创建使用多个参数的命令?)。我称其为更简单,因为我对 LaTeX 缺乏深入的了解,所以我不理解该帖子中描述的解决方案。
我的解决方案的代码如下:
\documentclass{article}
\usepackage{pgfkeys}
\def\showstatus{%
(level: \the\currentgrouplevel\ --
globaldefs: \the\globaldefs\ --
foo: \pgfkeysvalueof{/rpath/tpath/var3} --
bar: \pgfkeysvalueof{/rpath/tpath/var4})
}
\def\customvarset{\pgfqkeys{/rpath}}
\newenvironment{customenvtab}{%
\newcommand*{\resetvarsettab}{%
\customvarset{%
tpath/.cd,%
var3/.initial=var3 tbd,%
var4/.initial=var4 tbd
}
}
\resetvarsettab
\def\tabval##1{\pgfkeysvalueof{/rpath/tpath/##1}}
\newcommand{\cmdtab}[1]{%
\globaldefs=1
\customvarset{tpath/.cd, ##1}
\tabval{var3} & \tabval{var4}
\globaldefs=1
\resetvarsettab
}
\begin{tabular}{c|c}
}{%
\end{tabular}
}
\begin{document}
\section{Now Working}
%\showstatus
\begin{customenvtab}
\cmdtab{}\\
\cmdtab{var3=test var3}\\
\cmdtab{var4=test var4}\\
\cmdtab{var3=blo, var4=bli}
\end{customenvtab}
%\showstatus
\end{document}
现在的问题是:出于这个目的使用 \globaldefs=1 是否危险?如果是,我需要注意什么?或者我根本不应该使用它?
预先感谢您的帮助!
答案1
“除非您已经审查了其范围内的每一行代码,并且您亲自维护该代码,否则在任何地方使用它都是不安全的
\globaldefs
,这样您就可以确保更改不会使全局定义无效。”
因此,让我们集中精力寻找另一种方法:
您似乎希望通过设置来解决的问题\globaldefs
是设置键仅限于当前表单元格。
较新的 TeX 引擎带来了可扩展原语\expanded
。这可能会引起你的兴趣,因此你可能不需要修改\globaldefs
:
\documentclass{article}
\usepackage{pgfkeys}
\newcommand*\showstatus{%
(level: \the\currentgrouplevel\ --
globaldefs: \the\globaldefs\ --
foo: \pgfkeysvalueof{/rpath/tpath/var3} --
bar: \pgfkeysvalueof{/rpath/tpath/var4})%
}
\newcommand*\customvarset{\pgfqkeys{/rpath}}
\newenvironment{customenvtab}{%
\newcommand*\resetvarsettab{%
\customvarset{%
tpath/.cd,%
var3/.initial=var3 tbd,%
var4/.initial=var4 tbd
}%
}%
\resetvarsettab
\newcommand*\tabval[1]{\pgfkeysvalueof{/rpath/tpath/##1}}%
\newcommand\cmdtab[1]{%
\customvarset{tpath/.cd, ##1}%
{\let\protect\noexpand\expandafter}%
\expandafter\resetvarsettab
\expanded{bold value: \textbf{\tabval{var3}} & italic value: \textit{\tabval{var4}}}%
}%
\begin{tabular}{c|c}%
}{%
\end{tabular}%
}
\begin{document}
\section{Now Working}
%\showstatus
\begin{customenvtab}
\cmdtab{}\\
\cmdtab{var3=test var3}\\
\cmdtab{var4=test var4}\\
\cmdtab{var3=blo, var4=bli}
\end{customenvtab}
%\showstatus
\end{document}
如果您希望进行细粒度的扩展控制,请注意\tabval
需要四个扩展步骤才能提供结果:
步骤 1 传递\pgfkeysvalueof
。
步骤 2 传递\csname...\endcsname
。
步骤 3 传递控制序列标记。
步骤 4 传递控制序列标记的顶层扩展。
四个扩展步骤依次意味着 2 4 -1=15 \expandafter
...
如果你不熟悉\expandafter
扩展技巧,你可能会对这个问题感兴趣如何知道附加到 csname 宏时的 expandafter 数量?及其答案。
\expandafter
影响下一个和下一个标记:
的顶层扩展是下一个\expandafter
标记\expandafter
- 如果下一个标记是可扩展的:下一个标记的顶层扩展。
- 如果下一个 - 倒数一个标记不可扩展:则下一个 - 倒数一个标记。
\documentclass{article}
\usepackage{pgfkeys}
\newcommand*\showstatus{%
(level: \the\currentgrouplevel\ --
globaldefs: \the\globaldefs\ --
foo: \pgfkeysvalueof{/rpath/tpath/var3} --
bar: \pgfkeysvalueof{/rpath/tpath/var4})%
}
\newcommand*\customvarset{\pgfqkeys{/rpath}}
\chardef\stopromannumeral=`\^^00
\newcommand\exchange[2]{#2#1}
\newcommand\passfirsttosecond[2]{#2{#1}}
\newcommand\obtaintabvalandexchange[3]{%
% #1 <tokens to prepend to brace-nested value of pgf-"variable">
% #2 pgf-"variable"
% #3 <stuff to prepend>
% yields
% <stuff to prepend><tokens to prepend to brace-nested value of pgf-"variable">{<value of pgf-"variable">}
\expandafter\exchange\expandafter{\romannumeral
\expandafter\passfirsttosecond\expandafter{%
\romannumeral
\expandafter\expandafter\expandafter\expandafter\expandafter\expandafter\expandafter
\expandafter\expandafter\expandafter\expandafter\expandafter\expandafter\expandafter
\expandafter\stopromannumeral
\tabval{#2}%
}{\stopromannumeral#1}%
}{#3}%
}%
\newenvironment{customenvtab}{%
\newcommand*\resetvarsettab{%
\customvarset{%
tpath/.cd,%
var3/.initial=var3 tbd,%
var4/.initial=var4 tbd
}%
}%
\resetvarsettab
\newcommand*\tabval[1]{\pgfkeysvalueof{/rpath/tpath/##1}}%
\newcommand\cmdtab[1]{%
\customvarset{tpath/.cd, ##1}%
\obtaintabvalandexchange{italic value: \textit}{var4}{%
% You can nest \obtaintabvalandexchange in
% \obtaintabvalandexchange's 3rd argument.
% The last nesting-level then denotes the value in the
% leftmost table-cell.
\obtaintabvalandexchange{bold value: \textbf}{var3}{\resetvarsettab} &
}%
}%
\begin{tabular}{c|c}%
}{%
\end{tabular}%
}
\begin{document}
\section{Now Working}
%\showstatus
\begin{customenvtab}
\cmdtab{}\\
\cmdtab{var3=test var3}\\
\cmdtab{var4=test var4}\\
\cmdtab{var3=blo, var4=bli}
\end{customenvtab}
%\showstatus
\end{document}