
quiero usar unmacropara configurar los separadores ( &
,\\
)en un entorno tabular. Por tanto, la macro debería actuar como un interruptor booleano con tres estados. Desafortunadamente sigo obteniendo un resultado como este:
Ya probé la macro fuera del entorno tabular donde funciona bien. Creo que el problema se debe a algún problema de expansión pero no sé cómo solucionarlo. También intenté usar a \DeclareRobustCommand
or \protect
, pero el resultado no se ve afectado.
Aquí está el código que utilicé:
\documentclass{article}
\usepackage{etoolbox}
% Define command for automatic setting of delimeters
% Usage: \setdelim{<delim1>}{<delim2>}
\newbool{startflag}
\newbool{delimflag}
\newcommand*{\setdelim}[2]{%
\ifbool{startflag}{
\ifbool{delimflag}{% if true
#1
\boolfalse{delimflag}\ignorespaces
}{}% false is somehow not working in tabular environment}
\notbool{delimflag}{% if false
#2
\booltrue{delimflag}\ignorespaces
}{}% true is as well not working in tabular environment}
}{%
\setbool{startflag}{true}
\setbool{delimflag}{true}\ignorespaces
}
}
\begin{document}
\begin{tabular}{|l|l|}
\setdelim{init}{init} a
\setdelim{\span}{\cr} b
\setdelim{\span}{\cr} c
\setdelim{\span}{\cr} d
\end{tabular}
\end{document}
Editar:
Para aquellos de ustedes que todavía se preguntan cuál es el motivo de toda esta programación de culto a la carga. Utilizo \setdelim
el siguiente comando (comando modificado de awesome-cv de posquit0) para separar información opcional para el encabezado del cv.
\newcommand*{\@headersocial}[3][unframed]{%
\global\boolfalse{startflag}% reset startflag
\ifthenelse{\isundefined{\@address}}%
{}{%
\@setdelim{##2}{##3}%
\icon[##1]{\acvHeaderIconSize}{MapMarker}{\@address}%
}%
\ifthenelse{\isundefined{\@mobile}}%
{}{%
\@setdelim{##2}{##3}%
\icon[##1]{\acvHeaderIconSize}{Mobile}{\@mobile}%
}%
\ifthenelse{\isundefined{\@email}}%
{}{%
\@setdelim{##2}{##3}%
\href{mailto:\@email}{\icon[##1]{\acvHeaderIconSize}{Envelope}{\@email}}%
}%
\ifthenelse{\isundefined{\@homepage}}%
{}{%
\@setdelim{##2}{##3}%
\href{http://\@homepage}{\icon[##1]{\acvHeaderIconSize}{Home}{\@homepage}}%
}%
\ifthenelse{\isundefined{\@github}}%
{}{%
\@setdelim{##2}{##3}%
\href{https://github.com/\@github}{\icon[##1]{\acvHeaderIconSize}{GithubSquare}{\@github}}%
}%
\ifthenelse{\isundefined{\@linkedin}}%
{}{%
\@setdelim{##2}{##3}%
\href{https://www.linkedin.com/in/\@linkedin}{\icon[##1]{\acvHeaderIconSize}{Linkedin}{\@linkedin}}%
}%
\ifthenelse{\isundefined{\@skype}}%
{}{%
\@setdelim{##2}{##3}%
\icon[##1]{\acvHeaderIconSize}{Skype}{\@skype}%
}%
\ifthenelse{\isundefined{\@extrainfo}}%
{}{%
\@setdelim{##2}{##3}%
\@extrainfo%
}%
}
Este comando me permite imprimir un encabezado en un entorno tabular, como se muestra en la siguiente figura:
O así usando delimitadores regulares:
Respuesta1
El problema es que sus estados booleanos no se guardarán en columnas y filas ya que cada celda forma un grupo. Prefijar las llamadas \booltrue
y con debería resolver este problema. Tenga en cuenta que tendrá que restablecer los valores booleanos a falso para una nueva matriz.\boolfalse
\global
\documentclass{article}
\usepackage{etoolbox}
% Define command for automatic setting of delimeters
% Usage: \setdelim{<delim1>}{<delim2>}
\newbool{startflag}
\newbool{delimflag}
\newcommand*{\setdelim}[2]
{%
\ifbool{startflag}
{%
\ifbool{delimflag}
{%
#1%
\global\boolfalse{delimflag}%
}
{%
#2%
\global\booltrue{delimflag}%
}%
}
{%
\global\booltrue{startflag}%
\global\booltrue{delimflag}%
}%
\ignorespaces
}
\begin{document}
\begin{tabular}{|l|l|}
\setdelim{init}{init} a
\setdelim{&}{\\} b
\setdelim{&}{\\} c
\setdelim{&}{\\} d
\end{tabular}
\end{document}
Con la idea de@UlrichDiezPara usar los argumentos {init}{init}
como otra bandera, también podemos hacer que las cosas funcionen sin asignaciones globales. A continuación, cada nueva celda debe comenzar con \setdelim
. Dado que el valor booleano siempre se establece después de que comience la siguiente celda (después de #1
y #2
), el estado se transfiere a la siguiente celda.
Utilicé expl3
la sintaxis para este ejemplo, sólo para tener fácil acceso a \str_if_eq:nnTF
(una función que compara los dos argumentos como cadenas). De esta manera no necesito la prueba bastante complicada para ambos argumentos proporcionada init
por @UlrichDiez. expl3
Por supuesto, son posibles otras soluciones para realizar esta prueba . Tenga en cuenta que los espacios entre \ExplSyntaxOn
y \ExplSyntaxOff
se ignoran, por lo que no tengo que comentar el final de cada línea.
\documentclass[]{article}
\ExplSyntaxOn
\bool_new:N \l__erdinale_setdelim_bool
\cs_new_protected:Npn \erdinale_setdelim:nn #1#2
{
\str_if_eq:nnTF { {#1} {#2} } { {init} {init} }
{ \bool_set_true:N \l__erdinale_setdelim_bool }
{
\bool_if:NTF \l__erdinale_setdelim_bool
{
#1
\bool_set_false:N \l__erdinale_setdelim_bool
}
{
#2
\bool_set_true:N \l__erdinale_setdelim_bool
}
}
}
\cs_new_eq:NN \setdelim \erdinale_setdelim:nn
\ExplSyntaxOff
\begin{document}
\begin{tabular}{|l|l|}
\setdelim{init}{init} a
\setdelim{&}{\\} b
\setdelim{&}{\\} c
\setdelim{&}{\\} d
\end{tabular}
\begin{tabular}{|l|l|}
\setdelim{init}{init} a
\setdelim{&}{\\} b
\setdelim{&}{\\} c
\setdelim{&}{\\} d
\end{tabular}
\end{document}
Respuesta2
Si está dispuesto a comenzar el cuerpo de cada entorno tabular con \setdelim{init}{init}
, entonces puede resolver el caso de la concatenación del \setdelim
primer y segundo argumento de , lo que produce la secuencia initinit
y hacerlo con una sola bandera.
\documentclass{article}
\usepackage{etoolbox}
\makeatletter
\newcommand\CheckWhetherinitinit[1]{%
\ifcat$\detokenize\expandafter{\gobbletoexclam#1!}$%
\expandafter\@firstoftwo\else\expandafter\@secondoftwo\fi
% As #1 can contain & and \\ \@firstofone{...} is needed to "hide" #1 from the tabular/alignment.
{\expandafter\@firstofone\expandafter{\forkinitinit#1!{\@firstoftwo}initinit!{\@secondoftwo}!!!}}%
{\@secondoftwo}%
}%
\@ifdefinable\forkinitinit{\long\def\forkinitinit#1initinit!#2#3!!!{#2}}%
\@ifdefinable\gobbletoexclam{\long\def\gobbletoexclam#1!{}}%
\makeatother
% Define command for automatic setting of delimeters
% Usage: \setdelim{<delim1>}{<delim2>}
\newbool{delimflag}
\newcommand*{\setdelim}[2]{%
\CheckWhetherinitinit{#1#2}{%
\booltrue{delimflag}%
}{%
\ifbool{delimflag}{%
#1%
\boolfalse{delimflag}%
}{%
#2%
\booltrue{delimflag}%
}%
}%
}%
\begin{document}
\begin{tabular}{|l|l|}
\setdelim{init}{init} a
\setdelim{&}{\\} b
\setdelim{&}{\\} c
\setdelim{&}{\\} d
\end{tabular}
\begin{tabular}{|l|l|}
\setdelim{init}{init} a
\setdelim{&}{\\} b
\setdelim{&}{\\} c
\setdelim{&}{\\} d
\end{tabular}
\end{document}
(Para ser honesto, no sé cuál es el beneficio de
\begin{tabular}{|l|l|}
\setdelim{init}{init} a
\setdelim{&}{\\} b
\setdelim{&}{\\} c
\setdelim{&}{\\} d
\end{tabular}
versus el considerablemente más corto
\begin{tabular}{|l|l|}
a&b\\
c&d
\end{tabular}
es.)