![Verschachtelte bedingte Glossarbegriffe mithilfe von Glossaren \ifglsused in \newglossaryentry](https://rvso.com/image/305883/Verschachtelte%20bedingte%20Glossarbegriffe%20mithilfe%20von%20Glossaren%20%5Cifglsused%20in%20%5Cnewglossaryentry.png)
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
,symbolplural
undsort
(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 glossaries
Debugging-Befehle verwenden (nur beschrieben indokumentierter Code, nicht im Benutzerhandbuch). \showgloname
zeigt die Definition des name
Felds an, \showglofirst
zeigt die Definition des first
Felds an und \showglotext
zeigt die Definition des text
Felds 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 first
Feldes für den TNF
Eintrag:
> \glo@TNF@first=macro:
->tumor necrosis factor (TNF).
Der Wert des first
Feldes für den TNFalpha
Eintrag:
> \glo@TNFalpha@first=macro:
->tumor necrosis factor alpha\protect \nobreakspace {}(TNF--{\textalpha }).
Hier \TNFalpha
wurde der Befehl also erweitert und das geschützte Leerzeichen ebenfalls, wird ~
aber \textalpha
nicht erweitert, weil es geschützt ist.
Der Wert des name
Feldes für den TNF
Eintrag:
> \glo@TNF@name=macro:
->TNF.
Der Wert des name
Feldes für den TNFalpha
Eintrag:
> \glo@TNFalpha@name=macro:
->\TNFalpha .
Hier \TNFalpha
wurde nicht erweitert, da der name
Schlüssel standardmäßig nicht erweitert wird.
Der text
Schlü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 text
Feldes für den TNF
Eintrag:
> \glo@TNF@text=macro:
->TNF.
Der Wert des text
Feldes für den TNFalpha
Eintrag:
> \glo@TNFalpha@text=macro:
->TNF--{\textalpha }.
Anders als beim name
Acker \TNFalpha
wurde dieser nun erweitert.
Wenn Sie also \ifglsused
innerhalb des first
Schlüssels verwenden, wird es standardmäßig ausgewertetwenn der Eintrag definiert istWenn das obige Beispiel so geändert wird, dass die Definition für TNFalpha
jetzt 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 TNFalpha
definiert ist, TNF
nicht verwendet wurde, sodass die Definition auf den falschen Teil (drittes Argument) von erweitert wird \ifglsused
.
Verschachtelte Links
Wenn Sie \glsdisp
dem first
Feld (oder einen ähnlichen Befehl) hinzufügen, erhalten Sie verschachtelte Links. Sowohl als auch \glsdisp
verwenden \gls
intern denselben Befehl, \@gls@link
um mit dem Hyperlink umzugehen und den Linktext in einzuschließen \glstextformat
. Das Verschachteln dieser Befehle kann also zu Problemen führen.
first
Die einfachste Lösung besteht darin, die Erweiterung für die Felder und auszuschalten firstplural
, \glsdisp
aus dem Feldwert zu entfernen und nur noch zu verwenden, \glsunset
um den TNF
Eintrag 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:
Wenn Sie sie vertauschen, so dass Sie haben
\gls{TNF}. \gls{TNFalpha}.
anstatt
\gls{TNFalpha}. \gls{TNF}.
dann ist das Ergebnis
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 \stuff
muss erweitert werden, wenn der Eintrag als \stuff
nur ein temporärer Befehl definiert ist, dessen Definition sich ständig ändert. Wenn Sie diese Situation nicht haben, können Sie einfach alle Ihre \glsetnoexpandfield
Befehle eingeben, bevor Sie mit der Definition Ihrer Einträge beginnen.
Groß-/Kleinschreibung ändern
Der erste Buchstabe Großbuchstaben Befehle wie \Gls
use \makefirstuc
zur 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, \makefirstuc
müssen einige Einschränkungen angewendet werden, um richtig zu funktionieren.
- Wenn das Argument mit beginnt
\protect
, wird dies verworfen und\makefirstuc
auf den Rest angewendet. Beispielsweise\makefirstuc{\protect\textbf{foo}}
ist dasselbe wie\makefirstuc{\textbf{foo}}
. - Das Argument von
\makefirstuc
kann 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. Wenn das Argument von
\makefirstuc
mit einer Steuersequenz ohne Argument beginnt, wird angenommen, dass es sich bei dieser Steuersequenz um eine Zeichensteuersequenz wie\ae
oder handelt\o
, und die Groß-/Kleinschreibung wird darauf angewendet. Beispielsweise\makefirstuc{\ae foo}
ergibt\MakeUppercase\ae foo
which Æfoo. Dies bedeutet, dass\newcommand{\foo}{foo}\makefirstuc{\foo}
tut, was
\MakeUppercase\foo
FOO erzeugt.Wenn das Argument von
\makefirstuc
mit 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, \makefirstuc
da 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 \ifnotused
das zweite Argument auswählt.