
Ich versuche, einen Befehl zu schreiben, mit dem jede Notation auf das erste Auftreten verweisen kann. Betrachten Sie eine Notation A und einen Vektor B. Definieren Sie einen Befehl, bei dem fun{'}=B' und fun{x}=B^{x} für x=/=' gelten. Wenn ich B^(A) schreiben möchte, muss ich den Code „fun{(A)}“ verwenden. Beachten Sie, dass dieses „A“ den Code „Hyperlink“ verwendet. \equal
Funktioniert aber nicht, wenn \equal{(\hyperlink{x}{y})}{z}
.
Hier ist ein Minimalbeispiel meines Problems:
\documentclass{article}
\usepackage{hyperref}
\usepackage{ifthen}
\newcommand{\hyperaword}{(\hyperlink{1}{456})}
\begin{document}
\hypertarget{1}{3} % work
\hyperlink{1}{2} % work
\ifthenelse{\equal{\string\hyperaword}{456}}{123}{456} % work
\ifthenelse{\equal{\string (\hyperlink{1}{456})}{456}}{123}{456} % ERROR: Use of \hyper@link@ doesn't match its definition.
\end{document}
Dieses Problem tritt nur auf, wenn ich "(\hyperlink{xx}{xx})" verwende. Wenn ich "\hyperlink{xx}{xx}" und nicht "( )" verwende, ist alles in Ordnung.
Antwort1
Lassen Sie mich Ihre Frage umformulieren:
Ich habe einen Befehl
\newcommand \f [1] { \ifthenelse { \equal {#1} {...} } ... }
Meistens funktioniert das, aber wenn
#1
enthält\hyperlink
, tritt ein Fehler auf, anstatt einfach den False-Zweig auszuführen.
Antwort: Wie im ifthen
Paket erklärt, #1
isterweitertum die zu vergleichende Zeichenfolge zu erhalten.
Wenn Sie den Rohinhalt vergleichen möchten, verwenden Sie \detokenize
.
\string
funktionieren nur in begrenzten Fällen.
\newcommand \f [1] { \ifthenelse { \equal {\detokenize{#1}} {\detokenize{...}} } ... }
Alternativer Ansatz: verwenden Sie expl3 und \str_if_eq:nnTF
oder \tl_if_eq:nnTF
.
Antwort2
\string
bei einem Befehlsnamen wird der Name als Zeichenfolge zurückgegeben (eine Zeichenfolge mit Catcode 12), also \usepackage
ein einzelnes Token, aber \string\usepackage
die 11 Token\
u
s
e
p
a
c
k
a
g
e
\ifthenelse
equal
erweitert die beiden Argumente und prüft dann, ob sie gleich sind.
\equal{\string\hyperaword}{456}
testet, ob die 11 Token \ hyperaword den drei Token 4 5 6 entsprechen. Dies ist nie der Fall, also
\ifthenelse{\equal{\string\hyperaword}{456}}{123}{456}
ist immer456
Im zweiten Test \string(
wird zu erweitert, (
da dies (
bereits ein Zeichen mit Catcode 12 ist. \hyperlink
ist aber ein instabiler Befehl, den Sie nicht in einem Erweiterungskontext verwenden können. Es wird trotzdem ein Link mithilfe von pdftex-Grundelementen erstellt (falls Sie pdftex verwenden), sodass, insbesondere wenn es von umgeben ist ()
, niemals gleich sein wird. 456
Sie könnten den Fehler vermeiden, indem Sie verwenden \protect\hyperlink
, aber dann wird getestet, ob die drei Token (
\hyperlink
)
gleich den drei Token sind 4
5
6
, und dies ist wiederum nie der Fall.
Antwort3
Wenn der PDF-Viewer die PDF-Datei anzeigt,Ein „Hypertarget“ ist im Grunde nur ein Bereich 1 auf einer Seite einer PDF-Datei, der einen Namen hat, anhand dessen er identifiziert werden kann.
Wenn der PDF-Viewer die PDF-Datei anzeigt, ist ein „Hyperlink“ im Grunde nur ein Bereich 1 auf einer Seite der PDF-Datei, bei dem ein Anklicken dazu führt, dass ein anderer Bereich der PDF-Datei zu dem Fenster gescrollt wird, in dem die PDF-Datei angezeigt wird.
Das Makro \hypertarget
ist also eine Anweisung an den LaTeX-Compiler, in die PDF-Datei Anweisungen zu schreiben, die das PDF-Anzeigeprogramm zum Zeitpunkt der Anzeige der PDF-Datei, also zu einem Zeitpunkt, wenn der LaTeX-Compiler nicht mehr läuft, verwendet, um einem Bereich in der PDF-Datei einen Namen zu geben. Ein solcher benannter Bereich wird als „Ziel“ bezeichnet. Der Name eines solchen Bereichs wird als „Ziel“ bezeichnet. Wenn ein solcher benannter Bereich so klein ist, dass er als einzelner Punkt in der PDF-Datei betrachtet werden kann, wird er auch als „Anker“ bezeichnet. 3
Und das Makro \hyperlink
ist eine Anweisung an den LaTeX-Compiler, in die PDF-Datei Anweisungen zu schreiben, die das PDF-Anzeigeprogramm zum Zeitpunkt der Anzeige der PDF-Datei, also zu einem Zeitpunkt, wenn der LaTeX-Compiler nicht mehr läuft, verwendet, um einen Bereich der PDF-Datei mit der Anweisung zu verbinden, beim Anklicken einen anderen (Ziel-)Bereich der PDF-Datei in das Fenster zu scrollen, in dem die PDF-Datei angezeigt wird.
Während des TeX-Laufs verfolgen pdfTeX-basierte Engines Namen=Ziele von benannten Bereichen=Zielen/Ankern und geben am Ende des TeX-Laufs Fehlermeldungen aus, wenn ein Hyperlink ohne Angabe eines entsprechenden Ziels gesetzt wurde, indem ein entsprechender Name für einen Zielbereich/Anker innerhalb der PDF-Datei angegeben wird.
AberKeine TeX-Engine verwendet den \hypertarget
/ \hyperlink
-Mechanismus, um den Überblick über Textphrasen usw. zu behalten, die in den benannten scrollbaren Bereichen der PDF-Datei vorkommen.
Summa summarum:
Das Makro \hyperlink
liefert während der LaTeX-Ausführung keine nützlichen Informationen zurück. Es löst lediglich Schreibanweisungen für die PDF-Datei aus, die vom PDF-Anzeigeprogramm beim Anzeigen der PDF-Datei verarbeitet werden.Das heißt, diese Anweisungen werden nicht vom Latex-Compiler verarbeitet, sondern von einem anderen Programm, nämlich dem PDF-Anzeigeprogramm. Das heißt, diese Anweisungen werden zu einem Zeitpunkt verarbeitet, wenn der Latex-Compiler nicht mehr läuft und wenn alle Daten, die nur während der Laufzeit des Latex-Compilers existieren, nicht mehr existieren.
Ausdrücke in Ihrem Code wie
\ifthenelse{\equal{\string\hyperaword}{456}}{123}{456}
und weisen auf Versuche hin, während der Ausführung des Latex-Compilers
\ifthenelse{\equal{\string (\hyperlink{1}{456})}
irgendwie ein „Ergebnis“ der Anwendung auszuwerten .\hyperlink
Obwohl ich also nicht weiß, was genau Du bezweckst, bezweifle ich, dass das Makro \hyperlink
Token/Informationen liefert, deren weitere Verarbeitung/Prüfung während des TeX-Laufs für Dich von Nutzen wäre.
Wenn ich es richtig verstehe, liegt der Frage jetzt ein Missverständnis darüber zugrunde, worum es bei dem TeX-Makro \hyperlink
eigentlich geht, was das Verständnis der Frage bereits erschwert.
Bitte geben Sie genau an, was Sie erreichen möchten. Wahrscheinlich kann ich dann meine Antwort ändern und ein Codebeispiel hinzufügen, das einen Ansatz für die Angelegenheit zeigt.
1 Bei Seiten-/Spaltenumbrüchen und dergleichen können sowohl Hyperziele als auch Hyperlinks aus mehreren Bereichen bestehen, nicht nur aus einem einzigen Bereich.
2 Die Bedeutung von „einen anderen Bereich der PDF-Datei zu dem Fenster scrollen, in dem die PDF-Datei angezeigt wird“ hängt vom verwendeten Programm zum Anzeigen der PDF-Datei ab, da die „Aktionen“ im Zuge der Ausführung dieser Anweisungen in dieses Programm implementiert werden. Das Verhalten verschiedener PDF-Anzeigeprogramme variiert in Grenzfällen.
3 Das Hyperref-Paket arbeitet in vielen Situationen mit Ankern, vorausgesetzt, dass ein Ankerpunkt in die obere linke Ecke des Fensters gescrollt wird, in dem die PDF-Datei angezeigt wird, wenn auf einen entsprechenden Link geklickt wird. Intern gibt das Hyperref-Paket die Position eines Ankerpunkts in Bezug auf den Referenzpunkt des Felds an, das den Text/das Material enthält, das im Anzeigefenster angezeigt werden soll, wenn auf den Link geklickt wird. Im horizontalen Modus, wo TeX selbst die Dinge in Felder unterteilt, ist es meines Wissens der Referenzpunkt des ersten horizontalen Felds, das Teile des Textes/Materials enthält, die im Anzeigefenster angezeigt werden sollen, wenn auf den Link geklickt wird.
Das folgende Beispiel stellt ein Makro dar \LinkOrTarget{<destination name>}{<phrase>}
, dessen erste Instanz mit einer angegebenen⟨Zielname⟩bildet das Hyperziel und nachfolgende Instanzen bilden Hyperlinks.
Wenn ein Befehl \IntroduceHypertargetHere{<destination name>}{<phrase>}
auftritt, bildet dieser das Hypertarget, während alle Instanzen \LinkOrTarget{<destination name>}{<phrase>}
Hyperlinks bilden.
Wenn ein Befehl \IntroduceHypertargetHere{<destination name>}{<phrase>}
auftritt, benötigen Sie mehr als einen Latex-Lauf, bis alles übereinstimmt.
Daher: Beachten Sie die Hinweise und Warnungen auf dem Terminal und in der Log-Datei zur Notwendigkeit eines erneuten Ausführens von LaTeX (ohne Löschen von Aux-Dateien zwischen den LaTeX-Ausführungen).
Platzieren Sie nicht \IntroduceHypertargetHere{<destination name>}{<phrase>}
für das gleiche⟨Zielname⟩mehr als einmal. Wenn Sie dies tun, erhalten Sie Warnungen über mehrfach definierte Labels und das Hypertarget wird beim ersten dieser Fälle erstellt.
\documentclass{article}
\usepackage{hyperref}
\usepackage{zref}
\makeatletter
\zref@newprop{DestinationExplicitlyPlaced}{}%
\newcommand\WrapHypertargetInHy@raisedlink[2]{%
\Hy@raisedlink{\hypertarget{#1}{}}#2%
}%
\newcommand\IntroduceHypertargetHere[1]{%
\zref@setcurrent{DestinationExplicitlyPlaced}{true}%
\zref@labelbyprops{ExplicitDestination-#1}{DestinationExplicitlyPlaced}%
\IntroduceHypertargetHereInternal{#1}%
}%
\newcommand\IntroduceHypertargetHereInternal[2]{%
\@ifundefined{NameOfDestination_#1}{%
\expandafter\gdef\csname NameOfDestination_#1\endcsname{}%
\WrapHypertargetInHy@raisedlink
}{\hyperlink}{#1}{#2}%
}%
\newcommand\LinkOrTarget[2]{%
\zref@ifrefundefined{ExplicitDestination-#1}{\IntroduceHypertargetHereInternal}{%
\zref@ifrefcontainsprop{ExplicitDestination-#1}{DestinationExplicitlyPlaced}%
{\hyperlink}{\IntroduceHypertargetHereInternal}%
}%
{#1}{#2}%
}%
\makeatother
\begin{document}
Dummy page
\newpage
Smme text \LinkOrTarget{destination name}{Phrase which either is in link area or is in target area}.
\newpage
Some text \LinkOrTarget{destination name}{Phrase which either is in link area or is in target area}.
\newpage
Some text \LinkOrTarget{destination name}{Phrase which either is in link area or is in target area}.
%Some text \IntroduceHypertargetHere{destination name}{Phrase which is in target area}.
\newpage
Some text \LinkOrTarget{destination name}{Phrase which either is in link area or is in target area}.
\newpage
Some text \LinkOrTarget{destination name}{Phrase which either is in link area or is in target area}.
\end{document}