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 は「2 行目」を生成します。

私はパッケージのようなものを探していますglossariesが、一度にすべてのリストを生成するのではなく、特定のエントリを生成する機能があり、コマンドが\print{n}コマンド内のテキストに単純に置き換えられるように見えます\mycommand{n}{TEXT}

datatoolTeX.SX を検索したところ、パッケージとコードに関する回答がいくつか見つかりましたLuaが、適用できる解決策は見つかりませんでした。

datatoolglossariesまたはこれに類似するものの使用方法について簡単な説明をいただければ幸いです。

答え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}

関連情報