Acetaminophen’s diary

化学に関すること,TeXに関すること,ゆきだるまに関すること。

コミュニティ版 pLaTeX / upLaTeX 2017/05/05 版の解説 (2)

前回の続きです。

 

3. LaTeX2e 2017-04-15 対応

本家 LaTeX2e が更新されたので、それへの対応です。

3-1. \verbverbatim 環境の修正

「入力したまま」を表示する \verbverbatim 環境に対して、本家 LaTeX カーネル側で修正が入りました。修正内容とは「verbatim な範囲では“絶対に”ハイフネーション行分割が起きないようにする」というものです。

あれ? と思った方、鋭いです。従来も、verbatim な範囲ではハイフネーションが起きないように設計されているはずでした(要するに、たとえページをはみ出してもどこまでも「入力したまま」の内容が横にのびていく)。が、そこには条件があったのです。その条件とは、ざっくり言えば「verbatim に使われるフォントがタイプライタ体のときには」というものでした。

これでは「任意のフォントで verbatim したい」という場合に困ってしまいます(おそらくフォント選択の自由度が高い XeLaTeX や LuaLaTeX では、問題が顕著になると思います)。そこで新しい LaTeX では、verbatim な範囲ではどんなフォントを使っていてもハイフネーションが抑制されるようになっています。

補足:日付表記の変更に関して

なお、platex や uplatex の起動時のバナーを見て気づいた方がいらっしゃるかもしれませんが

LaTeX2e <2017/01/01>

という表示から

LaTeX2e <2017-04-15>

という表示に変わりました。年/月/日 (YYYY/MM/DD) から 年-月-日 (YYYY-MM-DD) に変わったことで、ISO 8601 に準拠したことになります。

従来の YYYY/MM/DD 方式では、地域によって YYYY/DD/MM だったり DD/MM/YYYY だったりとバラバラでした。たとえば 2017/05/04 と書かれていた場合、これが 2017 年 5 月 4 日なのか 2017 年 4 月 5 日なのかわからない…ということが多々ありました。LaTeX2e の日付はこれまで常に YYYY/MM/DD の順になっていましたが、ときどきパッケージ開発者が間違って YYYY/DD/MM と書いてしまうことがあって混乱を起こしていました。

ISO 8601 に規定されたハイフン方式は、地域差なく必ず YYYY-MM-DD を表します。長い歴史のある LaTeX team が日付表記を曖昧さのない方式に切り替えたことは英断だと思います。また、起動時のバナーにそれが現れていますので、アピールの意味合いも大きいと思われます。

pLaTeX の日付はまだ 2017/05/05 のように YYYY/MM/DD のフォーマットを維持していますが*1、近い将来、コミュニティ版 pLaTeX / upLaTeX も、LaTeX team に追随してこれを YYYY-MM-DD に切り替える予定です。

 

4. nidanfloat パッケージのバグ修正

図や表が大きすぎて、二段組の片カラムに入りきれず両カラムにまたがる場合があります。LaTeX は標準では、こうした段抜きフロートをページの top([t] オプション)か、別ページ ([p] オプション)にしか配置することができません。これを bottom([b] オプション)対応にするのが、nidanfloat パッケージです*2

このパッケージには古くからバグがあり、qa:44116qa:51706 で指摘されてきました。「右カラムの処理中に段抜きフロートが出現すると、カラムの高さの計算を間違って本文とフロートが重なる」というバグです。

\documentclass[twocolumn]{article}
\usepackage{nidanfloat}
\usepackage{lipsum}
\begin{document}
\lipsum[1-5]
\begin{table*}[b]
\begin{tabular}{cccccccc}
\hline
AAAAAA & BBBBBB & CCCCCC & DDDDDD & EEEEEE & FFFFFF & GGGGGG & HHHHHH \\
\hline
a & 1.00 & 1.00 & 1.00 & 1.00 & 1.00 & 1.00 & 1.00 \\ 
a & 2.00 & 2.00 & 2.00 & 2.00 & 2.00 & 2.00 & 2.00 \\ 
a & 3.00 & 3.00 & 3.00 & 3.00 & 3.00 & 3.00 & 3.00 \\ 
a & 4.00 & 4.00 & 4.00 & 4.00 & 4.00 & 4.00 & 4.00 \\ 
\hline
\end{tabular}
\end{table*}
\lipsum[1-3]
\end{document}

f:id:acetaminophen:20160311140406p:plain

今回のリリースで、ついにこのバグを修正することが出来ました! 実に 10 年以上の懸案が解消したことになります。

f:id:acetaminophen:20170604115113p:plain

 

5. 目次の中で \ref の直後の半角スペースが消えるバグの修正

ラベル \label の番号や出現したページ番号を取得する「相互参照」機能の \ref\pageref ですが、pLaTeX / upLaTeX ではたとえばセクション \section のタイトルに使うと、目次に出したときに後ろの空白が喰われて消滅するバグがありました。

\documentclass{article}
\begin{document}
\tableofcontents
\section{Question}\label{q1}
\section{Another Question}\label{q2}
\section{Answer for the question in \ref{q1} and \ref{q2}}
\end{document}

f:id:acetaminophen:20170604120409p:plain

新しいバージョンでは修正し、正常に半角スペースが残るようになりました。

f:id:acetaminophen:20170604120425p:plain

補足:一部には \section のような「動く引数」*3では \protect を前置すべきでは? という話がありました。しかし、LaTeX2e の source2e.pdf を見ると「\ref\pageref を robust にした」と書かれています。pLaTeX ではこれが意図せず壊れていたわけですから、LaTeX と合わせるためには robust な実装にしないといけないわけです。

 

6. 出力ルーチンの高さ補正量の誤り修正

これは説明が難しいのですが…大雑把に説明します。従来の pLaTeX で以下の縦組文書を処理した場合、脚注ありのページとなしのページで版面がまるごとずれていました

\documentclass{article}
\documentclass{tarticle}
\begin{document}
脚注がないpage\clearpage
脚注があるpage\par テスト\footnote{あいうpage}\clearpage
\noindent\vrule width\textwidth height\textheight
\end{document}

実際にオーバーレイしてみるとこんな感じでした。

f:id:acetaminophen:20170604122742p:plain

これは、pLaTeX / upLaTeX カーネルの出力ルーチン内で、高さ補正量が正しくなかったためでした。新しい pLaTeX では次のように綺麗に重なります。

f:id:acetaminophen:20170604122801p:plain

 

7. \linebreak を行頭禁則文字直前でも有効化

これは、pTeX 系特有の処理の代表である「禁則処理」が絡む話です。

pTeX のデフォルトでは、行頭禁則文字すなわち「。」や「、」や「!」等の直前では絶対に行分割が起きないような設定がされています。問題となるのは、このpTeX が定義した禁則文字」と「LaTeX が提供する明示的な強制改行命令 \\ または \linebreak」が連続したときの挙動です。

従来の pLaTeX は「pTeX の行頭禁則文字の直前でも \\ という強制改行命令は効く」という対処が施されていました。ところがどういうわけか、\linebreak に対してはそうなっていませんでした。同じ LaTeX レベルの命令なのに、一方は強制改行して一方は改行しない…というのは不自然なので、新しい pLaTeX では「pTeX の行頭禁則文字の直前でも \linebreak という強制改行命令も効く」という仕様にしました。

もっと詳しくpTeX の禁則処理は、ペナルティという概念を流用することで実現されています。現在の pTeX は「通常の TeX のペナルティ (\penalty) の直後に行頭禁則ペナルティ (\prebreakpenalty) が連続する場合、その場で 2 つのペナルティ値を合算する」という挙動を示します。LaTeX\\\(no)linebreak はともに「通常の TeX のペナルティを発行する命令」なので、直後に行頭禁則ペナルティが続くとそこで合算が起き、結果的に強制改行が無効化されてしまいます。pLaTeX ではこれらの命令を改修し、「通常の TeX のペナルティを発行した後に“見えない壁”を置く」ことで、あたかも連続していないかのように pTeX に見せかけて合算を抑制するようにした、と説明できます。

 

8. その他

ほかにもいくつかありますが、些細なバグ修正なので挙げるだけにとどめます。

  • \textundescore を縦組の数式内テキストで使ったときの位置が変だったのを修正
  • plext パッケージの \Kanji{数字} のあとにも数字が続く場合、その数字まで漢数字に変わってしまうもバグを修正
  • plext パッケージによって拡張された \parbox 命令と \pbox 命令(LaTeX\makebox みたいなもの)を robust にした。さらに、\pbox が calc パッケージ(簡単な式による寸法指定が可能に)でエラーにならないように修正

 

未完の最重要案件:plext パッケージ

実は、現在 2017/05/05 の pLaTeX に付属している plext パッケージは未完成な部分が残っています。それは、tabular 環境や \parbox 命令の「組方向オプション」拡張機能を使った場合の位置の問題です。これは現在 pLaTeX レポジトリの issue 24 で議論している最中です。

なぜこれが問題かというと、plext パッケージは 2001 年からその構造はほとんど変わっていません。それにもかかわらず、pTeX のほうは何度も修正を経ています。その結果「plext は変わっていないのに、plext を使った pLaTeX 文書の処理結果が年々変化してしまった」という事情があります。これでは困るので、「最新の pTeX の挙動に即して、plext の仕様を確定させよう」というのが目標です。詳細は GitHub の議論を参照してください。

*1:これはごく一部の LaTeX パッケージが「スラッシュで区切られた日付」を想定して書かれているためです。たとえば stfloats.sty というパッケージは、2016/06/28 v3.2 まで YYYY/MM/DD 書式しか想定していませんでした。このままでは LaTeX2e 2017-04-15 が出た途端に stfloats.sty が全く動かなくなる…という懸念を作者に報告し、対処済みの 2017/03/27 v3.3 をリリースしていただいた、という経緯があります。このようなケースが他にもあるかもしれないので、pLaTeX / upLaTeX はもう少し慎重に様子を見ようとしています。

*2:これと同じような機能を提供するものに dblfloatfix パッケージなどというものがありますが、nidanfloat のほうがフロートを元のページに配置しやすい傾向にあり、dblfloatfix のほうが次のページに送りやすい傾向にあります。

*3:ざっくりいうと、外部ファイル .aux や .toc などに一度書き出されて再度読みこまれるという処理を通るもの。