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