LaTex-Makro wird in tabellarischer Umgebung nicht richtig ausgeführt

LaTex-Makro wird in tabellarischer Umgebung nicht richtig ausgeführt

Ich möchte einenMakro&um die Trennzeichen ( , \\) festzulegenin einer tabellarischen Umgebung. Das Makro soll dabei als Boolescher Schalter mit drei Zuständen fungieren. Leider erhalte ich immer wieder folgendes Ergebnis:

Bildbeschreibung hier eingebenan Stelle von:Bildbeschreibung hier eingeben

Ich habe das Makro bereits außerhalb der tabellarischen Umgebung ausprobiert und es funktionierte einwandfrei. Ich glaube, das Problem tritt aufgrund eines Erweiterungsproblems auf, weiß aber nicht, wie ich es beheben kann. Ich habe auch versucht, ein \DeclareRobustCommandoder zu verwenden \protect, aber das Ergebnis wurde dadurch nicht beeinflusst.

Hier ist der Code, den ich verwendet habe:

\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}

Bearbeiten: Für diejenigen unter Ihnen, die sich immer noch fragen, was der Grund für diese ganze Cargo-Kult-Programmierung ist. Ich verwende \setdelimden folgenden Befehl (modifizierter Befehl von posquit0s awesome-cv), um einige optionale Informationen für den CV-Header abzutrennen.

\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%
        }%
    }

Mit diesem Befehl kann ich eine Kopfzeile in einer tabellarischen Umgebung drucken, wie in der folgenden Abbildung gezeigt:

Bildbeschreibung hier eingeben

Oder so mit normalen Trennzeichen:

Bildbeschreibung hier eingeben

Antwort1

Das Problem besteht darin, dass Ihre booleschen Zustände nicht über Spalten und Zeilen hinweg gespeichert werden, da jede Zelle eine Gruppe bildet. Das Voranstellen der \booltrueund \boolfalse-Aufrufe mit \globalsollte dieses Problem lösen. Denken Sie daran, dass Sie die booleschen Werte für ein neues Array auf „false“ zurücksetzen müssen.

\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}

Mit der Idee von@UlrichDiezUm die Argumente {init}{init}als weiteres Flag zu verwenden, können wir es auch ohne globale Zuweisungen zum Laufen bringen. Im Folgenden muss jede neue Zelle mit gestartet werden \setdelim. Da der Boolean immer erst gesetzt wird, nachdem die nächste Zelle gestartet wurde (nach #1und #2), wird der Status auf die nächste Zelle übertragen.

Ich habe expl3für dieses Beispiel Syntax verwendet, um einfachen Zugriff auf \str_if_eq:nnTF(eine Funktion, die die beiden Argumente als Zeichenfolgen vergleicht) zu haben. Auf diese Weise brauche ich nicht den ziemlich komplizierten Test für beide Argumente, initden @UlrichDiez bereitstellt. Andere Lösungen, um diesen Test ohne zu erhalten, expl3sind natürlich möglich. Beachten Sie, dass Leerzeichen zwischen \ExplSyntaxOnund \ExplSyntaxOffignoriert werden, sodass ich nicht jedes Zeilenende kommentieren muss.

\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}

Antwort2

Wenn Sie bereit sind, den Hauptteil jeder tabellarischen Umgebung mit zu beginnen , können Sie den Fall der Verkettung des ersten und zweiten Arguments von \setdelim{init}{init}herausarbeiten, was die Sequenz ergibt , und mit nur einem Flag auskommen.\setdeliminitinit

\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}

(Ehrlich gesagt, ich weiß nicht, was der Vorteil von

\begin{tabular}{|l|l|}
\setdelim{init}{init} a
\setdelim{&}{\\} b
\setdelim{&}{\\} c
\setdelim{&}{\\} d
\end{tabular}

gegenüber der deutlich kürzeren

\begin{tabular}{|l|l|}
a&b\\
c&d
\end{tabular}

Ist.)

verwandte Informationen