这是另一个关于保护和扩展的问题,我仍然不太明白……(我想这是我的问题)。我特别阅读了我如何“取消保护”一个论点?,还有其他许多人。
我正在尝试为标题创建自动和上下文标签(如果需要,请参阅下文了解详细信息)。如果我写例如 \myref{My_title_here}
,标签的链接为例如“A.II.3.d 我的标题在这里”,指向第1部分第2章第3节第4小节。是“标题编号”,是(这里是)A.II.3.d
的结果,我想把它放进去,但是:\getrefnumber {#1}
#1
My_title_here
\templabel
%\edef \templabel {\getrefnumber {#1}} doesn't work
\getrefnumber {#1}
我想要的是得到(的结果(扩展)例如 A.II.3.d
) \templabel
。同样,如果需要的话,代码位于最后。
解决方法
\edef
没有用,所以我最后尝试过\protected@edef
(是否\protected\edef
相同\protected@edef
?):
\protected@edef \templabel {\getrefnumber {#1}}
%\show \templabel->A.\protect \textlatin {I}.1.
我最后找到这个来删除\protect
:
\expandafter \expandafter \expandafter \def \expandafter \expandafter \expandafter \templabel \expandafter \expandafter \expandafter {\getrefnumber {#1}}
%\show \templabel ->A.\textlatin {I}.1.
我查看了 的定义\textlatin
,发现它看起来确实像\textbf
。这是一个格式化命令。要删除该\textlatin
命令,我使用以下命令:
\def \textlatin #1{#1}
问题
最后终于可以工作了,但是:
你能简单解释一下这里有什么问题吗?有保护和扩展吗?为什么我不能
\getrefnumber {#1}
直接使用?我想知道是否有更好的解决方案,或者更通用的解决方案,或者至少,解决方案是否涵盖了这里的所有情况:如何直接获取
A.I.1
而不是A.\protect \textlatin {I}.1
?此解决方案
\expandafter
在每种情况下都有效吗?我在这里可能会遇到哪些命令,在\getrefnumber {#1}
:\textlatin
,\textgreek
(因为我使用\greek
?)还有什么?我处理 \textlatin 命令的方式更好吗?这个解决方案有什么缺点吗?(我不明白 的定义
\textlatin
,它就像\textbf
)如果我使用
-
而不是.
(A-II-3-4)?是否-
会被视为算术运算,例如在扩张期间?
请随时提供有关代码的建议,我正在学习。
上下文,以防万一
我使用以下编号:
\def \thepart {\Alph {part}}
\def \thechapter {\Roman {chapter}}
\def \thesection {\arabic {section}}
\def \thesubsection {\alph {subsection}}
\def \thesubsubsection {\greek {\value{subsubsection}}}
\setcounter {secnumdepth} {3} % Paragraphs and subparagraphs unnumbered
我为标题创建了“信息性”编号(来源:(重新)定义包含部分编号的章节的 \ref):
\def \p@chapter {\thepart.}
\def \p@section {\thepart.\thechapter.}
\def \p@subsection {\thepart.\thechapter.\thesection.}
\def \p@subsubsection {\thepart.\thechapter.\thesection.\thesubsection.}
然后我创建标签命令,并将其修补到分区命令中(来源:
—自动创建标签的分段命令,
—根据相应 \label 的位置更改 \ref 的输出,
—如何根据 \ref 相对于 \label 的调用位置来更改其外观,
—自动创建标签)。
\newcommand {\myref }[1]{%
\@ifundefined {r@#1} {??} {\begingroup
%\edef \templabel {\getrefnumber {#1}} doesn't work
要进入A.I.2.b
,\templabel
这是问题
然后我将使用 xstrings 分割字符串:
\StrCut \templabel {.} \part@number \part@tail
\StrCut \part@tail {.} \chapter@number \chapter@tail
% …
\StrCut \paragraph@tail {.} \subparagraph@number \subparagraph@tail
并创建上下文链接(该链接的编号是例如“A-III-2-b 此处的标题” 但如果链接在 A-III 中,它将仅是“2-b 此处的标题”;它是上下文的):
\edef \templink {\getrefbykeydefault {#1} {anchor} {}}
\IfStrEq \thepart \part@number
{\IfStrEq \thechapter \chapter@number
%…
{\textcolor{red}{X} \hyperlink \templink \part@tail}}%
{\textcolor{red}{X} \hyperlink \templink \templabel}%
\endgroup}}
数学家协会
\documentclass[greek]{book} % THE GREEK OPTION IS THE CAUSE
\usepackage {hyperref}
\usepackage {babel}
\makeatletter
\def \p@chapter {\thepart.}
\def \p@section {\thepart.\thechapter.}
\def \p@subsection {\thepart.\thechapter.\thesection.}
\def \p@subsubsection {\thepart.\thechapter.\thesection.\thesubsection.}
\newcommand {\myref}[1]{%
\@ifundefined {r@#1} {??} {\begingroup
\edef \temp {\getrefnumber {#1}}
% \show \temp->A.\textlatin {I}.1.
\endgroup }}
\makeatother
\begin{document}
\mainmatter
\part{Hi :\\introduction}\label{Hi}
\chapter{Chapter}\label{Chapter}
See \myref{Test} below.
\section{Test}\label{Test}
\enddocument
答案1
部分答案,没有时间回答更多。
\getrefnumber
来自包refcount
并且完全可扩展。这意味着,它可以在 内部使用\edef
。但如果引用包含可破坏的内容,\getrefnumber
则将安全地提取此引用,但引用本身将中断。在您的例子中,\textlatin
被引入(可能是babel
),它因 的硬扩展而中断\edef
。
由于是一个遵循 LaTeX 保护协议的宏,因此正如您所观察到的,\textlatin
通过扩展是安全的。\protected@edef
在 LaTeX 中,宏可以通过 进行保护\DeclareRobustCommand
。然后出现了 e-TeX,它提供了\protected
定义命令来使宏变得健壮,并防止在可扩展上下文(如 内部)中扩展\edef
,写入文件。
\protected\edef\macro{definition text}
制作一个受保护的\macro
文本并以困难的方式扩展定义文本。\protected@edef
制作一个正常的(不受保护的)\macro
文本并在 LaTeX 的保护机制生效的情况下扩展定义文本。
refcount
顺便说一句,如果您使用类似包的可扩展提取命令\getrefnumber
,那么\refused
应该在扩展上下文之外使用相同的标签,以获得未定义引用的适当警告。