我想建立一個由 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
package 的東西,但能夠一次生成所有列表,而是生成一個特定條目,因此看起來該命令\print{n}
只是被 command 中的文字替換\mycommand{n}{TEXT}
。
datatool
透過 TeX.SX 搜索,我找到了一些有關軟體包和程式碼的答案Lua
,但還沒有找到可以應用的解決方案。
我真的很感激關於如何使用的簡短解釋datatool
,glossaries
或類似的東西。
答案1
既然您提到了datatool
和glossaries
,這裡有一些替代方案。
對於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}
索引值在儲存之前必須完全擴展,這一點很重要,否則它會隨著計數器值的變化而不斷變化。兩者都datatool
可以glossaries
在新增/定義新條目時開啟或關閉擴充功能。
在這種情況下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}