![重新定义定理突破 nameref](https://linux22.com/image/469679/%E9%87%8D%E6%96%B0%E5%AE%9A%E4%B9%89%E5%AE%9A%E7%90%86%E7%AA%81%E7%A0%B4%20nameref.png)
我想定义一个命令\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}