Макрос LaTex не выполняется должным образом в табличной среде

Макрос LaTex не выполняется должным образом в табличной среде

Я хочу использоватьмакросдля установки разделителей ( &,\\ )в табличной среде. Таким образом, макрос должен действовать как логический переключатель с тремя состояниями. К сожалению, я продолжаю получать такой результат:

введите описание изображения здесьвместо этого:введите описание изображения здесь

Я уже пробовал макрос вне табличной среды, где он работает нормально. Я думаю, что проблема возникает из-за какой-то проблемы с расширением, но я не знаю, как ее исправить. Я также пробовал использовать или \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}

является.)

Связанный контент