agregar \chapter en KOMA scrbook genera un mensaje "! Error de LaTeX: \do indefinido".

agregar \chapter en KOMA scrbook genera un mensaje "! Error de LaTeX: \do indefinido".

Contexto:Esta pregunta es una continuación deManejo de _ (guiones bajos) en la lista de argumentos separados por comas de una macro. En esta pregunta creo la macro \codecitepque toma una lista separada por comas como argumento e imprime estas claves generando hyperrefenlaces.

Problema:Mi MWE funciona muy bien, sin embargo, no logré implementarlo en mi documento real. De hecho, recibo el siguiente error:

! LaTeX Error: \do undefined.

He localizado la causa, que es... el \chaptercomando: \codecitepcomandos colocadosanteslos primeros \chaptercompilan bien, pero esosdespuésno.

Solución:(¡Sí, la solución viene antes que la pregunta!) Como se sugiere enNo se puede encontrar el error LaTeX, restablecer \dola definición después del comando que causa el error hace que la compilación funcione.

Sin embargo, agregar \def\do{}después de cada \chaptercomando es demasiado sucio, y no creo que redefinir/parchear \chapterel comando de KOMA con \def\do{}un sufijo sea una solución sostenible.

Pregunta:¿Qué hace que la definición del \chaptercambio \doy cómo evitarlo afecte mi propia \codecitepmacro?


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

Respuesta1

El paquete tocbasic.styutilizado por scrbookhace

\let\do\relax

como parte de \doforeachtocfile, que es ejecutado por \chapter. Esto significa que no puedes hacerlo \renewcommand\do{...}porque \dono está definido según LaTeX.

De hecho, si lo elimino \let\do\relaxde las dos macros internas, el problema desaparece.

El \renewcommand{\do}{...}problema ha aparecido en otras situaciones. Lo mejor, en mi opinión, es utilizar su propio procesador de listas.

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

Respuesta2

\dose utiliza en muchas construcciones de látex de bajo nivel, con sólo mirar a través de latex.ltxél se ve

 \global\let\do\noexpand

en\begin{document}

  \let\do\@makeother 

y

\let\do\do@noligs

verbatimy en\verb

\let\do\@makeother

enfilecontents

No rastreé exactamente qué lo restablece en su caso de uso, pero básicamente solo debería usarse para una definición local inmediatamente antes de que \dose ejecute la lista separada.

información relacionada