LaTex 巨集在表格環境中未正確執行

LaTex 巨集在表格環境中未正確執行

我想用一個設定分隔符號 ( &, \\)在表格環境中。因此,宏應該充當具有三種狀態的布林開關。不幸的是我不斷得到這樣的結果:

在此輸入影像描述而不是這個:在此輸入影像描述

我已經在表格環境之外嘗試過該宏,它運行良好。我相信該問題是由於某些擴展問題而發生的,但我不知道如何解決它。我也嘗試過使用 a \DeclareRobustCommandor \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}

帶著這樣的想法@烏爾里奇迪茲要使用參數{init}{init}作為另一個標誌,我們也可以在沒有全域分配的情況下使事情正常運作。下面每個新單元格都必須以 開頭\setdelim。由於布林值始終在下一個單元啟動後設定(在#1和 之後#2),因此狀態會轉移到下一個單元。

expl3在這個範例中使用了語法,只是為了輕鬆存取\str_if_eq:nnTF(將兩個參數作為字串進行比較的函數)。這樣我就不需要對init@UlrichDiez 提供的兩個參數進行相當複雜的測試。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}

是。

相關內容