Ich möchte mein Inhaltsverzeichnis manuell ändern. Der Grund dafür ist, dass mein Dokument nicht so sehr aus „Abschnitten“, sondern eher aus „Übungen“ besteht. Ich habe einen benutzerdefinierten Befehl dafür geschrieben und es funktioniert fast. Die folgenden Befehle werden in eine benutzerdefinierte .sty
Datei geschrieben und nachher geladen hyperref
:
\def\numberline@exer#1{%
\makebox[50pt][l]{\bf Ex. #1\hspace*{1em}}
}
\def\exercise#1{%
\section*{#1}\refstepcounter{exercise}\phantomsection%
\write\@auxout{%
\protect\@writefile{toc}{%
\protect\contentsline {section}{\numberline@exer{\theexercise}Title}{\thepage}%
{????}% This is the fourth argument, defined by hyperref
}%
}%
}
Dies macht im Grunde genau das, was ich will, außer dass kein Lesezeichen erstellt wird. Das liegt wahrscheinlich am vierten Argument. Ich habe versucht, herauszufinden, wie hyperref
redefines funktioniert \contentsline
, aber ich finde es hyperref.sty
unmöglich, das zu verstehen.
Meine Frage ist also: Was sollte das vierte Argument in meiner Definition sein? Ich würde auch gerne wissen, wie dieses vierte Argument funktioniert, aber das hat keine hohe Priorität.
NB: Ich bin nicht daran interessiert, Pakete zu installieren, mit denen Inhaltsverzeichnisse angepasst werden können. Ich mache das nur aus Übungsgründen und würde daher sehr gerne meine eigene .sty
Datei dafür verwenden.
Antwort1
Normalerweise \contentsline
sollten alle Änderungen von usw. vor dem Laden erfolgen hyperref
, anschließend muss das 4th
Argument von berücksichtigt werden \contentsline
, das von hinzugefügt wird hyperref
.
Das 4th
Argument ist der Hyperanker, also etwas wie section.1
oder east.17
.
Der Hyperanker kann mit eingefügt werden \@currentHref
, was den richtigen Anker liefern sollte, da \phantomsection
verwendet wurde.
Um das Lesezeichen hinzuzufügen, verwenden Sie \Hy@writebookmark
, da \contentsline
selbst die Lesezeichen nicht hinzufügt, dies geschieht im Wrapper-Befehl \addcontentsline
, der hier „umgangen“ wird.
\documentclass{article}
\usepackage[bookmarksopen]{hyperref}
\newcounter{exercise}
\makeatletter
\def\numberline@exer#1{%
\makebox[50pt][l]{\bfseries Ex. #1\hspace*{1em}}
}
\def\exercise#1{%
\phantomsection
\refstepcounter{exercise}
\section*{#1}%
\Hy@writebookmark{\csname theexercise\endcsname}{#1}{\@currentHref}{\toclevel@section}{toc}
\write\@auxout{%
\protect\@writefile{toc}{%
\protect\contentsline {section}{\numberline@exer{\theexercise}#1}{\thepage}{\@currentHref}%
}%
}%
}
\makeatother
\usepackage{blindtext}
\begin{document}
\tableofcontents
\section{First section}\label{foosection}
\clearpage
\blindtext[3]
\exercise{Foo}
\blindtext[2]
\end{document}
AktualisierenEine Version mit dem üblichen \addcontentsline
:
\documentclass{article}
\usepackage[bookmarksopen]{hyperref}
\newcounter{exercise}
\makeatletter
\newcommand*\l@exercise[2]{%
\ifnum \c@tocdepth >\z@
\addpenalty\@secpenalty
\addvspace{1.0em \@plus\p@}%
\setlength\@tempdima{3.8em}%
\begingroup
\parindent \z@ \rightskip \@pnumwidth
\parfillskip -\@pnumwidth
\leavevmode \bfseries
\advance\leftskip\@tempdima
\hskip -\leftskip
#1\nobreak\hfil \nobreak\hb@xt@\@pnumwidth{\hss #2}\par
\endgroup
\fi}
\let\toclevel@exercise\toclevel@section
\newcommand{\exercisebetter}[1]{%
\refstepcounter{exercise}
\section*{#1}%
\addcontentsline{toc}{exercise}{\protect\numberline{Ex: \theexercise}#1}
}
\makeatother
\usepackage{blindtext}
\begin{document}
\tableofcontents
\section{First section}\label{foosection}
\clearpage
\blindtext[3]
\exercisebetter{Foobar}
\blindtext[2]
\end{document}
Antwort2
Ich würde empfehlen, nicht \write\@auxout
direkt zu verwenden, sondern zu verwenden \addcontentsline
. \addcontentsline
respektiert \nofile
und verwendet automatisch \protected@write
, sodass Sie verwenden können, \protect
um fragile Befehle zu schützen. Und hyperref
behandelt automatisch Lesezeichen usw., wenn Sie verwenden \addcontentsline
. Sie müssen also nicht wissen, wie Sie das 4. Argument von „ \contents
added by“ festlegen hyperref
. Eine sehr einfache Lösung, die unabhängig davon funktioniert, ob verwendet wird hyperref
oder nicht (und unabhängig davon, ob hyperref
vor oder nach dem zusätzlichen Code geladen wird), wäre:
\documentclass{article}
\usepackage[bookmarksopen]{hyperref}
\providecommand*{\texorpdfstring}[2]{#1}% Needed if `hyperref` is not used.
\newcounter{exercise}
\makeatletter
\def\numberline@exer#1{%
\texorpdfstring{\makebox[50pt][l]{\bfseries Ex. #1\hspace*{1em}}}{Ex. #1}
}
\newcommand\l@exercise{\l@section}
\newcommand*{\exercise}{%
\@dblarg\@exercise
}
\newcommand*{\@exercise}[2][]{%
\refstepcounter{exercise}%
\section*{#2}%
\addcontentsline{toc}{exercise}{\protect\numberline@exer{\theexercise}#1}%
}
\let\toclevel@exercise\toclevel@section
\makeatother
\usepackage{blindtext}
\begin{document}
\tableofcontents
\section{First section}\label{foosection}
\clearpage
\blindtext[3]
\exercise{Foo}
\blindtext[2]
\exercise[Bar]{Foo-Bar}
\blindtext
\end{document}
Bei dieser Lösung gibt es \exercise
auch \section
ein optionales Argument zum Setzen und Ändern des Textes für das Inhaltsverzeichnis. Siehe \exercise[Bar]{Foo-Bar}
im Beispiel.