2

I am part of a large project working with big documents (>100 chapters and ~1000 pages per document). As it stands, we input our partial files into the main document via \input.

The project would greatly benefit from switching to \include, because \includeonly in conjunction with the partial .aux files allows to speed up compilation AND preserve the cross-references.

However, a pesky comma stands in the way. As of now, all our file paths contain a comma in one of the folder names (as in: volume8,4/section1.tex). \include is fine with that, but \includeonly of course has a huge parsing problem, as the comma is needed to separate the names of the files that are to be included.

I am aware that commas in file names are a bad idea, full stop. Changing the folder names once and for all would be clearly much better.

However, given that it's a long-running, multi-volume project with several collaborators, the change is not too likely to happen. Add to this that the occurrences of commas in our file structure, while predictable, are very pervasive – they show up in the main document as well as the individual chapters, which \input graphics or other files in the tree.

In the spirit of trying to work around the comma issue, here are my questions:

1. Is there a way to teach \includeonly to parse the path correctly? That is,

\includeonly{volume8,4/section1}

should include volume8,4/section1.tex rather than the (nonexistent) files volume8.tex and 4/section1.tex.

I have researched and tried different approaches to escape or quote the comma (",", \string, additional braces), and also tried changing the catcode of comma as suggested here; all to no avail. Some of these approaches work great with spaces in the path, but commas seem hopeless.

EDIT: double braces, as in \includeonly{{volume8,4/section1}}, don't do the trick either.

1.a. How would a solution be able to handle multi-file inclusion? For instance:

\includeonly{volume8,4/section1, volume8,4/section2}

should include section1.tex and section2.tex.

2. Would it help to specify a path for \include(only)? The path should take care of the (suitably processed/escaped/quoted) comma, which wouldn't need to show up explicitly in the argument. I would then write:

\includeonly{section1,section2}

Is there some internal macro that specifies the path for all inclusions, the way that \input@path does for \input – and would it be any help here?


Here's a MWE:

\documentclass{article}

%\usepackage{shellesc} % Some code to generate the appropriate folders and files %\ShellEscape{mkdir volume8,4} % %\begin{filecontents}[overwrite]{volume8,4/section1.tex} %\section{First section} %Hello %\end{filecontents} %\begin{filecontents}[overwrite]{volume8,4/section2.tex} %\section{Second section} %Bye %\end{filecontents} % End of code for folders and files

%\includeonly{volume8,4/section1} % How to make this work?

\begin{document}

\include{volume8,4/section1}

\include{volume8,4/section2}

\end{document}

marquinho
  • 1,721
  • Try \includeonly{{with,comma},without_comma,{with,comma,again}} (just guessing; may not be possible at all) – Phelype Oleinik Nov 19 '21 at 16:16
  • I just tested with curly brackets, but this seems not to work, although \includeonly{{file}} still allows to include file. Files with comma in their names are just ignored. – Jasper Habicht Nov 19 '21 at 16:22
  • That's right, I had tested for double braces, as in \includeonly{{volume8,4/section1}}, but it doesn't work. – marquinho Nov 19 '21 at 16:30
  • @marquinho try adding a comma at the end: \includeonly{{volume8,4/section1},} – Phelype Oleinik Nov 19 '21 at 16:33
  • @PhelypeOleinik I think it fails (again) in the nested \@for inside \include – David Carlisle Nov 19 '21 at 16:37
  • @PhelypeOleinik and David: Thanks, but it still fails (for me at least). Or can you make it work it in the MWE? – marquinho Nov 19 '21 at 16:40
  • 1
    @DavidCarlisle Oh.... Then mv 'volume8,4/section1' 'volume8.4/section1' should work smoothly :) – Phelype Oleinik Nov 19 '21 at 16:41
  • My plan was to blame the last person to have touched the latex filename handling code. – David Carlisle Nov 19 '21 at 16:42
  • 1
    @marquinho I'm not sure this is possible at all (without a major surgery in LaTeX's internals). A comma was always used as a list separator, and since LaTeX uses (the quirky) \@for to loop over comma separated lists, it is hard to trick it into accepting a comma – Phelype Oleinik Nov 19 '21 at 16:43
  • 2
    @marquinho are you on linux ? if so ln -s might be the simplest solution – David Carlisle Nov 19 '21 at 16:43
  • @DavidCarlisle https://chat.stackexchange.com/transcript/41?m=59414708#59414708 – Phelype Oleinik Nov 19 '21 at 16:43
  • @PhelypeOleinik that was then, this is now – David Carlisle Nov 19 '21 at 16:44
  • @DavidCarlisle We're on UNIX (Mac) so mv for batch renaming the folders as suggested by Phelype + some text editor to batch edit the file contents should work. – marquinho Nov 19 '21 at 16:52
  • I would have thought you could omit the volume8,4 from the tex then run with TEXINPUTS=volumne8,4: so that directory gets searched but it fails, perhaps kpathse also has problems with commas not just tex... – David Carlisle Nov 19 '21 at 16:53
  • 2
    yes a symlink with ln -s rather than mv would of course allow other existing applications to use the comma names. the last two people to touch the latex filehandling code were Phelype and and me and we both just failed to really answer your question, which is surprisingly hard.... – David Carlisle Nov 19 '21 at 16:55
  • @DavidCarlisle thanks for the clarification on the symlink, this is absolutely not in my wheelhouse! – marquinho Nov 19 '21 at 17:00
  • @PhelypeOleinik If you (or David) would like to answer with a brief explanation as to why no solution is possible, that might be good for the forum (for future reference). Thanks for your help! – marquinho Nov 19 '21 at 17:01

2 Answers2

4

By far the simplest solution is at the linux/Mac commandline do

ln -s volume8,4 volume8.4

then the directory will (from any application) be able to be referenced with either name, so you can avoid the commas from TeX,

However if that is not possible I did get this to work

\documentclass{article}

\includeonly{section1}

\begin{document}

\include{section1}

\include{section2}

\end{document}

That is remove the directory name, then you want to add that directory to the search path. This ought to be

TEXINPUTS=volume8,4: pdflatex mainfile

But that does not work, kpathse seems to have comma issues as well.

However this does work

TEXINPUTS=".//:" pdflatex bb460

which recursively adds all directories under the current directory. Of course this assumes the filenames are unique, if you have section1.tex in multiple subdirectories this is going to fail.

David Carlisle
  • 757,742
  • Thanks a lot, +1. I've kept toying with the other approach (redefining the input path) and found a working solution, see my answer. – marquinho Nov 20 '21 at 23:47
2

In addition to David Carlisle's filesys-based answer, I kept experimenting and have found a simpler solution.

It doesn't require the command line: everything can be specified within the document by redefining \input@path. The comma is suitably "masked" (using braces and \string) and "hidden" inside the path, so that it doesn't show up explicitly in \includeonly, in the spirit of point 2 in my question. This way, we circumvent the parsing problems.

In my question, I had overlooked that \include, at its core, contains an \input command. The internal macro \input@path has bearing on \include(only), too. The path for \include is specified by issuing

\def\input@path{{volume8\string,4/}}

which renders the comma harmless. The inclusion commands

\include{section1} 
\includeonly{section1,section2}

then work as expected. The main document generates the partial .aux files and a selective inclusion via \includeonly preserves the cross-references.

The downside: normally, the partial .aux files would be generated in the (sub)directory that contains the "sections", the included .tex documents (here, the subfolder volume8,4). With my solution, they are generated in the main folder where the main file and the main .aux live, since the program cannot write out to the "improperly" named directory.

This difference notwithstanding, all the partial files are read and \inputed correctly by the main .aux file (which goes \@input{section1.aux}). The cross-references etc. are processed accordingly.

The only downside I noticed, then, is that the main folder gets very crowded. (In our case, a price worth paying.)

Please do point out other failings of this solution, if you find them!


MWE for reference:

\documentclass{article}

\makeatletter \def\input@path{{volume8\string,4/}} \makeatother

\includeonly{section1 %,section2 % multiple inclusion still relies on comma as separator }

\begin{document}

\include{section1}

\include{section2}

\end{document}

marquinho
  • 1,721
  • hm I tried input@path thought it didn't work but I may have got the test wrong(I had thought it should work:-) I don't think you need \string though? +1 – David Carlisle Nov 21 '21 at 10:23
  • Yes, it feels like \string should be immaterial at this point. And I had neglected it in my first test. I can confirm that without \string, compilation fails! – marquinho Nov 21 '21 at 13:12
  • Weird, because \string, makes a catcode-12 comma, but... commas are already (modulo babel) catcode-12. I'll investigate... eventually – Phelype Oleinik Nov 21 '21 at 13:54