语境:这个问题是处理宏的逗号分隔参数列表中的 _(下划线)\codecitep
。在这个问题中,我创建了一个以逗号分隔的列表作为参数的宏,并打印这些键生成的hyperref
链接。
问题:我的 MWE 运行良好,但是我未能成功将其实现在我的实际文档中。我确实收到以下错误:
! LaTeX Error: \do undefined.
我已经找到了原因,那就是......\chapter
命令:
\codecitep
命令定位前第一个\chapter
编译成功,但是那些后不。
解决方案:(是的,解决方案先于问题!)正如找不到 LaTeX 错误,\do
在导致错误的命令之后重新设置定义使得编译工作。
但是,\def\do{}
在每个\chapter
命令后添加的方式太脏了,而且我认为用后缀重新定义/修补 KOMA 的\chapter
命令不是一个可持续的解决方案。\def\do{}
问题:是什么使得\chapter
改变\do
的定义,以及如何避免它影响我自己的\codecitep
宏?
\documentclass{scrbook}
\usepackage{etoolbox}
\usepackage{hyperref}
\usepackage{lipsum}
\newcommand{\codecitep}[1]{% cf. https://tex.stackexchange.com/a/87423/64454
[%
\def\nextitem{\def\nextitem{, }}% Separator
\renewcommand*{\do}[1]{\nextitem{\hyperref[code:##1]{##1}}}% How to process each item
\docsvlist{#1}% Process list
]%
}
\begin{document}
\section{Body before chapter}
A sentence with one code-citation only \codecitep{key1}.
Another sentence with two code-citations and followed by dummy text \codecitep{key1, key2}.
\chapter{Chapter title}
%\def\do{}% <----- uncomment to make the error disappear
\section{Body after chapter}
A sentence with one code-citation only \codecitep{key1}.
Another sentence with two code-citations and followed by dummy text \codecitep{key1, key2}.
\lipsum[1-2]
\section{Appendix}
\lipsum[3]
\subsection{key1}
\label{code:key1}
\label{code:a_123}
\lipsum[4]
\subsection{key2}
\label{code:key2}
\label{code:bb_456}
\lipsum[5]
\end{document}
答案1
tocbasic.sty
使用scrbook
的包
\let\do\relax
作为 的一部分\doforeachtocfile
,由 执行\chapter
。这意味着您无法执行\renewcommand\do{...}
,因为\do
根据 LaTeX 未定义。
确实,如果我\let\do\relax
从执行此操作的两个内部宏中删除它,问题就会消失。
这个\renewcommand{\do}{...}
问题在其他情况下也出现过。我认为最好的方法是使用你自己的列表处理器。
\documentclass{scrbook}
\usepackage{etoolbox}
\usepackage{hyperref}
\usepackage{lipsum}
\newcommand{\codecitep}[1]{% cf. https://tex.stackexchange.com/a/87423/64454
[%
\def\nextitem{\def\nextitem{, }}% Separator
\forcsvlist\codecitepitem{#1}% Process list
]%
}
\newcommand{\codecitepitem}[1]{%
\nextitem
\hyperref[code:#1]{\detokenize{#1}}%
}
\begin{document}
\section{Body before chapter}
A sentence with one code-citation only \codecitep{key1}.
Another sentence with two code-citations and followed by
dummy text \codecitep{key1, key2}.
\chapter{Chapter title}
\section{Body after chapter}
A sentence with one code-citation only \codecitep{key1}.
Another sentence with two code-citations and followed by
dummy text \codecitep{key1, key2}.
\lipsum[1-2]
\section{Appendix}
\lipsum[3]
\subsection{key1}
\label{code:key1}
\label{code:a_123}
\lipsum[4]
\subsection{key2}
\label{code:key2}
\label{code:bb_456}
\lipsum[5]
\end{document}
答案2
\do
用于许多低级乳胶构造,只需浏览latex.ltx
一下
\global\let\do\noexpand
在\begin{document}
\let\do\@makeother
和
\let\do\do@noligs
在verbatim
和\verb
\let\do\@makeother
在filecontents
\do
我没有准确追踪到在您的用例中是什么重置了它,但基本上它只能在执行分离列表之前立即用于本地定义。