我正在尝试使用命名(键值)参数创建命令来生成表格行。原因是表格有超过 9 列(命令参数),这些列的位置将发生变化、被删除或添加。因此很难用常规命令来保存它(因为位置和参数数量有限)。
我尝试让它工作xkeyval
包,但表内部出现问题。这是 MWE:
\documentclass{article}
\usepackage{xkeyval}
\begin{document}
\makeatletter
\define@key{myrowkey}{name}{\def\MyRowName{#1}}
\define@key{myrowkey}{num}{\def\MyRowNum{#1}}
\makeatother
\newcommand\myrow[1]{
\setkeys{myrowkey}{#1}
\MyRowName, \MyRowNum & \\ \hline
}
\newcommand\myrowb[1]{
\setkeys{myrowkey}{#1}
\MyRowName & \MyRowNum \\ \hline
}
\begin{table}
\begin{tabular}{|c|c|}\hline
A & B \\ \hline
\myrow{name=Abc,num=2000}
\myrow{name=Def,num=2000}
\end{tabular}
\end{table}
\end{document}
命令\myrow
按我希望的方式工作,而 则\myrowb
不然,即它会产生错误。如果我\def\MyRowName{...}
用替换\newcommand\MyRowName{}
,则\renewcommand\MyRowName{#1}
不再有错误,而是一个空单元格而不是值 (num)。
答案1
这些定义是在 的第一个单元格内进行的tabular
,不会保留到下一个单元格。您需要使它们的定义成为全局的,以便它们可以跨越多个列。如果您在关键定义中更改\def
为,它将起作用。\gdef
\documentclass{article}
\usepackage{xkeyval}% http://ctan.org/pkg/xkeyval
\begin{document}
\makeatletter
\define@key{myrowkey}{name}{\gdef\MyRowName{#1}}
\define@key{myrowkey}{num}{\gdef\MyRowNum{#1}}
\makeatother
\newcommand\myrow[1]{%
\setkeys{myrowkey}{#1}%
\MyRowName, \MyRowNum & \\ \hline
}
\newcommand\myrowb[1]{%
\setkeys{myrowkey}{#1}%
\MyRowName & \MyRowNum \\ \hline
}
\begin{table}
\begin{tabular}{|c|c|}\hline
A & B \\ \hline
\myrowb{name=Abc,num=2000}
\myrow{name=Def,num=2000}
\end{tabular}
\end{table}
\end{document}
请注意使用%
以避免在\myrow
和的定义中出现虚假空格\myrowb
。请参阅%
行末百分号 ( ) 有什么用?
答案2
没有\gdef
;这样做的好处是,如果您需要省略某些条目,那么您只需不设置键(前提是您在开始时为每个键设置一个空值)。
\documentclass{article}
\usepackage{xkeyval}
\makeatletter
\define@key{myrowkey}{name}{\def\MyRowName{#1}}
\define@key{myrowkey}{num}{\def\MyRowNum{#1}}
\newcommand\myrow[1]{%
\setkeys{myrowkey}{#1}%
\begingroup\protected@edef\x{\endgroup
\MyRowName, \MyRowNum &
}\x \\ \hline
}
\newcommand\myrowb[1]{%
\setkeys{myrowkey}{#1}%
\begingroup\protected@edef\x{\endgroup
\MyRowName & \MyRowNum
}\x \\ \hline
}
\makeatother
\begin{document}
\begin{tabular}{|c|c|}\hline
A & B \\ \hline
\myrow{name=Abc,num=2000}
\myrow{name=Def,num=2000}
\end{tabular}
\begin{tabular}{|c|c|}\hline
A & B \\ \hline
\myrowb{name=Abc,num=2000}
\myrowb{name=Def,num=2000}
\end{tabular}
\end{document}
这个想法是在 TeX “看到” 之前扩展键值&
。
同样的想法在 LaTeX3 中实现
\documentclass{article}
\usepackage{xparse}
\ExplSyntaxOn
\tl_new:N \l_ivan_row_name_tl
\tl_new:N \l_ivan_row_num_tl
\keys_define:nn { ivan/tab }
{
name .code:n = { \tl_set:Nn \l_ivan_row_name_tl { \exp_not:n { #1 } } },
name .initial:n = {},
num .code:n = { \tl_set:Nn \l_ivan_row_num_tl { \exp_not:n { #1 } } },
num .initial:n = {}
}
\NewDocumentCommand\myrow{m}
{
\keys_set:nn { ivan/tab } { #1 }
\use:x
{
\l_ivan_row_name_tl,~\l_ivan_row_num_tl
&
}
\\ \hline
}
\NewDocumentCommand\myrowb{m}
{
\keys_set:nn { ivan/tab } { #1 }
\use:x
{
\l_ivan_row_name_tl & \l_ivan_row_num_tl
}
\\ \hline
}
\ExplSyntaxOff
\begin{document}
\begin{tabular}{|c|c|}\hline
A & B \\ \hline
\myrow{name=Abc,num=2000}
\myrowb{name=\textbf{X}} % no num
\myrowb{name=Def,num=1}
\end{tabular}
\end{document}
如您所见,不提供值将使条目保持为空。添加键使用相同的方案。