\iffalse incompleto usando \phantom

\iffalse incompleto usando \phantom

Alguém pode me ajudar a depurar o código abaixo? Conforme está escrito, produz um Incomplete \iffalse errorna \xdeflinha da iteração final. O problema está de alguma forma relacionado à \phantommacro, pois \def\c{0}funciona bem. Eu sei que existem alguns testes condicionais dentro do \phantom, mas não sou um assistente do TeX o suficiente para descobrir o que está colidindo com o quê.

\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

Responder1

\phantomé um comando frágil e não é seguro em um arquivo \edef. Uma maneira de torná-lo seguro localmente é:

\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

Responder2

Não pode ter \phantominside \xdef, pois ele realiza atribuições.

Existem diversas estratégias para evitar o problema.

Primeira estratégia: use uma \protectedmacro:

\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}

O loop pode ser, de forma mais simples,

\foreach \i in {1,...,6}{%
  \StrChar{12345}{\i}[\c]%
  \xdef\result{\result\ifx\c\empty\Pzero\else\c\fi}%
}

Segunda estratégia: use registros de token.

\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}

Terceira estratégia: esquecer xstringe pgfforpreferir 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}

Contamos os itens do argumento; se o número de itens exceder o argumento fornecido, o número será simplesmente impresso (ou armazenado). Caso contrário, o número certo de \phantom{0}será adicionado em uma única etapa.

insira a descrição da imagem aqui

informação relacionada