はきくま!制作日記:カクヨムの記法を落とし込む
- 投稿日
カクヨムの記法で書いた小説の本文を、そのまま自作サイトの本文として表示するための変換処理の記録。
その1:本文はテキストエリア+独自記法
本文をリッチエディタにしなかったのは、カクヨムとの原稿の行き来のため。プレーンテキストのまま書いて、表示用の変換は formatLine 一か所で行う。順番が重要。
export function formatLine(line: string) {
let html = escapeHtml(line); // 最初に本文の < & をエスケープ
// 縦中横:タグを入れる前に処理する(後だと class 属性の英字まで拾う)
html = html.replace(/(?<![0-9,.])([0-9]{2,3})(?![0-9,.])/g, '<span class="tcy">$1</span>');
html = html.replace(/(?<![A-Za-z&;])([A-Za-z])(?![A-Za-z;])/g, '<span class="tcy">$1</span>');
html = html.replace(/\{\{(.+?)\}\}/g, '<span lang="zh-HK" class="u-ff_cantonese">$1</span>');
html = html.replace(/《《(.+?)》》/g, '<em class="bouten">$1</em>'); // ルビより先
html = html.replace(/[||]([^||《》]+?)《(.+?)》/g, "<ruby>$1<rt>$2</rt></ruby>");
html = html.replace(/([\p{Script=Han}々〆ヶ]+)《(.+?)》/gu, "<ruby>$1<rt>$2</rt></ruby>");
html = html.replace(/([?!]+)/g, '<span class="mark">$1</span>');
return html;
}
- 最初にエスケープしてから、自分で決めた記法だけを HTML にするので、
set:htmlでも安全 - 傍点
《《》》はルビ《》の二重なので、ルビより先に処理 - 縦中横の数字は、カンマや小数点に隣接するものを除外(
1,000,000が3桁ずつ分割されるのを防ぐ) - 小説の中の広東語は
{{ }}で囲んで書く。lang="zh-HK"と広東語専用フォントを当てるクラスを付けたspanに変換して、囲んだ部分だけ広東語用のフォントで表示される - ルビの親文字判定は
\p{Script=Han}にして、広東語の字にも振れるように - 自動ルビは直前の漢字の並びだけが親文字になる。「黄金の果実」のように かな を挟む時は
|で範囲を指定する(カクヨムと同じ書き方) - テキストエリアの値が空のフィールドは、API のレスポンスに項目ごと出てこない。
(text ?? "").split("\n")で受ける