プレーンテキスト貼り付け時の改行消失バグを修正
iA Writer など外部エディタからテキストを貼り付けると、単一の改行が無声で削除されてテキストが一塊になる問題を修正しました。marked() に breaks: true を渡す1行の変更で、CommonMark のデフォルト挙動を上書きしています。
背景
CommonMark 仕様 では、単一の \n はソフトブレーク(HTML 上はスペース)として扱われ、段落の区切りには \n\n(空行)が必要です。Lexxy のクリップボードハンドラは、プレーンテキストをいったん Markdown として解釈したうえで HTML に変換するため、この仕様が直接影響していました。
外部エディタから「Line 1\nLine 2\nLine 3」を貼り付けると、marked() はデフォルト設定で3行を連結したひとつの段落として出力します。ユーザーから見ると「壁のようなテキスト」が生成され、元の構造が失われていました。
この問題の影響範囲はプレーンテキストの貼り付けパスに限定されており、HTML 貼り付けや添付ファイルを含む貼り付けなど、他のコードパスは影響を受けていません。
技術的な変更
src/editor/clipboard.js の #pasteMarkdown メソッドで、marked() の呼び出しに { breaks: true } オプションを追加しました。
変更前:
#pasteMarkdown(text) {
const html = marked(text)
const doc = parseHtml(html)
// ...
}
変更後:
#pasteMarkdown(text) {
const html = marked(text, { breaks: true })
const doc = parseHtml(html)
// ...
}
breaks: true を有効にすると、marked は単一の \n を <br> タグに変換します。二重の \n\n は引き続き別々の <p> 要素を生成するため、段落構造の保持も維持されます。
変更に合わせて test/browser/tests/paste.test.js にブラウザテストが2件追加されました。1件目は「Line 1\nLine 2\nLine 3」が <p>Line 1<br>Line 2<br>Line 3</p> になることを、2件目は「Paragraph 1\n\nParagraph 2」が <p>Paragraph 1</p><p>Paragraph 2</p> になることをそれぞれ検証しています。
設計判断
既存の #pasteMarkdown パスを変更する最小限の修正 が選ばれました。プレーンテキストの貼り付けはクリップボードハンドラ内で独立したコードパスを持っており、marked の設定変更の影響範囲はこのパスに閉じています。
また、.claude/skills/bugs-reproducer.md のアーキテクチャドキュメントにも「markdown パスは breaks: true で marked を使用している。このオプションがないと貼り付けたプレーンテキストの単一改行は CommonMark のデフォルトで飲み込まれる。貼り付けで空白や構造が失われる場合はまず marked の設定を確認すること」という注記が追加されました。バグの根本原因を将来の調査者へ伝える目的で、コード変更と並行してドキュメントも更新されています。
まとめ
marked() への breaks: true 1オプションの追加で、CommonMark のデフォルト動作がもたらすユーザー体験の損失を修正しています。コード変更を最小化しつつ、根本原因をドキュメントに記録するアプローチは、同種のバグに対する将来の診断コストを下げる実践的な判断です。