TeX - LaTeX Asked by 63rrit on November 12, 2021
i have a multifile document, that is weirdly structured and i want to improve the structure.
the hierarchy looks like this:
dir0
├──header.tex
├──dir1
| ├──main1.tex
| └──img1.png
├──dir2
| ├──main2.tex
| └──img2.png
└──dir3
└──sharedtext.tex
the files look like this:
header.tex:
usepackage[...]{...} % packages used in both main1 and main2 go here
...
newcommand{textblockForBoth}[]{textblock that is used in both main1 and main2}
...
main1.tex:
documentclass[a4paper,oneside]{scrbook}
usepackage[...]{...} % packages only used in main1
...
input{../header.tex}
newcommand{textblockForMain1}[]{textblock that is used only in main1}
...
begin{document}
input{../dir3/sharedtext.tex}
end{document}
main2.tex:
documentclass[a4paper,oneside]{scrbook}
usepackage[...]{...} % packages only used in main2
...
input{../header.tex}
newcommand{textblockForMain2}[]{textblock that is used only in main2}
...
begin{document}
input{../dir3/sharedtext.tex}
end{document}
sharedtext.tex:
tableofcontents
chapter{chapter1}
sharedtext is written here and commands put some stuff here:
textblockHere % textblocks or just words from main1 or main2 are added
so basically the preambel is located in the header.tex,
shared text by all main files is stored in sharedtext.tex
and document specific words/textblocks are added with macros that are defined in the respective main.tex and are called in the sharedtext.tex
another thing is that graphics are in the directory of the main.tex files and need to be referenced correctly. but i think this can be done easily using the following:
graphicspath{...}
is there a better way to structure this?
and which commands do you suggest using?
i think import or include are better suited here then input.
The "subfile" package might also be an option
kind regards
63rrit
When counting how many times shared.tex
was input
, then you can combine shared.tex
and header.tex
:
File structure:
dir0
├──shared.tex
├──main1.tex
├──img1.png
├──main2.tex
└──img2.png
shared.tex
csname @ifxinputcountundefined firstelse secondfi oftwoendcsname{%
gdefinputcount{0}%
}{%
xdefinputcount{numbernumexprinputcount+1relax}%
}%
%%
ifnuminputcount=0 %
% This has formerly been header.tex:
usepackage[...]{...} % packages used in both main1 and main2 go here
...
newcommand{textblockForBoth}[]{textblock that is used in both main1 and main2}
...
%%%%%%%%%%
expandafterendinput
fi
%%
ifnuminputcount=1 %
% This has formerly been shared.tex:
tableofcontents
chapter{chapter1}
sharedtext is written here and commands put some stuff here:
textblockHere % textblocks or just words from main1 or main2 are added
%%%%%%%%%%
expandafterendinput
fi
main1.tex
documentclass[a4paper,oneside]{scrbook}
usepackage[...]{...} % packages only used in main1
...
% This time inputcount will be defined 0...
input{./shared.tex}
newcommand{textblockForMain1}[]{textblock that is used only in main1}
...
begin{document}
% This time inputcount will be incremented to 1...
input{./shared.tex}
end{document}
main2.tex
documentclass[a4paper,oneside]{scrbook}
usepackage[...]{...} % packages only used in main2
...
% This time inputcount will be defined 0...
input{./shared.tex}
newcommand{textblockForMain2}[]{textblock that is used only in main2}
...
begin{document}
% This time inputcount will be incremented to 1...
input{./shared.tex}
end{document}
With the things proposed in the following it is relied on the commandline-option --jobname
not(!) being used when compiling a .tex-file. This implies that the things proposed in the following do not(!) work out on online-platforms like overleaf where the commandline-option --jobname
is used by the underlying "machinery".
The following is similar to my first answer to the question shared common text across many documents.
The concept of counting how many times a file is loaded via input
is useful also when creating many documents of the same pattern.
It is possible
endinput
. You need to make sure that if..
..fi
are balanced before applying endinput
. You can use expandafter
for having TeX process fi
(and thus balance things) before processing endinput
.input
for deciding which portion of the file to process with the current call to input
.When loading the same file several times you can keep all things ("variables", sequences of text) specific to a document within the same file.
Loading that same file several times can be done outgoing from a "framework" common to all documents.
In order to get the jobname/the name of the resulting .pdf-file right, that framework can be loaded from the file which afterwards is to be loaded several times by the framework.
With the following templates all files main⟨K⟩.tex
are of the same pattern.
Compiling main⟨K⟩.tex
yields defining the counter-macro inputcount
and loading framework.tex
.
framework.tex
contains the framework (preamble, text-snippets etc) common to all documents.
As framework.tex
is loaded by main⟨K⟩.tex
, jobname
will yield the phrase "main⟨K⟩
".
framework.tex
in turn can—via input
—load jobname.tex
= main⟨K⟩.tex
again and again, each time incrementing inputcount
and therefore processing another portion of main⟨K⟩.tex
.
The first portion of main⟨K⟩.tex
might contain definitions(=values specific to the document main⟨K⟩) for macros that serve as variables.
The second portion of main⟨K⟩.tex
might contain a snippet of text specific to the document main⟨K⟩.
The third portion of main⟨K⟩.tex
might contain another snippet of text specific to the document main⟨K⟩.
Etc...
With the following template you can compile the file main1.tex
and the file main2.tex
.
Each of these loads framework.tex
which in turn provides the framework for all documents and reloads main1.tex
respective file main2.tex
twice.
The first time only the portion with the definitions of macros that serve as variables is processed.
The second time only the text-snippet specific to main1.tex
respective main2.tex
is processed.
File: framework.tex:
% This file is input from within main1.tex or main2.tex, thus
% jobname will be "main1" or "main2"...
documentclass{article}
%usepackage...
%...
% The value of inputcount will be increased to 1, thus
% Portion 1 will be processed and
% VariableA, VariableB and VariableC will be defined:
inputjobname.tex
begin{document}
tableofcontents
section{A section which all documents have in common}
This is a section which all documents have in common.
Now let's within the section which all documents have in common
use the variables specific to each document:
begin{itemize}
item verb|VariableA| is: VariableA
item verb|VariableB| is: VariableB
item verb|VariableC| is: VariableC
end{itemize}
section{Another section which all documents have in common}
This is another section which all documents have in common.
Now let's come to a snippet of text which differs from document
to document:
% The value of inputcount will be increased to 2, thus
% Portion 2 will be processed.
inputjobname.tex
end{document}
File: main1.tex:
csname @ifxinputcountundefined firstelse secondfi oftwoendcsname{%
% You could move the following newcommand to framework.tex.
newcommandinputcount{0}%
%%%%%%%%%
input framework.tex
}{%
xdefinputcount{numbernumexprinputcount+1relax}%
}%
%%
%% Portion 1 - Variables:
%%
ifnuminputcount=1 %
makeatletter
newcommandVariableA{%
This is Variable A with main1.tex.
}%
newcommandVariableB{%
This is Variable B with main1.tex.
}%
newcommandVariableC{%
This is Variable C with main1.tex.
}%
%...
makeatother
expandafterendinput
fi
%%
%% Portion 2 - First text snippet:
%%
ifnuminputcount=2 %
section{A section that is produced by processing
Portion 2 of texttt{main1.tex}}
Compiling texttt{main1.tex} yields a nice document.\
Compiling texttt{main1.tex} yields a nice document.\
Compiling texttt{main1.tex} yields a nice document.\
Compiling texttt{main1.tex} yields a nice document.\
That's the end of the section coming from Portion 2 of texttt{main1.tex}.
expandafterendinput
fi
File: main2.tex:
csname @ifxinputcountundefined firstelse secondfi oftwoendcsname{%
% You could move the following newcommand to framework.tex.
newcommandinputcount{0}%
%%%%%%%%%
input framework.tex
}{%
xdefinputcount{numbernumexprinputcount+1relax}%
}%
%%
%% Portion 1 - Variables:
%%
ifnuminputcount=1 %
makeatletter
newcommandVariableA{%
This is Variable A with main2.tex.
}%
newcommandVariableB{%
This is Variable B with main2.tex.
}%
newcommandVariableC{%
This is Variable C with main2.tex.
}%
%...
makeatother
expandafterendinput
fi
%%
%% Portion 2 - First text snippet:
%%
ifnuminputcount=2 %
section{A section that is produced by processing
Portion 2 of texttt{main2.tex}}
Compiling texttt{main2.tex} yields a nice document.\
Compiling texttt{main2.tex} yields a nice document.\
Compiling texttt{main2.tex} yields a nice document.\
Compiling texttt{main2.tex} yields a nice document.\
That's the end of the section coming from Portion 2 of texttt{main2.tex}.
expandafterendinput
fi
When compiling main1.tex I get main1.pdf
which looks like this:
When compiling main2.tex I get main2.pdf
which looks like this:
All files are kept in the same directory.
If necessary you can have files with images/whatsoever content specific to each document in a separate sub-directory whose name somehow can be deduced from the result of expanding jobname
. E.g.,
images for document main1 in subdirectory main1_images,
images for document main2 in subdirectory main2_images,
...
This way evaluating jobname
can be a "generic" way of specifying sub-directories with files belonging to one of the documents—e.g., within the graphicspath
-directive or within file-paths directly.
Therefore again:
With the things just proposed it is relied on the commandline-option --jobname
not(!) being used when compiling a .tex-file. This implies that the things just proposed do not(!) work out on online-platforms like overleaf where the commandline-option --jobname
is used by the underlying "machinery".
On such platforms/in situations where you cannot rely on jobname
delivering the name of the main .tex-input-file you could within each file main⟨K⟩.tex
define a macro jobfile
right before the command input framework.tex
to expand to the phrase main⟨K⟩
and within framework.tex
use that jobfile
-macro instead of the jobname
-primitive.
The disadvantage with this approach is that renaming a file main⟨K⟩.tex
implies the need of editing that file for changing the definition of the jobfile
-macro.
Answered by Ulrich Diez on November 12, 2021
Get help from others!
Recent Questions
Recent Answers
© 2024 TransWikia.com. All rights reserved. Sites we Love: PCI Database, UKBizDB, Menu Kuliner, Sharing RPP