3

I am working on a collection of books that uses content from other files. I want to have each reference in a file to avoid redundant content and to make it easier to review and correct the content.

Let me explain, I have created a file for each reference number, for example:

CEC/n/0001.tex
CEC/n/0002.tex
CEC/n/0003.tex
CEC/n/0004.tex
CEC/n/0005.tex
CEC/n/0006.tex
CEC/n/0007.tex
....
CEC/n/9999.tex

Suppose in a part of one of my books I need to include the numbers 1 to 5, the number 22 and the number 17. I am currently doing the following, which works:

\input{../../CEC/n/0001}

\input{../../CEC/n/0002}

\input{../../CEC/n/0003}

\input{../../CEC/n/0004}

\input{../../CEC/n/0005}

\input{../../CEC/n/0022}

\input{../../CEC/n/0017}

Is there a way to simplify it?

My idea is to be able to receive an array of numbers [1,2,3,4,5,22,17] or [1 to 5 AND 22 AND 17] and use it to include each of those files by their names? I need to include many reference combinations like above in different parts of my volumes and I want to simplify this task.

I'm sorry I can't create a minimal, verifiable example due to file inclusion.

A. Cedano
  • 453
  • It many of these cases it is better to use an external program to generate the source code for you. For example via python or similar. It is a lot easier to provide command line interface for those than it is for latex and friends. – daleif Sep 27 '21 at 14:20

1 Answers1

5

The following set of macros does the job, provided the file names have a common structure. The main command is

\multiinput{<prefix>}{<format>}{<list>}[<post action>]

In your case it would be

\multiinput{../../CEC/n/}{0000}{1-5,22,17}

Code, where in the second case I added \par as the post action to be performed when the file has been input.

\documentclass{article}

\ExplSyntaxOn

\NewDocumentCommand{\multiinput}{mmm+O{}} {% #1 = fixed part % #2 = format for the variable part % #3 = list % #4 = post action \cedano_multiinput:nnnn { #1 } { #2 } { #3 } { #4 } }

\seq_new:N \l__cedano_multiinput_items_seq \seq_new:N \l__cedano_multiinput_interval_seq

\cs_new_protected:Nn \cedano_multiinput:nnnn { % split the list at commas \seq_set_split:Nnn \l__cedano_multiinput_items_seq {,} { #3 } \seq_map_inline:Nn \l__cedano_multiinput_items_seq { __cedano_multiinput_item:nnnn { #1 } { #2 } { ##1 } { #4 } } }

\cs_new_protected:Nn __cedano_multiinput_item:nnnn { \seq_set_split:Nnn \l__cedano_multiinput_interval_seq { - } { #3 } \int_compare:nTF { \seq_count:N \l__cedano_multiinput_interval_seq = 1 } {% just one item __cedano_multiinput_file:nnnn { #1 } { #2 } { #3 } { #4 } } {% multiple files \int_step_inline:nnn { \seq_item:Nn \l__cedano_multiinput_interval_seq { 1 } } % start { \seq_item:Nn \l__cedano_multiinput_interval_seq { 2 } } % end { __cedano_multiinput_file:nnnn { #1 } { #2 } { ##1 } { #4 } } } }

\cs_new_protected:Nn __cedano_multiinput_file:nnnn { \file_input:n { #1 __cedano_multiinput_pad:nn { #2 } { #3 } } #4 }

\cs_new:Nn __cedano_multiinput_pad:nn { \prg_replicate:nn { \tl_count:n { #1 } - \tl_count:n { #2 } } { 0 } #2 }

\ExplSyntaxOff

\begin{document}

\textbf{From 1 to 10}

\multiinput{inputs/}{0000}{1-10}

\bigskip

\textbf{Selection}

\multiinput{inputs/}{0000}{1-2,4,7,9-10}[\par]

\end{document}

I created in the subdirectory inputs the files 0001.tex to 0010.tex that contain

I'm number XXXX

enter image description here

egreg
  • 1,121,712
  • Thanks for your reply. It would be just what I need, but I can't make it work. I have reproduced same code, creating the files in an input folder but it doesn't recognize the commands... ! Undefined control sequence. l.3 \ExplSyntaxOn and ! Undefined control sequence. l.5 \NewDocumentCommand {\multiinput}{mmm+O{}} with the message: The control sequence at the end of the top line of your error message was never \def'ed. If you have misspelled it (e.g., '\hobx'), type `I' and the correct spelling (e.g., 'I\hbox'). Otherwise just continue, and I'll forget about whatever was undefined – A. Cedano Sep 28 '21 at 08:04
  • @A.Cedano In this case you need to add \usepackage{xparse} – egreg Sep 28 '21 at 08:35
  • I added that and I'm having the same error. If I try only this \multiinput{inputs/}{0000}{1-10}and I open the PDF generated, i have one line: 110 and if I try only this: \multiinput{inputs/}{0000}{1-2,4,7,9-10}[\par] the PDF have these lines: 12 and I’m number 0004 and I’m number 0007 and 910 in both cases the error Undefined control sequence persists – A. Cedano Sep 28 '21 at 08:50
  • @A.Cedano What TeX system are you using and which release? – egreg Sep 28 '21 at 10:09
  • I'm using: TeX 3.14159265 (TeX Live 2017/Debian) into Ubuntu 18. The IDE I'm using is TeXstudio 3.1.2 – A. Cedano Sep 28 '21 at 10:13
  • @A.Cedano Sorry, but that TeX Live is really outdated. – egreg Sep 28 '21 at 10:20
  • I have everything updated using this command: sudo apt update && sudo apt upgrade -y Is there any other way to update to the latest version of TexLive? – A. Cedano Sep 28 '21 at 10:24
  • @A.Cedano https://tex.stackexchange.com/q/1092/4427 – egreg Sep 28 '21 at 10:47