キャプションが用語集の初回使用/後続使用のメカニズムを妨害する

キャプションが用語集の初回使用/後続使用のメカニズムを妨害する

これはフォローアップの質問です図表一覧の用語集がオーバーフロー、パッケージの最初の使用スキームを図のキャプションの用語集の用語でどのように使用できるかという質問がありました。パッケージがロードされていない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は 1 回呼び出されます。ただし、キャプションの幅が行幅を超える場合、キャプション テキストは 2 回設定され、今度は段落として設定されます。次に、\glsが 2 回呼び出され、用語集項目の 2 番目のバージョンの出力が得られます。

パッケージによりcaption、動作がより予測可能になります。オプションsinglelinecheckが設定されている場合 (デフォルト)、キャプション テキストは常に 2 回設定されます。1 回目は幅を測定してテキストが 1 行に収まるかどうかを確認するため、2 回目は最終結果のためにテキストが再度設定されます。 を使用するとsinglelinecheck=false、測定は無効になり、テキストは 1 回だけ設定されますが、キャプション テキストの中央揃えは失われます。

回避策としては、 の結果を\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-extra2つの選択肢があります。ここ

  1. キャプション内ではいつでも を呼び出すことができます\glsxtrshort。明らかな理由により、これらは最初の使用をトリガーしません。また、リンクを回避し、 で作成された用語集リストにこれらのエントリを表示したくない場合は、noindexおよびオプションも使用できます。次に、hyper=false\printglossaries
  2. この使用法を予測するには、コマンドglossaries-extraファミリが含まれます\glsfmtshort。これらは対応するコマンドと同一です\glsxtrshort[noindex,hyper=false]。したがって、単数形と複数形、短縮形、長形、完全形、小文字、最初の文字が大文字、完全な大文字の各形式をカバーする類似のコマンドがいくつかあります。

関連情報