diff --git a/docs/changelog.html b/docs/changelog.html index 66e96e8..adbd6e4 100644 --- a/docs/changelog.html +++ b/docs/changelog.html @@ -1,4 +1,4 @@ - +
@@ -432,6 +432,43 @@ body font-feature-settings: "kern", "liga"; } +/* Inline 色塊 (background-bearing inline boxes: code / kbd / mark / badge) + need EXTERNAL breathing room from the preceding text, distinct from juzhen's + text autospace (jz-hws, 0.25em). Without it the box's own padding is the only + visible space — which reads as space ON the block, not BETWEEN text and block, + so the box crowds the preceding glyph (worst at slide scale). A left margin + is the right tool: it sits OUTSIDE the background box. Only margin-left — the + trailing side stays governed by the juzhen pill (jz-hws before following + content, tight before CJK punctuation), so a box-then-、 still hugs. Scoped to + prose containers so `pre code` / diff / code blocks are unaffected. */ +/* NB: NO `:is()` here — Paged.js's CSS parser (academic mode) splits selector + lists on commas INSIDE `:is(...)`, yielding invalid fragments that abort + pagination. Selectors are spelled out instead. */ +code, kbd, mark, .badge +{ + margin-left: 0.25em; +} +/* Code blocks / diff columns are byte-aligned mono — no leading margin. */ +pre code, .diff-block code, .diff-block kbd +{ + margin-left: 0; +} +/* …and NOT when the box follows CJK punctuation: juzhen binds a box+trailing- + punctuation into a `jz-jinze`, so a box-group right after another jz-jinze + (which ends in that punctuation), or a box right after a punctuation jz-char, + is punctuation-preceded — there the box must hug it (else 「、 資訊」 floats). */ +jz-char + code, +jz-char + kbd, +jz-char + mark, +jz-char + .badge, +jz-jinze + jz-jinze > code:first-child, +jz-jinze + jz-jinze > kbd:first-child, +jz-jinze + jz-jinze > mark:first-child, +jz-jinze + jz-jinze > .badge:first-child +{ + margin-left: 0; +} + /* Mono opt-out: lock weight back to Regular (body inherits Medium 500), disable all CJK width-substitution / typography features so diff / code / table columns stay byte-aligned, and revert any inherited @@ -831,35 +868,41 @@ jz-jinze, jz-em { font: inherit; color: inherit; + text-indent: 0; + hanging-punctuation: none; +} +jz-char, +jz-jinze { + text-decoration: inherit; } /* src/css/_lang.css */ -:where(.juzhen):lang(zh-Hans), -:where(.juzhen) :lang(zh-Hans) { +:where(.juzhen:lang(zh-Hans)), +:where(.juzhen [lang]:lang(zh-Hans)) { font-family: "Noto Serif SC", "Noto Serif CJK SC", "Source Han Serif SC", serif; } -:where(.juzhen):lang(zh-Hant), -:where(.juzhen) :lang(zh-Hant) { +:where(.juzhen:lang(zh-Hant)), +:where(.juzhen [lang]:lang(zh-Hant)) { font-family: "Noto Serif TC", "Noto Serif CJK TC", "Source Han Serif TC", serif; } -:where(.juzhen):lang(zh-HK), -:where(.juzhen) :lang(zh-HK) { +:where(.juzhen:lang(zh-HK)), +:where(.juzhen [lang]:lang(zh-HK)) { font-family: "Noto Serif HK", "Noto Serif CJK HK", "Noto Serif TC", serif; } -:where(.juzhen):lang(ja), -:where(.juzhen) :lang(ja) { +:where(.juzhen:lang(ja)), +:where(.juzhen [lang]:lang(ja)) { font-family: "Noto Serif JP", "Noto Serif CJK JP", @@ -882,11 +925,55 @@ jz-char { jz-inner { display: inline; } +[data-jz-atoms=inline] jz-char { + display: inline; +} jz-char.jz-half jz-inner, jz-char.jz-half-le jz-inner { font-feature-settings: "halt" 1; -webkit-font-feature-settings: "halt" 1; } +[data-jz-halfwidth=margin] jz-char.jz-half jz-inner, +[data-jz-halfwidth=margin] jz-char.jz-half-le jz-inner { + font-feature-settings: normal; + -webkit-font-feature-settings: normal; +} +[data-jz-halfwidth=margin] jz-char.jz-half.jz-ink-left, +[data-jz-halfwidth=margin] jz-char.jz-half.jz-ink-center, +[data-jz-halfwidth=margin] jz-char.jz-half.jz-ink-right, +[data-jz-halfwidth=margin] jz-char.jz-half-le.jz-ink-left, +[data-jz-halfwidth=margin] jz-char.jz-half-le.jz-ink-center, +[data-jz-halfwidth=margin] jz-char.jz-half-le.jz-ink-right { + width: 0.5em; + overflow: visible; +} +[data-jz-halfwidth=margin] jz-char.jz-half.jz-ink-left jz-inner, +[data-jz-halfwidth=margin] jz-char.jz-half.jz-ink-center jz-inner, +[data-jz-halfwidth=margin] jz-char.jz-half.jz-ink-right jz-inner, +[data-jz-halfwidth=margin] jz-char.jz-half-le.jz-ink-left jz-inner, +[data-jz-halfwidth=margin] jz-char.jz-half-le.jz-ink-center jz-inner, +[data-jz-halfwidth=margin] jz-char.jz-half-le.jz-ink-right jz-inner { + display: inline-block; +} +[data-jz-halfwidth=margin] jz-char.jz-ink-center jz-inner { + margin-left: -0.25em; +} +[data-jz-halfwidth=margin] jz-char.jz-ink-right jz-inner { + margin-left: -0.5em; +} +[data-jz-halfwidth=margin] jz-char jz-inner { + text-decoration: inherit; +} +[data-jz-halfwidth=halt] jz-char.jz-half jz-inner, +[data-jz-halfwidth=halt] jz-char.jz-half-le jz-inner { + font-feature-settings: "halt" 1; + -webkit-font-feature-settings: "halt" 1; + margin-left: 0; +} +[data-jz-halfwidth=halt] jz-char.jz-half, +[data-jz-halfwidth=halt] jz-char.jz-half-le { + width: auto; +} /* src/css/_jinze.css */ jz-jinze { @@ -894,6 +981,9 @@ jz-jinze { white-space: nowrap; vertical-align: baseline; } +[data-jz-atoms=inline] jz-jinze { + display: inline; +} /* src/css/juzhen.css */ @@ -980,23 +1070,37 @@ kbd color: var(--fg); } -/* ---------- Opt-in line numbers () ---------- - behavior.js rebuilds each line as N - …line…, injecting the number as LITERAL TEXT (not a CSS counter) so - it survives Paged.js pagination — counters reset inside flowed content. - Inert unless the author adds class="lineno"; copy keeps the raw code only. */ +/* ---------- Line blocks () ---------- + behavior.js rebuilds each code line as a block …line… + (prepending N only for opt-in). + Block-per-line so a paginator (Paged.js) fragments BETWEEN lines — never mid- + text-node — preserving each line's leading indent across page breaks, and the + literal-text line number survives pagination (CSS counters reset in flowed + content). academic line-blocks every; other modes only `.lineno`. + `break-inside: avoid` keeps a soft-wrapped line whole on one page. */ pre.lineno > code { display: block; } -pre.lineno .cl +.cl { display: block; white-space: pre-wrap; text-indent: 0; + break-inside: avoid; } -pre.lineno .lno +/* 帶行號者:懸掛縮進——首行以負 text-indent 把行號拉進左側 gutter,折行的續行則 + 對齊 padding-left(即行號欄之後),不再溢到行號左側。gutter 寬 = .lno 之 + width+padding+border+margin 之和(約 3.6em)。 */ +pre.lineno .cl +{ + padding-left: 3.6em; + text-indent: -3.6em; +} +.lno { display: inline-block; - width: 2.5em; - margin-right: 1em; + width: 2.4em; + padding-right: 0.6em; + margin-right: 0.6em; + border-right: 1px solid var(--border); /* 行號與內文之間的清晰界線(逐行 border 堆疊成連續豎線) */ text-align: right; color: var(--muted); opacity: 0.7; @@ -2438,6 +2542,22 @@ main > *:nth-child(n+6) { animation-delay: 0.46s; }聚珍(Juzhen)/cjk-autospace 變更紀錄。← 回文檔
+下游回饋修復批次 2026-06-03
+聚焦 Peek.nvim 等下游回饋之原子透明與中西間隙正確性,皆以真實 Chromium 量測驗證(jsdom 之 TreeWalker/offset 失真,不可信)。
+ +修復
++
+ +- 原子透明(段落繼承屬性漏溢):
+jz-*inline-block 原子對消費端段落樣式透明——歸零會被原子重複套用之text-indent/hanging-punctuation(過套用),並令原子text-decoration: inherit以接續段落下劃線(欠套用)。段落首行縮排正常、下劃線連續不斷,消費端無需配置。- 中西間隙 ·
+gapTrim自我應驗:行末去隙原依「後字是否在更低行」判定,而後字落點受間隙自身(及下游間隙)之margin推擠,致行中間隙被誤 trim——表現為容器寬相關之「最後一個間隙消失」、行內codepill 跨行時右側間隙消失。改為「起始全部 trim、由左至右逐一定案」,量測不受任何margin污染。- 中西間隙 · 西文字集完整化:補入貨幣符號(
+€等 U+20A0–20BF)、拉丁擴充 A/B(拼音聲調 ā ǎ ē)、西里爾、數學運算符,並把希臘補全至含 α-ω。鄰接 CJK 之手工空格遂正規化、邊界補隙。列舉法以\uXXXX表示、無需 regex flag,相容 2016/Windows 10 時代瀏覽器。- 標點誤隙:全角省略號 …… 後接 CJK 不再誤補隙(
+DOTS_CJK移除|…);收尾彎引號 ” 後接拉丁/數字不再補隙(移除 panguQUOTE_AN偏例,與 」』)》】〕 等所有收尾標點一致)。全部常用中文標點 × 簡繁共 104 例稽核,CJK 間皆 0 誤隙。工具
++
+- +
demo/resize-check.html:可拖曳容器檢查頁——拖動方框寬度,驗證中西間隙在各寬度下恆穩、標點無誤隙;可切justify與「顯示間隙」描邊。v2 切片 1 · 增補 2026-06
切片 1 之上的修補與強化,聚焦標點半形對缺
@@ -2520,6 +2640,19 @@ main > *:nth-child(n+6) { animation-delay: 0.46s; }halt字型之支援,及下游回饋之邊界/分頁器修復。