Ein (zumindest im Original) recht umfangreiches Symbolverzeichnis soll in eine CSV-Datei ausgelagert werden, die per datatool eingelesen wird. Jedoch führt \printglossary damit nur den letzten Eintrag auf.

% arara: pdflatex
% arara: makeglossaries
% arara: pdflatex
\documentclass{article}
\usepackage{datatool}
\usepackage[nomain,symbols,xindy]{glossaries-extra}

\begin{filecontents*}{matsym.csv}
Marke,Symbol,Beschreibung
E,E,E-Modul
t0,t_0,Anfangszeitpunkt
tmax,t_\text{max},Endzeitpunkt
w,\omega,Winkelgeschwindigkeit
\end{filecontents*}

\DTLloaddb{matsym}{matsym.csv}
\DTLforeach*{matsym}{\marke=Marke,\sym=Symbol,\beschr=Beschreibung}{
    \glsxtrnewsymbol[description={\beschr}]{\marke}{\ensuremath{\sym}}
}
\makeglossaries

\begin{document}
\section{Die Tabelle, wie \textit{datatool} sie verstanden hat:}
\DTLdisplaydb[Symbol]{matsym} % sprich: OHNE Symbol

\section{Alle definierten Symbole werden hier genannt}
\DTLforeach*{matsym}{\marke=Marke}{\gls{\marke} }

\printglossary[type=symbols,title={Das Glossar zeigt nur den letzten Eintrag}]
\end{document}

Schnappschuss der Ausgabe

Ich habe als Anhaltspunkt die glo-Datei:

(indexentry :tkey (("\\marke " "\\glossentry{E}") ) :locref "{}{1}" :attr "pageglsnumberformat" ) 
(indexentry :tkey (("\\marke " "\\glossentry{t0}") ) :locref "{}{1}" :attr "pageglsnumberformat" ) 
(indexentry :tkey (("\\marke " "\\glossentry{tmax}") ) :locref "{}{1}" :attr "pageglsnumberformat" )
(indexentry :tkey (("\\marke " "\\glossentry{w}") ) :locref "{}{1}" :attr "pageglsnumberformat" )

Sieht so aus, als ob \makeglossaries alle Einträge unter der selben Marke anlegt hat, vermutlich weil die Definition in einer \DTLforeach-Schleife geschieht. Wie bekomme ich pdflatex dazu, jedesmal den tatsächlichen Wert anstatt diesem Platzhalter zu nehmen?

PS: Die Kombi datatool mit glossaries wird bewusst benutzt, auch wenn datatool eine eigene Glossarunterstützung (datagidx) mitbringt.

gefragt 05 Nov, 03:27

Giovani%20Ragazze's gravatar image

Giovani Ragazze
261
Akzeptiert-Rate: 0%

bearbeitet 05 Nov, 21:34


Das ist wieder einmal ein Expansionsproblem. \glsxtrnewsymbol expandiert beim Schreiben in die *.sls-Datei absichtlich nicht. Hier willst du aber, dass \marke genau einmal expandiert wird. Es gibt verschiedene Möglichkeiten, die Expansion zu erzwingen. Eine einfache wäre mit einem expandierten runner zu arbeiten:

\DTLforeach*{matsym}{\marke=Marke,\sym=Symbol,\beschr=Beschreibung}{%
  \edef\myrunner{%
    \noexpand\glsxtrnewsymbol
    [description={\unexpanded\expandafter{\beschr}}]%
    {\unexpanded\expandafter{\marke}}%
    {\noexpand\ensuremath{\unexpanded\expandafter{\sym}}}%
  }%
  \myrunner
}

Hier wird \glsxtrnewsymbol nicht direkt aufgerufen, sondern ein Befehl \myrunner definiert, der diesen Aufruf enthält. Durch Verwendung von \edef wird die Definition vollständig expandiert. Mit \noexpand wird verhindert, dass \glsxtrnewsymbol dabei selbst expandiert wird. Mit \unexpanded\expandafter{\foo} wird dafür gesorgt, dass \foo nicht komplett, sondern nur eine Stufe weit expandiert wird. Es wird also die Definition von \foo verwendet, darin enthaltene Makros werden aber nicht expandiert.

Insgesamt sieht das dann beispielsweise so aus:

\documentclass{article}
\usepackage{datatool}
\usepackage[nomain,symbols,xindy]{glossaries-extra}

\begin{filecontents*}{matsym.csv}
Marke,Symbol,Beschreibung
E,E,E-Modul
t0,t_0,Anfangszeitpunkt
tmax,t_\text{max},Endzeitpunkt
w,\omega,Winkelgeschwindigkeit
\end{filecontents*}

\DTLloaddb{matsym}{matsym.csv}
\newcommand*{\myrunner}{}% Makro quasi reservieren
\DTLforeach*{matsym}{\marke=Marke,\sym=Symbol,\beschr=Beschreibung}{%
  \edef\myrunner{%
    \noexpand\glsxtrnewsymbol
    [description={\unexpanded\expandafter{\beschr}}]%
    {\unexpanded\expandafter{\marke}}%
    {\noexpand\ensuremath{\unexpanded\expandafter{\sym}}}%
  }%
  \myrunner
}
\makeglossaries

\begin{document}
\section{Die Tabelle, wie \textit{datatool} sie verstanden hat:}
\DTLdisplaydb[Symbol]{matsym} % sprich: OHNE Symbol

\section{Alle definierten Symbole werden hier genannt}
\DTLforeach*{matsym}{\marke=Marke}{\gls{\marke} }% Hier wäre das explizite Expandieren auch kein Fehler. Es geht aber wohl auch so.

\printglossary[type=symbols,title={Das Glossar zeigt nur den letzten Eintrag}]
\end{document}

Ergebnis mit vollständigem Glossar


Eine eventuell etwas komplizierter aussehende Möglichkeit bestünde in der Verwendung von expl3. Damit gibt es nämlich die Möglichkeit, Befehle zu definieren, deren Argument automatisch einfach expandiert wird. Man könnte also für die \DTLforeach*-Schleife einen Befehl definieren, der an \glsxtrnewsymbol nicht mehr \beschr, \marke und \sym, sondern bereits deren Expansionen übergibt. Dazu definiert man beispielsweise zunächst einen Befehl, der den in der Schleife verwendeten Befehl ganz normal enthält, beispielsweise

\cs_new:Npn \dt__glsxtrnewmathsymbol:nnn #1 #2 #3
  {
    \glsxtrnewsymbol [ description = { #1 } ] { #2 } { \ensuremath{ #3 } }
  }

Würde man den nun in der Schleife als \dt__glsxtrnewmathsymbol{\beschr}{\marke}{\sym} aufrufen, so hätte man wieder den Aufruf \glsxtrnewmathsymbol[description={\beschr}]{\marke}{\ensuremath{\sym}} also genau dasselbe Problem wie bisher. Man kann in l3 aber per

\cs_generate_variant:Nn \dt__glsxtrnewmathsymbol:nnn { ooo }

einfach eine Variante \dt__glsxtrnewmathsymbol:ooo aus \dt__glsxtrnewmathsymbol:nnn erzeugen. Der Unterschied der ooo-Variante ist, dass die Argumente einfach expandiert werden, bevor sie zur Anwendung kommen. Es wird dann also nicht mehr \beschr, \marke und \sym, sondern die Definition dieser Makros in der Schleife verwendet.

Damit in der Schleife nicht die expl3-Syntax benötigt wird, definiert man sich noch eine Benutzeranweisung, die ohne _ und : auskommt. Man erhält dann mit:

\documentclass{article}
\usepackage{datatool}
\usepackage[nomain,symbols,xindy]{glossaries-extra}
\usepackage{xparse}% Für LaTeX >= 2020-10-01 nicht mehr zwingend aber zu empfehlen. Lädt auch expl3.

\begin{filecontents*}{matsym.csv}
Marke,Symbol,Beschreibung
E,E,E-Modul
t0,t_0,Anfangszeitpunkt
tmax,t_\text{max},Endzeitpunkt
w,\omega,Winkelgeschwindigkeit
\end{filecontents*}

\ExplSyntaxOn
\cs_new:Npn \dt__glsxtrnewmathsymbol:nnn #1 #2 #3
  {
    \glsxtrnewsymbol [ description = { #1 } ] { #2 } { \ensuremath{ #3 } }
  }
\cs_generate_variant:Nn \dt__glsxtrnewmathsymbol:nnn { ooo }

\NewDocumentCommand \dtglsxtrnewmathsymbol { m m m }
  {
    \dt__glsxtrnewmathsymbol:ooo { #1 } { #2 } { #3 }
  }
\ExplSyntaxOff

\DTLloaddb{matsym}{matsym.csv}
\DTLforeach*{matsym}{\marke=Marke,\sym=Symbol,\beschr=Beschreibung}{%
  \dtglsxtrnewmathsymbol{\beschr}{\marke}{\sym}%
}
\makeglossaries

\begin{document}
\section{Die Tabelle, wie \textit{datatool} sie verstanden hat:}
\DTLdisplaydb[Symbol]{matsym} % sprich: OHNE Symbol

\section{Alle definierten Symbole werden hier genannt}
\DTLforeach*{matsym}{\marke=Marke}{\gls{\marke} }% Hier wäre das explizite Expandieren auch kein Fehler. Es geht aber wohl auch so.

\printglossary[type=symbols,title={Das Glossar zeigt nur den letzten Eintrag}]
\end{document}

das oben bereits gezeigte Ergebnis.

Permanenter link

beantwortet 05 Nov, 08:21

Ijon%20Tichy's gravatar image

Ijon Tichy
9.7k31228
Akzeptiert-Rate: 52%

bearbeitet 06 Nov, 09:21

Also expandiert {\unexpanded\expandafter{\marke}} zu \expandafter{\marke}. Das sieht zwar aus, wie ein Makro mit einem Argument, aber es sind tatsächlich zwei: Zuerst die geschweiften Klammern und dann \marke. Also wird erst \marke expandiert und die geschweiften Klammern belassen. Beim ersten Eintrag bleibt dann {E-Modul}. Wenn ich \show\myrunner nach dem \edef einfüge, bekomme ich auch \myrunner=macro: ->\glsxtrnewsymbol [description={E-Modul}]{E}{\ensuremath {E}}.

Vielen Dank!

(05 Nov, 21:31) Giovani Ragazze

@Giovani Ragazze

Also expandiert {\unexpanded\expandafter{\marke}} zu \expandafter{\marke}.

Du meinst zwar das richtige, was da steht, ist aber nicht richtig. Bevor das Klammertoken expandiert, wird \marke einfach expandiert. Damit diese einfache Expansion von \edef nicht weiter expandiert werden kann, wird darauf dann \unexpanded angewendet.

Solange sich in \marke keine Token befinden, die bei der vollständigen Expansion zu Problemen führen, könnte man das auch einfach zu {\marke} verkürzen, also eine vollständige Expansion von \marke durch \edef durchführen.

(06 Nov, 08:10) Ijon Tichy
Deine Antwort
Vorschau umschalten

Folgen dieser Frage

Per E-Mail:

Wenn sie sich anmelden, kommen Sie für alle Updates hier in Frage

Per RSS:

Antworten

Antworten und Kommentare

Markdown-Grundlagen

  • *kursiv* oder _kursiv_
  • **Fett** oder __Fett__
  • Link:[Text](http://url.com/ "Titel")
  • Bild?![alt Text](/path/img.jpg "Titel")
  • nummerierte Liste: 1. Foo 2. Bar
  • zum Hinzufügen ein Zeilenumbruchs fügen Sie einfach zwei Leerzeichen an die Stelle an der die neue Linie sein soll.
  • grundlegende HTML-Tags werden ebenfalls unterstützt

Frage-Themen:

×36
×17
×7
×5

gestellte Frage: 05 Nov, 03:27

Frage wurde gesehen: 246 Mal

zuletzt geändert: 06 Nov, 08:52