texjporg / platex

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

LaTeX Font Warning: Font shape `JT1/mc/m/it' undefined #90

Closed aminophen closed 4 years ago

aminophen commented 4 years ago

LaTeX2e の NFSS が新しくなったのを機に,この警告を消す改良をしても良いのではないかと思ったので issue を立てます。

現象

\documentclass{article}
\begin{document}
{\itshape a}
\end{document}
LaTeX Font Warning: Font shape `JT1/mc/m/it' undefined
(Font)              using `JT1/mc/m/n' instead on input line 4.
LaTeX Font Warning: Font shape `JY1/mc/m/it' undefined
(Font)              using `JY1/mc/m/n' instead on input line 4.

原因は以下のとおり。

過去の経緯

この現象は随分昔から指摘されていて,例えば 2004 年の井上浩一氏のブログにも記述があります。

ノーマルの立体が使われることになるのだから特にこのウォーニングが出て困ることはないのだが、うっとうしいことではある。そして、和文フォントにフォントシェイプを独自に定義してそれに変更していたとすると、\itshapeを使うとノーマルの立体に戻ってしまうことになるのである。

この警告を嫌う人は割と多く,警告を抑制するためにプリアンブルに沢山の行を書く人もいるほどです(TeX Wiki にもこの方法が書かれています)。

\DeclareFontShape{JY1}{mc}{m}{it}{<->ssub*mc/m/n}{}
\DeclareFontShape{JY1}{mc}{m}{sl}{<->ssub*mc/m/n}{}
\DeclareFontShape{JY1}{mc}{m}{sc}{<->ssub*mc/m/n}{}
\DeclareFontShape{JY1}{gt}{m}{it}{<->ssub*gt/m/n}{}
\DeclareFontShape{JY1}{gt}{m}{sl}{<->ssub*gt/m/n}{}
\DeclareFontShape{JY1}{mc}{bx}{it}{<->ssub*gt/m/n}{}
\DeclareFontShape{JY1}{mc}{bx}{sl}{<->ssub*gt/m/n}{}
\DeclareFontShape{JT1}{mc}{m}{it}{<->ssub*mc/m/n}{}
\DeclareFontShape{JT1}{mc}{m}{sl}{<->ssub*mc/m/n}{}
\DeclareFontShape{JT1}{mc}{m}{sc}{<->ssub*mc/m/n}{}
\DeclareFontShape{JT1}{gt}{m}{it}{<->ssub*gt/m/n}{}
\DeclareFontShape{JT1}{gt}{m}{sl}{<->ssub*gt/m/n}{}
\DeclareFontShape{JT1}{mc}{bx}{it}{<->ssub*gt/m/n}{}
\DeclareFontShape{JT1}{mc}{bx}{sl}{<->ssub*gt/m/n}{}

提案

前掲の井上氏のブログには,以下のような提案がありました。

もっと根本的な修正も考えてみた。\fontshpae, \romanshapeや\kanjishapeでは、必ずそのフォントシェイプに変更しようとしており、その組み合わせが定義されていない場合はデフォルトのフォントをロードしようとする。そこでその組み合わせが定義されていない場合はフォントシェイプを変更しないようにするというものである。

\def\romanshape#1{\begingroup
  \edef\f@shape{#1}%
  \try@load@fontshape
  \expandafter\ifx\csname\curr@fontshape\endcsname\relax
      \else\xdef\f@shape{#1}\fi
  \endgroup}
\def\kanjishape#1{\begingroup
  \let\f@encoding\k@encoding
  \let\f@family\k@family
  \let\f@series\k@series
  \edef\f@shape{#1}%
  \try@load@fontshape
  \expandafter\ifx\csname\curr@fontshape\endcsname\relax
      \else\xdef\k@shape{#1}\fi
  \endgroup}

これはLaTeXの\fontshapeの動作とは大きく異なるものであり、一般には望ましくないだろうが、根本的な解決にはなる。

私もこれは把握していましたが,個人的には「従来の LaTeX2e の \fontshape の動作とかけ離れるので,今になって pLaTeX2e に入れるのはふさわしくない」と考えていました。

提案

ところが,皆様ご存知のとおり LaTeX2e 2020-02-02 で NFSS に大幅な拡張が入り,\fontshape の挙動が大きく変化しました。具体的には #88 のとおりです。

②シェープの実質的な多軸化

  • \DeclareFontShapeChangeRule{<現シェープ>}{<要求シェープ>}{<新シェープ>}{<代替シェープ>}: シェープ更新規則を宣言する。\DeclareFontSeriesChangeRuleのシェープ版。
  • \fontshape{<要求シェープ>}:【変更】現存のシェープ更新規則の規則に従って、\f@shapeの値を更新する。付帯規則も\fontseriesと同様。

この状況を鑑みると,pLaTeX2e の \fontshape を「直す」なら今だと思います。実際に「pLaTeX2e の新 NFSS 対応コード」を見ると,井上氏の「組み合わせが定義されていない場合はフォントシェイプを変更しない」に近い処理を含めても不自然ではありません。

\def\merge@kanji@shape@#1#2#3\@nil{%
  \def\reserved@a{#3}%
  \ifx\reserved@a\@empty
    % 更新規則がない場合
    \edef\k@shape{#2}% % => 要求シェープそのまま
  \else
    % 更新規則がある場合
    % #1: 更新規則に従う <新シェープ>
    % #2: 更新規則に従う <代替シェープ>
    % #3: ユーザが与えた <要求シェープ>
    \begingroup\let\f@encoding\k@encoding\let\f@family\k@family
      \maybe@load@fontshape\endgroup
    \edef\reserved@a{\k@encoding /\k@family /\k@series/#1}%
     \ifcsname \reserved@a\endcsname
       \edef\k@shape{#1}% % => 新シェープが利用可能ならそれを使う
    \else
       \ifcsname \k@encoding /\k@family /\k@series/#2\endcsname
         \edef\k@shape{#2}% % => 代替シェープが利用可能ならそれを使う;警告
         {\let\curr@fontshape\curr@kfontshape\@font@shape@subst@warning}%
       \else
         \edef\k@shape{#3}% % => どちらも無ければ要求シェープそのまま;警告
         {\let\curr@fontshape\curr@kfontshape\@font@shape@subst@warning}%
       \fi
    \fi
  \fi
}

冒頭のソース例は #3 の「どちらも無ければ要求シェープそのまま;警告」のブロックを通過しており,そこにチェックを追加すれば警告を消せそうです。これだけではまだ動作が不完全で危険なので,もう少し考えます。

aminophen commented 4 years ago

実装案を置いてみました。

基本的にはソース中のコメントに書きましたが,コンセプトは

「\fontshape / \fontshapeforce で和文も欧文も変更されようとした場合に,和文シェープが未定義でも警告しない」

としています(つまり \kanjishape, \kanjishapeforce では従来どおり必要に応じて警告する)。また,紛らわしいかもしれませんが,シリーズが未定義のものを選択する際の警告は消えません。(つまり https://github.com/texjporg/japanese-otf-mirror/issues/7 には影響しない。)

aminophen commented 4 years ago

'nowarn' ブランチで取り入れてみました。

aminophen commented 4 years ago

2020-04-12 を出したので close します。