файл1.tex

файл1.tex

Я хотел бы создать «список» имен файлов в произвольных точках документа и использовать этот список в приложении для загрузки этих файлов. Я понимаю, что в TeX есть обобщенная концепция списка для хранения элементов, подлежащих компоновке, но я ищу простой способ гибкого добавления элементов в список и последующего итерирования этих элементов для их интерпретации как «\input{item}».

Я немного погуглил, но ничего подходящего не нашлось. Так что, если на этот вопрос уже был дан ответ, я с радостью просто перейду по ссылке.

EDIT: просматривая ответы, я только что понял, что было бы полезно сохранять элементы списка уникальными, т. е. добавление одного и того же имени файла дважды не приведет к загрузке файла дважды. Возможно ли это (при разумном уровне простоты)?

решение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

Это можно сделать, например, с помощью etoolboxlist-utils.

Используйте, например, \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}

введите описание изображения здесь

Поскольку ОП запросил уникальное добавление элементов списка — альтернативная версия

Используя команду-обертку для добавления элементов списка, можно проверить, сохранен ли уже «новый» элемент в списке, используя команду 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}

Связанный контент