我想使用宏设置分隔符(&
,\\
)在表格环境中。因此,该宏应充当具有三种状态的布尔开关。不幸的是,我一直得到这样的结果:
我已经在表格环境之外尝试过该宏,它工作正常。我相信问题是由于某些扩展问题引起的,但我不知道如何修复它。我也尝试过使用或\DeclareRobustCommand
,\protect
但结果没有受到影响。
这是我使用的代码:
\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}
编辑:
对于那些仍然想知道整个货物崇拜编程的原因是什么的人。我使用\setdelim
以下命令(posquit0 的 awesome-cv 的修改命令)为 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%
}%
}
此命令允许我在表格环境中打印标题,如下图所示:
或者像这样使用常规分隔符:
答案1
问题是,由于每个单元格组成一个组,因此布尔状态不会跨列和跨行保存。在\booltrue
和\boolfalse
调用前加上前缀\global
应该可以解决这个问题。请记住,对于新数组,您必须将布尔值重置为 false。
\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}
带着这样的想法@UlrichDiez使用参数{init}{init}
作为另一个标志,我们也可以在没有全局分配的情况下使事情正常进行。下面每个新单元格都必须以 开始\setdelim
。由于布尔值总是在下一个单元格启动后设置(在#1
和之后#2
),因此状态会延续到下一个单元格。
我expl3
在本例中使用了语法,只是为了方便访问\str_if_eq:nnTF
(将两个参数作为字符串进行比较的函数)。这样我就不需要 @UlrichDiez 提供的相当复杂的两个参数测试了。当然,也可以使用init
其他解决方案来获得此测试。请注意,和之间的空格会被忽略,所以我不必注释掉每一行的结尾。expl3
\ExplSyntaxOn
\ExplSyntaxOff
\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}
答案2
如果您愿意用 来启动每个表格环境的主体\setdelim{init}{init}
,那么您就可以快速得出 的第一个和第二个参数的连接情况,\setdelim
从而产生序列initinit
并仅使用一个标志来执行。
\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}
(说实话,我不知道
\begin{tabular}{|l|l|}
\setdelim{init}{init} a
\setdelim{&}{\\} b
\setdelim{&}{\\} c
\setdelim{&}{\\} d
\end{tabular}
相比之下
\begin{tabular}{|l|l|}
a&b\\
c&d
\end{tabular}
是。)