我注意到我的 BibTeX 样式生成的一些链接不起作用,因为它们里面有空格。样式 (apsrev4-1) 使用类似以下内容将参考文献的期刊部分超链接到 doi.org 上的 DOI 解析器
\href {\doibase 10.1234/doi.handle}{Journal 12, 1234 (1984)}
但是,BibTeX 会对其输出进行自动换行,有时会在宏后面插入换行符\doibase
。在这些情况下,生成的 URL 会在该宏的扩展后立即包含一个空格,例如https://doi.org/ 10.1234/doi.handle
。我可以重现此行为:
\documentclass{article}
\usepackage{hyperref}
\newcommand{\base}[0]{http://www.example.com/}
\begin{document}
\href {\base test.html}{Link without space}
\href {\base
test.html}{Link with space}
\end{document}
如果我理解正确的话,这两次调用之间应该没有区别,因为宏后的所有空格都会被忽略。
我怎样才能使第二个版本的行为与第一个版本相似?我试图将其附加\ignorespaces
到宏的定义中\base
,但它所做的只是添加一个文字 (url-encoded) %5Cignorespaces
。
答案1
我不知道这对您是否有帮助,但是当 TeX 从 .tex-input-files 读取输入时,它会在输入行的每一端插入一个字符,该字符在 TeX 的内部字符编码方案中的代码点编号(对于传统 TeX 为 ASCII,对于基于 XeTeX 或 LuaTeX 的引擎为 unicode)等于整数参数的值\endlinechar
。
如果的值\endlinechar
超出了字符可能的代码点数范围,则不插入任何字符。
通常的值为\endlinechar
13(十进制),这意味着插入了一个返回字符,因为 13(十进制)是 ASCII 和 unicode 中返回字符的代码点编号。(TeX^^
符号中的返回字符可以用 表示^^M
,M
即字母表中的第 13 个字母。)
通常,返回字符的类别代码为 5。如果 TeX 在读取装置处于状态 S(跳过空格)时遇到 catcode-5 字符,则不会向该字符的标记流中插入任何标记。在对字符代码 32 和类别代码 10(空格)的显式空格标记、对控制字标记以及对控制空格进行标记之后,TeX 的读取装置切换到状态 S。\
如果 TeX 在读取装置处于状态 M(行中间)时遇到 catcode-5 字符,则将字符代码 32 和类别代码 10(空格)的显式空格标记插入到该字符的标记流中。在对控制空格以外的字符标记或控制符号标记进行标记之后,TeX 的读取装置切换到状态 M。如果 TeX 在读取设备处于状态 N(新行)时遇到 catcode-5 字符,则控制字标记\par
将插入到此字符的标记流中,无论其含义/定义\par
如何。当开始对另一行进行标记时,TeX 的读取设备将切换到状态 N。
因此,您可以假设在\base
(这是一个控制字标记)之后,阅读设备处于状态 S,因此由于 -thingie 而插入返回字符\endlinechar
不会导致将任何标记插入到标记流中。
但是\href
-command 有点特殊:\href
在从 .tex 输入文件读取并开始标记 URL 参数之前,调用宏将返回字符的类别代码更改为 13(活动),并将活动返回字符定义为提供空格标记/类别代码为 10(空格)和字符代码为 32 的字符标记的宏。因此,\href
.tex 输入文件中的换行符 URL 参数会将类别代码为 13(活动)的返回字符标记插入到标记流中。当时的活动返回字符标记被定义为扩展为空格标记的宏。
我不知道以下建议是否适合您的工作流程,但也许您可以分配\endlinechar
一个超出字符可能的代码点数范围的值,例如值 -1。这样,TeX 就不会在换行符处插入任何字符。
\documentclass{article}
\usepackage{hyperref}
\newcommand{\base}[0]{http://www.example.com/}
\begin{document}
\href {\base test.html}{Link without space}
\href {\base
test.html}{Link with space}
%Probably something like this does the trick for you:
\begingroup
\endlinechar=-1\relax
\href{\base
test.html}{What's this?}
\endgroup
\end{document}
但是如果您可以搜索用于在各处插入的来源\begingroup\endlinechar=-1\relax..\endgroup
,那么您也可以搜索用于删除 之后的换行符的来源\base
。
也许您可以定义\base
一个宏来调用它,该宏会抓取一个非分隔参数,并(假设这是下一个标记)检查它是否是 active-return,并且仅在不是的情况下将其放回。但这有一些缺点:
- 由于一切都必须按照宏扩展的方式进行,“前瞻”也必须通过宏参数来完成。因此前瞻不是在下一个标记上,而是在下一个宏参数上。如果后面有一个用花括号括起来的多标记参数
\base
,则这些花括号将被删除。如果在之后没有更多适合作为宏参数的标记\base
,例如,\href{\base}{What's this?}
那么您可能会收到一些 hyperref-release 错误消息。 \base
仅会处理标记之后的换行符。
\documentclass{article}
\usepackage{hyperref}
\begingroup
\makeatletter
\catcode`\^^M=12\relax%
\def\activereturnfork#1{%
\endgroup%
\newcommand\activereturnfork[1]{%
\forkactivereturn##1{}#1{##1}^^M^^M%
}%
\@ifdefinable\forkactivereturn{%
\long\def\forkactivereturn##1#1##2##3^^M^^M{##2}%
}%
}%
\catcode`\^^M=13\relax%
\activereturnfork{^^M}%
\newcommand{\base}[0]{http://www.example.com/\activereturnfork}
\begin{document}
\href {\base test.html}{Link without space}
\href {\base
test.html}{Link without space, too}
But:
% This will not be a link to http://www.example.com/{bracesremoved}.html
% but will be a link to http://www.example.com/bracesremoved.html :
\href {\base {bracesremoved}.html}{Link with braces removed}
% But curly braces in any case are unsafe-characters and therefore in
% urls should be encoded with percent-encoding as %7B respective %7D .
% With current \hyper@normalize (hyperref 2018/11/30 v6.88e Hypertext links
% for LaTeX) this works by accident:
% \base/\activereturnfork takes \Hy@RemovePercentCr's \ifx for its argument
% and returns it:
\href {\base}{Attempts at creating this link may cause troubles when in future hyperref-releases internals are changed.}
\end{document}
可能最好的选择是修改 BibTeX 样式,以便不在非标准类别代码制度下标记的宏参数中进行换行。