Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[ptex] ページ・数式の組方向 #21

Closed
h-kitagawa opened this issue Aug 30, 2017 · 15 comments
Closed

[ptex] ページ・数式の組方向 #21

h-kitagawa opened this issue Aug 30, 2017 · 15 comments

Comments

@h-kitagawa
Copy link
Member

LuaTeX-ja のチケット #37458, #37467 にも似たようなことを書いていますが,pTeX の組方向変更命令に気になる点があります.以下のソースを用いて説明します.

%%% dir.tex 
\tentgt % 縦組用フォントをゴシックに
\tracingonline1 \showboxdepth100000 \showboxbreadth10000
\yoko あa\par
\tate\showlists かd \par
\dtou$\tate \hbox{しg}$\showlists
bye

pTeX では,組方向は内部リストごとに設定できるようになっており,\yoko, \tate のような組方向変更命令がリストの先頭でしか使えないことはご存知だと思います.

まず,(外部)垂直モードでのリストの状況を調べてみると,tex.web では

@<Set init...@>=
nest_ptr:=0; max_nest_stack:=0;
mode:=vmode; head:=contrib_head; tail:=contrib_head;

と初期化されています.従って,"recent contribution" が空である” ときに組方向変更命令が実行可能ということになります.

上記のソースの具体例で言うと,次のようになります.

  • 最初の段落「あa」は普通に横組で組まれる.
  • 5行目先頭の時点で,recent contribution は空である.従って \tate は実行でき,ページの組方向が縦組になる(\showlists``` で tate direction` と表示されている).2つ目の段落「かd」は縦組で組まれる.
  • 6行目でも同じことが起こり,\dtou でページの組方向が dtou 方向となる.

これはなんとも不思議な挙動で個人的には何らかの処置をしたいと思っていますが,
tarticle などの標準縦組クラスで効果を発揮しているので微妙なところです.
\documentclass{tarticle} の直後で \showlists を実行すると

### yoko direction, vertical mode entered at line 0
### current page:
\write-{}

prevdepth 0.0

となっており,current page は非空だが recent contribution は空なので,その後に組方向を縦組に変更できるというわけです.

長いので,もう一点の気になる点についてはコメントを分けます.

@h-kitagawa
Copy link
Member Author

もう一点,\dtou さ$\tate \hbox{しg}$ についてです.
数式モードの先頭で組方向が設定できるのは「リストが空」という意味では自然ですが,その後の組版結果が不自然(「し」が縦組用フォントで組まれる.dvipdfmx では「さ」に対し 90 度回転)になります.

数式モードから抜ける前のリストを \showlists でみると

### tate direction, math mode entered at line 6
\mathord
.\hbox(4.58221+4.58221)x17.02771, tate direction
..\tentgt し
..\glue(\xkanjiskip) 2.40553 plus 1.0 minus 1.0
..\tenrm g
### dtou direction, horizontal mode entered at line 6
\hbox(0.0+0.0)x20.0
\tenmin さ
spacefactor 1000
(以下略)

となりますが,この数式リストは mlist_to_hlist で水平リストへと変換されて,一つ上の dtou 方向の段落の内容を格納するリストの中に埋め込まれてしまいます.数式から抜けた直後に \showlists すると,次のようになります.

### dtou direction, horizontal mode entered at line 6
\hbox(0.0+0.0)x20.0
\tenmin さ
\mathon
\hbox(4.58221+4.58221)x17.02771, tate direction
.\tentgt し
.\glue(\xkanjiskip) 2.40553 plus 1.0 minus 1.0
.\tenrm g
\mathoff
spacefactor 1000
(略)

つまり,「dtou 方向の段落の中に,縦組の数式が組方向の情報を失い埋め込まれる」わけです.
ディスプレイ数式 $$ ... $$ でも似た症状が起こるようです.

数式モードの内部では \tate 等の組方向変更命令を禁止するようにするのが安全だと思いますが,いかがでしょうか?

@aminophen
Copy link
Member

aminophen commented Aug 30, 2017

一つ目のコメントに対して,雑多なコメントだけ。

確かに不自然な挙動ではあるのですが,tarticle.cls などの改修が必要になることから一旦見送ったのでしたっけ。 forum:1344, forum:1508 ※ forum:1508 の biblatex のエラーは最新では出なくなっている

現在は tarticle.cls がコミュニティ管理になっているので,最悪我々で改修すればそこの問題は回避できますが,他の方々が配っている縦組クラスが動かなくなる可能性がありますよね。

私はまだ全貌が見えていないのでなんとも…

@h-kitagawa
Copy link
Member Author

確かに不自然な挙動ではあるのですが,tarticle.cls などの改修が必要になることから一旦見送ったのでしたっけ。

すでに3年前に forum に書いていたとは.すっかり忘れていました.

\dtou さ$\tate \hbox{しg}$

似たような状況として,非限定水平モードの先頭で \tate を実行する,というのもあります(これも既出かな?).

\tentgt
\noindent\tate かきく\hbox{\dtou あいう}
% \indent だと先頭に \parindent 分のボックスが入ってしまうのでこんなことはできない
\bye

@aminophen
Copy link
Member

(1) current page は非空だが recent contribution は空なので,その後に組方向を縦組に変更できる
(2) 数式モードの内部で \tate 等の組方向変更命令を実行できる
(3) 非限定水平モードの先頭で \tate を実行できる

挙げていただいた不可解な挙動をまとめるとこんな感じでしょうか。個人的には (2) の挙動は特に奇妙に感じ,縦ディレクションと縦数式ディレクションの行き来で不都合が生じなければ改善はアリかなと。

ただ,いずれも「判定が甘い故に不自然な挙動が生じている」とは思いますが,「それが実用の組版機能における致命的な問題を引き起こしている」とは感じていないので,改善が必須とまでは至っていません。一方同時に,上掲の biblatex で一時エラーが出ていたような例から,「判定の甘さをかいくぐれない状況が容易に生じうるデリケートさ」をはらんでいるのは事実で,これはある意味で問題といえるとも思います。

一番の興味としては,「縦組クラスはどう実装するのが安全か」です。pTeX を変えるにせよ変えないにせよ,これは気になる点です。また,現行の多くが \AtBeginDocument している理由もはっきりとは知りません。

@h-kitagawa
Copy link
Member Author

縦組クラス

tarticle, tbook(に限らず,単なる article, book クラスでも)では,クラスファイル読み込み時に \onecolumn または \twocolumn を実行していますが,これらは内部で \clearpage を呼んでいます.ここで,\clearpage 中の次のコードのため,current page に \write に由来する whatsit が追加されることになります.

  \write\m@ne{}%
  \vbox{}%
  \penalty -\@Mi

そのため,もし pTeX を「current page も recent contribution も空のときのみ組方向を変えられる」と仕様変更するとしたら,次のような選択肢が考えられるでしょうか.

  1. \onecolumn 等の前に \tate をおく
  2. プリアンブルにおいてのみ \onecolumn 等で \clearpage を実行しないようにする
  3. プリアンブルにおいてのみ \clearpage\write` を実行しないようにする

LuaTeX-ja の ltjtarticle 等では 1. を(結果的に)取っています.2., 3. は再定義の影響が気になります.
「current page がwhatsit のみからなり,かつ recent contribution が空のときのみ組方向を変えられる」というのは不自然な妥協案?

@h-kitagawa
Copy link
Member Author

「current page がwhatsit のみからなり,かつ recent contribution が空のときのみ組方向を変えられる」というのは不自然な妥協案?

tex.web を見ていたら,「current page が mark と whatsit のみからなる場合に empty となる」変数 page_contents があることに気づきました.これを用いて,外部垂直モードのときは
「page_contents = empty かつ recent contribution が空」のときのみ組方向の変更を許すことにすれば,判定の甘さを解決できると共に,現行の縦組クラスのコードはそのまま動くことになります.

change_direction ブランチで実装してみました.

@aminophen
Copy link
Member

aminophen commented Sep 2, 2017

縦組クラスを改修なしに使えるとのこと,ありがとうございます。

もう一点質問です。非限定水平モードの“穴”が塞がれた場合に

\documentclass{tarticle}
\usepackage[word]{continue}% これは atbegshi 依存
\begin{document}
あ
\newpage\end{document}

を通すにはどうすればよいのでしょうか? 現在の pTeX では,ZR さんが forum:1508 で書いていらっしゃったバッドノウハウが使えて,

\documentclass{tarticle}
\usepackage{atbegshi}% これを先に読んで…
\AtBeginShipout{\par\noindent\yoko}% ここで pTeX の穴を突く
\usepackage[word]{continue}
\begin{document}
あ
\newpage\end{document}

で回避できるっぽいのですが…。(forum:1508 は最新環境では発生しないエラーですが,類似のケースの例として上のソースを挙げてみました。)


追記

上の質問の背景には,forum:2134 のように「縦組クラス + atbegshi」でエラー

! Incompatible direction list can't be unboxed.

が出るときは \AtBeginShipout{\yoko} しておくとうまくいきそう,というのが背景にあります。これはほとんどのケースで有効ですが,うまくいかずエラー

! Use `\yoko' at top of list.

になってしまう例が \usepackage[word]{continue} だったという次第です。

@aminophen
Copy link
Member

aminophen commented Sep 2, 2017

commit bebc228 を Mac 環境でビルドしてみると,eptexdir/eptriptest.test が落ちたのですが,なぜ落ちるのかよく理解できません。再現しますか?

>>> Running e-TRIP test for e-pTeX.
>>> See /Users/aminophen/tex-devel/texlive-svn/Build/source/Work/texk/web2c/../../../texk/web2c/eptexdir/eptrip/eptrip.diffs for example of acceptable diffs.
+ echo '*** TRIP test for e-pTeX in compatibility mode ***.'
*** TRIP test for e-pTeX in compatibility mode ***.
+ ../pltotf /Users/aminophen/tex-devel/texlive-svn/Build/source/Work/texk/web2c/../../../texk/web2c/triptrap/trip.pl trip.tfm
+ ../tftopl ./trip.tfm trip.pl
+ diff /Users/aminophen/tex-devel/texlive-svn/Build/source/Work/texk/web2c/../../../texk/web2c/triptrap/trip.pl trip.pl
+ ln -s /Users/aminophen/tex-devel/texlive-svn/Build/source/Work/texk/web2c/../../../texk/web2c/triptrap/trip.tex .
+ rm -f trip.log
+ ../eptex --progname=epinitex --ini
+ test '!' -s trip.fmt
+ echo '*** trip.fmt not created by trip1.in, investigate!'
*** trip.fmt not created by trip1.in, investigate!
+ exit 1
FAIL eptexdir/eptriptest.test (exit status: 1)

→ cptripin.fot の中に ! You have to increase POOLSIZE. と書かれていたので

eptexdir/eptrip/texmf.cnf の

pool_size       = 36000

を 37000 にちょっと増やしてみるとテストは通りました。

@h-kitagawa
Copy link
Member Author

h-kitagawa commented Sep 2, 2017

pool_size = 36000

pTeX だと 40000 だったので,commit 3762246 でそれに揃えました.

縦組クラス + atbegshi

\AtBegShi@Output の処理を強引に横組でやらせるコードを書いてみました.テキトーに \box0 を使っています.
https://gist.github.com/h-kitagawa/27fb063da4730164fd53042aae8f8b33

@aminophen
Copy link
Member

\AtBegShi@Output の処理を強引に横組でやらせるコード

ありがとうございます。同じコードが luatexja でも動作することも確認できました。

@aminophen
Copy link
Member

よく理解できていない状態で申し訳ないですが,新設の ! Use `\tate' at top of the page. エラーについて,\par の有無でエラーが出たり出なかったりするのは意図的でしょうか?

\documentclass{tarticle}
\usepackage{etoolbox}
\AtEndPreamble{\write16{A}}% これがあるとエラーになる
%\AtEndPreamble{\write16{A}\par}% これに変えるとエラーが出ない
\begin{document}
あいうえお
\end{document}

@aminophen
Copy link
Member

aminophen commented Sep 3, 2017

もう一点、手元の Mac 環境では(すぐ上に書いたソースを tatecls-test.tex として)

aminophen$ platex tatecls-test
This is e-pTeX, Version 3.14159265-p3.7.1-161114-2.6 (utf8.euc) (TeX Live 2018/dev) (preloaded format=platex)
 restricted \write18 enabled.
entering extended mode
(./tatecls-test.tex
pLaTeX2e <2017/07/29>+1 (based on LaTeX2e <2017-04-15>)
Babel <3.12> and hyphenation patterns for 84 language(s) loaded.
… 中略 …
No file tatecls-test.aux.
! Use `\tate' at top of the page.
\@begindocumenthook ...x.pdf for detail}}}{}\tate 
                                                  \message {《縦組モード》}\...
l.5 \begin{document}
                    
? ^Z
[1]+  Stopped                 platex tatecls-test

aminophen$ platex tatecls-test
This is e-pTeX, Version 3.14159265-p3.7.1-161114-2.6 (utf8.euc) (TeX Live 2018/dev) (preloaded format=platex)
 restricted \write18 enabled.
entering extended mode
(./tatecls-test.tex
pLaTeX2e <2017/07/29>+1 (based on LaTeX2e <2017-04-15>)
Babel <3.12> and hyphenation patterns for 84 language(s) loaded.
… 中略 …
(./tatecls-test.aux) 《縦組モード》 [1
A
] (./tatecls-test.aux) )
Output written on tatecls-test.dvi (1 page, 288 bytes).
Transcript written on tatecls-test.log.

のように,「platex 一旦エラーが出た後に Ctrl + Z で強制終了してもう一回 platex を走らせる」とすると,その一回だけコンパイルが通ってしまうようです。初期化不良か何かでしょうか?

@h-kitagawa
Copy link
Member Author

\AtEndPreamble{\write16{A}}% これがあるとエラーになる
%\AtEndPreamble{\write16{A}\par}% これに変えるとエラーが出ない

上 (\par なし) だと,\write16{A} が recent contribution にいる状態となるので,今のコードだとエラーになります.下 (\par あり) では,\par によって page builder が発動され,\write16{A} は current page に移動,recent cont. は空となるので,エラーが出ない,というわけです.

次のコードを仕込んでおくと,\tate 実行直前のリストの状況がわかって便利です.

\makeatletter
\let\orig@tate=\tate
\tracingonline1
\showboxdepth10000
\showboxbreadth10000
\protected\def\tate{\showlists\orig@tate}

「platex 一旦エラーが出た後に Ctrl + Z で強制終了してもう一回 platex を走らせる」

こちらでも再現 (Gentoo Linux, amd64).Ctrl + Z は強制終了ではなく単に休止させているだけ(fg で再開されると思う)ですが,よくわかりません.

@h-kitagawa
Copy link
Member Author

h-kitagawa commented Sep 3, 2017

\AtEndPreamble{\write16{A}}% これがあるとエラーになる
%\AtEndPreamble{\write16{A}\par}% これに変えるとエラーが出ない

ff7fae2 で,recent contributions に hbox, vbox, rule, insertion がない場合も許容することにしました(page_contents = empty なので,先頭の glue, kern, penalty はdiscard される).

9/3 21:59 追記:hbox, vbox が dir_node でラップされている場合の考慮を忘れていたので, 3bb4554 で加えました.

@aminophen
Copy link
Member

上 (\par なし) だと,\write16{A} が recent contribution にいる状態となるので,今のコードだとエラーになります.下 (\par あり) では,\par によって page builder が発動され,\write16{A} は current page に移動,recent cont. は空となるので,エラーが出ない

ああなるほど,難しい… ff7fae2 の方が私は自然な挙動だと思います。

Ctrl + Z は強制終了ではなく単に休止させているだけ

おっと,発見のきっかけが TeXShop とかの「強制終了」ボタンを押したときだったので間違いました。 ff7fae2 だと同じ方法でエラーを起こせないので,とりあえず解決(?)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

2 participants