
我嘗試編寫一個命令,每個符號都可以連結到第一次出現。考慮符號 A 和向量 B。如果我想寫B^(A),那麼我需要使用程式碼「fun{(A)}」。請注意,這個“A”使用代碼“hyperlink”。不過\equal
是不上班的時候\equal{(\hyperlink{x}{y})}{z}
。
這是我的問題的一個最小示例:
\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}
只有當我使用“(\hyperlink{xx}{xx})”時才會出現此問題。如果我使用“\hyperlink{xx}{xx}”而不是“( )”,那麼就可以了。
答案1
讓我重寫你的問題:
我有一個命令
\newcommand \f [1] { \ifthenelse { \equal {#1} {...} } ... }
這在大多數情況下都有效,但是當
#1
contains時\hyperlink
,它會出錯,而不是只是運行錯誤分支。
回答:如包裝中所解釋的ifthen
,#1
那樣擴大取得要比較的字串。
如果您想比較原始內容,請使用\detokenize
.
\string
僅在有限的情況下起作用。
\newcommand \f [1] { \ifthenelse { \equal {\detokenize{#1}} {\detokenize{...}} } ... }
替代方法:使用 expl3 和\str_if_eq:nnTF
or \tl_if_eq:nnTF
。
答案2
\string
命令名稱以字串形式傳回名稱(catcode 12 的字元序列),因此\usepackage
是單一標記,但\string\usepackage
11 個標記\
u
s
e
p
a
c
k
a
g
e
\ifthenelse
equal
擴展兩個參數然後測試它們是否相等。
\equal{\string\hyperaword}{456}
測試 11 個標記 \ hyperaword 是否等於三個標記 4 5 6 這永遠不是真的,所以
\ifthenelse{\equal{\string\hyperaword}{456}}{123}{456}
總是456
在第二個測試中\string(
,它擴展為(
as(
已經是 catcode 12 的一個字元\hyperlink
。無論如何,它使用 pdftex 原語建立一個連結(如果您使用的是 pdftex),因此,特別是當被 包圍時()
,永遠不會等於456
您可以透過使用來避免錯誤\protect\hyperlink
,但然後測試是這三個標記是否(
\hyperlink
)
等於三個令牌4
5
6
,這又不是真的。
答案3
當 pdf 檢視器顯示 pdf 檔案時,「超級目標」基本上只是pdf 文件頁面上的一個區域1 ,它有一個可以識別的名稱。
當 pdf 檢視器顯示 pdf 檔案時,「超連結」基本上只是pdf 檔案頁面上的區域1 ,點擊該區域可將pdf 檔案的另一個區域捲動2
因此,巨集\hypertarget
是 LaTeX 編譯器寫入 pdf 檔案指令的指令,在檢視 pdf 檔案時,即在 LaTeX 編譯器不再執行時,pdf-檢視程式用於為 pdf 檔案中的某個區域命名。這樣的命名區域稱為「目標」。這樣一個區域的名稱稱為「目的地」。如果這樣的命名區域很小,可以被視為 pdf 檔案中的單一點,那麼它也稱為「錨點」。3
該巨集\hyperlink
是 LaTeX 編譯器寫入 pdf 檔案指令的指令,在查看 pdf 檔案時,即在 LaTeX 編譯器不再執行時,pdf-檢視程式用於連接pdf 檔案的一個區域,並指示將pdf 檔案的另一個(目標)區域捲動到點擊時顯示pdf 檔案的視窗。
在 TeX 運行期間,基於 pdfTeX 的引擎會追蹤名稱=指定區域的目的地=目標/錨點,並在 TeX 運行結束時引發錯誤訊息,以防放置超連結而未透過提供引入相應的目的地pdf 文件中目標區域/錨點的相應名稱。
但沒有 TeX 引擎使用\hypertarget
/\hyperlink
機制來追蹤 pdf 檔案的那些命名的可捲動區域中出現的文字短語等。
總結:
該巨集\hyperlink
在 LaTeX 運行期間不會傳回任何有用的信息。它僅觸發對pdf檔案的寫入指令,該指令在查看pdf檔時由pdf檢視程式處理。即,這些指令不是由 Latex 編譯器處理,而是由不同的程式處理,即 pdf 檢視程式。即,當乳膠編譯器不再運作並且僅在乳膠編譯器運行期間存在的所有資料都不再存在時,處理這些指令。
程式碼中的表達式如
\ifthenelse{\equal{\string\hyperaword}{456}}{123}{456}
和表示嘗試以某種方式評估在乳膠編譯器運行期間
\ifthenelse{\equal{\string (\hyperlink{1}{456})}
應用的“結果” 。\hyperlink
因此,儘管我不知道您到底想要實現什麼,但我懷疑巨集\hyperlink
提供的令牌/資訊在 TeX 運行期間的進一步處理/檢查對您有任何用處。
如果我理解正確的話,現在的問題涉及到對 TeX 宏\hyperlink
實際含義的誤解,這已經使問題難以理解。
請準確說明您希望實現的目標。然後我可能可以修改我的答案,並添加一個展示解決問題的方法的程式碼範例。
1在分頁/分欄等情況下,超級目標和超連結可能由多個區域組成,而不僅僅是一個區域。
2「將 pdf 檔案的另一個區域捲動到顯示 pdf 檔案的視窗」的含義取決於用於查看 pdf 檔案的程序,因為遵守這些指令過程中的「操作」是實施到該計劃中。不同 pdf 查看程序的行為在邊緣情況下有所不同。
3 hyperref 套件在許多情況下都可以使用錨點,假設當點擊對應的連結時,錨點會捲動到顯示 pdf 檔案的視窗的左上角。在內部,hyperref 套件指定錨點相對於該框的參考點的位置,該框包含單擊連結時將在顯示視窗中看到的文字/材料。在水平模式下,TeX 本身將事物劃分為框,據我所知,它是第一個水平框的參考點,其中包含單擊連結時應在顯示視窗中看到的部分文字/材料。
以下範例提供了一個宏\LinkOrTarget{<destination name>}{<phrase>}
,其中第一個實例具有指定的⟨目的地名稱⟩形成超目標,後續實例形成超連結。
如果出現命令\IntroduceHypertargetHere{<destination name>}{<phrase>}
,則該命令將形成超目標,而所有實例都會\LinkOrTarget{<destination name>}{<phrase>}
形成超連結。
如果出現一條命令\IntroduceHypertargetHere{<destination name>}{<phrase>}
,您需要多次運行乳膠,直到所有內容都匹配為止。
因此:遵守終端機上和 .log 檔案中有關重新運行 LaTeX 的需要的資訊和警告(不刪除 LaTeX 運行之間的輔助檔案)。
不要放置\IntroduceHypertargetHere{<destination name>}{<phrase>}
相同的位置⟨目的地名稱⟩不只一次。如果您這樣做,您將收到有關多重定義標籤的警告,並且超級目標將在第一個實例中建立。
\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}