\begin{itemize} 之后立即执行 \renewcommand 如何防止丢失 \item 错误

\begin{itemize} 之后立即执行 \renewcommand 如何防止丢失 \item 错误

下面的列表itemize工作正常。但是,如果我尝试移动

\renewcommand*{\do}[1]{\item #1.}

在 itemize 之外,它会导致

出了点问题——可能缺少 \item

问题:

  • 为什么将移至\renewcommand*{\do}[1]{\item #1.}序言会导致错误
  • 如何通过\renewcommand那里来避免这个错误?

代码:

\documentclass{article}
\usepackage{etoolbox}

\newcommand{\CSVList}{}
\listadd{\CSVList}{a}
\listadd{\CSVList}{b}
\listadd{\CSVList}{c}

\renewcommand*{\do}[1]{\item #1.}%

\begin{document}
    \begin{itemize}
        \renewcommand*{\do}[1]{\item #1.}%
        \dolistloop{\CSVList}%
    \end{itemize}

%% -------------------- This results in the "missing \item" error.
%    \begin{itemize}
%        \dolistloop{\CSVList}%
%    \end{itemize}
\end{document}

答案1

因为LaTeX 内核\do使用它来\begin{document}使得\@onlypreamble命令​​在序言之外使用时抛出错误。

包含的定义\document

\gdef\do##1{\global\let ##1\@notprerr}%
\@preamblecmds
\global\let \@nodocument \relax
\global\let\do\noexpand % <-- this causes the problem

所以紧接着\do就变成了,所以序言中的 没有任何效果。\noexpand\begin{document}\newcommand

如果将 放在\renewcommand内部,当环境组结束时, ( )itemize的先前定义将恢复,并且这会引发。\do\noexpandmissing \item

如果将 移到 的\renewcommand外部itemize,其新定义将保留到第二秒itemize,并且一切正常。

答案2

尝试这个:

\documentclass{article}
\usepackage{etoolbox}

\newcommand{\CSVList}{}
\listadd{\CSVList}{a}
\listadd{\CSVList}{b}
\listadd{\CSVList}{c}

\renewcommand*{\do}[1]{\item #1.}%

\begin{document}
    \begin{itemize}
        \renewcommand*{\do}[1]{\item #1.}%
        \dolistloop{\CSVList}%
    \end{itemize}

    \begin{itemize}
\show\do
        \dolistloop{\CSVList}%
    \end{itemize}
\end{document}

控制台将显示

> \do=\noexpand.
l.18 \show\do

因此你的\do{a}意愿

\noexpand\item a

输出结果将是,在“缺失\item”错误之后,

美国广播公司

更好的方法是定义一个特定的处理程序:

\documentclass{article}
\usepackage{etoolbox}

\newcommand{\CSVList}{}
\listadd{\CSVList}{a}
\listadd{\CSVList}{b}
\listadd{\CSVList}{c}

\newcommand*{\doCSV}[1]{\item #1.}

\begin{document}

\begin{itemize}
\forlistloop{\doCSV}{\CSVList}
\end{itemize}

\end{document}

我已删除所有多余的%字符。

一种不同的实现,其中处理程序是动态构建的;列表中的当前项目用 表示#1

\documentclass{article}
\usepackage{xparse}

\ExplSyntaxOn
\NewDocumentCommand{\addtolist}{mm}
 {
  \clist_if_exist:cF { l_grill_list_#1_clist }
   {
    \clist_new:c { l_grill_list_#1_clist }
   }
  \clist_map_inline:nn { #2 }
   {
    \clist_put_right:cn { l_grill_list_#1_clist } { ##1 }
   }
 }
\NewDocumentCommand{\uselist}{mm}
 {
  \cs_set_protected:Nn \__grill_uselist:n { #2 }
  \clist_map_function:cN { l_grill_list_#1_clist } \__grill_uselist:n
 }
\ExplSyntaxOff

\addtolist{CSVList}{a}
\addtolist{CSVList}{b,c}

\begin{document}

\begin{itemize}
\uselist{CSVList}{\item #1.}
\end{itemize}

\end{document}

相关内容