OTFパッケージの noreplace オプション

OTFパッケージの noreplace オプション

- 上田 完 の投稿
返信数: 9
たまたま独自のスタイルファイルを使用する必要が生じて気付いたのですが、

\documentclass{article}

\usepackage[noreplace]{otf}

\begin{document}

これは OTF パッケージのテストです。

\end{document}

のような内容のテキストを platex で処理しようとすると、以下のようなエラーメッセージが出て処理が中断します。

This is e-pTeX, Version 3.1415926-p3.2-110825-2.3 (utf8.euc) (TeX Live 2012/dev)
 restricted \write18 enabled.
entering extended mode
(./test01.tex
pLaTeX2e <2006/11/10> (based on LaTeX2e <2011/06/27> patch level 0)
Babel <v3.8m> and hyphenation patterns for english, dumylang, nohyphenation, af
rikaans, arabic, basque, bulgarian, catalan, pinyin, croatian, czech, danish, d
utch, ukenglish, usenglishmax, esperanto, estonian, farsi, finnish, french, gal
ician, german, ngerman, swissgerman, hungarian, icelandic, indonesian, interlin
gua, irish, italian, kurmanji, latin, latvian, lithuanian, mongolian, mongolian
lmc, bokmal, nynorsk, polish, portuguese, romanian, russian, serbian, serbianc,
 slovak, slovenian, spanish, swedish, turkish, turkmen, ukrainian, uppersorbian
, welsh, ancientgreek, ibycus, monogreek, greek, coptic, loaded.
(/usr/local/texlive/2011/texmf-dist/tex/latex/base/article.cls
Document Class: article 2007/10/19 v1.4h Standard LaTeX document class
(/usr/local/texlive/2011/texmf-dist/tex/latex/base/size10.clo))
(/usr/local/texlive/2011/texmf-dist/tex/platex/japanese-otf-uptex/otf.sty
! Too many }'s.
l.139 ^^I}
 

たまたま所用で独自のスタイルファイルを使用していてこの現象が発生して、そのスタイルファイル固有の問題かと思ってチェックしていたところ、\documentclass{article} の場合もエラーが出ることを確認した次第です。

 OTF パッケージの各ファイルを精査していないので、まだ自分ではこの現象を確認した、という事以上は何も把握していないのですが、何かご存知の方がおられましたら、ご教示いただければ幸いです。

当方の環境は、Debian / GNU Linux (sid) + TeX Live 2012/dev です。尚、
  • jarticle や jsarticle を使用するとき
  • article でも、noreplace オプションを指定しなかったときや、noreplace を打ち消すオプションを指定したとき
にはエラーが出ないことを確認しています。
上田 完 への返信

Re: OTFパッケージの noreplace オプション

- 匿 名 の投稿
Windows で W32TeX と TeX Live 2011 で試したところ同様のエラーが発生しました.
以下のようにすると回避できるようです.

\documentclass{article}

\makeatletter
\newif\if@enablejfam
\makeatother

\usepackage[noreplace]{otf}

\begin{document}

これは OTF パッケージのテストです。

\end{document}

OTF パッケージはあまり使わないのでよく分かりませんが
jarticle や jsarticle ではこのエラーは発生しないので
おそらく article で使用することは想定されていないのではないでしょうか.
匿 名 への返信

Re: OTFパッケージの noreplace オプション

- 前田 一貴 の投稿
匿名さんのコメントを見てから

Package: otf 2010/03/25 v1.7b1 psitau

を眺めてみましたが,101行目の \if@replace が偽の場合,対応する \else か \fi を探すのですが,
さらに 127行目の \if@enablejfam が未定義である場合は136行目の \fi が対応するものと
みなされて(本当はこれは \if@enablejfam に対応するはずのもの)そこまでのトークンが
全て消え,その直後の137行目の } だけが残って

! Too many }'s

と言われているのだと思われます.

簡略化すると,article で(otf は読み込まなくてもよい)

\makeatletter
\ifx ab
\@ifundefined{if@enablejfam}{}{\if@enablejfam\fi}
\makeatother

と書くと同様のエラーが出ます.一方,

\makeatletter
\ifx ab
\@ifundefined{if@enablejfam}{}{\if@enablejfam\else hoge\fi
\makeatother

だとエラーなしで hoge と出ます.後者を j(s)article でやると

! Incomplete \ifx; all text was ignored after line 6.

のエラーが出ます.そんな感じです.


> おそらく article で使用することは想定されていないのではないでしょうか.

125行目から

\@ifundefined{if@enablejfam}{%if disablejfam option is not available, do nothing.
}{%
\if@enablejfam
...
\fi
}

となっているので,\if@enablejfam が未定義の場合も想定されているのだと思いますが,
実際には未定義だとうまく動かないみたいですね.

# 解決策までは考えてないです.すいません.
前田 一貴 への返信

Re: OTFパッケージの noreplace オプション

- 匿 名 の投稿
>解決策
次のようなところでしょうか.
  \expandafter\ifx\csname if@enablejfam\endcsname\relax\else
      \csname if@enablejfam\endcsname
        \if@compatibility\else
            \DeclareSymbolFont{mincho}{\otf@JYn}{hmc}{m}{n}
            \DeclareSymbolFontAlphabet{\mathmc}{mincho}
            \SetSymbolFont{mincho}{bold}{\otf@JYn}{hmc}{bx}{n}
            \DeclareMathAlphabet{\mathgt}{\otf@JYn}{hgt}{m}{n}
            \SetMathAlphabet{\mathgt}{bold}{\otf@JYn}{hgt}{bx}{n}
            \jfam\symmincho
        \fi
      \csname fi\endcsname
  \fi

# スキップされる部分に含まれる「未定義かもしれない\if...」と
# それに対応する \else,\fi をことごとく \csname ...\endcsname の形にします.
匿 名 への返信

Re: OTFパッケージの noreplace オプション

- 前田 一貴 の投稿
私の前のコメントは,tlptexlive を入れている場合の

Package: otf 2010/03/25 v1.7b1 psitau, u0.09 ttk

とは行数がずれてます.古い otf.sty が残っていて,そちらを参照していたようです.
(CTAN を見た限りだと tlptexlive を入れていなければ合っているかも)


> 匿名さん

解決策ありがとうございます.
試してみると,一見正しく動いているのですが,j(s)article に disablejfam オプションが
ついていて,かつ otf に noreplace がついていないときに

(\end occurred when \iftrue on line 103 was incomplete)

と出ます.\if@enablejfam が偽の時に,\csname fi\endcsname じゃなくて,そのあとの
(\expandafter\ifx\csname if@enablejfam\endcsname\rel に対応する)\fiと対応して
しまって,\if@replace が閉じないままで行ってしまっているのではないでしょうか.
結果的には問題ないのですが,何か気持ち悪いです.

\if@replace の直前で \@ifundefined の第3引数の内容を何かのマクロに定義しておいて,
実際の第3引数にはそれを渡すのが安全そうですが,可読性は少し下がりますね.
前田 一貴 への返信

Re: OTFパッケージの noreplace オプション

- Z. R. の投稿

\if@replace の直前で \@ifundefined の第3引数の内容を何かのマクロに定義しておいて,実際の第3引数にはそれを渡すのが安全そうですが,可読性は少し下がりますね.

まとまった処理のブロックをマクロとして括り出すのは、そのマクロが適切に命名されている(\@modify@jfam@setup とか)限りは、可読性を下げることはないと思うのですが……。

括り出しをしないのであれば、私なら次のように書きます。(山本さんのとほとんど同じですが。)

%definitions of alt-normal font family
\@ifundefined{if@enablejfam}{%
    \let\if@jfam@used\iffalse
}{%
    \let\if@jfam@used\if@enablejfam
}
\if@replace
    …………
    \if@jfam@used
        \if@compatibility\else
            \DeclareSymbolFont{mincho}{\otf@JYn}{hmc}{m}{n}
            \DeclareSymbolFontAlphabet{\mathmc}{mincho}
            \SetSymbolFont{mincho}{bold}{\otf@JYn}{hmc}{bx}{n}
            \DeclareMathAlphabet{\mathgt}{\otf@JYn}{hgt}{m}{n}
            \SetMathAlphabet{\mathgt}{bold}{\otf@JYn}{hgt}{bx}{n}
            \jfam\symmincho
        \fi
    \fi
\fi

ただ、これにしても山本さんのコードにしても、「\@ifundefined の第 2・3 引数は TeX の if 文の外で実行される」という性質を使っていることに留意する必要があります。(まあ LaTeX テストは大概はそのように実装されているはずですが。)

Z. R. への返信

Re: OTFパッケージの noreplace オプション

- 前田 一貴 の投稿
山本さん,ZRさん,ありがとうございました.試してみましたがこれで問題なさそうです.
しかし,\if... が定義されていればそれを使ってテストをする,という分岐は自然に書きたく
なるものなので,それがそのまま書けないというのはなかなかの落とし穴ですね.

> まとまった処理のブロックをマクロとして括り出すのは、そのマクロが適切に命名されている(\@modify@jfam@setup とか)限りは、可読性を下げることはないと思うのですが……。
おっと,妙なことを書いていました.その通りです.失礼いたしました.
前田 一貴 への返信

Re: OTFパッケージの noreplace オプション

- 上田 完 の投稿
各位:

詳細なサジェスチョンを頂き有り難うございます。otf.sty で問題になっているルーチンにまでは辿りついていたのですが、対応関係で少々混乱して???となっていたところでした。

Z. R. さんの書かれていたものをそのまま利用して otf.sty を修正したところ、article クラスでも、事の発端だった独自スタイルファイル(これまた独自のフォントメトリックを使っているもので……)の方でも、\UTF{} や \CID{} を使いつつ、フォントメトリックを変えずに出力することができました。どうも有り難うございました。

こちらで修正した otf.sty の diff を添付しておきます。
上田 完 への返信

Re: OTFパッケージの noreplace オプション

- 山本 和義 の投稿
\if... が常に if 文の意味を持てばいいのなら,これでいいような気がします.いや,ちゃんとしたチェックはしていないのですが...

%definitions of alt-normal font family
\let\if@jfam@dummy\iftrue
\@ifundefined{if@enablejfam}{}{\let\if@jfam@dummy\if@enablejfam}
\if@replace
...
\@ifundefined{if@enablejfam}{}%if disablejfam option is not available, do nothing.
  {\if@jfam@dummy\if@compatibility\else
    \DeclareSymbolFont{mincho}{\otf@JYn}{hmc}{m}{n}
    \DeclareSymbolFontAlphabet{\mathmc}{mincho}
    \SetSymbolFont{mincho}{bold}{\otf@JYn}{hmc}{bx}{n}
    \DeclareMathAlphabet{\mathgt}{\otf@JYn}{hgt}{m}{n}
    \SetMathAlphabet{\mathgt}{bold}{\otf@JYn}{hgt}{bx}{n}
    \jfam\symmincho
  \fi\fi}
\fi