Crear una base de datos que contenga bloques numerados de código TeX

Crear una base de datos que contenga bloques numerados de código TeX

Quiero crear una base de datos que consta de bloques numerados de código TeX. En particular, quiero hacer algo como \mycommand{counterName}{Some text}y guardar una nueva entrada en algún lugar, para usarla Some Textmás adelante en otra parte del documento. Hay CounterNameun contador al que puedo referirme para insertar el texto en el documento:

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

.........

print{2}

Y TeX producirá "La segunda línea".

Estoy buscando algo parecido a glossariesun paquete, pero con la capacidad de producir no todas las listas a la vez, sino una entrada específica para que parezca que el comando \print{n}simplemente se sustituye por el texto en comando \mycommand{n}{TEXT}.

Buscando en TeX.SX encontré algunas respuestas sobre datatoolpaquetes y Luacódigos, pero no encontré una solución que pueda aplicar.

Realmente agradecería una breve explicación sobre cómo usar datatool, glossarieso algo similar para estas cosas.

Respuesta1

Como mencionaste datatooly glossaries, aquí hay algunas alternativas.

Con datatool, el método más simple requiere definir todas las entradas en orden incremental (sin usar un contador). El número de fila proporciona la indexación.

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

Esto produce:

imagen del documento

Línea 2: La segunda línea.
Todas las líneas:
1. La primera línea.
2. La segunda línea.

Si desea definir sus entradas desordenadas usando un contador, puede hacerlo con una columna adicional:

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

Esto produce:

imagen del documento

Línea 2: La segunda línea.
Todas las líneas:
2. La segunda línea.
1. La primera línea.

La lista ahora está fuera de orden numérico, pero coincide con el orden en que se definieron los bloques. Puede ordenarlos antes de mostrar la lista:

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

imagen del documento

Línea 2: La segunda línea.
Todas las líneas:
1. La primera línea.
2. La segunda línea.

He aquí un glossariesenfoque:

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

Esto produce:

imagen del documento

Nuevamente esto enumera en orden de definición. Si desea ordenar la lista, puede utilizar lo siguiente:

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

Esto produce:

imagen del documento

Línea 2: La segunda línea.
Todas las líneas:
2 La segunda línea

Esto solo enumera la entrada que ha sido indexada (con \glsadd). Si desea que se enumeren todas las entradas, utilice \glsaddall(después de que se hayan definido todas las entradas).

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

Esto produce:

imagen del documento

Línea 2: La segunda línea.
Todas las líneas:
1 La primera línea
2 La segunda línea

Expansión

Es importante que el valor de indexación \the\value{#1}se expanda completamente antes de almacenarlo; de lo contrario, seguirá cambiando a medida que el contador cambie de valor. Ambos datatooly glossariestienen una forma de activar o desactivar la expansión al agregar/definir una nueva entrada.

En el caso de datatool, la expansión se activa mediante \dtlexpandnewvalue. En el caso de glossaries, la expansión se activa para un campo particular usando\glssetexpandfield{Etiqueta de campo}.

El código que desea agregar (en el argumento final de \addline) puede contener comandos frágiles, en cuyo caso es importante no expandir el valor. Con datatool, la ampliación se vuelve a desactivar con \dtlnoexpandnewvalue. Con glossaries, el valor se almacena en la descriptionclave y la expansión está desactivada de forma predeterminada para ese campo.

Respuesta2

Lo siguiente se basa en el supuesto de que\printlistitem ocurredespués \addlistitem:

ingrese la descripción de la imagen aquí

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

Se pueden agregar más modificaciones, incluida la verificación/manejo de errores y su modificación para manejar referencias inversas (usando una configuración \label- ).\ref


Quizás le interese agregar un \printallitemspara enumerar todos los elementos que ha agregado en forma de ToC. El siguiente ejemplo lo imita estableciendo cada uno \addlistitemcomo un archivo \section. Puede realizar mejoras en la presentación según sea necesario:

ingrese la descripción de la imagen aquí

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

información relacionada