texjporg / platex

pLaTeX community edition
BSD 3-Clause "New" or "Revised" License
49 stars 8 forks source link

縦書き時のfigure内に\yokoでエラー #95

Closed abenori closed 1 year ago

abenori commented 3 years ago

https://github.com/abenori/jlreq/issues/65#issuecomment-753298913 からの転送です.以下でエラーが出ます.

\documentclass{article}
\begin{document}
\tate
% \yoko  % ここだとエラーにならない
\begin{figure}
  \yoko  % ここだとエラーになる
  a
\end{figure}
\end{document}
! Output loop---100 consecutive dead cycles.
\clearpage ...rite \m@ne {}\vbox {}\penalty -\@Mi 

l.10 \end{document}
aminophen commented 3 years ago

(自分のコメントもコピー)

エラーの発端は \@testwrongwidth が誤判定していることのようです。組方向が食い違っているせいか \dp の取得が正しくならず,double column float -- wrong になっている?


この場合に仮に対応するとしたら,どのような出力を期待すればいいでしょうか。(figure 環境内で \caption を発行した場合,そのキャプションの組方向はどうなることが期待されるか?)

ghost commented 3 years ago

縦書き中に横書きで図表キャプションを挿入することは、手元の書籍を見る限り、よくあるユースケースに思います。 ですので、外の環境によらずに、

となると使いやすくて嬉しいです。 ただ、キャプションだけ組方向を変えたいケースの指定方法はあまり考慮できてないです。

aminophen commented 3 years ago

縦書き中に横書きで図表キャプションを挿入することは、手元の書籍を見る限り、よくあるユースケースに思います。

それは分かります。そして,そのようなケースには pLaTeX の当初の開発元であるアスキーによる plext パッケージの \layoutcaption という命令書式が使えます。実際にこの命令の使いかたを紹介している本は

くらいしかありませんし,ごく最近までバグがあったことも記憶に新しいです (forum:2506, #76)。そのような命令があるのに,わざわざフロート環境の中で \yoko とか \tate を自分で書かないといけない状況が起きるのかどうかが疑問です。(\layoutcaption の機能があまりにも無名であることが原因かもしれませんが。)

仮に「縦書きでキャプションだけ横書きにしたい」と思って下のソースを書いたとします。(現在は Output loop のエラーになります。)

\documentclass{tarticle}
\begin{document}
縦書きの文章。

\begin{table}
\yoko
\caption{せつめいぶん}
表が入る
\end{table}

\end{document}

この出力結果をどうすべきでしょう?

逆もしかりで,横書きで \tate 実行した場合は,キャプションは右?左? 表全体も縦書きに回転すべき?

aminophen commented 3 years ago

もう少し考えてみましたが,「キャプションの組方向をどうするか・上か下か(右か左か)」よりも「図または表本体ならびにキャプションが一行に収まらず,折返す場合の幅をどうするか」が致命的に難しく思えてきました。前者はエイヤっと決めてしまえば済みますが,後者は技術的に難しいですね。

冒頭の例で「\yoko a」の「a」の代わりに「長い長い長い…文章」が入ると,行末で折返す必要が生じます(そうでないとページからはみ出してしまいます)。

plext パッケージの \layoutcaption / \layoutfloat / \pcaption といった命令群は,この事情を考慮して「キャプションの幅」をユーザが指定する仕様になっています。技術的にそうするほかないのだと思います。

以上のことから,以下の処理ではどうでしょうか?

ghost commented 2 years ago

\layoutcaption といった命令があることを知りませんでした。\layoutcaption らによって手元の問題も解決しました。 たしかにユーザーが指定する必要がありますね。エラーの原因も特定されやすくなるので、私も書かれた解決案がよいと思います。

aminophen commented 1 year ago

エラーメッセージを改良して,plext パッケージの \layoutfloat 命令を使うよう誘導する。

大変遅くなりましたが,こんな感じでどうでしょうか。\makatletter ... \makeatother が pLaTeX に導入したらいいんじゃないかと思うエラーチェックコードです。

\documentclass{article}

\makeatletter %%%%%

% patch ltfloat.dtx
%  \begin{macro}{\@floatboxreset}
%    \begin{macrocode}
\def\@floatboxreset{%
      \pltx@save@float@dir  % pLaTeX
      \reset@font
      \normalsize
      \@setminipage
}
%    \end{macrocode}
%  \end{macro}
%
% \begin{macro}{\@endfloatbox}
%    \begin{macrocode}
\def\@endfloatbox{%
      \par\vskip\z@skip      %% \par\vskip\z@ added 15 Dec 87
      \@minipagefalse
      \outer@nobreak
      \pltx@check@float@dir  % pLaTeX
    \egroup                  %% end of vbox
  \color@endbox
}
%    \end{macrocode}
% \end{macro}

% additions
\def\pltx@save@float@dir{%
  \edef\pltx@float@dir@first{\iftdir\tate\else\yoko\fi}}
\def\pltx@check@float@dir{%
  \edef\pltx@float@dir@last{\iftdir\tate\else\yoko\fi}%
  \ifx\pltx@float@dir@last\pltx@float@dir@first\else
    \pltx@err@float@dir
  \fi}
\def\pltx@err@float@dir{%
  \@latex@error{Direction change inside float!?\MessageBreak
    Use \noexpand\layoutcaption provided in
    \string\usepackage{plext}}\@ehc
}
%

\makeatother %%%%%

\maxdeadcycles3

\begin{document}

\tate
% \yoko  % ここだとエラーにならない
\begin{figure}
  \yoko  % ここだとエラーになる
  a
\end{figure}

%\tracingall

\end{document}
aminophen commented 1 year ago

https://github.com/texjporg/platex/commit/1657d588e0d5ef281d5d2099abe71af308e7a0a4 で上のコードを入れました。

kojiOnHill commented 1 year ago

1657d58の導入以前には、\marginpar{}を使った、下記のLaTeXコードは問題なくpLaTeXでコンパイルできていたのですが、導入後

 ! LaTeX Error: Direction change inside float!?
Use \layoutcaption provided in \usepackage{plext}.

というエラーが出るようになりました。エラー表示だとコードを処理するインタフェースによっては、処理が止まってしまうので、Warningにとどめる等できないでしょうか。

\documentclass{article}
\begin{document}
Main text.
\marginpar{This is marginpar.}
\end{document}
h20y6m commented 1 year ago

\marginpar のときも \@endfloatbox が実行されるようです。 (\@floatboxreset は実行されないので \pltx@float@dir@firstundefined

とりあえず \pltx@float@dir@firstundefined のときはチェックをスキップすればよい……? (フロートの中に \marginpar は入れない……ですよね?)

\def\pltx@check@float@dir{%
  \ifx\pltx@float@dir@first\@undefined\else
    \edef\pltx@float@dir@last{\iftdir\tate\else\yoko\fi}%
    \ifx\pltx@float@dir@last\pltx@float@dir@first\else
      \pltx@err@float@dir
    \fi
  \fi}
aminophen commented 1 year ago

\marginpar のバグを発生させてすみません。

1657d588e0d5ef281d5d2099abe71af308e7a0a4 の変更が意図しているのは「本件冒頭のコードのような『フロート内で組方向を無理やり変更した場合』にどうせ "! Output loop---100 consecutive dead cycles." という意味不明なエラーを出すくらいなら,先回りして明快なエラーを出してしまおう」ということです(これを Warning にとどめるのはナンセンスです)。その目的で \@endfloatbox を修正したのですが,まさかこの命令が \marginpar からも呼ばれるとは把握していませんでした。


それにしても,リポジトリに置いてある pldoc.pdf を生成するためには .dtx を処理しているわけで,その時にエラーが出なかったのはなぜ?(\begin{macro}...\end{macro} は \marginpar じゃないということ?)

TeXMathSmith commented 1 year ago

\marginparのトラブルの対応の検討ありがとうございます. dtxファイルの\DescribeMacroでも同じ現象が起きています.

TeXMathSmith commented 1 year ago

今更の質問ですが, 縦書きのキャプションは図表の右(か左?)に縦長に配置して, 横書きのキャプションは図表の上や下に横長に配置するものだと思います. \caption コマンドにオプションを付けるか, 変数でオプションを渡すかしないと難しいのではないでしょうか? 100年前の写真には縦1文字の行が横に並んで一見すると右から横に書いたかのように見える広告がありますが, こういう解釈を若い人に言うと軽蔑の笑みで見られてしまいます. 数えきれないくらい経験していますが, 昔の写真の解説なので, 昔の人の考え方で私の考え方ではないと力説して逃げていますが「そういうことですか」という言葉がくるだけで笑みは消えません. 1文字の行を並べるテクニックの解説はしたくありません.

aminophen commented 1 year ago

今更の質問ですが〜\caption コマンドにオプションを付けるか, 変数でオプションを渡すかしないと難しい

はい,そのとおりです。ですから #95 の冒頭の「縦書き時の figure 内に \yoko でエラーになる」に対してはこのコメントで書いたとおり「そのような使い方はサポートしない。エラーメッセージを改良して,plext パッケージの \layoutfloat 命令を使うよう誘導する」と回答しています。\layoutfloat / \layoutcaption / \pcaption といった命令群にはそのような組方向オプションの機能が(pLaTeX の開発元であるアスキーによって相当昔から)実装されています。

aminophen commented 1 year ago

さて \marginpar でエラーが出るのと \DescribeMacro でエラーが出るのは同根です(まさか \@endfloatbox というフロート専用っぽい名前の命令が \marginpar からも呼ばれるとは把握できなかった私のミス)。脱線話は止めて,これを修正する方に取り掛かりましょう。

https://github.com/texjporg/platex/issues/95#issuecomment-1443784872 の @h20y6m さんのコードで一応大丈夫そうな感じがしますが,\DescribeMacro がエラーになるのに \begin{macro}〜\end{macro} がエラーになっていなかった(どちらも \marginpar みたいな見出しが出るのに)のが腑に落ちていません。

TeXMathSmith commented 1 year ago

丁寧に教えていただきありがとうございます.

dtxファイルの例を作りました. DescribeEnvも同様ですので入れておきました. ^^Aが3ヶ所ありますので, 消すと症状を再現することができます. macrocodeの横の数字はその行の横から逃げないのでfloatではなく, \DescribeMacroの方は同じ行に複数書くと, reference point の行から逃げていって別の場所に表示されますので, float的かどうかに差があるのだと思います.

%\iffalse
%<package>\NeedsTeXFormat{LaTeX2e}[2020/10/01]
%<*driver>
\documentclass{ltxdoc}
    \setcounter{StandardModuleDepth}{1}
\begin{document}
    \let\pkg\packagename
    \DocInput{test.dtx}
    \PrintIndex
    \PrintChanges
\end{document}
%</driver>
%\fi
%\title{Test Float and \texttt{plext}}
%\maketitle
%The environment 
%^^A\DescribeEnv{macrocode}
%^^A\DescribeMacro{\begin\{macrocode\}}
%^^A\DescribeMacro{\end\{macrocode\}}
%"macrocode" enclosed by
\verb+\begin{macrocode}+ and \verb+\end{macrocode}+ lists code lines.
%
% \MaybeStop{}
%\iffalse
%<*package>
%\fi
%    \begin{macrocode}
The environment "macrocode" displays the code-lines of the sty-file.
%    \end{macrocode}
%\iffalse
%</package>
%\fi
% \Finale
% \endinput
aminophen commented 1 year ago

dtxファイルの例を作りました.

ありがとうございます。

macrocodeの横の数字はその行の横から逃げないのでfloatではなく,

私が気にしているのは \begin{macrocode}...\end{macrocode} ではなく \begin{macro}{\命令}...\end{macro} です。後者と \DescribeMacro の挙動はよく似ていると思うのですが。

h20y6m commented 1 year ago

\begin{macro}...\end{macro} は \marginpar じゃないということ?

macro 環境はリスト(\trivlist)で実装されているみたいです。 (そして左のあれはラベル)

aminophen commented 1 year ago

macro 環境はリスト (\trivlist)

ありがとうございます。

フロートの中に \marginpar は入れない……ですよね?

\documentclass{article}
\begin{document}
\begin{figure}
  a
  \marginpar{This is marginpar.}
\end{figure}
\end{document}
! LaTeX Error: Float(s) lost.

なので「フロートの中に \marginpar は入れない」だと思います。

よって a24eeabe1f2c49734947ab414aabe8717fb7ea80 で修正を取り込みました。

h20y6m commented 1 year ago

@aminophen \plIncludeInRelease の引数が足りません。 https://github.com/texjporg/platex/blob/a24eeabe1f2c49734947ab414aabe8717fb7ea80/plcore.dtx#L1760

aminophen commented 1 year ago

\plIncludeInRelease の引数

a68aab4c2f725faca2886f22c2eeb65daac5372c で直しました。ありがとうございます。

aminophen commented 1 year ago

https://okumuralab.org/tex/mod/forum/discuss.php?d=3544 の amsart が \@floatboxreset を上書きしてしまうので組方向変更のチェックが効かなくなるのは,仕方ないとして諦めて良いですかね。

\documentclass{amsart}
\begin{document}
\tate a
\begin{figure}
\yoko a
\end{figure}
\end{document}

% \@floatboxreset\pltx@save@float@dir を追加する処理(\g@addto@macro 等)を例えば \AtBeginDocument 遅らせれば対処できそうですが,platexrelease で巻き戻すのが難しいんですよね。

TeXMathSmith commented 1 year ago

多方面の対応ありがとうございます. \begin{macro} \begin{macrocode} \end{macrocode} \end{macro} の例を作りました. marginparっぽい挙動を出すため, マクロ2個をコンマでまとめることと macro環境をネストすることを一緒にしました. dtxファイルがリジェクトされたので, 拡張子をtxtにしてあります. test.txt

aminophen commented 1 year ago

ありがとうございます。

pLaTeX2e 2023-02-14 +1 を出してバグは解消したはずなので閉じます。

scottkosty commented 1 year ago

https://github.com/texjporg/platex/issues/95#issuecomment-1443701600 で報告された問題を迅速に修正していただきありがとうございます。 これは、LyX 用の日本語ドキュメントの自動テスト中に発生しました。 tlmgr の更新後に 1 つが失敗し始めました。 これは過去に何度も発生しており、アップストリームの LaTeX パッケージの修正には通常数週間かかり、修正後、CTAN にリリースするには通常さらに数週間かかります。 ここでの修正は、私が見た中で最速でした。 私はここでの議論を楽しんだ。 あなたには素晴らしいチームと非常に効果的なコミュニケーションがあります。 いつもお世話になっております!

TeXMathSmith commented 1 year ago

preloaded format の日付が2023.3.1のplatexとuplatexで正常動作を確認しました. ありがとうございます.