|
| 1 | +export const FONT_FAMILY = '"Hiragino Sans", "Hiragino Kaku Gothic ProN", "Noto Sans CJK SC", "Microsoft YaHei", sans-serif' |
| 2 | +export const FONT_SIZE = 17 |
| 3 | +export const LINE_HEIGHT = 28 |
| 4 | +export const FONT = `${FONT_SIZE}px ${FONT_FAMILY}` |
| 5 | +export const PADDING = 16 |
| 6 | + |
| 7 | +export const DEMO_TEXT = |
| 8 | + '排字师记录道:「禁则换行先看行首,再看行尾。」' + |
| 9 | + '他翻开《排版指南》第三章,找到〈标点规则〉一节。' + |
| 10 | + '书中写道:"行首禁止出现句号。或逗号,以及顿号、' + |
| 11 | + '感叹号!问号?分号;冒号:等标点。"' + |
| 12 | + '全角括号(如这样)与〔龟甲括号〕也有讲究。' + |
| 13 | + '日文引号「单引」与『双引』不可拆开,' + |
| 14 | + '黑括号【注释】和白括号〖标记〗同理。' + |
| 15 | + '花括号〘测试〙与方括号〚数据〛也遵守此规则。' + |
| 16 | + '此外,中点・用于分隔,长音符ー延长发音,' + |
| 17 | + '重复符々々表示叠字,竖排符〻亦然。' + |
| 18 | + '平假名迭代ゝゞ与片假名迭代ヽヾ是日文特有标记。' + |
| 19 | + '全角句点.和全角逗号,在某些风格中也常出现。' + |
| 20 | + '右尖括号〉与右双尖括号》同为行首禁止。' + |
| 21 | + '最后确认:左括号(、左〔、左〈、左《、左「、左『、' + |
| 22 | + '左【、左〖、左〘、左〚均不可出现在行尾……以上就是全部规则。' |
| 23 | + |
| 24 | +// --- i18n --- |
| 25 | + |
| 26 | +export type Lang = 'en' | 'zh' |
| 27 | +export type I18n = { en: string; zh: string } |
| 28 | + |
| 29 | +export const UI: Record<Lang, { |
| 30 | + title: string |
| 31 | + intro: string |
| 32 | + rulesTitle: string |
| 33 | + rulesDescription: string |
| 34 | +}> = { |
| 35 | + en: { |
| 36 | + title: 'CJK Line Breaking', |
| 37 | + intro: 'CJK kinsoku rules prevent punctuation from appearing at invalid line positions. Adjust the width to watch Pretext enforce these rules at every line break.', |
| 38 | + rulesTitle: 'Kinsoku Rules Reference', |
| 39 | + rulesDescription: 'Characters listed below are enforced by Pretext during line breaking. Click any entry to highlight it in the preview above.', |
| 40 | + }, |
| 41 | + zh: { |
| 42 | + title: 'CJK 禁则换行', |
| 43 | + intro: 'CJK 禁则处理(kinsoku)确保标点不会出现在错误的行首或行尾。调整宽度观察 Pretext 如何在每次换行时执行这些规则。', |
| 44 | + rulesTitle: '禁则规则速查', |
| 45 | + rulesDescription: '以下列出的字符由 Pretext 在换行时强制执行。点击任意条目可在上方预览中高亮显示。', |
| 46 | + }, |
| 47 | +} |
| 48 | + |
| 49 | +// --- Rule definitions --- |
| 50 | + |
| 51 | +export type RuleGroupEntry = { |
| 52 | + char: string |
| 53 | + unicode: string |
| 54 | + name: I18n |
| 55 | +} |
| 56 | + |
| 57 | +export type RuleGroup = { |
| 58 | + title: I18n |
| 59 | + description: I18n |
| 60 | + entries: RuleGroupEntry[] |
| 61 | +} |
| 62 | + |
| 63 | +export const RULE_GROUPS: RuleGroup[] = [ |
| 64 | + { |
| 65 | + title: { en: 'Line-start prohibited', zh: '行首禁则' }, |
| 66 | + description: { |
| 67 | + en: 'These characters must not appear at the start of a line. When a break falls just before one, the engine pulls it back to the end of the previous line.', |
| 68 | + zh: '这些字符不能出现在行首。当换行点恰好落在这些字符之前时,引擎会将它们吸附到上一行末尾。', |
| 69 | + }, |
| 70 | + entries: [ |
| 71 | + { char: '\uFF0C', unicode: 'FF0C', name: { en: 'Fullwidth comma', zh: '全角逗号' } }, |
| 72 | + { char: '\uFF0E', unicode: 'FF0E', name: { en: 'Fullwidth full stop', zh: '全角句点' } }, |
| 73 | + { char: '\uFF01', unicode: 'FF01', name: { en: 'Fullwidth exclamation', zh: '全角感叹号' } }, |
| 74 | + { char: '\uFF1A', unicode: 'FF1A', name: { en: 'Fullwidth colon', zh: '全角冒号' } }, |
| 75 | + { char: '\uFF1B', unicode: 'FF1B', name: { en: 'Fullwidth semicolon', zh: '全角分号' } }, |
| 76 | + { char: '\uFF1F', unicode: 'FF1F', name: { en: 'Fullwidth question mark', zh: '全角问号' } }, |
| 77 | + { char: '\u3001', unicode: '3001', name: { en: 'Ideographic comma', zh: '顿号' } }, |
| 78 | + { char: '\u3002', unicode: '3002', name: { en: 'Ideographic full stop', zh: '句号' } }, |
| 79 | + { char: '\u30FB', unicode: '30FB', name: { en: 'Katakana middle dot', zh: '中点' } }, |
| 80 | + { char: '\uFF09', unicode: 'FF09', name: { en: 'Fullwidth right paren', zh: '全角右括号' } }, |
| 81 | + { char: '\u3015', unicode: '3015', name: { en: 'Right tortoise bracket', zh: '右龟甲括号' } }, |
| 82 | + { char: '\u3009', unicode: '3009', name: { en: 'Right angle bracket', zh: '右尖括号' } }, |
| 83 | + { char: '\u300B', unicode: '300B', name: { en: 'Right double angle bracket', zh: '右书名号' } }, |
| 84 | + { char: '\u300D', unicode: '300D', name: { en: 'Right corner bracket', zh: '右单引号' } }, |
| 85 | + { char: '\u300F', unicode: '300F', name: { en: 'Right white corner bracket', zh: '右双引号' } }, |
| 86 | + { char: '\u3011', unicode: '3011', name: { en: 'Right black lenticular bracket', zh: '右黑括号' } }, |
| 87 | + { char: '\u3017', unicode: '3017', name: { en: 'Right white lenticular bracket', zh: '右白括号' } }, |
| 88 | + { char: '\u3019', unicode: '3019', name: { en: 'Right white tortoise bracket', zh: '右花括号' } }, |
| 89 | + { char: '\u301B', unicode: '301B', name: { en: 'Right white square bracket', zh: '右方括号' } }, |
| 90 | + { char: '\u30FC', unicode: '30FC', name: { en: 'Katakana prolonged sound', zh: '长音符' } }, |
| 91 | + { char: '\u3005', unicode: '3005', name: { en: 'Ideographic iteration mark', zh: '汉字重复符' } }, |
| 92 | + { char: '\u303B', unicode: '303B', name: { en: 'Vertical ideographic iteration', zh: '竖排重复符' } }, |
| 93 | + { char: '\u309D', unicode: '309D', name: { en: 'Hiragana iteration mark', zh: '平假名迭代符' } }, |
| 94 | + { char: '\u309E', unicode: '309E', name: { en: 'Hiragana voiced iteration', zh: '平假名浊迭代符' } }, |
| 95 | + { char: '\u30FD', unicode: '30FD', name: { en: 'Katakana iteration mark', zh: '片假名迭代符' } }, |
| 96 | + { char: '\u30FE', unicode: '30FE', name: { en: 'Katakana voiced iteration', zh: '片假名浊迭代符' } }, |
| 97 | + ], |
| 98 | + }, |
| 99 | + { |
| 100 | + title: { en: 'Line-end prohibited', zh: '行尾禁则' }, |
| 101 | + description: { |
| 102 | + en: 'These characters must not appear at the end of a line. When a break falls just after one, the engine pushes it to the start of the next line.', |
| 103 | + zh: '这些字符不能出现在行尾。当换行点恰好落在这些字符之后时,引擎会将它们推到下一行开头。', |
| 104 | + }, |
| 105 | + entries: [ |
| 106 | + { char: '\uFF08', unicode: 'FF08', name: { en: 'Fullwidth left paren', zh: '全角左括号' } }, |
| 107 | + { char: '\u3014', unicode: '3014', name: { en: 'Left tortoise bracket', zh: '左龟甲括号' } }, |
| 108 | + { char: '\u3008', unicode: '3008', name: { en: 'Left angle bracket', zh: '左尖括号' } }, |
| 109 | + { char: '\u300A', unicode: '300A', name: { en: 'Left double angle bracket', zh: '左书名号' } }, |
| 110 | + { char: '\u300C', unicode: '300C', name: { en: 'Left corner bracket', zh: '左单引号' } }, |
| 111 | + { char: '\u300E', unicode: '300E', name: { en: 'Left white corner bracket', zh: '左双引号' } }, |
| 112 | + { char: '\u3010', unicode: '3010', name: { en: 'Left black lenticular bracket', zh: '左黑括号' } }, |
| 113 | + { char: '\u3016', unicode: '3016', name: { en: 'Left white lenticular bracket', zh: '左白括号' } }, |
| 114 | + { char: '\u3018', unicode: '3018', name: { en: 'Left white tortoise bracket', zh: '左花括号' } }, |
| 115 | + { char: '\u301A', unicode: '301A', name: { en: 'Left white square bracket', zh: '左方括号' } }, |
| 116 | + ], |
| 117 | + }, |
| 118 | + { |
| 119 | + title: { en: 'Left-sticky punctuation', zh: '左粘连标点' }, |
| 120 | + description: { |
| 121 | + en: 'These marks stick to the preceding character and will not be broken onto the next line alone. Overlaps with line-start rules but applies in broader contexts.', |
| 122 | + zh: '这些标点紧跟前面的文字,不会被单独断到下一行。与行首禁则有部分重叠,但作用于更广泛的上下文。', |
| 123 | + }, |
| 124 | + entries: [ |
| 125 | + { char: '\u3002', unicode: '3002', name: { en: 'Ideographic full stop', zh: '句号' } }, |
| 126 | + { char: '\u3001', unicode: '3001', name: { en: 'Ideographic comma', zh: '顿号' } }, |
| 127 | + { char: '\u2026', unicode: '2026', name: { en: 'Horizontal ellipsis', zh: '省略号' } }, |
| 128 | + ], |
| 129 | + }, |
| 130 | +] |
0 commit comments