创建包含编号 TeX 代码块的数据库

创建包含编号 TeX 代码块的数据库

我想创建一个由 TeX 代码编号块组成的数据库。具体来说,我想做类似的事情\mycommand{counterName}{Some text},将新条目保存在某处,以便Some Text在文档的另一部分中使用。这CounterName是一个计数器,我可以参考它来获取插入文档的文本:

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

.........

print{2}

TeX 将生成“第二行”。

我正在寻找类似glossaries包的东西,但能够一次生成非所有列表,而是生成特定条目,因此看起来命令\print{n}只是由命令中的文本替换\mycommand{n}{TEXT}

通过搜索 TeX.SX,我找到了一些关于datatool包和Lua代码的答案,但还没有找到我可以应用的解决方案。

我将非常感激关于如何使用或类似内容的简单datatool说明glossaries

答案1

既然您提到了datatoolglossaries,这里有一些替代方案。

使用datatool,最简单的方法需要按递增顺序定义所有条目(不使用计数器)。行号提供索引。

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

得出的结果为:

文件图像

第 2 行:第二行。
所有行:
1. 第一行。2
. 第二行。

如果您想使用计数器来定义无序条目,则可以使用附加列来完成:

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

得出的结果为:

文件图像

第 2 行:第二行。
所有行:
2。第二行。1
。第一行。

该列表现在不按数字顺序排列,但与块定义的顺序相匹配。您可以在显示列表之前对它们进行排序:

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

文件图像

第 2 行:第二行。
所有行:
1. 第一行。2
. 第二行。

这里有一种glossaries方法:

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

得出的结果为:

文件图像

再次按定义顺序列出。如果您希望列表排序,可以使用以下命令:

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

得出的结果为:

文件图像

第 2 行:第二行。
所有行:
2 第二行

这仅列出已编入索引的条目(\glsadd使用 )。如果要列出所有条目,请使用\glsaddall(在所有条目都已定义之后)。

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

得出的结果为:

文件图像

第 2 行:第二行。
所有行:
1 第一行
2 第二行

扩张

索引值\the\value{#1}在存储之前必须完全展开,否则它会随着计数器值的变化而不断变化。datatoolglossaries都有在添加/定义新条目时打开或关闭展开的方法。

在 的情况下datatool,使用 开启扩展\dtlexpandnewvalue。在 的情况下glossaries,使用 开启特定字段的扩展\glssetexpandfield{字段标签}

您要添加的代码(在 的最后一个参数中\addline)可能包含脆弱的命令,在这种情况下,重要的是不要扩展值。使用datatool,扩展将再次使用 来关闭\dtlnoexpandnewvalue。使用glossaries,值将存储在description键中,并且默认情况下该字段的扩展处于关闭状态。

答案2

以下基于以下假设\printlistitem \addlistitem

在此处输入图片描述

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

可以添加更多修改,包括错误检查/处理和修改它以处理反向引用(使用\label-\ref设置)。


您可能有兴趣添加一个,\printallitems以目录的形式列出您添加的所有项目。以下示例通过将每个\addlistitem项目设置为来模拟此\section操作。您可以根据需要对演示文稿进行改进:

在此处输入图片描述

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

相关内容