如何将格式指令插入到字符串附加命令中?

如何将格式指令插入到字符串附加命令中?

\additem命令将一个项目附加到以逗号分隔的列表中,并\mylist排版该列表。

作品:

\documentclass {article}
\newcommand\mylist {\relax}

\newcommand\additem [1]
{\edef\mylist
 {\mylist
  \if\mylist\relax\else
   ,
  \fi
  #1}}

\begin {document}
\additem {a}
\additem {b}
\additem {c}
\mylist
\end {document}

现在,我想将每个项目都加粗,但不将逗号加粗。但是,如果我将其替换#1为,例如\textbf{#1},我会收到此错误:

! Undefined control sequence.
\GenericError  ...                                
                                                    #4  \errhelp \@err@     ...
l.15 \additem {a}

我的代码有什么问题?我怎样才能使每个项目都加粗?

不起作用:

\documentclass{article}

\newcommand\mylist{\relax}

\newcommand\additem [1]
{\edef\mylist
 {\mylist
  \if\mylist\relax\else
   ,
  \fi
  \textbf{#1}}}

\begin {document}

\additem {a}
\additem {b}
\additem {c}

\mylist

\end {document}

答案1

您必须使用\protected@edef(并修复空虚测试)

\documentclass{article}

\newcommand\mylist{}

\makeatletter
\newcommand\additem [1]
{\protected@edef\mylist
 {\mylist
  \if\relax\detokenize\expandafter{\mylist}\relax\else
   ,
  \fi
  \textbf{#1}}}
\makeatother

\begin {document}

\additem {a}
\additem {b}
\additem {c}

\mylist

\end {document}

像 这样的命令\textbf无法存活\edef,因为它们必须执行任务。你可以使用\noexpand\textbf,但在列表中添加更复杂的项目会导致同样的问题(尝试\additem{\'a})。

使用\protected@edef可以消除此类命令的问题。此外,测试\if\mylist\relax从一开始就是错误的:在您的原始版本(没有\textbf)中,这样做\additem{aa}\additem{b}会产生奇怪的结果。在这里,我使用来自如何检查宏值是否为空或不会使用纯 TeX 条件创建文本?(变化的是,我们需要查看的第一级扩展\mylist)。

另一个版本xparse允许使用多个列表,并且由于不使用,因此不存在此问题\edef

\documentclass{article}

\usepackage{xparse}

\ExplSyntaxOn
\NewDocumentCommand{\additem}{O{default}m}
 {
  \clist_if_exist:cF { l_eduardo_list_#1_clist }
   {
    \clist_new:c { l_eduardo_list_#1_clist }
   }
  \clist_put_right:cn { l_eduardo_list_#1_clist } { \textbf { #2 } }
 }
\NewDocumentCommand{\printlist}{O{default}}
 {
  \clist_use:cn { l_eduardo_list_#1_clist } { ,~ }
 }
\ExplSyntaxOff

\begin{document}

\additem{a}
\additem{b}
\additem{c}

\printlist

\additem[new]{A}
\additem[new]{B}
\additem[new]{C}

\printlist[new]

\end{document}

在此处输入图片描述

答案2

您的问题是,添加新项目是通过 完成的,\edef但宏\textbf不能简单地在 中扩展\edef。最好在没有 的情况下向列表添加新项目\edef。然后所有奇怪的宏都可以作为 的参数\additem,即添加的项目。您可以这样更正您的定义:

\def\mylist{}
\def\additem#1{\ifx\mylist\empty \def\mylist{#1}\else
   \expandafter\def\expandafter\mylist\expandafter{\mylist, #1}\fi
}

当然,如果您需要将项目以粗体显示,那么您可以在宏主体中的两个地方替换(或者,如果您确实使用 LaTeX,那么您可以使用 LaTeX 特定的#1)。{\bf#1}\textbf{#1}

相关内容