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 は「2 行目」を生成します。
私はパッケージのようなものを探していますglossaries
が、一度にすべてのリストを生成するのではなく、特定のエントリを生成する機能があり、コマンドが\print{n}
コマンド内のテキストに単純に置き換えられるように見えます\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 行目: 2 行目。
すべての行:
1. 最初の行目。2
. 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 行目。
すべての行:
2. 2 行目。1
. 1 行目。
リストは数字順ではなくなりましたが、ブロックが定義された順序と一致しています。リストを表示する前に並べ替えることができます。
\DTLsort{Index}{data}
\DTLforeach*{data}{\theIndex=Index,\Text=Text}{\theIndex. \Text.\par}
2 行目: 2 行目。
すべての行:
1. 最初の行目。2
. 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行目。
全行:
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行目: 2行目。
全行:
1 最初の行
2 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
追加したすべての項目を ToC の形式でリストするには、 を追加することをお勧めします。次の例では、各\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}