Mojikumi: a middle dot beside a bracket keeps only its quarter em (JLREQ 3.1.4)

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_013phQ3ekq6uGBEWD6FjFYG2
This commit is contained in:
con3codeandClaude Opus 5.5 committed 2026-10-20 19:33:13 +09:00
1 parent 91d4c66b24
commit 5248ad683c
2 files changed
+21 -8

No files matched your search

+20 -7
View File
@@ -127,13 +127,21 @@ impl<'a> Rules<'a> {
return Aki::fixed(if self.base == Base::LineEndHalfEm { 0.0 } else { trailing(left) });
}
// Consecutive punctuation in the Japanese sets (JLREQ 3.1.4): opening brackets together,
// and closing brackets, commas and full stops together, touch. Other neighbours keep the
// larger blank, so a closing bracket and an opening one are half an em apart. The Chinese
// sets keep the larger blank throughout.
// and closing brackets, commas and full stops together, touch. A middle dot (・:;) after
// a closing bracket or before an opening one keeps only its own quarter em. Other
// neighbours keep the larger blank, so a closing bracket and an opening one are half an
// em apart. The Chinese sets keep the larger blank throughout.
let opening = |c| matches!(c, 1 | 26 | 27);
let closing = |c| matches!(c, 2 | 6 | 21 | 28..=31);
if self.base != Base::Chinese && ((opening(left) && opening(right)) || (closing(left) && closing(right))) {
return Aki::default();
let closing_bracket = |c| matches!(c, 2 | 28 | 29);
let middle_dot = |c| matches!(c, 5 | 32);
if self.base != Base::Chinese {
if (opening(left) && opening(right)) || (closing(left) && closing(right)) {
return Aki::default();
}
if (closing_bracket(left) && middle_dot(right)) || (middle_dot(left) && opening(right)) {
return Aki { min: 0.0, desired: 0.25, max: 0.25, priority: 1, discrete: false };
}
}
let punctuation = trailing(left).max(leading(right));
if punctuation > 0.0 {
@@ -260,12 +268,17 @@ mod tests {
for (a, b) in [('」', '「'), ('。', '「'), ('、', '('), ('」', '漢'), ('漢', '「')] {
assert_eq!(aki(a, b), 0.5, "{set}: {a}{b}");
}
assert_eq!(aki('」', '・'), 0.5, "{set}: the larger blank stays");
// A middle dot keeps its quarter em beside a bracket (JLREQ 3.1.4, Figure 69 ⑦).
for (a, b) in [('」', '・'), (')', ':'), ('』', ';'), ('・', '「'), (';', '('), (':', '〈')] {
assert_eq!(aki(a, b), 0.25, "{set}: {a}{b}");
}
// After a comma or full stop the larger blank stays.
assert_eq!(aki('、', '・'), 0.5, "{set}: 、・");
}
// The Chinese sets are unchanged: the larger blank stays between any two marks.
for set in ["SimpChineseDefault", "TradChineseDefault"] {
let rules = Rules::resolve(&styles, set).unwrap().unwrap();
for (a, b) in [('」', '。'), (',', ')'), ('「', '『'), ('」', '「')] {
for (a, b) in [('」', '。'), (',', ')'), ('「', '『'), ('」', '「'), ('」', '・'), ('・', '「')] {
assert_eq!(rules.pair(class(a), class(b)).desired, 0.5, "{set}: {a}{b}");
}
}
+1 -1
View File
@@ -37,7 +37,7 @@ presets or tables are copied. Our default mojikumi and kinsoku tables are built
| Vertical metrics and shaping | done: upright runs shaped top to bottom (`vert`; `vkrn`/`vpal` when asked) with `vmtx`/`VORG` advances and origins, centred on the ideographic em box (`BASE`, else OS/2); turned runs shaped horizontally, without `vrt2`; Horizontal Kana (`hkna`) takes the vertical kana (`vkna`) in upright runs. Default location of variable fonts only (no `VVAR`) |
| Kinsoku | named (hard, soft, Chinese, Korean) and custom kinsoku sets, bunri-kinshi, rensuuji, hanging punctuation (regular, force); without a set, fixed no-start / no-end lists and a break anywhere between CJK characters; kinsoku type (push in / push out priorities) kept but not applied |
| Korean line breaking | at spaces (Hangul everywhere, hanja in Korean text); per-paragraph character-based breaking (`koreanCharBreaks`); DesignCraft-only, not in IDML |
| Mojikumi | applied in composition: the built-in base sets (line end half-width, line end one em, Simplified and Traditional Chinese) and the document's tables with their override rows, kept through IDML; Preflight notes tables it can't apply. In the Japanese sets consecutive punctuation closes up (JLREQ 3.1.4: 」。, 「『 touch; 」「 half an em apart) |
| Mojikumi | applied in composition: the built-in base sets (line end half-width, line end one em, Simplified and Traditional Chinese) and the document's tables with their override rows, kept through IDML; Preflight notes tables it can't apply. In the Japanese sets consecutive punctuation closes up (JLREQ 3.1.4: 」。, 「『 touch; 」・ a quarter em, 」「 half an em apart). Still open: 、・ and ・・ take the sum of both blanks in JLREQ (Table 1 notes) |
| Aki, tsume, jidori | done ([cjk-typography.md](cjk-typography.md)) |
| Character alignment, leading model | em box top / centre / bottom, ICF top / bottom (`BASE` `icft`/`icfb`, else the em box inset by 5%), roman baseline; aki above / below, centre (centre down as centre); under aki below a line's leading is the space to the line below it; with the Japanese composers (`Composer::Japanese`, `JapaneseSingleLine`, IDML `HL Composer J` / `HL Single J`), the others set lines baseline to baseline on the Roman baseline |
| Tate-chu-yoko | manual, with offsets; auto tate-chu-yoko of short digit runs (with roman letters when asked) in vertical text, narrowed to fit the em (`type.autoTateChuYoko`, IDML `AutoTcy`, `AutoTcyIncludeRoman`); manual groups of 3+ digits overflow the em |