重新定义定理突破 nameref

重新定义定理突破 nameref

我想定义一个命令\keyifythm{<envname>},重新定义 amsthm 定理环境以采用键值可选参数。我下面的方法有效,但由于我不明白的原因,它破坏了nameref支持。这是一个最小的非工作示例:

\documentclass{article}
\usepackage{amsthm,nameref}

\ExplSyntaxOn
\keys_define:nn { thmkeys/thmuse }
    {
      name .tl_set:N = \l_thmkeys_thmuse_name_tl,
    }

\NewDocumentCommand{ \keyifythm } { m } {
    \NewEnvironmentCopy { orig-#1 } { #1 }
    \RenewDocumentEnvironment { #1 } { ={name} O{} }
        {
          \keys_set:nn { thmkeys/thmuse } { ##1 }
          \tl_if_empty:NTF \l_thmkeys_thmuse_name_tl
            { \begin{orig-#1} }
            { \begin{orig-#1}[\l_thmkeys_thmuse_name_tl] }
        }
        {
          \end{orig-#1}
        }
    }
\ExplSyntaxOff

\newtheorem{theorem}{Theorem}

\keyifythm{theorem}

\begin{document}

\begin{theorem}[heading] \label{hjk}
Text
\end{theorem}

\ref{hjk}

\begin{theorem}[heading] \label{abc}
Text
\end{theorem}

\nameref{abc} % this fails

\end{document}

错误是

! Missing $ inserted.
<inserted text> 
                $
l.41 \nameref{abc}
                   % this fails
I've inserted a begin-math/end-math symbol since I think
you left one out. Proceed, with fingers crossed.

theorem我已经确定问题不仅仅是重新定义。例如,\keyifythm

\NewDocumentCommand{ \donothingtothm } { m } {
    \NewEnvironmentCopy { orig-#1 } { #1 }
    \RenewDocumentEnvironment { #1 } { o }
        {
          \IfNoValueTF{##1}
            { \begin{orig-#1} }
            { \begin{orig-#1}[##1] }
        }
        {
          \end{orig-#1}
        }
    }

与 nameref 配合得很好。问题肯定出在 nameref 修补 amsthm 命令的方式上\@begintheorem,但我不明白为什么我的重新定义会干扰这一点。有什么办法可以解决这个问题吗?

答案1

这与 amsthm 无关,与您的重新定义也没有太大关系:nameref使用包gettitlestring获取标题并将其写入 aux 文件,默认情况下此包不会扩展命令:

\documentclass{article}
%\PassOptionsToPackage{expand}{gettitlestring}
\usepackage{nameref}
\newtheorem{theorem}{Theorem}
\begin{document}
\ExplSyntaxOn
\tl_set:Nn\l_tmpa_tl{blub}
\begin{theorem}[\l_tmpa_tl] \label{hjk}
Text
\end{theorem}
\ExplSyntaxOff

\nameref{hjk}

\end{document}

将会写

\newlabel{hjk}{{1}{1}{\l_tmpa_tl }{}{}}

放入 aux 文件中,当读回该文件时,nameref 将不会对下划线感到满意。

您可以将选项传递expand给它,gettitlestring然后它将扩展命令(如果有脆弱的命令,则必须保护它们)。或者您应该在定义变量时至少扩展一次。

答案2

您想在 LaTeX 看到之前扩展(一次)标记列表变量\begin{orig-...}[...]

          \tl_if_empty:NTF \l_thmkeys_thmuse_name_tl
            { \begin{orig-#1} }
            { \use:e { \exp_not:N \begin{orig-#1}[ \exp_not:V \l_thmkeys_thmuse_name_tl] } }

更干净:

\documentclass{article}
\usepackage{amsthm,nameref}

\ExplSyntaxOn
\keys_define:nn { thmkeys/thmuse }
    {
      name .tl_set:N = \l_thmkeys_thmuse_name_tl,
    }

\NewDocumentCommand{ \keyifythm } { m } {
    \NewEnvironmentCopy { orig-#1 } { #1 }
    \RenewDocumentEnvironment { #1 } { ={name} O{} }
        {
          \keys_set:nn { thmkeys/thmuse } { ##1 }
          \tl_if_empty:NTF \l_thmkeys_thmuse_name_tl
            { \__thmkeys_begin:n {#1} }
            { \__thmkeys_begin:nV {#1} \l_thmkeys_thmuse_name_tl }
        }
        {
          \end{orig-#1}
        }
    }

\cs_new_protected:Nn \__thmkeys_begin:n { \begin{orig-#1} }
\cs_new_protected:Nn \__thmkeys_begin:nn { \begin{orig-#1}[#2] }
\cs_generate_variant:Nn \__thmkeys_begin:nn { nV }
\ExplSyntaxOff

\newtheorem{theorem}{Theorem}

\keyifythm{theorem}

\begin{document}

\begin{theorem}[heading] \label{hjk}
Text
\end{theorem}

\ref{hjk}

\begin{theorem}[heading] \label{abc}
Text
\end{theorem}

\nameref{abc} % this fails

\end{document}

在此处输入图片描述

相关内容