1

Is it possible to automatically create PDF bookmarks with ntheorem's headers?

Example:

\documentclass[a4paper]{scrartcl}
\usepackage[T1]{fontenc}
\usepackage[utf8]{inputenc}
\usepackage[hyperref]{ntheorem}
\usepackage{lipsum}
\usepackage{hyperref}

%ntheorem
\makeatletter
\renewtheoremstyle{break}%
    {\item[\rlap{\vbox{\hbox{\hskip\labelsep \theorem@headerfont
        ##1\ ##2\theorem@separator}\hbox{\strut}}}]}%
    {\item[\rlap{\vbox{\hbox{\hskip\labelsep \theorem@headerfont
        ##1\ ##2:\ ##3\theorem@separator}\hbox{\strut}}}]}%
\makeatother

\theoremstyle{break}
\theoremheaderfont{\normalfont\bfseries\large}
\theorembodyfont{\normalfont}
\theoremseparator{\medskip}
\theorempostskip{\topsep\medskip}
\newtheorem{exercise}{Exercise}

\begin{document}

\begin{exercise}[Lorem]
\lipsum[10]
\end{exercise}

\begin{exercise}[Ipsum]
\lipsum[10]
\end{exercise}

\end{document}

I want one bookmark for each exercise environment.

In this example the bookmarks should be called "Exercise 1: Lorem" and "Exercise 2: Ipsum". So generally "Exercise n: Name".

It doesn't have to be with hyperref, I don't mind using other packages.

2
  • The start macro \exercise is patched to catch the optional argument.
  • hyperref already sets an anchor for the numbered exercise. The bookmark uses this anchor directly.
  • Package bookmark is added to implement the previous point. Also the bookmarks are updated faster.

Full example file:

\documentclass[a4paper]{scrartcl}
\usepackage[T1]{fontenc}
\usepackage[utf8]{inputenc}
\usepackage[hyperref]{ntheorem}
\usepackage{lipsum}
\usepackage{letltxmacro}

\usepackage[bookmarksopen=true]{hyperref}
\usepackage{bookmark}

%ntheorem
\makeatletter
\renewtheoremstyle{break}%
    {\item[\rlap{\vbox{\hbox{\hskip\labelsep \theorem@headerfont
        ##1\ ##2\theorem@separator}\hbox{\strut}}}]}%
    {\item[\rlap{\vbox{\hbox{\hskip\labelsep \theorem@headerfont
        ##1\ ##2:\ ##3\theorem@separator}\hbox{\strut}}}]}%
\makeatother

\theoremstyle{break}
\theoremheaderfont{\normalfont\bfseries\large}
\theorembodyfont{\normalfont}
\theoremseparator{\medskip}
\theorempostskip{\topsep\medskip}
\newtheorem{exercise}{Exercise}

\makeatletter    
\LetLtxMacro\old@exercise\exercise
\renewcommand*{\exercise}[1][]{%
  \old@exercise[{#1}]%
  \bookmark[dest=\@currentHref]{Exercise \theexercise: #1}%
}
\makeatother

\begin{document}

\begin{exercise}[Lorem]
\lipsum[10]
\end{exercise}

\begin{exercise}[Ipsum]
\lipsum[10]
\end{exercise}

\end{document}

Result

Extension: Support for exercises without titles

\documentclass[a4paper]{scrartcl}
\usepackage[T1]{fontenc}
\usepackage[utf8]{inputenc}
\usepackage[hyperref]{ntheorem}
\usepackage{lipsum}
\usepackage{letltxmacro}

\usepackage[bookmarksopen=true]{hyperref}
\usepackage{bookmark}

%ntheorem
\makeatletter
\renewtheoremstyle{break}%
    {\item[\rlap{\vbox{\hbox{\hskip\labelsep \theorem@headerfont
        ##1\ ##2\theorem@separator}\hbox{\strut}}}]}%
    {\item[\rlap{\vbox{\hbox{\hskip\labelsep \theorem@headerfont
        ##1\ ##2:\ ##3\theorem@separator}\hbox{\strut}}}]}%
\makeatother

\theoremstyle{break}
\theoremheaderfont{\normalfont\bfseries\large}
\theorembodyfont{\normalfont}
\theoremseparator{\medskip}
\theorempostskip{\topsep\medskip}
\newtheorem{exercise}{Exercise}

\makeatletter
\LetLtxMacro\old@exercise\exercise
\renewcommand*{\exercise}{%
  \@ifnextchar[{%
    \exercise@opt
  }{%
    \old@exercise
    \exercise@bookmark{}%
  }%
}
\def\exercise@opt[#1]{%
  \old@exercise[{#1}]%
  \exercise@bookmark{: #1}%
}
\newcommand*{\exercise@bookmark}[1]{%
  \bookmark[dest=\@currentHref]{Exercise \theexercise#1}%
}
\makeatother

\begin{document}

\begin{exercise}[Lorem]
\lipsum[10]
\end{exercise}

\begin{exercise}[Ipsum]
\lipsum[10]
\end{exercise}

\begin{exercise}
\lipsum[10]
\end{exercise}

\end{document}

Result with additional exercise without title

  • Thanks, that was what I was looking for. Hyperref and bookmark have to be the two last packages, right? – MWin123 May 17 '16 at 16:55
  • You can remove my name from your answer -- I deleted it :-( – user31729 May 17 '16 at 16:56
  • @MWin123 Not necessarily. There are many packages, which should be used before hyperref. But other packages, especially unrelated packages, can also be loaded after hyperref. – Heiko Oberdiek May 17 '16 at 17:23
  • @ChristianHupfer Your updated answer would also work. – Heiko Oberdiek May 17 '16 at 17:27
  • @HeikoOberdiek: Yes, it works, but I deleted it rather – user31729 May 17 '16 at 17:36

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.