Erstellen einer Datenbank mit nummerierten TeX-Codeblöcken

Erstellen einer Datenbank mit nummerierten TeX-Codeblöcken

Ich möchte eine Datenbank erstellen, die aus nummerierten TeX-Codeblöcken besteht. Insbesondere möchte ich so etwas tun \mycommand{counterName}{Some text}und irgendwo einen neuen Eintrag speichern, um ihn Some Textspäter an anderer Stelle im Dokument zu verwenden. Es CounterNamegibt einen Zähler, auf den ich zurückgreifen kann, um den in das Dokument eingefügten Text abzurufen:

\newcounter{a}
\mycommand{a}{The first line}
\stepcounter{a}
\mycommand{a}{The second line}

.........

print{2}

Und TeX wird „Die zweite Zeile“ produzieren.

Ich suche nach etwas wie glossarieseinem Paket, aber mit der Möglichkeit, nicht die ganze Liste auf einmal zu erstellen, sondern nur einen bestimmten Eintrag, sodass es aussieht, als \print{n}würde der Befehl einfach durch den Text im Befehl ersetzt \mycommand{n}{TEXT}.

Beim Durchsuchen von TeX.SX habe ich einige Antworten zu datatoolPaketen und LuaCodes gefunden, aber keine Lösung, die ich anwenden kann.

datatoolIch wäre Ihnen für eine kurze Erklärung zur Verwendung glossariesoder etwas Ähnlichem zu diesem Thema sehr dankbar.

Antwort1

Da Sie datatoolund erwähnt haben glossaries, hier einige Alternativen.

Bei datatoolbesteht die einfachste Methode darin, alle Einträge in inkrementeller Reihenfolge (ohne Verwendung eines Zählers) zu definieren. Die Indizierung erfolgt über die Zeilennummer.

\documentclass{article}

\usepackage{datatool}

\DTLnewdb{data}

\newcommand{\addline}[1]{%
  \DTLnewrow{data}%
  \DTLnewdbentry{data}{Text}{#1}%
}

\newcommand{\print}[1]{%
  \DTLgetvalue{\thisval}{data}{#1}{1}%
  \thisval
}

\addline{The first line}
\addline{The second line}

\begin{document}

Line 2: \print{2}.

All lines:

\DTLforeach*{data}{\Text=Text}{\DTLcurrentindex. \Text.\par}

\end{document}

Das Ergebnis:

Bild des Dokuments

Zeile 2: Die zweite Zeile.
Alle Zeilen:
1. Die erste Zeile.
2. Die zweite Zeile.

Wenn Sie Ihre Einträge ungeordnet über einen Zähler definieren möchten, ist dies mit einer zusätzlichen Spalte möglich:

\documentclass{article}

\usepackage{datatool}

\DTLnewdb{data}

\newcommand{\addline}[2]{%
  \DTLnewrow{data}%
  \dtlexpandnewvalue
  \DTLnewdbentry{data}{Index}{\the\value{#1}}%
  \dtlnoexpandnewvalue
  \DTLnewdbentry{data}{Text}{#2}%
}

\newcommand{\print}[1]{%
  \dtlgetrowindex{\thisrowidx}{data}{1}{#1}%
  \ifx\thisrowidx\dtlnovalue
    Not found!%
  \else
     \DTLgetvalue{\thisval}{data}{\thisrowidx}{2}%
     \thisval
  \fi
}

\newcounter{a}
\setcounter{a}{2}
\addline{a}{The second line}

\setcounter{a}{1}
\addline{a}{The first line}

\begin{document}

Line 2: \print{2}.

All lines:

\DTLforeach*{data}{\theIndex=Index,\Text=Text}{\theIndex. \Text.\par}

\end{document}

Das Ergebnis:

Bild des Dokuments

Zeile 2: Die zweite Zeile.
Alle Zeilen:
2. Die zweite Zeile.
1. Die erste Zeile.

Die Liste ist nun nicht mehr numerisch geordnet, sondern entspricht der Reihenfolge, in der die Blöcke definiert wurden. Sie können sie sortieren, bevor Sie die Liste anzeigen:

\DTLsort{Index}{data}
\DTLforeach*{data}{\theIndex=Index,\Text=Text}{\theIndex. \Text.\par}

Bild des Dokuments

Zeile 2: Die zweite Zeile.
Alle Zeilen:
1. Die erste Zeile.
2. Die zweite Zeile.

Hier ist ein glossariesAnsatz:

\documentclass{article}

\usepackage{glossaries-extra}

\glssetexpandfield{name}

\newcommand{\addline}[2]{%
  \edef\thisidx{\the\value{#1}}%
  \newglossaryentry{\thisidx}{name={\thisidx},description={#2}}%
}

\newcommand{\print}[1]{%
  \glsentrydesc{#1}%
}

\newcounter{a}
\setcounter{a}{2}
\addline{a}{The second line}

\setcounter{a}{1}
\addline{a}{The first line}

\begin{document}

Line 2: \print{2}.

All lines:

\renewcommand{\glstreenamefmt}[1]{#1}
\renewcommand{\glossarysection}[2][]{}
\printunsrtglossary[style=index]

\end{document}

Das Ergebnis:

Bild des Dokuments

Auch hier erfolgt die Liste in der Reihenfolge der Definition. Wenn Sie die Liste sortiert haben möchten, können Sie stattdessen Folgendes verwenden:

\documentclass{article}

\usepackage[automake,nopostdot]{glossaries}

\makeglossaries

\glssetexpandfield{name}

\newcommand{\addline}[2]{%
  \edef\thisidx{\the\value{#1}}%
  \newglossaryentry{\thisidx}{name={\thisidx},description={#2}}%
}

\newcommand{\print}[1]{%
  \glsentrydesc{#1}\glsadd{#1}%
}

\newcounter{a}
\setcounter{a}{2}
\addline{a}{The second line}

\setcounter{a}{1}
\addline{a}{The first line}

\begin{document}

Line 2: \print{2}.

All lines:

\renewcommand{\glstreenamefmt}[1]{#1}
\renewcommand{\glossarysection}[2][]{}
\printglossary[style=index,nonumberlist]

\end{document}

Das Ergebnis:

Bild des Dokuments

Zeile 2: Die zweite Zeile.
Alle Zeilen:
2 Die zweite Zeile

Dies listet nur den Eintrag auf, der (mit ) indiziert wurde \glsadd. Wenn Sie möchten, dass alle Einträge aufgelistet werden, verwenden Sie \glsaddall(nachdem alle Einträge definiert wurden).

\documentclass{article}

\usepackage[automake,nopostdot]{glossaries}

\makeglossaries

\glssetexpandfield{name}

\newcommand{\addline}[2]{%
  \edef\thisidx{\the\value{#1}}%
  \newglossaryentry{\thisidx}{name={\thisidx},description={#2}}%
}

\newcommand{\print}[1]{%
  \glsentrydesc{#1}%
}

\newcounter{a}
\setcounter{a}{2}
\addline{a}{The second line}

\setcounter{a}{1}
\addline{a}{The first line}

\glsaddall

\begin{document}

Line 2: \print{2}.

All lines:

\renewcommand{\glstreenamefmt}[1]{#1}
\renewcommand{\glossarysection}[2][]{}
\printglossary[style=index,nonumberlist]

\end{document}

Das Ergebnis:

Bild des Dokuments

Zeile 2: Die zweite Zeile.
Alle Zeilen:
1 Die erste Zeile
2 Die zweite Zeile

Erweiterung

Es ist wichtig, dass der Indexierungswert \the\value{#1}vor dem Speichern vollständig erweitert wird, da er sich sonst ständig ändert, wenn sich der Wert des Zählers ändert. Sowohl als datatoolauch glossariesgibt es eine Möglichkeit, die Erweiterung beim Hinzufügen/Definieren eines neuen Eintrags ein- oder auszuschalten.

Bei datatoolwird die Erweiterung mit eingeschaltet \dtlexpandnewvalue. Bei glossarieswird die Erweiterung für ein bestimmtes Feld mit eingeschaltet.\glssetexpandfield{Feldbezeichnung}.

Der Code, den Sie (im letzten Argument von \addline) hinzufügen möchten, enthält möglicherweise instabile Befehle. In diesem Fall ist es wichtig, den Wert nicht zu erweitern. Mit datatoolwird die Erweiterung mit wieder ausgeschaltet \dtlnoexpandnewvalue. Mit glossarieswird der Wert im descriptionSchlüssel gespeichert und die Erweiterung ist für dieses Feld standardmäßig deaktiviert.

Antwort2

Das Folgende basiert auf der Annahme, \printlistitemdassnach \addlistitem:

Bildbeschreibung hier eingeben

\documentclass{article}

\usepackage{xparse}

\newcounter{listitem}
\NewDocumentCommand{\addlistitem}{o m}{%
  \IfValueTF{#1}
    {\expandafter\def\csname #1-list\endcsname{#2}}
    {\stepcounter{listitem}%
     \begingroup\edef\x{\endgroup\noexpand\expandafter
       \def\noexpand\csname \thelistitem-list\noexpand\endcsname}%
       \x{#2}}%
}

\newcommand{\printlistitem}[1]{%
  \ifcsname #1-list\endcsname
    \csname #1-list\endcsname
  \else
    Item~#1 does not exist.
  \fi
}

\begin{document}

\addlistitem{The first line}% 1
\addlistitem[B]{The second line}% C
\addlistitem{The third line}% 2

\printlistitem{2}

\printlistitem{1}

\printlistitem{3}

\printlistitem{B}

\end{document}

Es können weitere Modifikationen hinzugefügt werden, darunter Fehlerprüfung/-behandlung und Modifikationen für die Handhabung von Rückwärtsreferenzierungen (mithilfe eines \label-Setups \ref).


Möglicherweise möchten Sie ein hinzufügen, \printallitemsum alle Elemente aufzulisten, die Sie in Form eines Inhaltsverzeichnisses hinzugefügt haben. Das folgende Beispiel ahmt dies nach, indem jedes \addlistitemals festgelegt wird \section. Sie können die Präsentation nach Bedarf verfeinern:

Bildbeschreibung hier eingeben

\documentclass{article}

\usepackage{xparse,tocloft}

\newcounter{listitem}
\NewDocumentCommand{\addlistitem}{o m}{%
  \IfValueTF{#1}
    {\expandafter\def\csname #1-list\endcsname{#2}%
     \addcontentsline{los}{listitem}{\protect\numberline{#1} #2}}
    {\stepcounter{listitem}%
     \begingroup\edef\x{\endgroup\noexpand\expandafter
       \def\noexpand\csname \thelistitem-list\noexpand\endcsname}%
       \x{#2}%
     \addcontentsline{los}{listitem}{\protect\numberline{\thelistitem} #2}}%
}

\newcommand{\printlistitem}[1]{%
  \ifcsname #1-list\endcsname
    \csname #1-list\endcsname
  \else
    Item~#1 does not exist.
  \fi
}

\makeatletter
\let\l@listitem\l@section
\newcommand{\printallitems}{{%
  \renewcommand{\cftsecfont}{\mdseries}% Add more ToC-related tuning here
  \@starttoc{los}}}
\makeatother

\begin{document}

\printallitems

\bigskip

\addlistitem{The first line}% 1
\addlistitem[B]{The second line}% C
\addlistitem{The third line}% 2

\printlistitem{2}

\printlistitem{1}

\printlistitem{3}

\printlistitem{B}

\end{document}

verwandte Informationen