5

When using the \mdtheorem command (from mdframed) with \nameref (from hyperref), it seems that labels applied to an theorem made using \mdtheorem will not appropriately take the title given to the theorem. Instead, it takes the title of the current section, as in the following 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}

Worth noting is that the issue does not exist when using \newmdtheoremenv (which is not a valid fix because I need the unnumbered environment given by \mdtheorem and I prefer the theorem title being the frame title.)

Is there any way to get around this?

2 Answers 2

4

You need to allow nameref to extract the name when it sets thm. For this we can patch \thm (using xpatch):

enter image description here

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

Of course, if you don't supply a name as the optional argument to thm, then \nameref will fail. However, you can also use \autoref for this.

1
  • Great, this is exactly what I was looking for! I had a feeling the solution would be pointing nameref in the right direction, but wasn't too familiar with how to do that.
    – Hayden
    Dec 23, 2014 at 21:25
4

The generalization of Werner's answer. The following example patches \mdtheorem to catch all theorems by this command. The code of \mdtheorem contains lot of cases, thus the example uses a loop to get all \ifstrempty, whose argument is reused to get the title. The example does not set a title, if the title is empty. This can also be changed to use an empty title for 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}

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .