本記事の目的
大規模なtex文書をファイル分割することでQOL向上に努めた証の記録。
順を追って解説します。
環境・バージョン
タイプセットはlatexmk (uplatex + dvipdfmx)
コマンドで行います。
最後の方では、vscodeというエディタの拡張機能LaTeX Workshopを用いてタイプセットする方法も書いています。
素朴な方法
分割したtexファイルをsection01.tex
、section02.tex
とします。
これらをmaster.tex
で読み込んで、pdfファイルを作ります。
それぞれのファイルの中身は以下のような感じです。
%% master.tex \documentclass[uplatex,dvipdfmx]{jsarticle} \begin{document} \input{section01.tex} \input{section02.tex} \end{document}
%% section01.tex \section{ひとつめ} ほげほげ
%% section02.tex \section{ふたつめ} ほげほげ2
分割したファイルsection01.tex
とsection02.tex
には、document
環境の中身だけを書きます。
master.tex
ファイル内で\input
コマンドを書いたところに、引数で与えたファイルの内容がそのまま挿入されます。
つまり、master.tex
ファイルをタイプセットすれば、全ての内容を含んだ文書が完成するわけです。
しかし、この方法では、分割したファイルを単体でタイプセットすることができません。
分割したファイルにはdocument
環境の中身しか書いていないので、tex文書としては不完全であるからです。
この不満点は、docmute
パッケージを用いることで解決できます。
docmuteパッケージ
docmute
パッケージを用いると、\input
で分割ファイルを挿入する際に、document
環境内のみを抽出して読み込んでくれます。
(正確には、document
環境を改造して、入れ子になったdocument
環境やプリアンブルを無視するようにしている。)
例えば、次のようにして使います。
%% master.tex \documentclass[uplatex,dvipdfmx]{jsarticle} \usepackage{docmute} \begin{document} \input{section01.tex} \input{section02.tex} \end{document}
%% section01.tex \documentclass[uplatex,dvipdfmx]{jsarticle} \usepackage{docmute} \begin{document} \section{ひとつめ} ほげほげ \end{document}
%% section02.tex \documentclass[uplatex,dvipdfmx]{jsarticle} \usepackage{docmute} \begin{document} \section{ふたつめ} ほげほげ2 \end{document}
このとき、分割したtexファイルは、単体でもタイプセットを行うことができます。
さらに、master.tex
もそのままタイプセットができます。
分割ファイルで、目次や文献の出力を行う
せっかく、分割したファイルを単体でタイプセットできるようになったので、その場で目次や文献の出力の確認も行いたいところです。
いくつか方法は思いつきますが、例えば、シンプルにif文を使って、今タイプセットしているファイルが分割ファイルかmaster.tex
なのか判定して処理しましょう。
プリアンブルは各ファイルで共有したいので、mymacro.sty
ファイルを作って読み込むことにします。
%% ディレクトリ構造 / |- mymacro.sty |- mybib.bib |- master.tex |- section01.tex `- section02.tex
%% mymacro.sty \newif\ifsubfile \newcommand\mokuji{ \ifsubfile \tableofcontents \clearpage \else \relax \fi } \newcommand\bunken{ \ifsubfile \clearpage \bibliographystyle{junsrt} \bibliography{mybib} \else \relax \fi }
%% mybib.bib @book{hoge2022, title = {ほげほげ}, author = {ほげ星人}, year = {2022} }
%% master.tex \documentclass[uplatex,dvipdfmx]{jsarticle} \usepackage{docmute} \usepackage{mymacro} \begin{document} %% 目次 \tableofcontents %% 本文 \input{section01.tex} \input{section02.tex} %% 文献 \bibliographystyle{junsrt} \bibliography{mybib} \end{document}
%% section01.tex \documentclass[uplatex,dvipdfmx]{jsarticle} \usepackage{mymacro} \subfiletrue \begin{document} %% 目次 \mokuji \section{ひとつめ} ほげほげ\cite{hoge2022}. %% 文献 \bunken \end{document}
分割したtexファイルでは\subfiletrue
と書いてあるので、\ifsubfile
がtrue
になります。
master.tex
をタイプセットするときには、それはfalse
なので、\mokuji
と\bunken
は何もしないコマンド(\relax
)になります。
分割ファイルをサブディレクトリに入れる
分割したファイルが多くなってくると、サブディレクトリに格納したくなります。
texファイルなどをサブディレクトリに配置すると、パスの設定をちゃんとしないといけなくなります。
ここでは、以下のようなディレクトリ構造にしてみます:
/ |- .vscode/settings.json |- fonts/ | `- フォントファイル |- sty/ | `- mymacro.sty |- sections/ | |- 01.tex | `- 02.tex |- latexmkrc |- master.tex `- mybib.bib
まず、latexmk
の設定ファイルであるlatexmkrc
ファイルには、以下のように書きます:
#!/usr/bin/env perl ## latexコマンドの共通オプション $latex_options = '-synctex=1 -halt-on-error -file-line-error -interaction=nonstopmode'; if ($^O eq 'MSWin32') { # Windows の場合 $latex = "uplatex %O $latex_options -kanji=utf8 -no-guess-input-enc %P"; } else { # Windows以外のOSの場合(Linux, macOS) $latex = "uplatex %O $latex_options %P"; } $lualatex = "lualatex %O $latex_options %S"; $biber = "biber %O --bblencoding=utf8 -u -U --output_safechars %B"; $bibtex = "pbibtex %O %B"; $makeindex = "upmendex %O -o %D %S"; $dvipdf = "dvipdfmx %O -o %D %S"; ## latexコマンドの最大実行回数 $max_repeat = 5; ## $dvipdfを利用して.dviからPDFを作成 $pdf_mode = 3; ## specifies cleanup mode ## dvi, ps, pdfファイル以外を削除 $cleanup_mode = 2; ## -c optionで消すファイルの拡張子 $clean_ext = "bbl dvi"; ## show CPU time used $show_time = 1; ## パスの設定 - - - - - - - - - - - - - - - - - - - - - ## ルートディレクトリを探して登録 $key_file = 'master.tex'; if (-e $key_file) { $root_dir = '.'; } elsif (-e '../' . $key_file) { $root_dir = '..'; } ## styやfontを探索するパスを追加 if ($root_dir){ $ENV{'TEXINPUTS'} = $root_dir . '/;' . $root_dir . '/sty//;'; $ENV{'OPENTYPEFONTS'} = $root_dir . '/fonts//;'; }
前半部分は好きに書いて下さい。後半部分でパスの設定をしています。
分割したtexファイルの配置場所を変えたので、master.tex
の内容も少し修正します:
%% 修正前 \input{section01.tex} \input{section02.tex} %% 修正後 \input{sections/01.tex} \input{sections/02.tex}
ここで、sections/01.tex
には、上のsection01.tex
の内容をそのままコピペして下さい。02
の方も同じです。
サブディレクトリに配置したtexファイルから見て、bibファイルの相対位置が変わったので、\bunken
マクロを少し修正します。
\newcommand\bunken{ \ifsubfile \clearpage \bibliographystyle{junsrt} %% \bibliography{mybib} % 修正前 \bibliography{../mybib} % 修正後 \else \relax \fi }
他のファイルは、上で作ったそのままで良いです。
master.tex
をタイプセットするには、それと同じディレクトリに移動して
latexmk master.tex
と打ちます。
分割したセクションのtexファイルをタイプセットするには、sections
ディレクトリに移動してから
latexmk -r ../latexmkrc 01.tex
と打ちます。設定ファイルをオプションで直接指定しています(面倒ですが)。
vscodeでタイプセットするには、.vscode/settings.json
に以下の設定を書きます:
{ "latex-workshop.latex.tools": [ { "name": "Latexmk for sub dir", "command": "latexmk", "args": [ "-e", "read_first_rc_file_in_list( '../latexmkrc' );", "%DOC%" ] }, ], "latex-workshop.latex.recipes": [ { "name": "MASTER", "tools": [ "Latexmk for sub dir" ] }, ] }
↑を書いたら、vscodeを再起動します。(作業ディレクトリを開き直す)
そうしたら、master.tex
やsections/01.tex
などを開いて、サイドバーの「TeX」から「Build LaTeX project」の「Recipe: MASTER」をクリックすれば、タイプセットができるはずです。
また、サブディレクトリのsections/
内のtexファイルで、\includegraphics
コマンドなどを使う場合には、挿入する画像や図のファイルのパスは、master.tex
ファイルから見た相対パスを書けばよいです。
以上、説明が冗長な割にクソわかりにくいかと思いますが、とりあえず忘れないうちに記録しておきました。