katex 0.10.1 → 0.12.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.
Files changed (144) hide show
  1. package/CHANGELOG.md +141 -0
  2. package/LICENSE +1 -1
  3. package/README.md +6 -6
  4. package/cli.js +0 -0
  5. package/contrib/auto-render/auto-render.js +12 -3
  6. package/contrib/copy-tex/README.md +3 -5
  7. package/contrib/mathtex-script-type/README.md +12 -14
  8. package/contrib/mhchem/README.md +3 -1
  9. package/contrib/render-a11y-string/render-a11y-string.js +712 -0
  10. package/contrib/render-a11y-string/test/render-a11y-string-spec.js +526 -0
  11. package/dist/README.md +6 -6
  12. package/dist/contrib/auto-render.js +14 -3
  13. package/dist/contrib/auto-render.min.js +1 -1
  14. package/dist/contrib/auto-render.mjs +14 -3
  15. package/dist/contrib/mhchem.min.js +1 -1
  16. package/dist/contrib/render-a11y-string.js +870 -0
  17. package/dist/contrib/render-a11y-string.min.js +1 -0
  18. package/dist/contrib/render-a11y-string.mjs +753 -0
  19. package/dist/fonts/KaTeX_AMS-Regular.ttf +0 -0
  20. package/dist/fonts/KaTeX_AMS-Regular.woff +0 -0
  21. package/dist/fonts/KaTeX_AMS-Regular.woff2 +0 -0
  22. package/dist/fonts/KaTeX_Caligraphic-Bold.ttf +0 -0
  23. package/dist/fonts/KaTeX_Caligraphic-Bold.woff +0 -0
  24. package/dist/fonts/KaTeX_Caligraphic-Bold.woff2 +0 -0
  25. package/dist/fonts/KaTeX_Caligraphic-Regular.ttf +0 -0
  26. package/dist/fonts/KaTeX_Caligraphic-Regular.woff +0 -0
  27. package/dist/fonts/KaTeX_Caligraphic-Regular.woff2 +0 -0
  28. package/dist/fonts/KaTeX_Fraktur-Bold.ttf +0 -0
  29. package/dist/fonts/KaTeX_Fraktur-Bold.woff +0 -0
  30. package/dist/fonts/KaTeX_Fraktur-Bold.woff2 +0 -0
  31. package/dist/fonts/KaTeX_Fraktur-Regular.ttf +0 -0
  32. package/dist/fonts/KaTeX_Fraktur-Regular.woff +0 -0
  33. package/dist/fonts/KaTeX_Fraktur-Regular.woff2 +0 -0
  34. package/dist/fonts/KaTeX_Main-Bold.ttf +0 -0
  35. package/dist/fonts/KaTeX_Main-Bold.woff +0 -0
  36. package/dist/fonts/KaTeX_Main-Bold.woff2 +0 -0
  37. package/dist/fonts/KaTeX_Main-BoldItalic.ttf +0 -0
  38. package/dist/fonts/KaTeX_Main-BoldItalic.woff +0 -0
  39. package/dist/fonts/KaTeX_Main-BoldItalic.woff2 +0 -0
  40. package/dist/fonts/KaTeX_Main-Italic.ttf +0 -0
  41. package/dist/fonts/KaTeX_Main-Italic.woff +0 -0
  42. package/dist/fonts/KaTeX_Main-Italic.woff2 +0 -0
  43. package/dist/fonts/KaTeX_Main-Regular.ttf +0 -0
  44. package/dist/fonts/KaTeX_Main-Regular.woff +0 -0
  45. package/dist/fonts/KaTeX_Main-Regular.woff2 +0 -0
  46. package/dist/fonts/KaTeX_Math-BoldItalic.ttf +0 -0
  47. package/dist/fonts/KaTeX_Math-BoldItalic.woff +0 -0
  48. package/dist/fonts/KaTeX_Math-BoldItalic.woff2 +0 -0
  49. package/dist/fonts/KaTeX_Math-Italic.ttf +0 -0
  50. package/dist/fonts/KaTeX_Math-Italic.woff +0 -0
  51. package/dist/fonts/KaTeX_Math-Italic.woff2 +0 -0
  52. package/dist/fonts/KaTeX_SansSerif-Bold.ttf +0 -0
  53. package/dist/fonts/KaTeX_SansSerif-Bold.woff +0 -0
  54. package/dist/fonts/KaTeX_SansSerif-Bold.woff2 +0 -0
  55. package/dist/fonts/KaTeX_SansSerif-Italic.ttf +0 -0
  56. package/dist/fonts/KaTeX_SansSerif-Italic.woff +0 -0
  57. package/dist/fonts/KaTeX_SansSerif-Italic.woff2 +0 -0
  58. package/dist/fonts/KaTeX_SansSerif-Regular.ttf +0 -0
  59. package/dist/fonts/KaTeX_SansSerif-Regular.woff +0 -0
  60. package/dist/fonts/KaTeX_SansSerif-Regular.woff2 +0 -0
  61. package/dist/fonts/KaTeX_Script-Regular.ttf +0 -0
  62. package/dist/fonts/KaTeX_Script-Regular.woff +0 -0
  63. package/dist/fonts/KaTeX_Script-Regular.woff2 +0 -0
  64. package/dist/fonts/KaTeX_Size1-Regular.ttf +0 -0
  65. package/dist/fonts/KaTeX_Size1-Regular.woff +0 -0
  66. package/dist/fonts/KaTeX_Size1-Regular.woff2 +0 -0
  67. package/dist/fonts/KaTeX_Size2-Regular.ttf +0 -0
  68. package/dist/fonts/KaTeX_Size2-Regular.woff +0 -0
  69. package/dist/fonts/KaTeX_Size2-Regular.woff2 +0 -0
  70. package/dist/fonts/KaTeX_Size3-Regular.ttf +0 -0
  71. package/dist/fonts/KaTeX_Size3-Regular.woff +0 -0
  72. package/dist/fonts/KaTeX_Size3-Regular.woff2 +0 -0
  73. package/dist/fonts/KaTeX_Size4-Regular.ttf +0 -0
  74. package/dist/fonts/KaTeX_Size4-Regular.woff +0 -0
  75. package/dist/fonts/KaTeX_Size4-Regular.woff2 +0 -0
  76. package/dist/fonts/KaTeX_Typewriter-Regular.ttf +0 -0
  77. package/dist/fonts/KaTeX_Typewriter-Regular.woff +0 -0
  78. package/dist/fonts/KaTeX_Typewriter-Regular.woff2 +0 -0
  79. package/dist/katex.css +34 -10
  80. package/dist/katex.js +2906 -2115
  81. package/dist/katex.min.css +1 -1
  82. package/dist/katex.min.js +1 -1
  83. package/dist/katex.mjs +2809 -2020
  84. package/package.json +12 -11
  85. package/src/Lexer.js +1 -0
  86. package/src/MacroExpander.js +39 -10
  87. package/src/Options.js +15 -75
  88. package/src/Parser.js +152 -115
  89. package/src/Settings.js +70 -7
  90. package/src/Token.js +2 -0
  91. package/src/buildCommon.js +24 -90
  92. package/src/buildHTML.js +31 -31
  93. package/src/buildMathML.js +52 -9
  94. package/src/buildTree.js +13 -6
  95. package/src/defineFunction.js +7 -22
  96. package/src/delimiter.js +66 -27
  97. package/src/domTree.js +71 -4
  98. package/src/environments/array.js +235 -25
  99. package/src/fontMetrics.js +11 -2
  100. package/src/functions/accent.js +9 -9
  101. package/src/functions/accentunder.js +2 -2
  102. package/src/functions/arrow.js +15 -5
  103. package/src/functions/color.js +9 -38
  104. package/src/functions/def.js +184 -0
  105. package/src/functions/delimsizing.js +32 -8
  106. package/src/functions/enclose.js +33 -6
  107. package/src/functions/font.js +4 -1
  108. package/src/functions/genfrac.js +39 -27
  109. package/src/functions/horizBrace.js +6 -7
  110. package/src/functions/href.js +16 -0
  111. package/src/functions/html.js +102 -0
  112. package/src/functions/includegraphics.js +153 -0
  113. package/src/functions/lap.js +4 -7
  114. package/src/functions/math.js +1 -5
  115. package/src/functions/mclass.js +41 -2
  116. package/src/functions/op.js +27 -111
  117. package/src/functions/operatorname.js +136 -92
  118. package/src/functions/ordgroup.js +1 -1
  119. package/src/functions/overline.js +3 -2
  120. package/src/functions/phantom.js +5 -2
  121. package/src/functions/raisebox.js +4 -16
  122. package/src/functions/rule.js +20 -9
  123. package/src/functions/styling.js +0 -9
  124. package/src/functions/supsub.js +27 -7
  125. package/src/functions/symbolsOp.js +4 -0
  126. package/src/functions/tag.js +20 -4
  127. package/src/functions/text.js +4 -3
  128. package/src/functions/underline.js +3 -2
  129. package/src/functions/utils/assembleSupSub.js +110 -0
  130. package/src/functions.js +3 -0
  131. package/src/katex.less +45 -9
  132. package/src/macros.js +259 -98
  133. package/src/mathMLTree.js +6 -4
  134. package/src/parseNode.js +37 -57
  135. package/src/stretchy.js +3 -1
  136. package/src/svgGeometry.js +136 -44
  137. package/src/symbols.js +52 -69
  138. package/src/tree.js +2 -2
  139. package/src/types.js +2 -1
  140. package/src/unicodeAccents.js +3 -1
  141. package/src/unicodeSymbols.js +30 -321
  142. package/src/utils.js +10 -0
  143. package/src/wide-character.js +2 -2
  144. package/src/unicodeMake.js +0 -70
@@ -1,10 +1,9 @@
1
1
  // @flow
2
- import {checkNodeType} from "./parseNode";
3
-
4
2
  import type Parser from "./Parser";
5
- import type {ParseNode, AnyParseNode, NodeType} from "./parseNode";
3
+ import type {ParseNode, AnyParseNode, NodeType, UnsupportedCmdParseNode}
4
+ from "./parseNode";
6
5
  import type Options from "./Options";
7
- import type {ArgType, BreakToken, Mode} from "./types";
6
+ import type {ArgType, BreakToken} from "./types";
8
7
  import type {HtmlDomNode} from "./domTree";
9
8
  import type {Token} from "./Token";
10
9
  import type {MathDomNode} from "./mathMLTree";
@@ -21,7 +20,9 @@ export type FunctionHandler<NODETYPE: NodeType> = (
21
20
  context: FunctionContext,
22
21
  args: AnyParseNode[],
23
22
  optArgs: (?AnyParseNode)[],
24
- ) => ParseNode<NODETYPE>;
23
+ ) => UnsupportedCmdParseNode | ParseNode<NODETYPE>;
24
+ // Note: reverse the order of the return type union will cause a flow error.
25
+ // See https://github.com/facebook/flow/issues/3663.
25
26
 
26
27
  export type HtmlBuilder<NODETYPE> = (ParseNode<NODETYPE>, Options) => HtmlDomNode;
27
28
  export type MathMLBuilder<NODETYPE> = (
@@ -82,14 +83,6 @@ export type FunctionPropSpec = {
82
83
 
83
84
  // Must be true if the function is an infix operator.
84
85
  infix?: boolean,
85
-
86
- // Switch to the specified mode while consuming the command token.
87
- // This is useful for commands that switch between math and text mode,
88
- // for making sure that a switch happens early enough. Note that the
89
- // mode is switched immediately back to its original value after consuming
90
- // the command token, so that the argument parsing and/or function handler
91
- // can easily access the old mode while doing their own mode switching.
92
- consumeMode?: ?Mode,
93
86
  };
94
87
 
95
88
  type FunctionDefSpec<NODETYPE: NodeType> = {|
@@ -135,7 +128,6 @@ export type FunctionSpec<NODETYPE: NodeType> = {|
135
128
  allowedInMath: boolean,
136
129
  numOptionalArgs: number,
137
130
  infix: boolean,
138
- consumeMode: ?Mode,
139
131
 
140
132
  // FLOW TYPE NOTES: Doing either one of the following two
141
133
  //
@@ -176,7 +168,6 @@ export const _mathmlGroupBuilders: {[string]: MathMLBuilder<*>} = {};
176
168
 
177
169
  export default function defineFunction<NODETYPE: NodeType>({
178
170
  type,
179
- nodeType,
180
171
  names,
181
172
  props,
182
173
  handler,
@@ -195,14 +186,9 @@ export default function defineFunction<NODETYPE: NodeType>({
195
186
  : props.allowedInMath,
196
187
  numOptionalArgs: props.numOptionalArgs || 0,
197
188
  infix: !!props.infix,
198
- consumeMode: props.consumeMode,
199
189
  handler: handler,
200
190
  };
201
191
  for (let i = 0; i < names.length; ++i) {
202
- // TODO: The value type of _functions should be a type union of all
203
- // possible `FunctionSpec<>` possibilities instead of `FunctionSpec<*>`,
204
- // which is an existential type.
205
- // $FlowFixMe
206
192
  _functions[names[i]] = data;
207
193
  }
208
194
  if (type) {
@@ -240,6 +226,5 @@ export function defineFunctionBuilders<NODETYPE: NodeType>({
240
226
  // Since the corresponding buildHTML/buildMathML function expects a
241
227
  // list of elements, we normalize for different kinds of arguments
242
228
  export const ordargument = function(arg: AnyParseNode): AnyParseNode[] {
243
- const node = checkNodeType(arg, "ordgroup");
244
- return node ? node.body : [arg];
229
+ return arg.type === "ordgroup" ? arg.body : [arg];
245
230
  };
package/src/delimiter.js CHANGED
@@ -25,6 +25,7 @@ import ParseError from "./ParseError";
25
25
  import Style from "./Style";
26
26
 
27
27
  import {PathNode, SvgNode, SymbolNode} from "./domTree";
28
+ import {sqrtPath} from "./svgGeometry";
28
29
  import buildCommon from "./buildCommon";
29
30
  import {getCharacterMetrics} from "./fontMetrics";
30
31
  import symbols from "./symbols";
@@ -177,6 +178,9 @@ const makeInner = function(
177
178
  return {type: "elem", elem: inner};
178
179
  };
179
180
 
181
+ // Helper for makeStackedDelim
182
+ const lap = {type: "kern", size: -0.005};
183
+
180
184
  /**
181
185
  * Make a stacked delimiter out of a given delimiter, with the total height at
182
186
  * least `heightTotal`. This routine is mentioned on page 442 of the TeXbook.
@@ -309,8 +313,8 @@ const makeStackedDelim = function(
309
313
  const minHeight = topHeightTotal + bottomHeightTotal + middleHeightTotal;
310
314
 
311
315
  // Compute the number of copies of the repeat symbol we will need
312
- const repeatCount = Math.ceil(
313
- (heightTotal - minHeight) / (middleFactor * repeatHeightTotal));
316
+ const repeatCount = Math.max(0, Math.ceil(
317
+ (heightTotal - minHeight) / (middleFactor * repeatHeightTotal)));
314
318
 
315
319
  // Compute the total height of the delimiter including all the symbols
316
320
  const realHeightTotal =
@@ -327,6 +331,15 @@ const makeStackedDelim = function(
327
331
  // Calculate the depth
328
332
  const depth = realHeightTotal / 2 - axisHeight;
329
333
 
334
+ // This function differs from the TeX procedure in one way.
335
+ // We shift each repeat element downwards by 0.005em, to prevent a gap
336
+ // due to browser floating point rounding error.
337
+ // Then, at the last element-to element joint, we add one extra repeat
338
+ // element to cover the gap created by the shifts.
339
+ // Find the shift needed to align the upper end of the extra element at a point
340
+ // 0.005em above the lower end of the top element.
341
+ const shiftOfExtraElement = (repeatCount + 1) * 0.005 - repeatHeightTotal;
342
+
330
343
  // Now, we start building the pieces that will go into the vlist
331
344
 
332
345
  // Keep a list of the inner pieces
@@ -338,20 +351,45 @@ const makeStackedDelim = function(
338
351
  if (middle === null) {
339
352
  // Add that many symbols
340
353
  for (let i = 0; i < repeatCount; i++) {
354
+ inners.push(lap); // overlap
341
355
  inners.push(makeInner(repeat, font, mode));
342
356
  }
343
357
  } else {
344
358
  // When there is a middle bit, we need the middle part and two repeated
345
359
  // sections
346
360
  for (let i = 0; i < repeatCount; i++) {
361
+ inners.push(lap);
347
362
  inners.push(makeInner(repeat, font, mode));
348
363
  }
364
+ // Insert one extra repeat element.
365
+ inners.push({type: "kern", size: shiftOfExtraElement});
366
+ inners.push(makeInner(repeat, font, mode));
367
+ inners.push(lap);
368
+ // Now insert the middle of the brace.
349
369
  inners.push(makeInner(middle, font, mode));
350
370
  for (let i = 0; i < repeatCount; i++) {
371
+ inners.push(lap);
351
372
  inners.push(makeInner(repeat, font, mode));
352
373
  }
353
374
  }
354
375
 
376
+ // To cover the gap create by the overlaps, insert one more repeat element,
377
+ // at a position that juts 0.005 above the bottom of the top element.
378
+ if ((repeat === "\u239c" || repeat === "\u239f") && repeatCount === 0) {
379
+ // Parentheses need a short repeat element in order to avoid an overrun.
380
+ // We'll make a 0.3em tall element from a SVG.
381
+ const overlap = buildCommon.svgData.leftParenInner[2] / 2;
382
+ inners.push({type: "kern", size: -overlap});
383
+ const pathName = repeat === "\u239c" ? "leftParenInner" : "rightParenInner";
384
+ const innerSpan = buildCommon.staticSvg(pathName, options);
385
+ inners.push({type: "elem", elem: innerSpan});
386
+ inners.push({type: "kern", size: -overlap});
387
+ } else {
388
+ inners.push({type: "kern", size: shiftOfExtraElement});
389
+ inners.push(makeInner(repeat, font, mode));
390
+ inners.push(lap);
391
+ }
392
+
355
393
  // Add the top symbol
356
394
  inners.push(makeInner(top, font, mode));
357
395
 
@@ -377,21 +415,11 @@ const sqrtSvg = function(
377
415
  sqrtName: string,
378
416
  height: number,
379
417
  viewBoxHeight: number,
418
+ extraViniculum: number,
380
419
  options: Options,
381
420
  ): SvgSpan {
382
- let alternate;
383
- if (sqrtName === "sqrtTall") {
384
- // sqrtTall is from glyph U23B7 in the font KaTeX_Size4-Regular
385
- // One path edge has a variable length. It runs from the viniculumn
386
- // to a point near (14 units) the bottom of the surd. The viniculum
387
- // is 40 units thick. So the length of the line in question is:
388
- const vertSegment = viewBoxHeight - 54 - vbPad;
389
- alternate = `M702 ${vbPad}H400000v40H742v${vertSegment}l-4 4-4 4c-.667.7
390
- -2 1.5-4 2.5s-4.167 1.833-6.5 2.5-5.5 1-9.5 1h-12l-28-84c-16.667-52-96.667
391
- -294.333-240-727l-212 -643 -85 170c-4-3.333-8.333-7.667-13 -13l-13-13l77-155
392
- 77-156c66 199.333 139 419.667 219 661 l218 661zM702 ${vbPad}H400000v40H742z`;
393
- }
394
- const pathNode = new PathNode(sqrtName, alternate);
421
+ const path = sqrtPath(sqrtName, extraViniculum, viewBoxHeight);
422
+ const pathNode = new PathNode(sqrtName, path);
395
423
 
396
424
  const svg = new SvgNode([pathNode], {
397
425
  // Note: 1000:1 ratio of viewBox to document em width.
@@ -425,6 +453,11 @@ const makeSqrtImage = function(
425
453
 
426
454
  let sizeMultiplier = newOptions.sizeMultiplier; // default
427
455
 
456
+ // The standard sqrt SVGs each have a 0.04em thick viniculum.
457
+ // If Settings.minRuleThickness is larger than that, we add extraViniculum.
458
+ const extraViniculum = Math.max(0,
459
+ options.minRuleThickness - options.fontMetrics().sqrtRuleThickness);
460
+
428
461
  // Create a span containing an SVG image of a sqrt symbol.
429
462
  let span;
430
463
  let spanHeight = 0;
@@ -440,34 +473,39 @@ const makeSqrtImage = function(
440
473
 
441
474
  if (delim.type === "small") {
442
475
  // Get an SVG that is derived from glyph U+221A in font KaTeX-Main.
443
- viewBoxHeight = 1000 + vbPad; // 1000 unit glyph height.
476
+ // 1000 unit normal glyph height.
477
+ viewBoxHeight = 1000 + 1000 * extraViniculum + vbPad;
444
478
  if (height < 1.0) {
445
479
  sizeMultiplier = 1.0; // mimic a \textfont radical
446
480
  } else if (height < 1.4) {
447
481
  sizeMultiplier = 0.7; // mimic a \scriptfont radical
448
482
  }
449
- spanHeight = (1.0 + emPad) / sizeMultiplier;
450
- texHeight = 1.00 / sizeMultiplier;
451
- span = sqrtSvg("sqrtMain", spanHeight, viewBoxHeight, options);
483
+ spanHeight = (1.0 + extraViniculum + emPad) / sizeMultiplier;
484
+ texHeight = (1.00 + extraViniculum) / sizeMultiplier;
485
+ span = sqrtSvg("sqrtMain", spanHeight, viewBoxHeight, extraViniculum,
486
+ options);
452
487
  span.style.minWidth = "0.853em";
453
488
  advanceWidth = 0.833 / sizeMultiplier; // from the font.
454
489
 
455
490
  } else if (delim.type === "large") {
456
491
  // These SVGs come from fonts: KaTeX_Size1, _Size2, etc.
457
492
  viewBoxHeight = (1000 + vbPad) * sizeToMaxHeight[delim.size];
458
- texHeight = sizeToMaxHeight[delim.size] / sizeMultiplier;
459
- spanHeight = (sizeToMaxHeight[delim.size] + emPad) / sizeMultiplier;
460
- span = sqrtSvg("sqrtSize" + delim.size, spanHeight, viewBoxHeight, options);
493
+ texHeight = (sizeToMaxHeight[delim.size] + extraViniculum) / sizeMultiplier;
494
+ spanHeight = (sizeToMaxHeight[delim.size] + extraViniculum + emPad)
495
+ / sizeMultiplier;
496
+ span = sqrtSvg("sqrtSize" + delim.size, spanHeight, viewBoxHeight,
497
+ extraViniculum, options);
461
498
  span.style.minWidth = "1.02em";
462
499
  advanceWidth = 1.0 / sizeMultiplier; // 1.0 from the font.
463
500
 
464
501
  } else {
465
502
  // Tall sqrt. In TeX, this would be stacked using multiple glyphs.
466
503
  // We'll use a single SVG to accomplish the same thing.
467
- spanHeight = height + emPad;
468
- texHeight = height;
469
- viewBoxHeight = Math.floor(1000 * height) + vbPad;
470
- span = sqrtSvg("sqrtTall", spanHeight, viewBoxHeight, options);
504
+ spanHeight = height + extraViniculum + emPad;
505
+ texHeight = height + extraViniculum;
506
+ viewBoxHeight = Math.floor(1000 * height + extraViniculum) + vbPad;
507
+ span = sqrtSvg("sqrtTall", spanHeight, viewBoxHeight, extraViniculum,
508
+ options);
471
509
  span.style.minWidth = "0.742em";
472
510
  advanceWidth = 1.056;
473
511
  }
@@ -482,7 +520,8 @@ const makeSqrtImage = function(
482
520
  // This actually should depend on the chosen font -- e.g. \boldmath
483
521
  // should use the thicker surd symbols from e.g. KaTeX_Main-Bold, and
484
522
  // have thicker rules.
485
- ruleWidth: options.fontMetrics().sqrtRuleThickness * sizeMultiplier,
523
+ ruleWidth: (options.fontMetrics().sqrtRuleThickness + extraViniculum)
524
+ * sizeMultiplier,
486
525
  };
487
526
  };
488
527
 
package/src/domTree.js CHANGED
@@ -13,7 +13,7 @@
13
13
  */
14
14
  import {scriptFromCodepoint} from "./unicodeScripts";
15
15
  import utils from "./utils";
16
- import svgGeometry from "./svgGeometry";
16
+ import {path} from "./svgGeometry";
17
17
  import type Options from "./Options";
18
18
  import {DocumentFragment} from "./tree";
19
19
 
@@ -136,12 +136,16 @@ export type CssStyle = $Shape<{
136
136
  backgroundColor: string,
137
137
  borderBottomWidth: string,
138
138
  borderColor: string,
139
+ borderRightStyle: string,
139
140
  borderRightWidth: string,
140
141
  borderTopWidth: string,
142
+ borderStyle: string;
143
+ borderWidth: string,
141
144
  bottom: string,
142
145
  color: string,
143
146
  height: string,
144
147
  left: string,
148
+ margin: string,
145
149
  marginLeft: string,
146
150
  marginRight: string,
147
151
  marginTop: string,
@@ -264,6 +268,69 @@ export class Anchor implements HtmlDomNode {
264
268
  }
265
269
  }
266
270
 
271
+ /**
272
+ * This node represents an image embed (<img>) element.
273
+ */
274
+ export class Img implements VirtualNode {
275
+ src: string;
276
+ alt: string;
277
+ classes: string[];
278
+ height: number;
279
+ depth: number;
280
+ maxFontSize: number;
281
+ style: CssStyle;
282
+
283
+ constructor(
284
+ src: string,
285
+ alt: string,
286
+ style: CssStyle,
287
+ ) {
288
+ this.alt = alt;
289
+ this.src = src;
290
+ this.classes = ["mord"];
291
+ this.style = style;
292
+ }
293
+
294
+ hasClass(className: string): boolean {
295
+ return utils.contains(this.classes, className);
296
+ }
297
+
298
+ toNode(): Node {
299
+ const node = document.createElement("img");
300
+ node.src = this.src;
301
+ node.alt = this.alt;
302
+ node.className = "mord";
303
+
304
+ // Apply inline styles
305
+ for (const style in this.style) {
306
+ if (this.style.hasOwnProperty(style)) {
307
+ // $FlowFixMe
308
+ node.style[style] = this.style[style];
309
+ }
310
+ }
311
+
312
+ return node;
313
+ }
314
+
315
+ toMarkup(): string {
316
+ let markup = `<img src='${this.src} 'alt='${this.alt}' `;
317
+
318
+ // Add the styles, after hyphenation
319
+ let styles = "";
320
+ for (const style in this.style) {
321
+ if (this.style.hasOwnProperty(style)) {
322
+ styles += `${utils.hyphenate(style)}:${this.style[style]};`;
323
+ }
324
+ }
325
+ if (styles) {
326
+ markup += ` style="${utils.escape(styles)}"`;
327
+ }
328
+
329
+ markup += "'/>";
330
+ return markup;
331
+ }
332
+ }
333
+
267
334
  const iCombinations = {
268
335
  'î': '\u0131\u0302',
269
336
  'ï': '\u0131\u0308',
@@ -466,7 +533,7 @@ export class PathNode implements VirtualNode {
466
533
 
467
534
  constructor(pathName: string, alternate?: string) {
468
535
  this.pathName = pathName;
469
- this.alternate = alternate; // Used only for tall \sqrt
536
+ this.alternate = alternate; // Used only for \sqrt
470
537
  }
471
538
 
472
539
  toNode(): Node {
@@ -476,7 +543,7 @@ export class PathNode implements VirtualNode {
476
543
  if (this.alternate) {
477
544
  node.setAttribute("d", this.alternate);
478
545
  } else {
479
- node.setAttribute("d", svgGeometry.path[this.pathName]);
546
+ node.setAttribute("d", path[this.pathName]);
480
547
  }
481
548
 
482
549
  return node;
@@ -486,7 +553,7 @@ export class PathNode implements VirtualNode {
486
553
  if (this.alternate) {
487
554
  return `<path d='${this.alternate}'/>`;
488
555
  } else {
489
- return `<path d='${svgGeometry.path[this.pathName]}'/>`;
556
+ return `<path d='${path[this.pathName]}'/>`;
490
557
  }
491
558
  }
492
559
  }