是否可以将行尾的内容捕获为宏参数?
例如,考虑以下简单的可视化:
\documentclass{article}
\newenvironment{myitemize}
{\def\item{\textbullet\ }}
{}
\begin{document}
\begin{myitemize}
\item First
\item Second
\item Third
\item Last
\end{myitemize}
\end{document}
我想\item
用类似的东西来定义
\def\item#1\par{<do stuff with #1>}
但这需要在要拾取的项目之间留有空行\par
:
\documentclass{article}
\newenvironment{myitemize}
{\def\item##1\par{\textbullet\ ##1\par}}
{}
\begin{document}
\begin{myitemize}
\item First
\item Second
\item Third
\item Last
\end{myitemize}
\end{document}
看着\obeylines
latex.ltx
我认为这可能与有关^^M
,但我不确定如何将其纳入到的定义中\item
。
答案1
您可以使用environ
:
\documentclass{article}
\usepackage{environ}
\makeatletter
\NewEnviron{myitemize}{%
\def\item##1\item{\dosomething{##1}}%
\expandafter\@empty\BODY\item}
\newcommand{\dosomething}[1]{%
\def\werner@arg{#1}%
\ifx\werner@arg\werner@stop
\expandafter\env@ignore % to end the recursion
\else
``Here is #1\unskip''\par % what to do with #1
\expandafter\item % to continue the recursion
\fi}
\edef\werner@stop{\noexpand\env@ignore\space}
\makeatother
\begin{document}
\begin{myitemize}
\item First
\item Second
\item Last
\end{myitemize}
\end{document}
请注意\end{myitemize}
应该单独占一行(也可以让它与最后一项出现在同一行)。\unskip
如果\par
不在 旁边#1
或根本没有使用 ,则 是必需的,因为行尾位于项目文本的末尾。
更强大的实现如下expl3
:
\documentclass{article}
\usepackage{xparse}
\ExplSyntaxOn
\NewDocumentEnvironment{myitemize}{ O{} +b }
{
% do the setup
\keys_set:nn { werner/itemize } { #1 }
% split the contents at \item
\seq_set_split:Nnn \l_werner_itemize_input_seq { \item } { #2 }
% remove the first (empty) item
\seq_pop_left:NN \l_werner_itemize_input_seq \l_tmpa_tl
% issue the preamble
\tl_use:N \l_werner_itemize_pre_tl
% adorn the items
\seq_set_map:NNn
\l_werner_itemize_output_seq
\l_werner_itemize_input_seq
{ \__werner_itemize_do:n { ##1 } }
% output the items, separated by the chosen separator
\seq_use:NV \l_werner_itemize_output_seq \l_werner_itemize_sep_tl
% issue the postamble
\tl_use:N \l_werner_itemize_post_tl
}
{}
\seq_new:N \l_werner_itemize_input_seq
\seq_new:N \l_werner_itemize_output_seq
\cs_generate_variant:Nn \seq_use:Nn { NV }
\keys_define:nn { werner/itemize }
{
pre .tl_set:N = \l_werner_itemize_pre_tl,
post .tl_set:N = \l_werner_itemize_post_tl,
sep .tl_set:N = \l_werner_itemize_sep_tl,
action .code:n = \cs_set_eq:NN \__werner_itemize_do:n #1,
action .initial:n = \use:n,
}
\ExplSyntaxOff
\NewDocumentCommand{\quotepar}{m}{%
``#1''\par
}
\NewDocumentCommand{\normalitem}{m}{%
\item #1
}
\NewDocumentCommand{\bulletitem}{m}{%
\textbullet\ #1%
}
\begin{document}
\begin{myitemize}[action=\bulletitem,sep={, }]
\item First
\item Second
\item Last
\end{myitemize}
\begin{myitemize}[action=\quotepar]
\item First
\item Second
\item Last
\end{myitemize}
\begin{myitemize}[
action=\normalitem,
pre=\begin{itemize},
post=\end{itemize},
]
\item First
\item Second
\item Last
\end{myitemize}
\end{document}