katex 0.14.0 → 0.15.2

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/katex.mjs CHANGED
@@ -260,7 +260,126 @@ var utils = {
260
260
  };
261
261
 
262
262
  /* eslint no-console:0 */
263
+ // TODO: automatically generate documentation
264
+ // TODO: check all properties on Settings exist
265
+ // TODO: check the type of a property on Settings matches
266
+ var SETTINGS_SCHEMA = {
267
+ displayMode: {
268
+ type: "boolean",
269
+ description: "Render math in display mode, which puts the math in " + "display style (so \\int and \\sum are large, for example), and " + "centers the math on the page on its own line.",
270
+ cli: "-d, --display-mode"
271
+ },
272
+ output: {
273
+ type: {
274
+ enum: ["htmlAndMathml", "html", "mathml"]
275
+ },
276
+ description: "Determines the markup language of the output.",
277
+ cli: "-F, --format <type>"
278
+ },
279
+ leqno: {
280
+ type: "boolean",
281
+ description: "Render display math in leqno style (left-justified tags)."
282
+ },
283
+ fleqn: {
284
+ type: "boolean",
285
+ description: "Render display math flush left."
286
+ },
287
+ throwOnError: {
288
+ type: "boolean",
289
+ default: true,
290
+ cli: "-t, --no-throw-on-error",
291
+ cliDescription: "Render errors (in the color given by --error-color) ins" + "tead of throwing a ParseError exception when encountering an error."
292
+ },
293
+ errorColor: {
294
+ type: "string",
295
+ default: "#cc0000",
296
+ cli: "-c, --error-color <color>",
297
+ cliDescription: "A color string given in the format 'rgb' or 'rrggbb' " + "(no #). This option determines the color of errors rendered by the " + "-t option.",
298
+ cliProcessor: color => "#" + color
299
+ },
300
+ macros: {
301
+ type: "object",
302
+ cli: "-m, --macro <def>",
303
+ cliDescription: "Define custom macro of the form '\\foo:expansion' (use " + "multiple -m arguments for multiple macros).",
304
+ cliDefault: [],
305
+ cliProcessor: (def, defs) => {
306
+ defs.push(def);
307
+ return defs;
308
+ }
309
+ },
310
+ minRuleThickness: {
311
+ type: "number",
312
+ description: "Specifies a minimum thickness, in ems, for fraction lines," + " `\\sqrt` top lines, `{array}` vertical lines, `\\hline`, " + "`\\hdashline`, `\\underline`, `\\overline`, and the borders of " + "`\\fbox`, `\\boxed`, and `\\fcolorbox`.",
313
+ processor: t => Math.max(0, t),
314
+ cli: "--min-rule-thickness <size>",
315
+ cliProcessor: parseFloat
316
+ },
317
+ colorIsTextColor: {
318
+ type: "boolean",
319
+ description: "Makes \\color behave like LaTeX's 2-argument \\textcolor, " + "instead of LaTeX's one-argument \\color mode change.",
320
+ cli: "-b, --color-is-text-color"
321
+ },
322
+ strict: {
323
+ type: [{
324
+ enum: ["warn", "ignore", "error"]
325
+ }, "boolean", "function"],
326
+ description: "Turn on strict / LaTeX faithfulness mode, which throws an " + "error if the input uses features that are not supported by LaTeX.",
327
+ cli: "-S, --strict",
328
+ cliDefault: false
329
+ },
330
+ trust: {
331
+ type: ["boolean", "function"],
332
+ description: "Trust the input, enabling all HTML features such as \\url.",
333
+ cli: "-T, --trust"
334
+ },
335
+ maxSize: {
336
+ type: "number",
337
+ default: Infinity,
338
+ description: "If non-zero, all user-specified sizes, e.g. in " + "\\rule{500em}{500em}, will be capped to maxSize ems. Otherwise, " + "elements and spaces can be arbitrarily large",
339
+ processor: s => Math.max(0, s),
340
+ cli: "-s, --max-size <n>",
341
+ cliProcessor: parseInt
342
+ },
343
+ maxExpand: {
344
+ type: "number",
345
+ default: 1000,
346
+ description: "Limit the number of macro expansions to the specified " + "number, to prevent e.g. infinite macro loops. If set to Infinity, " + "the macro expander will try to fully expand as in LaTeX.",
347
+ processor: n => Math.max(0, n),
348
+ cli: "-e, --max-expand <n>",
349
+ cliProcessor: n => n === "Infinity" ? Infinity : parseInt(n)
350
+ },
351
+ globalGroup: {
352
+ type: "boolean",
353
+ cli: false
354
+ }
355
+ };
356
+
357
+ function getDefaultValue(schema) {
358
+ if (schema.default) {
359
+ return schema.default;
360
+ }
361
+
362
+ var type = schema.type;
363
+ var defaultType = Array.isArray(type) ? type[0] : type;
364
+
365
+ if (typeof defaultType !== 'string') {
366
+ return defaultType.enum[0];
367
+ }
368
+
369
+ switch (defaultType) {
370
+ case 'boolean':
371
+ return false;
372
+
373
+ case 'string':
374
+ return '';
263
375
 
376
+ case 'number':
377
+ return 0;
378
+
379
+ case 'object':
380
+ return {};
381
+ }
382
+ }
264
383
  /**
265
384
  * The main Settings object
266
385
  *
@@ -271,6 +390,8 @@ var utils = {
271
390
  * math (true), meaning that the math starts in \displaystyle
272
391
  * and is placed in a block with vertical margin.
273
392
  */
393
+
394
+
274
395
  class Settings {
275
396
  constructor(options) {
276
397
  this.displayMode = void 0;
@@ -289,20 +410,16 @@ class Settings {
289
410
  this.globalGroup = void 0;
290
411
  // allow null options
291
412
  options = options || {};
292
- this.displayMode = utils.deflt(options.displayMode, false);
293
- this.output = utils.deflt(options.output, "htmlAndMathml");
294
- this.leqno = utils.deflt(options.leqno, false);
295
- this.fleqn = utils.deflt(options.fleqn, false);
296
- this.throwOnError = utils.deflt(options.throwOnError, true);
297
- this.errorColor = utils.deflt(options.errorColor, "#cc0000");
298
- this.macros = options.macros || {};
299
- this.minRuleThickness = Math.max(0, utils.deflt(options.minRuleThickness, 0));
300
- this.colorIsTextColor = utils.deflt(options.colorIsTextColor, false);
301
- this.strict = utils.deflt(options.strict, "warn");
302
- this.trust = utils.deflt(options.trust, false);
303
- this.maxSize = Math.max(0, utils.deflt(options.maxSize, Infinity));
304
- this.maxExpand = Math.max(0, utils.deflt(options.maxExpand, 1000));
305
- this.globalGroup = utils.deflt(options.globalGroup, false);
413
+
414
+ for (var prop in SETTINGS_SCHEMA) {
415
+ if (SETTINGS_SCHEMA.hasOwnProperty(prop)) {
416
+ // $FlowFixMe
417
+ var schema = SETTINGS_SCHEMA[prop]; // TODO: validate options
418
+ // $FlowFixMe
419
+
420
+ this[prop] = options[prop] !== undefined ? schema.processor ? schema.processor(options[prop]) : options[prop] : getDefaultValue(schema);
421
+ }
422
+ }
306
423
  }
307
424
  /**
308
425
  * Report nonstrict (non-LaTeX-compatible) input.
@@ -9866,6 +9983,17 @@ function defineEnvironment(_ref) {
9866
9983
  }
9867
9984
  }
9868
9985
 
9986
+ /**
9987
+ * All registered global/built-in macros.
9988
+ * `macros.js` exports this same dictionary again and makes it public.
9989
+ * `Parser.js` requires this dictionary via `macros.js`.
9990
+ */
9991
+ var _macros = {}; // This function might one day accept an additional argument and do more things.
9992
+
9993
+ function defineMacro(name, body) {
9994
+ _macros[name] = body;
9995
+ }
9996
+
9869
9997
  // Helper functions
9870
9998
  function getHLines(parser) {
9871
9999
  // Return an array. The array length = number of hlines.
@@ -9890,7 +10018,19 @@ var validateAmsEnvironmentContext = context => {
9890
10018
  if (!settings.displayMode) {
9891
10019
  throw new ParseError("{" + context.envName + "} can be used only in" + " display mode.");
9892
10020
  }
9893
- };
10021
+ }; // autoTag (an argument to parseArray) can be one of three values:
10022
+ // * undefined: Regular (not-top-level) array; no tags on each row
10023
+ // * true: Automatic equation numbering, overridable by \tag
10024
+ // * false: Tags allowed on each row, but no automatic numbering
10025
+ // This function *doesn't* work with the "split" environment name.
10026
+
10027
+
10028
+ function getAutoTag(name) {
10029
+ if (name.indexOf("ed") === -1) {
10030
+ return name.indexOf("*") === -1;
10031
+ } // return undefined;
10032
+
10033
+ }
9894
10034
  /**
9895
10035
  * Parse the body of the environment, with rows delimited by \\ and
9896
10036
  * columns delimited by &, and create a nested list in row-major order
@@ -9906,7 +10046,7 @@ function parseArray(parser, _ref, style) {
9906
10046
  cols,
9907
10047
  arraystretch,
9908
10048
  colSeparationType,
9909
- addEqnNum,
10049
+ autoTag,
9910
10050
  singleRow,
9911
10051
  emptySingleRow,
9912
10052
  maxNumCols,
@@ -9941,7 +10081,29 @@ function parseArray(parser, _ref, style) {
9941
10081
  var row = [];
9942
10082
  var body = [row];
9943
10083
  var rowGaps = [];
9944
- var hLinesBeforeRow = []; // Test for \hline at the top of the array.
10084
+ var hLinesBeforeRow = [];
10085
+ var tags = autoTag != null ? [] : undefined; // amsmath uses \global\@eqnswtrue and \global\@eqnswfalse to represent
10086
+ // whether this row should have an equation number. Simulate this with
10087
+ // a \@eqnsw macro set to 1 or 0.
10088
+
10089
+ function beginRow() {
10090
+ if (autoTag) {
10091
+ parser.gullet.macros.set("\\@eqnsw", "1", true);
10092
+ }
10093
+ }
10094
+
10095
+ function endRow() {
10096
+ if (tags) {
10097
+ if (parser.gullet.macros.get("\\df@tag")) {
10098
+ tags.push(parser.subparse([new Token("\\df@tag")]));
10099
+ parser.gullet.macros.set("\\df@tag", undefined, true);
10100
+ } else {
10101
+ tags.push(Boolean(autoTag) && parser.gullet.macros.get("\\@eqnsw") === "1");
10102
+ }
10103
+ }
10104
+ }
10105
+
10106
+ beginRow(); // Test for \hline at the top of the array.
9945
10107
 
9946
10108
  hLinesBeforeRow.push(getHLines(parser));
9947
10109
 
@@ -9982,10 +10144,11 @@ function parseArray(parser, _ref, style) {
9982
10144
 
9983
10145
  parser.consume();
9984
10146
  } else if (next === "\\end") {
9985
- // Arrays terminate newlines with `\crcr` which consumes a `\cr` if
10147
+ endRow(); // Arrays terminate newlines with `\crcr` which consumes a `\cr` if
9986
10148
  // the last line is empty. However, AMS environments keep the
9987
10149
  // empty row if it's the only one.
9988
10150
  // NOTE: Currently, `cell` is the last item added into `row`.
10151
+
9989
10152
  if (row.length === 1 && cell.type === "styling" && cell.body[0].body.length === 0 && (body.length > 1 || !emptySingleRow)) {
9990
10153
  body.pop();
9991
10154
  }
@@ -10007,11 +10170,13 @@ function parseArray(parser, _ref, style) {
10007
10170
  size = parser.parseSizeGroup(true);
10008
10171
  }
10009
10172
 
10010
- rowGaps.push(size ? size.value : null); // check for \hline(s) following the row separator
10173
+ rowGaps.push(size ? size.value : null);
10174
+ endRow(); // check for \hline(s) following the row separator
10011
10175
 
10012
10176
  hLinesBeforeRow.push(getHLines(parser));
10013
10177
  row = [];
10014
10178
  body.push(row);
10179
+ beginRow();
10015
10180
  } else {
10016
10181
  throw new ParseError("Expected & or \\\\ or \\cr or \\end", parser.nextToken);
10017
10182
  }
@@ -10032,7 +10197,7 @@ function parseArray(parser, _ref, style) {
10032
10197
  hskipBeforeAndAfter,
10033
10198
  hLinesBeforeRow,
10034
10199
  colSeparationType,
10035
- addEqnNum,
10200
+ tags,
10036
10201
  leqno
10037
10202
  };
10038
10203
  } // Decides on a style for cells in an array according to whether the given
@@ -10170,20 +10335,33 @@ var htmlBuilder$7 = function htmlBuilder(group, options) {
10170
10335
  var cols = [];
10171
10336
  var colSep;
10172
10337
  var colDescrNum;
10173
- var eqnNumSpans = [];
10338
+ var tagSpans = [];
10174
10339
 
10175
- if (group.addEqnNum) {
10176
- // An environment with automatic equation numbers.
10177
- // Create node(s) that will trigger CSS counter increment.
10340
+ if (group.tags && group.tags.some(tag => tag)) {
10341
+ // An environment with manual tags and/or automatic equation numbers.
10342
+ // Create node(s), the latter of which trigger CSS counter increment.
10178
10343
  for (r = 0; r < nr; ++r) {
10179
10344
  var rw = body[r];
10180
10345
  var shift = rw.pos - offset;
10181
- var eqnTag = buildCommon.makeSpan(["eqn-num"], [], options);
10182
- eqnTag.depth = rw.depth;
10183
- eqnTag.height = rw.height;
10184
- eqnNumSpans.push({
10346
+ var tag = group.tags[r];
10347
+ var tagSpan = void 0;
10348
+
10349
+ if (tag === true) {
10350
+ // automatic numbering
10351
+ tagSpan = buildCommon.makeSpan(["eqn-num"], [], options);
10352
+ } else if (tag === false) {
10353
+ // \nonumber/\notag or starred environment
10354
+ tagSpan = buildCommon.makeSpan([], [], options);
10355
+ } else {
10356
+ // manual \tag
10357
+ tagSpan = buildCommon.makeSpan([], buildExpression$1(tag, options, true), options);
10358
+ }
10359
+
10360
+ tagSpan.depth = rw.depth;
10361
+ tagSpan.height = rw.height;
10362
+ tagSpans.push({
10185
10363
  type: "elem",
10186
- elem: eqnTag,
10364
+ elem: tagSpan,
10187
10365
  shift
10188
10366
  });
10189
10367
  }
@@ -10319,12 +10497,12 @@ var htmlBuilder$7 = function htmlBuilder(group, options) {
10319
10497
  }, options);
10320
10498
  }
10321
10499
 
10322
- if (!group.addEqnNum) {
10500
+ if (tagSpans.length === 0) {
10323
10501
  return buildCommon.makeSpan(["mord"], [body], options);
10324
10502
  } else {
10325
10503
  var eqnNumCol = buildCommon.makeVList({
10326
10504
  positionType: "individualShift",
10327
- children: eqnNumSpans
10505
+ children: tagSpans
10328
10506
  }, options);
10329
10507
  eqnNumCol = buildCommon.makeSpan(["tag"], [eqnNumCol], options);
10330
10508
  return buildCommon.makeFragment([body, eqnNumCol]);
@@ -10350,7 +10528,7 @@ var mathmlBuilder$6 = function mathmlBuilder(group, options) {
10350
10528
  row.push(new mathMLTree.MathNode("mtd", [buildGroup(rw[j], options)]));
10351
10529
  }
10352
10530
 
10353
- if (group.addEqnNum) {
10531
+ if (group.tags && group.tags[i]) {
10354
10532
  row.unshift(glue);
10355
10533
  row.push(glue);
10356
10534
 
@@ -10485,13 +10663,14 @@ var alignedHandler = function alignedHandler(context, args) {
10485
10663
 
10486
10664
  var cols = [];
10487
10665
  var separationType = context.envName.indexOf("at") > -1 ? "alignat" : "align";
10666
+ var isSplit = context.envName === "split";
10488
10667
  var res = parseArray(context.parser, {
10489
10668
  cols,
10490
10669
  addJot: true,
10491
- addEqnNum: context.envName === "align" || context.envName === "alignat",
10670
+ autoTag: isSplit ? undefined : getAutoTag(context.envName),
10492
10671
  emptySingleRow: true,
10493
10672
  colSeparationType: separationType,
10494
- maxNumCols: context.envName === "split" ? 2 : undefined,
10673
+ maxNumCols: isSplit ? 2 : undefined,
10495
10674
  leqno: context.parser.settings.leqno
10496
10675
  }, "display"); // Determining number of columns.
10497
10676
  // 1. If the first argument is given, we use it as a number of columns,
@@ -10851,7 +11030,7 @@ defineEnvironment({
10851
11030
  }],
10852
11031
  addJot: true,
10853
11032
  colSeparationType: "gather",
10854
- addEqnNum: context.envName === "gather",
11033
+ autoTag: getAutoTag(context.envName),
10855
11034
  emptySingleRow: true,
10856
11035
  leqno: context.parser.settings.leqno
10857
11036
  };
@@ -10884,7 +11063,7 @@ defineEnvironment({
10884
11063
  handler(context) {
10885
11064
  validateAmsEnvironmentContext(context);
10886
11065
  var res = {
10887
- addEqnNum: context.envName === "equation",
11066
+ autoTag: getAutoTag(context.envName),
10888
11067
  emptySingleRow: true,
10889
11068
  singleRow: true,
10890
11069
  maxNumCols: 1,
@@ -10910,7 +11089,9 @@ defineEnvironment({
10910
11089
 
10911
11090
  htmlBuilder: htmlBuilder$7,
10912
11091
  mathmlBuilder: mathmlBuilder$6
10913
- }); // Catch \hline outside array environment
11092
+ });
11093
+ defineMacro("\\nonumber", "\\gdef\\@eqnsw{0}");
11094
+ defineMacro("\\notag", "\\nonumber"); // Catch \hline outside array environment
10914
11095
 
10915
11096
  defineFunction({
10916
11097
  type: "text",
@@ -11010,7 +11191,7 @@ function mathmlBuilder$5(group, options) {
11010
11191
  var inner = buildExpression(group.body, options);
11011
11192
 
11012
11193
  if (group.mclass === "minner") {
11013
- return mathMLTree.newDocumentFragment(inner);
11194
+ node = new mathMLTree.MathNode("mpadded", inner);
11014
11195
  } else if (group.mclass === "mord") {
11015
11196
  if (group.isCharacterBox) {
11016
11197
  node = inner[0];
@@ -11038,6 +11219,10 @@ function mathmlBuilder$5(group, options) {
11038
11219
  } else if (group.mclass === "mopen" || group.mclass === "mclose") {
11039
11220
  node.attributes.lspace = "0em";
11040
11221
  node.attributes.rspace = "0em";
11222
+ } else if (group.mclass === "minner") {
11223
+ node.attributes.lspace = "0.0556em"; // 1 mu is the most likely option
11224
+
11225
+ node.attributes.width = "+0.1111em";
11041
11226
  } // MathML <mo> default space is 5/18 em, so <mrel> needs no action.
11042
11227
  // Ref: https://developer.mozilla.org/en-US/docs/Web/MathML/Element/mo
11043
11228
 
@@ -13036,17 +13221,6 @@ defineFunction({
13036
13221
  mathmlBuilder: mathmlBuilder$1
13037
13222
  });
13038
13223
 
13039
- /**
13040
- * All registered global/built-in macros.
13041
- * `macros.js` exports this same dictionary again and makes it public.
13042
- * `Parser.js` requires this dictionary via `macros.js`.
13043
- */
13044
- var _macros = {}; // This function might one day accept an additional argument and do more things.
13045
-
13046
- function defineMacro(name, body) {
13047
- _macros[name] = body;
13048
- }
13049
-
13050
13224
  // NOTE: Unlike most `htmlBuilder`s, this one handles not only
13051
13225
  // "operatorname", but also "supsub" since \operatorname* can
13052
13226
  // affect super/subscripting.
@@ -13427,6 +13601,26 @@ defineFunction({
13427
13601
 
13428
13602
  });
13429
13603
 
13604
+ defineFunction({
13605
+ type: "internal",
13606
+ names: ["\\relax"],
13607
+ props: {
13608
+ numArgs: 0,
13609
+ allowedInText: true
13610
+ },
13611
+
13612
+ handler(_ref) {
13613
+ var {
13614
+ parser
13615
+ } = _ref;
13616
+ return {
13617
+ type: "internal",
13618
+ mode: parser.mode
13619
+ };
13620
+ }
13621
+
13622
+ });
13623
+
13430
13624
  defineFunction({
13431
13625
  type: "rule",
13432
13626
  names: ["\\rule"],
@@ -14675,7 +14869,7 @@ class Namespace {
14675
14869
 
14676
14870
  for (var undef in undefs) {
14677
14871
  if (undefs.hasOwnProperty(undef)) {
14678
- if (undefs[undef] === undefined) {
14872
+ if (undefs[undef] == null) {
14679
14873
  delete this.current[undef];
14680
14874
  } else {
14681
14875
  this.current[undef] = undefs[undef];
@@ -14725,6 +14919,7 @@ class Namespace {
14725
14919
  * Local set() sets the current value and (when appropriate) adds an undo
14726
14920
  * operation to the undo stack. Global set() may change the undo
14727
14921
  * operation at every level, so takes time linear in their number.
14922
+ * A value of undefined means to delete existing definitions.
14728
14923
  */
14729
14924
 
14730
14925
 
@@ -14756,7 +14951,11 @@ class Namespace {
14756
14951
  }
14757
14952
  }
14758
14953
 
14759
- this.current[name] = value;
14954
+ if (value == null) {
14955
+ delete this.current[name];
14956
+ } else {
14957
+ this.current[name] = value;
14958
+ }
14760
14959
  }
14761
14960
 
14762
14961
  }
@@ -15132,7 +15331,7 @@ defineMacro("\\varOmega", "\\mathit{\\Omega}"); //\newcommand{\substack}[1]{\sub
15132
15331
  defineMacro("\\substack", "\\begin{subarray}{c}#1\\end{subarray}"); // \renewcommand{\colon}{\nobreak\mskip2mu\mathpunct{}\nonscript
15133
15332
  // \mkern-\thinmuskip{:}\mskip6muplus1mu\relax}
15134
15333
 
15135
- defineMacro("\\colon", "\\nobreak\\mskip2mu\\mathpunct{}" + "\\mathchoice{\\mkern-3mu}{\\mkern-3mu}{}{}{:}\\mskip6mu"); // \newcommand{\boxed}[1]{\fbox{\m@th$\displaystyle#1$}}
15334
+ defineMacro("\\colon", "\\nobreak\\mskip2mu\\mathpunct{}" + "\\mathchoice{\\mkern-3mu}{\\mkern-3mu}{}{}{:}\\mskip6mu\\relax"); // \newcommand{\boxed}[1]{\fbox{\m@th$\displaystyle#1$}}
15136
15335
 
15137
15336
  defineMacro("\\boxed", "\\fbox{$\\displaystyle{#1}$}"); // \def\iff{\DOTSB\;\Longleftrightarrow\;}
15138
15337
  // \def\implies{\DOTSB\;\Longrightarrow\;}
@@ -15659,8 +15858,6 @@ defineMacro("\\kaGreen", "\\textcolor{##71B307}{#1}");
15659
15858
  // List of commands that act like macros but aren't defined as a macro,
15660
15859
  // function, or symbol. Used in `isDefined`.
15661
15860
  var implicitCommands = {
15662
- "\\relax": true,
15663
- // MacroExpander.js
15664
15861
  "^": true,
15665
15862
  // Parser.js
15666
15863
  "_": true,
@@ -16024,15 +16221,13 @@ class MacroExpander {
16024
16221
  var expanded = this.expandOnce(); // expandOnce returns Token if and only if it's fully expanded.
16025
16222
 
16026
16223
  if (expanded instanceof Token) {
16027
- // \relax stops the expansion, but shouldn't get returned (a
16028
- // null return value couldn't get implemented as a function).
16029
16224
  // the token after \noexpand is interpreted as if its meaning
16030
16225
  // were ‘\relax’
16031
- if (expanded.text === "\\relax" || expanded.treatAsRelax) {
16032
- this.stack.pop();
16033
- } else {
16034
- return this.stack.pop(); // === expanded
16226
+ if (expanded.treatAsRelax) {
16227
+ expanded.text = "\\relax";
16035
16228
  }
16229
+
16230
+ return this.stack.pop(); // === expanded
16036
16231
  }
16037
16232
  } // Flow unable to figure out that this pathway is impossible.
16038
16233
  // https://github.com/facebook/flow/issues/4808
@@ -16698,6 +16893,25 @@ class Parser {
16698
16893
  this.gullet.endGroups();
16699
16894
  }
16700
16895
  }
16896
+ /**
16897
+ * Fully parse a separate sequence of tokens as a separate job.
16898
+ * Tokens should be specified in reverse order, as in a MacroDefinition.
16899
+ */
16900
+
16901
+
16902
+ subparse(tokens) {
16903
+ // Save the next token from the current job.
16904
+ var oldToken = this.nextToken;
16905
+ this.consume(); // Run the new job, terminating it with an excess '}'
16906
+
16907
+ this.gullet.pushToken(new Token("}"));
16908
+ this.gullet.pushTokens(tokens);
16909
+ var parse = this.parseExpression(false);
16910
+ this.expect("}"); // Restore the next token from the current job.
16911
+
16912
+ this.nextToken = oldToken;
16913
+ return parse;
16914
+ }
16701
16915
 
16702
16916
  /**
16703
16917
  * Parses an "expression", which is a list of atoms.
@@ -17639,12 +17853,11 @@ var parseTree = function parseTree(toParse, settings) {
17639
17853
  throw new ParseError("\\tag works only in display equations");
17640
17854
  }
17641
17855
 
17642
- parser.gullet.feed("\\df@tag");
17643
17856
  tree = [{
17644
17857
  type: "tag",
17645
17858
  mode: "text",
17646
17859
  body: tree,
17647
- tag: parser.parse()
17860
+ tag: parser.subparse([new Token("\\df@tag")])
17648
17861
  }];
17649
17862
  }
17650
17863
 
@@ -17746,7 +17959,7 @@ var katex = {
17746
17959
  /**
17747
17960
  * Current KaTeX version
17748
17961
  */
17749
- version: "0.14.0",
17962
+ version: "0.15.2",
17750
17963
 
17751
17964
  /**
17752
17965
  * Renders the given LaTeX into an HTML+MathML combination, and adds
@@ -17765,6 +17978,11 @@ var katex = {
17765
17978
  */
17766
17979
  ParseError,
17767
17980
 
17981
+ /**
17982
+ * The shema of Settings
17983
+ */
17984
+ SETTINGS_SCHEMA,
17985
+
17768
17986
  /**
17769
17987
  * Parses the given LaTeX into KaTeX's internal parse tree structure,
17770
17988
  * without rendering to HTML or MathML.
package/katex.js CHANGED
@@ -9,7 +9,7 @@
9
9
  */
10
10
 
11
11
  import ParseError from "./src/ParseError";
12
- import Settings from "./src/Settings";
12
+ import Settings, {SETTINGS_SCHEMA} from "./src/Settings";
13
13
 
14
14
  import {buildTree, buildHTMLTree} from "./src/buildTree";
15
15
  import parseTree from "./src/parseTree";
@@ -156,6 +156,10 @@ export default {
156
156
  * KaTeX error, usually during parsing.
157
157
  */
158
158
  ParseError,
159
+ /**
160
+ * The shema of Settings
161
+ */
162
+ SETTINGS_SCHEMA,
159
163
  /**
160
164
  * Parses the given LaTeX into KaTeX's internal parse tree structure,
161
165
  * without rendering to HTML or MathML.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "katex",
3
- "version": "0.14.0",
3
+ "version": "0.15.2",
4
4
  "description": "Fast math typesetting for the web.",
5
5
  "main": "dist/katex.js",
6
6
  "exports": {
@@ -47,7 +47,7 @@
47
47
  "dist/"
48
48
  ],
49
49
  "license": "MIT",
50
- "packageManager": "yarn@3.0.1",
50
+ "packageManager": "yarn@3.1.1",
51
51
  "devDependencies": {
52
52
  "@babel/core": "^7.10.4",
53
53
  "@babel/eslint-parser": "^7.15.0",
@@ -115,7 +115,7 @@
115
115
  "sri-toolbox": "^0.2.0",
116
116
  "style-loader": "^3.0.0",
117
117
  "stylelint": "^14.0.0",
118
- "stylelint-config-standard": "^23.0.0",
118
+ "stylelint-config-standard": "^24.0.0",
119
119
  "terser-webpack-plugin": "^5.0.3",
120
120
  "webpack": "^5.51.1",
121
121
  "webpack-bundle-analyzer": "^4.0.0",
@@ -20,7 +20,6 @@ import type Settings from "./Settings";
20
20
  // List of commands that act like macros but aren't defined as a macro,
21
21
  // function, or symbol. Used in `isDefined`.
22
22
  export const implicitCommands = {
23
- "\\relax": true, // MacroExpander.js
24
23
  "^": true, // Parser.js
25
24
  "_": true, // Parser.js
26
25
  "\\limits": true, // Parser.js
@@ -333,15 +332,12 @@ export default class MacroExpander implements MacroContextInterface {
333
332
  const expanded = this.expandOnce();
334
333
  // expandOnce returns Token if and only if it's fully expanded.
335
334
  if (expanded instanceof Token) {
336
- // \relax stops the expansion, but shouldn't get returned (a
337
- // null return value couldn't get implemented as a function).
338
335
  // the token after \noexpand is interpreted as if its meaning
339
336
  // were ‘\relax’
340
- if (expanded.text === "\\relax" || expanded.treatAsRelax) {
341
- this.stack.pop();
342
- } else {
343
- return this.stack.pop(); // === expanded
337
+ if (expanded.treatAsRelax) {
338
+ expanded.text = "\\relax";
344
339
  }
340
+ return this.stack.pop(); // === expanded
345
341
  }
346
342
  }
347
343