BXghost: (u)pTeX以外でも適切に和欧文間スペースを入れたい

2019-10-31 (updated: 2025-12-08) #LaTeX

今日はハロウィンですね。というわけでハロウィンとはサッパリまったく関係のない「ゴースト」の話をしたいと思います。

進化したPXghost: BXghost

TL;DR

和欧文間スペース(xkanjiskip)がデフォルトで適切に挿入されない状況下で有用な「ゴースト」の挿入を行うPXghostを拡張し、(u)pTeXに加えてLuaTeXやXeTeXでも利用可能になったBXghostパッケージをリリースしました:

対応TeXエンジンが増えていることを除き、このパッケージの使い方はPXghostとまったく同一です。なおBXghostは日本語組版を行うために開発されたものなので、(u)pTeX以外のエンジンでは日本語組版のために必要なパッケージはユーザの手によって予め適切に読み込まれていることを仮定します1

Warning

本稿は2025年12月の改訂時点の最新版v0.5.1に基づく解説です。その後のバージョンアップにより仕様が変更になっている可能性があります。必要に応じて最新のREADMEも確認してください。

これまでのあらすじ

pTeXで和欧混植を行う場合、特に何もしなくても多くのケースでは和文文字と欧文文字の間には和欧文間スペース(xkanjiskip)が適切に挿入されます。しかし、pTeXの仕様や設定の限界から、本来であれば和欧文間スペースが挿入されて欲しい箇所に、適切にスペースが挿入されない場合があります。

Note — 和欧文間スペース(xkanjiskip)

和欧文間スペースは、よくある日本語組版の設定では四分アキ——いわゆる全角幅の1/4サイズ——です。普通の空白文字(いわゆる半角スペース)を入れてしまうと二分アキが入ってしまいます。これは本来適切な和欧文間スペースよりも2倍も大きなサイズですね。

余談ですが、かつて(La)TeX以外の和欧文間スペースが自動で適切に入らない状況(テキストメモ、Web記事、パワーポイント、etc.)では私も和欧文間スペースが入るべき位置にいちいち空白文字を打ち込んでいました2が、それはそれで「実際にはスペースが開きすぎる」「そもそも意味論的に正しくもない」などのデメリットが多いので、最近は入れないようにしています。和欧文間スペースは原稿そのものを改変してしまうことによってではなく、レイアウトやレンダリングをコントロールする別のレイヤ(CSS)などで解決すべき問題なように思います。

実際、最近のWeb標準ではまさにこの問題に対処するものとしてCSSプロパティtext-autospaceMDN Web Docsのリファレンス)が登場しています。その初期値がどうなるべきかについては、膨大な数の文書が関わり影響範囲が大きいこともあって、複雑な議論があるようですが。

具体例として、次のようなpLaTeX文書を考えます3

%#!platex
\documentclass{jlreq}
\begin{document}
\begin{flushleft}
ワタシハLinuxチョットデキル \\
ディレクトリ\texttt{/usr/}は「ユーザ」じゃない!
\end{flushleft}
\end{document}

これを通常の手順でpLaTeXで処理すると、最終的な出力は次のようになります:

pTeXでうまく和欧文間スペースが入らない例

1行目の“Linux”は普通の英文字列なので問題ないですが、2行目の“/usr/”は始まりと終わりがスラッシュ/記号であるため和欧文間スペースが入っていません。しかし、実際にはここは和欧文間スペースを入れたいところです4

このような場合の対処策として、ZRさんがPXghostというパッケージを開発されました。このパッケージを読み込むと、次の2つの命令が定義されます:

  • \eghostguarded{<text>}:和欧文間スペースの挿入可否判断の際に、<text>が英文文字の列として扱われる
  • \jghostguarded{<text>}:和欧文間スペースの挿入可否判断の際に、<text>が和文文字の列として扱われる

上記の例では/usr/が英文文字の列として扱われなかったために和欧文間スペースが入っていませんでした。そこで、その部分をPXghostの\eghostguarded命令で包んでみます。

【入力】

%#!platex
\documentclass{jlreq}
\usepackage{pxghost}
\begin{document}
\begin{flushleft}
ワタシハLinuxチョットデキル \\
ディレクトリ\eghostguarded{\texttt{/usr/}}は「ユーザ」じゃない!
\end{flushleft}
\end{document}

【出力】

PXghostでうまく和欧文間スペースが入った例

今度はうまく和欧文間スペースが入りました。

このしくみは実はとても単純です。\eghostguarded{<text>}<text>の前後に「欧文ゴースト」すなわち「不可視かつ幅ゼロの欧文文字」5を挿入しています。欧文ゴーストは人の目には見えませんが、TeXはそれを英文文字として認識するため、その前後に和文文字がある場合は和欧文間スペースが挿入されます(前後に和文文字以外のものがある場合は余計なスペースを挿入しません)。

同様に\jghostguarded{<text>}<text>の前後に「和文ゴースト」6を挿入することによって<text>が和文文字の列として振る舞うようにしています。

さらに多くの問題発生例やPXghostの原理・応用については、日本TeX界の有名人たちによって詳細な記事が書かれていますので、未読で興味のある方はぜひ一度読んでみてください:

(u)pTeX以外ではどうなのか

PXghostは単機能ながらとても便利で、個人的にはZR氏の開発するPXシリーズの中ではルビ振りのPXrubricaと並んでお気に入りのパッケージです。しかし、PXghostは接頭辞PX(pTeX extention)が表すとおり(u)pTeX専用のパッケージなので当然他のエンジンでは使用できません。

Note — LaTeXパッケージ名の接頭辞(PX/ZX/BX)

(主に)ZRさん作のLaTeXパッケージ群8は接頭辞を見ると対応パッケージがわかります。基本的にはPXシリーズはpTeX専用、ZXシリーズはXeTeX専用、BXシリーズは基本的にエンジン汎用です(参考)。ただしBXシリーズの個別パッケージがどこまで「汎用」かはものによるので、詳細は個別のパッケージ文書を確認しましょう。もっとも普通の日本語用TeXエンジン——つまり(u)pTeXかLuaTeX——はすべてのBX系パッケージでサポートされているので、これらを使用している限りは問題にならないでしょう。

最近ではLuaTeXを利用して日本語組版を行う機会も増えていますが、そうした(u)pTeX以外のエンジンでは同様の問題は起こらないのでしょうか? さっそく試してみようということで、先ほどの例をbxjsclsを利用するように改変して様々なTeXエンジンで組版できるようにします。

【汎用の入力】

%#!ナンチャラlatex
\documentclass[autodetect-engine,dvi=dvipdfmx,ja=standard]{bxjsarticle}
\begin{document}
\begin{flushleft}
ワタシハLinuxチョットデキル \\
ディレクトリ\texttt{/usr/}は「ユーザ」じゃない!
\end{flushleft}
\end{document}

そして、この文書を実際に様々なTeXエンジンで組版します。なお蛇足ですがllmkというビルドツールを使うと上記ソースのナンチャラlatexの部分をpdflatex, xelatex, lualatex等々に書き換え

$ llmk <file>

とコマンドを叩くだけで指定したTeXエンジンを使用しつつ一発で最終的なPDF出力を得られます。便利ですね。

【LuaTeXの出力】

LuaTeXでうまく和欧文間スペースが入らない例

まずはLuaTeXの出力を確認しています。LuaTeXではbxjsarticleは自動的にLuaTeX-jaを読み込みます。LuaTeX-jaを用いる限りLuaTeXではpTeX系列に匹敵するクオリティの日本語組版が実現できるため、当然“Linux”前後には和欧文間スペースが入っています。一方で“/usr/”前後はpTeXと同じく和欧文間スペースが入っていません。

【XeTeXの出力】

XeTeXでうまく和欧文間スペースが入らない例

XeTeXの日本語組版サポートは、残念ながら現状pTeXやLuaTeXほどには充実しているとは言えませんが、それでもbxjsarticleが自動的に読み込むxeCJK + ZXjatypeのおかげで“Linux”のような通常の英文文字列と和文文字の境界には和欧文間スペースが挿入されます。“/usr/”前後は例によって和欧文間スペースが入っていません。

【pdfTeXの出力】

pdfTeXでうまく和欧文間スペースが入らない例

pdfTeXではどのようなシチュエーションにせよ和欧文間スペースは入りません。pdfTeXについては、そもそも上記のエンジン汎用LaTeXソースがエラーなく通って「それっぽい出力」が得られるという事実が驚異的なのであって、およそマトモな日本語組版は不可能だと思っておいた方がよいでしょう。

以上から、少なくともLuaTeXとXeTeXについては(u)pTeXと同様「和欧文間スペースを挿入する能力があるが、時としてゴーストを用いた調整が必要な場面がある」という状況にあることがわかります。

BXghostの使い方

(u)pTeX以外でもPXghost相当の機能が使えると便利そうということで、PXghostをLuaTeXおよびXeTeXでも利用できるように拡張したBXghostパッケージを作りました。BXghostは(u)pTeXでももちろん利用できます9

対応エンジンが増えたと言うだけで、使い方はPXghostとまったく同じです。(u)pTeX以外のエンジンを用いるときは間違えずにBXghostを読み込んでください。下記は具体的な使用例です。

【汎用の入力】

%#!ナンチャラlatex
\documentclass[autodetect-engine,dvi=dvipdfmx,ja=standard]{bxjsarticle}
\usepackage{bxghost}% pxghostの代わりにbxghostを読み込む
\begin{document}
\begin{flushleft}
ワタシハLinuxチョットデキル \\
ディレクトリ\eghostguarded{\texttt{/usr/}}は「ユーザ」じゃない!
\end{flushleft}
\end{document}

どのエンジンの出力結果もだいたい同じなので、ここではLuaTeXでの出力を載せておきます。

【LuaTeX の出力】

LuaTeX+BXghostでうまく和欧文間スペースが入った例

めでたく“/usr/”の前後にも和欧文間スペースが入りました🎉

「(La)TeXのコマンド」を適切に組版しよう

(La)TeXの解説文書を作ろうとして「(La)TeXのコマンド」(バックスラッシュから始まるアレ。TeXの用語では制御綴)を紙面に印字したい場合を考えます。これをナイーブにやろうとすると、まさに和欧文間スペースが適切に入らないケースにハマります。

\verbを使う方法

LaTeXでバックスラッシュを含むような文字列を、単純に出力しようと思うと\verbを使おうとなるのが普通でしょう。実際にやってみましょう(例文の出典)。

【入力】

朝起きがけの\verb|\expandafter|が気持ちのいい季節になりました。

【出力】

ナイーブに\verbを使うと和欧文間スペースが適切に入らない

“\expandafter”の後ろには和欧文間スペースが入っているのに、前には入らないという極めて中途半端で不格好な出力結果となってしまいました。

もちろん\eghostguardedを用いて\verb|\expandafter|部分を「欧文文字列扱い」できればいいのですが、ご存知の通り\verb呪われた命令であるため他の命令の引数内で使うことはできません。したがって、次のように\verb|\expandafter|を単純に\eghostguardedの引数に入れることはできません

% これではうまくいかない!
朝起きがけの\eghostguarded{\verb|\expandafter|}が気持ちのいい季節になりました。

BXghost v0.3.0以降では、\verbを常に欧文扱い(=\eghostguardedで保護された状態)にするパッケージオプションverbが利用可能です。

\documentclass{jlreq}
\usepackage[verb]{bxghost}
\begin{document}
朝起きがけの\verb|\expandafter|が気持ちのいい季節になりました。
\end{document}

verbオプションを使うと、\verbが常に欧文扱いされる

ただしこのオプションはLaTeXの標準コマンド\verbの定義を上書きするものなので、それに起因するトラブルに見舞われる可能性もあるので注意してください10。特にBXghostをverbオプション有効で用いる場合は\verbを再定義する他のパッケージよりも後に読み込まないと機能が有効にならない可能性があるため、なるべく最後の方で読み込むようにしてください。

また、オプションの性質上すべての\verbを欧文文字列として扱うようにするものなので、\verbの中に欧文文字列扱いすべきでない要素(例えば和文文字)が、特に先頭末尾において、現れる可能性がある文書では配慮が必要でしょう。\verbの先頭末尾に和文文字が現れる回数が少なければ、その\verbの直後にはから引数の\jghostguarded{}をおいておくことでその境界を和文扱いする回避策が有効でしょう。

\documentclass{jlreq}
\usepackage[verb]{bxghost}
\begin{document}
okumacroの\verb|\曜|\jghostguarded{}コマンドは便利だが、完全展開可能ではない。

BXjaholidayの\verb|\jadayofweek|コマンドなら先頭完全展開可能!
\end{document}

専用のコマンドを定義する方法

\verbは汎用性が高いですが、呪われているなどの弱点もあるので、TeX/LaTeXコマンド(制御綴)の印字に特化したコマンドを定義したい場合もあるでしょう。ここでは\cmd{command}と書くとタイプライタ体で\commandと印字されるようなコマンドを定義することを考えます11

テキストモードでは\textbackslashを使うとバックスラッシュを出力できることを知っていれば、次のように定義できますね。

【入力】

\documentclass{jlreq}
\usepackage[T1]{fontenc}  % 必要!

\newcommand\cmd[1]{\texttt{\textbackslash #1}}  % 不十分な定義

\begin{document}
朝起きがけの\cmd{expandafter}が気持ちのいい季節になりました。
\end{document}

【出力】

バックスラッシュの前に和欧文間スペースが入らない

デフォルトの\verbを使ったときと同じ状況——つまり\expandafterだけ和欧文間スペースが入っていない——になりましたが、今度は「呪われた命令」が含まれていないので、普通に\eghostguardedで囲うことができるので、コマンド定義の置換テキスト全体を\eghostguardedで包んでやって円満解決します

【入力】

\documentclass{jlreq}
\usepackage[T1]{fontenc}  % 必要!
\usepackage{bxghost}

\newcommand\cmd[1]{\eghostguarded{\texttt{\textbackslash #1}}}  % 完成した定義

\begin{document}
朝起きがけの\cmd{expandafter}が気持ちのいい季節になりました。
\end{document}

【出力】

期待通り\expandafterの前にも後ろにも和欧文間スペースが入った

完璧ですね。これを使って、じゃんじゃんLaTeXの解説文書を書きましょう!

Note — T1エンコーディング

タイプライタ体の\textbackslashを使用する場合にはフォントエンコーディングに注意が必要です。具体的には\usepackage[T1]{fontenc}によってT1エンコーディングにしておかないと、バックスラッシュ部分が数式扱いになって書体変更が適用されません。

\textbackslash を使うと和欧文間スペースは入るが書体がおかしい

詳しくはZRさんによるアレな記事を参照してください。

なお、最近のLaTeXで最新の書き方(\DocumentMetadataを使用)する場合には、デフォルトのエンコーディングも最初からT1になるようになっています。cf. LaTeX News 40その斜め読み


主な更新履歴

  • 2020-02-27: verbオプションの紹介を追加
  • 2025-12-08: 最新の状況に合わせた説明の追加。コラムの追加。全体的なスタイルの調整

  1. 2025年12月現在、具体的にはLuaTeXにおいてはLuaTeX-ja、XeTeXにおいてはbxjsclsの使用が前提になります。 ↩︎

  2. このブログ(ラング・ラグー)の記事も例外ではありません! ↩︎

  3. 元ネタは「ワタシハリナックスチョットデキル」(全部カタカナ表記)です。また/usrディレクトリの由来については諸説あります。 ↩︎

  4. 例えばurlパッケージ\url命令でスラッシュで終わるURLを和文文字列内に挿入した場合は適切に和欧文間スペースが入ります。ちなみにですが、同じ\urlという名前の命令でもhyperrefパッケージhidelinksオプションを使用している場合はスラッシュ直後に和欧文間スペースが入らないようです。 ↩︎

  5. その正体はPXghost/BXghostでは複合単語マーク(Compound Word Mark;CWM)と呼ばれる特殊な記号です。T1エンコーディング(Corkエンコーディング)では0x17。これはドイツ語などの長くて複雑な単語の区切れ目を表現するのに用いられるようです。しばしばUnicodeのゼロ幅スペース(Zero-width space;ZWSP;U+200B)にマップされます。(参考) ↩︎

  6. PXghost/BXghostの和文ゴーストは大雑把に言うと「空白スペースを出力し、直後に 1zw(すなわち和文文字1文字分の幅)戻る」ことで実現しています。 ↩︎

  7. この記事にある\hboxの例とsiunitxの例は、その後の(おそらくpTeX側の)修正のおかげで最新のTeX Live 2019ではいずれも再現しません。すなわちPXghostを使わなくても適切に和欧文間スペースが入ります。 ↩︎

  8. 最近は一部ZRさん以外の方が開発/メンテナンスしている場合もあります。そもそもBXghostがその一例です。 ↩︎

  9. ApTeX (pTeX-ng)という(u)pTeXの拡張エンジンに対してもpTeXと同じロジックが通用したので、特別なことはしていませんがサポート対象ということにしています。 ↩︎

  10. 「docパッケージなどLaTeXカーネルの\verbの定義を上書きするパッケージが複数ある」「shortvrbパッケージの\MakeShortVerbが対応しているのが\verbだけでほかのコマンドを指定できない」などの事情があり、やむを得ずカーネル命令の定義を上書きするような設計になりました。 ↩︎

  11. Knuth作のWEB用標準マクロ(webmac.tex ※直リンク注意!)では\.が同様の意図で定義されています。cf. とにかくWEB言語してみたい ↩︎