kmuto / review

Re:VIEW is flexible document format/conversion system
http://reviewml.org/
GNU Lesser General Public License v2.1
1.34k stars 214 forks source link

TeX: POSTDEFで図表を使うと、直前の採番を引き継いでしまう(frontmatter,backmatter内の\chapterでfigure,tableのカウンタがリセットされない) #1110

Open kmuto opened 6 years ago

kmuto commented 6 years ago

jsbookの不具合ではあるけれども、 \backmatter後の\chapterではfigureやtableなどのカウンタがリセットされない。

CHAPS:
- ch1.re
POSTDEF:
- post1.re
- post2.re

とあったとして、ch1.reで図1.1を使うと、post1は図2になる。さらにpost2は図3になる。 PREDEFも採番連続は同じ問題がある。

munepiさんが作るclsでこういう問題は経験ないので、jsbookの何かがおかしそう。

kmuto commented 6 years ago

jsbookの仕様というかバグというか、だろうか。希望動作になるよう上書きすると……

\renewcommand\frontmatter{%
  \if@openright
    \cleardoublepage
  \else
    \clearpage
  \fi
  \@mainmatterfalse
  \pagenumbering{roman}%
  \setcounter{chapter}{-100}}

\renewcommand\mainmatter{%
    \cleardoublepage
  \@mainmattertrue
  \pagenumbering{arabic}%
  \setcounter{chapter}{0}}

\renewcommand\backmatter{%
  \if@openright
    \cleardoublepage
  \else
    \clearpage
  \fi
  \@mainmatterfalse%
  \setcounter{chapter}{-100}}

\def\@chapter[#1]#2{%
  \ifnum \c@secnumdepth >\m@ne
    \if@mainmatter
      \refstepcounter{chapter}%
      \typeout{\@chapapp\thechapter\@chappos}%
      \addcontentsline{toc}{chapter}%
        {\protect\numberline
        % {\if@english\thechapter\else\@chapapp\thechapter\@chappos\fi}%
        {\@chapapp\thechapter\@chappos}%
        #1}%
    \else\refstepcounter{chapter}\phantomsection\addcontentsline{toc}{chapter}{#1}\fi
  \else
    \addcontentsline{toc}{chapter}{#1}%
  \fi
  \chaptermark{#1}%
  \addtocontents{lof}{\protect\addvspace{10\jsc@mpt}}%
  \addtocontents{lot}{\protect\addvspace{10\jsc@mpt}}%
  \if@twocolumn
    \@topnewpage[\@makechapterhead{#2}]%
  \else
    \@makechapterhead{#2}%
    \@afterheading
  \fi}

書き換えられるポイントが乏しく、jsbook.clsの該当マクロを丸ごと書き換える必要がある。 pagenumberingもここでべったりなのがなかなか辛い…。

munepi commented 6 years ago

某弊社のクラスファイルでは、そこらへん全部hyperref前提でやっていて、全部うまくいくようにしているんです。 しかも \chapter や \section などの「*」を使わないのも某弊社の仕様(工夫!?、特徴!?)で、理由は前付けや後付けの見出したちの目次への出力も完全に自動でやりたいがために、そうしているんです。

なので、すべての処理をマクロ内で完結させて、利用者側は何にもごちゃごちゃと余計な命令(とくにhyperref周り)を書かなくても良いようにしています。 前付けや後付けのカウンター調整も hypetref に対する PDF 内部の参照IDが全部うまくいくようにするための工夫です。

結局…、オープンソース版の grnchrycls(途中)を公開するしかないかなーというところです。

kmuto commented 6 years ago

とりあえずbackmatterにかませればいいので、こういうのでしょうかね。

\let\recls@backmatterorg\backmatter
\renewcommand*{\backmatter}{
  \recls@backmatterorg
  \setcounter{figure}{0}
  \setcounter{table}{0}
}
kmuto commented 6 years ago

chapterでリセットされない問題があるか

munepi commented 6 years ago

少なくとも、 abenori/jlreq upstream 側でこうしてもよいと思います。 仮にupstream 側で何か事情があって、 figure, table カウンタを chapter でリセットしていないのであれば、review-jlreq.cls 側で figure, table カウンタを chapter でリセットするようにすれば良いです。

-\newcounter{figure}
+\newcounter{figure}[chapter]

-\newcounter{table}
+\newcounter{table}[chapter]
munepi commented 6 years ago

↑「章でリセットされない」のはトンチンカンなコメントです。


結局、某弊社のクラスファイルでは、figure, tableカウンタがchapterでリセットされることから、 前付け、後付けの諸々のカウンタがhyperref前提でPDF内部のカウンタ(ID)も含めてうまくいくように、

を意図的に行なっています。

kmuto commented 6 years ago

はい、問題のほうはjsbookですね。 (jlreqのほうはカウントリセットは正しいんですが出力のほうがちょっと問題なので abenori/jlreq/issues/36 で報告済み。)

で、jsbookのほうは…

\documentclass[book,uplatex]{jsbook}

\begin{document}
\frontmatter

\chapter{pre1}
\begin{table}
\caption{Table in Pre1}% 期待は表1
\end{table}

\chapter{pre2}
\begin{table}
\caption{Table in Pre2}% 期待は表1、実際は表2
\end{table}

\mainmatter
\chapter{ch1}
\begin{table}
\caption{Table in Ch1}% 期待は表1.1
\end{table}

\chapter{ch2}
\begin{table}
\caption{Table in Ch2}% 期待は表2.1
\end{table}

\appendix
\chapter{app1}
\begin{table}
\caption{Table in App1}% 期待は表A.1
\end{table}

\chapter{app2}
\begin{table}
\caption{Table in App2}% 期待は表B.1
\end{table}

\backmatter
\chapter{post1}
\begin{table}
\caption{Table in Post1}% 期待は表1、実際は表B.2
\end{table}

\chapter{post2}
\begin{table}
\caption{Table in Post2}% 期待は表1、実際は表B.3
\end{table}
\end{document}

という状況で、frontmatter・mainmatter・backmatterにaddtoでsetcounterを入れて試しているのですが、jsbook.clsで

\def\@chapter[#1]#2{%
  \ifnum \c@secnumdepth >\m@ne
    \if@mainmatter
      \refstepcounter{chapter}% ←これがmainmatterでしか動かないのでif@mainmatter前に動かしたい
      \typeout{\@chapapp\thechapter\@chappos}%
      \addcontentsline{toc}{chapter}%
        {\protect\numberline
        % {\if@english\thechapter\else\@chapapp\thechapter\@chappos\fi}%
        {\@chapapp\thechapter\@chappos}%
        #1}%
    \else\addcontentsline{toc}{chapter}{#1}\fi
  \else
    \addcontentsline{toc}{chapter}{#1}%
  \fi

とrefstepcounterがmainmatterでしか動いてくれない仕掛けになっているのに対してpatchcmdで対処するのがうまくできていません。

とりあえず\tracingpatchesにして

\patchcmd\@chapter%
  {if@mainmatter}{if@frontmatter}%

は通るけど

\patchcmd\@chapter%
  {\if@mainmatter}{\if@frontmatter}%

にするだけでも通らなくなるので、何か私がpatchcmdについて勘違いをしているでしょうか。