TeX Alchemist Online

TeX を使って化学のお仕事をしています。

和文ゴーストによる \ruby の改良

追記 (2016/08/16)

本記事で解説した和文ゴーストによる \ruby の改良が,jsclasses 開発版の okumacro パッケージに取り込まれました! github.com

追記 (2016/09/06)

追記(2016/09/06):本記事で解説した \ruby の改修が採用された okumacro パッケージが,jsclasses の一部として TeX Live 2016 のレポジトリに収録されました。本記事で取り上げた問題点は,最新版(2016/08/16版以降)の okumacro パッケージでは既に解決済みとなります。

したがって,以下の本文は,2015年以前の okumacro パッケージの \ruby に関する解説になります。




[改訂第6版]LaTeX2e 美文書作成入門の付録Bには,「パス」の説明があります。

f:id:doraTeX:20160613011823p:plain

よく見ると,さりげなくすごい人名が登場しています。

f:id:doraTeX:20160613011836p:plain

というわけで,()() さんに敬意を表して,今日は pTeX によるルビの話です。

pTeX でのルビの実現方法としては,jsclasses 付属の okumacro パッケージが提供する \ruby が有名です。

ただし,okumacro パッケージの \ruby には,次のような不都合が知られています。

  1. 後ろに \kanjiskip は入るが,前には \kanjiskip が入らない。
  2. 前後に欧文文字が隣接するときに \xkanjiskip が入らない。
  3. 後ろの禁則処理が効かない。

検証サンプル

【ソース】

\documentclass{jsarticle}
\usepackage{okumacro}
\begin{document}
\fboxsep=0pt

\framebox[15zw][s]{私は保毛です。}\par
\framebox[15zw][s]{私は\ruby{保毛}{ほげ}です。}

A保毛B\par
A\ruby{保毛}{ほげ}B

\fbox{\parbox{5zw}{%
私は「保毛」です。\par
私は「\ruby{保毛}{ほげ}」です。}}
\end{document}

【出力結果】

f:id:doraTeX:20160613011459p:plain

和文ゴーストによる改善案

一昨日の記事「和文ゴーストとしての全角スペース」で紹介した pxghost パッケージ を使って,全角スペースでくるめば,これらの問題も解決します。

【ソース】

\documentclass{jsarticle}
\usepackage{okumacro}
\usepackage{pxghost}
\makeatletter
%% okumacro の \ruby を改変して \jghostguarded で囲む
\renewcommand{\ruby}[3][0zw]{%
  \jghostguarded{%
  \dimen1=#1\relax
  \dimen3=\f@size\p@
  \setbox1=\hbox{#2}%
  \setbox3=\hbox{\rubyfamily\fontsize{0.5\dimen3}{0pt}\selectfont #3}%
  \ifdim\dimen1=\z@
    \ifdim\wd1>\wd3 \dimen1=\wd1 \else \dimen1=\wd3 \fi
  \else
    \ifdim\dimen1<\wd1
      \dimen1=\wd1
    \fi
  \fi
  \hbox{%
    \kanjiskip=0pt plus 2fil
    \xkanjiskip=0pt plus 2fil
    \vbox{%
      \hbox to \dimen1{\rubyfamily
        \fontsize{0.5\dimen3}{0pt}\selectfont \kanjistrut
        \ifdim\dimen1<\wd3
          \hss\unhbox3\hss
        \else
          \hfil\unhbox3\hfil
        \fi
      }%
      \nointerlineskip
      \hbox to \dimen1{\kanjistrut\hfil\unhbox1\hfil}}}}}
\makeatother
\begin{document}
\fboxsep=0pt

\framebox[15zw][s]{私は保毛です。}\par
\framebox[15zw][s]{私は\ruby{保毛}{ほげ}です。}

A保毛B\par
A\ruby{保毛}{ほげ}B

\fbox{\parbox{5zw}{%
私は「保毛」です。\par
私は「\ruby{保毛}{ほげ}」です。}}
\end{document}

【出力結果】

f:id:doraTeX:20160613012812p:plain

このように,ルビの親文字の文字間に \kanjiskip が入らないという問題は残っているものの,その他の問題は修正され,ルビがない場合と同様の組版結果が実現できていることが分かります。

pxrubrica パッケージ

pTeX でルビを実現するより高機能なパッケージとして,pxrubrica パッケージ があります。pxrubrica パッケージの使い方は,TeX & LaTeX Advent Calendar 2014 のZRさんの記事に詳しく説明されています。

pxrubica パッケージを使えば,禁則の問題も,親文字の文字間に \kanjiskip が入らないという問題も解決されます。

なお,欧文文字が隣接する場合にデフォルトでは \xkanjiskip の自動挿入はなされませんが,\rubyusejghost を実行しておけばゴースト処理が施され, \xkanjiskip の自動挿入がなされるようになります。

【ソース】

\documentclass{jsarticle}
\usepackage{pxrubrica}
\begin{document}
\fboxsep=0pt

\framebox[15zw][s]{私は保毛です。}\par
\framebox[15zw][s]{私は\ruby{保毛}{ほ|げ}です。}

A保毛B\par
A\ruby{保毛}{ほ|げ}B\par
\rubyusejghost
A\ruby{保毛}{ほ|げ}B

\fbox{\parbox{5zw}{%
私は「保毛」です。\par
私は「\ruby{保毛}{ほ|げ}」です。}}
\end{document}

【出力結果】

f:id:doraTeX:20160613015405p:plain

というわけで,全角スペースによる和文ゴーストは偉大ですね!