##背景
前回の記事で\input
を用いてファイル分割をしつつ、さらに\ref,\autoref
を良い感じに (Undefined Labelなどの警告なしに) 振舞わせる、ということをやりました。
その記事を書いたあと、実際に自分の書類にそのファイル分割構造を適用してみたところ、documentclassがamsartである場合、BibTeX関係でどうしても警告が出てしまいました。
というわけで、別の方法でそれも良い感じにしました。
今回の記事はそういう報告です。
##前回のおさらい
前回の記事でやりたかったことは、
- TeXファイルを分割し、さらに個々のファイルはそれぞれコンパイルできるようにする。
- その上、ファイル横断的な
\ref
を「良い感じ」に振舞わせる。
でした。
そのために取った戦略は、親.texの.aux
を子.texで読み込むことで、子.texの中で親PDF内のナンバリングを出力可能にする、というものでした。
###問題点と今回での解決方法
それがなぜBibTeXと相性が悪いかというと、.aux
ファイルにはBibTeXに関する情報が記述されているからです。
BibLaTeXパッケージを使っていない場合は重複するラベルを無視するように調節すれば良いだけなのですが、BibLaTeXパッケージを使っている場合はかなり意味不明な挙動をとりました。
なので、今回は、親のauxを読むという戦略ではなく、
「そもそも別の補助ファイルにlabelの情報だけ書き出すようにしておく」
という戦略で解決を図ります。
##フォルダ構成とファイルの中身
フォルダ構成は以下の通りとします。前回の記事に加えて、bibファイルがあります。bibの中身にはHartshorneだけ書いておきます (私のお気に入りの本です)。
Main
├── MainFile.tex
├── MainFile.aux など
├── Style
│ ├── Test.bib
│ └── Test.sty
└── Sub
├── SubFile.tex
└── SubFile.aux など
MainFile.texとSubFile.texの中身は前回の記事とほとんど同じで、以下のようにします:
\documentclass[uplatex,dvipdfmx]{jsarticle}
%\documentclass{amsart}%%%amsartでもチェックします。
\newcommand{\MainFile}{MainFile}
\input{Style/Test.sty}
\begin{document}
\tableofcontents
\section{Main}\label{section: Main section}
a
\begin{thm}\label{thm: main theorem}
b
\end{thm}
\begin{lem}\label{lem: main lemma}
b
\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},
\cite{Ha}
\printbibliography
\end{document}
\ifcsname MainFile\endcsname\else
\documentclass[uplatex,dvipdfmx]{jsarticle}
%\documentclass{amsart}
\input{../Style/Test.sty}
\begin{document}
\SetTrueSecNumber{section: sub section}
\fi
\section{sub}\label{section: sub section}
i
\begin{thm}
\label{thm: sub theorem}
o
\end{thm}
\begin{lem}\label{lem: sub lemma}
u
\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},
\cite{Ha}
\ifcsname MainFile\endcsname\else
\printbibliography
\end{document}
\fi
前回の記事と違う点は、参照文献 (\cite{Ha}
) と\printbibliography
を記述していることです。
\printbibliography
はbiblatexのコマンドで、参考文献を出力するために書いているものです。これは、SubFile.tex
の場合は、\else ~~~ \fi
で囲まれた\end{document}
の直前の行に記述します (そうしないとMainFile.tex
の方で\printbibliography
がバッティングします)。
Test.sty
の中身にbiblatexの設定を書いておきます(試していませんが、natbibでも大丈夫だと思います)。これは好きに書いて大丈夫だと思います。.bibのパスも書いておきます。上のフォルダ構成で.styの中に.bibの相対パスを記述する場合は、MainFileとSubFileでコンパイル場所が違うことに注意してください。今回は以下のような.styからはじめて、ここに欲望を実現するためのマクロを書きます:
%TestStyle.TeX
\usepackage[backend=biber,style=alphabetic,sorting=ynt]{biblatex}
\makeatletter
\newcommand{\My@BibPath}{%
\ifcsname MainFile\endcsname%
Style/TestBib.bib%
\else%
../Style/TestBib.bib%
\fi%
}
\addbibresource{\My@BibPath}
\makeatother
\usepackage[pdftex]{graphicx}
\usepackage{hyperref}
\usepackage{aliascnt}
\hypersetup{
colorlinks=true,
citecolor=blue,
linkcolor=blue,
urlcolor=blue,
}
\usepackage{amsthm}
\theoremstyle{definition}
\newtheorem{thm}{Theorem}[section]
\newaliascnt{lem}{thm}
\newtheorem{lem}[lem]{Lemma}
\aliascntresetthe{lem}
\renewcommand{\sectionautorefname}{Section}
\newcommand{\thmautorefname}{Theorem}
\newcommand{\lemautorefname}{Lemma}
\usepackage{letltxmacro}
\makeatletter
\newcommand{\Test@FirstGroup}[5]{#1}
\newcommand{\Test@FourthGroup}[5]{#4}
\newcommand{\Test@NumberingPrint}[1]{%
\expandafter\Test@FirstGroup%
\romannumeral-`0\csname r@MainFile: #1\endcsname%
}
\def\Test@@NamingPrint#1.{%
\csname #1autorefname\endcsname\space%
}
\newcommand{\Test@NamingPrint}[1]{%
\expandafter\Test@@NamingPrint%
\romannumeral-`0\expandafter\Test@FourthGroup%
\romannumeral-`0\csname r@MainFile: #1\endcsname%
}
\AtBeginDocument{%
\LetLtxMacro{\Test@LetAutoref}{\autoref}
\LetLtxMacro{\Test@LetRef}{\ref}
\newcommand{\Test@SubFile@TrueRef}[1]{%
\ifcsname r@SubFile: #1\endcsname%
\Test@LetRef{SubFile: #1}%
\else%
\textcolor{magenta}{\Test@NumberingPrint{#1}}%
\fi%
}
\newcommand{\Test@TrueRef}[1]{%
\ifcsname MainFile\endcsname%
\Test@LetRef{MainFile: #1}%
\else%
\Test@SubFile@TrueRef{#1}%
\fi%
}
\newcommand{\Test@SubFile@TrueAutoref}[1]{%
\ifcsname r@SubFile: #1\endcsname%
\Test@LetAutoref{SubFile: #1}%
\else%
\textcolor{magenta}{\Test@NamingPrint{#1}}%
\fi%
}
\newcommand{\Test@TrueAutoref}[1]{%
\ifcsname MainFile\endcsname%
\Test@LetAutoref{MainFile: #1}%
\else%
\Test@SubFile@TrueAutoref{#1}%
\fi%
}
\renewcommand{\autoref}[1]{\Test@TrueAutoref{#1}}
\renewcommand{\ref}[1]{\Test@TrueRef{#1}}
}
\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}
}
ここまでで前回の記事と違うのは、
- biblatexに関する記述があること (一番最初の部分です)と、
-
\label
に関する再定義を (まだ) 書いていないこと、
の2点です。
1つ目はちゃんと設定してればなんでも良いです。
\label
に関する再定義を前回とは違う感じにして、欲望を実現します。
##やったこと
\label
に関する以下の再定義を.styに書き込みます:
\newwrite\Test@Label@Aux\relax%%%%%新しい「書き込み用コマンド」
\newcommand{\Test@Label@Aux@Write}[1]{%
\protected@write\Test@Label@Aux{}{%%%%ここは\immediate\writeではなく\protected@writeにしておかないとeqrefの振る舞いがおかしくなります。
\string\newlabel{#1}{{\@currentlabel}{\thepage}{\@currentlabelname}{\@currentHref}{}}%
}%%%%文字として書き出す
}
\AtBeginDocument{
\LetLtxMacro{\Test@LetLabel}{\label}%%%%\labelをコピー
\newcommand{\Test@TrueLabel}[1]{%
\ifcsname MainFile\endcsname%
\Test@LetLabel{MainFile: #1}
\Test@Label@Aux@Write{MainFile: #1}%%%%%MainFileコンパイル時は.myauxに定理番号などの情報を書き出すようにします。
\else%
\Test@LetLabel{SubFile: #1}%
\fi%
}
\renewcommand{\label}[1]{\Test@TrueLabel{#1}}%%%%再定義
\renewcommand{\ltx@label}[1]{\Test@TrueLabel{#1}}%%%%再定義、これはeqrefの方を良い感じにするための再定義です。
}
\ifcsname MainFile\endcsname%
\immediate\openout\Test@Label@Aux\jobname.myaux\relax%%%%拡張子.myauxで新しいファイルを作る。
\immediate\write\Test@Label@Aux{\relax}%%%%.myauxに\relaxと書く。
\else%
\@input{../MainFile.myaux}%%%%SubFileコンパイル時に、定理番号などの情報が書かれた.myauxをinputします。
\fi
\makeatother
これらをコンパイルすると以下のようになります。
まずはdocumentclassがjsarticleでuplatexによるコンパイルをした場合:
次にdocumentclassがamsartでpdflatexによるコンパイルをした場合:
ちゃんと良い感じになっていてかなり満足しました。
magenta色は綺麗で良いですね。