
Я хочу использоватьмакросдля установки разделителей ( &
,\\
)в табличной среде. Таким образом, макрос должен действовать как логический переключатель с тремя состояниями. К сожалению, я продолжаю получать такой результат:
Я уже пробовал макрос вне табличной среды, где он работает нормально. Я думаю, что проблема возникает из-за какой-то проблемы с расширением, но я не знаю, как ее исправить. Я также пробовал использовать или \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
следующую команду (модифицированную команду awesome-cv posquit0), чтобы отделить некоторую необязательную информацию для заголовка 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
и должен решить эту проблему. Имейте в виду, что вам придется сбросить булевы значения на false для нового массива.\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}
С идеей@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}
является.)