我想在文件中的任意點創建文件名“列表”,並使用附錄中的該列表來載入這些文件。我知道TeX中有一個通用的列表概念,用於保存要佈局的項目,但我正在尋找一種簡單的方法來靈活地添加到項目列表中,並在稍後迭代這些項目以將它們解釋為' \輸入{項目}'。
我用谷歌搜尋了一下,但沒有找到任何匹配的結果。因此,如果這個問題已經得到解答,我很樂意點擊連結。
編輯:查看答案我剛剛意識到保持列表項目唯一可能很有用,即添加相同的文件名兩次不會加載文件兩次。這可能嗎(在合理的簡單程度下)?
答案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
用法是一樣的。如果您希望能夠使用單一\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
Expect 元素例程,該例程取得目前清單元素作為最後一個參數。
\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}