标题干扰词汇表的首次/后续使用机制

标题干扰词汇表的首次/后续使用机制

这是关于图表列表中的词汇表溢出,其中有人问到如何glossaries将包的第一个使用方案与图标题中的词汇表术语一起使用。我给出了一个答案,只要caption未加载包,它就可以工作。

\documentclass{article}

\usepackage{caption}
\usepackage[colorlinks]{hyperref}
\usepackage{glossaries}

\makeglossaries
\newglossaryentry{acr}{%
  name        = {ACR-name},%
  description = {ACR-description},%
  first       = {ACR-first-description},%
}

\renewcommand{\glsdisplayfirst}[4]{#1 (1) #4}
\renewcommand{\glsdisplay}[4]{#1 (2+) #4}
\begin{document}
% \listoffigures %% even without \listoffigures the problem shows up

\begin{figure}[h]
  \caption[Short title \glshyperlink{acr}]{Long title \gls{acr}}
\end{figure}

\printglossary
\end{document}

可以看出,没有caption图形标题时,词汇表条目的第一个使用形式正如所期望的那样,但是有图形标题时,词汇表caption条目的后续使用形式就体现出来了。

如何在使用时保持其正常工作caption

答案1

LaTeX 将标题放在临时的草稿内\hbox,测量其宽度。如果宽度小于线宽,则盒子被重复用于排版标题。因此\gls被调用一次。但是,如果标题宽度超出了行宽,则标题文本将被设置两次,这次是段落。然后\gls被调用两次,您将获得词汇表项的第二个版本的输出。

caption使行为更加可预测。如果singlelinecheck设置了选项(默认),则标题文本始终设置两次,第一次用于测量宽度以检查文本是否适合一行,然后再次设置文本以获得最终结果。使用时singlelinecheck=false,测量被禁用并且文本仅设置一次,但标题文本的居中会丢失。

一种解决方法是将结果放在\gls{acr}一个临时框中,并在里面使用此框\caption

\documentclass{article}

\usepackage{caption}
\usepackage{glossaries}

\newsavebox\glsscratchbox

\makeglossaries
\newglossaryentry{acr}{%
  name        = {ACR-name},%
  description = {ACR-description},%
  first       = {ACR-first-description},%
}

\renewcommand{\glsdisplayfirst}[4]{#1 (1) #4}
\renewcommand{\glsdisplay}[4]{#1 (2+) #4}
\begin{document}
\listoffigures %% even without \listoffigures the problem shows up

\begin{figure}[h]
  \sbox\glsscratchbox{\gls{acr}}
  \caption[Short title \glshyperlink{acr}]{Long title \unhcopy\glsscratchbox}
\end{figure}

\printglossary
\end{document}

(使用该命令\unhcopy代替\usebox(这是一个\copy)。它剥离外层\hbox并允许空格以与行中其他空格相同的方式排版。否则(\usebox)重用框内的空间将始终具有自然宽度。)

结果

\gls标题中的解决方案与包caption

更新:添加了 Axel Sommerfeldt 的评论的简化。

glossaries必须记住缩写词的首次使用。如果测量了标题的宽度,则禁用此功能,但如果最终排版了标题文本,则不禁用此功能。

caption需要包,因为它将测试与最终排版步骤分开。它还提供了\caption@prepareslc在测量之前调用的宏。\glsunset暂时禁用测量。

\documentclass{article}

\usepackage{glossaries}
\usepackage{caption}

\makeatletter
\g@addto@macro\caption@prepareslc{%
  \let\glsunset\@gobble
}
\makeatother

\makeglossaries
\newglossaryentry{acr}{%
  name        = {ACR-name},%
  description = {ACR-description},%
  first       = {ACR-first-description},%
}

\renewcommand{\glsdisplayfirst}[4]{#1 (1) #4}
\renewcommand{\glsdisplay}[4]{#1 (2+) #4}
\begin{document}
\listoffigures

\begin{figure}[h]
  \caption[Short title \glshyperlink{acr}]{Long title \gls{acr}}
\end{figure}

\printglossary
\end{document}

细化

如果\gls{acr}使用,则为首字母缩略词设置一个全局标志,acr以记住首字母缩略词使用的状态。因此后续调用可以使用较短的形式。如果仅测量标题文本,则先前的解决方案会跳过状态设置。因此,当最终设置标题文本时,状态不会改变。

但是,有一种情况很容易被忽略。标题文本包含\gls多次相同的首字母缩略词,包括其首次使用。那么,之前的解决方案将包含首字母缩略词在测量步骤中的首次使用形式,因为那里的状态设置已被禁用。

通过在测量步骤中允许缩写词的正常状态变化但记住第一次使用来解决这个问题。在标题文本的最终排版之前,会进行重置。

进一步说明:

  • 引入一个开关\if@capmeasure,一般设置为\iffalse,当 里面检查了文本的宽度\caption,则设置为\iftrue
  • caption需要包,因为它将测试与最终排版步骤分开。它还提供了\caption@prepareslc在测量之前执行的宏。两者都在同一个本地组中执行。因此,添加到 就足够了\@capmeasurefalse\caption@prepareslc组结束后,开关会自动重置。
  • 测量之后,第一个缩写词的使用状态被重置。
  • glossaries'\glsunset已修补,以尊重设置\if@capmeasure并记住第一个缩写词的用法。

完整示例:

\documentclass{article}

\usepackage{glossaries}
\usepackage{caption}

\makeatletter
\newif\if@capmeasure
\g@addto@macro\caption@prepareslc{%
  \global\let\after@capmeasure\@empty
  \aftergroup\after@capmeasure
  \@capmeasuretrue
}
\CheckCommand*{\glsunset}[1]{%
  \glsdoifexists{#1}{%
    \expandafter \global \csname glo@#1@flagtrue\endcsname   
  }%
}
\renewcommand*{\glsunset}[1]{%
  \glsdoifexists{#1}{%
    \if@capmeasure
      \expandafter\ifx\csname ifglo@#1@flag\expandafter\endcsname
      \csname iftrue\endcsname
      \else 
        % first use
        \g@addto@macro\after@capmeasure{\glsreset{#1}}%
      \fi
    \fi
    \global\csname glo@#1@flagtrue\endcsname
  }%
}
\makeatother

\makeglossaries
\newglossaryentry{acr}{%
  name        = {ACR-name},%
  description = {ACR-description},%
  first       = {ACR-first-long-description},%
}

\renewcommand{\glsdisplayfirst}[4]{#1\textsuperscript{(1)}#4}
\renewcommand{\glsdisplay}[4]{#1\textsuperscript{(2+)}#4}
\begin{document}
\listoffigures

\begin{figure}[h]
  \caption[Short title \glshyperlink{acr}]%
  {Long title \textit{\gls{acr}} and \gls{acr}}
\end{figure}

\printglossary
\end{document}

改进后的结果

答案2

使用时,glossaries-extra您有两种选择。请参阅这里

  1. 您始终可以\glsxtrshort在标题内调用。出于显而易见的原因,这些不会触发首次使用。如果您还想避免链接并且不希望这些条目出现在使用 创建的词汇表列表中,您还可以使用noindex和选项。这将我们带到:hyper=false\printglossaries
  2. 预测此用法glossaries-extra包括命令系列\glsfmtshort。这些命令与相应的命令相同\glsxtrshort[noindex,hyper=false]。因此,您有几个类似的命令,涵盖单数和复数形式、短、长和完整形式以及小写、首字母大写和完整大写形式。

相关内容