同时使用 \nameref (hyperref) 和 \mdtheorem (mdframed) 时出现的问题

同时使用 \nameref (hyperref) 和 \mdtheorem (mdframed) 时出现的问题

当使用\mdtheorem命令 (from mdframed) 和\nameref(from hyperref) 时,似乎应用于使用 所作定理的标签\mdtheorem不会适当地采用定理的标题。相反,它采用当前部分的标题,如以下 MWE 所示:

\documentclass{article}
\usepackage{tikz}
\usepackage[framemethod=tikz]{mdframed}
\usepackage{hyperref}
\tikzset{tatregris/.style =
{draw=gray, thick, fill=white, shading = theoremtitle, %
text=gray, rectangle, rounded corners, right,minimum height=.7cm}}
\pgfdeclarehorizontalshading{theorembackground}{100bp}
{color(0bp)=(black!2); color(100bp)=(black!15)}
\makeatletter
\mdfdefinestyle{theoremstyle}{%
outerlinewidth=0em,outerlinecolor=white,%
leftmargin=-1em,rightmargin=-1em,%
middlelinewidth=1.2pt,roundcorner=5pt,linecolor=gray,
apptotikzsetting={\tikzset{mdfbackground/.append style ={%
shading = theorembackground}}},
innertopmargin=1.2\baselineskip,
skipabove={\dimexpr0.5\baselineskip+\topskip\relax},
skipbelow={-1em},
needspace=\baselineskip,
frametitlefont=\sffamily\scshape,
}
\makeatother
\mdtheorem[style=theoremstyle]{thm}{Theorem}[section]
\begin{document}
\section{Section name}
\begin{thm}[Theorem name] \label{theorem name}
This is a theorem.
\end{thm}
\nameref{theorem name} is a theorem.
\end{document}

值得注意的是,使用时该问题不存在\newmdtheoremenv(这不是一个有效的修复,因为我需要给出的未编号环境,\mdtheorem并且我更喜欢定理标题作为框架标题。)

有什么办法可以解决这个问题吗?

答案1

您需要允许nameref在设置时提取名称thm。为此,我们可以修补\thm(使用xpatch):

在此处输入图片描述

\documentclass{article}
\usepackage[framemethod=tikz]{mdframed}
\usepackage{hyperref,xpatch}

\tikzset{tatregris/.style =
  {draw=gray, thick, fill=white, shading = theoremtitle, %
  text=gray, rectangle, rounded corners, right,minimum height=.7cm}}
  \pgfdeclarehorizontalshading{theorembackground}{100bp}
  {color(0bp)=(black!2); color(100bp)=(black!15)}

\mdfdefinestyle{theoremstyle}{%
  outerlinewidth=0em,outerlinecolor=white,%
  leftmargin=-1em,rightmargin=-1em,%
  middlelinewidth=1.2pt,roundcorner=5pt,linecolor=gray,
  apptotikzsetting={\tikzset{mdfbackground/.append style ={%
  shading = theorembackground}}},
  innertopmargin=1.2\baselineskip,
  skipabove={\dimexpr0.5\baselineskip+\topskip\relax},
  skipbelow={-1em},
  needspace=\baselineskip,
  frametitlefont=\sffamily\scshape,
}

\mdtheorem[style=theoremstyle]{thm}{Theorem}[section]
\newcommand{\thmautorefname}{Theorem}
\makeatletter
\xpatchcmd{\thm}{\refstepcounter}{\NR@gettitle{#1}\refstepcounter}{}{}
\makeatother

\begin{document}
\section{Section name}

\begin{thm}[Theorem name] \label{theorem_name1}
This is a theorem.
\end{thm}

\nameref{theorem_name1} is a named theorem. \autoref{theorem_name2} is not a named theorem.

\begin{thm}\label{theorem_name2}
This is a theorem.
\end{thm}

\end{document}

当然,如果您不提供名称作为 的可选参数thm\nameref则将失败。但是,您也可以使用\autoref

答案2

Werner 的推广回答。以下示例修补了\mdtheorem通过此命令捕获所有定理。的代码\mdtheorem包含很多案例,因此示例使用循环来获取所有\ifstrempty,其参数被重用以获取标题。如果标题为空,则示例不会设置标题。这也可以更改为使用空标题nameref

\documentclass{article}
\usepackage[framemethod=tikz]{mdframed}
\usepackage{hyperref,xpatch}

\tikzset{tatregris/.style =
  {draw=gray, thick, fill=white, shading = theoremtitle, %
  text=gray, rectangle, rounded corners, right,minimum height=.7cm}}
  \pgfdeclarehorizontalshading{theorembackground}{100bp}
  {color(0bp)=(black!2); color(100bp)=(black!15)}

\mdfdefinestyle{theoremstyle}{%
  outerlinewidth=0em,outerlinecolor=white,%
  leftmargin=-1em,rightmargin=-1em,%
  middlelinewidth=1.2pt,roundcorner=5pt,linecolor=gray,
  apptotikzsetting={\tikzset{mdfbackground/.append style ={%
  shading = theorembackground}}},
  innertopmargin=1.2\baselineskip,
  skipabove={\dimexpr0.5\baselineskip+\topskip\relax},
  skipbelow={-1em},
  needspace=\baselineskip,
  frametitlefont=\sffamily\scshape,
}

\makeatletter
\newcommand*{\mdfNR@gettitle@ifstrempty}[1]{%
  \ifstrempty{#1}{%
    \@firstoftwo
  }{%
    \NR@gettitle{#1}%
    \@secondoftwo
  }%
}
% Variant: Define title string for nameref regardless of its emptyness
% \newcommand*{\mdfNR@gettitle@ifstrempty}[1]{%
%   \NR@gettitle{#1}%
%   \ifstrempty{#1}%
% }
\count@=\@ne
\@whilenum\count@>\z@\do{%
  \expandafter\xpatchcmd\csname mdtheorem code\endcsname{%
    \ifstrempty%
  }{%
    \mdfNR@gettitle@ifstrempty
  }{%
    \advance\count@\@ne
  }{%
    \count@=-\count@
  }%
}
\ifnum\count@>\z@
\else
  \@latex@warning{Could not patch \string\mdtheorem}%
\fi
\makeatother

\mdtheorem[style=theoremstyle]{thm}{Theorem}[section]
\newcommand{\thmautorefname}{Theorem}

\begin{document}
\section{Section name}

\begin{thm}[Theorem name] \label{theorem_name1}
This is a theorem.
\end{thm}

\nameref{theorem_name1} is a named theorem. \autoref{theorem_name2} is not a
named theorem.

\begin{thm}\label{theorem_name2}
This is a theorem.
\end{thm}

\end{document}

相关内容