Verschachtelte bedingte Glossarbegriffe mithilfe von Glossaren \ifglsused in \newglossaryentry

Verschachtelte bedingte Glossarbegriffe mithilfe von Glossaren \ifglsused in \newglossaryentry

Wenn ich einen Glossareintrag, der auf einem anderen Glossarbegriff basiert oder sich auf ihn bezieht, bedingt erweitern möchte, finde ich die bedingte \ifglsused{}{}{}Anweisung sehr hilfreich.

Um übergeordnete Änderungen zu berücksichtigen, falls der übergeordnete Begriff noch nicht verwendet wurde, \glsdisp{}{}stelle ich sicher, dass die Voraussetzung zwar „verwendet“, aber bei der ersten Verwendung nicht als programmiert angezeigt wird.

\ifglsused{TNF}{\glsdisp{TNF}{\TNFalpha}}{\glsdisp{TNF}{tumor necrosis factor--\textalpha~(\TNFalpha)}}Wie mit dem Artikel im MWE weiter unten gezeigt , funktioniert dies einwandfrei.

Interessanterweise schlägt diese identische Auswertung fehl, wenn sie Teil des \newglossaryentry{}IE innerhalb der first={}Deklaration des untergeordneten Begriffs selbst ist.

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} 

Update: Ich habe dieses Problem gelöst, indem ich einen neuen Glossarschlüssel (der die Basis angibt) und eine neue Funktion erstellt habe, die unabhängig von der Erstellung des Glossareintrags dieselbe Verwendungs- und Anzeigelogik ausführt. Die Funktionsvorlage, auf der ich dies basiert, ist hier: Neue Felder in Glossaren erstellen newglossaryentry

Da der Grund für diese Frage - verschachtelte Glossarerweiterungen mit minimaler Duplizierung - über einen völlig anderen Ansatz gelöst wird, wäre ich dennoch daran interessiert, mehr über die Nuancen vonnewglossaryentry

  • Ich vermute, dass dies bedeutet, dass es irgendwie first={}ausgewertet wird, bevor \gls{}es tatsächlich aufgerufen wird, und dass daher kein Boolescher Wert geändert wurde, was eine fortwährende falsche Auswertung ohne Fehler garantiert, aber es wäre gut, das zu wissen.

  • Meine nächste Vermutung wäre, dass dies etwas mit dem geschützten Status von \gls{} oder sogar nur mit der Reihenfolge zu tun hat, in der der Code ausgewertet wird?

Antwort1

Hier gibt es zwei Hauptprobleme.

Felderweiterung

Von demBenutzerhandbuch:

Wenn Sie neue Glossareinträge definieren, wird standardmäßig die Erweiterung durchgeführt, mit Ausnahme der Schlüssel name, description, descriptionplural, symbol, symbolpluralund sort(bei allen diesen Schlüsseln wird die Erweiterung über unterdrückt \glssetnoexpandfield).

(Der Grund für diese Ausnahmen liegt in der Abwärtskompatibilität mit früheren Versionen, die diese Informationen in die Glossardatei geschrieben haben. Die Unterdrückung der Erweiterung half dabei, fragile Befehle beim Schreibvorgang zu schützen.)

Um dies in Aktion zu sehen, können wir die glossariesDebugging-Befehle verwenden (nur beschrieben indokumentierter Code, nicht im Benutzerhandbuch). \showglonamezeigt die Definition des nameFelds an, \showglofirstzeigt die Definition des firstFelds an und \showglotextzeigt die Definition des textFelds an (in jedem Fall ist ein Argument erforderlich, und das ist die Eintragsbezeichnung). (Ich habe das MWE gekürzt.)

\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}

Dies erzeugt keine Ausgabe, zeigt aber die Definitionen im Transkript. (Wenn diese Befehle im interaktiven Modus von TeX ausgeführt werden, unterbrechen sie die Ausführung, als wären sie Fehlermeldungen.) Nachfolgend finden Sie die relevanten Teile des Transkripts.

Der Wert des firstFeldes für den TNFEintrag:

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

Der Wert des firstFeldes für den TNFalphaEintrag:

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

Hier \TNFalphawurde der Befehl also erweitert und das geschützte Leerzeichen ebenfalls, wird ~aber \textalphanicht erweitert, weil es geschützt ist.

Der Wert des nameFeldes für den TNFEintrag:

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

Der Wert des nameFeldes für den TNFalphaEintrag:

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

Hier \TNFalphawurde nicht erweitert, da der nameSchlüssel standardmäßig nicht erweitert wird.

Der textSchlüssel wurde nicht explizit verwendet und hat daher seinen Wert aus dem Feld übernommen name. In diesem Fall wird jedoch eine Erweiterung durchgeführt.

Der Wert des textFeldes für den TNFEintrag:

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

Der Wert des textFeldes für den TNFalphaEintrag:

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

Anders als beim nameAcker \TNFalphawurde dieser nun erweitert.

Wenn Sie also \ifglsusedinnerhalb des firstSchlüssels verwenden, wird es standardmäßig ausgewertetwenn der Eintrag definiert istWenn das obige Beispiel so geändert wird, dass die Definition für TNFalphajetzt lautet:

\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}
}

Dann \showglofirst{TNFalpha}wird immer noch das gleiche Ergebnis erzielt:

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

Dies liegt daran, dass, wenn TNFalphadefiniert ist, TNFnicht verwendet wurde, sodass die Definition auf den falschen Teil (drittes Argument) von erweitert wird \ifglsused.

Verschachtelte Links

Wenn Sie \glsdispdem firstFeld (oder einen ähnlichen Befehl) hinzufügen, erhalten Sie verschachtelte Links. Sowohl als auch \glsdispverwenden \glsintern denselben Befehl, \@gls@linkum mit dem Hyperlink umzugehen und den Linktext in einzuschließen \glstextformat. Das Verschachteln dieser Befehle kann also zu Problemen führen.

firstDie einfachste Lösung besteht darin, die Erweiterung für die Felder und auszuschalten firstplural, \glsdispaus dem Feldwert zu entfernen und nur noch zu verwenden, \glsunsetum den TNFEintrag als verwendet zu kennzeichnen. So:

\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} 

Das Ergebnis:

Tumornekrosefaktor Alpha (TNF-Alpha). TNF.

Wenn Sie sie vertauschen, so dass Sie haben

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

anstatt

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

dann ist das Ergebnis

Tumornekrosefaktor (TNF). TNF-alpha.

Bearbeiten:Die Erweiterungseinstellungen werden jedes Mal überprüft, wenn ein neuer Eintrag definiert wird. Sie müssen die Erweiterung jedoch nur dann erneut einschalten, wenn Sie einen Eintrag haben, bei dem die Felder erweitert werden müssen. Beispiel:

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

Diese Art der Definition sieht etwas seltsam aus, wenn sie explizit so gemacht wird, aber sie wird manchmal von Befehlen gemacht, die intern verwenden \newglossaryentry. Im obigen Beispiel \stuffmuss erweitert werden, wenn der Eintrag als \stuffnur ein temporärer Befehl definiert ist, dessen Definition sich ständig ändert. Wenn Sie diese Situation nicht haben, können Sie einfach alle Ihre \glsetnoexpandfieldBefehle eingeben, bevor Sie mit der Definition Ihrer Einträge beginnen.

Groß-/Kleinschreibung ändern

Der erste Buchstabe Großbuchstaben Befehle wie \Glsuse \makefirstuczur Verfügung gestellt vonmfirstuc. Dieser Befehl versucht zwar, mit der Möglichkeit umzugehen, dass das Argument einen Formatierungsbefehl enthalten könnte, aber da es keine allgemeine Möglichkeit gibt, die Syntax eines Befehls zu bestimmen, insbesondere welches Argument Text und welches ein Label ist, \makefirstucmüssen einige Einschränkungen angewendet werden, um richtig zu funktionieren.

  1. Wenn das Argument mit beginnt \protect, wird dies verworfen und \makefirstucauf den Rest angewendet. Beispielsweise \makefirstuc{\protect\textbf{foo}}ist dasselbe wie \makefirstuc{\textbf{foo}}.
  2. Das Argument von \makefirstuckann einfach mit Text beginnen. Beispielsweise führt \makefirstuc{foo}einfach „does \MakeUppercase foo“ zu „Foo“. Wohingegen „ \makefirstuc{{fo}o}does \MakeUppercase{fo}o“ zu „FOo“ führt.
  3. Wenn das Argument von \makefirstucmit einer Steuersequenz ohne Argument beginnt, wird angenommen, dass es sich bei dieser Steuersequenz um eine Zeichensteuersequenz wie \aeoder handelt \o, und die Groß-/Kleinschreibung wird darauf angewendet. Beispielsweise \makefirstuc{\ae foo}ergibt \MakeUppercase\ae foowhich Æfoo. Dies bedeutet, dass

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

    tut, was \MakeUppercase\fooFOO erzeugt.

  4. Wenn das Argument von \makefirstucmit einer Steuersequenz beginnt, auf die eine Gruppe folgt, wird davon ausgegangen, dass die Steuersequenz ein Formatierungsbefehl ist. Das gruppierte Material wird als Text betrachtet und die Groß-/Kleinschreibung wird darauf angewendet. Beispielsweise \makefirstuc{\textbf{foo}}ist äquivalent zu \textbf{\MakeUppercase foo}was zuFoo.

Für das Argument wird keine Erweiterung durchgeführt, \makefirstucda dies dazu führen könnte, dass einfache Textblockbefehle mit einem einzelnen Argument in etwas erweitert werden, das zu kompliziert zum Analysieren ist.

Zurückkehren zum MWE \Gls{TNFalpha}bei der ersten Verwendung (oder \Glsfirst{TNFalpha})

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

Dies fällt in Fall 4 (Kontrollsequenz gefolgt von einer Gruppe). Dies versucht also

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

was die Ursache Ihrer Fehlermeldung ist. Die einzige Möglichkeit, das Problem zu lösen, besteht darin, einen Befehl zu definieren, bei dem das erste Argument der Text ist, bei dem die Groß-/Kleinschreibung geändert werden muss. Beispiel:

% \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}
}

Da \TNFalpha„bereits“ mit einem Großbuchstaben beginnt, müssen Sie sich keine Gedanken darüber machen, wie der Fall behandelt wird, wenn die Bedingung \ifnotuseddas zweite Argument auswählt.

verwandte Informationen