beforeskip und hyperref

Klassen und Pakete zur einfachen Umsetzung individueller Vorstellungen


mck

beforeskip und hyperref

Beitrag von mck »

This topic has already been stated on tex.stackexchange.com: tex.stackexchange.com/posts/531101
I'm unsure if it's worth a bug report to the KOMA issue tracker. Therefor, I hope you can help to guide this issue into the suitable channels or even find a fix.

I realize an unexpected behavior of the hyperlink to a chapter title in the KOMA-Script class ``scrreprt``.

I modified the ``\chapter`` command using the ``\RedeclareSectionCommands`` command available since KOMA-Script version 3.15.
In more detail, to change the vertical position of the chapter title, I set the options ``beforeskip``.

Using the MWE below, it can be realized that the ``hyperref`` target anchor is not adapted to match the new title position.
The subsequent screenshots taken after the chapter was selected in the index of my PDF-viewer illustrate this behavior:

* ``beforeskip=0pt``: Bild
* ``beforeskip=-10pt``: Bild
* ``beforeskip=-20pt``: Bild
* ``beforeskip=-30pt``: Bild

The ``hyperref`` target seems to be too low. Is there a way to adapt the link in such way that the results look always as in the first case (``beforeskip=0pt``)?

MWE:
\documentclass[version=3.26]{scrreprt}

% Packages
\usepackage{blindtext}
\usepackage{hyperref}

% Change Chapter Title Location
\RedeclareSectionCommands[%
   beforeskip=-20pt, % Change this to see the different Hyperlink behavior
   afterindent=false,
]{chapter}

% Document Dummy Content
\begin{document}
\chapter{Example Chapter One}
\blindtext
\chapter{Example Chapter Two}
\blindtext
\end{document}

Benutzeravatar
KOMA
TeX-Entwickler
TeX-Entwickler
Beiträge: 2958
Registriert: Fr 4. Jul 2008, 17:28
Kontaktdaten:

Re: beforeskip und hyperref

Beitrag von KOMA »

Der Link funktioniert offenbar nicht (Error 404) und die Sprache im Forum hier ist Deutsch!

Das ist ein Feature kein Bug und kann aus Kompatibilitätsgründen nicht geändert werden, solange \@makechapterhead und \@makeschapterhead halbwegs vergleichbar zu den Standardklassen funktionieren sollen. Das Problem ist nämlich, dass die Abstände erst in \@makechapterhead zur Anwendung kommen, die Anker aber bereits in \@chapter gesetzt werden. Würden sich nicht so viele darauf stützen, dass diese internen Befehle der Standardklassen auch bei anderen Klassen verwendet werden können und dann auch in etwas gleich funktionieren, gäbe es übrigens weniger solche Probleme.

Eine andere Möglichkeit wäre, wenn hyperref eine klar definierte Schnittstelle bieten würde, um die Position des Ankers (unabhängig Befehlen wie \refstepcounter etc.) innerhalb der Überschrift festzulegen. Das geht derzeit aber AFAIK nur über interne Befehle von hyperref. Das habe ich schon vor weit mehr als zehn Jahren beim damaligen Maintainer angefragt, aber nie bekommen. Tatsächlich muss sich inzwischen KOMA-Script sogar aktiv gegen Patches durch hyperref wehren und interne Makros von hyperref nutzen, damit Links, Bookmarks etc. überhaupt korrekt funktionieren. Alles nicht sehr ideal. Alles recht fragil und wenn dann Dinge ermöglicht werden, die beim ursprünglichen Konzept (für die Standardklassen nicht notwendig waren und deshalb auch) nicht bedacht wurden, dann ist das Ergebnis eben so.

Da ich von größeren, negativen Abständen vor den Kapitelüberschriften wenig halte, sehe ich das aber auch nicht als gravierendes Problem.

Bei Kompatibilitätseinstellung zu einer alten Version, sollte man da ohnehin nicht erwarten, dass sich diesbezüglich etwas verbessert. Version 3.26 ist inzwischen schon arg alt und es war die erste Version, die überhaupt negative Abstände vor den Überschriften ermöglicht hat.

Benutzeravatar
u_fischer
Forum-Meister
Forum-Meister
Beiträge: 4266
Registriert: Do 22. Nov 2012, 11:09
Kontaktdaten:

Re: beforeskip und hyperref

Beitrag von u_fischer »

Eine andere Möglichkeit wäre, wenn hyperref eine klar definierte Schnittstelle bieten würde, um die Position des Ankers (unabhängig Befehlen wie \refstepcounter etc.) innerhalb der Überschrift festzulegen.
Nun, es gibt einen Hook (\HyperRaiseLinkHook) und eine Länge (\HyperRaiseLinkLength), aber der wirkt nur, wenn der Anchor im hmode erzeugt wird. D.h. er nützt dir nur, wenn du kontrollieren kannst, wo und wie der \refstepcounter ausgeführt wird.
Tatsächlich muss sich inzwischen KOMA-Script sogar aktiv gegen Patches durch hyperref wehren und interne Makros von hyperref nutzen, damit Links, Bookmarks etc. überhaupt korrekt funktionieren.
Welche konkret? Du musst nur sagen, was weg soll, wenn KOMA erkannt wird und ich mache es. Ich kann es auch abhängig davon machen, ob \DocumentMetadata benutzt wird. Und du könntest die tagging-Befehle einbauen ...

mck

Re: beforeskip und hyperref

Beitrag von mck »

D.h. für den Fall, dass ein größerer Abstand vor einer Überschrift gewünscht ist (das entscheidet ja meist nicht der Autor, sondern eine andere Instanz für einen) ist die Kombination KOMA-Script + hyperref eher ungeeignet.

Ganz neutral betrachtet ist das aber schon ein Bug für den Endanwender, egal wo die Ursache auch liegen mag. Aber zumindest ist jetzt klar, dass weitere Aktionen (KOMA-Script Issue Tacker etc.) nicht zielführend sein werden.

Sorry für den fehlerhaften Link...
Danke für die schnellen Antworten!

Benutzeravatar
KOMA
TeX-Entwickler
TeX-Entwickler
Beiträge: 2958
Registriert: Fr 4. Jul 2008, 17:28
Kontaktdaten:

Re: beforeskip und hyperref

Beitrag von KOMA »

mck hat geschrieben:
Sa 2. Apr 2022, 23:04
D.h. für den Fall, dass ein größerer Abstand vor einer Überschrift gewünscht ist (das entscheidet ja meist nicht der Autor, sondern eine andere Instanz für einen) ist die Kombination KOMA-Script + hyperref eher ungeeignet.
Bei einen größeren Abstand sehe ich überhaupt kein Problem. Problem sind eigentlich nur negative Abstände, bei denen die Überschrift bereits in den oberen Rand rutscht.

Benutzeravatar
KOMA
TeX-Entwickler
TeX-Entwickler
Beiträge: 2958
Registriert: Fr 4. Jul 2008, 17:28
Kontaktdaten:

Re: beforeskip und hyperref

Beitrag von KOMA »

u_fischer hat geschrieben:
Sa 2. Apr 2022, 22:24
Nun, es gibt einen Hook (\HyperRaiseLinkHook) und eine Länge (\HyperRaiseLinkLength), aber der wirkt nur, wenn der Anchor im hmode erzeugt wird. D.h. er nützt dir nur, wenn du kontrollieren kannst, wo und wie der \refstepcounter ausgeführt wird.
Da liegt ja genau das Problem. Bei den Standardklassen wird \refstepcounter noch im vertikalen Modus in \@chapter ausgeführt, bevor \@makechapterhead aufgerufen wird, in dem dann vertikale Abstand eingefügt wird. Da der vertikale Abstand bei den Standardklassen fest und positiv ist, ist das bei den Standardklassen tatsächlich kein Problem (der OP sieht das offenbar anders, ich aber nicht). Leider verlassen sich viele Paketautoren und Anwender darauf, dass insbesondere \@makechapterhead und \@makeschapterhead genau so funktionieren. Deshalb macht KOMA-Script das derzeit auch noch so (warnt aber ab der nächsten Version insbesondere dann, wenn \@makechapterhead oder \@makeschapterhead umdefiniert werden). Genau deshalb kann ich auch das \refstepcounter (zusammen mit \chaptermark und \addcontentsline etc.) nicht einfach aus \@chapter in \@makechapterhead nach dem Einfügen des Abstandes verschieben bzw. das eigentlich von KOMA-Script nicht benötigte \@makechapterhead einfach eliminieren. Damit wäre das Problem mit der Position der Anker (zumindest von nummerierten Überschriften) eigentlich einfach zu lösen. Eine Möglichkeit wäre, hyperref daran zu hindern den Anker bereits bei \refstepcounter zu setzen und ihn explizit später zu setzen. Dafür müsste ich derzeit tricksen, weil hyperref dafür bisher keine offizielle Schnittstelle anbietet.
u_fischer hat geschrieben:
Sa 2. Apr 2022, 22:24
Tatsächlich muss sich inzwischen KOMA-Script sogar aktiv gegen Patches durch hyperref wehren und interne Makros von hyperref nutzen, damit Links, Bookmarks etc. überhaupt korrekt funktionieren.
Welche konkret? Du musst nur sagen, was weg soll, wenn KOMA erkannt wird und ich mache es. Ich kann es auch abhängig davon machen, ob \DocumentMetadata benutzt wird. Und du könntest die tagging-Befehle einbauen ...
Tagging-Befehle ist geplant, derzeit fehlt aber schlicht die Man-Power. Derzeit bin ich zu 100% damit ausgelastet, den Build-Prozess und KOMA-Script selbst lauffähig zu halten. Das hat mich in den letzte Wochen mehr als 100 Stunden Arbeit gekostet. Neben bei sind bei dieser Code-Überarbeitung einige Dutzend ToDo-Anmerkungen angefallen, für deren Bearbeitung alleine ich Jahre brauchen werde.

Bei \DocumentMetadate muss ich mich auch erst noch einarbeiten. Nach dem, was ich bisher gelesen habe, müsste man das bisher auch vor \documentclass verwenden. Wie ich das also in einer Klasse oder gar einem Paket (bezüglich Papierformat etc. wäre ja typearea beteiligt) machen soll, ist mir bis jetzt noch vollkommen unklar. Vielleicht liege ich aber auch falsch. Wie gesagt: Dafür fehlt mir bisher die Zeit.

Was das Wehren gegen hyperref anbelangt:
\BeforePackage{hyperref}{\scr@chapter@before@hyperref@patch}
\newcommand*{\scr@chapter@after@hyperref@patch}{%
  \let\@chapter\scr@orig@chapter
  \let\@schapter\scr@orig@schapter
  \let\@addchap\scr@orig@addchap
  \ifx\hy@insteadofrefstepcounter\@gobble
    \renewcommand*{\hy@insteadofrefstepcounter}[1]{%
      \Hy@MakeCurrentHrefAuto{##1*}%
      \Hy@raisedlink{%
        \hyper@anchorstart{\@currentHref}\hyper@anchorend
      }%
    }%
  \fi
}
\AfterAtEndOfPackage{hyperref}{\scr@chapter@after@hyperref@patch}
Nähere dazu ist in scrkernel-sections.dtx zu finden. \hy@insteadofrefstepcounter ist übrigens der Code, den ich für nicht nummerierte Überschriften verwende, um den Anker trotz fehlendem \refstepcounter zu setzen. Das wird nicht nur bei Kapitelüberschriften genutzt, sondern ggf. auch für Teile und nicht nummerierten Versionen von Abschnitten und tieferen Ebenen. Auch dafür wäre offizieller Code hilfreich, am besten indem hyperref selbst \hy@insteadofrefstepcounter definieren würde. Dann würde KOMA-Script das nämlich unangetastet lassen und trotzdem verwenden.

Das Dumme an der Geschichte ist auch, dass wenn Du jetzt all meine Wünsche für hyperref umgehend erfüllen würdest, hätte ich weiterhin das Problem mit dem absurden Versionschaos, das bei Anwendern installiert ist und von dem sie erwarten, dass es zu funktionieren hat.

Wie gesagt: Entsprechendes hatte ich Heiko schon vor Jahr(zehnt)en vorgeschlagen. Da aber dazu nie etwas gekommen ist, habe ich es dann vor zwei Jahren als Hack in KOMA-Script eingebaut. Vor zwei Jahren hatte ich noch gehofft, demnächst auch die ganzen Patches an LaTeX-Kernel-Befehlen für Überschriften zu beseitigen und stattdessen nur noch eigenen Code dafür zu verwenden. Da war mir noch nicht klar, was bei eigentlich schrumpfender, verfügbarer Zeit alles an Arbeit auf mich zukommt, allein um mit LaTeX Schritt zu halten. Da hatte ich auch noch die Hoffnung, Unterstützung zu finden. Derzeit finde ich aber nicht einmal Tester für die massiven Umstellungen an der Codebasis.

Ab und zu packt mich dann noch der Rappel und ich fange an, Teile von KOMA-Script als neue Pakete komplett neu in l3 zu designen und zu implementieren. In der Regel geht mir dann nach wenigen Tagen die Zeit aus und irgendwelche Benutzeranfragen an mich oder Anfragen von mir an andere Entwickler kosten zusätzlich Zeit, so dass ich keine Zeit mehr für die Neuentwicklung finde, gleichzeitig stellt sich dann immer massiver die Frage, ob ich die von KOMA-Script selbst dann auch tatsächlich nutzen und trotzdem halbwegs kompatibel bleiben kann. Wochen später und ernüchtert werfe ich die angefangene Arbeit dann als reine Zeitverschwendung weg. Und dabei sind all die Dinge, zu denen ich eigentlich Lust hätte und bei denen ich schon einmal die Illusion hatte, sie demnächst in Angriff zu nehmen, noch gar nicht berücksichtigt.

Ich wünsche mir zunehmend, ich hätte 2002 den Absprung geschafft. Jetzt wird mir nicht viel anderes übrig bleiben, als bis zur Rente oder dem Zusammenbruch meiner veralteten IT weiter zu machen. Beides rückt glücklicherweise immer mehr in Sichtweite. Vielleicht verderbe ich es mir aber auch vorher mit allen anderen LaTeX-Entwicklern oder LaTeX selbst macht einen so gewaltigen Satz, dass ich schlicht keine Chance mehr habe, KOMA-Script am Leben zu halten.

Antworten