![为什么 hyperref 包会改变字体命令的编码?](https://linux22.com/image/296994/%E4%B8%BA%E4%BB%80%E4%B9%88%20hyperref%20%E5%8C%85%E4%BC%9A%E6%94%B9%E5%8F%98%E5%AD%97%E4%BD%93%E5%91%BD%E4%BB%A4%E7%9A%84%E7%BC%96%E7%A0%81%EF%BC%9F.png)
如果您使用 hyperref 编译以下文档,XeLaTeX
您将看到文本命令的编码被包更改hyperref
为“PU”编码。为什么这是必要的?
\documentclass{article}
\usepackage{fontspec}
\setmainfont{Linux Libertine O}
\usepackage{hyperref}
\begin{document}
\ttfamily
\meaning\textasciitilde\\
\meaning\textcelsius\\
\meaning\"\\
\meaning\NG\\
\meaning\k\\
\end{document}
有没有什么“陷阱”值得注意?
答案1
如果你不加载hyperref
,那么你会得到
macro:->\T1-cmd \textasciitilde \T1\textasciitilde
尽管默认编码是EU1
(或EU2
使用LuaLaTeX)。
和hyperref
你一起得到
macro:->\PU-cmd \textasciitilde \PU\textasciitilde
因为puenc.def
稍后已加载。该宏\PU-cmd
查找两个参数并执行
\ifx\protect\@typeset@protect
\@inmathwarn#1%
\expandafter\ifx\csname\cf@encoding\string#1\endcsname\relax
\expandafter\ifx\csname ?\string#1\endcsname\relax
\expandafter\def\csname ?\string#1\endcsname{\TextSymbolUnavailable#1}
\fi
\global\expandafter\let\csname\cf@encoding\string#1\expandafter\endcsname
\csname ?\string#1\endcsname
\fi
\csname\cf@encoding\string#1\expandafter\endcsname
\else
\noexpand#1%
\fi
参数是\textasciitilde
和\PU\textasciitilde
(一个标记)。
在正常排版中,\ifx\protect\typeset@protect
是真实的,所以\@inmathwarn\textasciitilde
是扩展的,但它确实
\ifmmode \@latex@warning {Command \protect #1 invalid in math mode}\fi
所以除非我们处于数学模式,否则什么也不会发生。然后 LaTeX 检查是否
\EU1\textasciitilde
(一个标记)的定义是:\cf@encoding
扩展为当前输出编码。如果不是,则通常意义上的\EU1\textasciitilde
相当于\relax
或未定义,LaTeX 将查找\?\textasciitilde
(默认文本命令),如果缺少其定义,则会定义错误消息以供进一步使用,\EU1\textasciitilde
全局等效于\?\textasciitilde
。
最后,\EU1\textasciitilde
进行扩展。
如果第一个条件为假(即我们正在写入文件或其他特殊位置),则\noexpand\textasciitilde
只会保留在输入流中。
你看,这PU
永远不会干预,除非\cf@encoding
是 PU
,这是在hyperref
执行写书签工作时发生的。