是否可以创建一个\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}