在 KOMA scrbook 中添加 \chapter 会生成“!LaTeX 错误:\do undefined。”

在 KOMA scrbook 中添加 \chapter 会生成“!LaTeX 错误:\do undefined。”

语境:这个问题是处理宏的逗号分隔参数列表中的 _(下划线)\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我没有准确追踪到在您的用例中是什么重置了它,但基本上它只能在执行分离列表之前立即用于本地定义。

相关内容