Hallo!
In Zusammenhang mit dem scrwfile-package und dem hyperref-Package bin ich, was die Bookmarks/Lesezeichen in .pdf-Dateien angeht, auf eine Seltsamkeit gestoßen:
Ich habe spaßeshalber in unten stehendem "Minimalbeispiel, das das Problem zeigt" einen \section
-Befehl für eine Abschnittsüberschrift per \addtocontents
in eine externe Datei "auslagern" und dann per \@starttoc
wieder einlesen lassen.
Ich dachte, das hätte nur den Effekt, dass man einmal öfter compilieren müsste, um die entsprechende Überschrift in den Dokumenttext und ins Inhaltsverzeichnis und als Bookmark/Lesezeichen in die .pdf-Datei zu bekommen, als man hätte compilieren müssen, wenn ich diesen Befehl nicht hätte "auslagern", sondern direkt aus der Hauptdatei heraus hätte verarbeiten lassen.
Wenn ich das "Minimalbeispiel, das das Problem zeigt" unter pdflatex compilieren lasse, ohne scrwfile verwenden zu lassen, ist das auch so ziemlich der einzige leicht wahrnehmbare Effekt. Jedenfalls bekomme ich dann eine .pdf-Datei, bei der die "Ausgelagerte Ueberschrift" in den Bookmarks/Lesezeichen erscheint.
Aber wenn ich das "Minimalbeispiel, das das Problem zeigt" unter pdflatex compilieren lasse, und dabei scrwfile verwenden lasse, dann bekomme ich eine .pdf-Datei, bei der die "Ausgelagerte Ueberschrift" nicht in den Bookmarks/Lesezeichen erscheint.
Nicht mehr ganz so, wie ich es erwartet habe.
Um 20:33 Uhr hatte ich geschrieben:
Im Moment bin ich zwar versucht, alles um mich herum vergessend in einen Zustand der "Coding-Trance" zu fallen und Ursachenforschung zu betreiben, denn ich hätte gerne zusammen mit dem Phänomen auch gleich die Ursache und evtl einen Behebungsvorschlag genannt, aber im Moment erlaubt mein enger Zeitplan mir das nicht.
Sollte mir diesbezüglich niemand zuvorkommen oder niemand bereits zuvorgekommen sein, werde ich mich aber wohl irgendwann wieder melden wenn ich mehr herausgefunden habe.
Soeben, als ich schon im Bettchen lag und einschlummern wollte, bin ich nochmal hochgeschreckt, denn zur Definition des Makros \scrwfile@@starttoc
in scrwfile.sty ist mir etwas aufgefallen.
\scrwfile@@starttoc
ist wie folgt definiert:
\newcommand*{\scrwfile@@starttoc}[1]{% \typeout{Use my own \string\@starttoc\space for #1}% \begingroup \if@filesw \xdef\scrwfile@writefilelist{\scrwfile@writefilelist,#1}% \fi \@fileswfalse \scrwfile@saved@starttoc{#1}% \endgroup }
Da steht also \@filesw
auf "false" während die externe Datei durch \scrwfile@saved@starttoc
, also das ursprüngliche \@starttoc-Makro
, gelesen wird.
Wenn nun diese externe Datei Dinge enthält, die in Abhängigkeit von \@iffilesw
eventuell in externe Dateien geschrieben werden sollen -- zB Absatzgliederungsbefehle wie \section
, die dank des durch hyperref gepatchten \refstepcounter
in Abhängigkeit von \if@filesw
Bookmark-Infos ins .out-file schreiben lassen --, dann werden diese Dinge mit Sicherheit nicht geschrieben, denn dank \@fileswfalse
ist das unterbunden.
Wie könnte man der Sache begegnen?
Das \@starttoc
-Makro des LaTeX-Kerns ist laut \show\@starttoc
wie folgt definiert:
\@starttoc=macro: #1->\begingroup \makeatletter \@input {\jobname .#1}\if@filesw \expandafter \ne wwrite \csname tf@#1\endcsname \immediate \openout \csname tf@#1\endcsname \job name .#1\relax \fi \@nobreakfalse \endgroup .
Ich nehme an, \@fileswfalse
in \scrwfile@@starttoc
dient dazu, das Allozieren des \write
-Handle "innerhalb von" \@starttoc
, was ja in Abhängigkeit von \if@filesw
passiert, zu unterbinden.
Wenn man das obige \scrwfile@@starttoc
-Makro ersetzt durch die Zeilen:
\newcommand{\scrwfile@replace@if@filesw}{}% \long\def\scrwfile@replace@if@filesw#1\if@filesw{#1\iffalse}% % \newcommand*{\scrwfile@@starttoc}[1]{% \typeout{Use my own \string\@starttoc\space for #1}% \if@filesw \xdef\scrwfile@writefilelist{\scrwfile@writefilelist,#1}% \fi \expandafter\scrwfile@replace@if@filesw\scrwfile@saved@starttoc{#1}% }%
, dann funktioniert - zumindest bei mir beim Compilieren des "Minimalbeispiels mit integrierter Änderung" - alles erwartungsgemäß.
Hier das Minimalbeispiel, das das Problem zeigt:
(Je nachdem, ob scrwfile nicht verwendet wird oder verwendet wird, landet die "Ausgelagerte Ueberschrift" in den Bookmarks/Lesezeichen oder landet sie nicht in den Bookmarks/Lesezeichen.)
\documentclass[a4paper]{article} \usepackage{hyperref} %\usepackage{scrwfile} \begin{document} \tableofcontents \section{Nicht ausgelagerte Ueberschrift} \addtocontents{tst}{\protect\section{Ausgelagerte Ueberschrift}}% \csname @starttoc\endcsname{tst}% \end{document}
Hier das Minimalbeispiel mit integrierter Änderung, mit der das Problem behoben scheint:
(Egal ob scrwfile nicht verwendet wird oder verwendet wird, landet die "Ausgelagerte Ueberschrift" immer in den Bookmarks/Lesezeichen.)
\documentclass[a4paper]{article} \usepackage{scrwfile} \begingroup \makeatletter \@firstofone{% \endgroup % Den dank \makeatletter geänderten Kategoriecode von % @ auf seinen vorigen Wert zurücksetzen. \newcommand{\scrwfile@replace@if@filesw}{}% \long\def\scrwfile@replace@if@filesw#1\if@filesw{#1\iffalse}% % \renewcommand*{\scrwfile@@starttoc}[1]{% \typeout{Use my own \string\@starttoc\space for #1}% \if@filesw \xdef\scrwfile@writefilelist{\scrwfile@writefilelist,#1}% \fi \expandafter\scrwfile@replace@if@filesw\scrwfile@saved@starttoc{#1}% }% }% \usepackage{hyperref} \begin{document} \tableofcontents \section{Nicht ausgelagerte Ueberschrift} \addtocontents{tst}{\protect\section{Ausgelagerte Ueberschrift}}% \csname @starttoc\endcsname{tst}% \end{document}
Mit freundlichem Gruß
Ulrich
Ja, das ist ein Problem
Das ist in der Tat ein Problem. Allerdings ist Deine Lösung keine allgemeine Lösung. Tatsächlich hatte ich mir die damals auch schon überlegt und sogar die Verwendung von etoolbox oder xpatch erwogen. Allerdings gibt es sehr viele Pakete, die
\@starttoc
patchen und dabei teilweise auch Dinge wiemachen. Solcherart veränderte Definitionen von
\@starttoc
führen dann mit Deinem Code zu Fehler.Sowohl das Allozieren des Handles, als auch das Öffnen der Datei anders zu verhindern ist nicht so ganz trivial. Eventuell wäre die bessere Lösung:
Das funktioniert dann zumindest so lange, solange keiner eine zusätzliche Gruppe für das Lesen der Hilfsdatei einfügt und die Hilfsdatei auch wirklich (als einzige) gelesen wird. Eventuell sollte man sogar einen Schritt weiter gehen und sicherheitshalber
\@input
gar nicht selbst zurückdefinieren, sondern das dem\endgroup
überlassen.Ich würde es nicht dem \endgroup überlassen ...
Ich würde es nicht dem
\endgroup
überlassen, denn dann gilt die Umdefinition des innerhalb von\scrwfile@@starttoc
verwendeten\@input
-Befehls auch während die durch diesen\@input
-Befehl einzulesende Datei eingelesen wird. Wenn diese einzulesende Datei ihrerseits einen nicht in Gruppen verschachtelten\@input
-Befehl enthält, um eine weitere Datei einzulesen, steht dank der geltenden Umdefinition spätestens nach dem Einlesen dieser weiteren Datei der@filesw
-Schalter in jedem Fall auffalse
, was innerhalb desjenigen loacal scope, innerhalb dessen\scrwfile@@starttoc
das umdefinierte\@input
aufgerufen hat, in dem Moment zu Problemen führen könnte, wo dort nach dem Einlesen der besagten weiteren Datei noch andere Dinge in Abhängigkeit von\if@filesw
passieren.In der Hoffnung, dass
\@starttoc
-Patcher\@starttoc
allenfalls so patchen, dass von\@starttoc
nach wie vor\@input
genau einmal verwendet wird, um die einzulesende Datei einzulesen, könnte man vielleicht ohne eine weitere Gruppe auskommen und statt dessen innerhalb von\scrwfile@@starttoc
\@input
zurücksetzen.Mit freundlichem Gruß
Ulrich