マクロツイーター

はてダから移行した記事の表示が崩れてますが、そのうちに直せればいいのに(えっ)

CJK パッケージで空白は空白になるかならないか

以前の記事CJK パッケージの和欧文間空白の取扱について説明したが、それにチョット関連する話として、CJK パッケージ(および bxcjkjatype パッケージ)での「ソース上の空白」の扱いについて解説する。

その前に

前提として、(CJK でない)欧文 LaTeX(pdfLaTeX も含む)のソース上の空白類文字(空白文字・タブ・改行文字)の扱いについては既知とする。特に欧文 LaTeX の次の性質について確認しておく。

  • (コメントでない)行末(改行文字)は常に空白文字と等価である。*1

改行文字と空白文字は TeX のプログラム上でも区別できないため、CJK パッケージを読み込んだ状況でも両者は区別されず等価になる。(従って以降では総称して「空白文字」と呼ぶ。)

CJK 環境中の空白文字

CJK パッケージにおいて、和文(CJK 言語)を記述するための環境は CJKCJK* の 2 通りがあり、両者で空白文字の扱いが異なる。

% pdfLaTeX 文書, 文字コードは UTF-8
\documentclass[a4paper]{article}
\usepackage{CJKutf8}
\begin{document}

% CJK 環境
X \begin{CJK}{UTF8}{ipxm}
漢 字 A B 漢 字
漢 字 C D
漢 字
\end{CJK} Y

% CJK* 環境
X \begin{CJK*}{UTF8}{ipxm}
漢 字 A B 漢 字
漢 字 C D
漢 字
\end{CJK*} Y
\end{document}
(水色の部分には欧文空白 2 個分の空きがあることに注意。)

この出力を見て判る通り、以下のような仕様になっている。

  • CJK 環境においては空白文字は通常(LaTeX の規則)通りに扱われ、欧文空白を出力する。
  • CJK* 環境においては、和文の直後の空白文字が無視される。欧文の直後の空白文字は欧文空白になる。
  • \begin{CJK(*)}{…}{…}\end{CJK(*)} の前後に空白文字がある場合、それは“特に無視されるわけではない”。(つまり「他に無視される要因が無ければ」欧文空白になる。((例えば、CJK* の出力では \end{CJK*} の直前の空白文字は「和文〈字〉の直後」なので無視されるが、直後の空白文字は無視されない。このため結果の出力では〈字〉と〈Y〉の間には欧文空白 1 個分の空きが発生する。)))

空白が保存される CJK 環境は、文節毎に空白を入れる韓国語*2に、CJK 文字の後の空白を消す*3 CJK* 環境は基本的に単語間に空白を入れない日本語や中国語の組版に適している。

\documentclass[a4paper]{article}
\usepackage{CJKutf8}
\begin{document}
Here's Korean text.
\begin{CJK}{UTF8}{mj}%
% 改行が空白になる
CJK 패키지로
한국어하는 건.
\end{CJK}

Here's Chinese text.
\begin{CJK*}{UTF8}{gbsn}%
% 改行が空白にならない
以\ CJK 宏包
写中文的事。
\end{CJK*}
\end{document}

なお、中国語の組版では漢字と欧文の間に欧文空白を入れるのが普通のようである*4が、そのような欧文交じりの中国語では、上掲の例のように、漢字→欧文と並んだ場合に間に入れる空白を“エスケープする”(空白命令 \␣ を使う)必要があるので、CJK* 環境は“最適”ではないことになる。

CJKspace パッケージ

先述の欠点を解消するのが CJKspace パッケージである。

% pdfLaTeX 文書, 文字コードは UTF-8
\documentclass[a4paper]{article}
\usepackage{CJKutf8,CJKspace}% CJKspace を加えた
\begin{document}

% CJK 環境
X \begin{CJK}{UTF8}{ipxm}
漢 字 A B 漢 字
漢 字 C D
漢 字
\end{CJK} Y

% CJK* 環境
X \begin{CJK*}{UTF8}{ipxm}
漢 字 A B 漢 字
漢 字 C D
漢 字
\end{CJK*} Y
\end{document}

CJKspace を読み込むと空白の取扱が以下のように変更される。

  • CJK 環境は何も変化しない。
  • CJK* 環境については、和文(CJK 文字)同士の間のみ空白文字が無視される。その他の空白文字は欧文空白になる。

この規則だと、中国語に関しては、“エスケープ”が不要になり、かつどこでも改行できるようになるので、非常に都合がいい。

% pdfLaTeX 文書, 文字コードは UTF-8
\documentclass[a4paper]{article}
\usepackage{CJKutf8,CJKspace}
\begin{document}
Here's Chinese text.
\begin{CJK*}{UTF8}{gbsn}%{pdf\LaTeX} 和
CJK 宏包写中文的
事。
\end{CJK*}
\end{document}

先の記事で述べたように、日本語の場合は和文と欧文の間は“四分空き”の命令〈~〉を入れるので少し事情は異なるのだが、それでも(色々な事情を鑑みると)CJKspace 読込の CJK* 環境が最も自然な選択であると、私が考えている。

% pdfLaTeX 文書, 文字コードは UTF-8
\documentclass[a4paper]{article}
\usepackage{CJKutf8,CJKspace}
\begin{document}
Here's Japanese text.
\begin{CJK*}{UTF8}{ipxm}\CJKtilde
{pdf\LaTeX}~と~
CJK~パッケージで
日本語する件。
\end{CJK*}
\end{document}

なお、〈~〉のある箇所で改行したい場合は、〈~〉の直後で改行するのが便利である。これは、「〈~〉の直後の空白文字は無視する」という規則のため〈~〉の後に % を書かなくて済むからである。((〈~〉の直前で改行した場合は、前の行の改行文字を無力化しておかないと余計な欧文空白が入ってしまう。))

bxcjkjatype パッケージの場合

bxcjkjatype パッケージにおける空白文字の扱いは以下のようになっている。

  • 既定では bxcjkjatype は CJKspace を読み込む。
  • bxcjkjatype では CJK(*) の指定を簡略化する uCJK(*) 環境が用意されている。空白文字の扱いについては、uCJKCJK と、uCJK*CJK* と同等になる。
  • whole オプション(または wholeCJK* オプション)は文書本体を暗黙的に uCJK* 環境で囲む。これに対して、wholeCJK オプションは文書本体を暗黙的に uCJK 環境で囲む。
  • 何か理由があって CJKspace を読み込みたくない場合は、パッケージ読込時に noCJKspace オプションを指定する。

従って、日本語を書く場合は uCJK* を用いることが想定されている。この時の空白文字の規則は前述の「CJKspace 読込時の CJK*」と同一である。そして、(以前の記事にある通り)autotilde もほぼ必須といえるだろう。

% pdfLaTeX 文書, 文字コードは UTF-8
\documentclass[a4paper]{article}
\usepackage[autotilde]{bxcjkjatype}
\begin{document}
Here's Japanese text.
\begin{uCJK*}%
{pdf\LaTeX}~と~bxcjkjatype~パッケージで
日本語する件。
\end{uCJK*}
\end{document}

whole オプションを指定した例も挙げておく。

% pdfLaTeX 文書, 文字コードは UTF-8
\documentclass[a4paper]{article}
\usepackage[whole,autotilde]{bxcjkjatype}
\begin{document}
Here's Japanese text.
{pdf\LaTeX}~と~bxcjkjatype~パッケージで
日本語する件。
ソースファイルの文字コードは~
UTF-8~にする必要がある。
\end{document}

そして BXJS クラス(の“標準設定”)は、wholeautotilde を付けた bxcjkjatype を読み込むので、結局この場合も空白文字の規則は「CJKspace 読込時の CJK*」と同一になる。((CJKspace の読込を抑止する手段は特に用意されていないが、取りあえず noCJKspace をクラスオプションに指定する(グローバルオプションにする)ことでそれが実現できる。))

% pdfLaTeX 文書, 文字コードは UTF-8
\documentclass[pdflatex,a4paper,ja=standard]{bxjsarticle}
\usepackage[whole,autotilde]{bxcjkjatype}
\begin{document}
\section{日本語するテスト}
{pdf\LaTeX}~と~bxjsarticle~クラスで
日本語文書する件。
ソースファイルの文字コードは~
UTF-8~にする必要がある。
\end{document}

*1:日本語に特化したエンジンである (u)pLaTeX では「日本語を扱いやすくする」ため、「行末が和文文字である場合は改行文字は空白にならず無視される」という“特別扱い”がある。しかし欧文 LaTeX にはそういう類のエンジンレベルでの“特別扱い”は無い。

*2:つまり、ソースを書く時は、文節の区切りで改行を入れるようにすればよい。

*3:つまり、pTeX のように、CJK 文字の直後で改行しても出力に影響しない。

*4:少なくとも xeCJK のマニュアルを見ている限りだとそのように見える。