文件1.tex

文件1.tex

我想在文档的任意位置创建一个文件名“列表”,并使用附录中的列表来加载这些文件。据我所知,TeX 中有一个用于保存要布局的项目的列表的广义概念,但我正在寻找一种简单的方法,可以灵活地添加到项目列表中,然后在这些项目上进行迭代以将它们解释为“\input{item}”。

我用 Google 搜索了一下,但没有找到任何匹配的内容。所以,如果这个问题已经得到解答,我很乐意直接点击链接。

编辑:看了答案后我才意识到保持列表项的唯一性可能会很有用,即两次添加相同的文件名不会加载文件两次。这可能吗(在合理的简单程度下)?

答案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一个元素例程,它将当前列表元素作为最后一个参数。

\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 要求添加独特的列表元素——替代版本

使用包装器命令添加列表元素,可以使用ifinlistetoolbox 中的命令检查列表中是否已存储“新”元素。如果此测试结果为真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}

相关内容