重组包含输入和宏的多个文件

重组包含输入和宏的多个文件

我有一个多文件文档,其结构很奇怪,我想改善其结构。

层次结构如下:

dir0
├──header.tex
├──dir1
|  ├──main1.tex
|  └──img1.png
├──dir2
|  ├──main2.tex
|  └──img2.png
└──dir3
   └──sharedtext.tex

这些文件看起来如下:

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}

共享文本.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

因此,基本上,序言位于 header.tex 中,所有主文件的共享文本都存储在 sharedtext.tex 中,并且文档特定的单词/文本块使用在相应的 main.tex 中定义并在 sharedtext.tex 中调用的宏添加

另一件事是图形位于 main.tex 文件的目录中,需要正确引用。但我认为可以使用以下命令轻松完成:

\graphicspath{...}

有没有更好的方法来构造它?你建议使用哪些命令?我认为 \import 或 \include 比 \input 更适合这里。“subfile”包也可能是一个选择

亲切的问候 63rrit

答案1

shared.tex当计算的次数时\input,你可以合并shared.texheader.tex

文件结构:

dir0
├──shared.tex
├──main1.tex
├──img1.png
├──main2.tex
└──img2.png

shared.tex

\csname @\ifx\inputcount\undefined first\else second\fi oftwo\endcsname{%
  \gdef\inputcount{0}%
}{%
  \xdef\inputcount{\number\numexpr\inputcount+1\relax}%
}%
%%
\ifnum\inputcount=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}
  ...
  %%%%%%%%%%
  \expandafter\endinput
\fi
%%
\ifnum\inputcount=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
  %%%%%%%%%%
  \expandafter\endinput
\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}

下面提出的事情依赖于命令行选项--jobname 不是(!)在编译 .tex 文件时使用。这意味着下面提出的事情不是(!)在像 overleaf 这样的在线平台上进行工作,其中命令行选项--jobname由底层“机器”使用。

以下与我的类似第一个答案针对这个问题在许多文档中共享的通用文本

\input当创建许多相同模式的文档时,计算文件加载次数的概念也很有用。

有可能的

  • 让 TeX 在特定点停止读取输入文件。这可以通过 来实现\endinput。您需要确保\if....\fi在应用 之前是平衡的\endinput。您可以使用\expandafter让 TeX\fi在处理 之前进行处理(从而平衡事物)\endinput
  • 多次输入一个输入文件,由此每次增加一个反宏,\input用于决定使用当前调用来处理文件的哪个部分\input

当多次加载同一个文件时,您可以将特定于文档的所有内容(“变量”、文本序列)保留在同一文件中。

可以通过所有文档共用的“框架”多次加载同一个文件。

为了正确获取作业名称/生成的 .pdf 文件的名称,可以从文件中加载该框架,随后该框架将多次加载该文件。

使用以下模板,所有文件都具有相同的模式。main⟨K⟩.tex

编译产生定义反宏并加载。包含所有文档共有的框架(序言、文本片段等)。main⟨K⟩.tex\inputcountframework.tex
framework.tex

framework.tex加载时,将产生短语“ ”。反过来,可以通过一次又一次地加载= ,每次递增,从而处理另一部分。 第一部分可能包含定义(=特定于文档的值main⟨K⟩.tex\jobnamemain⟨K⟩
framework.tex\input\jobname.texmain⟨K⟩.tex\inputcountmain⟨K⟩.tex
main⟨K⟩.tex主要的⟨K⟩) 表示用作变量的宏。
的第二部分可能包含特定于文档的文本片段main⟨K⟩.tex主要的⟨K⟩
的第三部分可能包含另一段特定于该文档的文本main⟨K⟩.tex主要的⟨K⟩
ETC...

使用以下模板您可以编译该文件main1.tex和文件main2.tex

这些加载framework.tex依次为所有文档提供框架,并重新加载 main1.tex相应的文件main2.tex两次。
第一次只处理作为变量的宏定义的部分。第二次只处理特定于相应的
文本片段。main1.texmain2.tex

文件: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:
\input\jobname.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.

\input\jobname.tex

\end{document}

文件:main1.tex:

\csname @\ifx\inputcount\undefined first\else second\fi oftwo\endcsname{%
  % You could move the following \newcommand to framework.tex.
  \newcommand\inputcount{0}%
  %%%%%%%%%
  \input framework.tex
}{%
  \xdef\inputcount{\number\numexpr\inputcount+1\relax}%
}%
%%
%% Portion 1 - Variables:
%%
\ifnum\inputcount=1  %
  \makeatletter
  \newcommand\VariableA{%
    This is Variable A with main1.tex.
  }%
  \newcommand\VariableB{%
    This is Variable B with main1.tex.
  }%
  \newcommand\VariableC{%
    This is Variable C with main1.tex.
  }%
  %...
  \makeatother
  \expandafter\endinput
\fi 
%%
%% Portion 2 - First text snippet:
%%
\ifnum\inputcount=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}.
  \expandafter\endinput
\fi

文件:main2.tex:

\csname @\ifx\inputcount\undefined first\else second\fi oftwo\endcsname{%
  % You could move the following \newcommand to framework.tex.
  \newcommand\inputcount{0}%
  %%%%%%%%%
  \input framework.tex
}{%
  \xdef\inputcount{\number\numexpr\inputcount+1\relax}%
}%
%%
%% Portion 1 - Variables:
%%
\ifnum\inputcount=1  %
  \makeatletter
  \newcommand\VariableA{%
    This is Variable A with main2.tex.
  }%
  \newcommand\VariableB{%
    This is Variable B with main2.tex.
  }%
  \newcommand\VariableC{%
    This is Variable C with main2.tex.
  }%
  %...
  \makeatother
  \expandafter\endinput
\fi 
%%
%% Portion 2 - First text snippet:
%%
\ifnum\inputcount=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}.
  \expandafter\endinput
\fi

当编译 main1.tex 时我得到main1.pdf如下内容:

在此处输入图片描述

当编译 main2.tex 时我得到main2.pdf如下内容:

在此处输入图片描述

所有文件都保存在同一目录中。

如果需要,您可以将包含特定于每个文档的图像/任何内容的文件放在单独的子目录中,其名称可以通过扩展的结果推断出来\jobname。例如,
文档的图像main1在子目录中main1_图像
文档图像main2在子目录中main2_图像
...

这种方式的评估\jobname可以是一种“通用”的方式,用于指定属于其中一个文档的文件的子目录 - 例如,在指令内\graphicspath或直接在文件路径内。

因此再次强调:

对于刚刚提出的事情,它依赖于命令行选项--jobname 不是(!)在编译 .tex 文件时使用。这意味着刚刚提出的事情不是(!)在像 overleaf 这样的在线平台上进行工作,其中命令行选项--jobname由底层“机器”使用。

在此类平台/无法依赖\jobname提供主 .tex 输入文件名称的情况下,您可以在每个文件中在命令之前定义一个宏来扩展短语 ,并在其中使用该-macro 而不是-primitive。 这种方法的缺点是重命名文件意味着需要编辑该文件以更改-macro 的定义。main⟨K⟩.tex\jobfile\input framework.texmain⟨K⟩framework.tex\jobfile\jobname
main⟨K⟩.tex\jobfile

相关内容