CJK対応マークダウン
CJK約物の近くで太字・斜体が正しくレンダリングされない問題を修正する
問題
CommonMark には、CJK(中国語・日本語・韓国語)の約物に隣接した強調(太字・斜体)が正しく動作しないという既知の問題があります。次のようなマークダウンを考えてみましょう:
**テスト。**テスト
修正なしでは、これは **テスト。**テスト とそのまま文字列として出力されてしまいます — 太字のマーカーが認識されません。同じ問題は他のCJK約物や斜体(* および _)にも発生します。
原因
CommonMark の仕様では、強調のパースにおいて特定の文字を「Unicode 約物」として分類しています。。(句点)などのCJK約物もこのカテゴリに該当します。仕様のフランキングルールにより、強調デリミタの直後に約物が来る場合、開始デリミタとして認識されなくなります。その結果、閉じる ** が開く ** と対応できなくなります。
影響を受ける文字には、以下のようなものが含まれます(これらに限りません):
| 文字 | 説明 |
|---|---|
。 | 句点(全角ピリオド) |
、 | 読点(全角コンマ) |
」 | 鉤括弧(閉じ) |
) | 全角括弧(閉じ) |
』 | 二重鉤括弧(閉じ) |
【 の対応 】 | 隅付き括弧(閉じ) |
《 の対応 》 | 二重山括弧(閉じ) |
**、*、__、_ の直前にCJKの閉じ約物が来ると、この問題が発生します。
remark-cjk-friendly による修正
<code>remark-cjk-friendly</code> プラグインは、micromark の強調パースルールにパッチを当て、CJK約物をフランキング検出において Unicode 約物として扱わないようにします。これにより、CJKテキストに隣接した太字・斜体が直感的に期待通り機能するようになります。
修正前後の比較
入力マークダウン:
**テスト。**テスト
| 出力 | |
|---|---|
| プラグインなし | **テスト。**テスト(文字列としてそのまま表示) |
| プラグインあり | テスト。テスト(太字が正しく適用される) |
同じ修正は斜体マーカーや他のCJK約物にも適用されます。
有効化・無効化
プラグインは src/ の cjkFriendly 設定で制御します:
export const settings = {
// ...
cjkFriendly: true, // false に設定すると無効
};
cjkFriendly が true(デフォルト)の場合、remark-cjk-friendly が MDX の remark プラグインチェーンに自動的に追加されます。コンテンツが英語のみで、標準の CommonMark 動作を使いたい場合は false に設定してください。
セットアッププリセットジェネレーターや create-zudo-doc CLI でプロジェクトを作成する際にも、--cjk-friendly / --no-cjk-friendly オプションで設定できます。