誰能幫我調試下面的程式碼?正如所寫的,它在最終迭代中產生了一個不完整的\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
inside \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}
一步添加正確的數量。