ファイル1.tex

ファイル1.tex

ドキュメント内の任意のポイントにファイル名の「リスト」を作成し、付録でそのリストを使用してこれらのファイルを読み込みたいと思います。レイアウトするアイテムを保持するための 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}

関連情報