katex 0.15.0 → 0.15.3
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/README.md +3 -3
- package/contrib/copy-tex/README.md +3 -3
- package/contrib/mathtex-script-type/README.md +5 -5
- package/contrib/mhchem/README.md +1 -1
- package/dist/README.md +3 -3
- package/dist/contrib/copy-tex.css +0 -1
- package/dist/contrib/copy-tex.min.css +1 -1
- package/dist/katex.css +1 -1
- package/dist/katex.js +220 -135
- package/dist/katex.min.css +1 -1
- package/dist/katex.min.js +1 -1
- package/dist/katex.mjs +123 -43
- package/package.json +5 -5
- package/src/Namespace.js +9 -4
- package/src/Parser.js +21 -0
- package/src/environments/array.js +72 -18
- package/src/functions/mclass.js +4 -1
- package/src/parseNode.js +2 -1
- package/src/parseTree.js +2 -2
- package/src/symbols.js +3 -3
package/dist/katex.mjs
CHANGED
|
@@ -4465,7 +4465,7 @@ defineSymbol(math, main, bin, "\u2293", "\\sqcap", true);
|
|
|
4465
4465
|
defineSymbol(math, main, bin, "\u2217", "\\ast");
|
|
4466
4466
|
defineSymbol(math, main, bin, "\u2294", "\\sqcup", true);
|
|
4467
4467
|
defineSymbol(math, main, bin, "\u25ef", "\\bigcirc", true);
|
|
4468
|
-
defineSymbol(math, main, bin, "\u2219", "\\bullet");
|
|
4468
|
+
defineSymbol(math, main, bin, "\u2219", "\\bullet", true);
|
|
4469
4469
|
defineSymbol(math, main, bin, "\u2021", "\\ddagger");
|
|
4470
4470
|
defineSymbol(math, main, bin, "\u2240", "\\wr", true);
|
|
4471
4471
|
defineSymbol(math, main, bin, "\u2a3f", "\\amalg");
|
|
@@ -4824,13 +4824,13 @@ defineSymbol(math, main, bin, "\u2217", "*", true);
|
|
|
4824
4824
|
defineSymbol(math, main, bin, "+", "+");
|
|
4825
4825
|
defineSymbol(math, main, bin, "\u2212", "-", true);
|
|
4826
4826
|
defineSymbol(math, main, bin, "\u22c5", "\\cdot", true);
|
|
4827
|
-
defineSymbol(math, main, bin, "\u2218", "\\circ");
|
|
4827
|
+
defineSymbol(math, main, bin, "\u2218", "\\circ", true);
|
|
4828
4828
|
defineSymbol(math, main, bin, "\u00f7", "\\div", true);
|
|
4829
4829
|
defineSymbol(math, main, bin, "\u00b1", "\\pm", true);
|
|
4830
4830
|
defineSymbol(math, main, bin, "\u00d7", "\\times", true);
|
|
4831
4831
|
defineSymbol(math, main, bin, "\u2229", "\\cap", true);
|
|
4832
4832
|
defineSymbol(math, main, bin, "\u222a", "\\cup", true);
|
|
4833
|
-
defineSymbol(math, main, bin, "\u2216", "\\setminus");
|
|
4833
|
+
defineSymbol(math, main, bin, "\u2216", "\\setminus", true);
|
|
4834
4834
|
defineSymbol(math, main, bin, "\u2227", "\\land");
|
|
4835
4835
|
defineSymbol(math, main, bin, "\u2228", "\\lor");
|
|
4836
4836
|
defineSymbol(math, main, bin, "\u2227", "\\wedge", true);
|
|
@@ -9983,6 +9983,17 @@ function defineEnvironment(_ref) {
|
|
|
9983
9983
|
}
|
|
9984
9984
|
}
|
|
9985
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
|
+
|
|
9986
9997
|
// Helper functions
|
|
9987
9998
|
function getHLines(parser) {
|
|
9988
9999
|
// Return an array. The array length = number of hlines.
|
|
@@ -10007,7 +10018,19 @@ var validateAmsEnvironmentContext = context => {
|
|
|
10007
10018
|
if (!settings.displayMode) {
|
|
10008
10019
|
throw new ParseError("{" + context.envName + "} can be used only in" + " display mode.");
|
|
10009
10020
|
}
|
|
10010
|
-
};
|
|
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
|
+
}
|
|
10011
10034
|
/**
|
|
10012
10035
|
* Parse the body of the environment, with rows delimited by \\ and
|
|
10013
10036
|
* columns delimited by &, and create a nested list in row-major order
|
|
@@ -10023,7 +10046,7 @@ function parseArray(parser, _ref, style) {
|
|
|
10023
10046
|
cols,
|
|
10024
10047
|
arraystretch,
|
|
10025
10048
|
colSeparationType,
|
|
10026
|
-
|
|
10049
|
+
autoTag,
|
|
10027
10050
|
singleRow,
|
|
10028
10051
|
emptySingleRow,
|
|
10029
10052
|
maxNumCols,
|
|
@@ -10058,7 +10081,29 @@ function parseArray(parser, _ref, style) {
|
|
|
10058
10081
|
var row = [];
|
|
10059
10082
|
var body = [row];
|
|
10060
10083
|
var rowGaps = [];
|
|
10061
|
-
var hLinesBeforeRow = [];
|
|
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.
|
|
10062
10107
|
|
|
10063
10108
|
hLinesBeforeRow.push(getHLines(parser));
|
|
10064
10109
|
|
|
@@ -10099,10 +10144,11 @@ function parseArray(parser, _ref, style) {
|
|
|
10099
10144
|
|
|
10100
10145
|
parser.consume();
|
|
10101
10146
|
} else if (next === "\\end") {
|
|
10102
|
-
// Arrays terminate newlines with `\crcr` which consumes a `\cr` if
|
|
10147
|
+
endRow(); // Arrays terminate newlines with `\crcr` which consumes a `\cr` if
|
|
10103
10148
|
// the last line is empty. However, AMS environments keep the
|
|
10104
10149
|
// empty row if it's the only one.
|
|
10105
10150
|
// NOTE: Currently, `cell` is the last item added into `row`.
|
|
10151
|
+
|
|
10106
10152
|
if (row.length === 1 && cell.type === "styling" && cell.body[0].body.length === 0 && (body.length > 1 || !emptySingleRow)) {
|
|
10107
10153
|
body.pop();
|
|
10108
10154
|
}
|
|
@@ -10124,11 +10170,13 @@ function parseArray(parser, _ref, style) {
|
|
|
10124
10170
|
size = parser.parseSizeGroup(true);
|
|
10125
10171
|
}
|
|
10126
10172
|
|
|
10127
|
-
rowGaps.push(size ? size.value : null);
|
|
10173
|
+
rowGaps.push(size ? size.value : null);
|
|
10174
|
+
endRow(); // check for \hline(s) following the row separator
|
|
10128
10175
|
|
|
10129
10176
|
hLinesBeforeRow.push(getHLines(parser));
|
|
10130
10177
|
row = [];
|
|
10131
10178
|
body.push(row);
|
|
10179
|
+
beginRow();
|
|
10132
10180
|
} else {
|
|
10133
10181
|
throw new ParseError("Expected & or \\\\ or \\cr or \\end", parser.nextToken);
|
|
10134
10182
|
}
|
|
@@ -10149,7 +10197,7 @@ function parseArray(parser, _ref, style) {
|
|
|
10149
10197
|
hskipBeforeAndAfter,
|
|
10150
10198
|
hLinesBeforeRow,
|
|
10151
10199
|
colSeparationType,
|
|
10152
|
-
|
|
10200
|
+
tags,
|
|
10153
10201
|
leqno
|
|
10154
10202
|
};
|
|
10155
10203
|
} // Decides on a style for cells in an array according to whether the given
|
|
@@ -10287,20 +10335,33 @@ var htmlBuilder$7 = function htmlBuilder(group, options) {
|
|
|
10287
10335
|
var cols = [];
|
|
10288
10336
|
var colSep;
|
|
10289
10337
|
var colDescrNum;
|
|
10290
|
-
var
|
|
10338
|
+
var tagSpans = [];
|
|
10291
10339
|
|
|
10292
|
-
if (group.
|
|
10293
|
-
// An environment with automatic equation numbers.
|
|
10294
|
-
// Create node(s)
|
|
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.
|
|
10295
10343
|
for (r = 0; r < nr; ++r) {
|
|
10296
10344
|
var rw = body[r];
|
|
10297
10345
|
var shift = rw.pos - offset;
|
|
10298
|
-
var
|
|
10299
|
-
|
|
10300
|
-
|
|
10301
|
-
|
|
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({
|
|
10302
10363
|
type: "elem",
|
|
10303
|
-
elem:
|
|
10364
|
+
elem: tagSpan,
|
|
10304
10365
|
shift
|
|
10305
10366
|
});
|
|
10306
10367
|
}
|
|
@@ -10436,12 +10497,12 @@ var htmlBuilder$7 = function htmlBuilder(group, options) {
|
|
|
10436
10497
|
}, options);
|
|
10437
10498
|
}
|
|
10438
10499
|
|
|
10439
|
-
if (
|
|
10500
|
+
if (tagSpans.length === 0) {
|
|
10440
10501
|
return buildCommon.makeSpan(["mord"], [body], options);
|
|
10441
10502
|
} else {
|
|
10442
10503
|
var eqnNumCol = buildCommon.makeVList({
|
|
10443
10504
|
positionType: "individualShift",
|
|
10444
|
-
children:
|
|
10505
|
+
children: tagSpans
|
|
10445
10506
|
}, options);
|
|
10446
10507
|
eqnNumCol = buildCommon.makeSpan(["tag"], [eqnNumCol], options);
|
|
10447
10508
|
return buildCommon.makeFragment([body, eqnNumCol]);
|
|
@@ -10467,7 +10528,7 @@ var mathmlBuilder$6 = function mathmlBuilder(group, options) {
|
|
|
10467
10528
|
row.push(new mathMLTree.MathNode("mtd", [buildGroup(rw[j], options)]));
|
|
10468
10529
|
}
|
|
10469
10530
|
|
|
10470
|
-
if (group.
|
|
10531
|
+
if (group.tags && group.tags[i]) {
|
|
10471
10532
|
row.unshift(glue);
|
|
10472
10533
|
row.push(glue);
|
|
10473
10534
|
|
|
@@ -10602,13 +10663,14 @@ var alignedHandler = function alignedHandler(context, args) {
|
|
|
10602
10663
|
|
|
10603
10664
|
var cols = [];
|
|
10604
10665
|
var separationType = context.envName.indexOf("at") > -1 ? "alignat" : "align";
|
|
10666
|
+
var isSplit = context.envName === "split";
|
|
10605
10667
|
var res = parseArray(context.parser, {
|
|
10606
10668
|
cols,
|
|
10607
10669
|
addJot: true,
|
|
10608
|
-
|
|
10670
|
+
autoTag: isSplit ? undefined : getAutoTag(context.envName),
|
|
10609
10671
|
emptySingleRow: true,
|
|
10610
10672
|
colSeparationType: separationType,
|
|
10611
|
-
maxNumCols:
|
|
10673
|
+
maxNumCols: isSplit ? 2 : undefined,
|
|
10612
10674
|
leqno: context.parser.settings.leqno
|
|
10613
10675
|
}, "display"); // Determining number of columns.
|
|
10614
10676
|
// 1. If the first argument is given, we use it as a number of columns,
|
|
@@ -10968,7 +11030,7 @@ defineEnvironment({
|
|
|
10968
11030
|
}],
|
|
10969
11031
|
addJot: true,
|
|
10970
11032
|
colSeparationType: "gather",
|
|
10971
|
-
|
|
11033
|
+
autoTag: getAutoTag(context.envName),
|
|
10972
11034
|
emptySingleRow: true,
|
|
10973
11035
|
leqno: context.parser.settings.leqno
|
|
10974
11036
|
};
|
|
@@ -11001,7 +11063,7 @@ defineEnvironment({
|
|
|
11001
11063
|
handler(context) {
|
|
11002
11064
|
validateAmsEnvironmentContext(context);
|
|
11003
11065
|
var res = {
|
|
11004
|
-
|
|
11066
|
+
autoTag: getAutoTag(context.envName),
|
|
11005
11067
|
emptySingleRow: true,
|
|
11006
11068
|
singleRow: true,
|
|
11007
11069
|
maxNumCols: 1,
|
|
@@ -11027,7 +11089,9 @@ defineEnvironment({
|
|
|
11027
11089
|
|
|
11028
11090
|
htmlBuilder: htmlBuilder$7,
|
|
11029
11091
|
mathmlBuilder: mathmlBuilder$6
|
|
11030
|
-
});
|
|
11092
|
+
});
|
|
11093
|
+
defineMacro("\\nonumber", "\\gdef\\@eqnsw{0}");
|
|
11094
|
+
defineMacro("\\notag", "\\nonumber"); // Catch \hline outside array environment
|
|
11031
11095
|
|
|
11032
11096
|
defineFunction({
|
|
11033
11097
|
type: "text",
|
|
@@ -11127,7 +11191,7 @@ function mathmlBuilder$5(group, options) {
|
|
|
11127
11191
|
var inner = buildExpression(group.body, options);
|
|
11128
11192
|
|
|
11129
11193
|
if (group.mclass === "minner") {
|
|
11130
|
-
|
|
11194
|
+
node = new mathMLTree.MathNode("mpadded", inner);
|
|
11131
11195
|
} else if (group.mclass === "mord") {
|
|
11132
11196
|
if (group.isCharacterBox) {
|
|
11133
11197
|
node = inner[0];
|
|
@@ -11155,6 +11219,10 @@ function mathmlBuilder$5(group, options) {
|
|
|
11155
11219
|
} else if (group.mclass === "mopen" || group.mclass === "mclose") {
|
|
11156
11220
|
node.attributes.lspace = "0em";
|
|
11157
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";
|
|
11158
11226
|
} // MathML <mo> default space is 5/18 em, so <mrel> needs no action.
|
|
11159
11227
|
// Ref: https://developer.mozilla.org/en-US/docs/Web/MathML/Element/mo
|
|
11160
11228
|
|
|
@@ -13153,17 +13221,6 @@ defineFunction({
|
|
|
13153
13221
|
mathmlBuilder: mathmlBuilder$1
|
|
13154
13222
|
});
|
|
13155
13223
|
|
|
13156
|
-
/**
|
|
13157
|
-
* All registered global/built-in macros.
|
|
13158
|
-
* `macros.js` exports this same dictionary again and makes it public.
|
|
13159
|
-
* `Parser.js` requires this dictionary via `macros.js`.
|
|
13160
|
-
*/
|
|
13161
|
-
var _macros = {}; // This function might one day accept an additional argument and do more things.
|
|
13162
|
-
|
|
13163
|
-
function defineMacro(name, body) {
|
|
13164
|
-
_macros[name] = body;
|
|
13165
|
-
}
|
|
13166
|
-
|
|
13167
13224
|
// NOTE: Unlike most `htmlBuilder`s, this one handles not only
|
|
13168
13225
|
// "operatorname", but also "supsub" since \operatorname* can
|
|
13169
13226
|
// affect super/subscripting.
|
|
@@ -14812,7 +14869,7 @@ class Namespace {
|
|
|
14812
14869
|
|
|
14813
14870
|
for (var undef in undefs) {
|
|
14814
14871
|
if (undefs.hasOwnProperty(undef)) {
|
|
14815
|
-
if (undefs[undef]
|
|
14872
|
+
if (undefs[undef] == null) {
|
|
14816
14873
|
delete this.current[undef];
|
|
14817
14874
|
} else {
|
|
14818
14875
|
this.current[undef] = undefs[undef];
|
|
@@ -14862,6 +14919,7 @@ class Namespace {
|
|
|
14862
14919
|
* Local set() sets the current value and (when appropriate) adds an undo
|
|
14863
14920
|
* operation to the undo stack. Global set() may change the undo
|
|
14864
14921
|
* operation at every level, so takes time linear in their number.
|
|
14922
|
+
* A value of undefined means to delete existing definitions.
|
|
14865
14923
|
*/
|
|
14866
14924
|
|
|
14867
14925
|
|
|
@@ -14893,7 +14951,11 @@ class Namespace {
|
|
|
14893
14951
|
}
|
|
14894
14952
|
}
|
|
14895
14953
|
|
|
14896
|
-
|
|
14954
|
+
if (value == null) {
|
|
14955
|
+
delete this.current[name];
|
|
14956
|
+
} else {
|
|
14957
|
+
this.current[name] = value;
|
|
14958
|
+
}
|
|
14897
14959
|
}
|
|
14898
14960
|
|
|
14899
14961
|
}
|
|
@@ -16831,6 +16893,25 @@ class Parser {
|
|
|
16831
16893
|
this.gullet.endGroups();
|
|
16832
16894
|
}
|
|
16833
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
|
+
}
|
|
16834
16915
|
|
|
16835
16916
|
/**
|
|
16836
16917
|
* Parses an "expression", which is a list of atoms.
|
|
@@ -17772,12 +17853,11 @@ var parseTree = function parseTree(toParse, settings) {
|
|
|
17772
17853
|
throw new ParseError("\\tag works only in display equations");
|
|
17773
17854
|
}
|
|
17774
17855
|
|
|
17775
|
-
parser.gullet.feed("\\df@tag");
|
|
17776
17856
|
tree = [{
|
|
17777
17857
|
type: "tag",
|
|
17778
17858
|
mode: "text",
|
|
17779
17859
|
body: tree,
|
|
17780
|
-
tag: parser.
|
|
17860
|
+
tag: parser.subparse([new Token("\\df@tag")])
|
|
17781
17861
|
}];
|
|
17782
17862
|
}
|
|
17783
17863
|
|
|
@@ -17879,7 +17959,7 @@ var katex = {
|
|
|
17879
17959
|
/**
|
|
17880
17960
|
* Current KaTeX version
|
|
17881
17961
|
*/
|
|
17882
|
-
version: "0.15.
|
|
17962
|
+
version: "0.15.3",
|
|
17883
17963
|
|
|
17884
17964
|
/**
|
|
17885
17965
|
* Renders the given LaTeX into an HTML+MathML combination, and adds
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "katex",
|
|
3
|
-
"version": "0.15.
|
|
3
|
+
"version": "0.15.3",
|
|
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
|
|
50
|
+
"packageManager": "yarn@3.2.0",
|
|
51
51
|
"devDependencies": {
|
|
52
52
|
"@babel/core": "^7.10.4",
|
|
53
53
|
"@babel/eslint-parser": "^7.15.0",
|
|
@@ -103,9 +103,9 @@
|
|
|
103
103
|
"p-retry": "^4.6.1",
|
|
104
104
|
"pako": "^2.0.0",
|
|
105
105
|
"postcss": "^8.0.0",
|
|
106
|
-
"postcss-less": "^
|
|
106
|
+
"postcss-less": "^6.0.0",
|
|
107
107
|
"postcss-loader": "^6.0.0",
|
|
108
|
-
"postcss-preset-env": "^
|
|
108
|
+
"postcss-preset-env": "^7.0.0",
|
|
109
109
|
"prettier": "^2.0.5",
|
|
110
110
|
"query-string": "^7.0.0",
|
|
111
111
|
"rimraf": "^3.0.2",
|
|
@@ -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": "^
|
|
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",
|
package/src/Namespace.js
CHANGED
|
@@ -15,7 +15,7 @@ export type Mapping<Value> = {[string]: Value};
|
|
|
15
15
|
export default class Namespace<Value> {
|
|
16
16
|
current: Mapping<Value>;
|
|
17
17
|
builtins: Mapping<Value>;
|
|
18
|
-
undefStack: Mapping
|
|
18
|
+
undefStack: Mapping<?Value>[];
|
|
19
19
|
|
|
20
20
|
/**
|
|
21
21
|
* Both arguments are optional. The first argument is an object of
|
|
@@ -48,7 +48,7 @@ export default class Namespace<Value> {
|
|
|
48
48
|
const undefs = this.undefStack.pop();
|
|
49
49
|
for (const undef in undefs) {
|
|
50
50
|
if (undefs.hasOwnProperty(undef)) {
|
|
51
|
-
if (undefs[undef]
|
|
51
|
+
if (undefs[undef] == null) {
|
|
52
52
|
delete this.current[undef];
|
|
53
53
|
} else {
|
|
54
54
|
this.current[undef] = undefs[undef];
|
|
@@ -97,8 +97,9 @@ export default class Namespace<Value> {
|
|
|
97
97
|
* Local set() sets the current value and (when appropriate) adds an undo
|
|
98
98
|
* operation to the undo stack. Global set() may change the undo
|
|
99
99
|
* operation at every level, so takes time linear in their number.
|
|
100
|
+
* A value of undefined means to delete existing definitions.
|
|
100
101
|
*/
|
|
101
|
-
set(name: string, value: Value, global: boolean = false) {
|
|
102
|
+
set(name: string, value: ?Value, global: boolean = false) {
|
|
102
103
|
if (global) {
|
|
103
104
|
// Global set is equivalent to setting in all groups. Simulate this
|
|
104
105
|
// by destroying any undos currently scheduled for this name,
|
|
@@ -119,6 +120,10 @@ export default class Namespace<Value> {
|
|
|
119
120
|
top[name] = this.current[name];
|
|
120
121
|
}
|
|
121
122
|
}
|
|
122
|
-
|
|
123
|
+
if (value == null) {
|
|
124
|
+
delete this.current[name];
|
|
125
|
+
} else {
|
|
126
|
+
this.current[name] = value;
|
|
127
|
+
}
|
|
123
128
|
}
|
|
124
129
|
}
|
package/src/Parser.js
CHANGED
|
@@ -150,6 +150,27 @@ export default class Parser {
|
|
|
150
150
|
}
|
|
151
151
|
}
|
|
152
152
|
|
|
153
|
+
/**
|
|
154
|
+
* Fully parse a separate sequence of tokens as a separate job.
|
|
155
|
+
* Tokens should be specified in reverse order, as in a MacroDefinition.
|
|
156
|
+
*/
|
|
157
|
+
subparse(tokens: Token[]): AnyParseNode[] {
|
|
158
|
+
// Save the next token from the current job.
|
|
159
|
+
const oldToken = this.nextToken;
|
|
160
|
+
this.consume();
|
|
161
|
+
|
|
162
|
+
// Run the new job, terminating it with an excess '}'
|
|
163
|
+
this.gullet.pushToken(new Token("}"));
|
|
164
|
+
this.gullet.pushTokens(tokens);
|
|
165
|
+
const parse = this.parseExpression(false);
|
|
166
|
+
this.expect("}");
|
|
167
|
+
|
|
168
|
+
// Restore the next token from the current job.
|
|
169
|
+
this.nextToken = oldToken;
|
|
170
|
+
|
|
171
|
+
return parse;
|
|
172
|
+
}
|
|
173
|
+
|
|
153
174
|
static endOfExpression: string[] = ["}", "\\endgroup", "\\end", "\\right", "&"];
|
|
154
175
|
|
|
155
176
|
/**
|
|
@@ -4,10 +4,12 @@ import Style from "../Style";
|
|
|
4
4
|
import defineEnvironment from "../defineEnvironment";
|
|
5
5
|
import {parseCD} from "./cd";
|
|
6
6
|
import defineFunction from "../defineFunction";
|
|
7
|
+
import defineMacro from "../defineMacro";
|
|
7
8
|
import mathMLTree from "../mathMLTree";
|
|
8
9
|
import ParseError from "../ParseError";
|
|
9
10
|
import {assertNodeType, assertSymbolNodeType} from "../parseNode";
|
|
10
11
|
import {checkSymbolNodeType} from "../parseNode";
|
|
12
|
+
import {Token} from "../Token";
|
|
11
13
|
import {calculateSize, makeEm} from "../units";
|
|
12
14
|
import utils from "../utils";
|
|
13
15
|
|
|
@@ -54,6 +56,18 @@ const validateAmsEnvironmentContext = context => {
|
|
|
54
56
|
}
|
|
55
57
|
};
|
|
56
58
|
|
|
59
|
+
// autoTag (an argument to parseArray) can be one of three values:
|
|
60
|
+
// * undefined: Regular (not-top-level) array; no tags on each row
|
|
61
|
+
// * true: Automatic equation numbering, overridable by \tag
|
|
62
|
+
// * false: Tags allowed on each row, but no automatic numbering
|
|
63
|
+
// This function *doesn't* work with the "split" environment name.
|
|
64
|
+
function getAutoTag(name): ?boolean {
|
|
65
|
+
if (name.indexOf("ed") === -1) {
|
|
66
|
+
return name.indexOf("*") === -1;
|
|
67
|
+
}
|
|
68
|
+
// return undefined;
|
|
69
|
+
}
|
|
70
|
+
|
|
57
71
|
/**
|
|
58
72
|
* Parse the body of the environment, with rows delimited by \\ and
|
|
59
73
|
* columns delimited by &, and create a nested list in row-major order
|
|
@@ -68,7 +82,7 @@ function parseArray(
|
|
|
68
82
|
cols,
|
|
69
83
|
arraystretch,
|
|
70
84
|
colSeparationType,
|
|
71
|
-
|
|
85
|
+
autoTag,
|
|
72
86
|
singleRow,
|
|
73
87
|
emptySingleRow,
|
|
74
88
|
maxNumCols,
|
|
@@ -79,7 +93,7 @@ function parseArray(
|
|
|
79
93
|
cols?: AlignSpec[],
|
|
80
94
|
arraystretch?: number,
|
|
81
95
|
colSeparationType?: ColSeparationType,
|
|
82
|
-
|
|
96
|
+
autoTag?: ?boolean,
|
|
83
97
|
singleRow?: boolean,
|
|
84
98
|
emptySingleRow?: boolean,
|
|
85
99
|
maxNumCols?: number,
|
|
@@ -116,6 +130,29 @@ function parseArray(
|
|
|
116
130
|
const rowGaps = [];
|
|
117
131
|
const hLinesBeforeRow = [];
|
|
118
132
|
|
|
133
|
+
const tags = (autoTag != null ? [] : undefined);
|
|
134
|
+
|
|
135
|
+
// amsmath uses \global\@eqnswtrue and \global\@eqnswfalse to represent
|
|
136
|
+
// whether this row should have an equation number. Simulate this with
|
|
137
|
+
// a \@eqnsw macro set to 1 or 0.
|
|
138
|
+
function beginRow() {
|
|
139
|
+
if (autoTag) {
|
|
140
|
+
parser.gullet.macros.set("\\@eqnsw", "1", true);
|
|
141
|
+
}
|
|
142
|
+
}
|
|
143
|
+
function endRow() {
|
|
144
|
+
if (tags) {
|
|
145
|
+
if (parser.gullet.macros.get("\\df@tag")) {
|
|
146
|
+
tags.push(parser.subparse([new Token("\\df@tag")]));
|
|
147
|
+
parser.gullet.macros.set("\\df@tag", undefined, true);
|
|
148
|
+
} else {
|
|
149
|
+
tags.push(Boolean(autoTag) &&
|
|
150
|
+
parser.gullet.macros.get("\\@eqnsw") === "1");
|
|
151
|
+
}
|
|
152
|
+
}
|
|
153
|
+
}
|
|
154
|
+
beginRow();
|
|
155
|
+
|
|
119
156
|
// Test for \hline at the top of the array.
|
|
120
157
|
hLinesBeforeRow.push(getHLines(parser));
|
|
121
158
|
|
|
@@ -154,6 +191,7 @@ function parseArray(
|
|
|
154
191
|
}
|
|
155
192
|
parser.consume();
|
|
156
193
|
} else if (next === "\\end") {
|
|
194
|
+
endRow();
|
|
157
195
|
// Arrays terminate newlines with `\crcr` which consumes a `\cr` if
|
|
158
196
|
// the last line is empty. However, AMS environments keep the
|
|
159
197
|
// empty row if it's the only one.
|
|
@@ -179,12 +217,14 @@ function parseArray(
|
|
|
179
217
|
size = parser.parseSizeGroup(true);
|
|
180
218
|
}
|
|
181
219
|
rowGaps.push(size ? size.value : null);
|
|
220
|
+
endRow();
|
|
182
221
|
|
|
183
222
|
// check for \hline(s) following the row separator
|
|
184
223
|
hLinesBeforeRow.push(getHLines(parser));
|
|
185
224
|
|
|
186
225
|
row = [];
|
|
187
226
|
body.push(row);
|
|
227
|
+
beginRow();
|
|
188
228
|
} else {
|
|
189
229
|
throw new ParseError("Expected & or \\\\ or \\cr or \\end",
|
|
190
230
|
parser.nextToken);
|
|
@@ -207,7 +247,7 @@ function parseArray(
|
|
|
207
247
|
hskipBeforeAndAfter,
|
|
208
248
|
hLinesBeforeRow,
|
|
209
249
|
colSeparationType,
|
|
210
|
-
|
|
250
|
+
tags,
|
|
211
251
|
leqno,
|
|
212
252
|
};
|
|
213
253
|
}
|
|
@@ -339,17 +379,27 @@ const htmlBuilder: HtmlBuilder<"array"> = function(group, options) {
|
|
|
339
379
|
let colSep;
|
|
340
380
|
let colDescrNum;
|
|
341
381
|
|
|
342
|
-
const
|
|
343
|
-
if (group.
|
|
344
|
-
// An environment with automatic equation numbers.
|
|
345
|
-
// Create node(s)
|
|
382
|
+
const tagSpans = [];
|
|
383
|
+
if (group.tags && group.tags.some((tag) => tag)) {
|
|
384
|
+
// An environment with manual tags and/or automatic equation numbers.
|
|
385
|
+
// Create node(s), the latter of which trigger CSS counter increment.
|
|
346
386
|
for (r = 0; r < nr; ++r) {
|
|
347
387
|
const rw = body[r];
|
|
348
388
|
const shift = rw.pos - offset;
|
|
349
|
-
const
|
|
350
|
-
|
|
351
|
-
|
|
352
|
-
|
|
389
|
+
const tag = group.tags[r];
|
|
390
|
+
let tagSpan;
|
|
391
|
+
if (tag === true) { // automatic numbering
|
|
392
|
+
tagSpan = buildCommon.makeSpan(["eqn-num"], [], options);
|
|
393
|
+
} else if (tag === false) {
|
|
394
|
+
// \nonumber/\notag or starred environment
|
|
395
|
+
tagSpan = buildCommon.makeSpan([], [], options);
|
|
396
|
+
} else { // manual \tag
|
|
397
|
+
tagSpan = buildCommon.makeSpan([],
|
|
398
|
+
html.buildExpression(tag, options, true), options);
|
|
399
|
+
}
|
|
400
|
+
tagSpan.depth = rw.depth;
|
|
401
|
+
tagSpan.height = rw.height;
|
|
402
|
+
tagSpans.push({type: "elem", elem: tagSpan, shift});
|
|
353
403
|
}
|
|
354
404
|
}
|
|
355
405
|
|
|
@@ -465,12 +515,12 @@ const htmlBuilder: HtmlBuilder<"array"> = function(group, options) {
|
|
|
465
515
|
}, options);
|
|
466
516
|
}
|
|
467
517
|
|
|
468
|
-
if (
|
|
518
|
+
if (tagSpans.length === 0) {
|
|
469
519
|
return buildCommon.makeSpan(["mord"], [body], options);
|
|
470
520
|
} else {
|
|
471
521
|
let eqnNumCol = buildCommon.makeVList({
|
|
472
522
|
positionType: "individualShift",
|
|
473
|
-
children:
|
|
523
|
+
children: tagSpans,
|
|
474
524
|
}, options);
|
|
475
525
|
eqnNumCol = buildCommon.makeSpan(["tag"], [eqnNumCol], options);
|
|
476
526
|
return buildCommon.makeFragment([body, eqnNumCol]);
|
|
@@ -494,7 +544,7 @@ const mathmlBuilder: MathMLBuilder<"array"> = function(group, options) {
|
|
|
494
544
|
row.push(new mathMLTree.MathNode("mtd",
|
|
495
545
|
[mml.buildGroup(rw[j], options)]));
|
|
496
546
|
}
|
|
497
|
-
if (group.
|
|
547
|
+
if (group.tags && group.tags[i]) {
|
|
498
548
|
row.unshift(glue);
|
|
499
549
|
row.push(glue);
|
|
500
550
|
if (group.leqno) {
|
|
@@ -631,14 +681,15 @@ const alignedHandler = function(context, args) {
|
|
|
631
681
|
}
|
|
632
682
|
const cols = [];
|
|
633
683
|
const separationType = context.envName.indexOf("at") > -1 ? "alignat" : "align";
|
|
684
|
+
const isSplit = context.envName === "split";
|
|
634
685
|
const res = parseArray(context.parser,
|
|
635
686
|
{
|
|
636
687
|
cols,
|
|
637
688
|
addJot: true,
|
|
638
|
-
|
|
689
|
+
autoTag: isSplit ? undefined : getAutoTag(context.envName),
|
|
639
690
|
emptySingleRow: true,
|
|
640
691
|
colSeparationType: separationType,
|
|
641
|
-
maxNumCols:
|
|
692
|
+
maxNumCols: isSplit ? 2 : undefined,
|
|
642
693
|
leqno: context.parser.settings.leqno,
|
|
643
694
|
},
|
|
644
695
|
"display"
|
|
@@ -984,7 +1035,7 @@ defineEnvironment({
|
|
|
984
1035
|
}],
|
|
985
1036
|
addJot: true,
|
|
986
1037
|
colSeparationType: "gather",
|
|
987
|
-
|
|
1038
|
+
autoTag: getAutoTag(context.envName),
|
|
988
1039
|
emptySingleRow: true,
|
|
989
1040
|
leqno: context.parser.settings.leqno,
|
|
990
1041
|
};
|
|
@@ -1017,7 +1068,7 @@ defineEnvironment({
|
|
|
1017
1068
|
handler(context) {
|
|
1018
1069
|
validateAmsEnvironmentContext(context);
|
|
1019
1070
|
const res = {
|
|
1020
|
-
|
|
1071
|
+
autoTag: getAutoTag(context.envName),
|
|
1021
1072
|
emptySingleRow: true,
|
|
1022
1073
|
singleRow: true,
|
|
1023
1074
|
maxNumCols: 1,
|
|
@@ -1043,6 +1094,9 @@ defineEnvironment({
|
|
|
1043
1094
|
mathmlBuilder,
|
|
1044
1095
|
});
|
|
1045
1096
|
|
|
1097
|
+
defineMacro("\\nonumber", "\\gdef\\@eqnsw{0}");
|
|
1098
|
+
defineMacro("\\notag", "\\nonumber");
|
|
1099
|
+
|
|
1046
1100
|
// Catch \hline outside array environment
|
|
1047
1101
|
defineFunction({
|
|
1048
1102
|
type: "text", // Doesn't matter what this is.
|