我想定义一个名为的命令\headers
,它采用未定义数量的参数。
例如\headers{Category One}{Category Two}{Category Three}
它将输出以下内容:
\textbf{\textit{Category One}} &
\textbf{\textit{Category Two}} &
\textbf{\textit{Category Three}} \\
\hline
\hline
我的想法是在我使用的自定义 tabularx 包中使用它,所以我可以直接这样做:
\begin{tabularx}{\hsize}{XXX}
\headers{Category One}{Category Two}{Category Three}
\end{tabularx}
我怎样才能实现这样的目标?我看过很多关于xparse
和的内容,\clist_map_inline:nn
但没有一个允许&
角色在第一个参数之后加入任何参数。
任何帮助都将不胜感激。
答案1
您可以获得如下输出:
使用代码:
\documentclass{article}
\usepackage{tabularx}
\usepackage{etoolbox}
\usepackage{booktabs}
\makeatletter
\newcommand\headers[1]{%
\def\sep{}%
\def\realheader{}%
\renewcommand*\do[1]{\protected@xappto\realheader{\sep\textbf{\textit{##1}}}\xdef\sep{&}}
\docsvlist{#1}%
\\\toprule\realheader\\\midrule
}
\makeatother
\begin{document}
\begin{tabularx}{\hsize}{XXX}
\headers{Category one, Category two, Category three}
stuff & stuff & stuff\\
\bottomrule
\end{tabularx}
\end{document}
我没有使用,而是\hline
屈服于我的偏见,使用了书签包,因为我认为这会提供更好的输出。
除了使用书签\docsvlist
与原帖相比,主要的变化是,我改变了语法,使用命令分隔列表作为标题,然后使用电子工具箱包。不幸的是,这似乎需要一点扩展技巧来\protected@xappto
逐个构建标头。
编辑
这是一个更精致的版本,它定义了一个新的表环境mytable
,该环境接受一个参数,该参数将列标题指定为逗号分隔的列表,并且环境主体包含 (tabularx) 环境。使用此代码:
\begin{mytable}{Category one, Category two, Category three}
stuff & stuff & stuff\\
\end{mytable}
生产
这与上面的基本相同,只是我使用了 OP 格式。这种方法的主要优点是您不必指定列标题,例如,
\begin{mytable}{Category one, Category two, Category three, Column four}
stuff & stuff & stuff & stuff\\
\end{mytable}
按预期工作。
以下是修改后的代码(请参阅注释以了解代码的作用):
\documentclass{article}
\usepackage{tabularx}
\usepackage{etoolbox}
\makeatletter
\newcounter{mytablecolumns}% to automate the number of columns
\newenvironment{mytable}[1]{%
\def\sep{}% will be the table column separator
\setcounter{mytablecolumns}{0}% reset column counter
\def\realheader{}% will become the table header
\renewcommand*\do[1]{% construct each entry in the header
\protected@xappto\realheader{\sep\textbf{\textit{##1}}}% add header
\stepcounter{mytablecolumns}% increment column counter
\xdef\sep{&}% set up next column separator
}
\docsvlist{#1}% create the table header
\xdef\sep{*{\arabic{mytablecolumns}}X}% create the table specifications
\expandafter\tabularx\expandafter\hsize\expandafter{\sep}% start tabularx
\realheader\\\hline\hline% insert header and two \hlines
}{\endtabularx}% end tabularx environment
\makeatother
\begin{document}
\begin{mytable}{Category one, Category two, Category three}
stuff & stuff & stuff\\
\end{mytable}
\end{document}
答案2
这是一个基于 LuaLaTeX 的解决方案。请注意,它加载booktabs
包并使用\midrule
而不是\hline\hline
。
所有实际工作都由名为 的 Lua 函数执行headers
,该函数利用了 Lua 的强大string.gsub
功能。该headers
函数被分配给 LuaTeX 的process_input_buffer
回调,该回调在非常早期的阶段运行,前TeX 开始其常规的宏扩展工作。
% !TEX TS-program = lualatex
\documentclass{article}
\usepackage{tabularx,booktabs}
\usepackage{luacode}
\begin{luacode}
-- start of Lua code
function headers ( s )
if string.find ( s , "^%s-\\headers" ) then
s = s:gsub ( "%b{}" , "&\\textbf{\\textit%0}" )
s = s:gsub ( "\\headers&" , "" ) .. "\\\\ \\midrule"
end
return s
end
-- end of Lua code
\end{luacode}
%% assign 'headers' function to LuaTeX's 'process_input_buffer' callback
\AtBeginDocument{\directlua{luatexbase.add_to_callback(
"process_input_buffer",headers,"headers")}}
\begin{document}
\noindent
\begin{tabularx}{\textwidth}{XXX}
\toprule
\headers{Category One}{Category Two}{Category Three}
\end{tabularx}
\end{document}