1
2

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 3 years have passed since last update.

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

Last updated at Posted at 2021-02-16

##背景
前回の記事\inputを用いてファイル分割をしつつ、さらに\ref,\autorefを良い感じに (Undefined Labelなどの警告なしに) 振舞わせる、ということをやりました。
その記事を書いたあと、実際に自分の書類にそのファイル分割構造を適用してみたところ、documentclassがamsartである場合、BibTeX関係でどうしても警告が出てしまいました。
というわけで、別の方法でそれも良い感じにしました。
今回の記事はそういう報告です。

##前回のおさらい
前回の記事でやりたかったことは、

  1. TeXファイルを分割し、さらに個々のファイルはそれぞれコンパイルできるようにする。
  2. その上、ファイル横断的な\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の中身は前回の記事とほとんど同じで、以下のようにします:

Main/MainFile.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}
Main/Sub/SubFile.tex
\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からはじめて、ここに欲望を実現するためのマクロを書きます:

Main/Style/Test.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}
}

ここまでで前回の記事と違うのは、

  1. biblatexに関する記述があること (一番最初の部分です)と、
  2. \labelに関する再定義を (まだ) 書いていないこと、

の2点です。
1つ目はちゃんと設定してればなんでも良いです。
\labelに関する再定義を前回とは違う感じにして、欲望を実現します。

##やったこと

\label に関する以下の再定義を.styに書き込みます:

Style/Test.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によるコンパイルをした場合:
スクリーンショット 2021-02-16 22.37.52.png

次にdocumentclassがamsartでpdflatexによるコンパイルをした場合:
スクリーンショット 2021-02-16 22.33.31.png

ちゃんと良い感じになっていてかなり満足しました。
magenta色は綺麗で良いですね。

GitHubに全部載せておきますので、.myauxや.auxへの書き出しはこちらを参照ください。

1
2
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
1
2

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?