为了创建文档结构,我通常使用如下方法:
\section{1}
Text for chapter 1
\section{2}
Text for chapter 2
\subsection{2.1}
Text for chapter 2.1
\subsubsection{2.1.1}
Text for chapter 2.1.1
\paragraph{2.1.1.1}\mbox{}\\
Text for chapter 2.1.1.1
是否可以\section \subsection \subsubsection\paragraph ...
根据目录结构自动处理?我的想法是拥有树状目录结构,作为文档创建的模板。在此示例中,所需文本"Text for chapter ..."
位于chapter.tex
文件内:
./1/chapter.tex
./2/chapter.tex
./2/2.1/chapter.tex
./2/2.1/2.1.1/chapter.tex
./2/2.1/2.1.1/2.1.1.1/chapter.tex
以下示例与上一个示例相同,只是所需文本包含在具有不同名称的文件中(每个目录一个文件)。这样更好,因为在编辑器中,您可以看到章节的正确名称,而不是chapter.txt
每个文档部分的名称:
./1/1.tex
./2/2.tex
./2/2.1/2_1.tex
./2/2.1/2.1.1/2_1_1.tex
./2/2.1/2.1.1/2.1.1.1/2_1_1_1.tex
作为奖励,我还希望自动标记每个章节\section \subsection \subsubsection\paragraph ...
,例如等等\label{2.1.1}
。
我猜我需要某种预处理器,它首先按字母顺序或数字下划线对目录进行排序,然后编写最终文档。我不确定这个 LaTeX 是否可以做到,或者是否需要一些外部工具。多平台解决方案很好,但我的主要操作系统是 Linux。谢谢。
答案1
这是一个解决方案
笔记
- 解决方案使用(la)TeX循环。
- 文件名更改为 1_1_1 -->1+1+1 (这样更简单)
\documentclass{article}
\usepackage{lipsum}
\setcounter{secnumdepth}{4}
\newif\ifmoreinput
\newcounter{sec}
\newcounter{ssec}[sec]
\newcounter{sssec}[ssec]
\newcounter{parg}[sssec]
\begin{document}
\loop
\stepcounter{section}%
\stepcounter{sec}%
\edef\mtpath{\thesection}%
\edef\mtfile{\thesec}%
\IfFileExists{\mtpath/\mtfile.tex}{%
\moreinputtrue%
\addtocounter{section}{-1}%
\let\SomeMagicCommandThatHoldsChapterNameGoesHere\section
\input{\mtpath/\mtfile.tex}%
{\loop
\stepcounter{subsection}%
\stepcounter{ssec}%
\edef\mtpath{\thesection/\thesubsection}%
\edef\mtfile{\thesec+\thessec}%
\IfFileExists{\mtpath/\mtfile.tex}{%
\moreinputtrue%
\addtocounter{subsection}{-1}%
\let\SomeMagicCommandThatHoldsChapterNameGoesHere\subsection
\input{\mtpath/\mtfile.tex}%
{\loop
\stepcounter{subsubsection}%
\stepcounter{sssec}%
\edef\mtpath{\thesection/\thesubsection/\thesubsubsection}%
\edef\mtfile{\thesec+\thessec+\thesssec}%
\IfFileExists{\mtpath/\mtfile.tex}{%
\moreinputtrue%
\addtocounter{subsubsection}{-1}%
\let\SomeMagicCommandThatHoldsChapterNameGoesHere\subsubsection
\input{\mtpath/\mtfile.tex}%
{\loop
\stepcounter{paragraph}%
\stepcounter{parg}%
\edef\mtpath{\thesection/\thesubsection/\thesubsubsection/\theparagraph}%
\edef\mtfile{\thesec+\thessec+\thesssec+\theparg}%
\IfFileExists{\mtpath/\mtfile.tex}{%
\moreinputtrue%
\addtocounter{paragraph}{-1}%
\let\SomeMagicCommandThatHoldsChapterNameGoesHere\paragraph
\input{\mtpath/\mtfile.tex}}{\moreinputfalse}%
\ifmoreinput\repeat}}{\moreinputfalse}%
\ifmoreinput\repeat}}{\moreinputfalse}%
\ifmoreinput\repeat}}{\moreinputfalse}%
\ifmoreinput\repeat
\end{document}
更新这里有一个更好的方法:我们用它makemymain.tex
来生成mymain.tex
这个新文件,它将结构良好,并且更有助于使用乳胶编辑器(我会尽可能解释)
制作我的主程序
\documentclass{article}
\usepackage{lipsum}
\setcounter{secnumdepth}{4}
\newcommand{\SomeMagicCommandThatHoldsChapterNameGoesHere}[1]{{#1}}
\newread\mtread
\newwrite\mtwrite
\immediate\openout\mtwrite=mymain.tex
\newcommand{\mtadd}[1]{\immediate\write\mtwrite{\string#1}}
\newcommand{\mtinput}[1]{%
\moreinputtrue%
\openin\mtread=\mtpath/\mtfile.tex
\read\mtread to \myread
\closein\mtread
\immediate\write\mtwrite{\string#1\myread}
\immediate\write\mtwrite{\string\input {\mtpath/\mtfile.tex}}}
% creating preamble of mymain.tex
\mtadd{\documentclass{article}}
\mtadd{\usepackage{lipsum}}
\mtadd{\setcounter{secnumdepth}{4}}
\mtadd{\newcommand{\string\SomeMagicCommandThatHoldsChapterNameGoesHere}[1]{}}
\mtadd{\begin{document}}
\AtEndDocument{\mtadd{\end{document}}}
\newif\ifmoreinput
\newcounter{sec}
\newcounter{ssec}[sec]
\newcounter{sssec}[ssec]
\newcounter{parg}[sssec]
\begin{document}
\tableofcontents
\loop
\stepcounter{section}%
\stepcounter{sec}%
\edef\mtpath{\thesection}%
\edef\mtfile{\thesec}%
\IfFileExists{\mtpath/\mtfile.tex}{%
\mtinput{\section}%
{\loop
\stepcounter{subsection}%
\stepcounter{ssec}%
\edef\mtpath{\thesection/\thesubsection}%
\edef\mtfile{\thesec+\thessec}%
\IfFileExists{\mtpath/\mtfile.tex}{%
\mtinput{\subsection}%
{\loop
\stepcounter{subsubsection}%
\stepcounter{sssec}%
\edef\mtpath{\thesection/\thesubsection/\thesubsubsection}%
\edef\mtfile{\thesec+\thessec+\thesssec}%
\IfFileExists{\mtpath/\mtfile.tex}{%
\mtinput{\subsubsection}%
{\loop
\stepcounter{paragraph}%
\stepcounter{parg}%
\edef\mtpath{\thesection/\thesubsection/\thesubsubsection/\theparagraph}%
\edef\mtfile{\thesec+\thessec+\thesssec+\theparg}%
\IfFileExists{\mtpath/\mtfile.tex}{%
\mtinput{\paragraph}}{\moreinputfalse}%
\ifmoreinput\repeat}}{\moreinputfalse}%
\ifmoreinput\repeat}}{\moreinputfalse}%
\ifmoreinput\repeat}}{\moreinputfalse}%
\ifmoreinput\repeat
\end{document}
更新 2 避免扩展问题(读写)
\newcommand{\SomeMagicCommandThatHoldsChapterNameGoesHere}[1]{{#1}}
替换为
\newcommand{\SomeMagicCommandThatHoldsChapterNameGoesHere}[1]{{\unexpanded{#1}}}
回到文件命名的原始约定2_1_1.tex
:
\catcode`\_12\relax
在第一个循环之前添加
制作我的主程序
\documentclass{article}
\usepackage{lipsum}
\newcommand{\SomeMagicCommandThatHoldsChapterNameGoesHere}[1]{{\unexpanded{#1}}}
\newread\mtread
\newwrite\mtwrite
\immediate\openout\mtwrite=mymain.tex
\newcommand{\mtadd}[1]{\immediate\write\mtwrite{\string#1}}
\newcommand{\mtinput}[1]{%
\moreinputtrue%
\openin\mtread=\mtpath/\mtfile.tex
\read\mtread to \myread
\closein\mtread
\immediate\write\mtwrite{\string#1\myread}
\immediate\write\mtwrite{\string\input {\mtpath/\mtfile.tex}^^J}}
% creating preamble of mymain.tex
\mtadd{\documentclass{article}}
\mtadd{\usepackage{lipsum}}
\mtadd{\setcounter{secnumdepth}{4}}
\mtadd{\newcommand{\string\SomeMagicCommandThatHoldsChapterNameGoesHere}[1]{}}
\mtadd{\begin{document}}
\AtEndDocument{\mtadd{\end{document}}}
\newif\ifmoreinput
\newcounter{sec}
\newcounter{ssec}[sec]
\newcounter{sssec}[ssec]
\newcounter{parg}[sssec]
\begin{document}
\tableofcontents
\catcode`\_12\relax
\loop
\stepcounter{section}%
\stepcounter{sec}%
\def\mtpath{\thesection}%
\def\mtfile{\thesec}%
\IfFileExists{\mtpath/\mtfile.tex}{%
\mtinput{\section}%
{\loop
\stepcounter{subsection}%
\stepcounter{ssec}%
\def\mtpath{\thesection/\thesubsection}%
\def\mtfile{\thesec_\thessec}%
\IfFileExists{\mtpath/\mtfile.tex}{%
\mtinput{\subsection}%
{\loop
\stepcounter{subsubsection}%
\stepcounter{sssec}%
\def\mtpath{\thesection/\thesubsection/\thesubsubsection}%
\def\mtfile{\thesec_\thessec_\thesssec}%
\IfFileExists{\mtpath/\mtfile.tex}{%
\mtinput{\subsubsection}%
{\loop
\stepcounter{paragraph}%
\stepcounter{parg}%
\def\mtpath{\thesection/\thesubsection/\thesubsubsection/\theparagraph}%
\def\mtfile{\thesec_\thessec_\thesssec_\theparg}%
\IfFileExists{\mtpath/\mtfile.tex}{%
\mtinput{\paragraph}}{\moreinputfalse}%
\ifmoreinput\repeat}}{\moreinputfalse}%
\ifmoreinput\repeat}}{\moreinputfalse}%
\ifmoreinput\repeat}}{\moreinputfalse}%
\ifmoreinput\repeat
\end{document}
主文件
\documentclass{article}
\usepackage{lipsum}
\setcounter{secnumdepth}{4}
\newcommand{\SomeMagicCommandThatHoldsChapterNameGoesHere}[1]{}
\begin{document}
\section{chapter 1}
\input{1/1.tex}
\section{chapter 2}
\input{2/2.tex}
\subsection{chapter 2.1}
\input{2/2.1/2_1.tex}
\subsubsection{chapter 2.1.1}
\input{2/2.1/2.1.1/2_1_1.tex}
\paragraph{chapter 2.1.1.1}
\input{2/2.1/2.1.1/2.1.1.1/2_1_1_1.tex}
\subsection{chapter 2.2}
\input{2/2.2/2_2.tex}
\subsubsection{chapter 2.2.1}
\input{2/2.2/2.2.1/2_2_1.tex}
\end{document}
答案2
这种方法可能不是一个好主意,LaTeX 旨在为您处理编号(例如,当您稍后决定在 1 和 2 之间添加一个部分时)。
如果你无论如何都想这么做,那么脚本语言可能是最简单的方法。Perl 中的示例:
use File::Find;
use Cwd;
# get working directory for script
$cwd1 = getcwd();
# find all tex files recursively, store the path relative to cwd1
find(sub{ push(@allfiles,substr(getcwd(),length($cwd1))."/".$_) if $_=~/tex$/; },'.');
# sort the file list to get the right order
# note: tex files are called 0chapter.tex for sorting purposes
foreach $file(sort @allfiles){
# count the number of underscores minus 2 (/1/0chapter.tex is level 0)
$strlevel = "sub" x (($file =~ tr#/#/#)-2);
# read the file
open(IN,"<$cwd1$file");
chomp(@contents = <IN>);
close(IN);
# print the first line of the file as (subsubsub)section title and the rest as contents
print "\\$strlevel"."section\{$contents[0]\}\n".join("\n",@contents[1..$#contents])."\n";
close(IN);
}
添加某个\newcommand{\subsubsubsection}[1]{\paragraph{#1}\mbox{}\\}
地方,您就设置好了。此脚本的示例输出,使用您的目录结构:
\section{Title of foo}
contents of foo
\section{Title of bar}
contents of bar
\subsection{Title of foobar}
contents of foobar
\subsubsection{Title of foobarbaz}
contents of foobarbaz
\subsubsubsection{Title of foobarbazqux}
contents of foobarbazqux