3

In a multi-file project organized as:

mainfile.tex
subfile1/subfile1.tex
subfile2/subfile2.tex
...

in order to make every subfile compilable on its own and make possible of referencing between subfiles, I'm currently using the package xr and write the following in the preamble of the subfiles:

\externaldocument{../subfile1/subfile1}
\externaldocument{../subfile2/subfile2}
...

but to avoid inputting the current file, I have to remove \externaldocument{../subfile1/subfile1} in subfile1.tex, remove \externaldocument{../subfile2/subfile2} in subfile2.tex, etc. This makes the preamble of the subfiles kind of hard to maintain when the number of files grows.

I wonder if this can be made automatic, that is to have a list of subfiles stored in list.tex, with each name of the subfile on a separate line:

subfile1
subfile2
...

and read this file line by line in the subfile, comparing if the current line is empty or equal to \jobname, and if not, add the line \externaldocument{../current-line/current-line}.

Is it possible to do this with expl3?


Below is a set of files to test. The files are organized as:

list.txt
main.tex
subfile-one/subfile-one.tex
subfile-two/subfile-two.tex

Below are the file contents.

  • list.txt (the last empty line is on purpose)
subfile-one
subfile-two

  • main.tex
\documentclass{article}
\usepackage{docmute}
\begin{document}
\input{subfile-one/subfile-one.tex}
\input{subfile-two/subfile-two.tex}
\end{document}
  • subfile-one.tex
\documentclass{article}

\usepackage{xr}

% \externaldocument{../subfile-two/subfile-two}

\setcounter{section}{0} \begin{document}

\section{one} \label{one}

\ref{two}

\end{document}

  • subfile-two.tex
\documentclass{article}

\usepackage{xr}

% \externaldocument{../subfile-one/subfile-one}

\setcounter{section}{1} \begin{document}

\section{two} \label{two}

\ref{one}

\end{document}

Expected behavior:

enter image description here

and each subfile should contain half of it.

Jinwen
  • 8,518
  • For clarification: are solutions using LaTeX2e or plain TeX functionality also ok, or are you looking for an expl3 solution specifically? If yes, why? – Marijn Nov 07 '22 at 12:24
  • And for ease of answering: could you please provide complete compilable versions of mainfile.tex, subfile1.tex, subfile2.tex, list.tex in your question, so that people willing to provide solutions just need to write a file/list processing macro and don't need to implement all of the surrounding code? – Marijn Nov 07 '22 at 12:27
  • In case non-expl3 syntax is ok you can find an implementation in https://tex.stackexchange.com/questions/111335/testing-lines-read-from-external-file. – Marijn Nov 07 '22 at 12:40

1 Answers1

3

The following should do (untested because of lack of compilable code in the question):

\documentclass{article}

\ExplSyntaxOn \tl_clear_new:N \l_jinwen_files_tl \prg_generate_conditional_variant:Nnn \str_if_eq:nn { on } { F } \ior_new:N \g_jinwen_file_ior \ior_open:Nn \g_jinwen_file_ior { list.tex } \ior_map_inline:Nn \g_jinwen_file_ior { \str_if_eq:onF { \jobname } {#1} { \tl_put_right:Nn \l_jinwen_files_tl { \externaldocument { ../#1/#1 } } } } \ior_close:N \g_jinwen_file_ior \exp_last_unbraced:NV \ExplSyntaxOff \l_jinwen_files_tl

\begin{document} whatever \end{document}

Skillmon
  • 60,462
  • Thank you for this hypothetical code. However, it doesn't seem to work properly. I've added a set of testing files to the question. If everything goes as expected, there should be no warnings for missing labels when compiling the three .tex files. But for now the \externaldocument doesn't seem to be properly configured. – Jinwen Nov 07 '22 at 13:49
  • @Jinwen you need to 1. include the expl3-code in subfile-two as well if you want it to work standalone, and 2. you need to compile both subfile-two and subfile-one standalone so that the aux files exist. If I do both I get the correct contents (and a warning about the labels being defined multiple times...) – Skillmon Nov 07 '22 at 14:25
  • About the "labels being defined multiple times" issue, I suggest using \exp_args:No \str_if_eq:nnF instead of \tl_if_eq:onF. Comparing them as token list instead of string seems to get the result "false" all the time. – Jinwen Nov 07 '22 at 14:27
  • Also, for unknown reason the \externaldocument inside \ior_map_inline:Nn does not behave like usual, only if I put it inside a \AtBeginDocument it then works normally again. Is it because there is an invisible grouping surrounding it here? – Jinwen Nov 07 '22 at 14:39
  • @Jinwen none that I'm aware of, but we can fix this using a scratch token list instead. The \tl_if_eq:onF test gets the wrong result because \jobname is a string (my bad). – Skillmon Nov 07 '22 at 14:43
  • 1
    And you might have issues with the \externaldocument because of the \ExplSyntaxOn. – Skillmon Nov 07 '22 at 14:43
  • Thank you for the edited answer. About your last point, do you think postpone \externaldocument to the hook begindocument/before would do? Seems that at that place the ExplSyntax has been turned off. Or just simply add \ExplSyntaxOff and \ExplSyntaxOn around the \externaldocument line? – Jinwen Nov 07 '22 at 14:54
  • 1
    @Jinwen my edited answer will only execute the \externaldocument after \ExplSyntaxOff. – Skillmon Nov 07 '22 at 16:14