如果我不使用,一切都会正常进行\PassOptionsToPackage{french}{babel}
。
我的文档类已经加载了 babel,然后,在我的文档类之前abntex2
加载french
我需要使用的语言。\PassOptionsToPackage{french}{babel}
% \PassOptionsToPackage{french}{babel}
\documentclass[english,12pt,a4paper,twoside]{abntex2}
\usepackage{caption,xpatch,listings}
\makeatletter
\tracingpatches
\newcommand{\specialcodelistingcontentsline}[1]{\contentsline{lstlisting}}
\newenvironment{code}{
\captionsetup{type=listing}
\xshowcmd\addcontentsline
\xpatchcmd{\addcontentsline}
{\contentsline}
{\specialcodelistingcontentsline}
{}
{\FAILEDPATCHSPECIALCONTENTSLINE}
}{}
\makeatother
\begin{document}
\begin{code}
Hi.
\end{code}
\end{document}
在此日志上,我们可以看到修补成功:
> \addcontentsline=macro:
#1#2#3->\begingroup \let \label \@gobble \ifx \@currentHref \@empty \Hy@Warning
{No destination for bookmark of \string \addcontentsline ,\MessageBreak destin
ation is added}\phantomsection \fi \expandafter \ifx \csname toclevel@#2\endcsn
ame \relax \begingroup \def \Hy@tempa {#1}\ifx \Hy@tempa \Hy@bookmarkstype \Hy@
WarningNoLine {bookmark level for unknown #2 defaults to 0}\else \Hy@Info {book
mark level for unknown #2 defaults to 0}\fi \endgroup \expandafter \gdef \csnam
e toclevel@#2\endcsname {0}\fi \edef \Hy@toclevel {\csname toclevel@#2\endcsnam
e }\Hy@writebookmark {\csname the#2\endcsname }{#3}{\@currentHref }{\Hy@tocleve
l }{#1}\ifHy@verbose \begingroup \def \Hy@tempa {#3}\@onelevel@sanitize \Hy@tem
pa \let \temp@online \on@line \let \on@line \@empty \Hy@Info {bookmark\temp@onl
ine :\MessageBreak thecounter {\csname the#2\endcsname }\MessageBreak text {\Hy
@tempa }\MessageBreak reference {\@currentHref }\MessageBreak toclevel {\Hy@toc
level }\MessageBreak type {#1}}\endgroup \fi \addtocontents {#1}{\protect \cont
entsline {#2}{#3}{\thepage }{\@currentHref }}\endgroup .
<recently read> \addcontentsline
l.23 \begin{code}
?
[debug] tracing \patchcmd on input line 23
[debug] analyzing '\addcontentsline'
[debug] ++ control sequence is defined
[debug] ++ control sequence is a macro
[debug] ++ macro can be retokenized cleanly
[debug] ++ search pattern found in replacement text
[debug] ++ patching possible
[debug] == retokenizing macro now
但是,在取消注释\PassOptionsToPackage{french}{babel}
最小示例后,补丁将失败:
> \addcontentsline=macro:
#1#2#3->\begingroup \let \label \@gobble \ifx \@currentHref \@empty \Hy@Warning
{No destination for bookmark of \string \addcontentsline ,\MessageBreak destin
ation is added}\phantomsection \fi \expandafter \ifx \csname toclevel@#2\endcsn
ame \relax \begingroup \def \Hy@tempa {#1}\ifx \Hy@tempa \Hy@bookmarkstype \Hy@
WarningNoLine {bookmark level for unknown #2 defaults to 0}\else \Hy@Info {book
mark level for unknown #2 defaults to 0}\fi \endgroup \expandafter \gdef \csnam
e toclevel@#2\endcsname {0}\fi \edef \Hy@toclevel {\csname toclevel@#2\endcsnam
e }\Hy@writebookmark {\csname the#2\endcsname }{#3}{\@currentHref }{\Hy@tocleve
l }{#1}\ifHy@verbose \begingroup \def \Hy@tempa {#3}\@onelevel@sanitize \Hy@tem
pa \let \temp@online \on@line \let \on@line \@empty \Hy@Info {bookmark\temp@onl
ine :\MessageBreak thecounter {\csname the#2\endcsname }\MessageBreak text {\Hy
@tempa }\MessageBreak reference {\@currentHref }\MessageBreak toclevel {\Hy@toc
level }\MessageBreak type {#1}}\endgroup \fi \addtocontents {#1}{\protect \cont
entsline {#2}{#3}{\thepage }{\@currentHref }}\endgroup .
<recently read> \addcontentsline
l.23 \begin{code}
?
[debug] tracing \patchcmd on input line 23
[debug] analyzing '\addcontentsline'
[debug] ++ control sequence is defined
[debug] ++ control sequence is a macro
[debug] -- macro cannot be retokenized cleanly
[debug] -> the macro may have been defined under a category
[debug] code regime different from the current one
[debug] -> the replacement text may contain special control
[debug] sequence tokens formed with \csname...\endcsname;
[debug] -> the replacement text may contain carriage return,
[debug] newline, or similar characters
! Undefined control sequence.
<argument> \FAILEDPATCHSPECIALCONTENTSLINE
更新
正如@Phelype Oleinikcatcode
,将临时更改:
为 12 解决了该问题。但是,我无法正确恢复catcode
。
以下操作不起作用,因为我曾经\begingroup
恢复过catcode
,但它也会恢复/取消我刚刚对\addcontentlines
\PassOptionsToPackage{french}{babel}
\documentclass[english,12pt,a4paper,twoside]{abntex2}
\usepackage{caption,xpatch,listings}
\makeatletter
\tracingpatches
\newcommand{\specialcodelistingcontentsline}[1]{\contentsline{lstlisting}}
\newenvironment{code}{
\captionsetup{type=listing}
\xshowcmd\addcontentsline
\begingroup
\catcode`\:=12
\xpatchcmd{\addcontentsline}
{\contentsline}
{\specialcodelistingcontentsline}
{}
{\FAILEDPATCHSPECIALCONTENTSLINE}
\endgroup
% Here the catcode is restored, however, my patch is also undone
}{}
\makeatother
\begin{document}
\begin{code}
Hi.
\end{code}
\end{document}
有关的:
答案1
在找到另一个答案之后保存并恢复 makeatletter/makeatother 状态,我设法catcode
用这个设置和恢复冒号:
\PassOptionsToPackage{french}{babel}
\documentclass[english,12pt,a4paper,twoside]{abntex2}
\usepackage{caption,xpatch,listings}
\makeatletter
\tracingpatches
\newcommand{\specialcodelistingcontentsline}[1]{\contentsline{lstlisting}}
\newenvironment{code}{
\captionsetup{type=listing}
\def\makesafecoloncatcoderestore##1{%
\edef##1{\catcode`:=\the\catcode`:\relax}%
}
\makesafecoloncatcoderestore\restorecodecoloncatcode
\catcode`\:=12
\xpatchcmd{\addcontentsline}
{\contentsline}
{\specialcodelistingcontentsline}
{\message{^^J^^JCould YES patch the contentsline environment!^^J^^J^^J^^J^^J^^J}}
{\FAILEDPATCHSPECIALCONTENTSLINE}
% \xshowcmd\addcontentsline
\restorecodecoloncatcode
}{}
\makeatother
\begin{document}
\begin{code}
Hi.
\end{code}
\end{document}
有关的: