hyperref + 词汇表 + latex = 数学关系周围的间距不好

hyperref + 词汇表 + latex = 数学关系周围的间距不好

使用 latex && dvips 编译以下输入(有时由于各种原因您必须这样做;我的情况是重新编译旧文档):

\documentclass{article}
\usepackage[hidelinks]{hyperref}
\usepackage{glossaries}
\newglossaryentry{productOrder}{name={product order}, text={\sqsubseteq}, sort=productOrder, description={foo}}
\begin{document}
\noindent
\(A \sqsubseteq B\) (good spacing)\\
\(A \gls{productOrder} B\) (bad spacing)\\
\(A \not\sqsubseteq B\) (good overlaying)\\
\(A \not\gls{productOrder} B\) (bad overlaying)
\end{document}

您得到的结果是词汇表条目周围的间距错误,并且斜线与符号不匹配:

编译结果

查看 dvi 文件时,您还会看到错误的间距和覆盖(顺便说一下,那里的链接没有隐藏)。

当然,你总是可以使用\mathrel{\gls{productOrder}}\not\mathrel{\gls{productOrder}}。每次使用时都这样做很乏味,尽管我们可以(可能)为此编写一个宏。

但是,使用 pdflatex 编译上述文件会产生正确的间距和正确的覆盖,这让我认为 hyperref-glossaries 包链中存在错误。有错误修复吗?交换加载两个包的顺序可以解决问题,但 Nicola 的文档建议不要这样做。

答案1

您可以执行类似以下的操作(只需多花一点力气就可以集成为(比如说)mathclass=mathrel现有 keyval 列表中的键,但在这里作为一个命令,您可以选择定义它来强制围绕定义的 gls 条目进行数学类。

\documentclass{article}
\usepackage[hidelinks]{hyperref}
\usepackage{glossaries}
\makeglossaries




\let\oldhyperlink\hyperlink
\def\hyperlink#1#2{\glsmaththing{\oldhyperlink{#2}{#2}}}
\def\glsmaththing{\csname mathclass\detokenize\expandafter{\glslabel}\endcsname}

\newglossaryentry{productOrder}{name={product order}, text={\sqsubseteq}, sort=productOrder, description={foo}}
\newcommand\mathclassproductOrder{\mathrel}

\begin{document}
\noindent
\(A \sqsubseteq B\) (good spacing) \\
\(A \gls{productOrder} B\) (bad spacing)
\end{document}

答案2

默认情况下,类似这样的命令\gls(与 一起使用时hyperref)基本上会执行以下任务:

\hyperlink{target}{\glstextformat{text}}

如上所述,这对于 PDF 引擎来说运行良好,但对于 DVI 引擎则不然。

扩展包,glossaries-extra,现在(从 1.21 版,2017-11-03 开始​​)提供了一个布尔键hyperoutside。默认hyperoutside=true行为按照基础glossaries包的规范:

\hyperlink{target}{\glstextformat{text}}

设置hyperoutside=false,切换命令:

\glstextformat{\hyperlink{target}{text}}

由于总是这样做有点麻烦,因此可以设置\gls[hyperoutside=false]{productOrder}类别属性。hyperoutside

扩展包提供了一个额外的键category,可以在定义条目时使用。该值只是一个标签,因此您可以将productOrder条目定义为:

\newglossaryentry{productOrder}{
  category=mathrelation,
  name={product order},
  text={\sqsubseteq}, sort=productOrder, description={foo}}

mathrelation然后可以将类别的属性hyperoutside设置为false

\glssetcategoryattribute{mathrelation}{hyperoutside}{false}

这意味着\gls{productOrder}现在的行为将类似于\gls[hyperoutside=false]{productOrder},但它不会影响您定义的任何其他条目(除非它们也有category=mathrelation)。

现在,它\glstextformat的外部\hyperlink可以被重新定义为\mathrel

\renewcommand{\glstextformat}[1]{\mathrel{#1}}

但这会给您的所有其他条目带来问题。

这个新版本glossaries-extra还识别另一个属性textformat,该属性可以设置为控制序列名称(不带前导反斜杠),用于标识可以代替的命令(接受单个参数)\glstextformat

\glssetcategoryattribute{mathrelation}{textformat}{mathrel}

这意味着

\glstextformat{\hyperlink{target}{text}}

任何用 定义的条目category=mathrelation都会执行:

\mathrel{\hyperlink{target}{text}}

所有其他条目将正常运行。

这是一个完整的示例,包括hyperoutside=true比较和colorlinks突出显示超链接:

\documentclass{article}

\usepackage[colorlinks]{hyperref}
\usepackage{glossaries-extra}

\glssetcategoryattribute{mathrelation}{hyperoutside}{false}
\glssetcategoryattribute{mathrelation}{textformat}{mathrel}

\newglossaryentry{productOrder}{
  category=mathrelation,
  name={product order},
  text={\sqsubseteq}, sort=productOrder, description={foo}}

\begin{document}
\noindent
\(A \sqsubseteq B\)\\
\(A \gls{productOrder} B\)\\
\(A \gls[hyperoutside]{productOrder} B\)
\end{document}

A⊑BA⊑BA⊑B

对于否定,我建议定义一个移动\not链接文本内部的命令:

\newcommand*{\notgls}[2][]{\glsdisp[#1]{#2}{\not\glsentrytext{#2}}}

更新的 MWE:

\documentclass{article}

\usepackage[colorlinks]{hyperref}
\usepackage{glossaries-extra}

\glssetcategoryattribute{mathrelation}{hyperoutside}{false}
\glssetcategoryattribute{mathrelation}{textformat}{mathrel}

\newglossaryentry{productOrder}{
  category=mathrelation,
  name={product order},
  text={\sqsubseteq}, sort=productOrder, description={foo}}

\newcommand*{\notgls}[2][]{\glsdisp[#1]{#2}{\not\glsentrytext{#2}}}

\begin{document}
\noindent
\(A \sqsubseteq B\)\\
\(A \gls{productOrder} B\)\\
\(A \not\gls{productOrder} B\)\\
\(A \notgls{productOrder} B\)
\end{document}

A⊑BA⊑BA/⊑BA⋢B

相关内容