我正在尝试构建一个宏,可用于将任意数量的项目放置在列表中
目前我的宏看起来像这样
\newcommand\presentation[6]{
\begin{minipage}[t]{\dimexpr(\linewidth) - 3em}
\textbf{#1} \\*
#2 \smallskip
\begin{itemize}
\setlength{\itemindent}{-0.15in}
\item #3 -- #4 #5 #6
\end{itemize}
\end{minipage} \bigskip\\*
}
如果10
输入参数传递给宏,我希望它这样做
\newcommand\presentation[6]{
\begin{minipage}[t]{\dimexpr(\linewidth) - 3em}
\textbf{#1} \\*
#2 \smallskip
\begin{itemize}
\setlength{\itemindent}{-0.15in}
\item #3 -- #4 #5 #6
\item #7 -- #8 #9 #10
\end{itemize}
\end{minipage} \bigskip\\*
}
等等,附加输入变量
基于这我尝试了以下方法但似乎不起作用......
\makeatletter
\newcommand{\present}[6]{%
\begin{minipage}[t]{\dimexpr(\linewidth) - 3em}
\textbf{#1} \\*
#2 \smallskip
\begin{itemize}
\setlength{\itemindent}{-0.15in}
\item #3 -- #4 #5 #6
}
\newcommand{\checknextarg}{\@ifnextchar\bgroup{\gobblenextarg}{
\end{itemize}
\end{minipage}
\bigskip\\*}
}
\newcommand{\gobblenextarg}[4]{ \item #1\@ifnextchar\bgroup{\gobblenextarg} -- #2\@ifnextchar\bgroup{\gobblenextarg} #3\@ifnextchar\bgroup{\gobblenextarg} #4\@ifnextchar\bgroup{\gobblenextarg}
{
\end{itemize}
\end{minipage}
\bigskip\\*
}
}
\makeatother
答案1
您的尝试\present
甚至没有调用\checknextarg
...为了简化代码,我假设参数的数量为 4n + 2 的形式,其中 n 是正整数。否则,需要进行更多测试。
笔记:
\dimexpr
放置它们的地方不需要括号。\bigskip\\*
没有多大意义,因为\bigskip
在大多数情况下它本身就是一个合法的断点(只要它前面是一个不可丢弃的物品垂直列表:一个框、一个东西、一个标记或一个插入——参见 TeXbook 第 110 页,或很短介绍如下)。另外,要小心不要引入不需要的空格。
针对您的具体问题,您可以做这样的事情:
\documentclass{article}
\makeatletter
\newcommand{\presentation}[2]{%
\begin{minipage}[t]{\dimexpr \linewidth - 3em}
\textbf{#1}\\*
#2\smallskip
\begin{itemize}
\setlength{\itemindent}{-0.15in}%
\checknexttoken
}
\newcommand{\checknexttoken}{\@ifnextchar\bgroup{\onemoretime}{\finished}}
\newcommand{\onemoretime}[4]{%
\item #1 -- #2 #3 #4%
\@ifnextchar\bgroup{\onemoretime}{\finished}%
}
\newcommand*{\finished}{%
\end{itemize}
\end{minipage}
\par
% \nopagebreak % uncomment if you want to prevent page breaks here
\bigskip
}
\makeatother
\begin{document}
\presentation{Title}{Items:}{first}{second}{third}{fourth}
\presentation{Title}{Items:}
{first}{second}{third}{fourth}
{fifth}{seventh}{eighth}{ninth}
\presentation{Title}{Items:}
{first}{second}{third}{fourth}
{fifth}{seventh}{eighth}{ninth}
{tenth}{eleventh}{twelfth}{thirteenth}
\end{document}
如果您需要在希望停止参数抓取的位置使用左括号,则只需\relax
在括号前的文本中插入一个,以防止触发“下一轮”。
关于分页的快速注释
当您在外部垂直模式下完成一个段落时,其每一行都会形成一个水平框,因此它是主垂直列表中不可丢弃的项目。主垂直列表中的每一行后面都会跟着“移出”的垂直材料(从\vadjust
、、...)、惩罚项(对于棍棒行或寡妇行等)和自动插入的行间粘连。在某些情况下,粘连项和惩罚项都是潜在的断点。在代表段落行的水平框后面紧跟着主垂直列表中的粘连项(例如,可以从紧随段落之后的粘连项或从自动添加在两个连续行之间的行间粘连中获得粘连\insert
)的常见情况下,因为框根据定义是\mark
\bigskip
不可丢弃,此粘合项是合法的断点(即,分页符可能在框之后立即发生,并且通常会丢弃粘合项:粘合项是可丢弃那些)。
\nopagebreak
插入惩罚项,惩罚项是可丢弃的项,因此\nopagebreak
紧接着的类似项\bigskip
会在主垂直列表中插入粘合项,从而阻止粘合项成为合法断点。\par
只需切换到垂直模式即可。它本身不会插入任何粘合项、框或惩罚项之类的东西。
答案2
我建议采用不同的方法,采用以下环境:
\documentclass{article}
\newenvironment{presentation}[2]
{\par\noindent\begin{minipage}[t]{\dimexpr\linewidth-3em}
\textbf{#1}\\#2\smallskip
\begin{itemize}\setlength{\itemindent}{-0.15in}}
{\end{itemize}\end{minipage}\par\addvspace{2\bigskipamount}}
\newcommand{\present}[4]{\item #1 -- #2 #3 #4}
\begin{document}
\begin{presentation}{Title}{Items:}
\present{first}{second}{third}{fourth}
\present{fifth}{seventh}{eighth}{ninth}
\end{presentation}
\begin{presentation}{Title}{Items:}
\present{first}{second}{third}{fourth}
\end{presentation}
\end{document}
这样做的好处是更加“自由形式”:行与行之间是否使用空行并不重要\present
,因此
\begin{presentation}{Title}{Items:}
\present{first}{second}{third}{fourth}
\present{fifth}{seventh}{eighth}{ninth}
\end{presentation}
将会排版相同。
您是否应该坚持“可变数量参数”的方法:
\documentclass{article}
\newcommand{\presentation}[2]{
\par\noindent\begin{minipage}[t]{\dimexpr\linewidth-3em}
\textbf{#1}\\#2\smallskip
\begin{itemize}\setlength{\itemindent}{-0.15in}
\present
}
\makeatletter
\newcommand{\present}[4]{
\item #1 -- #2 #3 #4
\@ifnextchar\bgroup{\present}{\end{itemize}\end{minipage}\par\addvspace{2\bigskipamount}}%
}
\makeatother
\begin{document}
\presentation{Title}{Items:}
{first}{second}{third}{fourth}
{fifth}{seventh}{eighth}{ninth}
\presentation{Title}{Items:}
{first}{second}{third}{fourth}
\end{document}
输出是一样的。