
コンテクスト:この質問は、マクロのカンマ区切りの引数リスト内の _ (アンダースコア) の処理\codecitep
この質問では、コンマ区切りのリストを引数として受け取り、リンクを生成するこれらのキーを出力するマクロを作成しますhyperref
。
問題:私の MWE はうまく動作しますが、実際のドキュメントに実装することはできませんでした。実際に次のエラーが発生します。
! LaTeX Error: \do undefined.
原因を突き止めました。それは...コマンドです\chapter
。
\codecitep
前に最初のものは\chapter
うまくコンパイルされますが、後しないでください。
解決:(そう、質問の前に解決策が来ます!)LaTeXエラーが見つかりません\do
エラーの原因となったコマンドの後に定義をリセットすると、コンパイルが機能するようになります。
ただし、\def\do{}
各コマンドの後に追加するのは非常に面倒であり、KOMA のコマンドをサフィックスで\chapter
再定義/パッチすることは持続可能な解決策ではないと思います。\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
。つまり、 はLaTeX によれば未定義な\renewcommand\do{...}
ので、は実行できません。\do
実際、\let\do\relax
それを実行している 2 つの内部マクロを削除すると、問題は解消されます。
この\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
多くの低レベルのLaTeX構造で使用されていますが、そこを見るだけで
\global\let\do\noexpand
で\begin{document}
\let\do\@makeother
そして
\let\do\do@noligs
とverbatim
\verb
\let\do\@makeother
でfilecontents
\do
あなたのユースケースで何がリセットされるのか正確には追跡していませんが、基本的には、分離されたリストが実行される直前のローカル定義にのみ使用する必要があります。