mirror of https://github.com/garrytan/gstack.git
fix(make-pdf): correct CJK rendering — NUL sentinel hardening, SC-first fonts, CJK quote context
Three CJK fixes in the PDF pipeline: - smartypants strips stray input NULs up front so document text can never forge the U+0000 placeholder sentinel and leak a preserved-zone marker into the output. - The CJK font stack led with Japanese families, so Simplified-Chinese text rendered han glyphs with JP variants. Lead with PingFang SC / Heiti SC / Noto Sans CJK SC / Source Han Sans SC before the JP fallbacks. - Quote-smartening only recognized ASCII openers as "start of quote" context; the fullwidth colon and CJK brackets now count, so quotes after them curl the right way. Contributed by @rssprivacy-commits (PR #2012). Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This commit is contained in:
parent
6e8e987133
commit
58482b3c69
|
|
@ -37,8 +37,8 @@
|
|||
// Metric-compatible sans stack: Helvetica (macOS), Liberation Sans (Linux,
|
||||
// ships via fonts-liberation), Arial (Windows). Shared by every text surface.
|
||||
const SANS_STACK = `Helvetica, "Liberation Sans", Arial`;
|
||||
// CJK fallback families, appended to the body stack only.
|
||||
const CJK_STACK = `"Hiragino Kaku Gothic ProN", "Noto Sans CJK JP", "Microsoft YaHei"`;
|
||||
// CJK fallback families (Simplified-Chinese first), appended to the body stack only.
|
||||
const CJK_STACK = `"PingFang SC", "Heiti SC", "Noto Sans CJK SC", "Source Han Sans SC", "Microsoft YaHei", "Hiragino Kaku Gothic ProN", "Noto Sans CJK JP"`;
|
||||
// Color-emoji families: Apple (macOS), Segoe (Windows), Noto (Linux).
|
||||
const EMOJI_FAMILIES = `"Apple Color Emoji", "Segoe UI Emoji", "Noto Color Emoji"`;
|
||||
|
||||
|
|
|
|||
|
|
@ -49,7 +49,7 @@ export function smartypants(html: string): string {
|
|||
});
|
||||
};
|
||||
|
||||
let s = html;
|
||||
let s = html.replace(/\u0000/g, ""); // drop stray input NUL (can't forge a placeholder)
|
||||
s = carve(s, CODE_ZONE_RE);
|
||||
s = carve(s, TAG_RE);
|
||||
s = carve(s, URL_RE);
|
||||
|
|
@ -94,11 +94,11 @@ function transformText(text: string): string {
|
|||
|
||||
// Double quotes: open if preceded by whitespace/bol, close if preceded
|
||||
// by word char or punctuation.
|
||||
s = s.replace(/(^|[\s\(\[\{\-])"/g, "$1\u201c"); // opening "
|
||||
s = s.replace(/(^|[\s\(\[\{\-\uff1a\uff08\u3010\u300c\u300e\u3008\u300a])"/g, "$1\u201c"); // opening "
|
||||
s = s.replace(/"/g, "\u201d"); // remaining " are closing
|
||||
|
||||
// Single quotes (after apostrophe pass):
|
||||
s = s.replace(/(^|[\s\(\[\{\-])'/g, "$1\u2018"); // opening '
|
||||
s = s.replace(/(^|[\s\(\[\{\-\uff1a\uff08\u3010\u300c\u300e\u3008\u300a])'/g, "$1\u2018"); // opening '
|
||||
s = s.replace(/'/g, "\u2019"); // remaining ' are closing
|
||||
|
||||
return s;
|
||||
|
|
|
|||
Loading…
Reference in New Issue