diff --git a/assets/kanbun-viewer/kanbun-render.js b/assets/kanbun-viewer/kanbun-render.js index aa642a0..d136189 100644 --- a/assets/kanbun-viewer/kanbun-render.js +++ b/assets/kanbun-viewer/kanbun-render.js @@ -209,7 +209,10 @@ // Lays the body columns into bands right to left for root's current // font size and width cap, wrapping only between columns. A band ends // at a stanza break when that costs at most STANZA_PULL columns; a - // blank stanza column is not set at the edge of a band. + // blank stanza column is not set at the edge of a band. No band is + // left holding a single column (2026-10-22): when a full band would + // leave one column over, the band ends at its stanza break, or, with + // no stanza break in it, hands one column on to the last band. function bandKanbunColumns(root) { const body = root.kanbunBody; const text = root.querySelector(':scope > .kanbun-text'); @@ -248,6 +251,13 @@ if (body[start + t].dataset.kanbunColumn === 'gap') { take = t; break; } } } + if (body.slice(start + take).filter(c => c.dataset.kanbunColumn !== 'gap').length === 1) { + let broken = false; + for (let t = take - 1; t >= 2; t--) { + if (body[start + t].dataset.kanbunColumn === 'gap') { take = t; broken = true; break; } + } + if (!broken && take > 1) take -= 1; + } let list = body.slice(start, start + take); while (list.length && list[list.length - 1].dataset.kanbunColumn === 'gap') list.pop(); const band = document.createElement('div'); diff --git a/assets/kanbun-viewer/works/chaozhongcuo-20181023-revised-202610.html b/assets/kanbun-viewer/works/chaozhongcuo-20181023-revised-202610.html index 77f72bb..dbe3b02 100644 --- a/assets/kanbun-viewer/works/chaozhongcuo-20181023-revised-202610.html +++ b/assets/kanbun-viewer/works/chaozhongcuo-20181023-revised-202610.html @@ -7,7 +7,7 @@ 漢文訓点 · chaozhongcuo-20181023-revised-202610 - + diff --git a/assets/kanbun-viewer/works/fengrusong-20181102-revised-202610.html b/assets/kanbun-viewer/works/fengrusong-20181102-revised-202610.html index da9e06a..c0b626f 100644 --- a/assets/kanbun-viewer/works/fengrusong-20181102-revised-202610.html +++ b/assets/kanbun-viewer/works/fengrusong-20181102-revised-202610.html @@ -7,7 +7,7 @@ 漢文訓点 · fengrusong-20181102-revised-202610 - + diff --git a/assets/kanbun-viewer/works/huanxisha-20261020-text.html b/assets/kanbun-viewer/works/huanxisha-20261020-text.html index 88aeaea..b7dd40f 100644 --- a/assets/kanbun-viewer/works/huanxisha-20261020-text.html +++ b/assets/kanbun-viewer/works/huanxisha-20261020-text.html @@ -7,7 +7,7 @@ 漢文訓点 · huanxisha-20261020-text - + diff --git a/assets/kanbun-viewer/works/jia-yi-a1-text.html b/assets/kanbun-viewer/works/jia-yi-a1-text.html index b97ebea..8af51cf 100644 --- a/assets/kanbun-viewer/works/jia-yi-a1-text.html +++ b/assets/kanbun-viewer/works/jia-yi-a1-text.html @@ -7,7 +7,7 @@ 漢文訓点 · jia-yi-a1-text - + diff --git a/assets/kanbun-viewer/works/jia-yi-a10-text.html b/assets/kanbun-viewer/works/jia-yi-a10-text.html index c72b49e..28ded6c 100644 --- a/assets/kanbun-viewer/works/jia-yi-a10-text.html +++ b/assets/kanbun-viewer/works/jia-yi-a10-text.html @@ -7,7 +7,7 @@ 漢文訓点 · jia-yi-a10-text - + diff --git a/assets/kanbun-viewer/works/jia-yi-a2-text.html b/assets/kanbun-viewer/works/jia-yi-a2-text.html index d9dc3cf..f97da8d 100644 --- a/assets/kanbun-viewer/works/jia-yi-a2-text.html +++ b/assets/kanbun-viewer/works/jia-yi-a2-text.html @@ -7,7 +7,7 @@ 漢文訓点 · jia-yi-a2-text - + diff --git a/assets/kanbun-viewer/works/jia-yi-a3-text.html b/assets/kanbun-viewer/works/jia-yi-a3-text.html index 6313b58..4cd6f02 100644 --- a/assets/kanbun-viewer/works/jia-yi-a3-text.html +++ b/assets/kanbun-viewer/works/jia-yi-a3-text.html @@ -7,7 +7,7 @@ 漢文訓点 · jia-yi-a3-text - + diff --git a/assets/kanbun-viewer/works/jia-yi-a4-text.html b/assets/kanbun-viewer/works/jia-yi-a4-text.html index 275ba8a..4f9ff02 100644 --- a/assets/kanbun-viewer/works/jia-yi-a4-text.html +++ b/assets/kanbun-viewer/works/jia-yi-a4-text.html @@ -7,7 +7,7 @@ 漢文訓点 · jia-yi-a4-text - + diff --git a/assets/kanbun-viewer/works/jia-yi-a5-text.html b/assets/kanbun-viewer/works/jia-yi-a5-text.html index 2b943c0..0f60d17 100644 --- a/assets/kanbun-viewer/works/jia-yi-a5-text.html +++ b/assets/kanbun-viewer/works/jia-yi-a5-text.html @@ -7,7 +7,7 @@ 漢文訓点 · jia-yi-a5-text - + diff --git a/assets/kanbun-viewer/works/jia-yi-a6-text.html b/assets/kanbun-viewer/works/jia-yi-a6-text.html index 06c3dca..f6d4c8b 100644 --- a/assets/kanbun-viewer/works/jia-yi-a6-text.html +++ b/assets/kanbun-viewer/works/jia-yi-a6-text.html @@ -7,7 +7,7 @@ 漢文訓点 · jia-yi-a6-text - + diff --git a/assets/kanbun-viewer/works/jia-yi-a7-text.html b/assets/kanbun-viewer/works/jia-yi-a7-text.html index f40dab2..e66e936 100644 --- a/assets/kanbun-viewer/works/jia-yi-a7-text.html +++ b/assets/kanbun-viewer/works/jia-yi-a7-text.html @@ -7,7 +7,7 @@ 漢文訓点 · jia-yi-a7-text - + diff --git a/assets/kanbun-viewer/works/jia-yi-a8-text.html b/assets/kanbun-viewer/works/jia-yi-a8-text.html index 85eb468..a734369 100644 --- a/assets/kanbun-viewer/works/jia-yi-a8-text.html +++ b/assets/kanbun-viewer/works/jia-yi-a8-text.html @@ -7,7 +7,7 @@ 漢文訓点 · jia-yi-a8-text - + diff --git a/assets/kanbun-viewer/works/jia-yi-a9-text.html b/assets/kanbun-viewer/works/jia-yi-a9-text.html index 4208e86..126a493 100644 --- a/assets/kanbun-viewer/works/jia-yi-a9-text.html +++ b/assets/kanbun-viewer/works/jia-yi-a9-text.html @@ -7,7 +7,7 @@ 漢文訓点 · jia-yi-a9-text - + diff --git a/assets/kanbun-viewer/works/jia-yi-b1-text.html b/assets/kanbun-viewer/works/jia-yi-b1-text.html index 8b4089d..4555a7b 100644 --- a/assets/kanbun-viewer/works/jia-yi-b1-text.html +++ b/assets/kanbun-viewer/works/jia-yi-b1-text.html @@ -7,7 +7,7 @@ 漢文訓点 · jia-yi-b1-text - + diff --git a/assets/kanbun-viewer/works/jia-yi-b2-text.html b/assets/kanbun-viewer/works/jia-yi-b2-text.html index 4ea4b84..ab02956 100644 --- a/assets/kanbun-viewer/works/jia-yi-b2-text.html +++ b/assets/kanbun-viewer/works/jia-yi-b2-text.html @@ -7,7 +7,7 @@ 漢文訓点 · jia-yi-b2-text - + diff --git a/assets/kanbun-viewer/works/jia-yi-b3-text.html b/assets/kanbun-viewer/works/jia-yi-b3-text.html index 2472e58..704a70a 100644 --- a/assets/kanbun-viewer/works/jia-yi-b3-text.html +++ b/assets/kanbun-viewer/works/jia-yi-b3-text.html @@ -7,7 +7,7 @@ 漢文訓点 · jia-yi-b3-text - + diff --git a/assets/kanbun-viewer/works/jia-yi-b4-text.html b/assets/kanbun-viewer/works/jia-yi-b4-text.html index 85c4657..8e4114b 100644 --- a/assets/kanbun-viewer/works/jia-yi-b4-text.html +++ b/assets/kanbun-viewer/works/jia-yi-b4-text.html @@ -7,7 +7,7 @@ 漢文訓点 · jia-yi-b4-text - + diff --git a/assets/kanbun-viewer/works/jia-yi-b5-text.html b/assets/kanbun-viewer/works/jia-yi-b5-text.html index 9bbc7d3..bef2ba1 100644 --- a/assets/kanbun-viewer/works/jia-yi-b5-text.html +++ b/assets/kanbun-viewer/works/jia-yi-b5-text.html @@ -7,7 +7,7 @@ 漢文訓点 · jia-yi-b5-text - + diff --git a/assets/kanbun-viewer/works/jia-yi-b6-text.html b/assets/kanbun-viewer/works/jia-yi-b6-text.html index ac1e02f..055c1e6 100644 --- a/assets/kanbun-viewer/works/jia-yi-b6-text.html +++ b/assets/kanbun-viewer/works/jia-yi-b6-text.html @@ -7,7 +7,7 @@ 漢文訓点 · jia-yi-b6-text - + diff --git a/assets/kanbun-viewer/works/jia-yi-b7-text.html b/assets/kanbun-viewer/works/jia-yi-b7-text.html index 841c45f..4805773 100644 --- a/assets/kanbun-viewer/works/jia-yi-b7-text.html +++ b/assets/kanbun-viewer/works/jia-yi-b7-text.html @@ -7,7 +7,7 @@ 漢文訓点 · jia-yi-b7-text - + diff --git a/assets/kanbun-viewer/works/linjiangxian-20180108-revised-202610.html b/assets/kanbun-viewer/works/linjiangxian-20180108-revised-202610.html index fe155bb..a7de243 100644 --- a/assets/kanbun-viewer/works/linjiangxian-20180108-revised-202610.html +++ b/assets/kanbun-viewer/works/linjiangxian-20180108-revised-202610.html @@ -7,7 +7,7 @@ 漢文訓点 · linjiangxian-20180108-revised-202610 - + diff --git a/assets/kanbun-viewer/works/linjiangxian-20260909-text.html b/assets/kanbun-viewer/works/linjiangxian-20260909-text.html index 6cbd406..4879830 100644 --- a/assets/kanbun-viewer/works/linjiangxian-20260909-text.html +++ b/assets/kanbun-viewer/works/linjiangxian-20260909-text.html @@ -7,7 +7,7 @@ 漢文訓点 · linjiangxian-20260909-text - + diff --git a/assets/kanbun-viewer/works/linjiangxianyin-20191028-revised-202610.html b/assets/kanbun-viewer/works/linjiangxianyin-20191028-revised-202610.html index a51514c..634b28a 100644 --- a/assets/kanbun-viewer/works/linjiangxianyin-20191028-revised-202610.html +++ b/assets/kanbun-viewer/works/linjiangxianyin-20191028-revised-202610.html @@ -7,7 +7,7 @@ 漢文訓点 · linjiangxianyin-20191028-revised-202610 - + diff --git a/assets/kanbun-viewer/works/manjianghong-2022-echo-202610.html b/assets/kanbun-viewer/works/manjianghong-2022-echo-202610.html index d3839ac..62c6e10 100644 --- a/assets/kanbun-viewer/works/manjianghong-2022-echo-202610.html +++ b/assets/kanbun-viewer/works/manjianghong-2022-echo-202610.html @@ -7,7 +7,7 @@ 漢文訓点 · manjianghong-2022-echo-202610 - + diff --git a/assets/kanbun-viewer/works/manjianghong-2022-sewn-202610.html b/assets/kanbun-viewer/works/manjianghong-2022-sewn-202610.html index f1d830e..a8f8e91 100644 --- a/assets/kanbun-viewer/works/manjianghong-2022-sewn-202610.html +++ b/assets/kanbun-viewer/works/manjianghong-2022-sewn-202610.html @@ -7,7 +7,7 @@ 漢文訓点 · manjianghong-2022-sewn-202610 - + diff --git a/assets/kanbun-viewer/works/manjianghong-rereading-202610-text.html b/assets/kanbun-viewer/works/manjianghong-rereading-202610-text.html index 9809171..597e7a0 100644 --- a/assets/kanbun-viewer/works/manjianghong-rereading-202610-text.html +++ b/assets/kanbun-viewer/works/manjianghong-rereading-202610-text.html @@ -7,7 +7,7 @@ 漢文訓点 · manjianghong-rereading-202610-text - + diff --git a/assets/kanbun-viewer/works/mantingfang-20191219-revised-202610.html b/assets/kanbun-viewer/works/mantingfang-20191219-revised-202610.html index 1c2c4c0..cee40a7 100644 --- a/assets/kanbun-viewer/works/mantingfang-20191219-revised-202610.html +++ b/assets/kanbun-viewer/works/mantingfang-20191219-revised-202610.html @@ -7,7 +7,7 @@ 漢文訓点 · mantingfang-20191219-revised-202610 - + diff --git a/assets/kanbun-viewer/works/pusaman-20261021-text.html b/assets/kanbun-viewer/works/pusaman-20261021-text.html index 15d5fbc..31caaf0 100644 --- a/assets/kanbun-viewer/works/pusaman-20261021-text.html +++ b/assets/kanbun-viewer/works/pusaman-20261021-text.html @@ -7,7 +7,7 @@ 漢文訓点 · pusaman-20261021-text - + diff --git a/assets/kanbun-viewer/works/queqiaoxian-20181222-revised-202610.html b/assets/kanbun-viewer/works/queqiaoxian-20181222-revised-202610.html index 16c6b4b..6e2e1ff 100644 --- a/assets/kanbun-viewer/works/queqiaoxian-20181222-revised-202610.html +++ b/assets/kanbun-viewer/works/queqiaoxian-20181222-revised-202610.html @@ -7,7 +7,7 @@ 漢文訓点 · queqiaoxian-20181222-revised-202610 - + diff --git a/assets/kanbun-viewer/works/yingtianchang-20261008-text.html b/assets/kanbun-viewer/works/yingtianchang-20261008-text.html index dece159..0771240 100644 --- a/assets/kanbun-viewer/works/yingtianchang-20261008-text.html +++ b/assets/kanbun-viewer/works/yingtianchang-20261008-text.html @@ -7,7 +7,7 @@ 漢文訓点 · yingtianchang-20261008-text - + diff --git a/assets/kanbun-viewer/works/zhegutian-20260909-text.html b/assets/kanbun-viewer/works/zhegutian-20260909-text.html index 944bfa3..1afd5fb 100644 --- a/assets/kanbun-viewer/works/zhegutian-20260909-text.html +++ b/assets/kanbun-viewer/works/zhegutian-20260909-text.html @@ -7,7 +7,7 @@ 漢文訓点 · zhegutian-20260909-text - + diff --git a/assets/kanbun-viewer/works/zhegutian-20261017-text.html b/assets/kanbun-viewer/works/zhegutian-20261017-text.html index 0421f0a..7f00f33 100644 --- a/assets/kanbun-viewer/works/zhegutian-20261017-text.html +++ b/assets/kanbun-viewer/works/zhegutian-20261017-text.html @@ -7,7 +7,7 @@ 漢文訓点 · zhegutian-20261017-text - + diff --git a/docs/poetry-kunten-renderer.md b/docs/poetry-kunten-renderer.md index 1ff616c..b4b8197 100644 --- a/docs/poetry-kunten-renderer.md +++ b/docs/poetry-kunten-renderer.md @@ -34,8 +34,11 @@ poetry-kunten-collation.md for coverage, uncertainties and textual decisions. band starts at the body's right edge, beside the title block, or below it when fewer than four columns fit beside it; bands are separated by space and a hairline, and a band ends at a stanza break when that costs - at most two columns. A cell is as tall as its own readings plus a gap, - so every reading stays beside its own character. The generated page + at most two columns. No band holds a single column (2026-10-22): when a + full band would leave one column over, the band ends at its stanza break + (at least two columns in), or else hands one column on to the last + band. A cell is as tall as its own readings plus a gap, so every + reading stays beside its own character. The generated page keeps the source title parts, stanzas and lines; kanbun-render.js (flowKanbunColumns, bandKanbunColumns) sets them. - tools/poetry_kunten.py builds one standalone, noindex HTML presentation diff --git a/ja/poetry/chaozhongcuo-20181023/index.html b/ja/poetry/chaozhongcuo-20181023/index.html index bd604e0..55ce41f 100644 --- a/ja/poetry/chaozhongcuo-20181023/index.html +++ b/ja/poetry/chaozhongcuo-20181023/index.html @@ -125,7 +125,7 @@

《朝中措》

- +

朝中措の調べ

羽の金を梳いて、ほのかな香りの花にする。香りは鏡の中に届いて止まる。 欄干の前、影を伴侶に、並びたいと願う。一筋の朱い髪が先に絡まる。 diff --git a/ja/poetry/fengrusong-20181102/index.html b/ja/poetry/fengrusong-20181102/index.html index a84972b..fd94e5f 100644 --- a/ja/poetry/fengrusong-20181102/index.html +++ b/ja/poetry/fengrusong-20181102/index.html @@ -127,7 +127,7 @@

《風入松》

- +

風入松の調べ

丘の亭では雪が降ろうとし、霜はすでに結ぶ。それでも頑なな陽は残る。 斜陽は煉瓦に落ちてなお去りがたく、金の炉を焚き、長い夜、君を待つ。 diff --git a/ja/poetry/huanxisha-20261020/index.html b/ja/poetry/huanxisha-20261020/index.html index 45cdda2..a2f1635 100644 --- a/ja/poetry/huanxisha-20261020/index.html +++ b/ja/poetry/huanxisha-20261020/index.html @@ -125,7 +125,7 @@
+

浣渓沙の調べ · 三日後、また別の家に泊まり、横になっても寝床に落ち着かない

久しく飢えた鵷鶵、竹の実はもうない。 よその家で、ひとまず一枝の梧桐を借りている。 diff --git a/ja/poetry/jia-yi/index.html b/ja/poetry/jia-yi/index.html index 11e988c..d96c56f 100644 --- a/ja/poetry/jia-yi/index.html +++ b/ja/poetry/jia-yi/index.html @@ -146,7 +146,7 @@

不語各含無限思,而今惟道相期。 夜闌暗忘漏聲移。 慵來還指日,明日又今時。

- +

A1 · 臨江仙の調べ · 学友と灯の下で夜を過ごし、明け方になって別れる

幾度、夜更けまで二人で黙って座ったことだろう。 ひとつきりの灯、その赤い涙がゆっくり垂れる。 @@ -182,7 +182,7 @@

乙一《無題 · 臨江仙 客散非因誰獨在,他人皆自相依。 席旁偶坐共相棲。 漏殘晨露上,風過落花時。

- +

B1 · 無題 · 臨江仙の調べ

ひっそりした廊下に月が明るく、人の気配がようやく静まった。 二人で花の小径を、ゆっくり歩く。 @@ -218,7 +218,7 @@
+

A2 · 臨江仙の調べ · 酒のあと、頬に手を添えて階上へ上がり、夜更けに寄り添い、人に問われても避けなかった

深く酔い、支え合って並んで寄りかかった。 階上へ上がり、人には知られたくなかった。 @@ -254,7 +254,7 @@

乙二《無題 · 踏莎行 欲喚還休,歡猶未省。 分明一水無舟艇。 殘灰散盡各歸時,餘釭獨照空庭靜。

- +

B2 · 無題 · 踏莎行の調べ

香りの温かな一室。並ぶ二つの影の跡。 笑い声は簾のあいだの闇へ沈む。 @@ -288,7 +288,7 @@

乙三《無題 · 臨江仙 不是東風先折取,恐花為我辭根。 新痕舊鑰莫輕論。 相逢原是客,客受主家恩。

- +

B3 · 無題 · 臨江仙の調べ

蝋燭は暗く、こおろぎは冷え、簾の影は細い。 酔いの名残にはまだわずかな温もり。 @@ -327,7 +327,7 @@

乙四《無題 · 渡江雲 謄復塗、深言怕誤,淺字偏安。 明朝銅色經他手,便認作、一諾窮年。 燈滅後、丁寧只是加餐。

- +

B4 · 無題 · 渡江雲の調べ

明るい銅、新しく刻まれた歯。 封じようとして、手を止める。 @@ -369,7 +369,7 @@

乙四《無題 · 渡江雲

乙五《無題 · 十六字令》

銅。鑰齒新裁付掌中。天寒了,加飯且從容。
- +

B5 · 無題 · 十六字令の調べ

銅。 歯を新しく刻んだ鍵を、あなたの掌へ。 @@ -391,7 +391,7 @@
+

A3 · 鷓鴣天の調べ · あなたから鍵を贈られ、数語の書きつけが添えられていた。灯の下で広げて読む

新しく刻まれた鍵の歯。私はそれを大切にする。 筆を取り上げる。まだ一字も書かぬうちから、もうためらう。 @@ -424,7 +424,7 @@
+

A4 · 臨江仙の調べ · 甲一を回想して。かつて学友と幾晩か黙って座った。別れてから便りはしだいに薄れ、長い時を経てようやく心を定めた

かつて、ひっそりした廊下で二人は黙って座った。 あのときは、ただありふれたことだと思っていた。 @@ -460,7 +460,7 @@
+

A5 · 臨江仙の調べ · 甲二を回想して。酒のあと、頬に手を添えて階上へ上がり、夜更けに人に問われ、初めて隠し立てをしなかった

あの夜、誰が客と主人を分けただろう。 肩を並べ、夜更けに寄りかかっていた。 @@ -495,7 +495,7 @@
+

A6 · 鷓鴣天の調べ · 甲三を回想して。箱の中の古い鍵は緑青に覆われていた。往復した手紙を思い返し、もの寂しく書く

小さな鍵。年を経て、錆は暗く広がった。 古い手紙を読み終えても、目はまだ冴えている。 @@ -528,7 +528,7 @@
+

A7 · 臨江仙の調べ · 蘭を株分けしてある人へ送る。かつて香草を贈られた時を思い、もの寂しく書く

手で古い蘭を分け、新しく植える。 あの春の温もりを、いまも覚えているだろうか。 @@ -577,7 +577,7 @@

乙六《得某所寄》

- +

B6 · 送られてきたものを受け取って

古い鉢に、移し植えた蘭。 春の痕が幾度かずれた。 @@ -653,7 +653,7 @@

甲八《夜聞舊曲》

- +

A8 · 夜、昔の曲を聞く

あのときは、窓の下で別れた。 いまは、軒先の雨になった。 @@ -696,7 +696,7 @@
+

B7 · 忘川、忘却の川 · 箱を探して古い草稿を見つけた。これ以上持ち歩かず、すべてある人に送り、この詩を添える

灯の下で、昔の詞を読む。 夜も深くなって、ようやく眠れた。 @@ -731,7 +731,7 @@
+

A9 · 鷓鴣天の調べ · 送られてきた古い草稿を受け取り、灯の下で読み終え、箱に残していたものと合わせて甲・乙として編んだ。綴じ上げてからは客が来るたび見せ、この末尾に記す

古びた紙束を二つ、机上にひろげる。 昔の灯影のもと、それぞれが一篇をなしていた。 @@ -766,7 +766,7 @@

甲十《中 遲,是誤了; 歸,也是誤了。

- +

A10 · 中呂 · 山坡羊の調べ · 旧居の前をまた通る

風が顔に当たる。ここで立ち止まる。 鼻先が先に動く。魂のほうが、私より先に着く。 diff --git a/ja/poetry/linjiangxian-20180108/index.html b/ja/poetry/linjiangxian-20180108/index.html index 92a4149..b56ec23 100644 --- a/ja/poetry/linjiangxian-20180108/index.html +++ b/ja/poetry/linjiangxian-20180108/index.html @@ -127,7 +127,7 @@

《臨江仙》

- +

臨江仙の調べ

麹と麦芽、塩と梅に、古い調合法はない。塵が来ても、芳しい流れにはまだ波が立たない。 簾の前、去ろうとすれば、影が先に留まる。 diff --git a/ja/poetry/linjiangxian-20260909/index.html b/ja/poetry/linjiangxian-20260909/index.html index 302834e..f55356f 100644 --- a/ja/poetry/linjiangxian-20260909/index.html +++ b/ja/poetry/linjiangxian-20260909/index.html @@ -127,7 +127,7 @@

《臨江仙》

- +

臨江仙の調べ

簾の影、幾晩も続いた長い話。 降りはじめた露が欄干を濡らす。 diff --git a/ja/poetry/linjiangxianyin-20191028/index.html b/ja/poetry/linjiangxianyin-20191028/index.html index 18a448d..6cc15c6 100644 --- a/ja/poetry/linjiangxianyin-20191028/index.html +++ b/ja/poetry/linjiangxianyin-20191028/index.html @@ -128,7 +128,7 @@

《臨江仙引》

+

臨江仙引の調べ

囲いは裂け、宴は散る。鐘は夕べに垂れる。しばし、安らぎを盗みとる。 星の街に、あのよい歳月はもうない。 diff --git a/ja/poetry/manjianghong-2022/index.html b/ja/poetry/manjianghong-2022/index.html index d4be868..94d5d7f 100644 --- a/ja/poetry/manjianghong-2022/index.html +++ b/ja/poetry/manjianghong-2022/index.html @@ -134,7 +134,7 @@

《滿江紅 · 更何須揀擇,過門皆璧。 初景寒柯違業識,豐城元禮宜同席。 看收場、針腳又周全,無痕跡。

- +

満江紅の調べ · 引き止めたくとも、こうなるとわかっている

古い裂け目を縫ったばかりなのに、春風はまた、しきりに客を引き止める。 扉は閉じようとし、かえって簾の影が翻り、春を忍び込ませる。 @@ -172,7 +172,7 @@

《 縱衣冠屢換,總稱圭璧。 初景寒柯違業識,豐城元禮宜同席。 曉山塗,晝影祭寒華,猶無息。

- +

満江紅の調べ · 引き止めたくとも、こうなるとわかっている · 別稿

水時計は尽き、鐘は返る。夜明けを促すところ、余韻はなお塞がれている。 扉は閉じようとし、粗末な襟は去ろうとする。それでもまた、よい客を迎える。 diff --git a/ja/poetry/manjianghong-rereading-202610/index.html b/ja/poetry/manjianghong-rereading-202610/index.html index 6b4f074..9c75ce6 100644 --- a/ja/poetry/manjianghong-rereading-202610/index.html +++ b/ja/poetry/manjianghong-rereading-202610/index.html @@ -129,7 +129,7 @@
+

満江紅の調べ · 旧作を読み返し、年月を経て再び消息を交わしたことを思う

古い詞をまた開けば、まず、あの頃注いだ力がわかる。 かつて細かく解きほぐし、わずかな言葉を千たび転じた。息はかすか、声は渋い。 diff --git a/ja/poetry/mantingfang-20191219/index.html b/ja/poetry/mantingfang-20191219/index.html index ccbc258..3e801b5 100644 --- a/ja/poetry/mantingfang-20191219/index.html +++ b/ja/poetry/mantingfang-20191219/index.html @@ -129,7 +129,7 @@

《滿庭芳 · 遙思 把千里關山,盡斂襟前。 幾月光陰忽薄,回眸際、指過眉山。 從頭認,詩還半闋,雙影壓箋邊。

- +

満庭芳の調べ · 遥かに楚潭を思う

風の佩玉がいま静まり、雨が朝の木槿を梳く。文は先に眉の弧を知っていた。 ひと声、低く呼ぶ。夢の弦が驚いて散る。 diff --git a/ja/poetry/pusaman-20261021/index.html b/ja/poetry/pusaman-20261021/index.html index 0993e4e..f5d539c 100644 --- a/ja/poetry/pusaman-20261021/index.html +++ b/ja/poetry/pusaman-20261021/index.html @@ -125,7 +125,7 @@

《菩薩蠻 · 效花 人前儂斂目,金鳳低冠伏。 對面畫雙眉,終同簪作笄。

- +

菩薩蛮の調べ · 花間集の詞風にならって

一つの化粧箱を前に、互いに雲なす髪を結い、髷は低く垂れる。 啼妝は、本物の真珠がよごすのを待つまでもない。 diff --git a/ja/poetry/queqiaoxian-20181222/index.html b/ja/poetry/queqiaoxian-20181222/index.html index 01c0906..eef93e5 100644 --- a/ja/poetry/queqiaoxian-20181222/index.html +++ b/ja/poetry/queqiaoxian-20181222/index.html @@ -125,7 +125,7 @@

《鵲橋仙》

- +

鵲橋仙の調べ

手紙は要らない。古い品は大切にしている。紙にはありふれた言葉ばかり。 柔らかな手の傷を、思いがけず唇が濡らした。幾年を経て、なおどれほど残るのか。 diff --git a/ja/poetry/september-2026/index.html b/ja/poetry/september-2026/index.html index 8559f94..16f018a 100644 --- a/ja/poetry/september-2026/index.html +++ b/ja/poetry/september-2026/index.html @@ -129,7 +129,7 @@

《鷓鴣 言漸杳,露初零。獨餘一語未分明。 頻頻蘸得毫端黑,墨至濃時偏不成。

- +

鷓鴣天の調べ · 幾晩か灯の下で書こうとした、未完

幾晩か、簾の前で一緒に灯芯を切った。 一生ぶんの話をして、また三更まで来た。 @@ -161,7 +161,7 @@

《臨江仙》

- +

臨江仙の調べ

簾の影、幾晩も続いた長い話。 降りはじめた露が欄干を濡らす。 diff --git a/ja/poetry/yingtianchang-20261008/index.html b/ja/poetry/yingtianchang-20261008/index.html index 6239189..c862622 100644 --- a/ja/poetry/yingtianchang-20261008/index.html +++ b/ja/poetry/yingtianchang-20261008/index.html @@ -129,7 +129,7 @@

《應天長·喚回》

- +

應天長の調べ · 呼び戻す

呼び戻してなお、誰も着ていない衣を整える。 袖口の余温は指に残る。 diff --git a/ja/poetry/zhegutian-20260909/index.html b/ja/poetry/zhegutian-20260909/index.html index 375a94d..b6a7e52 100644 --- a/ja/poetry/zhegutian-20260909/index.html +++ b/ja/poetry/zhegutian-20260909/index.html @@ -125,7 +125,7 @@

《鷓鴣 言漸杳,露初零。獨餘一語未分明。 頻頻蘸得毫端黑,墨至濃時偏不成。

- +

鷓鴣天の調べ · 幾晩か灯の下で書こうとした、未完

幾晩か、簾の前で一緒に灯芯を切った。 一生ぶんの話をして、また三更まで来た。 diff --git a/ja/poetry/zhegutian-20261017/index.html b/ja/poetry/zhegutian-20261017/index.html index 292a353..9e70c51 100644 --- a/ja/poetry/zhegutian-20261017/index.html +++ b/ja/poetry/zhegutian-20261017/index.html @@ -125,7 +125,7 @@

呵作霧,燼成花。輿中欹復正疑斜。 筋骸暗替君搖首,載過當停處已賒。

- +

鷓鴣天の調べ · 二更に車を待つ、別の家に泊まって猫に付き添おうとして

一片の短い書きつけが霜を含み、歯にまで届く。 葦毛の馬は出立を待ち、果物が車に満ちている。 diff --git a/package.json b/package.json index 00808ad..66220a5 100644 --- a/package.json +++ b/package.json @@ -12,7 +12,7 @@ "qa:first-love": "python3 tools/firstlovecheck.py", "qa:voucher": "node tools/vouchertypecheck.mjs", "qa:404": "node tools/notfoundcheck.mjs", - "qa": "npm run qa:poetry-library && npm run qa:poetry-kunten-manuscript && npm run qa:poetry-kunten-reader && npm run qa:poetry-kunten-lines && npm run qa:poetry-layout && npm run qa:poetry-kunten && npm run qa:poetry-kunten-recovery && npm run qa:poetry-kunten-multiline && npm run qa:poetry-kunten-zoom && npm run qa:summer-translations && npm run qa:html && npm run qa:first-love && npm run qa:voucher && npm run qa:order-core && npm run qa:shop && npm run qa:pv-configurator && npm run qa:pv-edition && npm run qa:shop-locales && npm run qa:poetry-migration && npm run qa:author-shop && npm run qa:h10-print && npm run qa:tuner && npm run qa:browser && npm run qa:a11y-functional && npm run qa:editorial && npm run qa:404 && npm run qa:about && npm run qa:fonts && npm run qa:wrap", + "qa": "npm run qa:poetry-library && npm run qa:poetry-kunten-manuscript && npm run qa:poetry-kunten-reader && npm run qa:poetry-kunten-lines && npm run qa:poetry-layout && npm run qa:poetry-kunten && npm run qa:poetry-kunten-recovery && npm run qa:poetry-kunten-multiline && npm run qa:poetry-kunten-bands && npm run qa:poetry-kunten-zoom && npm run qa:summer-translations && npm run qa:html && npm run qa:first-love && npm run qa:voucher && npm run qa:order-core && npm run qa:shop && npm run qa:pv-configurator && npm run qa:pv-edition && npm run qa:shop-locales && npm run qa:poetry-migration && npm run qa:author-shop && npm run qa:h10-print && npm run qa:tuner && npm run qa:browser && npm run qa:a11y-functional && npm run qa:editorial && npm run qa:404 && npm run qa:about && npm run qa:fonts && npm run qa:wrap", "qa:editorial": "node tools/editorialcheck.mjs", "qa:shop": "node tools/shopcheck.mjs", "qa:pv-configurator": "node tools/pv-configuratorcheck.mjs", @@ -35,6 +35,7 @@ "qa:poetry-kunten": "node tools/poetrykuntencheck.mjs", "qa:poetry-kunten-recovery": "node tools/poetrykuntenrecoverycheck.mjs", "qa:poetry-kunten-multiline": "node tools/poetrykuntenmultilinecheck.mjs", + "qa:poetry-kunten-bands": "node tools/poetrykuntenbandcheck.mjs", "qa:poetry-kunten-zoom": "node tools/poetrykuntenzoomcheck.mjs" }, "devDependencies": { diff --git a/tools/poetrykuntenbandcheck.mjs b/tools/poetrykuntenbandcheck.mjs new file mode 100644 index 0000000..b1e0711 --- /dev/null +++ b/tools/poetrykuntenbandcheck.mjs @@ -0,0 +1,86 @@ +#!/usr/bin/env node +// Band layout of every kanbun reader on every Japanese poetry page at +// seven widths (Chromium). Bands wrap only between columns; no band may +// hold a single column, at the end or in the middle (2026-10-22), and a +// two-stanza poem that cannot sit in one band splits at its stanza break +// (浣溪沙 at 390: 上片 one band, 下片 the next). +import assert from 'node:assert/strict'; +import {readFile,readdir} from 'node:fs/promises'; +import {createServer} from 'node:http'; +import path from 'node:path'; +import {chromium} from 'playwright'; + +const root = process.cwd(); +const data = JSON.parse(await readFile('content/poetry/kunten.json','utf8')).texts; +const library = JSON.parse(await readFile('content/poetry/library.json','utf8')); +const workById = new Map(library.works.map(work=>[work.id,work])); +const versionById = new Map(library.versions.map(version=>[version.id,version])); +const textById = new Map(library.texts.map(text=>[text.id,text])); +for (const tid of Object.keys(data)) { + const work = workById.get(versionById.get(textById.get(tid)?.version)?.work); + assert.ok(work?.route,'Annotated text must resolve to a canonical work: '+tid); +} +// Every generated Japanese page that carries a kanbun reader, including +// collection pages that repeat a poem (e.g. september-2026). +const routes = new Map(); +for (const dir of (await readdir('ja/poetry',{withFileTypes:true})).filter(d=>d.isDirectory())) { + const html = await readFile(path.join('ja/poetry',dir.name,'index.html'),'utf8').catch(()=>''); + const tids = [...html.matchAll(/data-poetry-kanbun-viewer="([^"]+)"/g)].map(m=>m[1]); + if (tids.length) routes.set('/ja/poetry/'+dir.name+'/',tids); +} +const covered = new Set([...routes.values()].flat()); +assert.deepEqual([...covered].sort(),Object.keys(data).sort(),'every annotated text has a reader page'); +const WIDTHS = [1280,1024,768,430,390,360,320]; +// Pinned layouts: [tid, width, expected bands as body-column counts]. +const PINNED = [['huanxisha-20261020-text',390,[3,3]]]; +const mime={'.html':'text/html; charset=utf-8','.css':'text/css','.js':'text/javascript', + '.woff2':'font/woff2','.png':'image/png','.json':'application/json'}; +const server=createServer(async(req,res)=>{ + try{ + let url=decodeURIComponent(new URL(req.url,'http://localhost').pathname); + if(url.endsWith('/'))url+='index.html'; + const file=path.resolve(root,'.'+url); + if(!file.startsWith(root+path.sep))throw Error('Path escape'); + res.writeHead(200,{'Content-Type':mime[path.extname(file)]||'application/octet-stream'}); + res.end(await readFile(file)); + }catch{res.writeHead(404);res.end('Not found');} +}); +await new Promise(done=>server.listen(0,'127.0.0.1',done)); +const base='http://127.0.0.1:'+server.address().port; +const layouts = {}; +let frames=0, wrapped=0; +const browser=await chromium.launch(); +try{ + for(const width of WIDTHS){ + const page=await browser.newPage({viewport:{width,height:900}}); + for(const [route,tids] of routes){ + await page.goto(base+route+'?layout=vertical&kunten=on',{waitUntil:'load'}); + for(const tid of tids){ + const stage=page.locator('[data-poetry-kanbun-viewer="'+tid+'"]'); + await stage.locator('iframe').waitFor({state:'visible',timeout:11000}); + await page.waitForFunction(id=>document.querySelector( + '[data-poetry-kanbun-viewer="'+id+'"]')?.dataset.kanbunReady==='true',tid,{timeout:9000}); + const bands=await stage.locator('iframe').contentFrame().locator('#kanbun-display').evaluate(el=> + [...el.querySelectorAll('.kanbun-band')].map(b=>({ + body:[...b.children].filter(c=>c.dataset.kanbunColumn==='body').length, + stanzas:[...new Set([...b.children].filter(c=>c.dataset.kanbunColumn==='body').map(c=>c.dataset.kanbunStanza))]}))); + const where=tid+' at '+width+'px: '+JSON.stringify(bands.map(b=>b.body)); + assert.ok(bands.length>0,where+' has no band'); + if(bands.length>1){ + wrapped++; + bands.forEach((b,i)=>assert.ok(b.body!==1,where+' band '+i+' holds a single column')); + } + layouts[route+' '+tid+'@'+width]=bands; + frames++; + } + } + await page.close(); + } + for(const [tid,width,expected] of PINNED){ + const bands=Object.entries(layouts).find(([k])=>k.endsWith(' '+tid+'@'+width))[1]; + assert.deepEqual(bands.map(b=>b.body),expected,tid+' at '+width+'px bands'); + assert.deepEqual(bands.map(b=>b.stanzas),expected.map((_,i)=>[String(i)]),tid+' at '+width+'px: one stanza a band'); + } + console.log('poetrykuntenbandcheck: '+frames+' kanbun readers on '+routes.size+' pages at '+WIDTHS.length+' widths (' + +wrapped+' wrapped); no single-column band; 浣溪沙 390px splits at its stanza break PASS'); +}finally{await browser.close();await new Promise(done=>server.close(done));} diff --git a/tools/poetrykuntenmultilinecheck.mjs b/tools/poetrykuntenmultilinecheck.mjs index bc4d974..ac94dcc 100644 --- a/tools/poetrykuntenmultilinecheck.mjs +++ b/tools/poetrykuntenmultilinecheck.mjs @@ -87,6 +87,11 @@ const inspect=async (frame, expected) => { const tops=[...b.children].map(c=>Math.round(box(c).top)); if(new Set(tops).size>1)errors.push('band columns do not all start at the top'); } + // No band holds a single body column once the body wraps (2026-10-22). + if(bands.length>1)bands.forEach((b,i)=>{ + if([...b.children].filter(c=>c.dataset.kanbunColumn==='body').length===1) + errors.push((i===bands.length-1?'last ':'')+'band '+i+' holds a single column'); + }); // A preface is set 低二格 and broken after clauses, short clauses // joining the column before so no column holds only one or two. prefaces.forEach((c,i)=>{