texjporg / platex

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

和欧文間に \nolinebreak があるとき当該箇所に \xkanjiskip が挿入されない #52

Closed yudai-nkt closed 6 years ago

yudai-nkt commented 7 years ago

以下のコードを pLaTeX + dvipdfmx で処理すると pLaTeX のバージョンによって組版結果が異なります.(2017-04-15 版の pLaTeX が手元になかったので,このバージョンではテストできませんでした)

\documentclass{jsarticle}
\begin{document}
ほげ\nolinebreak foo
\end{document}

pLaTeX2e <2016/11/29> による出力: mwe-16

pLaTeX2e <2017/05/05> による出力: mwe-17

このとおり,新しい pLaTeX では「ほげ」と "foo" の間に \xkanjiskip が入りませんが,旧版のように入るのが正しい結果ではないかと思います.upLaTeX や(texjporg ではないですが)LuaLaTeX + LuaTeX-ja でこれに相当する文書を作成しても同様でした.

なお,

ほげ\nobreak foo\bye

を TeX Live 2017 の plain e-pTeX + dvipdfmx で処理しても \xkanjiskip は挿入されているので,pLaTeX の問題のようです.

yudai-nkt commented 7 years ago

pLaTeX を更新してみましたが,最新版の pLaTeX2e <2017/07/29> でも 2017-05-05 版と同様に \xkanjiskip は入りませんでした.

aminophen commented 7 years ago

報告ありがとうございます。2017/05/05 あたりで,ここと #45 にある理由,すなわち あ\linebreak) のような禁則ペナルティ文字直前で改行できない問題を修正するため,\(no)linebreak の内部マクロの一つに \hskip\z@ を足したためだと思います(pldoc.pdf もご参照ください)。

\xkanjiskip は未考慮だったので後で考えます。

なお,

ほげ\nobreak foo

については,plain e-pTeX のみならず pLaTeX でも同様に \xkanjiskip が入るはずです(ただし禁則ペナルティ前での \break は効かない)。 \(no)linebreak\(no)break の実装思想が違う理由も pldoc.pdf に書いたとおりです。

yudai-nkt commented 7 years ago

GitHub 上の議論だけ追いかけて具体的なコミットや pldoc.pdf を読んでいなかったため,\nobreak\nolinebreak[4] の違いは LaTeX の場合と同様に

のみと思っていました,ありがとうございます.自分の用途だとどちらの処理も不要なのでひとまずは \nobreak を使うことにします.

aminophen commented 7 years ago

対策を考えてみました。合算が起きても起きなくても無害そうなのは「余分な0のペナルティ」?

\makeatletter
\def\@no@lnbk #1[#2]{%
  \ifvmode
    \@nolnerr
  \else
    \@tempskipa\lastskip
    \unskip
    \penalty #1\@getpen{#2}%
    \penalty\z@\relax %% added (2017/05/03)
    \ifdim\@tempskipa>\z@
      \hskip\@tempskipa
      \ignorespaces
    \fi
  \fi}
\makeatother

これは「明示的な(= \penalty プリミティブによる)ペナルティ同士は合算されない」という仕様を利用しています。つまり LaTeX 本来の \penalty #1\@getpen{#2}% というコードが発行するペナルティと、新たに追加した \penalty\z@\relax は合算されません。そして、後続文字に pTeX の前禁則ペナルティがあった場合、これは「0との合算」になるので、実質的に合算を防げていることになります。

これなら、「\linebreak によるペナルティと後続の前禁則ペナルティの合算が起きない」かつ「\xkanjiskip の挿入は正常に行われる」ような気がします。

aminophen commented 7 years ago

修正を入れた platex (pLaTeX2e <2017/07/29>+1) および uplatex (pLaTeX2e <2017/07/29u01>+1) を先程リリースしましたので完了とします。何かあったら reopen してください。

yudai-nkt commented 7 years ago

TeX Live を更新して修正を確認できました.対応ありがとうございます.

okumuralab commented 6 years ago

すみません,理解できていないのですが,

\documentclass{jsarticle}
\begin{document}

ああああああああああ
ああああああああああ
ああああああああああ
ああああああああああ
ああああああああ\nolinebreak ん

\end{document}

でTeX Live 2017では「ん」の前で改行が起こってしまいます。2016では大丈夫です。

aminophen commented 6 years ago

後で確認します。

aminophen commented 6 years ago

多分 \@no@lnbk\penalty\z@\relax を足したせいだと思いますが,これを足した理由は

あ\linebreak )

で改行を起こすためです。悩ましいですが,元に戻したほうが良い?

aminophen commented 6 years ago

\nolinebreak の変更を revert し,pLaTeX2e <2017/10/28>+4 を CTAN upload しました。

okumuralab commented 6 years ago

ありがとうございましたm(__)m