有人能帮我调试下面的代码吗?正如所写,它\iffalse error
在\xdef
最后一次迭代的行上产生了一个不完整的结果。问题在某种程度上与\phantom
宏有关,因为它\def\c{0}
工作正常。我知道里面有几个条件测试\phantom
,但我对 TeX 的了解不够,无法弄清楚什么与什么发生了冲突。
\documentclass{article}
\usepackage{tikz,xstring}
\begin{document}
\def\result{}
\foreach \i in {1,...,6}{
\StrChar{12345}{\i}[\c]
\ifx\c\empty
\def\c{\phantom{0}}
\fi
\xdef\result{\result\c}}
\stop
答案1
\phantom
是一个脆弱的命令,在 中并不安全\edef
。本地使其安全的一种方法是:
\documentclass{article}
\usepackage{tikz,xstring}
\begin{document}
\def\result{}
\let\oldphantom\phantom
\let\phantom\relax
\foreach \i in {1,...,6}{
\StrChar{12345}{\i}[\c]
\ifx\c\empty
\def\c{\phantom{0}}
\fi
\xdef\result{\result\c}}
\let\phantom\oldphantom
\show\result
\stop
答案2
您不能拥有\phantom
内部\xdef
,因为它执行分配。
有多种策略可以避免该问题。
第一个策略:使用\protected
宏:
\documentclass{article}
\usepackage{xstring,pgffor}
\protected\def\Pzero{\phantom{0}}
\begin{document}
\def\result{}
\foreach \i in {1,...,6}{%
\StrChar{12345}{\i}[\c]%
\ifx\c\empty
\def\c{\Pzero}%
\fi
\xdef\result{\result\c}%
}
X\result X
\end{document}
循环可以更简单地
\foreach \i in {1,...,6}{%
\StrChar{12345}{\i}[\c]%
\xdef\result{\result\ifx\c\empty\Pzero\else\c\fi}%
}
第二种策略:使用令牌寄存器。
\documentclass{article}
\usepackage{xstring,pgffor}
\newtoks\mytoks
\begin{document}
\def\result{}
\mytoks={}
\foreach \i in {1,...,6}{%
\StrChar{12345}{\i}[\c]%
\ifx\c\empty
\global\mytoks=\expandafter{\the\mytoks\phantom{0}}%
\else
\global\mytoks=\expandafter{\the\expandafter\mytoks\c}%
\fi
}
\edef\result{\the\mytoks}
X\result X
\end{document}
第三个策略:忘记xstring
和pgffor
更喜欢expl3
。
\documentclass{article}
\usepackage{xparse}
\ExplSyntaxOn
\NewDocumentCommand{\padnumber}{mmo}
{% #1 is the final number of digits
% #2 the given number
% #3 is an optional macro to store the result in
\IfNoValueTF{#3}
{
\jay_padnumber:nnn { \tl_use:N \l_jay_partial_tl } { #1 } { #2 }
}
{
\jay_padnumber:nnn { \tl_set_eq:NN #3 \l_jay_partial_tl } { #1 } { #2 }
}
}
\tl_new:N \l_jay_partial_tl
\cs_new_protected:Npn \jay_padnumber:nnn #1 #2 #3
{
% store the given number
\tl_set:Nn \l_jay_partial_tl { #3 }
\int_compare:nT { \tl_count:N \l_jay_partial_tl < #2 }
{
% add as many \phantom{0} as needed
\tl_put_right:Nx \l_jay_partial_tl
{
\prg_replicate:nn { #2 - \tl_count:N \l_jay_partial_tl } { \exp_not:N \phantom { 0 } }
}
}
% produce the result or store it
#1
}
\ExplSyntaxOff
\begin{document}
X1234567890 % test
X\padnumber{6}{12345}X
X\padnumber{7}{12345}X
X\padnumber{4}{12345}X
\padnumber{8}{12345}[\result]
\texttt{\meaning\result}
\end{document}
我们计算参数中的项目数;如果项目数超出给定的参数,则仅打印(或存储)数字。否则,\phantom{0}
将在一个步骤中添加正确的数量。