¿Alguien puede ayudarme a depurar el siguiente código? Tal como está escrito, produce un Incompleto \iffalse error
en la \xdef
línea de la iteración final. El problema está relacionado de alguna manera con la \phantom
macro, ya que \def\c{0}
funciona bien. Sé que hay un par de pruebas condicionales dentro \phantom
, pero no soy lo suficientemente experto en TeX para descubrir qué está chocando con 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
Respuesta1
\phantom
Es un comando frágil y no seguro en un archivo \edef
. Una forma de hacerlo seguro localmente es:
\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
Respuesta2
No puedes tenerlo \phantom
dentro \xdef
, porque realiza tareas.
Existen varias estrategias para evitar el problema.
Primera estrategia: usa una \protected
macro:
\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}
El bucle puede ser, más simplemente,
\foreach \i in {1,...,6}{%
\StrChar{12345}{\i}[\c]%
\xdef\result{\result\ifx\c\empty\Pzero\else\c\fi}%
}
Segunda estrategia: utilice registros de tokens.
\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}
Tercera estrategia: olvidar xstring
y pgffor
y preferir 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 los elementos del argumento; si el número de elementos excede el argumento dado, el número simplemente se imprime (o almacena). De lo contrario, \phantom{0}
se agrega el número correcto en un solo paso.