是否可以创建一个类似 \newcolumntype 的宏,接受多个参数,其中一个是可选参数?

是否可以创建一个类似 \newcolumntype 的宏,接受多个参数,其中一个是可选参数?

是否可以创建一个\newcolumntype接受多个参数并且其中一个是可选参数的类似宏?


我想创建一个A可以接受多个参数的列类型,以便我可以创建如下表格:

\begin{tabular}{|A[2cm]{1cm}{5cm}|c|l|r|}
...
\end{tabular}

笔记:A在此示例中,列类型接受 3 个参数。

答案1

Herbert 已经解释了如何实现强制参数。可选参数也是可行的,但需要一些低级黑客技术、辅助函数,不适合胆小的人。您可以在以下位置看到相同方法的两个版本数字打印希尼奇(后者是前者的改编)。

\makeatletter
\newtoks\mytoks
\mytoks\expandafter{\the\NC@list}
\newcolumntype{A}{}
\NC@list\expandafter{\the\mytoks \NC@do A}
\renewcommand*{\NC@rewrite@A}[3][]{%
  \@temptokena\expandafter{%
    \the\@temptokena 
      % INSERT DEFINITION HERE!
  }%
  \NC@find
}
\makeatother

答案2

没有可选参数,只有强制参数:

\documentclass{article}
\usepackage{array} 

\newcolumntype{A}[3]{@{\vrule\kern#1\vrule}p{#2}@{\vrule\kern#3\vrule}}
\begin{document} 

\begin{tabular}{|A{2cm}{1cm}{5cm}|c|l|r|}
foo & bar & baz & foobar
\end{tabular}

\end{document}

答案3

约瑟夫·赖特的回答我开发了一个 hack,允许使用以下命令使用可选参数定义新的列类型\newcolumntype

\documentclass{article}
\usepackage{array}
\usepackage{booktabs}

% ---------- hack to allow optional parameters with \newcolumntype ----------
\makeatletter
% newcommand with default value for optional parameter but without test whether command exists
% because array package has a different policy: warning instead of error if column type is already defined
\def\@xargdef@withoutcheck#1[#2][#3]#4{%
    % copied from \show\@xargdef without \@ifdefinable
    % also see The LaTeX 2e Sources (2014/05/01 p24f)
    \expandafter \def \expandafter #1\expandafter {%
        \expandafter \@protected@testopt \expandafter #1\csname \string #1\endcsname {#3}%
    }%
    \expandafter \@yargdef \csname \string #1\endcsname \tw@ {#2}{#4}%
}

% save a backup of original command which I am going to override
\let\original@newcol@\newcol@

% redefine a command which is internally called by \newcolumntype.
% check whether column type is already existing has already been done
% and existence of first optional argument (number of parameters) has been confirmed,
% see array package documentation (November 3, 2014 p21f).
% check whether 2nd optional argument is given:
\def\newcol@#1[#2]{%
    \@ifnextchar[%
        {\my@newcol@#1[#2]}%
        {\original@newcol@#1[#2]}%
}

% custom command which handles 2nd optional argument (default value of optional parameter)
\def\my@newcol@#1[#2][#3]#4{\expandafter\@xargdef@withoutcheck\csname NC@rewrite@#1\endcsname[#2][#3]{\NC@find#4}}
\makeatother


% ---------- example usage ----------
\newcolumntype{m}[1][c]{>{$} #1 <{$}}
\newcolumntype{M}[1][c]{>{\displaystyle}m[#1]}

\newcolumntype{A}[3][0em]{>{\typeout{opt: #1}\rule[#1]{#2}{#3}} l <{\rule[#1]{#2}{#3}}}


% ---------- test document ----------
\begin{document}
\begin{center}
\begin{tabular}{M[l] M M[r]}
    \toprule
    a+b=c & a+b=c & a+b=c \\
    1 & 2 & 3 \\
    \bottomrule
\end{tabular}
\end{center}
\bigskip

Please note that in this case it is necessary to add curley braces around the optional argument because otherwise the `m' of the unit would be interpreted as a column specifier:
\begin{center}
\begin{tabular}{A{1em}{.5pt} A[{.3em}]{1em}{.5pt}}
    \toprule
    1 & a\\ 
    2 & b\\
    3 & c\\
    hello & world \\
    \bottomrule
\end{tabular}
\end{center}
\end{document}

答案4

tblr使用我的新 LaTeX3 软件包环境,一切都变得非常简单tabularray。您可以使用命令和一个可选参数\NewColumnType来创建一个新的列类型。A

\documentclass{article}

\usepackage{tabularray}
\UseTblrLibrary{booktabs}

\NewColumnType{A}[3][0em]{>{\rule[#1]{#2}{#3}} l <{\rule[#1]{#2}{#3}}}

\begin{document}

\begin{tblr}{A{1em}{.5pt} A[.3em]{1em}{.5pt}}
  \toprule
    1 & a\\ 
    2 & b\\
    3 & c\\
    hello & world \\
  \bottomrule
\end{tblr}

\end{document}

在此处输入图片描述

相关内容