使用 \phantom 的 \iffalse 不完整

使用 \phantom 的 \iffalse 不完整

有人能帮我调试下面的代码吗?正如所写,它\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}

第三个策略:忘记xstringpgffor更喜欢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}将在一个步骤中添加正确的数量。

在此处输入图片描述

相关内容