宏捕获直到行尾作为参数

宏捕获直到行尾作为参数

是否可以将行尾的内容捕获为宏参数?

例如,考虑以下简单的可视化:

在此处输入图片描述

\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}

看着\obeylineslatex.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}

在此处输入图片描述

相关内容