\newglossaryentry で Glossaries \ifglsused を使用したネストされた条件付き用語集用語

\newglossaryentry で Glossaries \ifglsused を使用したネストされた条件付き用語集用語

別の用語集の用語に基づいて、または別の用語集の用語に関連する用語集のエントリを条件付きで拡張したい場合、条件\ifglsused{}{}{}ステートメントが非常に役立つと思います。

親用語がまだ使用されていない場合に親の変更を満たすために、\glsdisp{}{}前提条件が「使用」されるが、最初の使用でプログラムされたとおりには表示されないことを確認します。

\ifglsused{TNF}{\glsdisp{TNF}{\TNFalpha}}{\glsdisp{TNF}{tumor necrosis factor--\textalpha~(\TNFalpha)}}以下の MWE の項目 で示されているように、これは正常に動作します。

興味深いことに、この同一の評価は、子項自体の宣言 \newglossaryentry{}内の ieの一部である場合は失敗します。first={}

MWE:

\documentclass{article}
\usepackage[utf8]{inputenc}

\setlength\parindent{0pt}

%=========================================================================================================================================
% PACKAGES REQUIRED FOR GLOSSARIES
%=========================================================================================================================================

% Glossaries must be loaded before amsmath as per details in the following forum answer
% https://tex.stackexchange.com/questions/85696/what-causes-this-strange-interaction-between--and-amsmath
\usepackage[nogroupskip,toc,acronym]{glossaries} % must come after href   
\usepackage{scrwfile}%http://www.dickimaw-books.com/cgi-bin/faq.cgi?action=view&categorylabel=glossaries#glsnewwriteexceeded
\usepackage{siunitx,microtype,textcomp,textgreek}
\usepackage{etoolbox}
\makeglossaries

\newglossaryentry{TNF}{ 
    type={acronym}, 
    sort={tumor necrosis factor},  
    name={TNF}, 
    short={TNF}, 
    long={tumor necrosis factor}, 
    first={tumor necrosis factor (TNF)}, 
    description={tumor necrosis factor}     
}

\newcommand{\TNFalpha}{TNF--{\textalpha}}
\newglossaryentry{TNFalpha}{ 
    type={acronym}, 
    sort={tumor necrosis factor alpha},  
    name={TNF--{\textalpha}}, 
    short={TNF--{\textalpha}}, 
    long={tumor necrosis factor alpha}, 
    first={\ifglsused{TNF}{\glsdisp{TNF}{\TNFalpha}}{\glsdisp{TNF}{tumor necrosis factor--\textalpha~(\TNFalpha)}}}, 
    description={tumor necrosis factor alpha}
}

\begin{document}

    \begin{itemize}
        %\item \gls{TNFalpha}
        \item \gls{TNF}
        \item \gls{TNFalpha}
        \item \glsentryfirst{TNFalpha}
        \item \ifglsused{TNF}{\glsdisp{TNF}{\TNFalpha}}{\glsdisp{TNF}{tumor necrosis factor--\textalpha~(\TNFalpha)}}
    \end{itemize}

\end{document} 

更新: 新しい用語集キー (ベースを指定する) と、用語集エントリの作成とは独立して同じ使用および表示ロジックを実行する新しい関数を作成することで、この問題を解決しました。これのベースとなった関数テンプレートは次のとおりです。 用語集に新しいフィールドを作成する newglossaryentry

この質問の背後にある理由、つまり重複を最小限に抑えたネストされた用語集の拡張は、まったく異なるアプローチで解決されるため、私は依然としてニュアンスについて学ぶことに興味があります。newglossaryentry

  • first={}これは、実際に呼び出す前に何らかの方法で評価されているため、使用されないブール値が変更され、失敗することなく永続的に偽の評価が保証されることを意味すると推測し\gls{}ていますが、知っておくと便利です。

  • 次に推測するのは、これが \gls{} の保護ステータスと関係があるか、あるいは単にコードが評価される順序と関係があるのではないかということです。

答え1

ここでは主に2つの問題があります。

フィールドの拡張

からユーザーマニュアル:

新しい用語集エントリを定義すると、、、、、および キーを除いて、デフォルトで拡張が実行されますname(これら のdescriptionキーはdescriptionpluralすべてによって拡張が抑制されます)。symbolsymbolpluralsort\glssetnoexpandfield

(これらの例外の理由は、用語集ファイルにその情報を書き込んでいた以前のバージョンとの下位互換性のためです。拡張の抑制は、書き込みプロセスで脆弱なコマンドを保護するのに役立ちました。)

これを実際に確認するには、glossariesデバッグコマンド(文書化されたコード(ユーザーマニュアルには記載されていません)。フィールド\showglonameの定義が表示されname、フィールド\showglofirstの定義が表示されfirst、フィールド\showglotextの定義が表示されますtext(それぞれの場合に必要な引数は 1 つで、それがエントリ ラベルです)。(MWE を省略しました。)

\documentclass{article}

\usepackage{textgreek}
\usepackage[nogroupskip,toc,acronym]{glossaries}
\makeglossaries

\newglossaryentry{TNF}{ 
  type={acronym}, 
  sort={tumor necrosis factor},  
  name={TNF}, 
  first={tumor necrosis factor (TNF)}, 
  description={tumor necrosis factor}
}   

\newcommand{\TNFalpha}{TNF--{\textalpha}}
\newglossaryentry{TNFalpha}{
    type={acronym},
    sort={tumor necrosis factor alpha},
    name={\TNFalpha},
    first={tumor necrosis factor alpha~(\TNFalpha)},   
    description={tumor necrosis factor alpha}
}

\begin{document}
\showglofirst{TNF}
\showglofirst{TNFalpha}

\showgloname{TNF}
\showgloname{TNFalpha}

\showglotext{TNF}
\showglotext{TNFalpha}

\end{document}

これは出力を作成しませんが、トランスクリプトに定義を表示します。(TeX の対話モードで実行すると、これらのコマンドはエラー メッセージであるかのように実行を中断します。) 以下はトランスクリプトの関連部分です。

firstエントリのフィールドの値TNF:

> \glo@TNF@first=macro:
->tumor necrosis factor (TNF).

firstエントリのフィールドの値TNFalpha:

> \glo@TNFalpha@first=macro:
->tumor necrosis factor alpha\protect \nobreakspace  {}(TNF--{\textalpha }).

ここでは\TNFalphaコマンドが展開されており、改行不可スペースも展開されています~が、\textalpha保護されているため展開されません。

nameエントリのフィールドの値TNF:

> \glo@TNF@name=macro:
->TNF.

nameエントリのフィールドの値TNFalpha:

> \glo@TNFalpha@name=macro:
->\TNFalpha .

ここでは、キーがデフォルトで展開されていない\TNFalphaため、展開されていません。name

キーtextは明示的に使用されなかったため、フィールドから値を取得しましたnameが、この場合は拡張が実行されます。

textエントリのフィールドの値TNF:

> \glo@TNF@text=macro:
->TNF.

textエントリのフィールドの値TNFalpha:

> \glo@TNFalpha@text=macro:
->TNF--{\textalpha }.

フィールドとは異なりname\TNFalpha現在は拡張されています。

\ifglsusedしたがって、キー内で使用するとfirst、デフォルトでは評価されますエントリが定義されるとき上記の例を変更して、 の定義をTNFalpha次のようにすると、

\newglossaryentry{TNFalpha}{
    type={acronym},
    sort={tumor necrosis factor alpha},
    name={\TNFalpha}, 
    first={\ifglsused{TNF}{\TNFalpha}{tumor necrosis factor alpha~(\TNFalpha)}}, 
    description={tumor necrosis factor alpha}
}

それでも\showglofirst{TNFalpha}同じ結果が生成されます。

> \glo@TNFalpha@first=macro:
->tumor necrosis factor alpha\protect \nobreakspace  {}(TNF--{\textalpha }).

TNFalphaこれは、 が定義されているときにTNFが使用されていないため、その定義が の false 部分 (3 番目の引数) に展開されるためです\ifglsused

ネストされたリンク

\glsdispフィールドに (または同様のコマンド)を追加するとfirst、ネストされたリンクが作成されます。 と はどちらも、\glsdispハイパーリンクを処理し、リンク テキストを 内にラップするために、\gls内部で同じコマンドを使用します。そのため、これらのコマンドをネストすると問題が発生する可能性があります。\@gls@link\glstextformat

first最も簡単な解決策は、およびフィールドの拡張をオフにしfirstplural\glsdispフィールド値から を削除して、エントリが使用済みとして\glsunsetマークすることです。次のようになります。TNF

\documentclass{article}

\usepackage{textgreek}
\usepackage[nogroupskip,toc,acronym]{glossaries}
\makeglossaries

\newglossaryentry{TNF}{ 
  type={acronym}, 
  sort={tumor necrosis factor},  
  name={TNF}, 
  first={tumor necrosis factor (TNF)}, 
  description={tumor necrosis factor}
}   

\glssetnoexpandfield{first}
\glssetnoexpandfield{firstpl}

\newcommand{\TNFalpha}{TNF--{\textalpha}}
\newglossaryentry{TNFalpha}{
    type={acronym},
    sort={tumor necrosis factor alpha},
    name={\TNFalpha}, 
    first={\ifglsused{TNF}{\TNFalpha}{\glsunset{TNF}tumor necrosis factor alpha~(\TNFalpha)}},
    description={tumor necrosis factor alpha}
}

\begin{document}
\gls{TNFalpha}. \gls{TNF}.

\end{document} 

これにより、次のものが生成されます。

腫瘍壊死因子アルファ(TNF-アルファ)。TNF。

これらを入れ替えると

\gls{TNF}. \gls{TNFalpha}.

の代わりに

\gls{TNFalpha}. \gls{TNF}.

結果は

腫瘍壊死因子(TNF)。TNF-アルファ。

編集:拡張設定は新しいエントリが定義されるたびにチェックされますが、フィールドを拡張する必要があるエントリがある場合にのみ、拡張を再度オンにする必要があります。例:

\newcommand{\stuff}{foo}
\newglossaryentry{stuff1}{name={\stuff},description={stuff1}}
\renewcommand{\stuff}{bar}
\newglossaryentry{stuff2}{name={\stuff},description={stuff2}}

このタイプの定義は、明示的にこのように行うと少し奇妙に見えますが、内部的に を使用するコマンドによって行われることがあります\newglossaryentry。上記の例では、\stuffエントリが として定義されるときに を展開する必要があります\stuff。 は、定義が変わり続ける一時的なコマンドです。このような状況でない場合は、\glsetnoexpandfieldエントリの定義を開始する前に、すべてのコマンドを配置するだけで済みます。

大文字と小文字の変更

最初の文字の大文字コマンドは、\Glsuse\makefirstucによって提供されるmfirstucこのコマンドは、引数に書式設定コマンドが含まれている可能性に対処しようとしますが、コマンドの構文 (具体的にはどの引数がテキストでどの引数がラベルであるか) を判断する一般的な方法がないため、\makefirstuc適切に機能するためにはいくつかの制限を適用する必要があります。

  1. 引数が で始まる場合\protect、これは破棄され、\makefirstuc残りの部分に適用されます。たとえば、\makefirstuc{\protect\textbf{foo}}は と同じです\makefirstuc{\textbf{foo}}
  2. の引数は、\makefirstucテキストだけで始まる場合があります。たとえば、\makefirstuc{foo}は のみで\MakeUppercase foo、結果は Foo になります。一方、 は で、結果は FOo に\makefirstuc{{fo}o}なります\MakeUppercase{fo}o
  3. \makefirstucの引数が引数なしの制御シーケンスで始まる場合、その制御シーケンスは\aeまたはなどの文字制御シーケンスであるとみなされ\o、大文字と小文字の変更が適用されます。たとえば、はÆfooになり\makefirstuc{\ae foo}ます\MakeUppercase\ae foo。これは、

    \newcommand{\foo}{foo}\makefirstuc{\foo}
    

    これは FOO を生成します\MakeUppercase\foo

  4. の引数が\makefirstuc制御シーケンスで始まり、その後にグループが続く場合、制御シーケンスは書式設定コマンドであるとみなされます。グループ化された素材はテキストであるとみなされ、大文字と小文字の変更が適用されます。たとえば、は、次の結果\makefirstuc{\textbf{foo}}と同等です。\textbf{\MakeUppercase foo}うーん。

引数に対しては展開は実行されません。\makefirstucこれにより、単一の引数を持つ単純なテキスト ブロック コマンドが、解析するには複雑すぎるものに展開される可能性があります。

MWEへの\Gls{TNFalpha}初回使用時(または\Glsfirst{TNFalpha})試行時

\makefirstuc{\ifglsused{TNF}{\TNFalpha}{\glsunset{TNF}tumor necrosis
factor alpha~(\TNFalpha)}}

これはケース4(制御シーケンスの後にグループが続く)に該当します。つまり、これは

{\ifglsused{\MakeUppercase TNF}{\TNFalpha}{\glsunset{TNF}tumor necrosis 
factor alpha~(\TNFalpha)}}

これがエラー メッセージの原因です。この問題を解決する唯一の方法は、大文字と小文字の変更が必要なテキストを最初の引数とするコマンドを定義することです。例:

% \ifnotused{not used}{used}{label}
\newcommand*{\ifnotused}[3]{%
  \ifglsused{#3}{#2}{\glsunset{#3}#1}%
}

\newcommand{\TNFalpha}{TNF--{\textalpha}}
\newglossaryentry{TNFalpha}{
    type={acronym},
    sort={tumor necrosis factor alpha},
    name={\TNFalpha}, 
    first={\ifnotused{tumor necrosis factor alpha~(\TNFalpha)}{\TNFalpha}{TNF}},
    description={tumor necrosis factor alpha}
}

すでに大文字で始まっているので、条件文で2 番目の引数を選択する\TNFalpha場合の処理​​について心配する必要はありません。\ifnotused

関連情報