参照をいい感じにしつつTeXファイル分割

##背景

* TeXファイルが長くなったので節ごとに分割したい(します)。
* 節ごとのTeXファイルはそれぞれごとにコンパイルできてほしい。
* ```\autoref```とかもいい感じに振る舞ってほしい。

上二つを実現する方法としては[subfilesを使う方法](https://qiita.com/sankichi92/items/1e113fcf6cc045eb64f7)がありますが、リンク先の記事でも言及されている通り、あまり3つ目の欲望が満たせそうにないので、今回は[「仕掛け」を用いる方法](https://qiita.com/wtsnjp/items/6ba3b8e12514d8a3bd41)を使います。
この記事は、上記の欲望が達成されたような気がする、という報告です。
→[GitHubへ](https://github.com/yujitomo/Problems-And-TeX-Test/tree/master/%E3%83%86%E3%82%B9%E3%83%88/%E3%83%95%E3%82%A1%E3%82%A4%E3%83%AB%E5%88%86%E5%89%B2%E3%83%86%E3%82%B9%E3%83%88/MainFIle)

##フォルダ構成
フォルダ構成は以下の通りとします：

```PlainText:フォルダ構造
Main
├── MainFile.tex
├── MainFile.aux など
├── Style
│   └── Test.sty
└── Sub
    ├── SubFile.tex
    └── SubFile.aux など
```
SubFile.tex は例えば「Section 5に対応するファイル」のような感じで、
MainFile.tex はなんか全部inputされてる感じのやつを想定してます。

###中身
中身は以下の通りであるとします ([「仕掛け」の記事](https://qiita.com/wtsnjp/items/6ba3b8e12514d8a3bd41)で紹介されている「仕掛け」が施してあります)。

```latex:MainFile.tex
\newcommand{\MainFile}{MainFile}
\documentclass[uplatex,dvipdfmx]{jsarticle}
\input{Style/Test.sty}
\begin{document}
\section{親ファイル}\label{section: Main section}
あ
\begin{thm}\label{thm: main theorem}
  え？
\end{thm}
\begin{lem}\label{lem: main lemma}
  え？
\end{lem}

\input{Sub/SubFile.tex}

\autoref{section: Main section},\autoref{section: sub section},
\autoref{thm: main theorem},\autoref{thm: sub theorem},
\autoref{lem: main lemma},\autoref{lem: sub lemma},
\ref{section: Main section},\ref{section: sub section},
\ref{thm: main theorem},\ref{thm: sub theorem},
\ref{lem: main lemma},\ref{lem: sub lemma},

\end{document}
```
```latex:Sub/SubFile.tex
\ifcsname MainFile\endcsname\else
\documentclass[uplatex,dvipdfmx]{jsarticle}
\input{../Style/Test.sty}
\begin{document}
\fi

\SetTrueSecNumber{section: sub section}
\section{子ファイル}\label{section: sub section}
い
\begin{thm}\label{thm: sub theorem}
  え？
\end{thm}
\begin{lem}\label{lem: sub lemma}
  え？
\end{lem}

\autoref{section: Main section},\autoref{section: sub section},
\autoref{thm: main theorem},\autoref{thm: sub theorem},
\autoref{lem: main lemma},\autoref{lem: sub lemma},
\ref{section: Main section},\ref{section: sub section},
\ref{thm: main theorem},\ref{thm: sub theorem},
\ref{lem: main lemma},\ref{lem: sub lemma},

\ifcsname MainFile\endcsname\else
\end{document}
\fi
```
「仕掛け」の意味は[当該記事](https://qiita.com/wtsnjp/items/6ba3b8e12514d8a3bd41)を参照してください。
この仕掛けによって、MainFile.tex と SubFile.tex はそれぞれごとにコンパイルすることができます (もちろん、Test.sty にめちゃくちゃなことが書いてあったらエラー吐きますが)。
Style ファイルには以下の (上のファイルたちをまともに出力させるための) 事柄が既に書かれているとします (これらの意味については説明しません。ハイパーリンク系は青色にしてます)。

```latex:Style/Test.sty
\usepackage{xcolor}
\usepackage{graphicx}
\usepackage[setpagesize=false]{hyperref}
\usepackage{aliascnt}
\hypersetup{colorlinks=true,citecolor=blue,linkcolor=blue,urlcolor=blue,}

\usepackage{amsthm}
\theoremstyle{definition}
\newtheorem{thm}{定理}[section]
\newaliascnt{lem}{thm}
\newtheorem{lem}[lem]{補題}
\aliascntresetthe{lem}
\renewcommand{\sectionautorefname}{節}
\newcommand{\thmautorefname}{定理}
\newcommand{\lemautorefname}{補題}
```

[Subfilesの記事](https://qiita.com/sankichi92/items/1e113fcf6cc045eb64f7)の最後の方にも書いてある通りですが、このままだと参照とかはあんまりいい感じじゃないです。なので、この.styにいろいろ追記して参照とかをいい感じにしていきます。

##やったこと

* 参照 (```\autoref```とか```\ref```とか) もいい感じにした。

###「いい感じに」の定義

* MainFile.tex では通常通りに出力してほしい。
* MainFile.tex のラベルであって SubFile.tex 内のラベルにないものを SubFile.tex で参照した場合は、MainFile.tex 内での正しいナンバリングが (ハイパーリンクなしで) 印字されてほしい。

これらを実現するために、```\label```と```\ref```と```\autoref```を再定義します。

##再定義
.sty ファイルに (```\usepackage{hyperref}```よりも後に) 以下を書き込みます(コメントは直前に行った作業の説明です)：

```latex:Style/Test.sty

\usepackage{letltxmacro}%monkey patch
\makeatletter
\newcommand{\Test@FirstGroup}[5]{#1}%5個のうちの1番目
\newcommand{\Test@FourthGroup}[5]{#4}%5個のうちの4番目

\newcommand{\Test@NumberingPrint}[1]{%
 \expandafter\Test@FirstGroup%
 \romannumeral-`0\csname r@MainFile: #1\endcsname%
}%%ラベルに対してそのラベルが振られているものの番号(3.5とか)を文字列として返す

\def\Test@@NamingPrint#1.{%
  \csname #1autorefname\endcsname%
}
\newcommand{\Test@NamingPrint}[1]{%
  \expandafter\Test@@NamingPrint%
  \romannumeral-`0\expandafter\Test@FourthGroup%
  \romannumeral-`0\csname r@MainFile: #1\endcsname%
}%%ラベルに対して「定理3.5」や「補題1.9」や「節6」などを文字列として返す


\AtBeginDocument{%%hyperrefよりあとから書き換えるためにAtBeginDocumentする

  \LetLtxMacro{\Test@LetLabel}{\label}%labelをコピー(letのようなもの)
  \newcommand{\Test@TrueLabel}[1]{%
    \ifcsname MainFile\endcsname%
    \Test@LetLabel{MainFile: #1}\else%
    \Test@LetLabel{SubFile: #1}\fi%
  }%コンパイル場所によってlabelの振る舞いを変える
  \renewcommand{\label}[1]{\Test@TrueLabel{#1}}%label再定義


  \LetLtxMacro{\Test@LetRef}{\ref}%refをコピー
  \newcommand{\Test@SubFile@TrueRef}[1]{%
    \ifcsname r@SubFile: #1\endcsname%
    \Test@LetRef{SubFile: #1}\else%
    \textcolor{magenta}{\Test@NumberingPrint{#1}}\fi%
  }%SubFileでのrefの振る舞い
  \newcommand{\Test@TrueRef}[1]{%
    \ifcsname MainFile\endcsname%
    \Test@LetRef{MainFile: #1}\else%
    \Test@SubFile@TrueRef{#1}\fi%
  }%コンパイル場所によってrefの振る舞いを変える
  \renewcommand{\ref}[1]{\Test@TrueRef{#1}}%ref再定義

  
  \LetLtxMacro{\Test@LetAutoref}{\autoref}%autorefをコピー
  \newcommand{\Test@SubFile@TrueAutoref}[1]{%
    \ifcsname r@SubFile: #1\endcsname%
    \Test@LetAutoref{SubFile: #1}\else%
    \textcolor{magenta}{\Test@NamingPrint{#1}}\fi%
  }%SubFileでのautorefの振る舞い
  \newcommand{\Test@TrueAutoref}[1]{%
    \ifcsname MainFile\endcsname%
    \Test@LetAutoref{MainFile: #1}\else%
    \Test@SubFile@TrueAutoref{#1}\fi%
  }%コンパイル場所によってautorefの振る舞いを変える
  \renewcommand{\autoref}[1]{\Test@TrueAutoref{#1}}%autoref再定義
}

%Sectionのラベルに対してMainFile内でのその節の番号を返す
\newcommand{\SetTrueSecNumber}[1]{%
  \expandafter\newcount\csname Count@#1\endcsname
  \csname Count@#1\endcsname=\Test@NumberingPrint{#1}
  \expandafter\advance\csname Count@#1\endcsname by -1
  \setcounter{section}{\csname Count@#1\endcsname}
}

%MainFileの.auxをinput
\ifcsname MainFile\endcsname\else%
\input{../MainFile.aux}\fi
\makeatother
```

コンパイルすると、
![スクリーンショット 2021-02-13 2.31.05.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1104388/b8c83af0-afa3-04c1-bddf-eb44bac14fe9.png)
このようになります。
SubFile の magenta 色の部分は MainFile のラベルであり、SubFile ではただ色がついて印字されているだけになります。
青色はちゃんとクリックすると該当箇所へと飛びます。

これで期待通りの出力が得られた！
と思ったのですが、節番号がおかしいですね。
SubFile.tex の中の```\section{子ファイル}```の直前の1行をコメントアウトしてから、
SubFile.tex を保存
→ MainFile.tex をコンパイル
→ コメントアウトをもとにもどして SubFile.tex をコンパイル
とします。すると
![スクリーンショット 2021-02-13 2.35.47.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1104388/896980d3-2a70-2f24-bf0b-3beed15ef060.png)
となり、節番号もちゃんとします。

嬉しいです。

後日、機会 (や要望) があれば、このTest.styの中身について詳しく説明します。

##発展
* 3層にする場合も同様です。SubFile の方で```\SubFile```というコマンドを定義して、適当に条件分岐を増やせば良いだけです。(cf. [GitHub](https://github.com/yujitomo/Problems-And-TeX-Test/tree/master/%E3%83%86%E3%82%B9%E3%83%88/%E3%83%95%E3%82%A1%E3%82%A4%E3%83%AB%E5%88%86%E5%89%B2%E3%83%86%E3%82%B9%E3%83%88/3%E5%B1%A4%E6%A7%8B%E9%80%A0))。
* enumerate に対するラベルでも同様の振る舞いをします。
* このままだと```\eqref```はうまく振る舞いません。理由ですが、amsmath が行う数式環境内でのラベルの記録は、通常のラベルづけのコマンド```\label```をコピーした```\ltx@label```というものが行っているからです。なので、上の```\label```の再定義を用いて```\renewcommand{\ltx@label}{\label}```としてやる必要があります。これだけ書いていればあとはいい感じになってくれます。(cf. [GitHub](https://github.com/yujitomo/Problems-And-TeX-Test/tree/master/%E3%83%86%E3%82%B9%E3%83%88/%E3%83%95%E3%82%A1%E3%82%A4%E3%83%AB%E5%88%86%E5%89%B2%E3%83%86%E3%82%B9%E3%83%88/3%E5%B1%A4%E6%A7%8B%E9%80%A0))。

##参考記事
[効率的な LaTeX ファイル分割術](https://qiita.com/wtsnjp/items/6ba3b8e12514d8a3bd41)
[分割した LaTeX ファイルを subfiles を使ってコンパイルする](https://qiita.com/sankichi92/items/1e113fcf6cc045eb64f7)