ドキュメント内の任意のポイントにファイル名の「リスト」を作成し、付録でそのリストを使用してこれらのファイルを読み込みたいと思います。レイアウトするアイテムを保持するための TeX のリストの一般的な概念があることは理解していますが、アイテムのリストに柔軟に追加し、後でこれらのアイテムを反復処理して「\input{item}」として解釈する簡単な方法を探しています。
グーグルで少し検索してみましたが、一致するものは何も見つかりませんでした。もしすでに回答が出ているのであれば、リンクをたどっていただければ幸いです。
編集: 回答を見て、リスト項目を一意に保つと便利かもしれないことに気付きました。つまり、同じファイル名を 2 回追加しても、ファイルが 2 回ロードされることはありません。これは可能でしょうか (妥当なレベルの単純さで)?
答え1
LaTeX カーネルには、以下に基づいた標準的なリスト管理があります\@for
。
\makeatletter
\newcommand{\addtofilelist}[1]{%
\ifx\files@to@input@later\@empty
\g@addto@macro\files@to@input@later{#1}%
\else
\g@addto@macro\files@to@input@later{,#1}%
\fi
}
\let\files@to@input@later\@empty % initialize
\newcommand{\inputthefiles}{%
\@for\next:=\files@to@input@later\do{\input{\next}}%
}
\makeatother
だからあなたは言う
\addtofilelist{foo.tex}
\addtofilelist{bar.tex}
必要なときに、最後に発行することができます
\inputthefiles
必要に応じて動作します。
ベースとなるテクニックexpl3
:
\usepackage{xparse}
\ExplSyntaxOn
\NewDocumentCommand{\addtofilelist}{m}
{
\seq_gput_right:Nn \g_regnirpsj_file_list_seq { #1 }
}
\NewDocumentCommand{\inputthefiles}{}
{
\seq_map_inline:Nn \g_regnirpsj_file_list_seq { \input{ ##1 } }
}
\seq_new:N \g_regnirpsj_file_list_seq
\ExplSyntaxOff
使い方は同じです。1つのコマンドでファイルのリストを追加したい場合は\addtofilelist
、最初の定義を次のように変更します。
\NewDocumentCommand{\addtofilelist}{m}
{
\clist_map_inline:nn { #1 }
{
\seq_gput_right:Nn \g_regnirpsj_file_list_seq { ##1 }
}
}
そして、いつでも言えるようになります
\addtofilelist{foo.tex, bar.tex}
任意の数のファイル名をコンマで区切って指定します。これはカーネル ベースのソリューションでも可能ですが、その場合はスペースが許可されないのに対し、カーネル ベースのソリューションではスペースはコンマの前後で無視されることに注意してくださいxparse
。
答え2
etoolbox
これは、たとえばリストユーティリティを使用して実行できます。
たとえば、\listgadd{\myfilelist}{}
リストの初期化子として使用します。
その後、任意の位置で、\listgadd{\myfilelist}{file1}
または をファイルの束に対して使用します\forcsvlist{\listgadd{\myfilelist}}{file2, file3,file4}
。
付録のすべてのファイルを入力するには、各ファイルの入力の前後に何らかの作業を行うラッパーコマンドがあると便利ですが、次のようにすれば十分でしょう。
\forlistloop{\input}{\myfilelist}
、
リストを反復処理します。
すべてのリスト反復子マクロへの最初の引数はetoolbox
要素ルーチンを期待し、最後の引数として現在のリスト要素を取得します。
\documentclass[12pt]{article}
\usepackage{etoolbox}%
\usepackage{blindtext}%
\listgadd{\myfilelist}{}%
\newcommand{\inputallfiles}[1]{%
\input{#1}%
}%
\begin{document}
\blindtext
\listgadd{\myfilelist}{file1}%
\blindtext[10]
\forcsvlist{\listgadd{\myfilelist}}{file2,file3,file1}%
\appendix%
\section{First}
\forlistloop{\inputallfiles}{\myfilelist}%
\end{document}
ファイル1.tex
\textit{Hello World}
ファイル2.tex
\textbf{Hello World}
ファイル3.tex
\textsc{Hello World}
OPがリスト要素のユニークな追加を要求したため - 代替バージョン
ifinlist
リスト要素の追加用のラッパー コマンドを使用すると、 etoolbox のコマンドを使用して、リストに「新しい」要素がすでに格納されているかどうかを確認できます。このテストの結果が の場合はfalse
追加できますが、それ以外の場合は無視されます。
command
\addtofilelist
単一の要素またはコンマで区切られた要素のリストにも機能する を追加しました。
マクロでは、安全性を高めるために\inputallfiles
テストを追加しました\InputIfFileExists...
。
\documentclass[12pt]{article}
\usepackage{etoolbox}%
\usepackage{blindtext}%
\listgadd{\myfilelist}{}%
\newcommand{\uniqueaddtolist}[2]{%
\ifdef{#1}{%
\ifinlist{#2}{#1}{%
% Do nothing
}{%
\listgadd{#1}{#2}%
}
}{% No list so far, so just add one!
\listgadd{#1}{#2}%
}%
}%
\newcommand{\uniqueaddtofilelist}[1]{%
\uniqueaddtolist{\myfilelist}{#1}%
}%
\newcommand{\addtofilelist}[1]{%
\forcsvlist{\uniqueaddtofilelist}{#1}%
}%
\newcommand{\inputallfiles}[1]{%
\InputIfFileExists{#1}{}{}%
}%
\begin{document}
\blindtext
\addtofilelist{file1}%
\blindtext[10]
\addtofilelist{file2,file3,file1}%
\appendix%
\section{First}
\forlistloop{\inputallfiles}{\myfilelist}%
\end{document}