Skip to content

Commit ff1734f

Browse files
edemaineylemkimon
andauthored
fix: \char support for >16-bit Unicode characters (#3006)
* fix: \char support for >16-bit Unicode characters `String.fromCharCode` only supports Unicode characters up to 16-bit. `String.fromCodePoint` from ECMAScript 2015 supports all Unicode code points. Unfortunately, IE doesn't support the latter, so use former as fallback. Fixes #3004 Co-authored-by: ylemkimon <y@ylem.kim>
1 parent 90dcaef commit ff1734f

File tree

2 files changed

+19
-2
lines changed

2 files changed

+19
-2
lines changed

src/functions/char.js

Lines changed: 13 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -21,14 +21,25 @@ defineFunction({
2121
const node = assertNodeType(group[i], "textord");
2222
number += node.text;
2323
}
24-
const code = parseInt(number);
24+
let code = parseInt(number);
25+
let text;
2526
if (isNaN(code)) {
2627
throw new ParseError(`\\@char has non-numeric argument ${number}`);
28+
// If we drop IE support, the following code could be replaced with
29+
// text = String.fromCodePoint(code)
30+
} else if (code < 0 || code >= 0x10ffff) {
31+
throw new ParseError(`\\@char with invalid code point ${number}`);
32+
} else if (code <= 0xffff) {
33+
text = String.fromCharCode(code);
34+
} else { // Astral code point; split into surrogate halves
35+
code -= 0x10000;
36+
text = String.fromCharCode((code >> 10) + 0xd800,
37+
(code & 0x3ff) + 0xdc00);
2738
}
2839
return {
2940
type: "textord",
3041
mode: parser.mode,
31-
text: String.fromCharCode(code),
42+
text: text,
3243
};
3344
},
3445
});

test/katex-spec.js

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3313,6 +3313,12 @@ describe("A macro expander", function() {
33133313
expect(parsedChar[0].type).toEqual("textord");
33143314
});
33153315

3316+
it("\\char handles >16-bit characters", () => {
3317+
const parsed = getParsed('\\char"1d7d9');
3318+
expect(parsed[0].type).toEqual("textord");
3319+
expect(parsed[0].text).toEqual("𝟙");
3320+
});
3321+
33163322
it("should build Unicode private area characters", function() {
33173323
expect`\gvertneqq\lvertneqq\ngeqq\ngeqslant\nleqq`.toBuild();
33183324
expect`\nleqslant\nshortmid\nshortparallel\varsubsetneq`.toBuild();

0 commit comments

Comments
 (0)