temml 0.9.1 → 0.10.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/temml.mjs CHANGED
@@ -1232,6 +1232,8 @@ defineSymbol(math, textord, "\u2018", "`");
1232
1232
  defineSymbol(math, textord, "$", "\\$");
1233
1233
  defineSymbol(text, textord, "$", "\\$");
1234
1234
  defineSymbol(text, textord, "$", "\\textdollar");
1235
+ defineSymbol(math, textord, "¢", "\\cent");
1236
+ defineSymbol(text, textord, "¢", "\\cent");
1235
1237
  defineSymbol(math, textord, "%", "\\%");
1236
1238
  defineSymbol(text, textord, "%", "\\%");
1237
1239
  defineSymbol(math, textord, "_", "\\_");
@@ -2077,8 +2079,6 @@ function buildMathML(tree, texExpression, style, settings) {
2077
2079
  let wrapper = expression.length === 1 && tag === null && (n1 instanceof MathNode)
2078
2080
  && !(n1.type === "mstyle" && n1.attributes.mathcolor)
2079
2081
  ? expression[0]
2080
- : expression.length > 1 && wrap === "none"
2081
- ? new mathMLTree.MathNode("mrow", expression)
2082
2082
  : setLineBreaks(expression, wrap, settings.displayMode);
2083
2083
 
2084
2084
  if (tag) {
@@ -2093,7 +2093,7 @@ function buildMathML(tree, texExpression, style, settings) {
2093
2093
  wrapper = new mathMLTree.MathNode("semantics", [wrapper, annotation]);
2094
2094
  }
2095
2095
 
2096
- if (wrap !== "none") {
2096
+ if (wrap !== "none" && wrapper.children.length > 1) {
2097
2097
  const maths = [];
2098
2098
  for (let i = 0; i < wrapper.children.length; i++) {
2099
2099
  const math = new mathMLTree.MathNode("math", [wrapper.children[i]]);
@@ -3148,13 +3148,12 @@ defineFunction({
3148
3148
  names: ["\\\\"],
3149
3149
  props: {
3150
3150
  numArgs: 0,
3151
- numOptionalArgs: 1,
3152
- argTypes: ["size"],
3151
+ numOptionalArgs: 0,
3153
3152
  allowedInText: true
3154
3153
  },
3155
3154
 
3156
3155
  handler({ parser }, args, optArgs) {
3157
- const size = optArgs[0];
3156
+ const size = parser.gullet.future().text === "[" ? parser.parseSizeGroup(true) : null;
3158
3157
  const newLine = !parser.settings.displayMode;
3159
3158
  return {
3160
3159
  type: "cr",
@@ -3907,7 +3906,7 @@ defineFunction({
3907
3906
 
3908
3907
  defineFunction({
3909
3908
  type: "enclose",
3910
- names: ["\\angl", "\\cancel", "\\bcancel", "\\xcancel", "\\sout", "\\overline", "\\underline"],
3909
+ names: ["\\angl", "\\cancel", "\\bcancel", "\\xcancel", "\\sout", "\\overline"],
3911
3910
  // , "\\phase", "\\longdiv"
3912
3911
  props: {
3913
3912
  numArgs: 1
@@ -3924,6 +3923,25 @@ defineFunction({
3924
3923
  mathmlBuilder: mathmlBuilder$8
3925
3924
  });
3926
3925
 
3926
+ defineFunction({
3927
+ type: "enclose",
3928
+ names: ["\\underline"],
3929
+ props: {
3930
+ numArgs: 1,
3931
+ allowedInText: true
3932
+ },
3933
+ handler({ parser, funcName }, args) {
3934
+ const body = args[0];
3935
+ return {
3936
+ type: "enclose",
3937
+ mode: parser.mode,
3938
+ label: funcName,
3939
+ body
3940
+ };
3941
+ },
3942
+ mathmlBuilder: mathmlBuilder$8
3943
+ });
3944
+
3927
3945
  /**
3928
3946
  * All registered environments.
3929
3947
  * `environments.js` exports this same dictionary again and makes it public.
@@ -4895,7 +4913,6 @@ defineFunction({
4895
4913
  "\\mathscr",
4896
4914
  "\\mathsf",
4897
4915
  "\\mathtt",
4898
- "\\oldstylenums",
4899
4916
 
4900
4917
  // aliases
4901
4918
  "\\Bbb",
@@ -6729,10 +6746,9 @@ defineFunction({
6729
6746
  }
6730
6747
  });
6731
6748
 
6732
- // \pmb is a simulation of bold font.
6749
+ // In LaTeX, \pmb is a simulation of bold font.
6733
6750
  // The version of \pmb in ambsy.sty works by typesetting three copies of the argument
6734
- // with small offsets. We use CSS text-shadow.
6735
- // It's a hack. Not as good as a real bold font. Better than nothing.
6751
+ // with small offsets. We use CSS font-weight:bold.
6736
6752
 
6737
6753
  defineFunction({
6738
6754
  type: "pmb",
@@ -6752,7 +6768,7 @@ defineFunction({
6752
6768
  const inner = buildExpression(group.body, style);
6753
6769
  // Wrap with an <mstyle> element.
6754
6770
  const node = wrapWithMstyle(inner);
6755
- node.setAttribute("style", "text-shadow: 0.02em 0.01em 0.04px");
6771
+ node.setAttribute("style", "font-weight:bold");
6756
6772
  return node
6757
6773
  }
6758
6774
  });
@@ -7310,8 +7326,7 @@ const fontMap = {
7310
7326
  mathfrak: "fraktur",
7311
7327
  mathscr: "script",
7312
7328
  mathsf: "sans-serif",
7313
- mathtt: "monospace",
7314
- oldstylenums: "oldstylenums"
7329
+ mathtt: "monospace"
7315
7330
  };
7316
7331
 
7317
7332
  /**
@@ -7381,8 +7396,6 @@ const getVariant = function(group, style) {
7381
7396
  return "sans-serif"
7382
7397
  case "mathtt":
7383
7398
  return "monospace"
7384
- case "oldstylenums":
7385
- return "oldstylenums"
7386
7399
  }
7387
7400
 
7388
7401
  let text = group.text;
@@ -7625,8 +7638,8 @@ const smallCaps = Object.freeze({
7625
7638
  const numberRegEx$1 = /^\d(?:[\d,.]*\d)?$/; // Keep in sync with numberRegEx in Parser.js
7626
7639
  const latinRegEx = /[A-Ba-z]/;
7627
7640
 
7628
- const italicNumber = (text, variant) => {
7629
- const mn = new mathMLTree.MathNode("mn", [text]);
7641
+ const italicNumber = (text, variant, tag) => {
7642
+ const mn = new mathMLTree.MathNode(tag, [text]);
7630
7643
  const wrapper = new mathMLTree.MathNode("mstyle", [mn]);
7631
7644
  wrapper.style["font-style"] = "italic";
7632
7645
  wrapper.style["font-family"] = "Cambria, 'Times New Roman', serif";
@@ -7676,28 +7689,21 @@ defineFunctionBuilders({
7676
7689
  const variant = getVariant(group, style) || "normal";
7677
7690
 
7678
7691
  let node;
7679
- if (group.mode === "text") {
7692
+ if (numberRegEx$1.test(group.text)) {
7693
+ const tag = group.mode === "text" ? "mtext" : "mn";
7680
7694
  if (variant === "italic" || variant === "bold-italic") {
7681
- if (numberRegEx$1.test(group.text)) {
7682
- return italicNumber(text, variant)
7695
+ return italicNumber(text, variant, tag)
7696
+ } else {
7697
+ if (variant !== "normal") {
7698
+ text.text = text.text.split("").map(c => variantChar(c, variant)).join("");
7683
7699
  }
7700
+ node = new mathMLTree.MathNode(tag, [text]);
7684
7701
  }
7702
+ } else if (group.mode === "text") {
7685
7703
  if (variant !== "normal") {
7686
7704
  text.text = variantChar(text.text, variant);
7687
7705
  }
7688
7706
  node = new mathMLTree.MathNode("mtext", [text]);
7689
- } else if (numberRegEx$1.test(group.text)) {
7690
- if (variant === "oldstylenums") {
7691
- const ms = new mathMLTree.MathNode("mstyle", [text], ["oldstylenums"]);
7692
- node = new mathMLTree.MathNode("mn", [ms]);
7693
- } else if (variant === "italic" || variant === "bold-italic") {
7694
- return italicNumber(text, variant)
7695
- } else {
7696
- if (variant !== "normal") {
7697
- text.text = text.text.split("").map(c => variantChar(c, variant)).join("");
7698
- }
7699
- node = new mathMLTree.MathNode("mn", [text]);
7700
- }
7701
7707
  } else if (group.text === "\\prime") {
7702
7708
  node = new mathMLTree.MathNode("mo", [text]);
7703
7709
  // TODO: If/when Chromium uses ssty variant for prime, remove the next line.
@@ -8396,7 +8402,7 @@ defineMacro("\\underbar", "\\underline{\\text{#1}}");
8396
8402
  // \kern6\p@\hbox{.}\hbox{.}\hbox{.}}}
8397
8403
  // We'll call \varvdots, which gets a glyph from symbols.js.
8398
8404
  // The zero-width rule gets us an equivalent to the vertical 6pt kern.
8399
- defineMacro("\\vdots", "\\mathord{\\varvdots\\rule{0pt}{15pt}}");
8405
+ defineMacro("\\vdots", "{\\varvdots\\rule{0pt}{15pt}}");
8400
8406
  defineMacro("\u22ee", "\\vdots");
8401
8407
 
8402
8408
  //////////////////////////////////////////////////////////////////////
@@ -11416,6 +11422,36 @@ const uSubsAndSups = Object.freeze({
11416
11422
  '\u1DBF': 'θ'
11417
11423
  });
11418
11424
 
11425
+ // Used for Unicode input of calligraphic and script letters
11426
+ const asciiFromScript = Object.freeze({
11427
+ "\ud835\udc9c": "A",
11428
+ "\u212c": "B",
11429
+ "\ud835\udc9e": "C",
11430
+ "\ud835\udc9f": "D",
11431
+ "\u2130": "E",
11432
+ "\u2131": "F",
11433
+ "\ud835\udca2": "G",
11434
+ "\u210B": "H",
11435
+ "\u2110": "I",
11436
+ "\ud835\udca5": "J",
11437
+ "\ud835\udca6": "K",
11438
+ "\u2112": "L",
11439
+ "\u2113": "M",
11440
+ "\ud835\udca9": "N",
11441
+ "\ud835\udcaa": "O",
11442
+ "\ud835\udcab": "P",
11443
+ "\ud835\udcac": "Q",
11444
+ "\u211B": "R",
11445
+ "\ud835\udcae": "S",
11446
+ "\ud835\udcaf": "T",
11447
+ "\ud835\udcb0": "U",
11448
+ "\ud835\udcb1": "V",
11449
+ "\ud835\udcb2": "W",
11450
+ "\ud835\udcb3": "X",
11451
+ "\ud835\udcb4": "Y",
11452
+ "\ud835\udcb5": "Z"
11453
+ });
11454
+
11419
11455
  // Mapping of Unicode accent characters to their LaTeX equivalent in text and
11420
11456
  // math mode (when they exist).
11421
11457
  var unicodeAccents = {
@@ -12651,6 +12687,22 @@ class Parser {
12651
12687
  text
12652
12688
  };
12653
12689
  } else {
12690
+ if (asciiFromScript[text]) {
12691
+ // Unicode 14 disambiguates chancery from roundhand.
12692
+ // See https://www.unicode.org/charts/PDF/U1D400.pdf
12693
+ this.consume();
12694
+ const nextCode = this.fetch().text.charCodeAt(0);
12695
+ // mathcal is Temml default. Use mathscript if called for.
12696
+ const font = nextCode === 0xfe01 ? "mathscr" : "mathcal";
12697
+ if (nextCode === 0xfe00 || nextCode === 0xfe01) { this.consume(); }
12698
+ return {
12699
+ type: "font",
12700
+ mode: "math",
12701
+ font,
12702
+ body: { type: "mathord", mode: "math", loc, text: asciiFromScript[text] }
12703
+ }
12704
+ }
12705
+ // Default ord character. No disambiguation necessary.
12654
12706
  s = {
12655
12707
  type: group,
12656
12708
  mode: this.mode,
@@ -12907,7 +12959,7 @@ class Style {
12907
12959
  * https://mit-license.org/
12908
12960
  */
12909
12961
 
12910
- const version = "0.9.1";
12962
+ const version = "0.10.0";
12911
12963
 
12912
12964
  function postProcess(block) {
12913
12965
  const labelMap = {};
@@ -14,7 +14,7 @@
14
14
  * https://mit-license.org/
15
15
  */
16
16
 
17
- const version = "0.9.1";
17
+ const version = "0.10.0";
18
18
 
19
19
  function postProcess(block) {
20
20
  const labelMap = {};
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "temml",
3
- "version": "0.9.1",
3
+ "version": "0.10.0",
4
4
  "description": "TeX to MathML conversion in JavaScript.",
5
5
  "main": "dist/temml.js",
6
6
  "homepage": "https://temml.org",
package/src/Parser.js CHANGED
@@ -7,6 +7,7 @@ import { supportedCodepoint } from "./unicodeScripts";
7
7
  import ParseError from "./ParseError";
8
8
  import { combiningDiacriticalMarksEndRegex } from "./Lexer";
9
9
  import { uSubsAndSups, unicodeSubRegEx } from "./unicodeSupOrSub"
10
+ import { asciiFromScript } from "./asciiFromScript"
10
11
  import SourceLocation from "./SourceLocation";
11
12
  import { Token } from "./Token";
12
13
 
@@ -909,6 +910,22 @@ export default class Parser {
909
910
  text
910
911
  };
911
912
  } else {
913
+ if (asciiFromScript[text]) {
914
+ // Unicode 14 disambiguates chancery from roundhand.
915
+ // See https://www.unicode.org/charts/PDF/U1D400.pdf
916
+ this.consume()
917
+ const nextCode = this.fetch().text.charCodeAt(0)
918
+ // mathcal is Temml default. Use mathscript if called for.
919
+ const font = nextCode === 0xfe01 ? "mathscr" : "mathcal";
920
+ if (nextCode === 0xfe00 || nextCode === 0xfe01) { this.consume() }
921
+ return {
922
+ type: "font",
923
+ mode: "math",
924
+ font,
925
+ body: { type: "mathord", mode: "math", loc, text: asciiFromScript[text] }
926
+ }
927
+ }
928
+ // Default ord character. No disambiguation necessary.
912
929
  s = {
913
930
  type: group,
914
931
  mode: this.mode,
@@ -0,0 +1,29 @@
1
+ // Used for Unicode input of calligraphic and script letters
2
+ export const asciiFromScript = Object.freeze({
3
+ "\ud835\udc9c": "A",
4
+ "\u212c": "B",
5
+ "\ud835\udc9e": "C",
6
+ "\ud835\udc9f": "D",
7
+ "\u2130": "E",
8
+ "\u2131": "F",
9
+ "\ud835\udca2": "G",
10
+ "\u210B": "H",
11
+ "\u2110": "I",
12
+ "\ud835\udca5": "J",
13
+ "\ud835\udca6": "K",
14
+ "\u2112": "L",
15
+ "\u2113": "M",
16
+ "\ud835\udca9": "N",
17
+ "\ud835\udcaa": "O",
18
+ "\ud835\udcab": "P",
19
+ "\ud835\udcac": "Q",
20
+ "\u211B": "R",
21
+ "\ud835\udcae": "S",
22
+ "\ud835\udcaf": "T",
23
+ "\ud835\udcb0": "U",
24
+ "\ud835\udcb1": "V",
25
+ "\ud835\udcb2": "W",
26
+ "\ud835\udcb3": "X",
27
+ "\ud835\udcb4": "Y",
28
+ "\ud835\udcb5": "Z"
29
+ })
@@ -195,8 +195,6 @@ export default function buildMathML(tree, texExpression, style, settings) {
195
195
  let wrapper = expression.length === 1 && tag === null && (n1 instanceof MathNode)
196
196
  && !(n1.type === "mstyle" && n1.attributes.mathcolor)
197
197
  ? expression[0]
198
- : expression.length > 1 && wrap === "none"
199
- ? new mathMLTree.MathNode("mrow", expression)
200
198
  : setLineBreaks(expression, wrap, settings.displayMode)
201
199
 
202
200
  if (tag) {
@@ -211,7 +209,7 @@ export default function buildMathML(tree, texExpression, style, settings) {
211
209
  wrapper = new mathMLTree.MathNode("semantics", [wrapper, annotation]);
212
210
  }
213
211
 
214
- if (wrap !== "none") {
212
+ if (wrap !== "none" && wrapper.children.length > 1) {
215
213
  const maths = []
216
214
  for (let i = 0; i < wrapper.children.length; i++) {
217
215
  const math = new mathMLTree.MathNode("math", [wrapper.children[i]])
@@ -11,13 +11,12 @@ defineFunction({
11
11
  names: ["\\\\"],
12
12
  props: {
13
13
  numArgs: 0,
14
- numOptionalArgs: 1,
15
- argTypes: ["size"],
14
+ numOptionalArgs: 0,
16
15
  allowedInText: true
17
16
  },
18
17
 
19
18
  handler({ parser }, args, optArgs) {
20
- const size = optArgs[0];
19
+ const size = parser.gullet.future().text === "[" ? parser.parseSizeGroup(true) : null;
21
20
  const newLine = !parser.settings.displayMode;
22
21
  return {
23
22
  type: "cr",
@@ -175,7 +175,7 @@ defineFunction({
175
175
 
176
176
  defineFunction({
177
177
  type: "enclose",
178
- names: ["\\angl", "\\cancel", "\\bcancel", "\\xcancel", "\\sout", "\\overline", "\\underline"],
178
+ names: ["\\angl", "\\cancel", "\\bcancel", "\\xcancel", "\\sout", "\\overline"],
179
179
  // , "\\phase", "\\longdiv"
180
180
  props: {
181
181
  numArgs: 1
@@ -191,3 +191,22 @@ defineFunction({
191
191
  },
192
192
  mathmlBuilder
193
193
  });
194
+
195
+ defineFunction({
196
+ type: "enclose",
197
+ names: ["\\underline"],
198
+ props: {
199
+ numArgs: 1,
200
+ allowedInText: true
201
+ },
202
+ handler({ parser, funcName }, args) {
203
+ const body = args[0];
204
+ return {
205
+ type: "enclose",
206
+ mode: parser.mode,
207
+ label: funcName,
208
+ body
209
+ };
210
+ },
211
+ mathmlBuilder
212
+ });
@@ -67,7 +67,6 @@ defineFunction({
67
67
  "\\mathscr",
68
68
  "\\mathsf",
69
69
  "\\mathtt",
70
- "\\oldstylenums",
71
70
 
72
71
  // aliases
73
72
  "\\Bbb",
@@ -2,10 +2,9 @@ import defineFunction, { ordargument } from "../defineFunction"
2
2
  import { wrapWithMstyle } from "../mathMLTree"
3
3
  import * as mml from "../buildMathML"
4
4
 
5
- // \pmb is a simulation of bold font.
5
+ // In LaTeX, \pmb is a simulation of bold font.
6
6
  // The version of \pmb in ambsy.sty works by typesetting three copies of the argument
7
- // with small offsets. We use CSS text-shadow.
8
- // It's a hack. Not as good as a real bold font. Better than nothing.
7
+ // with small offsets. We use CSS font-weight:bold.
9
8
 
10
9
  defineFunction({
11
10
  type: "pmb",
@@ -25,7 +24,7 @@ defineFunction({
25
24
  const inner = mml.buildExpression(group.body, style)
26
25
  // Wrap with an <mstyle> element.
27
26
  const node = wrapWithMstyle(inner)
28
- node.setAttribute("style", "text-shadow: 0.02em 0.01em 0.04px")
27
+ node.setAttribute("style", "font-weight:bold")
29
28
  return node
30
29
  }
31
30
  })
@@ -10,8 +10,8 @@ import * as mml from "../buildMathML"
10
10
  const numberRegEx = /^\d(?:[\d,.]*\d)?$/ // Keep in sync with numberRegEx in Parser.js
11
11
  const latinRegEx = /[A-Ba-z]/
12
12
 
13
- const italicNumber = (text, variant) => {
14
- const mn = new mathMLTree.MathNode("mn", [text])
13
+ const italicNumber = (text, variant, tag) => {
14
+ const mn = new mathMLTree.MathNode(tag, [text])
15
15
  const wrapper = new mathMLTree.MathNode("mstyle", [mn])
16
16
  wrapper.style["font-style"] = "italic"
17
17
  wrapper.style["font-family"] = "Cambria, 'Times New Roman', serif"
@@ -61,28 +61,21 @@ defineFunctionBuilders({
61
61
  const variant = getVariant(group, style) || "normal"
62
62
 
63
63
  let node
64
- if (group.mode === "text") {
64
+ if (numberRegEx.test(group.text)) {
65
+ const tag = group.mode === "text" ? "mtext" : "mn"
65
66
  if (variant === "italic" || variant === "bold-italic") {
66
- if (numberRegEx.test(group.text)) {
67
- return italicNumber(text, variant)
67
+ return italicNumber(text, variant, tag)
68
+ } else {
69
+ if (variant !== "normal") {
70
+ text.text = text.text.split("").map(c => variantChar(c, variant)).join("")
68
71
  }
72
+ node = new mathMLTree.MathNode(tag, [text])
69
73
  }
74
+ } else if (group.mode === "text") {
70
75
  if (variant !== "normal") {
71
76
  text.text = variantChar(text.text, variant)
72
77
  }
73
78
  node = new mathMLTree.MathNode("mtext", [text])
74
- } else if (numberRegEx.test(group.text)) {
75
- if (variant === "oldstylenums") {
76
- const ms = new mathMLTree.MathNode("mstyle", [text], ["oldstylenums"])
77
- node = new mathMLTree.MathNode("mn", [ms])
78
- } else if (variant === "italic" || variant === "bold-italic") {
79
- return italicNumber(text, variant)
80
- } else {
81
- if (variant !== "normal") {
82
- text.text = text.text.split("").map(c => variantChar(c, variant)).join("")
83
- }
84
- node = new mathMLTree.MathNode("mn", [text])
85
- }
86
79
  } else if (group.text === "\\prime") {
87
80
  node = new mathMLTree.MathNode("mo", [text])
88
81
  // TODO: If/when Chromium uses ssty variant for prime, remove the next line.
package/src/macros.js CHANGED
@@ -228,7 +228,7 @@ defineMacro("\\underbar", "\\underline{\\text{#1}}");
228
228
  // \kern6\p@\hbox{.}\hbox{.}\hbox{.}}}
229
229
  // We'll call \varvdots, which gets a glyph from symbols.js.
230
230
  // The zero-width rule gets us an equivalent to the vertical 6pt kern.
231
- defineMacro("\\vdots", "\\mathord{\\varvdots\\rule{0pt}{15pt}}");
231
+ defineMacro("\\vdots", "{\\varvdots\\rule{0pt}{15pt}}");
232
232
  defineMacro("\u22ee", "\\vdots");
233
233
 
234
234
  //////////////////////////////////////////////////////////////////////
@@ -8,7 +8,7 @@
8
8
  * https://mit-license.org/
9
9
  */
10
10
 
11
- export const version = "0.9.1";
11
+ export const version = "0.10.0";
12
12
 
13
13
  export function postProcess(block) {
14
14
  const labelMap = {}
package/src/symbols.js CHANGED
@@ -474,6 +474,8 @@ defineSymbol(math, textord, "\u2018", "`");
474
474
  defineSymbol(math, textord, "$", "\\$");
475
475
  defineSymbol(text, textord, "$", "\\$");
476
476
  defineSymbol(text, textord, "$", "\\textdollar");
477
+ defineSymbol(math, textord, "¢", "\\cent");
478
+ defineSymbol(text, textord, "¢", "\\cent");
477
479
  defineSymbol(math, textord, "%", "\\%");
478
480
  defineSymbol(text, textord, "%", "\\%");
479
481
  defineSymbol(math, textord, "_", "\\_");
package/src/variant.js CHANGED
@@ -17,8 +17,7 @@ const fontMap = {
17
17
  mathfrak: "fraktur",
18
18
  mathscr: "script",
19
19
  mathsf: "sans-serif",
20
- mathtt: "monospace",
21
- oldstylenums: "oldstylenums"
20
+ mathtt: "monospace"
22
21
  }
23
22
 
24
23
  /**
@@ -88,8 +87,6 @@ export const getVariant = function(group, style) {
88
87
  return "sans-serif"
89
88
  case "mathtt":
90
89
  return "monospace"
91
- case "oldstylenums":
92
- return "oldstylenums"
93
90
  default:
94
91
  break
95
92
  }