Seite 1 von 1

Anker im Inhaltsverzeichnis - geht das?

Verfasst: Do 6. Dez 2018, 20:08
von Rolli
Hallo!

Ich möchte Folgendes:
Alle Überschriften im laufenden Text (also \chapter (sofern vorhanden), \section, \subsection, ...) sollen anklickbar sein. Beim Anklicken soll in das
Inhaltsverzeichnis gesprungen werden, an die korrekte Stelle.

Also im Beispiel:

Klick auf "3 Drittens" auf Seite 3 soll ergeben, dass "3 Drittens" auf Seite 1 (im Inhaltsverzeichnis) angezeigt wird.

So wie ich das im Beispiel gemacht habe, geht es natürlich nicht. Man müsste dafür im Inhaltsverzeichnis Anker setzen können.

Geht das?
\documentclass{scrartcl}
\usepackage{blindtext}
\usepackage{hyperref}

\begin{document}

\tableofcontents

\section{\href{Erstens}{Erstens}}
\Blindtext
\section{\href{Zweitens}{Zweitens}}
\Blindtext
\section{\href{Drittens}{Drittens}}
\Blindtext

\end{document}
Gruß vom Rolli

Verfasst: Do 6. Dez 2018, 21:36
von Bartman
Die Antworten zu Linking the section text to the TOC betreffen Standardklassen. Vielleicht lässt sich eine der Lösungen auf KOMA-Script übertragen.

Verfasst: Fr 7. Dez 2018, 08:30
von Gast
Man muss dazu eigentlich nur in die Verzeichniseinträge einen Anker einschleusen und in die Ausgabe der Überschriften den Sprung zu diesem Anker.

Die Anker kann man bei KOMA-Script auf zwei Arten einschleusen: Entweder man deklariert den Verzeichnisstil der einzelnen Einträge über \DeclareTOCStyleEntry oder \RedeclareSectionCommands um (theoretisch kann man dazu auch zunächst einen neuen Stil definieren, der die Anker direkt erzeugt) oder man nimmt über \addtocentrydefault Einfluss darauf, was in das Inhaltsverzeichnis geschrieben wird. Dabei muss man aber beachten, dass hyperref diese Texte davon auch für die Bookmaarks verwendet, also ggf. hier zusätzlich mit \textorpdfstring gearbeitet werden sollte.

Den Sprung zum Anker kann man einfach in die Ausgabe der Überschriften \sectionnlinesformat und \sectioncatchphraseformat einfügen.

Um fortlaufende Anker zu erzeugen böte sich theoretisch der Zähler der jeweiligen Gliederungsebene an. Allerdings funktioniert das dann nur für nummerierte Überschriften. Besser ist daher, einen eigenen Zähler zu verwenden. Dann funktioniert es auch für nicht nummerierte Überschriften.
\documentclass{scrartcl}
\usepackage{blindtext}
\usepackage{xpatch}
\usepackage{hyperref}

\newcounter{tocentrynumber}
\xpatchcmd{\addtocentrydefault}{#3}{%
  \texorpdfstring{\protect\hypertarget{tocentry.\thetocentrynumber}{#3}}{#3}%
}{}{\undefined}
\makeatletter
\renewcommand*{\sectionlinesformat}[4]{%
  \stepcounter{tocentrynumber}%
  \hyperlink{tocentry.\thetocentrynumber}{\@hangfrom{\hskip #2#3}{#4}}%
}
\makeatother
\renewcommand*{\sectioncatchphraseformat}[4]{%
  \stepcounter{tocentrynumber}%
  \hyperlink{tocentry.\thetocentrynumber}{\hskip #2#3#4}%
}

\begin{document}
\tableofcontents

\section{Erstens}
\Blindtext
\section{Zweitens}
\Blindtext
\section{Drittens}
\Blindtext
\addsec{Nichtnummeriertens}
\Blindtext

\blinddocument
\blinddocument
\blinddocument
\blinddocument

\end{document}
Zu beachten ist allerdings, dass diverse Pakete leider nicht \addsectiontocentry o. ä. und damit auch nicht \addtocentrydefault verwenden, um eigene Einträge im Inhaltsverzeichnis vorzunehmen. Das ist dann aber ein Problem dieser Pakete. Wollte man hier eingreifen müsste man in der Tat den Verzeichnisstil der Einträge manipulieren (siehe Hinweis oben) oder direkt \addcontentsline oder sogar \addtocontents umdefinieren.

Verfasst: Fr 7. Dez 2018, 09:46
von Rolli
Hi,

danke für den Tipp - ich bin immer wieder erstaunt ...
Im Overleaf geht es übrigens (warum auch immer) nicht.

Es hat nur noch einen winzigen Schönheitsfehler: Klicken auf eine Überschrift im laufenden Text springt n a c h dem Eintrag ins Inhaltsverzeichnis; d.h. der Anker scheint hinter dem Überschrifts-Text zu sein. Wie bekommt man den vor den Überschrifts-Text?

Ich vermute mal, das geht irgendwie mit \xpretocmd? Leider bin ich noch nicht so tief in den Niederungen ...

Gruß vom Rolli

Verfasst: Fr 7. Dez 2018, 10:29
von Gast
Eigentlich ist der gesamte Text der Überschrift im Inhaltsverzeichnis der Anker. Man könnte natürlich auch (ungestestet!)
\xpatchcmd{\addtocentrydefault}{#3}{%
  \texorpdfstring{\protect\hypertarget{tocentry.\thetocentrynumber}{}}{}#3%
}{}{\undefined}
verwenden, um den Anker unmittelbar vor dem Text einzufügen. Das dürfte aber kaum etwas verändern.

Man könnte den Anker bei nummerierten Einträgen auch bereits in der Nummer einfügen (ungetestet!):
\makeatletter
\newcommand{\addtocentrydefault}[3]{%
  \IfArgIsEmpty{#2}{%
    \expandafter\tocbasic@addxcontentsline\expandafter{\ext@toc}{#1}{#2}{%
      \texorpdfstring{\protect\hypertarget{tocentry.\thetocentrynumber}{}}{}#3%
    }%
  }{%
    \expandafter\tocbasic@addxcontentsline\expandafter{\ext@toc}{#1}{%
      \texorpdfstring{\protect\hypertarget{tocentry.\thetocentrynumber}{}}{}#2%
    }{#3}%
  }%
}
\makeatother
Mehr Kontrolle über die Position des Ankers hat man ggf. über den Verzeichnisstil. Spätestens wenn man sich einen komplett eigenen Verzeichnisstil definiert, kann man da machen, was immer man will. Siehe dazu das Kapitel zu tocbasic in der KOMA-Script-Anleitung.

Der Status Rückfrage ist übrigens nicht für Ergänzungsfragen durch den Fragesteller. Bitte informiere dich über die korrekte Bedeutung (einfach mit der Maus über das Fragezeichen bei "Status aktuellen halten" fahren).

Verfasst: Fr 7. Dez 2018, 10:32
von Gast
Bei mir funktioniert das übrigens auch mit dem von Overleaf heruntergeladenen PDF. Nur im Overleaf-Previewer funktioniert es nicht, aber dort funktionieren bei mir Links häufig nicht. Bis vor kurzem haben bei mir dort Links überhaupt nicht funktioniert. Das Feature scheint schlicht noch in Entwicklung zu sein.

Verfasst: Fr 7. Dez 2018, 12:33
von Rolli
Danke erstmal für die Hilfestellung soweit.
Untenstehendes bringt den Fehler
 Command \addtocentrydefault already defined. 
.
Wenn ich
 \newcommand{\addtocentrydefault} 
in
 \renewcommand{\addtocentrydefault} 
ändere, geht es zwar beim ersten Texifien; beim zweiten Durchlauf (für das Einfügen der Hyperlinks) kommt jedoch die Fehlermeldung
 ! Undefined control sequence. \@hyper@@anchor ...r@spot {#2#3}\let \put@me@back \@empty \ifx \relax #2\rel... 
.

Leider bin ich noch nicht so in den Tiefen der Package-Programmierung drin, dass mir diese Fehlermeldung mehr als "Bahnhof" sagt ...

Über die kommenden ruhigeren Tage schaue ich mir mal tocbasic an - nochmals Dank für den Tipp. Bis dahin wird es wohl so bleiben, falls nicht noch jemand eine zündende Idee hat.

Gruß vom Rolli
\documentclass{scrartcl}
\usepackage{blindtext}
\usepackage{xpatch}
\usepackage{hyperref}

\newcounter{tocentrynumber}
\makeatletter
\newcommand{\addtocentrydefault}[3]{%
  \IfArgIsEmpty{#2}{%
    \expandafter\tocbasic@addxcontentsline\expandafter{\ext@toc}{#1}{#2}{%
      \texorpdfstring{\protect\hypertarget{tocentry.\thetocentrynumber}{}}{}#3%
    }%
  }{%
    \expandafter\tocbasic@addxcontentsline\expandafter{\ext@toc}{#1}{%
      \texorpdfstring{\protect\hypertarget{tocentry.\thetocentrynumber}{}}{}#2%
    }{#3}%
  }%
}
\makeatother

\begin{document}

\tableofcontents

\section{Erstens}
\Blindtext
\section{Zweitens}
\Blindtext
\section{Drittens}
\Blindtext
\addsec{Nichtnummeriertens}
\Blindtext

\blinddocument
\blinddocument
\blinddocument
\blinddocument

\end{document}

Verfasst: Fr 7. Dez 2018, 13:20
von Gast
Bei einer Lösung über den Eintragsstil könnte es allerdings etwas aufwändiger werden, den laufenden Zähler für die Einträge zu bestimmen. Man kann das sicher lösen (beispielsweise indem man die Erhöhung des Zählers getrennt in die toc-Datei schreibt oder indem man für jede Ebene einen eigenen Zähler verwenden oder indem man nur dann den Zähler erhöht, wenn man tatsächlich eine Ebene setzte, die einen Eintrag im Inhaltsverzeichnis hat, oder indem man einfach alle Ebenen im Inhaltsverzeichnis ausgeben lässt), aber es ist nicht so einfach wie oben gezeigt.

Verfasst: Fr 7. Dez 2018, 17:17
von Gast
Wenn es ein Problem ist, dass der PDF-Viewer zur linken unteren Ecke eines Targets springt statt zur linken oberen Ecke, dann kann man das Target ggf. recht einfach vertikal verschieben:
\documentclass{scrartcl}
\usepackage{blindtext}
\usepackage{xpatch}
\usepackage{hyperref}

\newcounter{tocentrynumber}
\xpatchcmd{\addtocentrydefault}{#3}{%
  \texorpdfstring{\protect\xhyperdummytarget{tocentry.\thetocentrynumber}}{}%
  #3%
}{}{\undefined}
\newcommand*{\xhyperdummytarget}[1]{%
  \smash{\raisebox{\ht\strutbox}{\hypertarget{#1}{\strut}}}%
}
\makeatletter
\renewcommand*{\sectionlinesformat}[4]{%
  \stepcounter{tocentrynumber}%
  \hyperlink{tocentry.\thetocentrynumber}{\@hangfrom{\hskip #2#3}{#4}}%
}
\makeatother
\renewcommand*{\sectioncatchphraseformat}[4]{%
  \stepcounter{tocentrynumber}%
  \hyperlink{tocentry.\thetocentrynumber}{\hskip #2#3#4}%
}

\begin{document}
\tableofcontents

\section{Erstens}
\Blindtext
\section{Zweitens}
\Blindtext
\section{Drittens}
\Blindtext
\addsec{Nichtnummeriertens}
\Blindtext

\blinddocument
\blinddocument
\blinddocument
\blinddocument

\end{document}
Eine Möglichkeit über den Eintragsstil zu arbeiten wäre übrigens:
\documentclass{scrartcl}
\usepackage{blindtext}
\usepackage{xpatch}
\usepackage{hyperref}

\newcommand*{\anchortocentry}[1]{%
  \smash{\raisebox{\ht\strutbox}{\hypertarget{\nexttocentry}{\strut}}}\ignorespaces#1%
}
\BeforeStartingTOC[toc]{\newcommand*{\nexttocentry}{page.0}}
\newcounter{tocentrynumber}
\RedeclareSectionCommands[tocentryformat=\anchortocentry]{section,subsection,subsubsection,paragraph,subparagraph}
\makeatletter
\renewcommand*{\sectionlinesformat}[4]{%
  \stepcounter{tocentrynumber}%
  \addtocontents{\ext@toc}{\protect\def\protect\nexttocentry{tocentry.\thetocentrynumber}}%
  \hyperlink{tocentry.\thetocentrynumber}{\@hangfrom{\hskip #2#3}{#4}}%
}
\renewcommand*{\sectioncatchphraseformat}[4]{%
  \stepcounter{tocentrynumber}%
  \addtocontents{\ext@toc}{\protect\def\protect\nexttocentry{tocentry.\thetocentrynumber}}%
  \hyperlink{tocentry.#1.\thetocentrynumber}{\hskip #2#3#4}%
}
\makeatother

\begin{document}
\tableofcontents

\section{Erstens}
\Blindtext
\subsection{Suberstens}
\blindtext
\subsubsection{Subsuberstens}
\blindtext
\subparagraph{Paraerstens}
\blindtext
\section{Zweitens}
\Blindtext
\section{Drittens}
\Blindtext
\addsec{Nichtnummeriertens}
\Blindtext

\blinddocument
\blinddocument
\blinddocument
\blinddocument

\end{document}
wie zu sehen ist, habe ich auch da den Anker verschoben. Es gibt sicher diverse andere Möglichkeiten. So könnte man statt eines eigenen Zählers beispielsweise auch auf den von hyperref erzeugten zurückgreifen und diesen um einen Präfix erweitern. Manche Lösungen sind raffinierter als andere, manche sind schöner, mancher sind leichter zu verstehen. Das ist bei TeX oft so.

Verfasst: Mo 10. Dez 2018, 16:46
von Rolli
Super, danke - das mit dem Anker verschieben klappt.
Trotzdem schaue ich mir's mal an ...

Gruß vom Rolli