vendor: 5,509 bytes, lines 1-183
1"use strict"; 2(self["webpackChunk_N_E"] = self["webpackChunk_N_E"] || []).push([[1265],{ 3 4/***/ 1008: 5/***/ (function(__unused_webpack___webpack_module__, __webpack_exports__, __webpack_require__) { 6 7/* harmony export */ __webpack_require__.d(__webpack_exports__, { 8/* harmony export */ "ZP": function() { return /* binding */ katex; } 9/* harmony export */ }); 10/* unused harmony exports ParseError, SETTINGS_SCHEMA, __defineFunction, __defineMacro, __defineSymbol, __domTree, __parse, __renderToDomTree, __renderToHTMLTree, __setFontMetrics, render, renderToString, version */ 11/** 12 * Lexing or parsing positional information for error reporting. 13 * This object is immutable. 14 */ 15class SourceLocation { 16 // The + prefix indicates that these fields aren't writeable 17 // Lexer holding the input string. 18 // Start offset, zero-based inclusive. 19 // End offset, zero-based exclusive. 20 constructor(lexer, start, end) { 21 this.lexer = void 0; 22 this.start = void 0; 23 this.end = void 0; 24 this.lexer = lexer; 25 this.start = start; 26 this.end = end; 27 } 28 /** 29 * Merges two `SourceLocation`s from location providers, given they are 30 * provided in order of appearance. 31 * - Returns the first one's location if only the first is provided. 32 * - Returns a merged range of the first and the last if both are provided 33 * and their lexers match. 34 * - Otherwise, returns null. 35 */ 36 37 38 static range(first, second) { 39 if (!second) { 40 return first && first.loc; 41 } else if (!first || !first.loc || !second.loc || first.loc.lexer !== second.loc.lexer) { 42 return null; 43 } else { 44 return new SourceLocation(first.loc.lexer, first.loc.start, second.loc.end); 45 } 46 } 47 48} 49 50/** 51 * Interface required to break circular dependency between Token, Lexer, and 52 * ParseError. 53 */ 54 55/** 56 * The resulting token returned from `lex`. 57 * 58 * It consists of the token text plus some position information. 59 * The position information is essentially a range in an input string, 60 * but instead of referencing the bare input string, we refer to the lexer. 61 * That way it is possible to attach extra metadata to the input string, 62 * like for example a file name or similar. 63 * 64 * The position information is optional, so it is OK to construct synthetic 65 * tokens if appropriate. Not providing available position information may 66 * lead to degraded error reporting, though. 67 */ 68class Token { 69 // don't expand the token 70 // used in \noexpand 71 constructor(text, // the text of this token 72 loc) { 73 this.text = void 0; 74 this.loc = void 0; 75 this.noexpand = void 0; 76 this.treatAsRelax = void 0; 77 this.text = text; 78 this.loc = loc; 79 } 80 /** 81 * Given a pair of tokens (this and endToken), compute a `Token` encompassing 82 * the whole input range enclosed by these two. 83 */ 84 85 86 range(endToken, // last token of the range, inclusive 87 text // the text of the newly constructed token 88 ) { 89 return new Token(text, SourceLocation.range(this, endToken)); 90 } 91 92} 93 94/** 95 * This is the ParseError class, which is the main error thrown by KaTeX 96 * functions when something has gone wrong. This is used to distinguish internal 97 * errors from errors in the expression that the user provided. 98 * 99 * If possible, a caller should provide a Token or ParseNode with information 100 * about where in the source string the problem occurred. 101 */ 102class ParseError { 103 // Error start position based on passed-in Token or ParseNode. 104 // Length of affected text based on passed-in Token or ParseNode. 105 // The underlying error message without any context added. 106 constructor(message, // The error message 107 token // An object providing position information 108 ) { 109 this.name = void 0; 110 this.position = void 0; 111 this.length = void 0; 112 this.rawMessage = void 0; 113 var error = "KaTeX parse error: " + message; 114 var start; 115 var end; 116 var loc = token && token.loc; 117 118 if (loc && loc.start <= loc.end) { 119 // If we have the input and a position, make the error a bit fancier 120 // Get the input 121 var input = loc.lexer.input; // Prepend some information 122 123 start = loc.start; 124 end = loc.end; 125 126 if (start === input.length) { 127 error += " at end of input: "; 128 } else { 129 error += " at position " + (start + 1) + ": "; 130 } // Underline token in question using combining underscores 131 132 133 var underlined = input.slice(start, end).replace(/[^]/g, "$&\u0332"); // Extract some context from the input and add it to the error 134 135 var left; 136 137 if (start > 15) { 138 left = "â¦" + input.slice(start - 15, start); 139 } else { 140 left = input.slice(0, start); 141 } 142 143 var right; 144 145 if (end + 15 < input.length) { 146 right = input.slice(end, end + 15) + "â¦"; 147 } else { 148 right = input.slice(end); 149 } 150 151 error += left + underlined + right; 152 } // Some hackery to make ParseError a prototype of Error 153 // See http://stackoverflow.com/a/8460753 154 // $FlowFixMe 155 156 157 var self = new Error(error); 158 self.name = "ParseError"; // $FlowFixMe 159 160 self.__proto__ = ParseError.prototype; 161 self.position = start; 162 163 if (start != null && end != null) { 164 self.length = end - start; 165 } 166 167 self.rawMessage = message; 168 return self; 169 } 170 171} // $FlowFixMe More hackery 172 173 174ParseError.prototype.__proto__ = Error.prototype; 175 176/** 177 * This file contains a list of utility functions which are useful in other 178 * files. 179 */ 180 181/** 182 * Return whether an element is contained in a list 183 */
184var contains = function contains(list, elem) { 185 return list.indexOf(elem) !== -1; 186}; 187/** 188 * Provide a default value if a setting is undefined 189 * NOTE: Couldn't use `T` as the output type due to facebook/flow#5022. 190 */ 191 192 193var deflt = function deflt(setting, defaultIfUndefined) { 194 return setting === undefined ? defaultIfUndefined : setting; 195}; // hyphenate and escape adapted from Facebook's React under Apache 2 license 196 197 198var uppercase = /([A-Z])/g; 199 200var hyphenate = function hyphenate(str) { 201 return str.replace(uppercase, "-$1").toLowerCase(); 202}; 203 204var ESCAPE_LOOKUP = { 205 "&": "&", 206 ">": ">", 207 "<": "<", 208 "\"": """, 209 "'": "'" 210}; 211var ESCAPE_REGEX = /[&><"']/g; 212/** 213 * Escapes text to prevent scripting attacks. 214 */ 215 216function escape(text) { 217 return String(text).replace(ESCAPE_REGEX, match => ESCAPE_LOOKUP[match]); 218} 219/** 220 * Sometimes we want to pull out the innermost element of a group. In most 221 * cases, this will just be the group itself, but when ordgroups and colors have 222 * a single element, we want to pull that out. 223 */ 224 225 226var getBaseElem = function getBaseElem(group) { 227 if (group.type === "ordgroup") { 228 if (group.body.length === 1) { 229 return getBaseElem(group.body[0]); 230 } else { 231 return group; 232 } 233 } else if (group.type === "color") { 234 if (group.body.length === 1) { 235 return getBaseElem(group.body[0]); 236 } else { 237 return group; 238 } 239 } else if (group.type === "font") { 240 return getBaseElem(group.body); 241 } else { 242 return group; 243 } 244}; 245/** 246 * TeXbook algorithms often reference "character boxes", which are simply groups 247 * with a single character in them. To decide if something is a character box, 248 * we find its innermost group, and see if it is a single character. 249 */ 250 251 252var isCharacterBox = function isCharacterBox(group) { 253 var baseElem = getBaseElem(group); // These are all they types of groups which hold single characters 254 255 return baseElem.type === "mathord" || baseElem.type === "textord" || baseElem.type === "atom"; 256}; 257 258var assert = function assert(value) { 259 if (!value) { 260 throw new Error('Expected non-null, but got ' + String(value)); 261 } 262 263 return value; 264}; 265/** 266 * Return the protocol of a URL, or "_relative" if the URL does not specify a 267 * protocol (and thus is relative), or `null` if URL has invalid protocol 268 * (so should be outright rejected). 269 */ 270 271var protocolFromUrl = function protocolFromUrl(url) { 272 // Check for possible leading protocol. 273 // https://url.spec.whatwg.org/#url-parsing strips leading whitespace 274 // (U+20) or C0 control (U+00-U+1F) characters. 275 // eslint-disable-next-line no-control-regex 276 var protocol = /^[\x00-\x20]*([^\\/#?]*?)(:|�*58|�*3a|&colon)/i.exec(url); 277 278 if (!protocol) { 279 return "_relative"; 280 } // Reject weird colons 281 282 283 if (protocol[2] !== ":") { 284 return null; 285 } // Reject invalid characters in scheme according to 286 // https://datatracker.ietf.org/doc/html/rfc3986#section-3.1 287 288 289 if (!/^[a-zA-Z][a-zA-Z0-9+\-.]*$/.test(protocol[1])) { 290 return null; 291 } // Lowercase the protocol 292 293 294 return protocol[1].toLowerCase(); 295}; 296var utils = { 297 contains, 298 deflt, 299 escape, 300 hyphenate, 301 getBaseElem, 302 isCharacterBox, 303 protocolFromUrl 304}; 305 306/* eslint no-console:0 */ 307// TODO: automatically generate documentation 308// TODO: check all properties on Settings exist 309// TODO: check the type of a property on Settings matches 310var SETTINGS_SCHEMA = { 311 displayMode: { 312 type: "boolean", 313 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.", 314 cli: "-d, --display-mode" 315 }, 316 output: { 317 type: { 318 enum: ["htmlAndMathml", "html", "mathml"] 319 }, 320 description: "Determines the markup language of the output.", 321 cli: "-F, --format <type>" 322 }, 323 leqno: { 324 type: "boolean", 325 description: "Render display math in leqno style (left-justified tags)." 326 }, 327 fleqn: { 328 type: "boolean", 329 description: "Render display math flush left." 330 }, 331 throwOnError: { 332 type: "boolean", 333 default: true, 334 cli: "-t, --no-throw-on-error", 335 cliDescription: "Render errors (in the color given by --error-color) ins" + "tead of throwing a ParseError exception when encountering an error." 336 }, 337 errorColor: { 338 type: "string", 339 default: "#cc0000", 340 cli: "-c, --error-color <color>", 341 cliDescription: "A color string given in the format 'rgb' or 'rrggbb' " + "(no #). This option determines the color of errors rendered by the " + "-t option.", 342 cliProcessor: color => "#" + color 343 }, 344 macros: { 345 type: "object", 346 cli: "-m, --macro <def>", 347 cliDescription: "Define custom macro of the form '\\foo:expansion' (use " + "multiple -m arguments for multiple macros).", 348 cliDefault: [], 349 cliProcessor: (def, defs) => { 350 defs.push(def); 351 return defs; 352 } 353 }, 354 minRuleThickness: { 355 type: "number", 356 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`.", 357 processor: t => Math.max(0, t), 358 cli: "--min-rule-thickness <size>", 359 cliProcessor: parseFloat 360 }, 361 colorIsTextColor: { 362 type: "boolean", 363 description: "Makes \\color behave like LaTeX's 2-argument \\textcolor, " + "instead of LaTeX's one-argument \\color mode change.", 364 cli: "-b, --color-is-text-color" 365 }, 366 strict: { 367 type: [{ 368 enum: ["warn", "ignore", "error"] 369 }, "boolean", "function"], 370 description: "Turn on strict / LaTeX faithfulness mode, which throws an " + "error if the input uses features that are not supported by LaTeX.", 371 cli: "-S, --strict", 372 cliDefault: false 373 }, 374 trust: { 375 type: ["boolean", "function"], 376 description: "Trust the input, enabling all HTML features such as \\url.", 377 cli: "-T, --trust" 378 }, 379 maxSize: { 380 type: "number", 381 default: Infinity, 382 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", 383 processor: s => Math.max(0, s), 384 cli: "-s, --max-size <n>", 385 cliProcessor: parseInt 386 }, 387 maxExpand: { 388 type: "number", 389 default: 1000, 390 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.", 391 processor: n => Math.max(0, n), 392 cli: "-e, --max-expand <n>", 393 cliProcessor: n => n === "Infinity" ? Infinity : parseInt(n) 394 }, 395 globalGroup: { 396 type: "boolean", 397 cli: false 398 } 399}; 400 401function getDefaultValue(schema) { 402 if (schema.default) { 403 return schema.default; 404 } 405 406 var type = schema.type; 407 var defaultType = Array.isArray(type) ? type[0] : type; 408 409 if (typeof defaultType !== 'string') { 410 return defaultType.enum[0]; 411 } 412 413 switch (defaultType) { 414 case 'boolean': 415 return false;
vendor: 4,712 bytes, lines 416-547
416 417 case 'string': 418 return ''; 419 420 case 'number': 421 return 0; 422 423 case 'object': 424 return {}; 425 } 426} 427/** 428 * The main Settings object 429 * 430 * The current options stored are: 431 * - displayMode: Whether the expression should be typeset as inline math 432 * (false, the default), meaning that the math starts in 433 * \textstyle and is placed in an inline-block); or as display 434 * math (true), meaning that the math starts in \displaystyle 435 * and is placed in a block with vertical margin. 436 */ 437 438 439class Settings { 440 constructor(options) { 441 this.displayMode = void 0; 442 this.output = void 0; 443 this.leqno = void 0; 444 this.fleqn = void 0; 445 this.throwOnError = void 0; 446 this.errorColor = void 0; 447 this.macros = void 0; 448 this.minRuleThickness = void 0; 449 this.colorIsTextColor = void 0; 450 this.strict = void 0; 451 this.trust = void 0; 452 this.maxSize = void 0; 453 this.maxExpand = void 0; 454 this.globalGroup = void 0; 455 // allow null options 456 options = options || {}; 457 458 for (var prop in SETTINGS_SCHEMA) { 459 if (SETTINGS_SCHEMA.hasOwnProperty(prop)) { 460 // $FlowFixMe 461 var schema = SETTINGS_SCHEMA[prop]; // TODO: validate options 462 // $FlowFixMe 463 464 this[prop] = options[prop] !== undefined ? schema.processor ? schema.processor(options[prop]) : options[prop] : getDefaultValue(schema); 465 } 466 } 467 } 468 /** 469 * Report nonstrict (non-LaTeX-compatible) input. 470 * Can safely not be called if `this.strict` is false in JavaScript. 471 */ 472 473 474 reportNonstrict(errorCode, errorMsg, token) { 475 var strict = this.strict; 476 477 if (typeof strict === "function") { 478 // Allow return value of strict function to be boolean or string 479 // (or null/undefined, meaning no further processing). 480 strict = strict(errorCode, errorMsg, token); 481 } 482 483 if (!strict || strict === "ignore") { 484 return; 485 } else if (strict === true || strict === "error") { 486 throw new ParseError("LaTeX-incompatible input and strict mode is set to 'error': " + (errorMsg + " [" + errorCode + "]"), token); 487 } else if (strict === "warn") { 488 typeof console !== "undefined" && console.warn("LaTeX-incompatible input and strict mode is set to 'warn': " + (errorMsg + " [" + errorCode + "]")); 489 } else { 490 // won't happen in type-safe code 491 typeof console !== "undefined" && console.warn("LaTeX-incompatible input and strict mode is set to " + ("unrecognized '" + strict + "': " + errorMsg + " [" + errorCode + "]")); 492 } 493 } 494 /** 495 * Check whether to apply strict (LaTeX-adhering) behavior for unusual 496 * input (like `\\`). Unlike `nonstrict`, will not throw an error; 497 * instead, "error" translates to a return value of `true`, while "ignore" 498 * translates to a return value of `false`. May still print a warning: 499 * "warn" prints a warning and returns `false`. 500 * This is for the second category of `errorCode`s listed in the README. 501 */ 502 503 504 useStrictBehavior(errorCode, errorMsg, token) { 505 var strict = this.strict; 506 507 if (typeof strict === "function") { 508 // Allow return value of strict function to be boolean or string 509 // (or null/undefined, meaning no further processing). 510 // But catch any exceptions thrown by function, treating them 511 // like "error". 512 try { 513 strict = strict(errorCode, errorMsg, token); 514 } catch (error) { 515 strict = "error"; 516 } 517 } 518 519 if (!strict || strict === "ignore") { 520 return false; 521 } else if (strict === true || strict === "error") { 522 return true; 523 } else if (strict === "warn") { 524 typeof console !== "undefined" && console.warn("LaTeX-incompatible input and strict mode is set to 'warn': " + (errorMsg + " [" + errorCode + "]")); 525 return false; 526 } else { 527 // won't happen in type-safe code 528 typeof console !== "undefined" && console.warn("LaTeX-incompatible input and strict mode is set to " + ("unrecognized '" + strict + "': " + errorMsg + " [" + errorCode + "]")); 529 return false; 530 } 531 } 532 /** 533 * Check whether to test potentially dangerous input, and return 534 * `true` (trusted) or `false` (untrusted). The sole argument `context` 535 * should be an object with `command` field specifying the relevant LaTeX 536 * command (as a string starting with `\`), and any other arguments, etc. 537 * If `context` has a `url` field, a `protocol` field will automatically 538 * get added by this function (changing the specified object). 539 */ 540 541 542 isTrusted(context) { 543 if (context.url && !context.protocol) { 544 var protocol = utils.protocolFromUrl(context.url); 545 546 if (protocol == null) { 547 return false;
vendor: 9,826 bytes, lines 548-822
548 } 549 550 context.protocol = protocol; 551 } 552 553 var trust = typeof this.trust === "function" ? this.trust(context) : this.trust; 554 return Boolean(trust); 555 } 556 557} 558 559/** 560 * This file contains information and classes for the various kinds of styles 561 * used in TeX. It provides a generic `Style` class, which holds information 562 * about a specific style. It then provides instances of all the different kinds 563 * of styles possible, and provides functions to move between them and get 564 * information about them. 565 */ 566 567/** 568 * The main style class. Contains a unique id for the style, a size (which is 569 * the same for cramped and uncramped version of a style), and a cramped flag. 570 */ 571class Style { 572 constructor(id, size, cramped) { 573 this.id = void 0; 574 this.size = void 0; 575 this.cramped = void 0; 576 this.id = id; 577 this.size = size; 578 this.cramped = cramped; 579 } 580 /** 581 * Get the style of a superscript given a base in the current style. 582 */ 583 584 585 sup() { 586 return styles[sup[this.id]]; 587 } 588 /** 589 * Get the style of a subscript given a base in the current style. 590 */ 591 592 593 sub() { 594 return styles[sub[this.id]]; 595 } 596 /** 597 * Get the style of a fraction numerator given the fraction in the current 598 * style. 599 */ 600 601 602 fracNum() { 603 return styles[fracNum[this.id]]; 604 } 605 /** 606 * Get the style of a fraction denominator given the fraction in the current 607 * style. 608 */ 609 610 611 fracDen() { 612 return styles[fracDen[this.id]]; 613 } 614 /** 615 * Get the cramped version of a style (in particular, cramping a cramped style 616 * doesn't change the style). 617 */ 618 619 620 cramp() { 621 return styles[cramp[this.id]]; 622 } 623 /** 624 * Get a text or display version of this style. 625 */ 626 627 628 text() { 629 return styles[text$1[this.id]]; 630 } 631 /** 632 * Return true if this style is tightly spaced (scriptstyle/scriptscriptstyle) 633 */ 634 635 636 isTight() { 637 return this.size >= 2; 638 } 639 640} // Export an interface for type checking, but don't expose the implementation. 641// This way, no more styles can be generated. 642 643 644// IDs of the different styles 645var D = 0; 646var Dc = 1; 647var T = 2; 648var Tc = 3; 649var S = 4; 650var Sc = 5; 651var SS = 6; 652var SSc = 7; // Instances of the different styles 653 654var styles = [new Style(D, 0, false), new Style(Dc, 0, true), new Style(T, 1, false), new Style(Tc, 1, true), new Style(S, 2, false), new Style(Sc, 2, true), new Style(SS, 3, false), new Style(SSc, 3, true)]; // Lookup tables for switching from one style to another 655 656var sup = [S, Sc, S, Sc, SS, SSc, SS, SSc]; 657var sub = [Sc, Sc, Sc, Sc, SSc, SSc, SSc, SSc]; 658var fracNum = [T, Tc, S, Sc, SS, SSc, SS, SSc]; 659var fracDen = [Tc, Tc, Sc, Sc, SSc, SSc, SSc, SSc]; 660var cramp = [Dc, Dc, Tc, Tc, Sc, Sc, SSc, SSc]; 661var text$1 = [D, Dc, T, Tc, T, Tc, T, Tc]; // We only export some of the styles. 662 663var Style$1 = { 664 DISPLAY: styles[D], 665 TEXT: styles[T], 666 SCRIPT: styles[S], 667 SCRIPTSCRIPT: styles[SS] 668}; 669 670/* 671 * This file defines the Unicode scripts and script families that we 672 * support. To add new scripts or families, just add a new entry to the 673 * scriptData array below. Adding scripts to the scriptData array allows 674 * characters from that script to appear in \text{} environments. 675 */ 676 677/** 678 * Each script or script family has a name and an array of blocks. 679 * Each block is an array of two numbers which specify the start and 680 * end points (inclusive) of a block of Unicode codepoints. 681 */ 682 683/** 684 * Unicode block data for the families of scripts we support in \text{}. 685 * Scripts only need to appear here if they do not have font metrics. 686 */ 687var scriptData = [{ 688 // Latin characters beyond the Latin-1 characters we have metrics for. 689 // Needed for Czech, Hungarian and Turkish text, for example. 690 name: 'latin', 691 blocks: [[0x0100, 0x024f], // Latin Extended-A and Latin Extended-B 692 [0x0300, 0x036f] // Combining Diacritical marks 693 ] 694}, { 695 // The Cyrillic script used by Russian and related languages. 696 // A Cyrillic subset used to be supported as explicitly defined 697 // symbols in symbols.js 698 name: 'cyrillic', 699 blocks: [[0x0400, 0x04ff]] 700}, { 701 // Armenian 702 name: 'armenian', 703 blocks: [[0x0530, 0x058F]] 704}, { 705 // The Brahmic scripts of South and Southeast Asia 706 // Devanagari (0900â097F) 707 // Bengali (0980â09FF) 708 // Gurmukhi (0A00â0A7F) 709 // Gujarati (0A80â0AFF) 710 // Oriya (0B00â0B7F) 711 // Tamil (0B80â0BFF) 712 // Telugu (0C00â0C7F) 713 // Kannada (0C80â0CFF) 714 // Malayalam (0D00â0D7F) 715 // Sinhala (0D80â0DFF) 716 // Thai (0E00â0E7F) 717 // Lao (0E80â0EFF) 718 // Tibetan (0F00â0FFF) 719 // Myanmar (1000â109F) 720 name: 'brahmic', 721 blocks: [[0x0900, 0x109F]] 722}, { 723 name: 'georgian', 724 blocks: [[0x10A0, 0x10ff]] 725}, { 726 // Chinese and Japanese. 727 // The "k" in cjk is for Korean, but we've separated Korean out 728 name: "cjk", 729 blocks: [[0x3000, 0x30FF], // CJK symbols and punctuation, Hiragana, Katakana 730 [0x4E00, 0x9FAF], // CJK ideograms 731 [0xFF00, 0xFF60] // Fullwidth punctuation 732 // TODO: add halfwidth Katakana and Romanji glyphs 733 ] 734}, { 735 // Korean 736 name: 'hangul', 737 blocks: [[0xAC00, 0xD7AF]] 738}]; 739/** 740 * Given a codepoint, return the name of the script or script family 741 * it is from, or null if it is not part of a known block 742 */ 743 744function scriptFromCodepoint(codepoint) { 745 for (var i = 0; i < scriptData.length; i++) { 746 var script = scriptData[i]; 747 748 for (var _i = 0; _i < script.blocks.length; _i++) { 749 var block = script.blocks[_i]; 750 751 if (codepoint >= block[0] && codepoint <= block[1]) { 752 return script.name; 753 } 754 } 755 } 756 757 return null; 758} 759/** 760 * A flattened version of all the supported blocks in a single array. 761 * This is an optimization to make supportedCodepoint() fast. 762 */ 763 764var allBlocks = []; 765scriptData.forEach(s => s.blocks.forEach(b => allBlocks.push(...b))); 766/** 767 * Given a codepoint, return true if it falls within one of the 768 * scripts or script families defined above and false otherwise. 769 * 770 * Micro benchmarks shows that this is faster than 771 * /[\u3000-\u30FF\u4E00-\u9FAF\uFF00-\uFF60\uAC00-\uD7AF\u0900-\u109F]/.test() 772 * in Firefox, Chrome and Node. 773 */ 774 775function supportedCodepoint(codepoint) { 776 for (var i = 0; i < allBlocks.length; i += 2) { 777 if (codepoint >= allBlocks[i] && codepoint <= allBlocks[i + 1]) { 778 return true; 779 } 780 } 781 782 return false; 783} 784 785/** 786 * This file provides support to domTree.js and delimiter.js. 787 * It's a storehouse of path geometry for SVG images. 788 */ 789// In all paths below, the viewBox-to-em scale is 1000:1. 790var hLinePad = 80; // padding above a sqrt vinculum. Prevents image cropping. 791// The vinculum of a \sqrt can be made thicker by a KaTeX rendering option. 792// Think of variable extraVinculum as two detours in the SVG path. 793// The detour begins at the lower left of the area labeled extraVinculum below. 794// The detour proceeds one extraVinculum distance up and slightly to the right, 795// displacing the radiused corner between surd and vinculum. The radius is 796// traversed as usual, then the detour resumes. It goes right, to the end of 797// the very long vinculum, then down one extraVinculum distance, 798// after which it resumes regular path geometry for the radical. 799 800/* vinculum 801 / 802 /ââââââââââââââââââââââextraVinculum 803 / ââââââââââââââââââââââ0.04em (40 unit) std vinculum thickness 804 / / 805 / / 806 / /\ 807 / / surd 808*/ 809 810var sqrtMain = function sqrtMain(extraVinculum, hLinePad) { 811 // sqrtMain path geometry is from glyph U221A in the font KaTeX Main 812 return "M95," + (622 + extraVinculum + hLinePad) + "\nc-2.7,0,-7.17,-2.7,-13.5,-8c-5.8,-5.3,-9.5,-10,-9.5,-14\nc0,-2,0.3,-3.3,1,-4c1.3,-2.7,23.83,-20.7,67.5,-54\nc44.2,-33.3,65.8,-50.3,66.5,-51c1.3,-1.3,3,-2,5,-2c4.7,0,8.7,3.3,12,10\ns173,378,173,378c0.7,0,35.3,-71,104,-213c68.7,-142,137.5,-285,206.5,-429\nc69,-144,104.5,-217.7,106.5,-221\nl" + extraVinculum / 2.075 + " -" + extraVinculum + "\nc5.3,-9.3,12,-14,20,-14\nH400000v" + (40 + extraVinculum) + "H845.2724\ns-225.272,467,-225.272,467s-235,486,-235,486c-2.7,4.7,-9,7,-19,7\nc-6,0,-10,-1,-12,-3s-194,-422,-194,-422s-65,47,-65,47z\nM" + (834 + extraVinculum) + " " + hLinePad + "h400000v" + (40 + extraVinculum) + "h-400000z"; 813}; 814 815var sqrtSize1 = function sqrtSize1(extraVinculum, hLinePad) { 816 // size1 is from glyph U221A in the font KaTeX_Size1-Regular 817 return "M263," + (601 + extraVinculum + hLinePad) + "c0.7,0,18,39.7,52,119\nc34,79.3,68.167,158.7,102.5,238c34.3,79.3,51.8,119.3,52.5,120\nc340,-704.7,510.7,-1060.3,512,-1067\nl" + extraVinculum / 2.084 + " -" + extraVinculum + "\nc4.7,-7.3,11,-11,19,-11\nH40000v" + (40 + extraVinculum) + "H1012.3\ns-271.3,567,-271.3,567c-38.7,80.7,-84,175,-136,283c-52,108,-89.167,185.3,-111.5,232\nc-22.3,46.7,-33.8,70.3,-34.5,71c-4.7,4.7,-12.3,7,-23,7s-12,-1,-12,-1\ns-109,-253,-109,-253c-72.7,-168,-109.3,-252,-110,-252c-10.7,8,-22,16.7,-34,26\nc-22,17.3,-33.3,26,-34,26s-26,-26,-26,-26s76,-59,76,-59s76,-60,76,-60z\nM" + (1001 + extraVinculum) + " " + hLinePad + "h400000v" + (40 + extraVinculum) + "h-400000z"; 818}; 819 820var sqrtSize2 = function sqrtSize2(extraVinculum, hLinePad) { 821 // size2 is from glyph U221A in the font KaTeX_Size2-Regular 822 return "M983 " + (10 + extraVinculum + hLinePad) + "\nl" + extraVinculum / 3.13 + " -" + extraVinculum + "\nc4,-6.7,10,-10,18,-10 H400000v" + (40 + extraVinculum) + "\nH1013.1s-83.4,268,-264.1,840c-180.7,572,-277,876.3,-289,913c-4.7,4.7,-12.7,7,-24,7\ns-12,0,-12,0c-1.3,-3.3,-3.7,-11.7,-7,-25c-35.3,-125.3,-106.7,-373.3,-214,-744\nc-10,12,-21,25,-33,39s-32,39,-32,39c-6,-5.3,-15,-14,-27,-26s25,-30,25,-30\nc26.7,-32.7,52,-63,76,-91s52,-60,52,-60s208,722,208,722\nc56,-175.3,126.3,-397.3,211,-666c84.7,-268.7,153.8,-488.2,207.5,-658.5\nc53.7,-170.3,84.5,-266.8,92.5,-289.5z\
vendor: 4,637 bytes, lines 822-910
822nM" + (1001 + extraVinculum) + " " + hLinePad + "h400000v" + (40 + extraVinculum) + "h-400000z"; 823}; 824 825var sqrtSize3 = function sqrtSize3(extraVinculum, hLinePad) { 826 // size3 is from glyph U221A in the font KaTeX_Size3-Regular 827 return "M424," + (2398 + extraVinculum + hLinePad) + "\nc-1.3,-0.7,-38.5,-172,-111.5,-514c-73,-342,-109.8,-513.3,-110.5,-514\nc0,-2,-10.7,14.3,-32,49c-4.7,7.3,-9.8,15.7,-15.5,25c-5.7,9.3,-9.8,16,-12.5,20\ns-5,7,-5,7c-4,-3.3,-8.3,-7.7,-13,-13s-13,-13,-13,-13s76,-122,76,-122s77,-121,77,-121\ns209,968,209,968c0,-2,84.7,-361.7,254,-1079c169.3,-717.3,254.7,-1077.7,256,-1081\nl" + extraVinculum / 4.223 + " -" + extraVinculum + "c4,-6.7,10,-10,18,-10 H400000\nv" + (40 + extraVinculum) + "H1014.6\ns-87.3,378.7,-272.6,1166c-185.3,787.3,-279.3,1182.3,-282,1185\nc-2,6,-10,9,-24,9\nc-8,0,-12,-0.7,-12,-2z M" + (1001 + extraVinculum) + " " + hLinePad + "\nh400000v" + (40 + extraVinculum) + "h-400000z"; 828}; 829 830var sqrtSize4 = function sqrtSize4(extraVinculum, hLinePad) { 831 // size4 is from glyph U221A in the font KaTeX_Size4-Regular 832 return "M473," + (2713 + extraVinculum + hLinePad) + "\nc339.3,-1799.3,509.3,-2700,510,-2702 l" + extraVinculum / 5.298 + " -" + extraVinculum + "\nc3.3,-7.3,9.3,-11,18,-11 H400000v" + (40 + extraVinculum) + "H1017.7\ns-90.5,478,-276.2,1466c-185.7,988,-279.5,1483,-281.5,1485c-2,6,-10,9,-24,9\nc-8,0,-12,-0.7,-12,-2c0,-1.3,-5.3,-32,-16,-92c-50.7,-293.3,-119.7,-693.3,-207,-1200\nc0,-1.3,-5.3,8.7,-16,30c-10.7,21.3,-21.3,42.7,-32,64s-16,33,-16,33s-26,-26,-26,-26\ns76,-153,76,-153s77,-151,77,-151c0.7,0.7,35.7,202,105,604c67.3,400.7,102,602.7,104,\n606zM" + (1001 + extraVinculum) + " " + hLinePad + "h400000v" + (40 + extraVinculum) + "H1017.7z"; 833}; 834 835var phasePath = function phasePath(y) { 836 var x = y / 2; // x coordinate at top of angle 837 838 return "M400000 " + y + " H0 L" + x + " 0 l65 45 L145 " + (y - 80) + " H400000z"; 839}; 840 841var sqrtTall = function sqrtTall(extraVinculum, hLinePad, viewBoxHeight) { 842 // sqrtTall is from glyph U23B7 in the font KaTeX_Size4-Regular 843 // One path edge has a variable length. It runs vertically from the vinculum 844 // to a point near (14 units) the bottom of the surd. The vinculum 845 // is normally 40 units thick. So the length of the line in question is: 846 var vertSegment = viewBoxHeight - 54 - hLinePad - extraVinculum; 847 return "M702 " + (extraVinculum + hLinePad) + "H400000" + (40 + extraVinculum) + "\nH742v" + vertSegment + "l-4 4-4 4c-.667.7 -2 1.5-4 2.5s-4.167 1.833-6.5 2.5-5.5 1-9.5 1\nh-12l-28-84c-16.667-52-96.667 -294.333-240-727l-212 -643 -85 170\nc-4-3.333-8.333-7.667-13 -13l-13-13l77-155 77-156c66 199.333 139 419.667\n219 661 l218 661zM702 " + hLinePad + "H400000v" + (40 + extraVinculum) + "H742z"; 848}; 849 850var sqrtPath = function sqrtPath(size, extraVinculum, viewBoxHeight) { 851 extraVinculum = 1000 * extraVinculum; // Convert from document ems to viewBox. 852 853 var path = ""; 854 855 switch (size) { 856 case "sqrtMain": 857 path = sqrtMain(extraVinculum, hLinePad); 858 break; 859 860 case "sqrtSize1": 861 path = sqrtSize1(extraVinculum, hLinePad); 862 break; 863 864 case "sqrtSize2": 865 path = sqrtSize2(extraVinculum, hLinePad); 866 break; 867 868 case "sqrtSize3": 869 path = sqrtSize3(extraVinculum, hLinePad); 870 break; 871 872 case "sqrtSize4": 873 path = sqrtSize4(extraVinculum, hLinePad); 874 break; 875 876 case "sqrtTall": 877 path = sqrtTall(extraVinculum, hLinePad, viewBoxHeight); 878 } 879 880 return path; 881}; 882var innerPath = function innerPath(name, height) { 883 // The inner part of stretchy tall delimiters 884 switch (name) { 885 case "\u239c": 886 return "M291 0 H417 V" + height + " H291z M291 0 H417 V" + height + " H291z"; 887 888 case "\u2223": 889 return "M145 0 H188 V" + height + " H145z M145 0 H188 V" + height + " H145z"; 890 891 case "\u2225": 892 return "M145 0 H188 V" + height + " H145z M145 0 H188 V" + height + " H145z" + ("M367 0 H410 V" + height + " H367z M367 0 H410 V" + height + " H367z"); 893 894 case "\u239f": 895 return "M457 0 H583 V" + height + " H457z M457 0 H583 V" + height + " H457z"; 896 897 case "\u23a2": 898 return "M319 0 H403 V" + height + " H319z M319 0 H403 V" + height + " H319z"; 899 900 case "\u23a5": 901 return "M263 0 H347 V" + height + " H263z M263 0 H347 V" + height + " H263z"; 902 903 case "\u23aa": 904 return "M384 0 H504 V" + height + " H384z M384 0 H504 V" + height + " H384z"; 905 906 case "\u23d0": 907 return "M312 0 H355 V" + height + " H312z M312 0 H355 V" + height + " H312z"; 908 909 case "\u2016": 910 return "M257 0 H300 V" + height + " H257z M257 0 H300 V" + height + " H257z" + ("M478 0 H521 V" + height + " H478z M478 0 H521 V" + height + " H478z");
vendor: 17,177 bytes, lines 911-994
911 912 default: 913 return ""; 914 } 915}; 916var path = { 917 // The doubleleftarrow geometry is from glyph U+21D0 in the font KaTeX Main 918 doubleleftarrow: "M262 157\nl10-10c34-36 62.7-77 86-123 3.3-8 5-13.3 5-16 0-5.3-6.7-8-20-8-7.3\n 0-12.2.5-14.5 1.5-2.3 1-4.8 4.5-7.5 10.5-49.3 97.3-121.7 169.3-217 216-28\n 14-57.3 25-88 33-6.7 2-11 3.8-13 5.5-2 1.7-3 4.2-3 7.5s1 5.8 3 7.5\nc2 1.7 6.3 3.5 13 5.5 68 17.3 128.2 47.8 180.5 91.5 52.3 43.7 93.8 96.2 124.5\n 157.5 9.3 8 15.3 12.3 18 13h6c12-.7 18-4 18-10 0-2-1.7-7-5-15-23.3-46-52-87\n-86-123l-10-10h399738v-40H218c328 0 0 0 0 0l-10-8c-26.7-20-65.7-43-117-69 2.7\n-2 6-3.7 10-5 36.7-16 72.3-37.3 107-64l10-8h399782v-40z\nm8 0v40h399730v-40zm0 194v40h399730v-40z", 919 // doublerightarrow is from glyph U+21D2 in font KaTeX Main 920 doublerightarrow: "M399738 392l\n-10 10c-34 36-62.7 77-86 123-3.3 8-5 13.3-5 16 0 5.3 6.7 8 20 8 7.3 0 12.2-.5\n 14.5-1.5 2.3-1 4.8-4.5 7.5-10.5 49.3-97.3 121.7-169.3 217-216 28-14 57.3-25 88\n-33 6.7-2 11-3.8 13-5.5 2-1.7 3-4.2 3-7.5s-1-5.8-3-7.5c-2-1.7-6.3-3.5-13-5.5-68\n-17.3-128.2-47.8-180.5-91.5-52.3-43.7-93.8-96.2-124.5-157.5-9.3-8-15.3-12.3-18\n-13h-6c-12 .7-18 4-18 10 0 2 1.7 7 5 15 23.3 46 52 87 86 123l10 10H0v40h399782\nc-328 0 0 0 0 0l10 8c26.7 20 65.7 43 117 69-2.7 2-6 3.7-10 5-36.7 16-72.3 37.3\n-107 64l-10 8H0v40zM0 157v40h399730v-40zm0 194v40h399730v-40z", 921 // leftarrow is from glyph U+2190 in font KaTeX Main 922 leftarrow: "M400000 241H110l3-3c68.7-52.7 113.7-120\n 135-202 4-14.7 6-23 6-25 0-7.3-7-11-21-11-8 0-13.2.8-15.5 2.5-2.3 1.7-4.2 5.8\n-5.5 12.5-1.3 4.7-2.7 10.3-4 17-12 48.7-34.8 92-68.5 130S65.3 228.3 18 247\nc-10 4-16 7.7-18 11 0 8.7 6 14.3 18 17 47.3 18.7 87.8 47 121.5 85S196 441.3 208\n 490c.7 2 1.3 5 2 9s1.2 6.7 1.5 8c.3 1.3 1 3.3 2 6s2.2 4.5 3.5 5.5c1.3 1 3.3\n 1.8 6 2.5s6 1 10 1c14 0 21-3.7 21-11 0-2-2-10.3-6-25-20-79.3-65-146.7-135-202\n l-3-3h399890zM100 241v40h399900v-40z", 923 // overbrace is from glyphs U+23A9/23A8/23A7 in font KaTeX_Size4-Regular 924 leftbrace: "M6 548l-6-6v-35l6-11c56-104 135.3-181.3 238-232 57.3-28.7 117\n-45 179-50h399577v120H403c-43.3 7-81 15-113 26-100.7 33-179.7 91-237 174-2.7\n 5-6 9-10 13-.7 1-7.3 1-20 1H6z", 925 leftbraceunder: "M0 6l6-6h17c12.688 0 19.313.3 20 1 4 4 7.313 8.3 10 13\n 35.313 51.3 80.813 93.8 136.5 127.5 55.688 33.7 117.188 55.8 184.5 66.5.688\n 0 2 .3 4 1 18.688 2.7 76 4.3 172 5h399450v120H429l-6-1c-124.688-8-235-61.7\n-331-161C60.687 138.7 32.312 99.3 7 54L0 41V6z", 926 // overgroup is from the MnSymbol package (public domain) 927 leftgroup: "M400000 80\nH435C64 80 168.3 229.4 21 260c-5.9 1.2-18 0-18 0-2 0-3-1-3-3v-38C76 61 257 0\n 435 0h399565z", 928 leftgroupunder: "M400000 262\nH435C64 262 168.3 112.6 21 82c-5.9-1.2-18 0-18 0-2 0-3 1-3 3v38c76 158 257 219\n 435 219h399565z", 929 // Harpoons are from glyph U+21BD in font KaTeX Main 930 leftharpoon: "M0 267c.7 5.3 3 10 7 14h399993v-40H93c3.3\n-3.3 10.2-9.5 20.5-18.5s17.8-15.8 22.5-20.5c50.7-52 88-110.3 112-175 4-11.3 5\n-18.3 3-21-1.3-4-7.3-6-18-6-8 0-13 .7-15 2s-4.7 6.7-8 16c-42 98.7-107.3 174.7\n-196 228-6.7 4.7-10.7 8-12 10-1.3 2-2 5.7-2 11zm100-26v40h399900v-40z", 931 leftharpoonplus: "M0 267c.7 5.3 3 10 7 14h399993v-40H93c3.3-3.3 10.2-9.5\n 20.5-18.5s17.8-15.8 22.5-20.5c50.7-52 88-110.3 112-175 4-11.3 5-18.3 3-21-1.3\n-4-7.3-6-18-6-8 0-13 .7-15 2s-4.7 6.7-8 16c-42 98.7-107.3 174.7-196 228-6.7 4.7\n-10.7 8-12 10-1.3 2-2 5.7-2 11zm100-26v40h399900v-40zM0 435v40h400000v-40z\nm0 0v40h400000v-40z", 932 leftharpoondown: "M7 241c-4 4-6.333 8.667-7 14 0 5.333.667 9 2 11s5.333\n 5.333 12 10c90.667 54 156 130 196 228 3.333 10.667 6.333 16.333 9 17 2 .667 5\n 1 9 1h5c10.667 0 16.667-2 18-6 2-2.667 1-9.667-3-21-32-87.333-82.667-157.667\n-152-211l-3-3h399907v-40zM93 281 H400000 v-40L7 241z", 933 leftharpoondownplus: "M7 435c-4 4-6.3 8.7-7 14 0 5.3.7 9 2 11s5.3 5.3 12\n 10c90.7 54 156 130 196 228 3.3 10.7 6.3 16.3 9 17 2 .7 5 1 9 1h5c10.7 0 16.7\n-2 18-6 2-2.7 1-9.7-3-21-32-87.3-82.7-157.7-152-211l-3-3h399907v-40H7zm93 0\nv40h399900v-40zM0 241v40h399900v-40zm0 0v40h399900v-40z", 934 // hook is from glyph U+21A9 in font KaTeX Main 935 lefthook: "M400000 281 H103s-33-11.2-61-33.5S0 197.3 0 164s14.2-61.2 42.5\n-83.5C70.8 58.2 104 47 142 47 c16.7 0 25 6.7 25 20 0 12-8.7 18.7-26 20-40 3.3\n-68.7 15.7-86 37-10 12-15 25.3-15 40 0 22.7 9.8 40.7 29.5 54 19.7 13.3 43.5 21\n 71.5 23h399859zM103 281v-40h399897v40z", 936 leftlinesegment: "M40 281 V428 H0 V94 H40 V241 H400000 v40z\nM40 281 V428 H0 V94 H40 V241 H400000 v40z", 937 leftmapsto: "M40 281 V448H0V74H40V241H400000v40z\nM40 281 V448H0V74H40V241H400000v40z", 938 // tofrom is from glyph U+21C4 in font KaTeX AMS Regular 939 leftToFrom: "M0 147h400000v40H0zm0 214c68 40 115.7 95.7 143 167h22c15.3 0 23\n-.3 23-1 0-1.3-5.3-13.7-16-37-18-35.3-41.3-69-70-101l-7-8h399905v-40H95l7-8\nc28.7-32 52-65.7 70-101 10.7-23.3 16-35.7 16-37 0-.7-7.7-1-23-1h-22C115.7 265.3\n 68 321 0 361zm0-174v-40h399900v40zm100 154v40h399900v-40z", 940 longequal: "M0 50 h400000 v40H0z m0 194h40000v40H0z\nM0 50 h400000 v40H0z m0 194h40000v40H0z", 941 midbrace: "M200428 334\nc-100.7-8.3-195.3-44-280-108-55.3-42-101.7-93-139-153l-9-14c-2.7 4-5.7 8.7-9 14\n-53.3 86.7-123.7 153-211 199-66.7 36-137.3 56.3-212 62H0V214h199568c178.3-11.7\n 311.7-78.3 403-201 6-8 9.7-12 11-12 .7-.7 6.7-1 18-1s17.3.3 18 1c1.3 0 5 4 11\n 12 44.7 59.3 101.3 106.3 170 141s145.3 54.3 229 60h199572v120z", 942 midbraceunder: "M199572 214\nc100.7 8.3 195.3 44 280 108 55.3 42 101.7 93 139 153l9 14c2.7-4 5.7-8.7 9-14\n 53.3-86.7 123.7-153 211-199 66.7-36 137.3-56.3 212-62h199568v120H200432c-178.3\n 11.7-311.7 78.3-403 201-6 8-9.7 12-11 12-.7.7-6.7 1-18 1s-17.3-.3-18-1c-1.3 0\n-5-4-11-12-44.7-59.3-101.3-106.3-170-141s-145.3-54.3-229-60H0V214z", 943 oiintSize1: "M512.6 71.6c272.6 0 320.3 106.8 320.3 178.2 0 70.8-47.7 177.6\n-320.3 177.6S193.1 320.6 193.1 249.8c0-71.4 46.9-178.2 319.5-178.2z\nm368.1 178.2c0-86.4-60.9-215.4-368.1-215.4-306.4 0-367.3 129-367.3 215.4 0 85.8\n60.9 214.8 367.3 214.8 307.2 0 368.1-129 368.1-214.8z", 944 oiintSize2: "M757.8 100.1c384.7 0 451.1 137.6 451.1 230 0 91.3-66.4 228.8\n-451.1 228.8-386.3 0-452.7-137.5-452.7-228.8 0-92.4 66.4-230 452.7-230z\nm502.4 230c0-111.2-82.4-277.2-502.4-277.2s-504 166-504 277.2\nc0 110 84 276 504 276s502.4-166 502.4-276z", 945 oiiintSize1: "M681.4 71.6c408.9 0 480.5 106.8 480.5 178.2 0 70.8-71.6 177.6\n-480.5 177.6S202.1 320.6 202.1 249.8c0-71.4 70.5-178.2 479.3-178.2z\nm525.8 178.2c0-86.4-86.8-215.4-525.7-215.4-437.9 0-524.7 129-524.7 215.4 0\n85.8 86.8 214.8 524.7 214.8 438.9 0 525.7-129 525.7-214.8z", 946 oiiintSize2: "M1021.2 53c603.6 0 707.8 165.8 707.8 277.2 0 110-104.2 275.8\n-707.8 275.8-606 0-710.2-165.8-710.2-275.8C311 218.8 415.2 53 1021.2 53z\nm770.4 277.1c0-131.2-126.4-327.6-770.5-327.6S248.4 198.9 248.4 330.1\nc0 130 128.8 326.4 772.7 326.4s770.5-196.4 770.5-326.4z", 947 rightarrow: "M0 241v40h399891c-47.3 35.3-84 78-110 128\n-16.7 32-27.7 63.7-33 95 0 1.3-.2 2.7-.5 4-.3 1.3-.5 2.3-.5 3 0 7.3 6.7 11 20\n 11 8 0 13.2-.8 15.5-2.5 2.3-1.7 4.2-5.5 5.5-11.5 2-13.3 5.7-27 11-41 14.7-44.7\n 39-84.5 73-119.5s73.7-60.2 119-75.5c6-2 9-5.7 9-11s-3-9-9-11c-45.3-15.3-85\n-40.5-119-75.5s-58.3-74.8-73-119.5c-4.7-14-8.3-27.3-11-40-1.3-6.7-3.2-10.8-5.5\n-12.5-2.3-1.7-7.5-2.5-15.5-2.5-14 0-21 3.7-21 11 0 2 2 10.3 6 25 20.7 83.3 67\n 151.7 139 205zm0 0v40h399900v-40z", 948 rightbrace: "M400000 542l\n-6 6h-17c-12.7 0-19.3-.3-20-1-4-4-7.3-8.3-10-13-35.3-51.3-80.8-93.8-136.5-127.5\ns-117.2-55.8-184.5-66.5c-.7 0-2-.3-4-1-18.7-2.7-76-4.3-172-5H0V214h399571l6 1\nc124.7 8 235 61.7 331 161 31.3 33.3 59.7 72.7 85 118l7 13v35z", 949 rightbraceunder: "M399994 0l6 6v35l-6 11c-56 104-135.3 181.3-238 232-57.3\n 28.7-117 45-179 50H-300V214h399897c43.3-7 81-15 113-26 100.7-33 179.7-91 237\n-174 2.7-5 6-9 10-13 .7-1 7.3-1 20-1h17z", 950 rightgroup: "M0 80h399565c371 0 266.7 149.4 414 180 5.9 1.2 18 0 18 0 2 0\n 3-1 3-3v-38c-76-158-257-219-435-219H0z", 951 rightgroupunder: "M0 262h399565c371 0 266.7-149.4 414-180 5.9-1.2 18 0 18\n 0 2 0 3 1 3 3v38c-76 158-257 219-435 219H0z", 952 rightharpoon: "M0 241v40h399993c4.7-4.7 7-9.3 7-14 0-9.3\n-3.7-15.3-11-18-92.7-56.7-159-133.7-199-231-3.3-9.3-6-14.7-8-16-2-1.3-7-2-15-2\n-10.7 0-16.7 2-18 6-2 2.7-1 9.7 3 21 15.3 42 36.7 81.8 64 119.5 27.3 37.7 58\n 69.2 92 94.5zm0 0v40h399900v-40z", 953 rightharpoonplus: "M0 241v40h399993c4.7-4.7 7-9.3 7-14 0-9.3-3.7-15.3-11\n-18-92.7-56.7-159-133.7-199-231-3.3-9.3-6-14.7-8-16-2-1.3-7-2-15-2-10.7 0-16.7\n 2-18 6-2 2.7-1 9.7 3 21 15.3 42 36.7 81.8 64 119.5 27.3 37.7 58 69.2 92 94.5z\nm0 0v40h399900v-40z m100 194v40h399900v-40zm0 0v40h399900v-40z", 954 rightharpoondown: "M399747 511c0 7.3 6.7 11 20 11 8 0 13-.8 15-2.5s4.7-6.8\n 8-15.5c40-94 99.3-166.3 178-217 13.3-8 20.3-12.3 21-13 5.3-3.3 8.5-5.8 9.5\n-7.5 1-1.7 1.5-5.2 1.5-10.5s-2.3-10.3-7-15H0v40h399908c-34 25.3-64.7 57-92 95\n-27.3 38-48.7 77.7-64 119-3.3 8.7-5 14-5 16zM0 241v40h399900v-40z", 955 rightharpoondownplus: "M399747 705c0 7.3 6.7 11 20 11 8 0 13-.8\n 15-2.5s4.7-6.8 8-15.5c40-94 99.3-166.3 178-217 13.3-8 20.3-12.3 21-13 5.3-3.3\n 8.5-5.8 9.5-7.5 1-1.7 1.5-5.2 1.5-10.5s-2.3-10.3-7-15H0v40h399908c-34 25.3\n-64.7 57-92 95-27.3 38-48.7 77.7-64 119-3.3 8.7-5 14-5 16zM0 435v40h399900v-40z\nm0-194v40h400000v-40zm0 0v40h400000v-40z", 956 righthook: "M399859 241c-764 0 0 0 0 0 40-3.3 68.7-15.7 86-37 10-12 15-25.3\n 15-40 0-22.7-9.8-40.7-29.5-54-19.7-13.3-43.5-21-71.5-23-17.3-1.3-26-8-26-20 0\n-13.3 8.7-20 26-20 38 0 71 11.2 99 33.5 0 0 7 5.6 21 16.7 14 11.2 21 33.5 21\n 66.8s-14 61.2-42 83.5c-28 22.3-61 33.5-99 33.5L0 241z M0 281v-40h399859v40z", 957 rightlinesegment: "M399960 241 V94 h40 V428 h-40 V281 H0 v-40z\nM399960 241 V94 h40 V428 h-40 V281 H0 v-40z", 958 rightToFrom: "M400000 167c-70.7-42-118-97.7-142-167h-23c-15.3 0-23 .3-23\n 1 0 1.3 5.3 13.7 16 37 18 35.3 41.3 69 70 101l7 8H0v40h399905l-7 8c-28.7 32\n-52 65.7-70 101-10.7 23.3-16 35.7-16 37 0 .7 7.7 1 23 1h23c24-69.3 71.3-125 142\n-167z M100 147v40h399900v-40zM0 341v40h399900v-40z", 959 // twoheadleftarrow is from glyph U+219E in font KaTeX AMS Regular 960 twoheadleftarrow: "M0 167c68 40\n 115.7 95.7 143 167h22c15.3 0 23-.3 23-1 0-1.3-5.3-13.7-16-37-18-35.3-41.3-69\n-70-101l-7-8h125l9 7c50.7 39.3 85 86 103 140h46c0-4.7-6.3-18.7-19-42-18-35.3\n-40-67.3-66-96l-9-9h399716v-40H284l9-9c26-28.7 48-60.7 66-96 12.7-23.333 19\n-37.333 19-42h-46c-18 54-52.3 100.7-103 140l-9 7H95l7-8c28.7-32 52-65.7 70-101\n 10.7-23.333 16-35.7 16-37 0-.7-7.7-1-23-1h-22C115.7 71.3 68 127 0 167z", 961 twoheadrightarrow: "M400000 167\nc-68-40-115.7-95.7-143-167h-22c-15.3 0-23 .3-23 1 0 1.3 5.3 13.7 16 37 18 35.3\n 41.3 69 70 101l7 8h-125l-9-7c-50.7-39.3-85-86-103-140h-46c0 4.7 6.3 18.7 19 42\n 18 35.3 40 67.3 66 96l9 9H0v40h399716l-9 9c-26 28.7-48 60.7-66 96-12.7 23.333\n-19 37.333-19 42h46c18-54 52.3-100.7 103-140l9-7h125l-7 8c-28.7 32-52 65.7-70\n 101-10.7 23.333-16 35.7-16 37 0 .7 7.7 1 23 1h22c27.3-71.3 75-127 143-167z", 962 // tilde1 is a modified version of a glyph from the MnSymbol package 963 tilde1: "M200 55.538c-77 0-168 73.953-177 73.953-3 0-7\n-2.175-9-5.437L2 97c-1-2-2-4-2-6 0-4 2-7 5-9l20-12C116 12 171 0 207 0c86 0\n 114 68 191 68 78 0 168-68 177-68 4 0 7 2 9 5l12 19c1 2.175 2 4.35 2 6.525 0\n 4.35-2 7.613-5 9.788l-19 13.05c-92 63.077-116.937 75.308-183 76.128\n-68.267.847-113-73.952-191-73.952z", 964 // ditto tilde2, tilde3, & tilde4 965 tilde2: "M344 55.266c-142 0-300.638 81.316-311.5 86.418\n-8.01 3.762-22.5 10.91-23.5 5.562L1 120c-1-2-1-3-1-4 0-5 3-9 8-10l18.4-9C160.9\n 31.9 283 0 358 0c148 0 188 122 331 122s314-97 326-97c4 0 8 2 10 7l7 21.114\nc1 2.14 1 3.21 1 4.28 0 5.347-3 9.626-7 10.696l-22.3 12.622C852.6 158.372 751\n 181.476 676 181.476c-149 0-189-126.21-332-126.21z", 966 tilde3: "M786 59C457 59 32 175.242 13 175.242c-6 0-10-3.457\n-11-10.37L.15 138c-1-7 3-12 10-13l19.2-6.4C378.4 40.7 634.3 0 804.3 0c337 0\n 411.8 157 746.8 157 328 0 754-112 773-112 5 0 10 3 11 9l1 14.075c1 8.066-.697\n 16.595-6.697 17.492l-21.052 7.31c-367.9 98.146-609.15 122.696-778.15 122.696\n -338 0-409-156.573-744-156.573z", 967 tilde4: "M786 58C457 58 32 177.487 13 177.487c-6 0-10-3.345\n-11-10.035L.15 143c-1-7 3-12 10-13l22-6.7C381.2 35 637.15 0 807.15 0c337 0 409\n 177 744 177 328 0 754-127 773-127 5 0 10 3 11 9l1 14.794c1 7.805-3 13.38-9\n 14.495l-20.7 5.574c-366.85 99.79-607.3 139.372-776.3 139.372-338 0-409\n -175.236-744-175.236z", 968 // vec is from glyph U+20D7 in font KaTeX Main 969 vec: "M377 20c0-5.333 1.833-10 5.5-14S391 0 397 0c4.667 0 8.667 1.667 12 5\n3.333 2.667 6.667 9 10 19 6.667 24.667 20.333 43.667 41 57 7.333 4.667 11\n10.667 11 18 0 6-1 10-3 12s-6.667 5-14 9c-28.667 14.667-53.667 35.667-75 63\n-1.333 1.333-3.167 3.5-5.5 6.5s-4 4.833-5 5.5c-1 .667-2.5 1.333-4.5 2s-4.333 1\n-7 1c-4.667 0-9.167-1.833-13.5-5.5S337 184 337 178c0-12.667 15.667-32.333 47-59\nH213l-171-1c-8.667-6-13-12.333-13-19 0-4.667 4.333-11.333 13-20h359\nc-16-25.333-24-45-24-59z", 970 // widehat1 is a modified version of a glyph from the MnSymbol package 971 widehat1: "M529 0h5l519 115c5 1 9 5 9 10 0 1-1 2-1 3l-4 22\nc-1 5-5 9-11 9h-2L532 67 19 159h-2c-5 0-9-4-11-9l-5-22c-1-6 2-12 8-13z", 972 // ditto widehat2, widehat3, & widehat4 973 widehat2: "M1181 0h2l1171 176c6 0 10 5 10 11l-2 23c-1 6-5 10\n-11 10h-1L1182 67 15 220h-1c-6 0-10-4-11-10l-2-23c-1-6 4-11 10-11z", 974 widehat3: "M1181 0h2l1171 236c6 0 10 5 10 11l-2 23c-1 6-5 10\n-11 10h-1L1182 67 15 280h-1c-6 0-10-4-11-10l-2-23c-1-6 4-11 10-11z", 975 widehat4: "M1181 0h2l1171 296c6 0 10 5 10 11l-2 23c-1 6-5 10\n-11 10h-1L1182 67 15 340h-1c-6 0-10-4-11-10l-2-23c-1-6 4-11 10-11z", 976 // widecheck paths are all inverted versions of widehat 977 widecheck1: "M529,159h5l519,-115c5,-1,9,-5,9,-10c0,-1,-1,-2,-1,-3l-4,-22c-1,\n-5,-5,-9,-11,-9h-2l-512,92l-513,-92h-2c-5,0,-9,4,-11,9l-5,22c-1,6,2,12,8,13z", 978 widecheck2: "M1181,220h2l1171,-176c6,0,10,-5,10,-11l-2,-23c-1,-6,-5,-10,\n-11,-10h-1l-1168,153l-1167,-153h-1c-6,0,-10,4,-11,10l-2,23c-1,6,4,11,10,11z", 979 widecheck3: "M1181,280h2l1171,-236c6,0,10,-5,10,-11l-2,-23c-1,-6,-5,-10,\n-11,-10h-1l-1168,213l-1167,-213h-1c-6,0,-10,4,-11,10l-2,23c-1,6,4,11,10,11z", 980 widecheck4: "M1181,340h2l1171,-296c6,0,10,-5,10,-11l-2,-23c-1,-6,-5,-10,\n-11,-10h-1l-1168,273l-1167,-273h-1c-6,0,-10,4,-11,10l-2,23c-1,6,4,11,10,11z", 981 // The next ten paths support reaction arrows from the mhchem package. 982 // Arrows for \ce{<-->} are offset from xAxis by 0.22ex, per mhchem in LaTeX 983 // baraboveleftarrow is mostly from glyph U+2190 in font KaTeX Main 984 baraboveleftarrow: "M400000 620h-399890l3 -3c68.7 -52.7 113.7 -120 135 -202\nc4 -14.7 6 -23 6 -25c0 -7.3 -7 -11 -21 -11c-8 0 -13.2 0.8 -15.5 2.5\nc-2.3 1.7 -4.2 5.8 -5.5 12.5c-1.3 4.7 -2.7 10.3 -4 17c-12 48.7 -34.8 92 -68.5 130\ns-74.2 66.3 -121.5 85c-10 4 -16 7.7 -18 11c0 8.7 6 14.3 18 17c47.3 18.7 87.8 47\n121.5 85s56.5 81.3 68.5 130c0.7 2 1.3 5 2 9s1.2 6.7 1.5 8c0.3 1.3 1 3.3 2 6\ns2.2 4.5 3.5 5.5c1.3 1 3.3 1.8 6 2.5s6 1 10 1c14 0 21 -3.7 21 -11\nc0 -2 -2 -10.3 -6 -25c-20 -79.3 -65 -146.7 -135 -202l-3 -3h399890z\nM100 620v40h399900v-40z M0 241v40h399900v-40zM0 241v40h399900v-40z", 985 // rightarrowabovebar is mostly from glyph U+2192, KaTeX Main 986 rightarrowabovebar: "M0 241v40h399891c-47.3 35.3-84 78-110 128-16.7 32\n-27.7 63.7-33 95 0 1.3-.2 2.7-.5 4-.3 1.3-.5 2.3-.5 3 0 7.3 6.7 11 20 11 8 0\n13.2-.8 15.5-2.5 2.3-1.7 4.2-5.5 5.5-11.5 2-13.3 5.7-27 11-41 14.7-44.7 39\n-84.5 73-119.5s73.7-60.2 119-75.5c6-2 9-5.7 9-11s-3-9-9-11c-45.3-15.3-85-40.5\n-119-75.5s-58.3-74.8-73-119.5c-4.7-14-8.3-27.3-11-40-1.3-6.7-3.2-10.8-5.5\n-12.5-2.3-1.7-7.5-2.5-15.5-2.5-14 0-21 3.7-21 11 0 2 2 10.3 6 25 20.7 83.3 67\n151.7 139 205zm96 379h399894v40H0zm0 0h399904v40H0z", 987 // The short left harpoon has 0.5em (i.e. 500 units) kern on the left end. 988 // Ref from mhchem.sty: \rlap{\raisebox{-.22ex}{$\kern0.5em 989 baraboveshortleftharpoon: "M507,435c-4,4,-6.3,8.7,-7,14c0,5.3,0.7,9,2,11\nc1.3,2,5.3,5.3,12,10c90.7,54,156,130,196,228c3.3,10.7,6.3,16.3,9,17\nc2,0.7,5,1,9,1c0,0,5,0,5,0c10.7,0,16.7,-2,18,-6c2,-2.7,1,-9.7,-3,-21\nc-32,-87.3,-82.7,-157.7,-152,-211c0,0,-3,-3,-3,-3l399351,0l0,-40\nc-398570,0,-399437,0,-399437,0z M593 435 v40 H399500 v-40z\nM0 281 v-40 H399908 v40z M0 281 v-40 H399908 v40z", 990 rightharpoonaboveshortbar: "M0,241 l0,40c399126,0,399993,0,399993,0\nc4.7,-4.7,7,-9.3,7,-14c0,-9.3,-3.7,-15.3,-11,-18c-92.7,-56.7,-159,-133.7,-199,\n-231c-3.3,-9.3,-6,-14.7,-8,-16c-2,-1.3,-7,-2,-15,-2c-10.7,0,-16.7,2,-18,6\nc-2,2.7,-1,9.7,3,21c15.3,42,36.7,81.8,64,119.5c27.3,37.7,58,69.2,92,94.5z\nM0 241 v40 H399908 v-40z M0 475 v-40 H399500 v40z M0 475 v-40 H399500 v40z", 991 shortbaraboveleftharpoon: "M7,435c-4,4,-6.3,8.7,-7,14c0,5.3,0.7,9,2,11\nc1.3,2,5.3,5.3,12,10c90.7,54,156,130,196,228c3.3,10.7,6.3,16.3,9,17c2,0.7,5,1,9,\n1c0,0,5,0,5,0c10.7,0,16.7,-2,18,-6c2,-2.7,1,-9.7,-3,-21c-32,-87.3,-82.7,-157.7,\n-152,-211c0,0,-3,-3,-3,-3l399907,0l0,-40c-399126,0,-399993,0,-399993,0z\nM93 435 v40 H400000 v-40z M500 241 v40 H400000 v-40z M500 241 v40 H400000 v-40z", 992 shortrightharpoonabovebar: "M53,241l0,40c398570,0,399437,0,399437,0\nc4.7,-4.7,7,-9.3,7,-14c0,-9.3,-3.7,-15.3,-11,-18c-92.7,-56.7,-159,-133.7,-199,\n-231c-3.3,-9.3,-6,-14.7,-8,-16c-2,-1.3,-7,-2,-15,-2c-10.7,0,-16.7,2,-18,6\nc-2,2.7,-1,9.7,3,21c15.3,42,36.7,81.8,64,119.5c27.3,37.7,58,69.2,92,94.5z\nM500 241 v40 H399408 v-40z M500 435 v40 H400000 v-40z" 993}; 994var tallDelim = function tallDelim
vendor: 3,900 bytes, lines 994-1057
994(label, midHeight) { 995 switch (label) { 996 case "lbrack": 997 return "M403 1759 V84 H666 V0 H319 V1759 v" + midHeight + " v1759 h347 v-84\nH403z M403 1759 V0 H319 V1759 v" + midHeight + " v1759 h84z"; 998 999 case "rbrack": 1000 return "M347 1759 V0 H0 V84 H263 V1759 v" + midHeight + " v1759 H0 v84 H347z\nM347 1759 V0 H263 V1759 v" + midHeight + " v1759 h84z"; 1001 1002 case "vert": 1003 return "M145 15 v585 v" + midHeight + " v585 c2.667,10,9.667,15,21,15\nc10,0,16.667,-5,20,-15 v-585 v" + -midHeight + " v-585 c-2.667,-10,-9.667,-15,-21,-15\nc-10,0,-16.667,5,-20,15z M188 15 H145 v585 v" + midHeight + " v585 h43z"; 1004 1005 case "doublevert": 1006 return "M145 15 v585 v" + midHeight + " v585 c2.667,10,9.667,15,21,15\nc10,0,16.667,-5,20,-15 v-585 v" + -midHeight + " v-585 c-2.667,-10,-9.667,-15,-21,-15\nc-10,0,-16.667,5,-20,15z M188 15 H145 v585 v" + midHeight + " v585 h43z\nM367 15 v585 v" + midHeight + " v585 c2.667,10,9.667,15,21,15\nc10,0,16.667,-5,20,-15 v-585 v" + -midHeight + " v-585 c-2.667,-10,-9.667,-15,-21,-15\nc-10,0,-16.667,5,-20,15z M410 15 H367 v585 v" + midHeight + " v585 h43z"; 1007 1008 case "lfloor": 1009 return "M319 602 V0 H403 V602 v" + midHeight + " v1715 h263 v84 H319z\nMM319 602 V0 H403 V602 v" + midHeight + " v1715 H319z"; 1010 1011 case "rfloor": 1012 return "M319 602 V0 H403 V602 v" + midHeight + " v1799 H0 v-84 H319z\nMM319 602 V0 H403 V602 v" + midHeight + " v1715 H319z"; 1013 1014 case "lceil": 1015 return "M403 1759 V84 H666 V0 H319 V1759 v" + midHeight + " v602 h84z\nM403 1759 V0 H319 V1759 v" + midHeight + " v602 h84z"; 1016 1017 case "rceil": 1018 return "M347 1759 V0 H0 V84 H263 V1759 v" + midHeight + " v602 h84z\nM347 1759 V0 h-84 V1759 v" + midHeight + " v602 h84z"; 1019 1020 case "lparen": 1021 return "M863,9c0,-2,-2,-5,-6,-9c0,0,-17,0,-17,0c-12.7,0,-19.3,0.3,-20,1\nc-5.3,5.3,-10.3,11,-15,17c-242.7,294.7,-395.3,682,-458,1162c-21.3,163.3,-33.3,349,\n-36,557 l0," + (midHeight + 84) + "c0.2,6,0,26,0,60c2,159.3,10,310.7,24,454c53.3,528,210,\n949.7,470,1265c4.7,6,9.7,11.7,15,17c0.7,0.7,7,1,19,1c0,0,18,0,18,0c4,-4,6,-7,6,-9\nc0,-2.7,-3.3,-8.7,-10,-18c-135.3,-192.7,-235.5,-414.3,-300.5,-665c-65,-250.7,-102.5,\n-544.7,-112.5,-882c-2,-104,-3,-167,-3,-189\nl0,-" + (midHeight + 92) + "c0,-162.7,5.7,-314,17,-454c20.7,-272,63.7,-513,129,-723c65.3,\n-210,155.3,-396.3,270,-559c6.7,-9.3,10,-15.3,10,-18z"; 1022 1023 case "rparen": 1024 return "M76,0c-16.7,0,-25,3,-25,9c0,2,2,6.3,6,13c21.3,28.7,42.3,60.3,\n63,95c96.7,156.7,172.8,332.5,228.5,527.5c55.7,195,92.8,416.5,111.5,664.5\nc11.3,139.3,17,290.7,17,454c0,28,1.7,43,3.3,45l0," + (midHeight + 9) + "\nc-3,4,-3.3,16.7,-3.3,38c0,162,-5.7,313.7,-17,455c-18.7,248,-55.8,469.3,-111.5,664\nc-55.7,194.7,-131.8,370.3,-228.5,527c-20.7,34.7,-41.7,66.3,-63,95c-2,3.3,-4,7,-6,11\nc0,7.3,5.7,11,17,11c0,0,11,0,11,0c9.3,0,14.3,-0.3,15,-1c5.3,-5.3,10.3,-11,15,-17\nc242.7,-294.7,395.3,-681.7,458,-1161c21.3,-164.7,33.3,-350.7,36,-558\nl0,-" + (midHeight + 144) + "c-2,-159.3,-10,-310.7,-24,-454c-53.3,-528,-210,-949.7,\n-470,-1265c-4.7,-6,-9.7,-11.7,-15,-17c-0.7,-0.7,-6.7,-1,-18,-1z"; 1025 1026 default: 1027 // We should not ever get here. 1028 throw new Error("Unknown stretchy delimiter."); 1029 } 1030}; 1031 1032/** 1033 * This node represents a document fragment, which contains elements, but when 1034 * placed into the DOM doesn't have any representation itself. It only contains 1035 * children and doesn't have any DOM node properties. 1036 */ 1037class DocumentFragment { 1038 // HtmlDomNode 1039 // Never used; needed for satisfying interface. 1040 constructor(children) { 1041 this.children = void 0; 1042 this.classes = void 0; 1043 this.height = void 0; 1044 this.depth = void 0; 1045 this.maxFontSize = void 0; 1046 this.style = void 0; 1047 this.children = children; 1048 this.classes = []; 1049 this.height = 0; 1050 this.depth = 0; 1051 this.maxFontSize = 0; 1052 this.style = {}; 1053 } 1054 1055 hasClass(className) { 1056 return utils.contains(this.classes, className); 1057 }
1058 /** Convert the fragment into a node. */ 1059 1060 1061 toNode() { 1062 var frag = document.createDocumentFragment(); 1063 1064 for (var i = 0; i < this.children.length; i++) { 1065 frag.appendChild(this.children[i].toNode()); 1066 } 1067 1068 return frag; 1069 } 1070 /** Convert the fragment into HTML markup. */ 1071 1072 1073 toMarkup() { 1074 var markup = ""; // Simply concatenate the markup for the children together. 1075 1076 for (var i = 0; i < this.children.length; i++) { 1077 markup += this.children[i].toMarkup(); 1078 } 1079 1080 return markup; 1081 } 1082 /** 1083 * Converts the math node into a string, similar to innerText. Applies to 1084 * MathDomNode's only. 1085 */ 1086 1087 1088 toText() { 1089 // To avoid this, we would subclass documentFragment separately for 1090 // MathML, but polyfills for subclassing is expensive per PR 1469. 1091 // $FlowFixMe: Only works for ChildType = MathDomNode. 1092 var toText = child => child.toText(); 1093 1094 return this.children.map(toText).join(""); 1095 } 1096 1097}
vendor: 16,782 bytes, lines 1097-1487
1097 1098 1099// This file is GENERATED by buildMetrics.sh. DO NOT MODIFY. 1100var fontMetricsData = { 1101 "AMS-Regular": { 1102 "32": [0, 0, 0, 0, 0.25], 1103 "65": [0, 0.68889, 0, 0, 0.72222], 1104 "66": [0, 0.68889, 0, 0, 0.66667], 1105 "67": [0, 0.68889, 0, 0, 0.72222], 1106 "68": [0, 0.68889, 0, 0, 0.72222], 1107 "69": [0, 0.68889, 0, 0, 0.66667], 1108 "70": [0, 0.68889, 0, 0, 0.61111], 1109 "71": [0, 0.68889, 0, 0, 0.77778], 1110 "72": [0, 0.68889, 0, 0, 0.77778], 1111 "73": [0, 0.68889, 0, 0, 0.38889], 1112 "74": [0.16667, 0.68889, 0, 0, 0.5], 1113 "75": [0, 0.68889, 0, 0, 0.77778], 1114 "76": [0, 0.68889, 0, 0, 0.66667], 1115 "77": [0, 0.68889, 0, 0, 0.94445], 1116 "78": [0, 0.68889, 0, 0, 0.72222], 1117 "79": [0.16667, 0.68889, 0, 0, 0.77778], 1118 "80": [0, 0.68889, 0, 0, 0.61111], 1119 "81": [0.16667, 0.68889, 0, 0, 0.77778], 1120 "82": [0, 0.68889, 0, 0, 0.72222], 1121 "83": [0, 0.68889, 0, 0, 0.55556], 1122 "84": [0, 0.68889, 0, 0, 0.66667], 1123 "85": [0, 0.68889, 0, 0, 0.72222], 1124 "86": [0, 0.68889, 0, 0, 0.72222], 1125 "87": [0, 0.68889, 0, 0, 1.0], 1126 "88": [0, 0.68889, 0, 0, 0.72222], 1127 "89": [0, 0.68889, 0, 0, 0.72222], 1128 "90": [0, 0.68889, 0, 0, 0.66667], 1129 "107": [0, 0.68889, 0, 0, 0.55556], 1130 "160": [0, 0, 0, 0, 0.25], 1131 "165": [0, 0.675, 0.025, 0, 0.75], 1132 "174": [0.15559, 0.69224, 0, 0, 0.94666], 1133 "240": [0, 0.68889, 0, 0, 0.55556], 1134 "295": [0, 0.68889, 0, 0, 0.54028], 1135 "710": [0, 0.825, 0, 0, 2.33334], 1136 "732": [0, 0.9, 0, 0, 2.33334], 1137 "770": [0, 0.825, 0, 0, 2.33334], 1138 "771": [0, 0.9, 0, 0, 2.33334], 1139 "989": [0.08167, 0.58167, 0, 0, 0.77778], 1140 "1008": [0, 0.43056, 0.04028, 0, 0.66667], 1141 "8245": [0, 0.54986, 0, 0, 0.275], 1142 "8463": [0, 0.68889, 0, 0, 0.54028], 1143 "8487": [0, 0.68889, 0, 0, 0.72222], 1144 "8498": [0, 0.68889, 0, 0, 0.55556], 1145 "8502": [0, 0.68889, 0, 0, 0.66667], 1146 "8503": [0, 0.68889, 0, 0, 0.44445], 1147 "8504": [0, 0.68889, 0, 0, 0.66667], 1148 "8513": [0, 0.68889, 0, 0, 0.63889], 1149 "8592": [-0.03598, 0.46402, 0, 0, 0.5], 1150 "8594": [-0.03598, 0.46402, 0, 0, 0.5], 1151 "8602": [-0.13313, 0.36687, 0, 0, 1.0], 1152 "8603": [-0.13313, 0.36687, 0, 0, 1.0], 1153 "8606": [0.01354, 0.52239, 0, 0, 1.0], 1154 "8608": [0.01354, 0.52239, 0, 0, 1.0], 1155 "8610": [0.01354, 0.52239, 0, 0, 1.11111], 1156 "8611": [0.01354, 0.52239, 0, 0, 1.11111], 1157 "8619": [0, 0.54986, 0, 0, 1.0], 1158 "8620": [0, 0.54986, 0, 0, 1.0], 1159 "8621": [-0.13313, 0.37788, 0, 0, 1.38889], 1160 "8622": [-0.13313, 0.36687, 0, 0, 1.0], 1161 "8624": [0, 0.69224, 0, 0, 0.5], 1162 "8625": [0, 0.69224, 0, 0, 0.5], 1163 "8630": [0, 0.43056, 0, 0, 1.0], 1164 "8631": [0, 0.43056, 0, 0, 1.0], 1165 "8634": [0.08198, 0.58198, 0, 0, 0.77778], 1166 "8635": [0.08198, 0.58198, 0, 0, 0.77778], 1167 "8638": [0.19444, 0.69224, 0, 0, 0.41667], 1168 "8639": [0.19444, 0.69224, 0, 0, 0.41667], 1169 "8642": [0.19444, 0.69224, 0, 0, 0.41667], 1170 "8643": [0.19444, 0.69224, 0, 0, 0.41667], 1171 "8644": [0.1808, 0.675, 0, 0, 1.0], 1172 "8646": [0.1808, 0.675, 0, 0, 1.0], 1173 "8647": [0.1808, 0.675, 0, 0, 1.0], 1174 "8648": [0.19444, 0.69224, 0, 0, 0.83334], 1175 "8649": [0.1808, 0.675, 0, 0, 1.0], 1176 "8650": [0.19444, 0.69224, 0, 0, 0.83334], 1177 "8651": [0.01354, 0.52239, 0, 0, 1.0], 1178 "8652": [0.01354, 0.52239, 0, 0, 1.0], 1179 "8653": [-0.13313, 0.36687, 0, 0, 1.0], 1180 "8654": [-0.13313, 0.36687, 0, 0, 1.0], 1181 "8655": [-0.13313, 0.36687, 0, 0, 1.0], 1182 "8666": [0.13667, 0.63667, 0, 0, 1.0], 1183 "8667": [0.13667, 0.63667, 0, 0, 1.0], 1184 "8669": [-0.13313, 0.37788, 0, 0, 1.0], 1185 "8672": [-0.064, 0.437, 0, 0, 1.334], 1186 "8674": [-0.064, 0.437, 0, 0, 1.334], 1187 "8705": [0, 0.825, 0, 0, 0.5], 1188 "8708": [0, 0.68889, 0, 0, 0.55556], 1189 "8709": [0.08167, 0.58167, 0, 0, 0.77778], 1190 "8717": [0, 0.43056, 0, 0, 0.42917], 1191 "8722": [-0.03598, 0.46402, 0, 0, 0.5], 1192 "8724": [0.08198, 0.69224, 0, 0, 0.77778], 1193 "8726": [0.08167, 0.58167, 0, 0, 0.77778], 1194 "8733": [0, 0.69224, 0, 0, 0.77778], 1195 "8736": [0, 0.69224, 0, 0, 0.72222], 1196 "8737": [0, 0.69224, 0, 0, 0.72222], 1197 "8738": [0.03517, 0.52239, 0, 0, 0.72222], 1198 "8739": [0.08167, 0.58167, 0, 0, 0.22222], 1199 "8740": [0.25142, 0.74111, 0, 0, 0.27778], 1200 "8741": [0.08167, 0.58167, 0, 0, 0.38889], 1201 "8742": [0.25142, 0.74111, 0, 0, 0.5], 1202 "8756": [0, 0.69224, 0, 0, 0.66667], 1203 "8757": [0, 0.69224, 0, 0, 0.66667], 1204 "8764": [-0.13313, 0.36687, 0, 0, 0.77778], 1205 "8765": [-0.13313, 0.37788, 0, 0, 0.77778], 1206 "8769": [-0.13313, 0.36687, 0, 0, 0.77778], 1207 "8770": [-0.03625, 0.46375, 0, 0, 0.77778], 1208 "8774": [0.30274, 0.79383, 0, 0, 0.77778], 1209 "8776": [-0.01688, 0.48312, 0, 0, 0.77778], 1210 "8778": [0.08167, 0.58167, 0, 0, 0.77778], 1211 "8782": [0.06062, 0.54986, 0, 0, 0.77778], 1212 "8783": [0.06062, 0.54986, 0, 0, 0.77778], 1213 "8785": [0.08198, 0.58198, 0, 0, 0.77778], 1214 "8786": [0.08198, 0.58198, 0, 0, 0.77778], 1215 "8787": [0.08198, 0.58198, 0, 0, 0.77778], 1216 "8790": [0, 0.69224, 0, 0, 0.77778], 1217 "8791": [0.22958, 0.72958, 0, 0, 0.77778], 1218 "8796": [0.08198, 0.91667, 0, 0, 0.77778], 1219 "8806": [0.25583, 0.75583, 0, 0, 0.77778], 1220 "8807": [0.25583, 0.75583, 0, 0, 0.77778], 1221 "8808": [0.25142, 0.75726, 0, 0, 0.77778], 1222 "8809": [0.25142, 0.75726, 0, 0, 0.77778], 1223 "8812": [0.25583, 0.75583, 0, 0, 0.5], 1224 "8814": [0.20576, 0.70576, 0, 0, 0.77778], 1225 "8815": [0.20576, 0.70576, 0, 0, 0.77778], 1226 "8816": [0.30274, 0.79383, 0, 0, 0.77778], 1227 "8817": [0.30274, 0.79383, 0, 0, 0.77778], 1228 "8818": [0.22958, 0.72958, 0, 0, 0.77778], 1229 "8819": [0.22958, 0.72958, 0, 0, 0.77778], 1230 "8822": [0.1808, 0.675, 0, 0, 0.77778], 1231 "8823": [0.1808, 0.675, 0, 0, 0.77778], 1232 "8828": [0.13667, 0.63667, 0, 0, 0.77778], 1233 "8829": [0.13667, 0.63667, 0, 0, 0.77778], 1234 "8830": [0.22958, 0.72958, 0, 0, 0.77778], 1235 "8831": [0.22958, 0.72958, 0, 0, 0.77778], 1236 "8832": [0.20576, 0.70576, 0, 0, 0.77778], 1237 "8833": [0.20576, 0.70576, 0, 0, 0.77778], 1238 "8840": [0.30274, 0.79383, 0, 0, 0.77778], 1239 "8841": [0.30274, 0.79383, 0, 0, 0.77778], 1240 "8842": [0.13597, 0.63597, 0, 0, 0.77778], 1241 "8843": [0.13597, 0.63597, 0, 0, 0.77778], 1242 "8847": [0.03517, 0.54986, 0, 0, 0.77778], 1243 "8848": [0.03517, 0.54986, 0, 0, 0.77778], 1244 "8858": [0.08198, 0.58198, 0, 0, 0.77778], 1245 "8859": [0.08198, 0.58198, 0, 0, 0.77778], 1246 "8861": [0.08198, 0.58198, 0, 0, 0.77778], 1247 "8862": [0, 0.675, 0, 0, 0.77778], 1248 "8863": [0, 0.675, 0, 0, 0.77778], 1249 "8864": [0, 0.675, 0, 0, 0.77778], 1250 "8865": [0, 0.675, 0, 0, 0.77778], 1251 "8872": [0, 0.69224, 0, 0, 0.61111], 1252 "8873": [0, 0.69224, 0, 0, 0.72222], 1253 "8874": [0, 0.69224, 0, 0, 0.88889], 1254 "8876": [0, 0.68889, 0, 0, 0.61111], 1255 "8877": [0, 0.68889, 0, 0, 0.61111], 1256 "8878": [0, 0.68889, 0, 0, 0.72222], 1257 "8879": [0, 0.68889, 0, 0, 0.72222], 1258 "8882": [0.03517, 0.54986, 0, 0, 0.77778], 1259 "8883": [0.03517, 0.54986, 0, 0, 0.77778], 1260 "8884": [0.13667, 0.63667, 0, 0, 0.77778], 1261 "8885": [0.13667, 0.63667, 0, 0, 0.77778], 1262 "8888": [0, 0.54986, 0, 0, 1.11111], 1263 "8890": [0.19444, 0.43056, 0, 0, 0.55556], 1264 "8891": [0.19444, 0.69224, 0, 0, 0.61111], 1265 "8892": [0.19444, 0.69224, 0, 0, 0.61111], 1266 "8901": [0, 0.54986, 0, 0, 0.27778], 1267 "8903": [0.08167, 0.58167, 0, 0, 0.77778], 1268 "8905": [0.08167, 0.58167, 0, 0, 0.77778], 1269 "8906": [0.08167, 0.58167, 0, 0, 0.77778], 1270 "8907": [0, 0.69224, 0, 0, 0.77778], 1271 "8908": [0, 0.69224, 0, 0, 0.77778], 1272 "8909": [-0.03598, 0.46402, 0, 0, 0.77778], 1273 "8910": [0, 0.54986, 0, 0, 0.76042], 1274 "8911": [0, 0.54986, 0, 0, 0.76042], 1275 "8912": [0.03517, 0.54986, 0, 0, 0.77778], 1276 "8913": [0.03517, 0.54986, 0, 0, 0.77778], 1277 "8914": [0, 0.54986, 0, 0, 0.66667], 1278 "8915": [0, 0.54986, 0, 0, 0.66667], 1279 "8916": [0, 0.69224, 0, 0, 0.66667], 1280 "8918": [0.0391, 0.5391, 0, 0, 0.77778], 1281 "8919": [0.0391, 0.5391, 0, 0, 0.77778], 1282 "8920": [0.03517, 0.54986, 0, 0, 1.33334], 1283 "8921": [0.03517, 0.54986, 0, 0, 1.33334], 1284 "8922": [0.38569, 0.88569, 0, 0, 0.77778], 1285 "8923": [0.38569, 0.88569, 0, 0, 0.77778], 1286 "8926": [0.13667, 0.63667, 0, 0, 0.77778], 1287 "8927": [0.13667, 0.63667, 0, 0, 0.77778], 1288 "8928": [0.30274, 0.79383, 0, 0, 0.77778], 1289 "8929": [0.30274, 0.79383, 0, 0, 0.77778], 1290 "8934": [0.23222, 0.74111, 0, 0, 0.77778], 1291 "8935": [0.23222, 0.74111, 0, 0, 0.77778], 1292 "8936": [0.23222, 0.74111, 0, 0, 0.77778], 1293 "8937": [0.23222, 0.74111, 0, 0, 0.77778], 1294 "8938": [0.20576, 0.70576, 0, 0, 0.77778], 1295 "8939": [0.20576, 0.70576, 0, 0, 0.77778], 1296 "8940": [0.30274, 0.79383, 0, 0, 0.77778], 1297 "8941": [0.30274, 0.79383, 0, 0, 0.77778], 1298 "8994": [0.19444, 0.69224, 0, 0, 0.77778], 1299 "8995": [0.19444, 0.69224, 0, 0, 0.77778], 1300 "9416": [0.15559, 0.69224, 0, 0, 0.90222], 1301 "9484": [0, 0.69224, 0, 0, 0.5], 1302 "9488": [0, 0.69224, 0, 0, 0.5], 1303 "9492": [0, 0.37788, 0, 0, 0.5], 1304 "9496": [0, 0.37788, 0, 0, 0.5], 1305 "9585": [0.19444, 0.68889, 0, 0, 0.88889], 1306 "9586": [0.19444, 0.74111, 0, 0, 0.88889], 1307 "9632": [0, 0.675, 0, 0, 0.77778], 1308 "9633": [0, 0.675, 0, 0, 0.77778], 1309 "9650": [0, 0.54986, 0, 0, 0.72222], 1310 "9651": [0, 0.54986, 0, 0, 0.72222], 1311 "9654": [0.03517, 0.54986, 0, 0, 0.77778], 1312 "9660": [0, 0.54986, 0, 0, 0.72222], 1313 "9661": [0, 0.54986, 0, 0, 0.72222], 1314 "9664": [0.03517, 0.54986, 0, 0, 0.77778], 1315 "9674": [0.11111, 0.69224, 0, 0, 0.66667], 1316 "9733": [0.19444, 0.69224, 0, 0, 0.94445], 1317 "10003": [0, 0.69224, 0, 0, 0.83334], 1318 "10016": [0, 0.69224, 0, 0, 0.83334], 1319 "10731": [0.11111, 0.69224, 0, 0, 0.66667], 1320 "10846": [0.19444, 0.75583, 0, 0, 0.61111], 1321 "10877": [0.13667, 0.63667, 0, 0, 0.77778], 1322 "10878": [0.13667, 0.63667, 0, 0, 0.77778], 1323 "10885": [0.25583, 0.75583, 0, 0, 0.77778], 1324 "10886": [0.25583, 0.75583, 0, 0, 0.77778], 1325 "10887": [0.13597, 0.63597, 0, 0, 0.77778], 1326 "10888": [0.13597, 0.63597, 0, 0, 0.77778], 1327 "10889": [0.26167, 0.75726, 0, 0, 0.77778], 1328 "10890": [0.26167, 0.75726, 0, 0, 0.77778], 1329 "10891": [0.48256, 0.98256, 0, 0, 0.77778], 1330 "10892": [0.48256, 0.98256, 0, 0, 0.77778], 1331 "10901": [0.13667, 0.63667, 0, 0, 0.77778], 1332 "10902": [0.13667, 0.63667, 0, 0, 0.77778], 1333 "10933": [0.25142, 0.75726, 0, 0, 0.77778], 1334 "10934": [0.25142, 0.75726, 0, 0, 0.77778], 1335 "10935": [0.26167, 0.75726, 0, 0, 0.77778], 1336 "10936": [0.26167, 0.75726, 0, 0, 0.77778], 1337 "10937": [0.26167, 0.75726, 0, 0, 0.77778], 1338 "10938": [0.26167, 0.75726, 0, 0, 0.77778], 1339 "10949": [0.25583, 0.75583, 0, 0, 0.77778], 1340 "10950": [0.25583, 0.75583, 0, 0, 0.77778], 1341 "10955": [0.28481, 0.79383, 0, 0, 0.77778], 1342 "10956": [0.28481, 0.79383, 0, 0, 0.77778], 1343 "57350": [0.08167, 0.58167, 0, 0, 0.22222], 1344 "57351": [0.08167, 0.58167, 0, 0, 0.38889], 1345 "57352": [0.08167, 0.58167, 0, 0, 0.77778], 1346 "57353": [0, 0.43056, 0.04028, 0, 0.66667], 1347 "57356": [0.25142, 0.75726, 0, 0, 0.77778], 1348 "57357": [0.25142, 0.75726, 0, 0, 0.77778], 1349 "57358": [0.41951, 0.91951, 0, 0, 0.77778], 1350 "57359": [0.30274, 0.79383, 0, 0, 0.77778], 1351 "57360": [0.30274, 0.79383, 0, 0, 0.77778], 1352 "57361": [0.41951, 0.91951, 0, 0, 0.77778], 1353 "57366": [0.25142, 0.75726, 0, 0, 0.77778], 1354 "57367": [0.25142, 0.75726, 0, 0, 0.77778], 1355 "57368": [0.25142, 0.75726, 0, 0, 0.77778], 1356 "57369": [0.25142, 0.75726, 0, 0, 0.77778], 1357 "57370": [0.13597, 0.63597, 0, 0, 0.77778], 1358 "57371": [0.13597, 0.63597, 0, 0, 0.77778] 1359 }, 1360 "Caligraphic-Regular": { 1361 "32": [0, 0, 0, 0, 0.25], 1362 "65": [0, 0.68333, 0, 0.19445, 0.79847], 1363 "66": [0, 0.68333, 0.03041, 0.13889, 0.65681], 1364 "67": [0, 0.68333, 0.05834, 0.13889, 0.52653], 1365 "68": [0, 0.68333, 0.02778, 0.08334, 0.77139], 1366 "69": [0, 0.68333, 0.08944, 0.11111, 0.52778], 1367 "70": [0, 0.68333, 0.09931, 0.11111, 0.71875], 1368 "71": [0.09722, 0.68333, 0.0593, 0.11111, 0.59487], 1369 "72": [0, 0.68333, 0.00965, 0.11111, 0.84452], 1370 "73": [0, 0.68333, 0.07382, 0, 0.54452], 1371 "74": [0.09722, 0.68333, 0.18472, 0.16667, 0.67778], 1372 "75": [0, 0.68333, 0.01445, 0.05556, 0.76195], 1373 "76": [0, 0.68333, 0, 0.13889, 0.68972], 1374 "77": [0, 0.68333, 0, 0.13889, 1.2009], 1375 "78": [0, 0.68333, 0.14736, 0.08334, 0.82049], 1376 "79": [0, 0.68333, 0.02778, 0.11111, 0.79611], 1377 "80": [0, 0.68333, 0.08222, 0.08334, 0.69556], 1378 "81": [0.09722, 0.68333, 0, 0.11111, 0.81667], 1379 "82": [0, 0.68333, 0, 0.08334, 0.8475], 1380 "83": [0, 0.68333, 0.075, 0.13889, 0.60556], 1381 "84": [0, 0.68333, 0.25417, 0, 0.54464], 1382 "85": [0, 0.68333, 0.09931, 0.08334, 0.62583], 1383 "86": [0, 0.68333, 0.08222, 0, 0.61278], 1384 "87": [0, 0.68333, 0.08222, 0.08334, 0.98778], 1385 "88": [0, 0.68333, 0.14643, 0.13889, 0.7133], 1386 "89": [0.09722, 0.68333, 0.08222, 0.08334, 0.66834], 1387 "90": [0, 0.68333, 0.07944, 0.13889, 0.72473], 1388 "160": [0, 0, 0, 0, 0.25] 1389 }, 1390 "Fraktur-Regular": { 1391 "32": [0, 0, 0, 0, 0.25], 1392 "33": [0, 0.69141, 0, 0, 0.29574], 1393 "34": [0, 0.69141, 0, 0, 0.21471], 1394 "38": [0, 0.69141, 0, 0, 0.73786], 1395 "39": [0, 0.69141, 0, 0, 0.21201], 1396 "40": [0.24982, 0.74947, 0, 0, 0.38865], 1397 "41": [0.24982, 0.74947, 0, 0, 0.38865], 1398 "42": [0, 0.62119, 0, 0, 0.27764], 1399 "43": [0.08319, 0.58283, 0, 0, 0.75623], 1400 "44": [0, 0.10803, 0, 0, 0.27764], 1401 "45": [0.08319, 0.58283, 0, 0, 0.75623], 1402 "46": [0, 0.10803, 0, 0, 0.27764], 1403 "47": [0.24982, 0.74947, 0, 0, 0.50181], 1404 "48": [0, 0.47534, 0, 0, 0.50181], 1405 "49": [0, 0.47534, 0, 0, 0.50181], 1406 "50": [0, 0.47534, 0, 0, 0.50181], 1407 "51": [0.18906, 0.47534, 0, 0, 0.50181], 1408 "52": [0.18906, 0.47534, 0, 0, 0.50181], 1409 "53": [0.18906, 0.47534, 0, 0, 0.50181], 1410 "54": [0, 0.69141, 0, 0, 0.50181], 1411 "55": [0.18906, 0.47534, 0, 0, 0.50181], 1412 "56": [0, 0.69141, 0, 0, 0.50181], 1413 "57": [0.18906, 0.47534, 0, 0, 0.50181], 1414 "58": [0, 0.47534, 0, 0, 0.21606], 1415 "59": [0.12604, 0.47534, 0, 0, 0.21606], 1416 "61": [-0.13099, 0.36866, 0, 0, 0.75623], 1417 "63": [0, 0.69141, 0, 0, 0.36245], 1418 "65": [0, 0.69141, 0, 0, 0.7176], 1419 "66": [0, 0.69141, 0, 0, 0.88397], 1420 "67": [0, 0.69141, 0, 0, 0.61254], 1421 "68": [0, 0.69141, 0, 0, 0.83158], 1422 "69": [0, 0.69141, 0, 0, 0.66278], 1423 "70": [0.12604, 0.69141, 0, 0, 0.61119], 1424 "71": [0, 0.69141, 0, 0, 0.78539], 1425 "72": [0.06302, 0.69141, 0, 0, 0.7203], 1426 "73": [0, 0.69141, 0, 0, 0.55448], 1427 "74": [0.12604, 0.69141, 0, 0, 0.55231], 1428 "75": [0, 0.69141, 0, 0, 0.66845], 1429 "76": [0, 0.69141, 0, 0, 0.66602], 1430 "77": [0, 0.69141, 0, 0, 1.04953], 1431 "78": [0, 0.69141, 0, 0, 0.83212], 1432 "79": [0, 0.69141, 0, 0, 0.82699], 1433 "80": [0.18906, 0.69141, 0, 0, 0.82753], 1434 "81": [0.03781, 0.69141, 0, 0, 0.82699], 1435 "82": [0, 0.69141, 0, 0, 0.82807], 1436 "83": [0, 0.69141, 0, 0, 0.82861], 1437 "84": [0, 0.69141, 0, 0, 0.66899], 1438 "85": [0, 0.69141, 0, 0, 0.64576], 1439 "86": [0, 0.69141, 0, 0, 0.83131], 1440 "87": [0, 0.69141, 0, 0, 1.04602], 1441 "88": [0, 0.69141, 0, 0, 0.71922], 1442 "89": [0.18906, 0.69141, 0, 0, 0.83293], 1443 "90": [0.12604, 0.69141, 0, 0, 0.60201], 1444 "91": [0.24982, 0.74947, 0, 0, 0.27764], 1445 "93": [0.24982, 0.74947, 0, 0, 0.27764], 1446 "94": [0, 0.69141, 0, 0, 0.49965], 1447 "97": [0, 0.47534, 0, 0, 0.50046], 1448 "98": [0, 0.69141, 0, 0, 0.51315], 1449 "99": [0, 0.47534, 0, 0, 0.38946], 1450 "100": [0, 0.62119, 0, 0, 0.49857], 1451 "101": [0, 0.47534, 0, 0, 0.40053], 1452 "102": [0.18906, 0.69141, 0, 0, 0.32626], 1453 "103": [0.18906, 0.47534, 0, 0, 0.5037], 1454 "104": [0.18906, 0.69141, 0, 0, 0.52126], 1455 "105": [0, 0.69141, 0, 0, 0.27899], 1456 "106": [0, 0.69141, 0, 0, 0.28088], 1457 "107": [0, 0.69141, 0, 0, 0.38946], 1458 "108": [0, 0.69141, 0, 0, 0.27953], 1459 "109": [0, 0.47534, 0, 0, 0.76676], 1460 "110": [0, 0.47534, 0, 0, 0.52666], 1461 "111": [0, 0.47534, 0, 0, 0.48885], 1462 "112": [0.18906, 0.52396, 0, 0, 0.50046], 1463 "113": [0.18906, 0.47534, 0, 0, 0.48912], 1464 "114": [0, 0.47534, 0, 0, 0.38919], 1465 "115": [0, 0.47534, 0, 0, 0.44266], 1466 "116": [0, 0.62119, 0, 0, 0.33301], 1467 "117": [0, 0.47534, 0, 0, 0.5172], 1468 "118": [0, 0.52396, 0, 0, 0.5118], 1469 "119": [0, 0.52396, 0, 0, 0.77351], 1470 "120": [0.18906, 0.47534, 0, 0, 0.38865], 1471 "121": [0.18906, 0.47534, 0, 0, 0.49884], 1472 "122": [0.18906, 0.47534, 0, 0, 0.39054], 1473 "160": [0, 0, 0, 0, 0.25], 1474 "8216": [0, 0.69141, 0, 0, 0.21471], 1475 "8217": [0, 0.69141, 0, 0, 0.21471], 1476 "58112": [0, 0.62119, 0, 0, 0.49749], 1477 "58113": [0, 0.62119, 0, 0, 0.4983], 1478 "58114": [0.18906, 0.69141, 0, 0, 0.33328], 1479 "58115": [0.18906, 0.69141, 0, 0, 0.32923], 1480 "58116": [0.18906, 0.47534, 0, 0, 0.50343], 1481 "58117": [0, 0.69141, 0, 0, 0.33301], 1482 "58118": [0, 0.62119, 0, 0, 0.33409], 1483 "58119": [0, 0.47534, 0, 0, 0.50073] 1484 }, 1485 "Main-Bold": { 1486 "32": [0, 0, 0, 0, 0.25], 1487 "33": [0, 0.69444, 0, 0, 0.35],
vendor: 2,406 bytes, lines 1488-1548
1488 "34": [0, 0.69444, 0, 0, 0.60278], 1489 "35": [0.19444, 0.69444, 0, 0, 0.95833], 1490 "36": [0.05556, 0.75, 0, 0, 0.575], 1491 "37": [0.05556, 0.75, 0, 0, 0.95833], 1492 "38": [0, 0.69444, 0, 0, 0.89444], 1493 "39": [0, 0.69444, 0, 0, 0.31944], 1494 "40": [0.25, 0.75, 0, 0, 0.44722], 1495 "41": [0.25, 0.75, 0, 0, 0.44722], 1496 "42": [0, 0.75, 0, 0, 0.575], 1497 "43": [0.13333, 0.63333, 0, 0, 0.89444], 1498 "44": [0.19444, 0.15556, 0, 0, 0.31944], 1499 "45": [0, 0.44444, 0, 0, 0.38333], 1500 "46": [0, 0.15556, 0, 0, 0.31944], 1501 "47": [0.25, 0.75, 0, 0, 0.575], 1502 "48": [0, 0.64444, 0, 0, 0.575], 1503 "49": [0, 0.64444, 0, 0, 0.575], 1504 "50": [0, 0.64444, 0, 0, 0.575], 1505 "51": [0, 0.64444, 0, 0, 0.575], 1506 "52": [0, 0.64444, 0, 0, 0.575], 1507 "53": [0, 0.64444, 0, 0, 0.575], 1508 "54": [0, 0.64444, 0, 0, 0.575], 1509 "55": [0, 0.64444, 0, 0, 0.575], 1510 "56": [0, 0.64444, 0, 0, 0.575], 1511 "57": [0, 0.64444, 0, 0, 0.575], 1512 "58": [0, 0.44444, 0, 0, 0.31944], 1513 "59": [0.19444, 0.44444, 0, 0, 0.31944], 1514 "60": [0.08556, 0.58556, 0, 0, 0.89444], 1515 "61": [-0.10889, 0.39111, 0, 0, 0.89444], 1516 "62": [0.08556, 0.58556, 0, 0, 0.89444], 1517 "63": [0, 0.69444, 0, 0, 0.54305], 1518 "64": [0, 0.69444, 0, 0, 0.89444], 1519 "65": [0, 0.68611, 0, 0, 0.86944], 1520 "66": [0, 0.68611, 0, 0, 0.81805], 1521 "67": [0, 0.68611, 0, 0, 0.83055], 1522 "68": [0, 0.68611, 0, 0, 0.88194], 1523 "69": [0, 0.68611, 0, 0, 0.75555], 1524 "70": [0, 0.68611, 0, 0, 0.72361], 1525 "71": [0, 0.68611, 0, 0, 0.90416], 1526 "72": [0, 0.68611, 0, 0, 0.9], 1527 "73": [0, 0.68611, 0, 0, 0.43611], 1528 "74": [0, 0.68611, 0, 0, 0.59444], 1529 "75": [0, 0.68611, 0, 0, 0.90138], 1530 "76": [0, 0.68611, 0, 0, 0.69166], 1531 "77": [0, 0.68611, 0, 0, 1.09166], 1532 "78": [0, 0.68611, 0, 0, 0.9], 1533 "79": [0, 0.68611, 0, 0, 0.86388], 1534 "80": [0, 0.68611, 0, 0, 0.78611], 1535 "81": [0.19444, 0.68611, 0, 0, 0.86388], 1536 "82": [0, 0.68611, 0, 0, 0.8625], 1537 "83": [0, 0.68611, 0, 0, 0.63889], 1538 "84": [0, 0.68611, 0, 0, 0.8], 1539 "85": [0, 0.68611, 0, 0, 0.88472], 1540 "86": [0, 0.68611, 0.01597, 0, 0.86944], 1541 "87": [0, 0.68611, 0.01597, 0, 1.18888], 1542 "88": [0, 0.68611, 0, 0, 0.86944], 1543 "89": [0, 0.68611, 0.02875, 0, 0.86944], 1544 "90": [0, 0.68611, 0, 0, 0.70277], 1545 "91": [0.25, 0.75, 0, 0, 0.31944], 1546 "92": [0.25, 0.75, 0, 0, 0.575], 1547 "93": [0.25, 0.75, 0, 0, 0.31944], 1548 "94": [0, 0.69444, 0, 0, 0.575],
vendor: 8,281 bytes, lines 1549-1741
1549 "95": [0.31, 0.13444, 0.03194, 0, 0.575], 1550 "97": [0, 0.44444, 0, 0, 0.55902], 1551 "98": [0, 0.69444, 0, 0, 0.63889], 1552 "99": [0, 0.44444, 0, 0, 0.51111], 1553 "100": [0, 0.69444, 0, 0, 0.63889], 1554 "101": [0, 0.44444, 0, 0, 0.52708], 1555 "102": [0, 0.69444, 0.10903, 0, 0.35139], 1556 "103": [0.19444, 0.44444, 0.01597, 0, 0.575], 1557 "104": [0, 0.69444, 0, 0, 0.63889], 1558 "105": [0, 0.69444, 0, 0, 0.31944], 1559 "106": [0.19444, 0.69444, 0, 0, 0.35139], 1560 "107": [0, 0.69444, 0, 0, 0.60694], 1561 "108": [0, 0.69444, 0, 0, 0.31944], 1562 "109": [0, 0.44444, 0, 0, 0.95833], 1563 "110": [0, 0.44444, 0, 0, 0.63889], 1564 "111": [0, 0.44444, 0, 0, 0.575], 1565 "112": [0.19444, 0.44444, 0, 0, 0.63889], 1566 "113": [0.19444, 0.44444, 0, 0, 0.60694], 1567 "114": [0, 0.44444, 0, 0, 0.47361], 1568 "115": [0, 0.44444, 0, 0, 0.45361], 1569 "116": [0, 0.63492, 0, 0, 0.44722], 1570 "117": [0, 0.44444, 0, 0, 0.63889], 1571 "118": [0, 0.44444, 0.01597, 0, 0.60694], 1572 "119": [0, 0.44444, 0.01597, 0, 0.83055], 1573 "120": [0, 0.44444, 0, 0, 0.60694], 1574 "121": [0.19444, 0.44444, 0.01597, 0, 0.60694], 1575 "122": [0, 0.44444, 0, 0, 0.51111], 1576 "123": [0.25, 0.75, 0, 0, 0.575], 1577 "124": [0.25, 0.75, 0, 0, 0.31944], 1578 "125": [0.25, 0.75, 0, 0, 0.575], 1579 "126": [0.35, 0.34444, 0, 0, 0.575], 1580 "160": [0, 0, 0, 0, 0.25], 1581 "163": [0, 0.69444, 0, 0, 0.86853], 1582 "168": [0, 0.69444, 0, 0, 0.575], 1583 "172": [0, 0.44444, 0, 0, 0.76666], 1584 "176": [0, 0.69444, 0, 0, 0.86944], 1585 "177": [0.13333, 0.63333, 0, 0, 0.89444], 1586 "184": [0.17014, 0, 0, 0, 0.51111], 1587 "198": [0, 0.68611, 0, 0, 1.04166], 1588 "215": [0.13333, 0.63333, 0, 0, 0.89444], 1589 "216": [0.04861, 0.73472, 0, 0, 0.89444], 1590 "223": [0, 0.69444, 0, 0, 0.59722], 1591 "230": [0, 0.44444, 0, 0, 0.83055], 1592 "247": [0.13333, 0.63333, 0, 0, 0.89444], 1593 "248": [0.09722, 0.54167, 0, 0, 0.575], 1594 "305": [0, 0.44444, 0, 0, 0.31944], 1595 "338": [0, 0.68611, 0, 0, 1.16944], 1596 "339": [0, 0.44444, 0, 0, 0.89444], 1597 "567": [0.19444, 0.44444, 0, 0, 0.35139], 1598 "710": [0, 0.69444, 0, 0, 0.575], 1599 "711": [0, 0.63194, 0, 0, 0.575], 1600 "713": [0, 0.59611, 0, 0, 0.575], 1601 "714": [0, 0.69444, 0, 0, 0.575], 1602 "715": [0, 0.69444, 0, 0, 0.575], 1603 "728": [0, 0.69444, 0, 0, 0.575], 1604 "729": [0, 0.69444, 0, 0, 0.31944], 1605 "730": [0, 0.69444, 0, 0, 0.86944], 1606 "732": [0, 0.69444, 0, 0, 0.575], 1607 "733": [0, 0.69444, 0, 0, 0.575], 1608 "915": [0, 0.68611, 0, 0, 0.69166], 1609 "916": [0, 0.68611, 0, 0, 0.95833], 1610 "920": [0, 0.68611, 0, 0, 0.89444], 1611 "923": [0, 0.68611, 0, 0, 0.80555], 1612 "926": [0, 0.68611, 0, 0, 0.76666], 1613 "928": [0, 0.68611, 0, 0, 0.9], 1614 "931": [0, 0.68611, 0, 0, 0.83055], 1615 "933": [0, 0.68611, 0, 0, 0.89444], 1616 "934": [0, 0.68611, 0, 0, 0.83055], 1617 "936": [0, 0.68611, 0, 0, 0.89444], 1618 "937": [0, 0.68611, 0, 0, 0.83055], 1619 "8211": [0, 0.44444, 0.03194, 0, 0.575], 1620 "8212": [0, 0.44444, 0.03194, 0, 1.14999], 1621 "8216": [0, 0.69444, 0, 0, 0.31944], 1622 "8217": [0, 0.69444, 0, 0, 0.31944], 1623 "8220": [0, 0.69444, 0, 0, 0.60278], 1624 "8221": [0, 0.69444, 0, 0, 0.60278], 1625 "8224": [0.19444, 0.69444, 0, 0, 0.51111], 1626 "8225": [0.19444, 0.69444, 0, 0, 0.51111], 1627 "8242": [0, 0.55556, 0, 0, 0.34444], 1628 "8407": [0, 0.72444, 0.15486, 0, 0.575], 1629 "8463": [0, 0.69444, 0, 0, 0.66759], 1630 "8465": [0, 0.69444, 0, 0, 0.83055], 1631 "8467": [0, 0.69444, 0, 0, 0.47361], 1632 "8472": [0.19444, 0.44444, 0, 0, 0.74027], 1633 "8476": [0, 0.69444, 0, 0, 0.83055], 1634 "8501": [0, 0.69444, 0, 0, 0.70277], 1635 "8592": [-0.10889, 0.39111, 0, 0, 1.14999], 1636 "8593": [0.19444, 0.69444, 0, 0, 0.575], 1637 "8594": [-0.10889, 0.39111, 0, 0, 1.14999], 1638 "8595": [0.19444, 0.69444, 0, 0, 0.575], 1639 "8596": [-0.10889, 0.39111, 0, 0, 1.14999], 1640 "8597": [0.25, 0.75, 0, 0, 0.575], 1641 "8598": [0.19444, 0.69444, 0, 0, 1.14999], 1642 "8599": [0.19444, 0.69444, 0, 0, 1.14999], 1643 "8600": [0.19444, 0.69444, 0, 0, 1.14999], 1644 "8601": [0.19444, 0.69444, 0, 0, 1.14999], 1645 "8636": [-0.10889, 0.39111, 0, 0, 1.14999], 1646 "8637": [-0.10889, 0.39111, 0, 0, 1.14999], 1647 "8640": [-0.10889, 0.39111, 0, 0, 1.14999], 1648 "8641": [-0.10889, 0.39111, 0, 0, 1.14999], 1649 "8656": [-0.10889, 0.39111, 0, 0, 1.14999], 1650 "8657": [0.19444, 0.69444, 0, 0, 0.70277], 1651 "8658": [-0.10889, 0.39111, 0, 0, 1.14999], 1652 "8659": [0.19444, 0.69444, 0, 0, 0.70277], 1653 "8660": [-0.10889, 0.39111, 0, 0, 1.14999], 1654 "8661": [0.25, 0.75, 0, 0, 0.70277], 1655 "8704": [0, 0.69444, 0, 0, 0.63889], 1656 "8706": [0, 0.69444, 0.06389, 0, 0.62847], 1657 "8707": [0, 0.69444, 0, 0, 0.63889], 1658 "8709": [0.05556, 0.75, 0, 0, 0.575], 1659 "8711": [0, 0.68611, 0, 0, 0.95833], 1660 "8712": [0.08556, 0.58556, 0, 0, 0.76666], 1661 "8715": [0.08556, 0.58556, 0, 0, 0.76666], 1662 "8722": [0.13333, 0.63333, 0, 0, 0.89444], 1663 "8723": [0.13333, 0.63333, 0, 0, 0.89444], 1664 "8725": [0.25, 0.75, 0, 0, 0.575], 1665 "8726": [0.25, 0.75, 0, 0, 0.575], 1666 "8727": [-0.02778, 0.47222, 0, 0, 0.575], 1667 "8728": [-0.02639, 0.47361, 0, 0, 0.575], 1668 "8729": [-0.02639, 0.47361, 0, 0, 0.575], 1669 "8730": [0.18, 0.82, 0, 0, 0.95833], 1670 "8733": [0, 0.44444, 0, 0, 0.89444], 1671 "8734": [0, 0.44444, 0, 0, 1.14999], 1672 "8736": [0, 0.69224, 0, 0, 0.72222], 1673 "8739": [0.25, 0.75, 0, 0, 0.31944], 1674 "8741": [0.25, 0.75, 0, 0, 0.575], 1675 "8743": [0, 0.55556, 0, 0, 0.76666], 1676 "8744": [0, 0.55556, 0, 0, 0.76666], 1677 "8745": [0, 0.55556, 0, 0, 0.76666], 1678 "8746": [0, 0.55556, 0, 0, 0.76666], 1679 "8747": [0.19444, 0.69444, 0.12778, 0, 0.56875], 1680 "8764": [-0.10889, 0.39111, 0, 0, 0.89444], 1681 "8768": [0.19444, 0.69444, 0, 0, 0.31944], 1682 "8771": [0.00222, 0.50222, 0, 0, 0.89444], 1683 "8773": [0.027, 0.638, 0, 0, 0.894], 1684 "8776": [0.02444, 0.52444, 0, 0, 0.89444], 1685 "8781": [0.00222, 0.50222, 0, 0, 0.89444], 1686 "8801": [0.00222, 0.50222, 0, 0, 0.89444], 1687 "8804": [0.19667, 0.69667, 0, 0, 0.89444], 1688 "8805": [0.19667, 0.69667, 0, 0, 0.89444], 1689 "8810": [0.08556, 0.58556, 0, 0, 1.14999], 1690 "8811": [0.08556, 0.58556, 0, 0, 1.14999], 1691 "8826": [0.08556, 0.58556, 0, 0, 0.89444], 1692 "8827": [0.08556, 0.58556, 0, 0, 0.89444], 1693 "8834": [0.08556, 0.58556, 0, 0, 0.89444], 1694 "8835": [0.08556, 0.58556, 0, 0, 0.89444], 1695 "8838": [0.19667, 0.69667, 0, 0, 0.89444], 1696 "8839": [0.19667, 0.69667, 0, 0, 0.89444], 1697 "8846": [0, 0.55556, 0, 0, 0.76666], 1698 "8849": [0.19667, 0.69667, 0, 0, 0.89444], 1699 "8850": [0.19667, 0.69667, 0, 0, 0.89444], 1700 "8851": [0, 0.55556, 0, 0, 0.76666], 1701 "8852": [0, 0.55556, 0, 0, 0.76666], 1702 "8853": [0.13333, 0.63333, 0, 0, 0.89444], 1703 "8854": [0.13333, 0.63333, 0, 0, 0.89444], 1704 "8855": [0.13333, 0.63333, 0, 0, 0.89444], 1705 "8856": [0.13333, 0.63333, 0, 0, 0.89444], 1706 "8857": [0.13333, 0.63333, 0, 0, 0.89444], 1707 "8866": [0, 0.69444, 0, 0, 0.70277], 1708 "8867": [0, 0.69444, 0, 0, 0.70277], 1709 "8868": [0, 0.69444, 0, 0, 0.89444], 1710 "8869": [0, 0.69444, 0, 0, 0.89444], 1711 "8900": [-0.02639, 0.47361, 0, 0, 0.575], 1712 "8901": [-0.02639, 0.47361, 0, 0, 0.31944], 1713 "8902": [-0.02778, 0.47222, 0, 0, 0.575], 1714 "8968": [0.25, 0.75, 0, 0, 0.51111], 1715 "8969": [0.25, 0.75, 0, 0, 0.51111], 1716 "8970": [0.25, 0.75, 0, 0, 0.51111], 1717 "8971": [0.25, 0.75, 0, 0, 0.51111], 1718 "8994": [-0.13889, 0.36111, 0, 0, 1.14999], 1719 "8995": [-0.13889, 0.36111, 0, 0, 1.14999], 1720 "9651": [0.19444, 0.69444, 0, 0, 1.02222], 1721 "9657": [-0.02778, 0.47222, 0, 0, 0.575], 1722 "9661": [0.19444, 0.69444, 0, 0, 1.02222], 1723 "9667": [-0.02778, 0.47222, 0, 0, 0.575], 1724 "9711": [0.19444, 0.69444, 0, 0, 1.14999], 1725 "9824": [0.12963, 0.69444, 0, 0, 0.89444], 1726 "9825": [0.12963, 0.69444, 0, 0, 0.89444], 1727 "9826": [0.12963, 0.69444, 0, 0, 0.89444], 1728 "9827": [0.12963, 0.69444, 0, 0, 0.89444], 1729 "9837": [0, 0.75, 0, 0, 0.44722], 1730 "9838": [0.19444, 0.69444, 0, 0, 0.44722], 1731 "9839": [0.19444, 0.69444, 0, 0, 0.44722], 1732 "10216": [0.25, 0.75, 0, 0, 0.44722], 1733 "10217": [0.25, 0.75, 0, 0, 0.44722], 1734 "10815": [0, 0.68611, 0, 0, 0.9], 1735 "10927": [0.19667, 0.69667, 0, 0, 0.89444], 1736 "10928": [0.19667, 0.69667, 0, 0, 0.89444], 1737 "57376": [0.19444, 0.69444, 0, 0, 0] 1738 }, 1739 "Main-BoldItalic": { 1740 "32": [0, 0, 0, 0, 0.25], 1741 "33": [0, 0.69444, 0.11417, 0, 0.38611],
vendor: 15,788 bytes, lines 1742-2105
1742 "34": [0, 0.69444, 0.07939, 0, 0.62055], 1743 "35": [0.19444, 0.69444, 0.06833, 0, 0.94444], 1744 "37": [0.05556, 0.75, 0.12861, 0, 0.94444], 1745 "38": [0, 0.69444, 0.08528, 0, 0.88555], 1746 "39": [0, 0.69444, 0.12945, 0, 0.35555], 1747 "40": [0.25, 0.75, 0.15806, 0, 0.47333], 1748 "41": [0.25, 0.75, 0.03306, 0, 0.47333], 1749 "42": [0, 0.75, 0.14333, 0, 0.59111], 1750 "43": [0.10333, 0.60333, 0.03306, 0, 0.88555], 1751 "44": [0.19444, 0.14722, 0, 0, 0.35555], 1752 "45": [0, 0.44444, 0.02611, 0, 0.41444], 1753 "46": [0, 0.14722, 0, 0, 0.35555], 1754 "47": [0.25, 0.75, 0.15806, 0, 0.59111], 1755 "48": [0, 0.64444, 0.13167, 0, 0.59111], 1756 "49": [0, 0.64444, 0.13167, 0, 0.59111], 1757 "50": [0, 0.64444, 0.13167, 0, 0.59111], 1758 "51": [0, 0.64444, 0.13167, 0, 0.59111], 1759 "52": [0.19444, 0.64444, 0.13167, 0, 0.59111], 1760 "53": [0, 0.64444, 0.13167, 0, 0.59111], 1761 "54": [0, 0.64444, 0.13167, 0, 0.59111], 1762 "55": [0.19444, 0.64444, 0.13167, 0, 0.59111], 1763 "56": [0, 0.64444, 0.13167, 0, 0.59111], 1764 "57": [0, 0.64444, 0.13167, 0, 0.59111], 1765 "58": [0, 0.44444, 0.06695, 0, 0.35555], 1766 "59": [0.19444, 0.44444, 0.06695, 0, 0.35555], 1767 "61": [-0.10889, 0.39111, 0.06833, 0, 0.88555], 1768 "63": [0, 0.69444, 0.11472, 0, 0.59111], 1769 "64": [0, 0.69444, 0.09208, 0, 0.88555], 1770 "65": [0, 0.68611, 0, 0, 0.86555], 1771 "66": [0, 0.68611, 0.0992, 0, 0.81666], 1772 "67": [0, 0.68611, 0.14208, 0, 0.82666], 1773 "68": [0, 0.68611, 0.09062, 0, 0.87555], 1774 "69": [0, 0.68611, 0.11431, 0, 0.75666], 1775 "70": [0, 0.68611, 0.12903, 0, 0.72722], 1776 "71": [0, 0.68611, 0.07347, 0, 0.89527], 1777 "72": [0, 0.68611, 0.17208, 0, 0.8961], 1778 "73": [0, 0.68611, 0.15681, 0, 0.47166], 1779 "74": [0, 0.68611, 0.145, 0, 0.61055], 1780 "75": [0, 0.68611, 0.14208, 0, 0.89499], 1781 "76": [0, 0.68611, 0, 0, 0.69777], 1782 "77": [0, 0.68611, 0.17208, 0, 1.07277], 1783 "78": [0, 0.68611, 0.17208, 0, 0.8961], 1784 "79": [0, 0.68611, 0.09062, 0, 0.85499], 1785 "80": [0, 0.68611, 0.0992, 0, 0.78721], 1786 "81": [0.19444, 0.68611, 0.09062, 0, 0.85499], 1787 "82": [0, 0.68611, 0.02559, 0, 0.85944], 1788 "83": [0, 0.68611, 0.11264, 0, 0.64999], 1789 "84": [0, 0.68611, 0.12903, 0, 0.7961], 1790 "85": [0, 0.68611, 0.17208, 0, 0.88083], 1791 "86": [0, 0.68611, 0.18625, 0, 0.86555], 1792 "87": [0, 0.68611, 0.18625, 0, 1.15999], 1793 "88": [0, 0.68611, 0.15681, 0, 0.86555], 1794 "89": [0, 0.68611, 0.19803, 0, 0.86555], 1795 "90": [0, 0.68611, 0.14208, 0, 0.70888], 1796 "91": [0.25, 0.75, 0.1875, 0, 0.35611], 1797 "93": [0.25, 0.75, 0.09972, 0, 0.35611], 1798 "94": [0, 0.69444, 0.06709, 0, 0.59111], 1799 "95": [0.31, 0.13444, 0.09811, 0, 0.59111], 1800 "97": [0, 0.44444, 0.09426, 0, 0.59111], 1801 "98": [0, 0.69444, 0.07861, 0, 0.53222], 1802 "99": [0, 0.44444, 0.05222, 0, 0.53222], 1803 "100": [0, 0.69444, 0.10861, 0, 0.59111], 1804 "101": [0, 0.44444, 0.085, 0, 0.53222], 1805 "102": [0.19444, 0.69444, 0.21778, 0, 0.4], 1806 "103": [0.19444, 0.44444, 0.105, 0, 0.53222], 1807 "104": [0, 0.69444, 0.09426, 0, 0.59111], 1808 "105": [0, 0.69326, 0.11387, 0, 0.35555], 1809 "106": [0.19444, 0.69326, 0.1672, 0, 0.35555], 1810 "107": [0, 0.69444, 0.11111, 0, 0.53222], 1811 "108": [0, 0.69444, 0.10861, 0, 0.29666], 1812 "109": [0, 0.44444, 0.09426, 0, 0.94444], 1813 "110": [0, 0.44444, 0.09426, 0, 0.64999], 1814 "111": [0, 0.44444, 0.07861, 0, 0.59111], 1815 "112": [0.19444, 0.44444, 0.07861, 0, 0.59111], 1816 "113": [0.19444, 0.44444, 0.105, 0, 0.53222], 1817 "114": [0, 0.44444, 0.11111, 0, 0.50167], 1818 "115": [0, 0.44444, 0.08167, 0, 0.48694], 1819 "116": [0, 0.63492, 0.09639, 0, 0.385], 1820 "117": [0, 0.44444, 0.09426, 0, 0.62055], 1821 "118": [0, 0.44444, 0.11111, 0, 0.53222], 1822 "119": [0, 0.44444, 0.11111, 0, 0.76777], 1823 "120": [0, 0.44444, 0.12583, 0, 0.56055], 1824 "121": [0.19444, 0.44444, 0.105, 0, 0.56166], 1825 "122": [0, 0.44444, 0.13889, 0, 0.49055], 1826 "126": [0.35, 0.34444, 0.11472, 0, 0.59111], 1827 "160": [0, 0, 0, 0, 0.25], 1828 "168": [0, 0.69444, 0.11473, 0, 0.59111], 1829 "176": [0, 0.69444, 0, 0, 0.94888], 1830 "184": [0.17014, 0, 0, 0, 0.53222], 1831 "198": [0, 0.68611, 0.11431, 0, 1.02277], 1832 "216": [0.04861, 0.73472, 0.09062, 0, 0.88555], 1833 "223": [0.19444, 0.69444, 0.09736, 0, 0.665], 1834 "230": [0, 0.44444, 0.085, 0, 0.82666], 1835 "248": [0.09722, 0.54167, 0.09458, 0, 0.59111], 1836 "305": [0, 0.44444, 0.09426, 0, 0.35555], 1837 "338": [0, 0.68611, 0.11431, 0, 1.14054], 1838 "339": [0, 0.44444, 0.085, 0, 0.82666], 1839 "567": [0.19444, 0.44444, 0.04611, 0, 0.385], 1840 "710": [0, 0.69444, 0.06709, 0, 0.59111], 1841 "711": [0, 0.63194, 0.08271, 0, 0.59111], 1842 "713": [0, 0.59444, 0.10444, 0, 0.59111], 1843 "714": [0, 0.69444, 0.08528, 0, 0.59111], 1844 "715": [0, 0.69444, 0, 0, 0.59111], 1845 "728": [0, 0.69444, 0.10333, 0, 0.59111], 1846 "729": [0, 0.69444, 0.12945, 0, 0.35555], 1847 "730": [0, 0.69444, 0, 0, 0.94888], 1848 "732": [0, 0.69444, 0.11472, 0, 0.59111], 1849 "733": [0, 0.69444, 0.11472, 0, 0.59111], 1850 "915": [0, 0.68611, 0.12903, 0, 0.69777], 1851 "916": [0, 0.68611, 0, 0, 0.94444], 1852 "920": [0, 0.68611, 0.09062, 0, 0.88555], 1853 "923": [0, 0.68611, 0, 0, 0.80666], 1854 "926": [0, 0.68611, 0.15092, 0, 0.76777], 1855 "928": [0, 0.68611, 0.17208, 0, 0.8961], 1856 "931": [0, 0.68611, 0.11431, 0, 0.82666], 1857 "933": [0, 0.68611, 0.10778, 0, 0.88555], 1858 "934": [0, 0.68611, 0.05632, 0, 0.82666], 1859 "936": [0, 0.68611, 0.10778, 0, 0.88555], 1860 "937": [0, 0.68611, 0.0992, 0, 0.82666], 1861 "8211": [0, 0.44444, 0.09811, 0, 0.59111], 1862 "8212": [0, 0.44444, 0.09811, 0, 1.18221], 1863 "8216": [0, 0.69444, 0.12945, 0, 0.35555], 1864 "8217": [0, 0.69444, 0.12945, 0, 0.35555], 1865 "8220": [0, 0.69444, 0.16772, 0, 0.62055], 1866 "8221": [0, 0.69444, 0.07939, 0, 0.62055] 1867 }, 1868 "Main-Italic": { 1869 "32": [0, 0, 0, 0, 0.25], 1870 "33": [0, 0.69444, 0.12417, 0, 0.30667], 1871 "34": [0, 0.69444, 0.06961, 0, 0.51444], 1872 "35": [0.19444, 0.69444, 0.06616, 0, 0.81777], 1873 "37": [0.05556, 0.75, 0.13639, 0, 0.81777], 1874 "38": [0, 0.69444, 0.09694, 0, 0.76666], 1875 "39": [0, 0.69444, 0.12417, 0, 0.30667], 1876 "40": [0.25, 0.75, 0.16194, 0, 0.40889], 1877 "41": [0.25, 0.75, 0.03694, 0, 0.40889], 1878 "42": [0, 0.75, 0.14917, 0, 0.51111], 1879 "43": [0.05667, 0.56167, 0.03694, 0, 0.76666], 1880 "44": [0.19444, 0.10556, 0, 0, 0.30667], 1881 "45": [0, 0.43056, 0.02826, 0, 0.35778], 1882 "46": [0, 0.10556, 0, 0, 0.30667], 1883 "47": [0.25, 0.75, 0.16194, 0, 0.51111], 1884 "48": [0, 0.64444, 0.13556, 0, 0.51111], 1885 "49": [0, 0.64444, 0.13556, 0, 0.51111], 1886 "50": [0, 0.64444, 0.13556, 0, 0.51111], 1887 "51": [0, 0.64444, 0.13556, 0, 0.51111], 1888 "52": [0.19444, 0.64444, 0.13556, 0, 0.51111], 1889 "53": [0, 0.64444, 0.13556, 0, 0.51111], 1890 "54": [0, 0.64444, 0.13556, 0, 0.51111], 1891 "55": [0.19444, 0.64444, 0.13556, 0, 0.51111], 1892 "56": [0, 0.64444, 0.13556, 0, 0.51111], 1893 "57": [0, 0.64444, 0.13556, 0, 0.51111], 1894 "58": [0, 0.43056, 0.0582, 0, 0.30667], 1895 "59": [0.19444, 0.43056, 0.0582, 0, 0.30667], 1896 "61": [-0.13313, 0.36687, 0.06616, 0, 0.76666], 1897 "63": [0, 0.69444, 0.1225, 0, 0.51111], 1898 "64": [0, 0.69444, 0.09597, 0, 0.76666], 1899 "65": [0, 0.68333, 0, 0, 0.74333], 1900 "66": [0, 0.68333, 0.10257, 0, 0.70389], 1901 "67": [0, 0.68333, 0.14528, 0, 0.71555], 1902 "68": [0, 0.68333, 0.09403, 0, 0.755], 1903 "69": [0, 0.68333, 0.12028, 0, 0.67833], 1904 "70": [0, 0.68333, 0.13305, 0, 0.65277], 1905 "71": [0, 0.68333, 0.08722, 0, 0.77361], 1906 "72": [0, 0.68333, 0.16389, 0, 0.74333], 1907 "73": [0, 0.68333, 0.15806, 0, 0.38555], 1908 "74": [0, 0.68333, 0.14028, 0, 0.525], 1909 "75": [0, 0.68333, 0.14528, 0, 0.76888], 1910 "76": [0, 0.68333, 0, 0, 0.62722], 1911 "77": [0, 0.68333, 0.16389, 0, 0.89666], 1912 "78": [0, 0.68333, 0.16389, 0, 0.74333], 1913 "79": [0, 0.68333, 0.09403, 0, 0.76666], 1914 "80": [0, 0.68333, 0.10257, 0, 0.67833], 1915 "81": [0.19444, 0.68333, 0.09403, 0, 0.76666], 1916 "82": [0, 0.68333, 0.03868, 0, 0.72944], 1917 "83": [0, 0.68333, 0.11972, 0, 0.56222], 1918 "84": [0, 0.68333, 0.13305, 0, 0.71555], 1919 "85": [0, 0.68333, 0.16389, 0, 0.74333], 1920 "86": [0, 0.68333, 0.18361, 0, 0.74333], 1921 "87": [0, 0.68333, 0.18361, 0, 0.99888], 1922 "88": [0, 0.68333, 0.15806, 0, 0.74333], 1923 "89": [0, 0.68333, 0.19383, 0, 0.74333], 1924 "90": [0, 0.68333, 0.14528, 0, 0.61333], 1925 "91": [0.25, 0.75, 0.1875, 0, 0.30667], 1926 "93": [0.25, 0.75, 0.10528, 0, 0.30667], 1927 "94": [0, 0.69444, 0.06646, 0, 0.51111], 1928 "95": [0.31, 0.12056, 0.09208, 0, 0.51111], 1929 "97": [0, 0.43056, 0.07671, 0, 0.51111], 1930 "98": [0, 0.69444, 0.06312, 0, 0.46], 1931 "99": [0, 0.43056, 0.05653, 0, 0.46], 1932 "100": [0, 0.69444, 0.10333, 0, 0.51111], 1933 "101": [0, 0.43056, 0.07514, 0, 0.46], 1934 "102": [0.19444, 0.69444, 0.21194, 0, 0.30667], 1935 "103": [0.19444, 0.43056, 0.08847, 0, 0.46], 1936 "104": [0, 0.69444, 0.07671, 0, 0.51111], 1937 "105": [0, 0.65536, 0.1019, 0, 0.30667], 1938 "106": [0.19444, 0.65536, 0.14467, 0, 0.30667], 1939 "107": [0, 0.69444, 0.10764, 0, 0.46], 1940 "108": [0, 0.69444, 0.10333, 0, 0.25555], 1941 "109": [0, 0.43056, 0.07671, 0, 0.81777], 1942 "110": [0, 0.43056, 0.07671, 0, 0.56222], 1943 "111": [0, 0.43056, 0.06312, 0, 0.51111], 1944 "112": [0.19444, 0.43056, 0.06312, 0, 0.51111], 1945 "113": [0.19444, 0.43056, 0.08847, 0, 0.46], 1946 "114": [0, 0.43056, 0.10764, 0, 0.42166], 1947 "115": [0, 0.43056, 0.08208, 0, 0.40889], 1948 "116": [0, 0.61508, 0.09486, 0, 0.33222], 1949 "117": [0, 0.43056, 0.07671, 0, 0.53666], 1950 "118": [0, 0.43056, 0.10764, 0, 0.46], 1951 "119": [0, 0.43056, 0.10764, 0, 0.66444], 1952 "120": [0, 0.43056, 0.12042, 0, 0.46389], 1953 "121": [0.19444, 0.43056, 0.08847, 0, 0.48555], 1954 "122": [0, 0.43056, 0.12292, 0, 0.40889], 1955 "126": [0.35, 0.31786, 0.11585, 0, 0.51111], 1956 "160": [0, 0, 0, 0, 0.25], 1957 "168": [0, 0.66786, 0.10474, 0, 0.51111], 1958 "176": [0, 0.69444, 0, 0, 0.83129], 1959 "184": [0.17014, 0, 0, 0, 0.46], 1960 "198": [0, 0.68333, 0.12028, 0, 0.88277], 1961 "216": [0.04861, 0.73194, 0.09403, 0, 0.76666], 1962 "223": [0.19444, 0.69444, 0.10514, 0, 0.53666], 1963 "230": [0, 0.43056, 0.07514, 0, 0.71555], 1964 "248": [0.09722, 0.52778, 0.09194, 0, 0.51111], 1965 "338": [0, 0.68333, 0.12028, 0, 0.98499], 1966 "339": [0, 0.43056, 0.07514, 0, 0.71555], 1967 "710": [0, 0.69444, 0.06646, 0, 0.51111], 1968 "711": [0, 0.62847, 0.08295, 0, 0.51111], 1969 "713": [0, 0.56167, 0.10333, 0, 0.51111], 1970 "714": [0, 0.69444, 0.09694, 0, 0.51111], 1971 "715": [0, 0.69444, 0, 0, 0.51111], 1972 "728": [0, 0.69444, 0.10806, 0, 0.51111], 1973 "729": [0, 0.66786, 0.11752, 0, 0.30667], 1974 "730": [0, 0.69444, 0, 0, 0.83129], 1975 "732": [0, 0.66786, 0.11585, 0, 0.51111], 1976 "733": [0, 0.69444, 0.1225, 0, 0.51111], 1977 "915": [0, 0.68333, 0.13305, 0, 0.62722], 1978 "916": [0, 0.68333, 0, 0, 0.81777], 1979 "920": [0, 0.68333, 0.09403, 0, 0.76666], 1980 "923": [0, 0.68333, 0, 0, 0.69222], 1981 "926": [0, 0.68333, 0.15294, 0, 0.66444], 1982 "928": [0, 0.68333, 0.16389, 0, 0.74333], 1983 "931": [0, 0.68333, 0.12028, 0, 0.71555], 1984 "933": [0, 0.68333, 0.11111, 0, 0.76666], 1985 "934": [0, 0.68333, 0.05986, 0, 0.71555], 1986 "936": [0, 0.68333, 0.11111, 0, 0.76666], 1987 "937": [0, 0.68333, 0.10257, 0, 0.71555], 1988 "8211": [0, 0.43056, 0.09208, 0, 0.51111], 1989 "8212": [0, 0.43056, 0.09208, 0, 1.02222], 1990 "8216": [0, 0.69444, 0.12417, 0, 0.30667], 1991 "8217": [0, 0.69444, 0.12417, 0, 0.30667], 1992 "8220": [0, 0.69444, 0.1685, 0, 0.51444], 1993 "8221": [0, 0.69444, 0.06961, 0, 0.51444], 1994 "8463": [0, 0.68889, 0, 0, 0.54028] 1995 }, 1996 "Main-Regular": { 1997 "32": [0, 0, 0, 0, 0.25], 1998 "33": [0, 0.69444, 0, 0, 0.27778], 1999 "34": [0, 0.69444, 0, 0, 0.5], 2000 "35": [0.19444, 0.69444, 0, 0, 0.83334], 2001 "36": [0.05556, 0.75, 0, 0, 0.5], 2002 "37": [0.05556, 0.75, 0, 0, 0.83334], 2003 "38": [0, 0.69444, 0, 0, 0.77778], 2004 "39": [0, 0.69444, 0, 0, 0.27778], 2005 "40": [0.25, 0.75, 0, 0, 0.38889], 2006 "41": [0.25, 0.75, 0, 0, 0.38889], 2007 "42": [0, 0.75, 0, 0, 0.5], 2008 "43": [0.08333, 0.58333, 0, 0, 0.77778], 2009 "44": [0.19444, 0.10556, 0, 0, 0.27778], 2010 "45": [0, 0.43056, 0, 0, 0.33333], 2011 "46": [0, 0.10556, 0, 0, 0.27778], 2012 "47": [0.25, 0.75, 0, 0, 0.5], 2013 "48": [0, 0.64444, 0, 0, 0.5], 2014 "49": [0, 0.64444, 0, 0, 0.5], 2015 "50": [0, 0.64444, 0, 0, 0.5], 2016 "51": [0, 0.64444, 0, 0, 0.5], 2017 "52": [0, 0.64444, 0, 0, 0.5], 2018 "53": [0, 0.64444, 0, 0, 0.5], 2019 "54": [0, 0.64444, 0, 0, 0.5], 2020 "55": [0, 0.64444, 0, 0, 0.5], 2021 "56": [0, 0.64444, 0, 0, 0.5], 2022 "57": [0, 0.64444, 0, 0, 0.5], 2023 "58": [0, 0.43056, 0, 0, 0.27778], 2024 "59": [0.19444, 0.43056, 0, 0, 0.27778], 2025 "60": [0.0391, 0.5391, 0, 0, 0.77778], 2026 "61": [-0.13313, 0.36687, 0, 0, 0.77778], 2027 "62": [0.0391, 0.5391, 0, 0, 0.77778], 2028 "63": [0, 0.69444, 0, 0, 0.47222], 2029 "64": [0, 0.69444, 0, 0, 0.77778], 2030 "65": [0, 0.68333, 0, 0, 0.75], 2031 "66": [0, 0.68333, 0, 0, 0.70834], 2032 "67": [0, 0.68333, 0, 0, 0.72222], 2033 "68": [0, 0.68333, 0, 0, 0.76389], 2034 "69": [0, 0.68333, 0, 0, 0.68056], 2035 "70": [0, 0.68333, 0, 0, 0.65278], 2036 "71": [0, 0.68333, 0, 0, 0.78472], 2037 "72": [0, 0.68333, 0, 0, 0.75], 2038 "73": [0, 0.68333, 0, 0, 0.36111], 2039 "74": [0, 0.68333, 0, 0, 0.51389], 2040 "75": [0, 0.68333, 0, 0, 0.77778], 2041 "76": [0, 0.68333, 0, 0, 0.625], 2042 "77": [0, 0.68333, 0, 0, 0.91667], 2043 "78": [0, 0.68333, 0, 0, 0.75], 2044 "79": [0, 0.68333, 0, 0, 0.77778], 2045 "80": [0, 0.68333, 0, 0, 0.68056], 2046 "81": [0.19444, 0.68333, 0, 0, 0.77778], 2047 "82": [0, 0.68333, 0, 0, 0.73611], 2048 "83": [0, 0.68333, 0, 0, 0.55556], 2049 "84": [0, 0.68333, 0, 0, 0.72222], 2050 "85": [0, 0.68333, 0, 0, 0.75], 2051 "86": [0, 0.68333, 0.01389, 0, 0.75], 2052 "87": [0, 0.68333, 0.01389, 0, 1.02778], 2053 "88": [0, 0.68333, 0, 0, 0.75], 2054 "89": [0, 0.68333, 0.025, 0, 0.75], 2055 "90": [0, 0.68333, 0, 0, 0.61111], 2056 "91": [0.25, 0.75, 0, 0, 0.27778], 2057 "92": [0.25, 0.75, 0, 0, 0.5], 2058 "93": [0.25, 0.75, 0, 0, 0.27778], 2059 "94": [0, 0.69444, 0, 0, 0.5], 2060 "95": [0.31, 0.12056, 0.02778, 0, 0.5], 2061 "97": [0, 0.43056, 0, 0, 0.5], 2062 "98": [0, 0.69444, 0, 0, 0.55556], 2063 "99": [0, 0.43056, 0, 0, 0.44445], 2064 "100": [0, 0.69444, 0, 0, 0.55556], 2065 "101": [0, 0.43056, 0, 0, 0.44445], 2066 "102": [0, 0.69444, 0.07778, 0, 0.30556], 2067 "103": [0.19444, 0.43056, 0.01389, 0, 0.5], 2068 "104": [0, 0.69444, 0, 0, 0.55556], 2069 "105": [0, 0.66786, 0, 0, 0.27778], 2070 "106": [0.19444, 0.66786, 0, 0, 0.30556], 2071 "107": [0, 0.69444, 0, 0, 0.52778], 2072 "108": [0, 0.69444, 0, 0, 0.27778], 2073 "109": [0, 0.43056, 0, 0, 0.83334], 2074 "110": [0, 0.43056, 0, 0, 0.55556], 2075 "111": [0, 0.43056, 0, 0, 0.5], 2076 "112": [0.19444, 0.43056, 0, 0, 0.55556], 2077 "113": [0.19444, 0.43056, 0, 0, 0.52778], 2078 "114": [0, 0.43056, 0, 0, 0.39167], 2079 "115": [0, 0.43056, 0, 0, 0.39445], 2080 "116": [0, 0.61508, 0, 0, 0.38889], 2081 "117": [0, 0.43056, 0, 0, 0.55556], 2082 "118": [0, 0.43056, 0.01389, 0, 0.52778], 2083 "119": [0, 0.43056, 0.01389, 0, 0.72222], 2084 "120": [0, 0.43056, 0, 0, 0.52778], 2085 "121": [0.19444, 0.43056, 0.01389, 0, 0.52778], 2086 "122": [0, 0.43056, 0, 0, 0.44445], 2087 "123": [0.25, 0.75, 0, 0, 0.5], 2088 "124": [0.25, 0.75, 0, 0, 0.27778], 2089 "125": [0.25, 0.75, 0, 0, 0.5], 2090 "126": [0.35, 0.31786, 0, 0, 0.5], 2091 "160": [0, 0, 0, 0, 0.25], 2092 "163": [0, 0.69444, 0, 0, 0.76909], 2093 "167": [0.19444, 0.69444, 0, 0, 0.44445], 2094 "168": [0, 0.66786, 0, 0, 0.5], 2095 "172": [0, 0.43056, 0, 0, 0.66667], 2096 "176": [0, 0.69444, 0, 0, 0.75], 2097 "177": [0.08333, 0.58333, 0, 0, 0.77778], 2098 "182": [0.19444, 0.69444, 0, 0, 0.61111], 2099 "184": [0.17014, 0, 0, 0, 0.44445], 2100 "198": [0, 0.68333, 0, 0, 0.90278], 2101 "215": [0.08333, 0.58333, 0, 0, 0.77778], 2102 "216": [0.04861, 0.73194, 0, 0, 0.77778], 2103 "223": [0, 0.69444, 0, 0, 0.5], 2104 "230": [0, 0.43056, 0, 0, 0.72222], 2105 "247": [0.08333, 0.58333, 0, 0, 0.77778],
vendor: 16,221 bytes, lines 2106-2475
2106 "248": [0.09722, 0.52778, 0, 0, 0.5], 2107 "305": [0, 0.43056, 0, 0, 0.27778], 2108 "338": [0, 0.68333, 0, 0, 1.01389], 2109 "339": [0, 0.43056, 0, 0, 0.77778], 2110 "567": [0.19444, 0.43056, 0, 0, 0.30556], 2111 "710": [0, 0.69444, 0, 0, 0.5], 2112 "711": [0, 0.62847, 0, 0, 0.5], 2113 "713": [0, 0.56778, 0, 0, 0.5], 2114 "714": [0, 0.69444, 0, 0, 0.5], 2115 "715": [0, 0.69444, 0, 0, 0.5], 2116 "728": [0, 0.69444, 0, 0, 0.5], 2117 "729": [0, 0.66786, 0, 0, 0.27778], 2118 "730": [0, 0.69444, 0, 0, 0.75], 2119 "732": [0, 0.66786, 0, 0, 0.5], 2120 "733": [0, 0.69444, 0, 0, 0.5], 2121 "915": [0, 0.68333, 0, 0, 0.625], 2122 "916": [0, 0.68333, 0, 0, 0.83334], 2123 "920": [0, 0.68333, 0, 0, 0.77778], 2124 "923": [0, 0.68333, 0, 0, 0.69445], 2125 "926": [0, 0.68333, 0, 0, 0.66667], 2126 "928": [0, 0.68333, 0, 0, 0.75], 2127 "931": [0, 0.68333, 0, 0, 0.72222], 2128 "933": [0, 0.68333, 0, 0, 0.77778], 2129 "934": [0, 0.68333, 0, 0, 0.72222], 2130 "936": [0, 0.68333, 0, 0, 0.77778], 2131 "937": [0, 0.68333, 0, 0, 0.72222], 2132 "8211": [0, 0.43056, 0.02778, 0, 0.5], 2133 "8212": [0, 0.43056, 0.02778, 0, 1.0], 2134 "8216": [0, 0.69444, 0, 0, 0.27778], 2135 "8217": [0, 0.69444, 0, 0, 0.27778], 2136 "8220": [0, 0.69444, 0, 0, 0.5], 2137 "8221": [0, 0.69444, 0, 0, 0.5], 2138 "8224": [0.19444, 0.69444, 0, 0, 0.44445], 2139 "8225": [0.19444, 0.69444, 0, 0, 0.44445], 2140 "8230": [0, 0.123, 0, 0, 1.172], 2141 "8242": [0, 0.55556, 0, 0, 0.275], 2142 "8407": [0, 0.71444, 0.15382, 0, 0.5], 2143 "8463": [0, 0.68889, 0, 0, 0.54028], 2144 "8465": [0, 0.69444, 0, 0, 0.72222], 2145 "8467": [0, 0.69444, 0, 0.11111, 0.41667], 2146 "8472": [0.19444, 0.43056, 0, 0.11111, 0.63646], 2147 "8476": [0, 0.69444, 0, 0, 0.72222], 2148 "8501": [0, 0.69444, 0, 0, 0.61111], 2149 "8592": [-0.13313, 0.36687, 0, 0, 1.0], 2150 "8593": [0.19444, 0.69444, 0, 0, 0.5], 2151 "8594": [-0.13313, 0.36687, 0, 0, 1.0], 2152 "8595": [0.19444, 0.69444, 0, 0, 0.5], 2153 "8596": [-0.13313, 0.36687, 0, 0, 1.0], 2154 "8597": [0.25, 0.75, 0, 0, 0.5], 2155 "8598": [0.19444, 0.69444, 0, 0, 1.0], 2156 "8599": [0.19444, 0.69444, 0, 0, 1.0], 2157 "8600": [0.19444, 0.69444, 0, 0, 1.0], 2158 "8601": [0.19444, 0.69444, 0, 0, 1.0], 2159 "8614": [0.011, 0.511, 0, 0, 1.0], 2160 "8617": [0.011, 0.511, 0, 0, 1.126], 2161 "8618": [0.011, 0.511, 0, 0, 1.126], 2162 "8636": [-0.13313, 0.36687, 0, 0, 1.0], 2163 "8637": [-0.13313, 0.36687, 0, 0, 1.0], 2164 "8640": [-0.13313, 0.36687, 0, 0, 1.0], 2165 "8641": [-0.13313, 0.36687, 0, 0, 1.0], 2166 "8652": [0.011, 0.671, 0, 0, 1.0], 2167 "8656": [-0.13313, 0.36687, 0, 0, 1.0], 2168 "8657": [0.19444, 0.69444, 0, 0, 0.61111], 2169 "8658": [-0.13313, 0.36687, 0, 0, 1.0], 2170 "8659": [0.19444, 0.69444, 0, 0, 0.61111], 2171 "8660": [-0.13313, 0.36687, 0, 0, 1.0], 2172 "8661": [0.25, 0.75, 0, 0, 0.61111], 2173 "8704": [0, 0.69444, 0, 0, 0.55556], 2174 "8706": [0, 0.69444, 0.05556, 0.08334, 0.5309], 2175 "8707": [0, 0.69444, 0, 0, 0.55556], 2176 "8709": [0.05556, 0.75, 0, 0, 0.5], 2177 "8711": [0, 0.68333, 0, 0, 0.83334], 2178 "8712": [0.0391, 0.5391, 0, 0, 0.66667], 2179 "8715": [0.0391, 0.5391, 0, 0, 0.66667], 2180 "8722": [0.08333, 0.58333, 0, 0, 0.77778], 2181 "8723": [0.08333, 0.58333, 0, 0, 0.77778], 2182 "8725": [0.25, 0.75, 0, 0, 0.5], 2183 "8726": [0.25, 0.75, 0, 0, 0.5], 2184 "8727": [-0.03472, 0.46528, 0, 0, 0.5], 2185 "8728": [-0.05555, 0.44445, 0, 0, 0.5], 2186 "8729": [-0.05555, 0.44445, 0, 0, 0.5], 2187 "8730": [0.2, 0.8, 0, 0, 0.83334], 2188 "8733": [0, 0.43056, 0, 0, 0.77778], 2189 "8734": [0, 0.43056, 0, 0, 1.0], 2190 "8736": [0, 0.69224, 0, 0, 0.72222], 2191 "8739": [0.25, 0.75, 0, 0, 0.27778], 2192 "8741": [0.25, 0.75, 0, 0, 0.5], 2193 "8743": [0, 0.55556, 0, 0, 0.66667], 2194 "8744": [0, 0.55556, 0, 0, 0.66667], 2195 "8745": [0, 0.55556, 0, 0, 0.66667], 2196 "8746": [0, 0.55556, 0, 0, 0.66667], 2197 "8747": [0.19444, 0.69444, 0.11111, 0, 0.41667], 2198 "8764": [-0.13313, 0.36687, 0, 0, 0.77778], 2199 "8768": [0.19444, 0.69444, 0, 0, 0.27778], 2200 "8771": [-0.03625, 0.46375, 0, 0, 0.77778], 2201 "8773": [-0.022, 0.589, 0, 0, 0.778], 2202 "8776": [-0.01688, 0.48312, 0, 0, 0.77778], 2203 "8781": [-0.03625, 0.46375, 0, 0, 0.77778], 2204 "8784": [-0.133, 0.673, 0, 0, 0.778], 2205 "8801": [-0.03625, 0.46375, 0, 0, 0.77778], 2206 "8804": [0.13597, 0.63597, 0, 0, 0.77778], 2207 "8805": [0.13597, 0.63597, 0, 0, 0.77778], 2208 "8810": [0.0391, 0.5391, 0, 0, 1.0], 2209 "8811": [0.0391, 0.5391, 0, 0, 1.0], 2210 "8826": [0.0391, 0.5391, 0, 0, 0.77778], 2211 "8827": [0.0391, 0.5391, 0, 0, 0.77778], 2212 "8834": [0.0391, 0.5391, 0, 0, 0.77778], 2213 "8835": [0.0391, 0.5391, 0, 0, 0.77778], 2214 "8838": [0.13597, 0.63597, 0, 0, 0.77778], 2215 "8839": [0.13597, 0.63597, 0, 0, 0.77778], 2216 "8846": [0, 0.55556, 0, 0, 0.66667], 2217 "8849": [0.13597, 0.63597, 0, 0, 0.77778], 2218 "8850": [0.13597, 0.63597, 0, 0, 0.77778], 2219 "8851": [0, 0.55556, 0, 0, 0.66667], 2220 "8852": [0, 0.55556, 0, 0, 0.66667], 2221 "8853": [0.08333, 0.58333, 0, 0, 0.77778], 2222 "8854": [0.08333, 0.58333, 0, 0, 0.77778], 2223 "8855": [0.08333, 0.58333, 0, 0, 0.77778], 2224 "8856": [0.08333, 0.58333, 0, 0, 0.77778], 2225 "8857": [0.08333, 0.58333, 0, 0, 0.77778], 2226 "8866": [0, 0.69444, 0, 0, 0.61111], 2227 "8867": [0, 0.69444, 0, 0, 0.61111], 2228 "8868": [0, 0.69444, 0, 0, 0.77778], 2229 "8869": [0, 0.69444, 0, 0, 0.77778], 2230 "8872": [0.249, 0.75, 0, 0, 0.867], 2231 "8900": [-0.05555, 0.44445, 0, 0, 0.5], 2232 "8901": [-0.05555, 0.44445, 0, 0, 0.27778], 2233 "8902": [-0.03472, 0.46528, 0, 0, 0.5], 2234 "8904": [0.005, 0.505, 0, 0, 0.9], 2235 "8942": [0.03, 0.903, 0, 0, 0.278], 2236 "8943": [-0.19, 0.313, 0, 0, 1.172], 2237 "8945": [-0.1, 0.823, 0, 0, 1.282], 2238 "8968": [0.25, 0.75, 0, 0, 0.44445], 2239 "8969": [0.25, 0.75, 0, 0, 0.44445], 2240 "8970": [0.25, 0.75, 0, 0, 0.44445], 2241 "8971": [0.25, 0.75, 0, 0, 0.44445], 2242 "8994": [-0.14236, 0.35764, 0, 0, 1.0], 2243 "8995": [-0.14236, 0.35764, 0, 0, 1.0], 2244 "9136": [0.244, 0.744, 0, 0, 0.412], 2245 "9137": [0.244, 0.745, 0, 0, 0.412], 2246 "9651": [0.19444, 0.69444, 0, 0, 0.88889], 2247 "9657": [-0.03472, 0.46528, 0, 0, 0.5], 2248 "9661": [0.19444, 0.69444, 0, 0, 0.88889], 2249 "9667": [-0.03472, 0.46528, 0, 0, 0.5], 2250 "9711": [0.19444, 0.69444, 0, 0, 1.0], 2251 "9824": [0.12963, 0.69444, 0, 0, 0.77778], 2252 "9825": [0.12963, 0.69444, 0, 0, 0.77778], 2253 "9826": [0.12963, 0.69444, 0, 0, 0.77778], 2254 "9827": [0.12963, 0.69444, 0, 0, 0.77778], 2255 "9837": [0, 0.75, 0, 0, 0.38889], 2256 "9838": [0.19444, 0.69444, 0, 0, 0.38889], 2257 "9839": [0.19444, 0.69444, 0, 0, 0.38889], 2258 "10216": [0.25, 0.75, 0, 0, 0.38889], 2259 "10217": [0.25, 0.75, 0, 0, 0.38889], 2260 "10222": [0.244, 0.744, 0, 0, 0.412], 2261 "10223": [0.244, 0.745, 0, 0, 0.412], 2262 "10229": [0.011, 0.511, 0, 0, 1.609], 2263 "10230": [0.011, 0.511, 0, 0, 1.638], 2264 "10231": [0.011, 0.511, 0, 0, 1.859], 2265 "10232": [0.024, 0.525, 0, 0, 1.609], 2266 "10233": [0.024, 0.525, 0, 0, 1.638], 2267 "10234": [0.024, 0.525, 0, 0, 1.858], 2268 "10236": [0.011, 0.511, 0, 0, 1.638], 2269 "10815": [0, 0.68333, 0, 0, 0.75], 2270 "10927": [0.13597, 0.63597, 0, 0, 0.77778], 2271 "10928": [0.13597, 0.63597, 0, 0, 0.77778], 2272 "57376": [0.19444, 0.69444, 0, 0, 0] 2273 }, 2274 "Math-BoldItalic": { 2275 "32": [0, 0, 0, 0, 0.25], 2276 "48": [0, 0.44444, 0, 0, 0.575], 2277 "49": [0, 0.44444, 0, 0, 0.575], 2278 "50": [0, 0.44444, 0, 0, 0.575], 2279 "51": [0.19444, 0.44444, 0, 0, 0.575], 2280 "52": [0.19444, 0.44444, 0, 0, 0.575], 2281 "53": [0.19444, 0.44444, 0, 0, 0.575], 2282 "54": [0, 0.64444, 0, 0, 0.575], 2283 "55": [0.19444, 0.44444, 0, 0, 0.575], 2284 "56": [0, 0.64444, 0, 0, 0.575], 2285 "57": [0.19444, 0.44444, 0, 0, 0.575], 2286 "65": [0, 0.68611, 0, 0, 0.86944], 2287 "66": [0, 0.68611, 0.04835, 0, 0.8664], 2288 "67": [0, 0.68611, 0.06979, 0, 0.81694], 2289 "68": [0, 0.68611, 0.03194, 0, 0.93812], 2290 "69": [0, 0.68611, 0.05451, 0, 0.81007], 2291 "70": [0, 0.68611, 0.15972, 0, 0.68889], 2292 "71": [0, 0.68611, 0, 0, 0.88673], 2293 "72": [0, 0.68611, 0.08229, 0, 0.98229], 2294 "73": [0, 0.68611, 0.07778, 0, 0.51111], 2295 "74": [0, 0.68611, 0.10069, 0, 0.63125], 2296 "75": [0, 0.68611, 0.06979, 0, 0.97118], 2297 "76": [0, 0.68611, 0, 0, 0.75555], 2298 "77": [0, 0.68611, 0.11424, 0, 1.14201], 2299 "78": [0, 0.68611, 0.11424, 0, 0.95034], 2300 "79": [0, 0.68611, 0.03194, 0, 0.83666], 2301 "80": [0, 0.68611, 0.15972, 0, 0.72309], 2302 "81": [0.19444, 0.68611, 0, 0, 0.86861], 2303 "82": [0, 0.68611, 0.00421, 0, 0.87235], 2304 "83": [0, 0.68611, 0.05382, 0, 0.69271], 2305 "84": [0, 0.68611, 0.15972, 0, 0.63663], 2306 "85": [0, 0.68611, 0.11424, 0, 0.80027], 2307 "86": [0, 0.68611, 0.25555, 0, 0.67778], 2308 "87": [0, 0.68611, 0.15972, 0, 1.09305], 2309 "88": [0, 0.68611, 0.07778, 0, 0.94722], 2310 "89": [0, 0.68611, 0.25555, 0, 0.67458], 2311 "90": [0, 0.68611, 0.06979, 0, 0.77257], 2312 "97": [0, 0.44444, 0, 0, 0.63287], 2313 "98": [0, 0.69444, 0, 0, 0.52083], 2314 "99": [0, 0.44444, 0, 0, 0.51342], 2315 "100": [0, 0.69444, 0, 0, 0.60972], 2316 "101": [0, 0.44444, 0, 0, 0.55361], 2317 "102": [0.19444, 0.69444, 0.11042, 0, 0.56806], 2318 "103": [0.19444, 0.44444, 0.03704, 0, 0.5449], 2319 "104": [0, 0.69444, 0, 0, 0.66759], 2320 "105": [0, 0.69326, 0, 0, 0.4048], 2321 "106": [0.19444, 0.69326, 0.0622, 0, 0.47083], 2322 "107": [0, 0.69444, 0.01852, 0, 0.6037], 2323 "108": [0, 0.69444, 0.0088, 0, 0.34815], 2324 "109": [0, 0.44444, 0, 0, 1.0324], 2325 "110": [0, 0.44444, 0, 0, 0.71296], 2326 "111": [0, 0.44444, 0, 0, 0.58472], 2327 "112": [0.19444, 0.44444, 0, 0, 0.60092], 2328 "113": [0.19444, 0.44444, 0.03704, 0, 0.54213], 2329 "114": [0, 0.44444, 0.03194, 0, 0.5287], 2330 "115": [0, 0.44444, 0, 0, 0.53125], 2331 "116": [0, 0.63492, 0, 0, 0.41528], 2332 "117": [0, 0.44444, 0, 0, 0.68102], 2333 "118": [0, 0.44444, 0.03704, 0, 0.56666], 2334 "119": [0, 0.44444, 0.02778, 0, 0.83148], 2335 "120": [0, 0.44444, 0, 0, 0.65903], 2336 "121": [0.19444, 0.44444, 0.03704, 0, 0.59028], 2337 "122": [0, 0.44444, 0.04213, 0, 0.55509], 2338 "160": [0, 0, 0, 0, 0.25], 2339 "915": [0, 0.68611, 0.15972, 0, 0.65694], 2340 "916": [0, 0.68611, 0, 0, 0.95833], 2341 "920": [0, 0.68611, 0.03194, 0, 0.86722], 2342 "923": [0, 0.68611, 0, 0, 0.80555], 2343 "926": [0, 0.68611, 0.07458, 0, 0.84125], 2344 "928": [0, 0.68611, 0.08229, 0, 0.98229], 2345 "931": [0, 0.68611, 0.05451, 0, 0.88507], 2346 "933": [0, 0.68611, 0.15972, 0, 0.67083], 2347 "934": [0, 0.68611, 0, 0, 0.76666], 2348 "936": [0, 0.68611, 0.11653, 0, 0.71402], 2349 "937": [0, 0.68611, 0.04835, 0, 0.8789], 2350 "945": [0, 0.44444, 0, 0, 0.76064], 2351 "946": [0.19444, 0.69444, 0.03403, 0, 0.65972], 2352 "947": [0.19444, 0.44444, 0.06389, 0, 0.59003], 2353 "948": [0, 0.69444, 0.03819, 0, 0.52222], 2354 "949": [0, 0.44444, 0, 0, 0.52882], 2355 "950": [0.19444, 0.69444, 0.06215, 0, 0.50833], 2356 "951": [0.19444, 0.44444, 0.03704, 0, 0.6], 2357 "952": [0, 0.69444, 0.03194, 0, 0.5618], 2358 "953": [0, 0.44444, 0, 0, 0.41204], 2359 "954": [0, 0.44444, 0, 0, 0.66759], 2360 "955": [0, 0.69444, 0, 0, 0.67083], 2361 "956": [0.19444, 0.44444, 0, 0, 0.70787], 2362 "957": [0, 0.44444, 0.06898, 0, 0.57685], 2363 "958": [0.19444, 0.69444, 0.03021, 0, 0.50833], 2364 "959": [0, 0.44444, 0, 0, 0.58472], 2365 "960": [0, 0.44444, 0.03704, 0, 0.68241], 2366 "961": [0.19444, 0.44444, 0, 0, 0.6118], 2367 "962": [0.09722, 0.44444, 0.07917, 0, 0.42361], 2368 "963": [0, 0.44444, 0.03704, 0, 0.68588], 2369 "964": [0, 0.44444, 0.13472, 0, 0.52083], 2370 "965": [0, 0.44444, 0.03704, 0, 0.63055], 2371 "966": [0.19444, 0.44444, 0, 0, 0.74722], 2372 "967": [0.19444, 0.44444, 0, 0, 0.71805], 2373 "968": [0.19444, 0.69444, 0.03704, 0, 0.75833], 2374 "969": [0, 0.44444, 0.03704, 0, 0.71782], 2375 "977": [0, 0.69444, 0, 0, 0.69155], 2376 "981": [0.19444, 0.69444, 0, 0, 0.7125], 2377 "982": [0, 0.44444, 0.03194, 0, 0.975], 2378 "1009": [0.19444, 0.44444, 0, 0, 0.6118], 2379 "1013": [0, 0.44444, 0, 0, 0.48333], 2380 "57649": [0, 0.44444, 0, 0, 0.39352], 2381 "57911": [0.19444, 0.44444, 0, 0, 0.43889] 2382 }, 2383 "Math-Italic": { 2384 "32": [0, 0, 0, 0, 0.25], 2385 "48": [0, 0.43056, 0, 0, 0.5], 2386 "49": [0, 0.43056, 0, 0, 0.5], 2387 "50": [0, 0.43056, 0, 0, 0.5], 2388 "51": [0.19444, 0.43056, 0, 0, 0.5], 2389 "52": [0.19444, 0.43056, 0, 0, 0.5], 2390 "53": [0.19444, 0.43056, 0, 0, 0.5], 2391 "54": [0, 0.64444, 0, 0, 0.5], 2392 "55": [0.19444, 0.43056, 0, 0, 0.5], 2393 "56": [0, 0.64444, 0, 0, 0.5], 2394 "57": [0.19444, 0.43056, 0, 0, 0.5], 2395 "65": [0, 0.68333, 0, 0.13889, 0.75], 2396 "66": [0, 0.68333, 0.05017, 0.08334, 0.75851], 2397 "67": [0, 0.68333, 0.07153, 0.08334, 0.71472], 2398 "68": [0, 0.68333, 0.02778, 0.05556, 0.82792], 2399 "69": [0, 0.68333, 0.05764, 0.08334, 0.7382], 2400 "70": [0, 0.68333, 0.13889, 0.08334, 0.64306], 2401 "71": [0, 0.68333, 0, 0.08334, 0.78625], 2402 "72": [0, 0.68333, 0.08125, 0.05556, 0.83125], 2403 "73": [0, 0.68333, 0.07847, 0.11111, 0.43958], 2404 "74": [0, 0.68333, 0.09618, 0.16667, 0.55451], 2405 "75": [0, 0.68333, 0.07153, 0.05556, 0.84931], 2406 "76": [0, 0.68333, 0, 0.02778, 0.68056], 2407 "77": [0, 0.68333, 0.10903, 0.08334, 0.97014], 2408 "78": [0, 0.68333, 0.10903, 0.08334, 0.80347], 2409 "79": [0, 0.68333, 0.02778, 0.08334, 0.76278], 2410 "80": [0, 0.68333, 0.13889, 0.08334, 0.64201], 2411 "81": [0.19444, 0.68333, 0, 0.08334, 0.79056], 2412 "82": [0, 0.68333, 0.00773, 0.08334, 0.75929], 2413 "83": [0, 0.68333, 0.05764, 0.08334, 0.6132], 2414 "84": [0, 0.68333, 0.13889, 0.08334, 0.58438], 2415 "85": [0, 0.68333, 0.10903, 0.02778, 0.68278], 2416 "86": [0, 0.68333, 0.22222, 0, 0.58333], 2417 "87": [0, 0.68333, 0.13889, 0, 0.94445], 2418 "88": [0, 0.68333, 0.07847, 0.08334, 0.82847], 2419 "89": [0, 0.68333, 0.22222, 0, 0.58056], 2420 "90": [0, 0.68333, 0.07153, 0.08334, 0.68264], 2421 "97": [0, 0.43056, 0, 0, 0.52859], 2422 "98": [0, 0.69444, 0, 0, 0.42917], 2423 "99": [0, 0.43056, 0, 0.05556, 0.43276], 2424 "100": [0, 0.69444, 0, 0.16667, 0.52049], 2425 "101": [0, 0.43056, 0, 0.05556, 0.46563], 2426 "102": [0.19444, 0.69444, 0.10764, 0.16667, 0.48959], 2427 "103": [0.19444, 0.43056, 0.03588, 0.02778, 0.47697], 2428 "104": [0, 0.69444, 0, 0, 0.57616], 2429 "105": [0, 0.65952, 0, 0, 0.34451], 2430 "106": [0.19444, 0.65952, 0.05724, 0, 0.41181], 2431 "107": [0, 0.69444, 0.03148, 0, 0.5206], 2432 "108": [0, 0.69444, 0.01968, 0.08334, 0.29838], 2433 "109": [0, 0.43056, 0, 0, 0.87801], 2434 "110": [0, 0.43056, 0, 0, 0.60023], 2435 "111": [0, 0.43056, 0, 0.05556, 0.48472], 2436 "112": [0.19444, 0.43056, 0, 0.08334, 0.50313], 2437 "113": [0.19444, 0.43056, 0.03588, 0.08334, 0.44641], 2438 "114": [0, 0.43056, 0.02778, 0.05556, 0.45116], 2439 "115": [0, 0.43056, 0, 0.05556, 0.46875], 2440 "116": [0, 0.61508, 0, 0.08334, 0.36111], 2441 "117": [0, 0.43056, 0, 0.02778, 0.57246], 2442 "118": [0, 0.43056, 0.03588, 0.02778, 0.48472], 2443 "119": [0, 0.43056, 0.02691, 0.08334, 0.71592], 2444 "120": [0, 0.43056, 0, 0.02778, 0.57153], 2445 "121": [0.19444, 0.43056, 0.03588, 0.05556, 0.49028], 2446 "122": [0, 0.43056, 0.04398, 0.05556, 0.46505], 2447 "160": [0, 0, 0, 0, 0.25], 2448 "915": [0, 0.68333, 0.13889, 0.08334, 0.61528], 2449 "916": [0, 0.68333, 0, 0.16667, 0.83334], 2450 "920": [0, 0.68333, 0.02778, 0.08334, 0.76278], 2451 "923": [0, 0.68333, 0, 0.16667, 0.69445], 2452 "926": [0, 0.68333, 0.07569, 0.08334, 0.74236], 2453 "928": [0, 0.68333, 0.08125, 0.05556, 0.83125], 2454 "931": [0, 0.68333, 0.05764, 0.08334, 0.77986], 2455 "933": [0, 0.68333, 0.13889, 0.05556, 0.58333], 2456 "934": [0, 0.68333, 0, 0.08334, 0.66667], 2457 "936": [0, 0.68333, 0.11, 0.05556, 0.61222], 2458 "937": [0, 0.68333, 0.05017, 0.08334, 0.7724], 2459 "945": [0, 0.43056, 0.0037, 0.02778, 0.6397], 2460 "946": [0.19444, 0.69444, 0.05278, 0.08334, 0.56563], 2461 "947": [0.19444, 0.43056, 0.05556, 0, 0.51773], 2462 "948": [0, 0.69444, 0.03785, 0.05556, 0.44444], 2463 "949": [0, 0.43056, 0, 0.08334, 0.46632], 2464 "950": [0.19444, 0.69444, 0.07378, 0.08334, 0.4375], 2465 "951": [0.19444, 0.43056, 0.03588, 0.05556, 0.49653], 2466 "952": [0, 0.69444, 0.02778, 0.08334, 0.46944], 2467 "953": [0, 0.43056, 0, 0.05556, 0.35394], 2468 "954": [0, 0.43056, 0, 0, 0.57616], 2469 "955": [0, 0.69444, 0, 0, 0.58334], 2470 "956": [0.19444, 0.43056, 0, 0.02778, 0.60255], 2471 "957": [0, 0.43056, 0.06366, 0.02778, 0.49398], 2472 "958": [0.19444, 0.69444, 0.04601, 0.11111, 0.4375], 2473 "959": [0, 0.43056, 0, 0.05556, 0.48472], 2474 "960": [0, 0.43056, 0.03588, 0, 0.57003], 2475 "961": [0.19444, 0.43056, 0, 0.08334, 0.51702],
vendor: 5,671 bytes, lines 2476-2616
2476 "962": [0.09722, 0.43056, 0.07986, 0.08334, 0.36285], 2477 "963": [0, 0.43056, 0.03588, 0, 0.57141], 2478 "964": [0, 0.43056, 0.1132, 0.02778, 0.43715], 2479 "965": [0, 0.43056, 0.03588, 0.02778, 0.54028], 2480 "966": [0.19444, 0.43056, 0, 0.08334, 0.65417], 2481 "967": [0.19444, 0.43056, 0, 0.05556, 0.62569], 2482 "968": [0.19444, 0.69444, 0.03588, 0.11111, 0.65139], 2483 "969": [0, 0.43056, 0.03588, 0, 0.62245], 2484 "977": [0, 0.69444, 0, 0.08334, 0.59144], 2485 "981": [0.19444, 0.69444, 0, 0.08334, 0.59583], 2486 "982": [0, 0.43056, 0.02778, 0, 0.82813], 2487 "1009": [0.19444, 0.43056, 0, 0.08334, 0.51702], 2488 "1013": [0, 0.43056, 0, 0.05556, 0.4059], 2489 "57649": [0, 0.43056, 0, 0.02778, 0.32246], 2490 "57911": [0.19444, 0.43056, 0, 0.08334, 0.38403] 2491 }, 2492 "SansSerif-Bold": { 2493 "32": [0, 0, 0, 0, 0.25], 2494 "33": [0, 0.69444, 0, 0, 0.36667], 2495 "34": [0, 0.69444, 0, 0, 0.55834], 2496 "35": [0.19444, 0.69444, 0, 0, 0.91667], 2497 "36": [0.05556, 0.75, 0, 0, 0.55], 2498 "37": [0.05556, 0.75, 0, 0, 1.02912], 2499 "38": [0, 0.69444, 0, 0, 0.83056], 2500 "39": [0, 0.69444, 0, 0, 0.30556], 2501 "40": [0.25, 0.75, 0, 0, 0.42778], 2502 "41": [0.25, 0.75, 0, 0, 0.42778], 2503 "42": [0, 0.75, 0, 0, 0.55], 2504 "43": [0.11667, 0.61667, 0, 0, 0.85556], 2505 "44": [0.10556, 0.13056, 0, 0, 0.30556], 2506 "45": [0, 0.45833, 0, 0, 0.36667], 2507 "46": [0, 0.13056, 0, 0, 0.30556], 2508 "47": [0.25, 0.75, 0, 0, 0.55], 2509 "48": [0, 0.69444, 0, 0, 0.55], 2510 "49": [0, 0.69444, 0, 0, 0.55], 2511 "50": [0, 0.69444, 0, 0, 0.55], 2512 "51": [0, 0.69444, 0, 0, 0.55], 2513 "52": [0, 0.69444, 0, 0, 0.55], 2514 "53": [0, 0.69444, 0, 0, 0.55], 2515 "54": [0, 0.69444, 0, 0, 0.55], 2516 "55": [0, 0.69444, 0, 0, 0.55], 2517 "56": [0, 0.69444, 0, 0, 0.55], 2518 "57": [0, 0.69444, 0, 0, 0.55], 2519 "58": [0, 0.45833, 0, 0, 0.30556], 2520 "59": [0.10556, 0.45833, 0, 0, 0.30556], 2521 "61": [-0.09375, 0.40625, 0, 0, 0.85556], 2522 "63": [0, 0.69444, 0, 0, 0.51945], 2523 "64": [0, 0.69444, 0, 0, 0.73334], 2524 "65": [0, 0.69444, 0, 0, 0.73334], 2525 "66": [0, 0.69444, 0, 0, 0.73334], 2526 "67": [0, 0.69444, 0, 0, 0.70278], 2527 "68": [0, 0.69444, 0, 0, 0.79445], 2528 "69": [0, 0.69444, 0, 0, 0.64167], 2529 "70": [0, 0.69444, 0, 0, 0.61111], 2530 "71": [0, 0.69444, 0, 0, 0.73334], 2531 "72": [0, 0.69444, 0, 0, 0.79445], 2532 "73": [0, 0.69444, 0, 0, 0.33056], 2533 "74": [0, 0.69444, 0, 0, 0.51945], 2534 "75": [0, 0.69444, 0, 0, 0.76389], 2535 "76": [0, 0.69444, 0, 0, 0.58056], 2536 "77": [0, 0.69444, 0, 0, 0.97778], 2537 "78": [0, 0.69444, 0, 0, 0.79445], 2538 "79": [0, 0.69444, 0, 0, 0.79445], 2539 "80": [0, 0.69444, 0, 0, 0.70278], 2540 "81": [0.10556, 0.69444, 0, 0, 0.79445], 2541 "82": [0, 0.69444, 0, 0, 0.70278], 2542 "83": [0, 0.69444, 0, 0, 0.61111], 2543 "84": [0, 0.69444, 0, 0, 0.73334], 2544 "85": [0, 0.69444, 0, 0, 0.76389], 2545 "86": [0, 0.69444, 0.01528, 0, 0.73334], 2546 "87": [0, 0.69444, 0.01528, 0, 1.03889], 2547 "88": [0, 0.69444, 0, 0, 0.73334], 2548 "89": [0, 0.69444, 0.0275, 0, 0.73334], 2549 "90": [0, 0.69444, 0, 0, 0.67223], 2550 "91": [0.25, 0.75, 0, 0, 0.34306], 2551 "93": [0.25, 0.75, 0, 0, 0.34306], 2552 "94": [0, 0.69444, 0, 0, 0.55], 2553 "95": [0.35, 0.10833, 0.03056, 0, 0.55], 2554 "97": [0, 0.45833, 0, 0, 0.525], 2555 "98": [0, 0.69444, 0, 0, 0.56111], 2556 "99": [0, 0.45833, 0, 0, 0.48889], 2557 "100": [0, 0.69444, 0, 0, 0.56111], 2558 "101": [0, 0.45833, 0, 0, 0.51111], 2559 "102": [0, 0.69444, 0.07639, 0, 0.33611], 2560 "103": [0.19444, 0.45833, 0.01528, 0, 0.55], 2561 "104": [0, 0.69444, 0, 0, 0.56111], 2562 "105": [0, 0.69444, 0, 0, 0.25556], 2563 "106": [0.19444, 0.69444, 0, 0, 0.28611], 2564 "107": [0, 0.69444, 0, 0, 0.53056], 2565 "108": [0, 0.69444, 0, 0, 0.25556], 2566 "109": [0, 0.45833, 0, 0, 0.86667], 2567 "110": [0, 0.45833, 0, 0, 0.56111], 2568 "111": [0, 0.45833, 0, 0, 0.55], 2569 "112": [0.19444, 0.45833, 0, 0, 0.56111], 2570 "113": [0.19444, 0.45833, 0, 0, 0.56111], 2571 "114": [0, 0.45833, 0.01528, 0, 0.37222], 2572 "115": [0, 0.45833, 0, 0, 0.42167], 2573 "116": [0, 0.58929, 0, 0, 0.40417], 2574 "117": [0, 0.45833, 0, 0, 0.56111], 2575 "118": [0, 0.45833, 0.01528, 0, 0.5], 2576 "119": [0, 0.45833, 0.01528, 0, 0.74445], 2577 "120": [0, 0.45833, 0, 0, 0.5], 2578 "121": [0.19444, 0.45833, 0.01528, 0, 0.5], 2579 "122": [0, 0.45833, 0, 0, 0.47639], 2580 "126": [0.35, 0.34444, 0, 0, 0.55], 2581 "160": [0, 0, 0, 0, 0.25], 2582 "168": [0, 0.69444, 0, 0, 0.55], 2583 "176": [0, 0.69444, 0, 0, 0.73334], 2584 "180": [0, 0.69444, 0, 0, 0.55], 2585 "184": [0.17014, 0, 0, 0, 0.48889], 2586 "305": [0, 0.45833, 0, 0, 0.25556], 2587 "567": [0.19444, 0.45833, 0, 0, 0.28611], 2588 "710": [0, 0.69444, 0, 0, 0.55], 2589 "711": [0, 0.63542, 0, 0, 0.55], 2590 "713": [0, 0.63778, 0, 0, 0.55], 2591 "728": [0, 0.69444, 0, 0, 0.55], 2592 "729": [0, 0.69444, 0, 0, 0.30556], 2593 "730": [0, 0.69444, 0, 0, 0.73334], 2594 "732": [0, 0.69444, 0, 0, 0.55], 2595 "733": [0, 0.69444, 0, 0, 0.55], 2596 "915": [0, 0.69444, 0, 0, 0.58056], 2597 "916": [0, 0.69444, 0, 0, 0.91667], 2598 "920": [0, 0.69444, 0, 0, 0.85556], 2599 "923": [0, 0.69444, 0, 0, 0.67223], 2600 "926": [0, 0.69444, 0, 0, 0.73334], 2601 "928": [0, 0.69444, 0, 0, 0.79445], 2602 "931": [0, 0.69444, 0, 0, 0.79445], 2603 "933": [0, 0.69444, 0, 0, 0.85556], 2604 "934": [0, 0.69444, 0, 0, 0.79445], 2605 "936": [0, 0.69444, 0, 0, 0.85556], 2606 "937": [0, 0.69444, 0, 0, 0.79445], 2607 "8211": [0, 0.45833, 0.03056, 0, 0.55], 2608 "8212": [0, 0.45833, 0.03056, 0, 1.10001], 2609 "8216": [0, 0.69444, 0, 0, 0.30556], 2610 "8217": [0, 0.69444, 0, 0, 0.30556], 2611 "8220": [0, 0.69444, 0, 0, 0.55834], 2612 "8221": [0, 0.69444, 0, 0, 0.55834] 2613 }, 2614 "SansSerif-Italic": { 2615 "32": [0, 0, 0, 0, 0.25], 2616 "33": [0, 0.69444, 0.05733, 0, 0.31945],
vendor: 17,727 bytes, lines 2617-3050
2617 "34": [0, 0.69444, 0.00316, 0, 0.5], 2618 "35": [0.19444, 0.69444, 0.05087, 0, 0.83334], 2619 "36": [0.05556, 0.75, 0.11156, 0, 0.5], 2620 "37": [0.05556, 0.75, 0.03126, 0, 0.83334], 2621 "38": [0, 0.69444, 0.03058, 0, 0.75834], 2622 "39": [0, 0.69444, 0.07816, 0, 0.27778], 2623 "40": [0.25, 0.75, 0.13164, 0, 0.38889], 2624 "41": [0.25, 0.75, 0.02536, 0, 0.38889], 2625 "42": [0, 0.75, 0.11775, 0, 0.5], 2626 "43": [0.08333, 0.58333, 0.02536, 0, 0.77778], 2627 "44": [0.125, 0.08333, 0, 0, 0.27778], 2628 "45": [0, 0.44444, 0.01946, 0, 0.33333], 2629 "46": [0, 0.08333, 0, 0, 0.27778], 2630 "47": [0.25, 0.75, 0.13164, 0, 0.5], 2631 "48": [0, 0.65556, 0.11156, 0, 0.5], 2632 "49": [0, 0.65556, 0.11156, 0, 0.5], 2633 "50": [0, 0.65556, 0.11156, 0, 0.5], 2634 "51": [0, 0.65556, 0.11156, 0, 0.5], 2635 "52": [0, 0.65556, 0.11156, 0, 0.5], 2636 "53": [0, 0.65556, 0.11156, 0, 0.5], 2637 "54": [0, 0.65556, 0.11156, 0, 0.5], 2638 "55": [0, 0.65556, 0.11156, 0, 0.5], 2639 "56": [0, 0.65556, 0.11156, 0, 0.5], 2640 "57": [0, 0.65556, 0.11156, 0, 0.5], 2641 "58": [0, 0.44444, 0.02502, 0, 0.27778], 2642 "59": [0.125, 0.44444, 0.02502, 0, 0.27778], 2643 "61": [-0.13, 0.37, 0.05087, 0, 0.77778], 2644 "63": [0, 0.69444, 0.11809, 0, 0.47222], 2645 "64": [0, 0.69444, 0.07555, 0, 0.66667], 2646 "65": [0, 0.69444, 0, 0, 0.66667], 2647 "66": [0, 0.69444, 0.08293, 0, 0.66667], 2648 "67": [0, 0.69444, 0.11983, 0, 0.63889], 2649 "68": [0, 0.69444, 0.07555, 0, 0.72223], 2650 "69": [0, 0.69444, 0.11983, 0, 0.59722], 2651 "70": [0, 0.69444, 0.13372, 0, 0.56945], 2652 "71": [0, 0.69444, 0.11983, 0, 0.66667], 2653 "72": [0, 0.69444, 0.08094, 0, 0.70834], 2654 "73": [0, 0.69444, 0.13372, 0, 0.27778], 2655 "74": [0, 0.69444, 0.08094, 0, 0.47222], 2656 "75": [0, 0.69444, 0.11983, 0, 0.69445], 2657 "76": [0, 0.69444, 0, 0, 0.54167], 2658 "77": [0, 0.69444, 0.08094, 0, 0.875], 2659 "78": [0, 0.69444, 0.08094, 0, 0.70834], 2660 "79": [0, 0.69444, 0.07555, 0, 0.73611], 2661 "80": [0, 0.69444, 0.08293, 0, 0.63889], 2662 "81": [0.125, 0.69444, 0.07555, 0, 0.73611], 2663 "82": [0, 0.69444, 0.08293, 0, 0.64584], 2664 "83": [0, 0.69444, 0.09205, 0, 0.55556], 2665 "84": [0, 0.69444, 0.13372, 0, 0.68056], 2666 "85": [0, 0.69444, 0.08094, 0, 0.6875], 2667 "86": [0, 0.69444, 0.1615, 0, 0.66667], 2668 "87": [0, 0.69444, 0.1615, 0, 0.94445], 2669 "88": [0, 0.69444, 0.13372, 0, 0.66667], 2670 "89": [0, 0.69444, 0.17261, 0, 0.66667], 2671 "90": [0, 0.69444, 0.11983, 0, 0.61111], 2672 "91": [0.25, 0.75, 0.15942, 0, 0.28889], 2673 "93": [0.25, 0.75, 0.08719, 0, 0.28889], 2674 "94": [0, 0.69444, 0.0799, 0, 0.5], 2675 "95": [0.35, 0.09444, 0.08616, 0, 0.5], 2676 "97": [0, 0.44444, 0.00981, 0, 0.48056], 2677 "98": [0, 0.69444, 0.03057, 0, 0.51667], 2678 "99": [0, 0.44444, 0.08336, 0, 0.44445], 2679 "100": [0, 0.69444, 0.09483, 0, 0.51667], 2680 "101": [0, 0.44444, 0.06778, 0, 0.44445], 2681 "102": [0, 0.69444, 0.21705, 0, 0.30556], 2682 "103": [0.19444, 0.44444, 0.10836, 0, 0.5], 2683 "104": [0, 0.69444, 0.01778, 0, 0.51667], 2684 "105": [0, 0.67937, 0.09718, 0, 0.23889], 2685 "106": [0.19444, 0.67937, 0.09162, 0, 0.26667], 2686 "107": [0, 0.69444, 0.08336, 0, 0.48889], 2687 "108": [0, 0.69444, 0.09483, 0, 0.23889], 2688 "109": [0, 0.44444, 0.01778, 0, 0.79445], 2689 "110": [0, 0.44444, 0.01778, 0, 0.51667], 2690 "111": [0, 0.44444, 0.06613, 0, 0.5], 2691 "112": [0.19444, 0.44444, 0.0389, 0, 0.51667], 2692 "113": [0.19444, 0.44444, 0.04169, 0, 0.51667], 2693 "114": [0, 0.44444, 0.10836, 0, 0.34167], 2694 "115": [0, 0.44444, 0.0778, 0, 0.38333], 2695 "116": [0, 0.57143, 0.07225, 0, 0.36111], 2696 "117": [0, 0.44444, 0.04169, 0, 0.51667], 2697 "118": [0, 0.44444, 0.10836, 0, 0.46111], 2698 "119": [0, 0.44444, 0.10836, 0, 0.68334], 2699 "120": [0, 0.44444, 0.09169, 0, 0.46111], 2700 "121": [0.19444, 0.44444, 0.10836, 0, 0.46111], 2701 "122": [0, 0.44444, 0.08752, 0, 0.43472], 2702 "126": [0.35, 0.32659, 0.08826, 0, 0.5], 2703 "160": [0, 0, 0, 0, 0.25], 2704 "168": [0, 0.67937, 0.06385, 0, 0.5], 2705 "176": [0, 0.69444, 0, 0, 0.73752], 2706 "184": [0.17014, 0, 0, 0, 0.44445], 2707 "305": [0, 0.44444, 0.04169, 0, 0.23889], 2708 "567": [0.19444, 0.44444, 0.04169, 0, 0.26667], 2709 "710": [0, 0.69444, 0.0799, 0, 0.5], 2710 "711": [0, 0.63194, 0.08432, 0, 0.5], 2711 "713": [0, 0.60889, 0.08776, 0, 0.5], 2712 "714": [0, 0.69444, 0.09205, 0, 0.5], 2713 "715": [0, 0.69444, 0, 0, 0.5], 2714 "728": [0, 0.69444, 0.09483, 0, 0.5], 2715 "729": [0, 0.67937, 0.07774, 0, 0.27778], 2716 "730": [0, 0.69444, 0, 0, 0.73752], 2717 "732": [0, 0.67659, 0.08826, 0, 0.5], 2718 "733": [0, 0.69444, 0.09205, 0, 0.5], 2719 "915": [0, 0.69444, 0.13372, 0, 0.54167], 2720 "916": [0, 0.69444, 0, 0, 0.83334], 2721 "920": [0, 0.69444, 0.07555, 0, 0.77778], 2722 "923": [0, 0.69444, 0, 0, 0.61111], 2723 "926": [0, 0.69444, 0.12816, 0, 0.66667], 2724 "928": [0, 0.69444, 0.08094, 0, 0.70834], 2725 "931": [0, 0.69444, 0.11983, 0, 0.72222], 2726 "933": [0, 0.69444, 0.09031, 0, 0.77778], 2727 "934": [0, 0.69444, 0.04603, 0, 0.72222], 2728 "936": [0, 0.69444, 0.09031, 0, 0.77778], 2729 "937": [0, 0.69444, 0.08293, 0, 0.72222], 2730 "8211": [0, 0.44444, 0.08616, 0, 0.5], 2731 "8212": [0, 0.44444, 0.08616, 0, 1.0], 2732 "8216": [0, 0.69444, 0.07816, 0, 0.27778], 2733 "8217": [0, 0.69444, 0.07816, 0, 0.27778], 2734 "8220": [0, 0.69444, 0.14205, 0, 0.5], 2735 "8221": [0, 0.69444, 0.00316, 0, 0.5] 2736 }, 2737 "SansSerif-Regular": { 2738 "32": [0, 0, 0, 0, 0.25], 2739 "33": [0, 0.69444, 0, 0, 0.31945], 2740 "34": [0, 0.69444, 0, 0, 0.5], 2741 "35": [0.19444, 0.69444, 0, 0, 0.83334], 2742 "36": [0.05556, 0.75, 0, 0, 0.5], 2743 "37": [0.05556, 0.75, 0, 0, 0.83334], 2744 "38": [0, 0.69444, 0, 0, 0.75834], 2745 "39": [0, 0.69444, 0, 0, 0.27778], 2746 "40": [0.25, 0.75, 0, 0, 0.38889], 2747 "41": [0.25, 0.75, 0, 0, 0.38889], 2748 "42": [0, 0.75, 0, 0, 0.5], 2749 "43": [0.08333, 0.58333, 0, 0, 0.77778], 2750 "44": [0.125, 0.08333, 0, 0, 0.27778], 2751 "45": [0, 0.44444, 0, 0, 0.33333], 2752 "46": [0, 0.08333, 0, 0, 0.27778], 2753 "47": [0.25, 0.75, 0, 0, 0.5], 2754 "48": [0, 0.65556, 0, 0, 0.5], 2755 "49": [0, 0.65556, 0, 0, 0.5], 2756 "50": [0, 0.65556, 0, 0, 0.5], 2757 "51": [0, 0.65556, 0, 0, 0.5], 2758 "52": [0, 0.65556, 0, 0, 0.5], 2759 "53": [0, 0.65556, 0, 0, 0.5], 2760 "54": [0, 0.65556, 0, 0, 0.5], 2761 "55": [0, 0.65556, 0, 0, 0.5], 2762 "56": [0, 0.65556, 0, 0, 0.5], 2763 "57": [0, 0.65556, 0, 0, 0.5], 2764 "58": [0, 0.44444, 0, 0, 0.27778], 2765 "59": [0.125, 0.44444, 0, 0, 0.27778], 2766 "61": [-0.13, 0.37, 0, 0, 0.77778], 2767 "63": [0, 0.69444, 0, 0, 0.47222], 2768 "64": [0, 0.69444, 0, 0, 0.66667], 2769 "65": [0, 0.69444, 0, 0, 0.66667], 2770 "66": [0, 0.69444, 0, 0, 0.66667], 2771 "67": [0, 0.69444, 0, 0, 0.63889], 2772 "68": [0, 0.69444, 0, 0, 0.72223], 2773 "69": [0, 0.69444, 0, 0, 0.59722], 2774 "70": [0, 0.69444, 0, 0, 0.56945], 2775 "71": [0, 0.69444, 0, 0, 0.66667], 2776 "72": [0, 0.69444, 0, 0, 0.70834], 2777 "73": [0, 0.69444, 0, 0, 0.27778], 2778 "74": [0, 0.69444, 0, 0, 0.47222], 2779 "75": [0, 0.69444, 0, 0, 0.69445], 2780 "76": [0, 0.69444, 0, 0, 0.54167], 2781 "77": [0, 0.69444, 0, 0, 0.875], 2782 "78": [0, 0.69444, 0, 0, 0.70834], 2783 "79": [0, 0.69444, 0, 0, 0.73611], 2784 "80": [0, 0.69444, 0, 0, 0.63889], 2785 "81": [0.125, 0.69444, 0, 0, 0.73611], 2786 "82": [0, 0.69444, 0, 0, 0.64584], 2787 "83": [0, 0.69444, 0, 0, 0.55556], 2788 "84": [0, 0.69444, 0, 0, 0.68056], 2789 "85": [0, 0.69444, 0, 0, 0.6875], 2790 "86": [0, 0.69444, 0.01389, 0, 0.66667], 2791 "87": [0, 0.69444, 0.01389, 0, 0.94445], 2792 "88": [0, 0.69444, 0, 0, 0.66667], 2793 "89": [0, 0.69444, 0.025, 0, 0.66667], 2794 "90": [0, 0.69444, 0, 0, 0.61111], 2795 "91": [0.25, 0.75, 0, 0, 0.28889], 2796 "93": [0.25, 0.75, 0, 0, 0.28889], 2797 "94": [0, 0.69444, 0, 0, 0.5], 2798 "95": [0.35, 0.09444, 0.02778, 0, 0.5], 2799 "97": [0, 0.44444, 0, 0, 0.48056], 2800 "98": [0, 0.69444, 0, 0, 0.51667], 2801 "99": [0, 0.44444, 0, 0, 0.44445], 2802 "100": [0, 0.69444, 0, 0, 0.51667], 2803 "101": [0, 0.44444, 0, 0, 0.44445], 2804 "102": [0, 0.69444, 0.06944, 0, 0.30556], 2805 "103": [0.19444, 0.44444, 0.01389, 0, 0.5], 2806 "104": [0, 0.69444, 0, 0, 0.51667], 2807 "105": [0, 0.67937, 0, 0, 0.23889], 2808 "106": [0.19444, 0.67937, 0, 0, 0.26667], 2809 "107": [0, 0.69444, 0, 0, 0.48889], 2810 "108": [0, 0.69444, 0, 0, 0.23889], 2811 "109": [0, 0.44444, 0, 0, 0.79445], 2812 "110": [0, 0.44444, 0, 0, 0.51667], 2813 "111": [0, 0.44444, 0, 0, 0.5], 2814 "112": [0.19444, 0.44444, 0, 0, 0.51667], 2815 "113": [0.19444, 0.44444, 0, 0, 0.51667], 2816 "114": [0, 0.44444, 0.01389, 0, 0.34167], 2817 "115": [0, 0.44444, 0, 0, 0.38333], 2818 "116": [0, 0.57143, 0, 0, 0.36111], 2819 "117": [0, 0.44444, 0, 0, 0.51667], 2820 "118": [0, 0.44444, 0.01389, 0, 0.46111], 2821 "119": [0, 0.44444, 0.01389, 0, 0.68334], 2822 "120": [0, 0.44444, 0, 0, 0.46111], 2823 "121": [0.19444, 0.44444, 0.01389, 0, 0.46111], 2824 "122": [0, 0.44444, 0, 0, 0.43472], 2825 "126": [0.35, 0.32659, 0, 0, 0.5], 2826 "160": [0, 0, 0, 0, 0.25], 2827 "168": [0, 0.67937, 0, 0, 0.5], 2828 "176": [0, 0.69444, 0, 0, 0.66667], 2829 "184": [0.17014, 0, 0, 0, 0.44445], 2830 "305": [0, 0.44444, 0, 0, 0.23889], 2831 "567": [0.19444, 0.44444, 0, 0, 0.26667], 2832 "710": [0, 0.69444, 0, 0, 0.5], 2833 "711": [0, 0.63194, 0, 0, 0.5], 2834 "713": [0, 0.60889, 0, 0, 0.5], 2835 "714": [0, 0.69444, 0, 0, 0.5], 2836 "715": [0, 0.69444, 0, 0, 0.5], 2837 "728": [0, 0.69444, 0, 0, 0.5], 2838 "729": [0, 0.67937, 0, 0, 0.27778], 2839 "730": [0, 0.69444, 0, 0, 0.66667], 2840 "732": [0, 0.67659, 0, 0, 0.5], 2841 "733": [0, 0.69444, 0, 0, 0.5], 2842 "915": [0, 0.69444, 0, 0, 0.54167], 2843 "916": [0, 0.69444, 0, 0, 0.83334], 2844 "920": [0, 0.69444, 0, 0, 0.77778], 2845 "923": [0, 0.69444, 0, 0, 0.61111], 2846 "926": [0, 0.69444, 0, 0, 0.66667], 2847 "928": [0, 0.69444, 0, 0, 0.70834], 2848 "931": [0, 0.69444, 0, 0, 0.72222], 2849 "933": [0, 0.69444, 0, 0, 0.77778], 2850 "934": [0, 0.69444, 0, 0, 0.72222], 2851 "936": [0, 0.69444, 0, 0, 0.77778], 2852 "937": [0, 0.69444, 0, 0, 0.72222], 2853 "8211": [0, 0.44444, 0.02778, 0, 0.5], 2854 "8212": [0, 0.44444, 0.02778, 0, 1.0], 2855 "8216": [0, 0.69444, 0, 0, 0.27778], 2856 "8217": [0, 0.69444, 0, 0, 0.27778], 2857 "8220": [0, 0.69444, 0, 0, 0.5], 2858 "8221": [0, 0.69444, 0, 0, 0.5] 2859 }, 2860 "Script-Regular": { 2861 "32": [0, 0, 0, 0, 0.25], 2862 "65": [0, 0.7, 0.22925, 0, 0.80253], 2863 "66": [0, 0.7, 0.04087, 0, 0.90757], 2864 "67": [0, 0.7, 0.1689, 0, 0.66619], 2865 "68": [0, 0.7, 0.09371, 0, 0.77443], 2866 "69": [0, 0.7, 0.18583, 0, 0.56162], 2867 "70": [0, 0.7, 0.13634, 0, 0.89544], 2868 "71": [0, 0.7, 0.17322, 0, 0.60961], 2869 "72": [0, 0.7, 0.29694, 0, 0.96919], 2870 "73": [0, 0.7, 0.19189, 0, 0.80907], 2871 "74": [0.27778, 0.7, 0.19189, 0, 1.05159], 2872 "75": [0, 0.7, 0.31259, 0, 0.91364], 2873 "76": [0, 0.7, 0.19189, 0, 0.87373], 2874 "77": [0, 0.7, 0.15981, 0, 1.08031], 2875 "78": [0, 0.7, 0.3525, 0, 0.9015], 2876 "79": [0, 0.7, 0.08078, 0, 0.73787], 2877 "80": [0, 0.7, 0.08078, 0, 1.01262], 2878 "81": [0, 0.7, 0.03305, 0, 0.88282], 2879 "82": [0, 0.7, 0.06259, 0, 0.85], 2880 "83": [0, 0.7, 0.19189, 0, 0.86767], 2881 "84": [0, 0.7, 0.29087, 0, 0.74697], 2882 "85": [0, 0.7, 0.25815, 0, 0.79996], 2883 "86": [0, 0.7, 0.27523, 0, 0.62204], 2884 "87": [0, 0.7, 0.27523, 0, 0.80532], 2885 "88": [0, 0.7, 0.26006, 0, 0.94445], 2886 "89": [0, 0.7, 0.2939, 0, 0.70961], 2887 "90": [0, 0.7, 0.24037, 0, 0.8212], 2888 "160": [0, 0, 0, 0, 0.25] 2889 }, 2890 "Size1-Regular": { 2891 "32": [0, 0, 0, 0, 0.25], 2892 "40": [0.35001, 0.85, 0, 0, 0.45834], 2893 "41": [0.35001, 0.85, 0, 0, 0.45834], 2894 "47": [0.35001, 0.85, 0, 0, 0.57778], 2895 "91": [0.35001, 0.85, 0, 0, 0.41667], 2896 "92": [0.35001, 0.85, 0, 0, 0.57778], 2897 "93": [0.35001, 0.85, 0, 0, 0.41667], 2898 "123": [0.35001, 0.85, 0, 0, 0.58334], 2899 "125": [0.35001, 0.85, 0, 0, 0.58334], 2900 "160": [0, 0, 0, 0, 0.25], 2901 "710": [0, 0.72222, 0, 0, 0.55556], 2902 "732": [0, 0.72222, 0, 0, 0.55556], 2903 "770": [0, 0.72222, 0, 0, 0.55556], 2904 "771": [0, 0.72222, 0, 0, 0.55556], 2905 "8214": [-0.00099, 0.601, 0, 0, 0.77778], 2906 "8593": [1e-05, 0.6, 0, 0, 0.66667], 2907 "8595": [1e-05, 0.6, 0, 0, 0.66667], 2908 "8657": [1e-05, 0.6, 0, 0, 0.77778], 2909 "8659": [1e-05, 0.6, 0, 0, 0.77778], 2910 "8719": [0.25001, 0.75, 0, 0, 0.94445], 2911 "8720": [0.25001, 0.75, 0, 0, 0.94445], 2912 "8721": [0.25001, 0.75, 0, 0, 1.05556], 2913 "8730": [0.35001, 0.85, 0, 0, 1.0], 2914 "8739": [-0.00599, 0.606, 0, 0, 0.33333], 2915 "8741": [-0.00599, 0.606, 0, 0, 0.55556], 2916 "8747": [0.30612, 0.805, 0.19445, 0, 0.47222], 2917 "8748": [0.306, 0.805, 0.19445, 0, 0.47222], 2918 "8749": [0.306, 0.805, 0.19445, 0, 0.47222], 2919 "8750": [0.30612, 0.805, 0.19445, 0, 0.47222], 2920 "8896": [0.25001, 0.75, 0, 0, 0.83334], 2921 "8897": [0.25001, 0.75, 0, 0, 0.83334], 2922 "8898": [0.25001, 0.75, 0, 0, 0.83334], 2923 "8899": [0.25001, 0.75, 0, 0, 0.83334], 2924 "8968": [0.35001, 0.85, 0, 0, 0.47222], 2925 "8969": [0.35001, 0.85, 0, 0, 0.47222], 2926 "8970": [0.35001, 0.85, 0, 0, 0.47222], 2927 "8971": [0.35001, 0.85, 0, 0, 0.47222], 2928 "9168": [-0.00099, 0.601, 0, 0, 0.66667], 2929 "10216": [0.35001, 0.85, 0, 0, 0.47222], 2930 "10217": [0.35001, 0.85, 0, 0, 0.47222], 2931 "10752": [0.25001, 0.75, 0, 0, 1.11111], 2932 "10753": [0.25001, 0.75, 0, 0, 1.11111], 2933 "10754": [0.25001, 0.75, 0, 0, 1.11111], 2934 "10756": [0.25001, 0.75, 0, 0, 0.83334], 2935 "10758": [0.25001, 0.75, 0, 0, 0.83334] 2936 }, 2937 "Size2-Regular": { 2938 "32": [0, 0, 0, 0, 0.25], 2939 "40": [0.65002, 1.15, 0, 0, 0.59722], 2940 "41": [0.65002, 1.15, 0, 0, 0.59722], 2941 "47": [0.65002, 1.15, 0, 0, 0.81111], 2942 "91": [0.65002, 1.15, 0, 0, 0.47222], 2943 "92": [0.65002, 1.15, 0, 0, 0.81111], 2944 "93": [0.65002, 1.15, 0, 0, 0.47222], 2945 "123": [0.65002, 1.15, 0, 0, 0.66667], 2946 "125": [0.65002, 1.15, 0, 0, 0.66667], 2947 "160": [0, 0, 0, 0, 0.25], 2948 "710": [0, 0.75, 0, 0, 1.0], 2949 "732": [0, 0.75, 0, 0, 1.0], 2950 "770": [0, 0.75, 0, 0, 1.0], 2951 "771": [0, 0.75, 0, 0, 1.0], 2952 "8719": [0.55001, 1.05, 0, 0, 1.27778], 2953 "8720": [0.55001, 1.05, 0, 0, 1.27778], 2954 "8721": [0.55001, 1.05, 0, 0, 1.44445], 2955 "8730": [0.65002, 1.15, 0, 0, 1.0], 2956 "8747": [0.86225, 1.36, 0.44445, 0, 0.55556], 2957 "8748": [0.862, 1.36, 0.44445, 0, 0.55556], 2958 "8749": [0.862, 1.36, 0.44445, 0, 0.55556], 2959 "8750": [0.86225, 1.36, 0.44445, 0, 0.55556], 2960 "8896": [0.55001, 1.05, 0, 0, 1.11111], 2961 "8897": [0.55001, 1.05, 0, 0, 1.11111], 2962 "8898": [0.55001, 1.05, 0, 0, 1.11111], 2963 "8899": [0.55001, 1.05, 0, 0, 1.11111], 2964 "8968": [0.65002, 1.15, 0, 0, 0.52778], 2965 "8969": [0.65002, 1.15, 0, 0, 0.52778], 2966 "8970": [0.65002, 1.15, 0, 0, 0.52778], 2967 "8971": [0.65002, 1.15, 0, 0, 0.52778], 2968 "10216": [0.65002, 1.15, 0, 0, 0.61111], 2969 "10217": [0.65002, 1.15, 0, 0, 0.61111], 2970 "10752": [0.55001, 1.05, 0, 0, 1.51112], 2971 "10753": [0.55001, 1.05, 0, 0, 1.51112], 2972 "10754": [0.55001, 1.05, 0, 0, 1.51112], 2973 "10756": [0.55001, 1.05, 0, 0, 1.11111], 2974 "10758": [0.55001, 1.05, 0, 0, 1.11111] 2975 }, 2976 "Size3-Regular": { 2977 "32": [0, 0, 0, 0, 0.25], 2978 "40": [0.95003, 1.45, 0, 0, 0.73611], 2979 "41": [0.95003, 1.45, 0, 0, 0.73611], 2980 "47": [0.95003, 1.45, 0, 0, 1.04445], 2981 "91": [0.95003, 1.45, 0, 0, 0.52778], 2982 "92": [0.95003, 1.45, 0, 0, 1.04445], 2983 "93": [0.95003, 1.45, 0, 0, 0.52778], 2984 "123": [0.95003, 1.45, 0, 0, 0.75], 2985 "125": [0.95003, 1.45, 0, 0, 0.75], 2986 "160": [0, 0, 0, 0, 0.25], 2987 "710": [0, 0.75, 0, 0, 1.44445], 2988 "732": [0, 0.75, 0, 0, 1.44445], 2989 "770": [0, 0.75, 0, 0, 1.44445], 2990 "771": [0, 0.75, 0, 0, 1.44445], 2991 "8730": [0.95003, 1.45, 0, 0, 1.0], 2992 "8968": [0.95003, 1.45, 0, 0, 0.58334], 2993 "8969": [0.95003, 1.45, 0, 0, 0.58334], 2994 "8970": [0.95003, 1.45, 0, 0, 0.58334], 2995 "8971": [0.95003, 1.45, 0, 0, 0.58334], 2996 "10216": [0.95003, 1.45, 0, 0, 0.75], 2997 "10217": [0.95003, 1.45, 0, 0, 0.75] 2998 }, 2999 "Size4-Regular": { 3000 "32": [0, 0, 0, 0, 0.25], 3001 "40": [1.25003, 1.75, 0, 0, 0.79167], 3002 "41": [1.25003, 1.75, 0, 0, 0.79167], 3003 "47": [1.25003, 1.75, 0, 0, 1.27778], 3004 "91": [1.25003, 1.75, 0, 0, 0.58334], 3005 "92": [1.25003, 1.75, 0, 0, 1.27778], 3006 "93": [1.25003, 1.75, 0, 0, 0.58334], 3007 "123": [1.25003, 1.75, 0, 0, 0.80556], 3008 "125": [1.25003, 1.75, 0, 0, 0.80556], 3009 "160": [0, 0, 0, 0, 0.25], 3010 "710": [0, 0.825, 0, 0, 1.8889], 3011 "732": [0, 0.825, 0, 0, 1.8889], 3012 "770": [0, 0.825, 0, 0, 1.8889], 3013 "771": [0, 0.825, 0, 0, 1.8889], 3014 "8730": [1.25003, 1.75, 0, 0, 1.0], 3015 "8968": [1.25003, 1.75, 0, 0, 0.63889], 3016 "8969": [1.25003, 1.75, 0, 0, 0.63889], 3017 "8970": [1.25003, 1.75, 0, 0, 0.63889], 3018 "8971": [1.25003, 1.75, 0, 0, 0.63889], 3019 "9115": [0.64502, 1.155, 0, 0, 0.875], 3020 "9116": [1e-05, 0.6, 0, 0, 0.875], 3021 "9117": [0.64502, 1.155, 0, 0, 0.875], 3022 "9118": [0.64502, 1.155, 0, 0, 0.875], 3023 "9119": [1e-05, 0.6, 0, 0, 0.875], 3024 "9120": [0.64502, 1.155, 0, 0, 0.875], 3025 "9121": [0.64502, 1.155, 0, 0, 0.66667], 3026 "9122": [-0.00099, 0.601, 0, 0, 0.66667], 3027 "9123": [0.64502, 1.155, 0, 0, 0.66667], 3028 "9124": [0.64502, 1.155, 0, 0, 0.66667], 3029 "9125": [-0.00099, 0.601, 0, 0, 0.66667], 3030 "9126": [0.64502, 1.155, 0, 0, 0.66667], 3031 "9127": [1e-05, 0.9, 0, 0, 0.88889], 3032 "9128": [0.65002, 1.15, 0, 0, 0.88889], 3033 "9129": [0.90001, 0, 0, 0, 0.88889], 3034 "9130": [0, 0.3, 0, 0, 0.88889], 3035 "9131": [1e-05, 0.9, 0, 0, 0.88889], 3036 "9132": [0.65002, 1.15, 0, 0, 0.88889], 3037 "9133": [0.90001, 0, 0, 0, 0.88889], 3038 "9143": [0.88502, 0.915, 0, 0, 1.05556], 3039 "10216": [1.25003, 1.75, 0, 0, 0.80556], 3040 "10217": [1.25003, 1.75, 0, 0, 0.80556], 3041 "57344": [-0.00499, 0.605, 0, 0, 1.05556], 3042 "57345": [-0.00499, 0.605, 0, 0, 1.05556], 3043 "57680": [0, 0.12, 0, 0, 0.45], 3044 "57681": [0, 0.12, 0, 0, 0.45], 3045 "57682": [0, 0.12, 0, 0, 0.45], 3046 "57683": [0, 0.12, 0, 0, 0.45] 3047 }, 3048 "Typewriter-Regular": { 3049 "32": [0, 0, 0, 0, 0.525], 3050 "33": [0, 0.61111, 0, 0, 0.525],
vendor: 4,769 bytes, lines 3051-3175
3051 "34": [0, 0.61111, 0, 0, 0.525], 3052 "35": [0, 0.61111, 0, 0, 0.525], 3053 "36": [0.08333, 0.69444, 0, 0, 0.525], 3054 "37": [0.08333, 0.69444, 0, 0, 0.525], 3055 "38": [0, 0.61111, 0, 0, 0.525], 3056 "39": [0, 0.61111, 0, 0, 0.525], 3057 "40": [0.08333, 0.69444, 0, 0, 0.525], 3058 "41": [0.08333, 0.69444, 0, 0, 0.525], 3059 "42": [0, 0.52083, 0, 0, 0.525], 3060 "43": [-0.08056, 0.53055, 0, 0, 0.525], 3061 "44": [0.13889, 0.125, 0, 0, 0.525], 3062 "45": [-0.08056, 0.53055, 0, 0, 0.525], 3063 "46": [0, 0.125, 0, 0, 0.525], 3064 "47": [0.08333, 0.69444, 0, 0, 0.525], 3065 "48": [0, 0.61111, 0, 0, 0.525], 3066 "49": [0, 0.61111, 0, 0, 0.525], 3067 "50": [0, 0.61111, 0, 0, 0.525], 3068 "51": [0, 0.61111, 0, 0, 0.525], 3069 "52": [0, 0.61111, 0, 0, 0.525], 3070 "53": [0, 0.61111, 0, 0, 0.525], 3071 "54": [0, 0.61111, 0, 0, 0.525], 3072 "55": [0, 0.61111, 0, 0, 0.525], 3073 "56": [0, 0.61111, 0, 0, 0.525], 3074 "57": [0, 0.61111, 0, 0, 0.525], 3075 "58": [0, 0.43056, 0, 0, 0.525], 3076 "59": [0.13889, 0.43056, 0, 0, 0.525], 3077 "60": [-0.05556, 0.55556, 0, 0, 0.525], 3078 "61": [-0.19549, 0.41562, 0, 0, 0.525], 3079 "62": [-0.05556, 0.55556, 0, 0, 0.525], 3080 "63": [0, 0.61111, 0, 0, 0.525], 3081 "64": [0, 0.61111, 0, 0, 0.525], 3082 "65": [0, 0.61111, 0, 0, 0.525], 3083 "66": [0, 0.61111, 0, 0, 0.525], 3084 "67": [0, 0.61111, 0, 0, 0.525], 3085 "68": [0, 0.61111, 0, 0, 0.525], 3086 "69": [0, 0.61111, 0, 0, 0.525], 3087 "70": [0, 0.61111, 0, 0, 0.525], 3088 "71": [0, 0.61111, 0, 0, 0.525], 3089 "72": [0, 0.61111, 0, 0, 0.525], 3090 "73": [0, 0.61111, 0, 0, 0.525], 3091 "74": [0, 0.61111, 0, 0, 0.525], 3092 "75": [0, 0.61111, 0, 0, 0.525], 3093 "76": [0, 0.61111, 0, 0, 0.525], 3094 "77": [0, 0.61111, 0, 0, 0.525], 3095 "78": [0, 0.61111, 0, 0, 0.525], 3096 "79": [0, 0.61111, 0, 0, 0.525], 3097 "80": [0, 0.61111, 0, 0, 0.525], 3098 "81": [0.13889, 0.61111, 0, 0, 0.525], 3099 "82": [0, 0.61111, 0, 0, 0.525], 3100 "83": [0, 0.61111, 0, 0, 0.525], 3101 "84": [0, 0.61111, 0, 0, 0.525], 3102 "85": [0, 0.61111, 0, 0, 0.525], 3103 "86": [0, 0.61111, 0, 0, 0.525], 3104 "87": [0, 0.61111, 0, 0, 0.525], 3105 "88": [0, 0.61111, 0, 0, 0.525], 3106 "89": [0, 0.61111, 0, 0, 0.525], 3107 "90": [0, 0.61111, 0, 0, 0.525], 3108 "91": [0.08333, 0.69444, 0, 0, 0.525], 3109 "92": [0.08333, 0.69444, 0, 0, 0.525], 3110 "93": [0.08333, 0.69444, 0, 0, 0.525], 3111 "94": [0, 0.61111, 0, 0, 0.525], 3112 "95": [0.09514, 0, 0, 0, 0.525], 3113 "96": [0, 0.61111, 0, 0, 0.525], 3114 "97": [0, 0.43056, 0, 0, 0.525], 3115 "98": [0, 0.61111, 0, 0, 0.525], 3116 "99": [0, 0.43056, 0, 0, 0.525], 3117 "100": [0, 0.61111, 0, 0, 0.525], 3118 "101": [0, 0.43056, 0, 0, 0.525], 3119 "102": [0, 0.61111, 0, 0, 0.525], 3120 "103": [0.22222, 0.43056, 0, 0, 0.525], 3121 "104": [0, 0.61111, 0, 0, 0.525], 3122 "105": [0, 0.61111, 0, 0, 0.525], 3123 "106": [0.22222, 0.61111, 0, 0, 0.525], 3124 "107": [0, 0.61111, 0, 0, 0.525], 3125 "108": [0, 0.61111, 0, 0, 0.525], 3126 "109": [0, 0.43056, 0, 0, 0.525], 3127 "110": [0, 0.43056, 0, 0, 0.525], 3128 "111": [0, 0.43056, 0, 0, 0.525], 3129 "112": [0.22222, 0.43056, 0, 0, 0.525], 3130 "113": [0.22222, 0.43056, 0, 0, 0.525], 3131 "114": [0, 0.43056, 0, 0, 0.525], 3132 "115": [0, 0.43056, 0, 0, 0.525], 3133 "116": [0, 0.55358, 0, 0, 0.525], 3134 "117": [0, 0.43056, 0, 0, 0.525], 3135 "118": [0, 0.43056, 0, 0, 0.525], 3136 "119": [0, 0.43056, 0, 0, 0.525], 3137 "120": [0, 0.43056, 0, 0, 0.525], 3138 "121": [0.22222, 0.43056, 0, 0, 0.525], 3139 "122": [0, 0.43056, 0, 0, 0.525], 3140 "123": [0.08333, 0.69444, 0, 0, 0.525], 3141 "124": [0.08333, 0.69444, 0, 0, 0.525], 3142 "125": [0.08333, 0.69444, 0, 0, 0.525], 3143 "126": [0, 0.61111, 0, 0, 0.525], 3144 "127": [0, 0.61111, 0, 0, 0.525], 3145 "160": [0, 0, 0, 0, 0.525], 3146 "176": [0, 0.61111, 0, 0, 0.525], 3147 "184": [0.19445, 0, 0, 0, 0.525], 3148 "305": [0, 0.43056, 0, 0, 0.525], 3149 "567": [0.22222, 0.43056, 0, 0, 0.525], 3150 "711": [0, 0.56597, 0, 0, 0.525], 3151 "713": [0, 0.56555, 0, 0, 0.525], 3152 "714": [0, 0.61111, 0, 0, 0.525], 3153 "715": [0, 0.61111, 0, 0, 0.525], 3154 "728": [0, 0.61111, 0, 0, 0.525], 3155 "730": [0, 0.61111, 0, 0, 0.525], 3156 "770": [0, 0.61111, 0, 0, 0.525], 3157 "771": [0, 0.61111, 0, 0, 0.525], 3158 "776": [0, 0.61111, 0, 0, 0.525], 3159 "915": [0, 0.61111, 0, 0, 0.525], 3160 "916": [0, 0.61111, 0, 0, 0.525], 3161 "920": [0, 0.61111, 0, 0, 0.525], 3162 "923": [0, 0.61111, 0, 0, 0.525], 3163 "926": [0, 0.61111, 0, 0, 0.525], 3164 "928": [0, 0.61111, 0, 0, 0.525], 3165 "931": [0, 0.61111, 0, 0, 0.525], 3166 "933": [0, 0.61111, 0, 0, 0.525], 3167 "934": [0, 0.61111, 0, 0, 0.525], 3168 "936": [0, 0.61111, 0, 0, 0.525], 3169 "937": [0, 0.61111, 0, 0, 0.525], 3170 "8216": [0, 0.61111, 0, 0, 0.525], 3171 "8217": [0, 0.61111, 0, 0, 0.525], 3172 "8242": [0, 0.61111, 0, 0, 0.525], 3173 "9251": [0.11111, 0.21944, 0, 0, 0.525] 3174 } 3175};
3176 3177/** 3178 * This file contains metrics regarding fonts and individual symbols. The sigma 3179 * and xi variables, as well as the metricMap map contain data extracted from 3180 * TeX, TeX font metrics, and the TTF files. These data are then exposed via the 3181 * `metrics` variable and the getCharacterMetrics function. 3182 */ 3183// In TeX, there are actually three sets of dimensions, one for each of 3184// textstyle (size index 5 and higher: >=9pt), scriptstyle (size index 3 and 4: 3185// 7-8pt), and scriptscriptstyle (size index 1 and 2: 5-6pt). These are 3186// provided in the arrays below, in that order. 3187// 3188// The font metrics are stored in fonts cmsy10, cmsy7, and cmsy5 respectively. 3189// This was determined by running the following script: 3190// 3191// latex -interaction=nonstopmode \ 3192// '\documentclass{article}\usepackage{amsmath}\begin{document}' \ 3193// '$a$ \expandafter\show\the\textfont2' \ 3194// '\expandafter\show\the\scriptfont2' \ 3195// '\expandafter\show\the\scriptscriptfont2' \ 3196// '\stop' 3197// 3198// The metrics themselves were retrieved using the following commands: 3199// 3200// tftopl cmsy10 3201// tftopl cmsy7 3202// tftopl cmsy5 3203// 3204// The output of each of these commands is quite lengthy. The only part we 3205// care about is the FONTDIMEN section. Each value is measured in EMs. 3206var sigmasAndXis = { 3207 slant: [0.250, 0.250, 0.250], 3208 // sigma1 3209 space: [0.000, 0.000, 0.000], 3210 // sigma2 3211 stretch: [0.000, 0.000, 0.000], 3212 // sigma3 3213 shrink: [0.000, 0.000, 0.000], 3214 // sigma4 3215 xHeight: [0.431, 0.431, 0.431], 3216 // sigma5 3217 quad: [1.000, 1.171, 1.472], 3218 // sigma6 3219 extraSpace: [0.000, 0.000, 0.000], 3220 // sigma7 3221 num1: [0.677, 0.732, 0.925], 3222 // sigma8 3223 num2: [0.394, 0.384, 0.387], 3224 // sigma9 3225 num3: [0.444, 0.471, 0.504], 3226 // sigma10 3227 denom1: [0.686, 0.752, 1.025], 3228 // sigma11 3229 denom2: [0.345, 0.344, 0.532], 3230 // sigma12 3231 sup1: [0.413, 0.503, 0.504], 3232 // sigma13 3233 sup2: [0.363, 0.431, 0.404], 3234 // sigma14 3235 sup3: [0.289, 0.286, 0.294], 3236 // sigma15 3237 sub1: [0.150, 0.143, 0.200], 3238 // sigma16 3239 sub2: [0.247, 0.286, 0.400], 3240 // sigma17 3241 supDrop: [0.386, 0.353, 0.494], 3242 // sigma18 3243 subDrop: [0.050, 0.071, 0.100], 3244 // sigma19 3245 delim1: [2.390, 1.700, 1.980], 3246 // sigma20 3247 delim2: [1.010, 1.157, 1.420], 3248 // sigma21 3249 axisHeight: [0.250, 0.250, 0.250], 3250 // sigma22 3251 // These font metrics are extracted from TeX by using tftopl on cmex10.tfm; 3252 // they correspond to the font parameters of the extension fonts (family 3). 3253 // See the TeXbook, page 441. In AMSTeX, the extension fonts scale; to 3254 // match cmex7, we'd use cmex7.tfm values for script and scriptscript 3255 // values. 3256 defaultRuleThickness: [0.04, 0.049, 0.049], 3257 // xi8; cmex7: 0.049 3258 bigOpSpacing1: [0.111, 0.111, 0.111], 3259 // xi9 3260 bigOpSpacing2: [0.166, 0.166, 0.166], 3261 // xi10 3262 bigOpSpacing3: [0.2, 0.2, 0.2], 3263 // xi11 3264 bigOpSpacing4: [0.6, 0.611, 0.611], 3265 // xi12; cmex7: 0.611 3266 bigOpSpacing5: [0.1, 0.143, 0.143], 3267 // xi13; cmex7: 0.143 3268 // The \sqrt rule width is taken from the height of the surd character. 3269 // Since we use the same font at all sizes, this thickness doesn't scale. 3270 sqrtRuleThickness: [0.04, 0.04, 0.04], 3271 // This value determines how large a pt is, for metrics which are defined 3272 // in terms of pts. 3273 // This value is also used in katex.scss; if you change it make sure the 3274 // values match. 3275 ptPerEm: [10.0, 10.0, 10.0], 3276 // The space between adjacent `|` columns in an array definition. From 3277 // `\showthe\doublerulesep` in LaTeX. Equals 2.0 / ptPerEm. 3278 doubleRuleSep: [0.2, 0.2, 0.2], 3279 // The width of separator lines in {array} environments. From 3280 // `\showthe\arrayrulewidth` in LaTeX. Equals 0.4 / ptPerEm. 3281 arrayRuleWidth: [0.04, 0.04, 0.04], 3282 // Two values from LaTeX source2e: 3283 fboxsep: [0.3, 0.3, 0.3], 3284 // 3 pt / ptPerEm 3285 fboxrule: [0.04, 0.04, 0.04] // 0.4 pt / ptPerEm 3286 3287}; // This map contains a mapping from font name and character code to character
vendor: 4,607 bytes, lines 3288-3472
3288// should have Latin-1 and Cyrillic characters, but may not depending on the 3289// operating system. The metrics do not account for extra height from the 3290// accents. In the case of Cyrillic characters which have both ascenders and 3291// descenders we prefer approximations with ascenders, primarily to prevent 3292// the fraction bar or root line from intersecting the glyph. 3293// TODO(kevinb) allow union of multiple glyph metrics for better accuracy. 3294 3295var extraCharacterMap = { 3296 // Latin-1 3297 'à ': 'A', 3298 'Ã': 'D', 3299 'Ã': 'o', 3300 'Ã¥': 'a', 3301 'ð': 'd', 3302 'þ': 'o', 3303 // Cyrillic 3304 'Ð': 'A', 3305 'Ð': 'B', 3306 'Ð': 'B', 3307 'Ð': 'F', 3308 'Ð': 'A', 3309 'Ð': 'E', 3310 'Ð': 'K', 3311 'Ð': '3', 3312 'Ð': 'N', 3313 'Ð': 'N', 3314 'Ð': 'K', 3315 'Ð': 'N', 3316 'Ð': 'M', 3317 'Ð': 'H', 3318 'Ð': 'O', 3319 'Ð': 'N', 3320 'Ð ': 'P', 3321 'С': 'C', 3322 'Т': 'T', 3323 'У': 'y', 3324 'Ф': 'O', 3325 'Ð¥': 'X', 3326 'Ц': 'U', 3327 'Ч': 'h', 3328 'Ш': 'W', 3329 'Щ': 'W', 3330 'Ъ': 'B', 3331 'Ы': 'X', 3332 'Ь': 'B', 3333 'Ð': '3', 3334 'Ю': 'X', 3335 'Я': 'R', 3336 'а': 'a', 3337 'б': 'b', 3338 'в': 'a', 3339 'г': 'r', 3340 'д': 'y', 3341 'е': 'e', 3342 'ж': 'm', 3343 'з': 'e', 3344 'и': 'n', 3345 'й': 'n', 3346 'к': 'n', 3347 'л': 'n', 3348 'м': 'm', 3349 'н': 'n', 3350 'о': 'o', 3351 'п': 'n', 3352 'Ñ': 'p', 3353 'Ñ': 'c', 3354 'Ñ': 'o', 3355 'Ñ': 'y', 3356 'Ñ': 'b', 3357 'Ñ ': 'x', 3358 'Ñ': 'n', 3359 'Ñ': 'n', 3360 'Ñ': 'w', 3361 'Ñ': 'w', 3362 'Ñ': 'a', 3363 'Ñ': 'm', 3364 'Ñ': 'a', 3365 'Ñ': 'e', 3366 'Ñ': 'm', 3367 'Ñ': 'r' 3368}; 3369 3370/** 3371 * This function adds new font metrics to default metricMap 3372 * It can also override existing metrics 3373 */ 3374function setFontMetrics(fontName, metrics) { 3375 fontMetricsData[fontName] = metrics; 3376} 3377/** 3378 * This function is a convenience function for looking up information in the 3379 * metricMap table. It takes a character as a string, and a font. 3380 * 3381 * Note: the `width` property may be undefined if fontMetricsData.js wasn't 3382 * built using `Make extended_metrics`. 3383 */ 3384 3385function getCharacterMetrics(character, font, mode) { 3386 if (!fontMetricsData[font]) { 3387 throw new Error("Font metrics not found for font: " + font + "."); 3388 } 3389 3390 var ch = character.charCodeAt(0); 3391 var metrics = fontMetricsData[font][ch]; 3392 3393 if (!metrics && character[0] in extraCharacterMap) { 3394 ch = extraCharacterMap[character[0]].charCodeAt(0); 3395 metrics = fontMetricsData[font][ch]; 3396 } 3397 3398 if (!metrics && mode === 'text') { 3399 // We don't typically have font metrics for Asian scripts. 3400 // But since we support them in text mode, we need to return 3401 // some sort of metrics. 3402 // So if the character is in a script we support but we 3403 // don't have metrics for it, just use the metrics for 3404 // the Latin capital letter M. This is close enough because 3405 // we (currently) only care about the height of the glyph 3406 // not its width. 3407 if (supportedCodepoint(ch)) { 3408 metrics = fontMetricsData[font][77]; // 77 is the charcode for 'M' 3409 } 3410 } 3411 3412 if (metrics) { 3413 return { 3414 depth: metrics[0], 3415 height: metrics[1], 3416 italic: metrics[2], 3417 skew: metrics[3], 3418 width: metrics[4] 3419 }; 3420 } 3421} 3422var fontMetricsBySizeIndex = {}; 3423/** 3424 * Get the font metrics for a given size. 3425 */ 3426 3427function getGlobalMetrics(size) { 3428 var sizeIndex; 3429 3430 if (size >= 5) { 3431 sizeIndex = 0; 3432 } else if (size >= 3) { 3433 sizeIndex = 1; 3434 } else { 3435 sizeIndex = 2; 3436 } 3437 3438 if (!fontMetricsBySizeIndex[sizeIndex]) { 3439 var metrics = fontMetricsBySizeIndex[sizeIndex] = { 3440 cssEmPerMu: sigmasAndXis.quad[sizeIndex] / 18 3441 }; 3442 3443 for (var key in sigmasAndXis) { 3444 if (sigmasAndXis.hasOwnProperty(key)) { 3445 metrics[key] = sigmasAndXis[key][sizeIndex]; 3446 } 3447 } 3448 } 3449 3450 return fontMetricsBySizeIndex[sizeIndex]; 3451} 3452 3453/** 3454 * This file contains information about the options that the Parser carries 3455 * around with it while parsing. Data is held in an `Options` object, and when 3456 * recursing, a new `Options` object can be created with the `.with*` and 3457 * `.reset` functions. 3458 */ 3459var sizeStyleMap = [// Each element contains [textsize, scriptsize, scriptscriptsize]. 3460// The size mappings are taken from TeX with \normalsize=10pt. 3461[1, 1, 1], // size1: [5, 5, 5] \tiny 3462[2, 1, 1], // size2: [6, 5, 5] 3463[3, 1, 1], // size3: [7, 5, 5] \scriptsize 3464[4, 2, 1], // size4: [8, 6, 5] \footnotesize 3465[5, 2, 1], // size5: [9, 6, 5] \small 3466[6, 3, 1], // size6: [10, 7, 5] \normalsize 3467[7, 4, 2], // size7: [12, 8, 6] \large 3468[8, 6, 3], // size8: [14.4, 10, 7] \Large 3469[9, 7, 6], // size9: [17.28, 12, 10] \LARGE 3470[10, 8, 7], // size10: [20.74, 14.4, 12] \huge 3471[11, 10, 9] // size11: [24.88, 20.74, 17.28] \HUGE 3472];
vendor: 10,849 bytes, lines 3473-3898
3473var sizeMultipliers = [// fontMetrics.js:getGlobalMetrics also uses size indexes, so if 3474// you change size indexes, change that function. 34750.5, 0.6, 0.7, 0.8, 0.9, 1.0, 1.2, 1.44, 1.728, 2.074, 2.488]; 3476 3477var sizeAtStyle = function sizeAtStyle(size, style) { 3478 return style.size < 2 ? size : sizeStyleMap[size - 1][style.size - 1]; 3479}; // In these types, "" (empty string) means "no change". 3480 3481 3482/** 3483 * This is the main options class. It contains the current style, size, color, 3484 * and font. 3485 * 3486 * Options objects should not be modified. To create a new Options with 3487 * different properties, call a `.having*` method. 3488 */ 3489class Options { 3490 // A font family applies to a group of fonts (i.e. SansSerif), while a font 3491 // represents a specific font (i.e. SansSerif Bold). 3492 // See: https://tex.stackexchange.com/questions/22350/difference-between-textrm-and-mathrm 3493 3494 /** 3495 * The base size index. 3496 */ 3497 constructor(data) { 3498 this.style = void 0; 3499 this.color = void 0; 3500 this.size = void 0; 3501 this.textSize = void 0; 3502 this.phantom = void 0; 3503 this.font = void 0; 3504 this.fontFamily = void 0; 3505 this.fontWeight = void 0; 3506 this.fontShape = void 0; 3507 this.sizeMultiplier = void 0; 3508 this.maxSize = void 0; 3509 this.minRuleThickness = void 0; 3510 this._fontMetrics = void 0; 3511 this.style = data.style; 3512 this.color = data.color; 3513 this.size = data.size || Options.BASESIZE; 3514 this.textSize = data.textSize || this.size; 3515 this.phantom = !!data.phantom; 3516 this.font = data.font || ""; 3517 this.fontFamily = data.fontFamily || ""; 3518 this.fontWeight = data.fontWeight || ''; 3519 this.fontShape = data.fontShape || ''; 3520 this.sizeMultiplier = sizeMultipliers[this.size - 1]; 3521 this.maxSize = data.maxSize; 3522 this.minRuleThickness = data.minRuleThickness; 3523 this._fontMetrics = undefined; 3524 } 3525 /** 3526 * Returns a new options object with the same properties as "this". Properties 3527 * from "extension" will be copied to the new options object. 3528 */ 3529 3530 3531 extend(extension) { 3532 var data = { 3533 style: this.style, 3534 size: this.size, 3535 textSize: this.textSize, 3536 color: this.color, 3537 phantom: this.phantom, 3538 font: this.font, 3539 fontFamily: this.fontFamily, 3540 fontWeight: this.fontWeight, 3541 fontShape: this.fontShape, 3542 maxSize: this.maxSize, 3543 minRuleThickness: this.minRuleThickness 3544 }; 3545 3546 for (var key in extension) { 3547 if (extension.hasOwnProperty(key)) { 3548 data[key] = extension[key]; 3549 } 3550 } 3551 3552 return new Options(data); 3553 } 3554 /** 3555 * Return an options object with the given style. If `this.style === style`, 3556 * returns `this`. 3557 */ 3558 3559 3560 havingStyle(style) { 3561 if (this.style === style) { 3562 return this; 3563 } else { 3564 return this.extend({ 3565 style: style, 3566 size: sizeAtStyle(this.textSize, style) 3567 }); 3568 } 3569 } 3570 /** 3571 * Return an options object with a cramped version of the current style. If 3572 * the current style is cramped, returns `this`. 3573 */ 3574 3575 3576 havingCrampedStyle() { 3577 return this.havingStyle(this.style.cramp()); 3578 } 3579 /** 3580 * Return an options object with the given size and in at least `\textstyle`. 3581 * Returns `this` if appropriate. 3582 */ 3583 3584 3585 havingSize(size) { 3586 if (this.size === size && this.textSize === size) { 3587 return this; 3588 } else { 3589 return this.extend({ 3590 style: this.style.text(), 3591 size: size, 3592 textSize: size, 3593 sizeMultiplier: sizeMultipliers[size - 1] 3594 }); 3595 } 3596 } 3597 /** 3598 * Like `this.havingSize(BASESIZE).havingStyle(style)`. If `style` is omitted, 3599 * changes to at least `\textstyle`. 3600 */ 3601 3602 3603 havingBaseStyle(style) { 3604 style = style || this.style.text(); 3605 var wantSize = sizeAtStyle(Options.BASESIZE, style); 3606 3607 if (this.size === wantSize && this.textSize === Options.BASESIZE && this.style === style) { 3608 return this; 3609 } else { 3610 return this.extend({ 3611 style: style, 3612 size: wantSize 3613 }); 3614 } 3615 } 3616 /** 3617 * Remove the effect of sizing changes such as \Huge. 3618 * Keep the effect of the current style, such as \scriptstyle. 3619 */ 3620 3621 3622 havingBaseSizing() { 3623 var size; 3624 3625 switch (this.style.id) { 3626 case 4: 3627 case 5: 3628 size = 3; // normalsize in scriptstyle 3629 3630 break; 3631 3632 case 6: 3633 case 7: 3634 size = 1; // normalsize in scriptscriptstyle 3635 3636 break; 3637 3638 default: 3639 size = 6; 3640 // normalsize in textstyle or displaystyle 3641 } 3642 3643 return this.extend({ 3644 style: this.style.text(), 3645 size: size 3646 }); 3647 } 3648 /** 3649 * Create a new options object with the given color. 3650 */ 3651 3652 3653 withColor(color) { 3654 return this.extend({ 3655 color: color 3656 }); 3657 } 3658 /** 3659 * Create a new options object with "phantom" set to true. 3660 */ 3661 3662 3663 withPhantom() { 3664 return this.extend({ 3665 phantom: true 3666 }); 3667 } 3668 /** 3669 * Creates a new options object with the given math font or old text font. 3670 * @type {[type]} 3671 */ 3672 3673 3674 withFont(font) { 3675 return this.extend({ 3676 font 3677 }); 3678 } 3679 /** 3680 * Create a new options objects with the given fontFamily. 3681 */ 3682 3683 3684 withTextFontFamily(fontFamily) { 3685 return this.extend({ 3686 fontFamily, 3687 font: "" 3688 }); 3689 } 3690 /** 3691 * Creates a new options object with the given font weight 3692 */ 3693 3694 3695 withTextFontWeight(fontWeight) { 3696 return this.extend({ 3697 fontWeight, 3698 font: "" 3699 }); 3700 } 3701 /** 3702 * Creates a new options object with the given font weight 3703 */ 3704 3705 3706 withTextFontShape(fontShape) { 3707 return this.extend({ 3708 fontShape, 3709 font: "" 3710 }); 3711 } 3712 /** 3713 * Return the CSS sizing classes required to switch from enclosing options 3714 * `oldOptions` to `this`. Returns an array of classes. 3715 */ 3716 3717 3718 sizingClasses(oldOptions) { 3719 if (oldOptions.size !== this.size) { 3720 return ["sizing", "reset-size" + oldOptions.size, "size" + this.size]; 3721 } else { 3722 return []; 3723 } 3724 } 3725 /** 3726 * Return the CSS sizing classes required to switch to the base size. Like 3727 * `this.havingSize(BASESIZE).sizingClasses(this)`. 3728 */ 3729 3730 3731 baseSizingClasses() { 3732 if (this.size !== Options.BASESIZE) { 3733 return ["sizing", "reset-size" + this.size, "size" + Options.BASESIZE]; 3734 } else { 3735 return []; 3736 } 3737 } 3738 /** 3739 * Return the font metrics for this size. 3740 */ 3741 3742 3743 fontMetrics() { 3744 if (!this._fontMetrics) { 3745 this._fontMetrics = getGlobalMetrics(this.size); 3746 } 3747 3748 return this._fontMetrics; 3749 } 3750 /** 3751 * Gets the CSS color of the current options object 3752 */ 3753 3754 3755 getColor() { 3756 if (this.phantom) { 3757 return "transparent"; 3758 } else { 3759 return this.color; 3760 } 3761 } 3762 3763} 3764 3765Options.BASESIZE = 6; 3766 3767/** 3768 * This file does conversion between units. In particular, it provides 3769 * calculateSize to convert other units into ems. 3770 */ 3771// Thus, multiplying a length by this number converts the length from units 3772// into pts. Dividing the result by ptPerEm gives the number of ems 3773// *assuming* a font size of ptPerEm (normal size, normal style). 3774 3775var ptPerUnit = { 3776 // https://en.wikibooks.org/wiki/LaTeX/Lengths and 3777 // https://tex.stackexchange.com/a/8263 3778 "pt": 1, 3779 // TeX point 3780 "mm": 7227 / 2540, 3781 // millimeter 3782 "cm": 7227 / 254, 3783 // centimeter 3784 "in": 72.27, 3785 // inch 3786 "bp": 803 / 800, 3787 // big (PostScript) points 3788 "pc": 12, 3789 // pica 3790 "dd": 1238 / 1157, 3791 // didot 3792 "cc": 14856 / 1157, 3793 // cicero (12 didot) 3794 "nd": 685 / 642, 3795 // new didot 3796 "nc": 1370 / 107, 3797 // new cicero (12 new didot) 3798 "sp": 1 / 65536, 3799 // scaled point (TeX's internal smallest unit) 3800 // https://tex.stackexchange.com/a/41371 3801 "px": 803 / 800 // \pdfpxdimen defaults to 1 bp in pdfTeX and LuaTeX 3802 3803}; // Dictionary of relative units, for fast validity testing. 3804 3805var relativeUnit = { 3806 "ex": true, 3807 "em": true, 3808 "mu": true 3809}; 3810 3811/** 3812 * Determine whether the specified unit (either a string defining the unit 3813 * or a "size" parse node containing a unit field) is valid. 3814 */ 3815var validUnit = function validUnit(unit) { 3816 if (typeof unit !== "string") { 3817 unit = unit.unit; 3818 } 3819 3820 return unit in ptPerUnit || unit in relativeUnit || unit === "ex"; 3821}; 3822/* 3823 * Convert a "size" parse node (with numeric "number" and string "unit" fields, 3824 * as parsed by functions.js argType "size") into a CSS em value for the 3825 * current style/scale. `options` gives the current options. 3826 */ 3827 3828var calculateSize = function calculateSize(sizeValue, options) { 3829 var scale; 3830 3831 if (sizeValue.unit in ptPerUnit) { 3832 // Absolute units 3833 scale = ptPerUnit[sizeValue.unit] // Convert unit to pt 3834 / options.fontMetrics().ptPerEm // Convert pt to CSS em 3835 / options.sizeMultiplier; // Unscale to make absolute units 3836 } else if (sizeValue.unit === "mu") { 3837 // `mu` units scale with scriptstyle/scriptscriptstyle. 3838 scale = options.fontMetrics().cssEmPerMu; 3839 } else { 3840 // Other relative units always refer to the *textstyle* font 3841 // in the current size. 3842 var unitOptions; 3843 3844 if (options.style.isTight()) { 3845 // isTight() means current style is script/scriptscript. 3846 unitOptions = options.havingStyle(options.style.text()); 3847 } else { 3848 unitOptions = options; 3849 } // TODO: In TeX these units are relative to the quad of the current 3850 // *text* font, e.g. cmr10. KaTeX instead uses values from the 3851 // comparably-sized *Computer Modern symbol* font. At 10pt, these 3852 // match. At 7pt and 5pt, they differ: cmr7=1.138894, cmsy7=1.170641; 3853 // cmr5=1.361133, cmsy5=1.472241. Consider $\scriptsize a\kern1emb$. 3854 // TeX \showlists shows a kern of 1.13889 * fontsize; 3855 // KaTeX shows a kern of 1.171 * fontsize. 3856 3857 3858 if (sizeValue.unit === "ex") { 3859 scale = unitOptions.fontMetrics().xHeight; 3860 } else if (sizeValue.unit === "em") { 3861 scale = unitOptions.fontMetrics().quad; 3862 } else { 3863 throw new ParseError("Invalid unit: '" + sizeValue.unit + "'"); 3864 } 3865 3866 if (unitOptions !== options) { 3867 scale *= unitOptions.sizeMultiplier / options.sizeMultiplier; 3868 } 3869 } 3870 3871 return Math.min(sizeValue.number * scale, options.maxSize); 3872}; 3873/** 3874 * Round `n` to 4 decimal places, or to the nearest 1/10,000th em. See 3875 * https://github.com/KaTeX/KaTeX/pull/2460. 3876 */ 3877 3878var makeEm = function makeEm(n) { 3879 return +n.toFixed(4) + "em"; 3880}; 3881 3882/** 3883 * These objects store the data about the DOM nodes we create, as well as some 3884 * extra data. They can then be transformed into real DOM nodes with the 3885 * `toNode` function or HTML markup using `toMarkup`. They are useful for both 3886 * storing extra properties on the nodes, as well as providing a way to easily 3887 * work with the DOM. 3888 * 3889 * Similar functions for working with MathML nodes exist in mathMLTree.js. 3890 * 3891 * TODO: refactor `span` and `anchor` into common superclass when 3892 * target environments support class inheritance 3893 */ 3894 3895/** 3896 * Create an HTML className based on a list of classes. In addition to joining 3897 * with spaces, we also remove empty classes. 3898 */
vendor: 9,232 bytes, lines 3899-4255
3899var createClass = function createClass(classes) { 3900 return classes.filter(cls => cls).join(" "); 3901}; 3902 3903var initNode = function initNode(classes, options, style) { 3904 this.classes = classes || []; 3905 this.attributes = {}; 3906 this.height = 0; 3907 this.depth = 0; 3908 this.maxFontSize = 0; 3909 this.style = style || {}; 3910 3911 if (options) { 3912 if (options.style.isTight()) { 3913 this.classes.push("mtight"); 3914 } 3915 3916 var color = options.getColor(); 3917 3918 if (color) { 3919 this.style.color = color; 3920 } 3921 } 3922}; 3923/** 3924 * Convert into an HTML node 3925 */ 3926 3927 3928var toNode = function toNode(tagName) { 3929 var node = document.createElement(tagName); // Apply the class 3930 3931 node.className = createClass(this.classes); // Apply inline styles 3932 3933 for (var style in this.style) { 3934 if (this.style.hasOwnProperty(style)) { 3935 // $FlowFixMe Flow doesn't seem to understand span.style's type. 3936 node.style[style] = this.style[style]; 3937 } 3938 } // Apply attributes 3939 3940 3941 for (var attr in this.attributes) { 3942 if (this.attributes.hasOwnProperty(attr)) { 3943 node.setAttribute(attr, this.attributes[attr]); 3944 } 3945 } // Append the children, also as HTML nodes 3946 3947 3948 for (var i = 0; i < this.children.length; i++) { 3949 node.appendChild(this.children[i].toNode()); 3950 } 3951 3952 return node; 3953}; 3954/** 3955 * https://w3c.github.io/html-reference/syntax.html#syntax-attributes 3956 * 3957 * > Attribute Names must consist of one or more characters 3958 * other than the space characters, U+0000 NULL, 3959 * '"', "'", ">", "/", "=", the control characters, 3960 * and any characters that are not defined by Unicode. 3961 */ 3962 3963 3964var invalidAttributeNameRegex = /[\s"'>/=\x00-\x1f]/; 3965/** 3966 * Convert into an HTML markup string 3967 */ 3968 3969var toMarkup = function toMarkup(tagName) { 3970 var markup = "<" + tagName; // Add the class 3971 3972 if (this.classes.length) { 3973 markup += " class=\"" + utils.escape(createClass(this.classes)) + "\""; 3974 } 3975 3976 var styles = ""; // Add the styles, after hyphenation 3977 3978 for (var style in this.style) { 3979 if (this.style.hasOwnProperty(style)) { 3980 styles += utils.hyphenate(style) + ":" + this.style[style] + ";"; 3981 } 3982 } 3983 3984 if (styles) { 3985 markup += " style=\"" + utils.escape(styles) + "\""; 3986 } // Add the attributes 3987 3988 3989 for (var attr in this.attributes) { 3990 if (this.attributes.hasOwnProperty(attr)) { 3991 if (invalidAttributeNameRegex.test(attr)) { 3992 throw new ParseError("Invalid attribute name '" + attr + "'"); 3993 } 3994 3995 markup += " " + attr + "=\"" + utils.escape(this.attributes[attr]) + "\""; 3996 } 3997 } 3998 3999 markup += ">"; // Add the markup of the children, also as markup 4000 4001 for (var i = 0; i < this.children.length; i++) { 4002 markup += this.children[i].toMarkup(); 4003 } 4004 4005 markup += "</" + tagName + ">"; 4006 return markup; 4007}; // Making the type below exact with all optional fields doesn't work due to 4008// - https://github.com/facebook/flow/issues/4582 4009// - https://github.com/facebook/flow/issues/5688 4010// However, since *all* fields are optional, $Shape<> works as suggested in 5688 4011// above. 4012// This type does not include all CSS properties. Additional properties should 4013// be added as needed. 4014 4015 4016/** 4017 * This node represents a span node, with a className, a list of children, and 4018 * an inline style. It also contains information about its height, depth, and 4019 * maxFontSize. 4020 * 4021 * Represents two types with different uses: SvgSpan to wrap an SVG and DomSpan 4022 * otherwise. This typesafety is important when HTML builders access a span's 4023 * children. 4024 */ 4025class Span { 4026 constructor(classes, children, options, style) { 4027 this.children = void 0; 4028 this.attributes = void 0; 4029 this.classes = void 0; 4030 this.height = void 0; 4031 this.depth = void 0; 4032 this.width = void 0; 4033 this.maxFontSize = void 0; 4034 this.style = void 0; 4035 initNode.call(this, classes, options, style); 4036 this.children = children || []; 4037 } 4038 /** 4039 * Sets an arbitrary attribute on the span. Warning: use this wisely. Not 4040 * all browsers support attributes the same, and having too many custom 4041 * attributes is probably bad. 4042 */ 4043 4044 4045 setAttribute(attribute, value) { 4046 this.attributes[attribute] = value; 4047 } 4048 4049 hasClass(className) { 4050 return utils.contains(this.classes, className); 4051 } 4052 4053 toNode() { 4054 return toNode.call(this, "span"); 4055 } 4056 4057 toMarkup() { 4058 return toMarkup.call(this, "span"); 4059 } 4060 4061} 4062/** 4063 * This node represents an anchor (<a>) element with a hyperlink. See `span` 4064 * for further details. 4065 */ 4066 4067class Anchor { 4068 constructor(href, classes, children, options) { 4069 this.children = void 0; 4070 this.attributes = void 0; 4071 this.classes = void 0; 4072 this.height = void 0; 4073 this.depth = void 0; 4074 this.maxFontSize = void 0; 4075 this.style = void 0; 4076 initNode.call(this, classes, options); 4077 this.children = children || []; 4078 this.setAttribute('href', href); 4079 } 4080 4081 setAttribute(attribute, value) { 4082 this.attributes[attribute] = value; 4083 } 4084 4085 hasClass(className) { 4086 return utils.contains(this.classes, className); 4087 } 4088 4089 toNode() { 4090 return toNode.call(this, "a"); 4091 } 4092 4093 toMarkup() { 4094 return toMarkup.call(this, "a"); 4095 } 4096 4097} 4098/** 4099 * This node represents an image embed (<img>) element. 4100 */ 4101 4102class Img { 4103 constructor(src, alt, style) { 4104 this.src = void 0; 4105 this.alt = void 0; 4106 this.classes = void 0; 4107 this.height = void 0; 4108 this.depth = void 0; 4109 this.maxFontSize = void 0; 4110 this.style = void 0; 4111 this.alt = alt; 4112 this.src = src; 4113 this.classes = ["mord"]; 4114 this.style = style; 4115 } 4116 4117 hasClass(className) { 4118 return utils.contains(this.classes, className); 4119 } 4120 4121 toNode() { 4122 var node = document.createElement("img"); 4123 node.src = this.src; 4124 node.alt = this.alt; 4125 node.className = "mord"; // Apply inline styles 4126 4127 for (var style in this.style) { 4128 if (this.style.hasOwnProperty(style)) { 4129 // $FlowFixMe 4130 node.style[style] = this.style[style]; 4131 } 4132 } 4133 4134 return node; 4135 } 4136 4137 toMarkup() { 4138 var markup = "<img src=\"" + utils.escape(this.src) + "\"" + (" alt=\"" + utils.escape(this.alt) + "\""); // Add the styles, after hyphenation 4139 4140 var styles = ""; 4141 4142 for (var style in this.style) { 4143 if (this.style.hasOwnProperty(style)) { 4144 styles += utils.hyphenate(style) + ":" + this.style[style] + ";"; 4145 } 4146 } 4147 4148 if (styles) { 4149 markup += " style=\"" + utils.escape(styles) + "\""; 4150 } 4151 4152 markup += "'/>"; 4153 return markup; 4154 } 4155 4156} 4157var iCombinations = { 4158 'î': '\u0131\u0302', 4159 'ï': '\u0131\u0308', 4160 'Ã': '\u0131\u0301', 4161 // 'Ä«': '\u0131\u0304', // enable when we add Extended Latin 4162 'ì': '\u0131\u0300' 4163}; 4164/** 4165 * A symbol node contains information about a single symbol. It either renders 4166 * to a single text node, or a span with a single text node in it, depending on 4167 * whether it has CSS classes, styles, or needs italic correction. 4168 */ 4169 4170class SymbolNode { 4171 constructor(text, height, depth, italic, skew, width, classes, style) { 4172 this.text = void 0; 4173 this.height = void 0; 4174 this.depth = void 0; 4175 this.italic = void 0; 4176 this.skew = void 0; 4177 this.width = void 0; 4178 this.maxFontSize = void 0; 4179 this.classes = void 0; 4180 this.style = void 0; 4181 this.text = text; 4182 this.height = height || 0; 4183 this.depth = depth || 0; 4184 this.italic = italic || 0; 4185 this.skew = skew || 0; 4186 this.width = width || 0; 4187 this.classes = classes || []; 4188 this.style = style || {}; 4189 this.maxFontSize = 0; // Mark text from non-Latin scripts with specific classes so that we 4190 // can specify which fonts to use. This allows us to render these 4191 // characters with a serif font in situations where the browser would 4192 // either default to a sans serif or render a placeholder character. 4193 // We use CSS class names like cjk_fallback, hangul_fallback and 4194 // brahmic_fallback. See ./unicodeScripts.js for the set of possible 4195 // script names 4196 4197 var script = scriptFromCodepoint(this.text.charCodeAt(0)); 4198 4199 if (script) { 4200 this.classes.push(script + "_fallback"); 4201 } 4202 4203 if (/[îïÃì]/.test(this.text)) { 4204 // add Ä« when we add Extended Latin 4205 this.text = iCombinations[this.text]; 4206 } 4207 } 4208 4209 hasClass(className) { 4210 return utils.contains(this.classes, className); 4211 } 4212 /** 4213 * Creates a text node or span from a symbol node. Note that a span is only 4214 * created if it is needed. 4215 */ 4216 4217 4218 toNode() { 4219 var node = document.createTextNode(this.text); 4220 var span = null; 4221 4222 if (this.italic > 0) { 4223 span = document.createElement("span"); 4224 span.style.marginRight = makeEm(this.italic); 4225 } 4226 4227 if (this.classes.length > 0) { 4228 span = span || document.createElement("span"); 4229 span.className = createClass(this.classes); 4230 } 4231 4232 for (var style in this.style) { 4233 if (this.style.hasOwnProperty(style)) { 4234 span = span || document.createElement("span"); // $FlowFixMe Flow doesn't seem to understand span.style's type. 4235 4236 span.style[style] = this.style[style]; 4237 } 4238 } 4239 4240 if (span) { 4241 span.appendChild(node); 4242 return span; 4243 } else { 4244 return node; 4245 } 4246 } 4247 /** 4248 * Creates markup for a symbol node. 4249 */ 4250 4251 4252 toMarkup() { 4253 // TODO(alpert): More duplication than I'd like from 4254 // span.prototype.toMarkup and symbolNode.prototype.toNode... 4255 var needsSpan = false;
vendor: 4,084 bytes, lines 4256-4427
4256 var markup = "<span"; 4257 4258 if (this.classes.length) { 4259 needsSpan = true; 4260 markup += " class=\""; 4261 markup += utils.escape(createClass(this.classes)); 4262 markup += "\""; 4263 } 4264 4265 var styles = ""; 4266 4267 if (this.italic > 0) { 4268 styles += "margin-right:" + this.italic + "em;"; 4269 } 4270 4271 for (var style in this.style) { 4272 if (this.style.hasOwnProperty(style)) { 4273 styles += utils.hyphenate(style) + ":" + this.style[style] + ";"; 4274 } 4275 } 4276 4277 if (styles) { 4278 needsSpan = true; 4279 markup += " style=\"" + utils.escape(styles) + "\""; 4280 } 4281 4282 var escaped = utils.escape(this.text); 4283 4284 if (needsSpan) { 4285 markup += ">"; 4286 markup += escaped; 4287 markup += "</span>"; 4288 return markup; 4289 } else { 4290 return escaped; 4291 } 4292 } 4293 4294} 4295/** 4296 * SVG nodes are used to render stretchy wide elements. 4297 */ 4298 4299class SvgNode { 4300 constructor(children, attributes) { 4301 this.children = void 0; 4302 this.attributes = void 0; 4303 this.children = children || []; 4304 this.attributes = attributes || {}; 4305 } 4306 4307 toNode() { 4308 var svgNS = "http://www.w3.org/2000/svg"; 4309 var node = document.createElementNS(svgNS, "svg"); // Apply attributes 4310 4311 for (var attr in this.attributes) { 4312 if (Object.prototype.hasOwnProperty.call(this.attributes, attr)) { 4313 node.setAttribute(attr, this.attributes[attr]); 4314 } 4315 } 4316 4317 for (var i = 0; i < this.children.length; i++) { 4318 node.appendChild(this.children[i].toNode()); 4319 } 4320 4321 return node; 4322 } 4323 4324 toMarkup() { 4325 var markup = "<svg xmlns=\"http://www.w3.org/2000/svg\""; // Apply attributes 4326 4327 for (var attr in this.attributes) { 4328 if (Object.prototype.hasOwnProperty.call(this.attributes, attr)) { 4329 markup += " " + attr + "=\"" + utils.escape(this.attributes[attr]) + "\""; 4330 } 4331 } 4332 4333 markup += ">"; 4334 4335 for (var i = 0; i < this.children.length; i++) { 4336 markup += this.children[i].toMarkup(); 4337 } 4338 4339 markup += "</svg>"; 4340 return markup; 4341 } 4342 4343} 4344class PathNode { 4345 constructor(pathName, alternate) { 4346 this.pathName = void 0; 4347 this.alternate = void 0; 4348 this.pathName = pathName; 4349 this.alternate = alternate; // Used only for \sqrt, \phase, & tall delims 4350 } 4351 4352 toNode() { 4353 var svgNS = "http://www.w3.org/2000/svg"; 4354 var node = document.createElementNS(svgNS, "path"); 4355 4356 if (this.alternate) { 4357 node.setAttribute("d", this.alternate); 4358 } else { 4359 node.setAttribute("d", path[this.pathName]); 4360 } 4361 4362 return node; 4363 } 4364 4365 toMarkup() { 4366 if (this.alternate) { 4367 return "<path d=\"" + utils.escape(this.alternate) + "\"/>"; 4368 } else { 4369 return "<path d=\"" + utils.escape(path[this.pathName]) + "\"/>"; 4370 } 4371 } 4372 4373} 4374class LineNode { 4375 constructor(attributes) { 4376 this.attributes = void 0; 4377 this.attributes = attributes || {}; 4378 } 4379 4380 toNode() { 4381 var svgNS = "http://www.w3.org/2000/svg"; 4382 var node = document.createElementNS(svgNS, "line"); // Apply attributes 4383 4384 for (var attr in this.attributes) { 4385 if (Object.prototype.hasOwnProperty.call(this.attributes, attr)) { 4386 node.setAttribute(attr, this.attributes[attr]); 4387 } 4388 } 4389 4390 return node; 4391 } 4392 4393 toMarkup() { 4394 var markup = "<line"; 4395 4396 for (var attr in this.attributes) { 4397 if (Object.prototype.hasOwnProperty.call(this.attributes, attr)) { 4398 markup += " " + attr + "=\"" + utils.escape(this.attributes[attr]) + "\""; 4399 } 4400 } 4401 4402 markup += "/>"; 4403 return markup; 4404 } 4405 4406} 4407function assertSymbolDomNode(group) { 4408 if (group instanceof SymbolNode) { 4409 return group; 4410 } else { 4411 throw new Error("Expected symbolNode but got " + String(group) + "."); 4412 } 4413} 4414function assertSpan(group) { 4415 if (group instanceof Span) { 4416 return group; 4417 } else { 4418 throw new Error("Expected span<HtmlDomNode> but got " + String(group) + "."); 4419 } 4420} 4421 4422/** 4423 * This file holds a list of all no-argument functions and single-character 4424 * symbols (like 'a' or ';'). 4425 * 4426 * For each of the symbols, there are three properties they can have: 4427 * - font (required): the font to be used for this symbol. Either "main" (the
4428 normal font), or "ams" (the ams fonts). 4429 * - group (required): the ParseNode group type the symbol should have (i.e. 4430 "textord", "mathord", etc). 4431 See https://github.com/KaTeX/KaTeX/wiki/Examining-TeX#group-types 4432 * - replace: the character that this symbol or function should be 4433 * replaced with (i.e. "\phi" has a replace value of "\u03d5", the phi 4434 * character in the main font). 4435 * 4436 * The outermost map in the table indicates what mode the symbols should be 4437 * accepted in (e.g. "math" or "text"). 4438 */ 4439// Some of these have a "-token" suffix since these are also used as `ParseNode` 4440// types for raw text tokens, and we want to avoid conflicts with higher-level 4441// `ParseNode` types. These `ParseNode`s are constructed within `Parser` by 4442// looking up the `symbols` map. 4443var ATOMS = { 4444 "bin": 1, 4445 "close": 1, 4446 "inner": 1, 4447 "open": 1, 4448 "punct": 1, 4449 "rel": 1 4450}; 4451var NON_ATOMS = { 4452 "accent-token": 1, 4453 "mathord": 1, 4454 "op-token": 1, 4455 "spacing": 1, 4456 "textord": 1 4457}; 4458var symbols = { 4459 "math": {}, 4460 "text": {} 4461}; 4462/** `acceptUnicodeChar = true` is only applicable if `replace` is set. */ 4463 4464function defineSymbol(mode, font, group, replace, name, acceptUnicodeChar) { 4465 symbols[mode][name] = { 4466 font, 4467 group, 4468 replace 4469 }; 4470 4471 if (acceptUnicodeChar && replace) { 4472 symbols[mode][replace] = symbols[mode][name]; 4473 } 4474} // Some abbreviations for commonly used strings. 4475// This helps minify the code, and also spotting typos using jshint. 4476// modes: 4477 4478var math = "math"; 4479var text = "text"; // fonts: 4480 4481var main = "main"; 4482var ams = "ams"; // groups: 4483 4484var accent = "accent-token"; 4485var bin = "bin"; 4486var close = "close"; 4487var inner = "inner"; 4488var mathord = "mathord"; 4489var op = "op-token"; 4490var open = "open"; 4491var punct = "punct"; 4492var rel = "rel"; 4493var spacing = "spacing"; 4494var textord = "textord"; // Now comes the symbol table 4495// Relation Symbols 4496 4497defineSymbol(math, main, rel, "\u2261", "\\equiv", true); 4498defineSymbol(math, main, rel, "\u227a", "\\prec", true); 4499defineSymbol(math, main, rel, "\u227b", "\\succ", true); 4500defineSymbol(math, main, rel, "\u223c", "\\sim", true); 4501defineSymbol(math, main, rel, "\u22a5", "\\perp"); 4502defineSymbol(math, main, rel, "\u2aaf", "\\preceq", true); 4503defineSymbol(math, main, rel, "\u2ab0", "\\succeq", true); 4504defineSymbol(math, main, rel, "\u2243", "\\simeq", true); 4505defineSymbol(math, main, rel, "\u2223", "\\mid", true); 4506defineSymbol(math, main, rel, "\u226a", "\\ll", true); 4507defineSymbol(math, main, rel, "\u226b", "\\gg", true); 4508defineSymbol(math, main, rel, "\u224d", "\\asymp", true); 4509defineSymbol(math, main, rel, "\u2225", "\\parallel"); 4510defineSymbol(math, main, rel, "\u22c8", "\\bowtie", true); 4511defineSymbol(math, main, rel, "\u2323", "\\smile", true); 4512defineSymbol(math, main, rel, "\u2291", "\\sqsubseteq", true); 4513defineSymbol(math, main, rel, "\u2292", "\\sqsupseteq", true); 4514defineSymbol(math, main, rel, "\u2250", "\\doteq", true); 4515defineSymbol(math, main, rel, "\u2322", "\\frown", true); 4516defineSymbol(math, main, rel, "\u220b", "\\ni", true); 4517defineSymbol(math, main, rel, "\u221d", "\\propto", true); 4518defineSymbol(math, main, rel, "\u22a2", "\\vdash", true); 4519defineSymbol(math, main, rel, "\u22a3", "\\dashv", true); 4520defineSymbol(math, main, rel, "\u220b", "\\owns"); // Punctuation 4521 4522defineSymbol(math, main, punct, "\u002e", "\\ldotp"); 4523defineSymbol(math, main, punct, "\u22c5", "\\cdotp"); // Misc Symbols 4524 4525defineSymbol(math, main, textord, "\u0023", "\\#"); 4526defineSymbol(text, main, textord, "\u0023", "\\#"); 4527defineSymbol(math, main, textord, "\u0026", "\\&"); 4528defineSymbol(text, main, textord, "\u0026", "\\&"); 4529defineSymbol(math, main, textord, "\u2135", "\\aleph", true); 4530defineSymbol(math, main, textord, "\u2200", "\\forall", true); 4531defineSymbol(math, main, textord, "\u210f", "\\hbar", true); 4532defineSymbol(math, main, textord, "\u2203", "\\exists", true); 4533defineSymbol(math, main, textord, "\u2207", "\\nabla", true); 4534defineSymbol(math, main, textord, "\u266d", "\\flat", true); 4535defineSymbol(math, main, textord, "\u2113", "\\ell", true); 4536defineSymbol(math, main, textord, "\u266e", "\\natural", true); 4537defineSymbol(math, main, textord, "\u2663", "\\clubsuit", true); 4538defineSymbol(math, main, textord, "\u2118", "\\wp", true); 4539defineSymbol(math, main, textord, "\u266f", "\\sharp", true); 4540defineSymbol(math, main, textord, "\u2662", "\\diamondsuit", true); 4541defineSymbol(math, main, textord, "\u211c", "\\Re", true); 4542defineSymbol(math, main, textord, "\u2661", "\\heartsuit", true); 4543defineSymbol(math, main, textord, "\u2111", "\\Im", true); 4544defineSymbol(math, main, textord, "\u2660", "\\spadesuit", true); 4545defineSymbol(math, main, textord, "\u00a7", "\\S", true); 4546defineSymbol(text, main, textord, "\u00a7", "\\S"); 4547defineSymbol(math, main, textord, "\u00b6", "\\P", true); 4548defineSymbol(text, main, textord, "\u00b6", "\\P"); // Math and Text 4549 4550defineSymbol(math, main, textord, "\u2020", "\\dag"); 4551defineSymbol(text, main, textord, "\u2020", "\\dag"); 4552defineSymbol(text, main, textord, "\u2020", "\\textdagger"); 4553defineSymbol(math, main, textord, "\u2021", "\\ddag"); 4554defineSymbol(text, main, textord, "\u2021", "\\ddag"); 4555defineSymbol(text, main, textord, "\u2021", "\\textdaggerdbl"); // Large Delimiters 4556
4557defineSymbol(math, main, close, "\u23b1", "\\rmoustache", true); 4558defineSymbol(math, main, open, "\u23b0", "\\lmoustache", true); 4559defineSymbol(math, main, close, "\u27ef", "\\rgroup", true); 4560defineSymbol(math, main, open, "\u27ee", "\\lgroup", true); // Binary Operators 4561 4562defineSymbol(math, main, bin, "\u2213", "\\mp", true); 4563defineSymbol(math, main, bin, "\u2296", "\\ominus", true); 4564defineSymbol(math, main, bin, "\u228e", "\\uplus", true); 4565defineSymbol(math, main, bin, "\u2293", "\\sqcap", true); 4566defineSymbol(math, main, bin, "\u2217", "\\ast"); 4567defineSymbol(math, main, bin, "\u2294", "\\sqcup", true); 4568defineSymbol(math, main, bin, "\u25ef", "\\bigcirc", true); 4569defineSymbol(math, main, bin, "\u2219", "\\bullet", true); 4570defineSymbol(math, main, bin, "\u2021", "\\ddagger"); 4571defineSymbol(math, main, bin, "\u2240", "\\wr", true); 4572defineSymbol(math, main, bin, "\u2a3f", "\\amalg"); 4573defineSymbol(math, main, bin, "\u0026", "\\And"); // from amsmath 4574// Arrow Symbols 4575 4576defineSymbol(math, main, rel, "\u27f5", "\\longleftarrow", true); 4577defineSymbol(math, main, rel, "\u21d0", "\\Leftarrow", true); 4578defineSymbol(math, main, rel, "\u27f8", "\\Longleftarrow", true); 4579defineSymbol(math, main, rel, "\u27f6", "\\longrightarrow", true); 4580defineSymbol(math, main, rel, "\u21d2", "\\Rightarrow", true); 4581defineSymbol(math, main, rel, "\u27f9", "\\Longrightarrow", true); 4582defineSymbol(math, main, rel, "\u2194", "\\leftrightarrow", true); 4583defineSymbol(math, main, rel, "\u27f7", "\\longleftrightarrow", true); 4584defineSymbol(math, main, rel, "\u21d4", "\\Leftrightarrow", true); 4585defineSymbol(math, main, rel, "\u27fa", "\\Longleftrightarrow", true); 4586defineSymbol(math, main, rel, "\u21a6", "\\mapsto", true); 4587defineSymbol(math, main, rel, "\u27fc", "\\longmapsto", true); 4588defineSymbol(math, main, rel, "\u2197", "\\nearrow", true); 4589defineSymbol(math, main, rel, "\u21a9", "\\hookleftarrow", true); 4590defineSymbol(math, main, rel, "\u21aa", "\\hookrightarrow", true); 4591defineSymbol(math, main, rel, "\u2198", "\\searrow", true); 4592defineSymbol(math, main, rel, "\u21bc", "\\leftharpoonup", true); 4593defineSymbol(math, main, rel, "\u21c0", "\\rightharpoonup", true); 4594defineSymbol(math, main, rel, "\u2199", "\\swarrow", true); 4595defineSymbol(math, main, rel, "\u21bd", "\\leftharpoondown", true); 4596defineSymbol(math, main, rel, "\u21c1", "\\rightharpoondown", true); 4597defineSymbol(math, main, rel, "\u2196", "\\nwarrow", true); 4598defineSymbol(math, main, rel, "\u21cc", "\\rightleftharpoons", true); // AMS Negated Binary Relations 4599 4600defineSymbol(math, ams, rel, "\u226e", "\\nless", true); // Symbol names preceded by "@" each have a corresponding macro. 4601 4602defineSymbol(math, ams, rel, "\ue010", "\\@nleqslant"); 4603defineSymbol(math, ams, rel, "\ue011", "\\@nleqq"); 4604defineSymbol(math, ams, rel, "\u2a87", "\\lneq", true); 4605defineSymbol(math, ams, rel, "\u2268", "\\lneqq", true); 4606defineSymbol(math, ams, rel, "\ue00c", "\\@lvertneqq"); 4607defineSymbol(math, ams, rel, "\u22e6", "\\lnsim", true); 4608defineSymbol(math, ams, rel, "\u2a89", "\\lnapprox", true); 4609defineSymbol(math, ams, rel, "\u2280", "\\nprec", true); // unicode-math maps \u22e0 to \npreccurlyeq. We'll use the AMS synonym. 4610 4611defineSymbol(math, ams, rel, "\u22e0", "\\npreceq", true); 4612defineSymbol(math, ams, rel, "\u22e8", "\\precnsim", true); 4613defineSymbol(math, ams, rel, "\u2ab9", "\\precnapprox", true); 4614defineSymbol(math, ams, rel, "\u2241", "\\nsim", true); 4615defineSymbol(math, ams, rel, "\ue006", "\\@nshortmid"); 4616defineSymbol(math, ams, rel, "\u2224", "\\nmid", true); 4617defineSymbol(math, ams, rel, "\u22ac", "\\nvdash", true); 4618defineSymbol(math, ams, rel, "\u22ad", "\\nvDash", true); 4619defineSymbol(math, ams, rel, "\u22ea", "\\ntriangleleft"); 4620defineSymbol(math, ams, rel, "\u22ec", "\\ntrianglelefteq", true); 4621defineSymbol(math, ams, rel, "\u228a", "\\subsetneq", true); 4622defineSymbol(math, ams, rel, "\ue01a", "\\@varsubsetneq"); 4623defineSymbol(math, ams, rel, "\u2acb", "\\subsetneqq", true); 4624defineSymbol(math, ams, rel, "\ue017", "\\@varsubsetneqq"); 4625defineSymbol(math, ams, rel, "\u226f", "\\ngtr", true); 4626defineSymbol(math, ams, rel, "\ue00f", "\\@ngeqslant"); 4627defineSymbol(math, ams, rel, "\ue00e", "\\@ngeqq"); 4628defineSymbol(math, ams, rel, "\u2a88", "\\gneq", true); 4629defineSymbol(math, ams, rel, "\u2269", "\\gneqq", true); 4630defineSymbol(math, ams, rel, "\ue00d", "\\@gvertneqq"); 4631defineSymbol(math, ams, rel, "\u22e7", "\\gnsim", true); 4632defineSymbol(math, ams, rel, "\u2a8a", "\\gnapprox", true); 4633defineSymbol(math, ams, rel, "\u2281", "\\nsucc", true);
4633 // unicode-math maps \u22e1 to \nsucccurlyeq. We'll use the AMS synonym. 4634 4635defineSymbol(math, ams, rel, "\u22e1", "\\nsucceq", true); 4636defineSymbol(math, ams, rel, "\u22e9", "\\succnsim", true); 4637defineSymbol(math, ams, rel, "\u2aba", "\\succnapprox", true); // unicode-math maps \u2246 to \simneqq. We'll use the AMS synonym. 4638 4639defineSymbol(math, ams, rel, "\u2246", "\\ncong", true); 4640defineSymbol(math, ams, rel, "\ue007", "\\@nshortparallel"); 4641defineSymbol(math, ams, rel, "\u2226", "\\nparallel", true); 4642defineSymbol(math, ams, rel, "\u22af", "\\nVDash", true); 4643defineSymbol(math, ams, rel, "\u22eb", "\\ntriangleright"); 4644defineSymbol(math, ams, rel, "\u22ed", "\\ntrianglerighteq", true); 4645defineSymbol(math, ams, rel, "\ue018", "\\@nsupseteqq"); 4646defineSymbol(math, ams, rel, "\u228b", "\\supsetneq", true); 4647defineSymbol(math, ams, rel, "\ue01b", "\\@varsupsetneq"); 4648defineSymbol(math, ams, rel, "\u2acc", "\\supsetneqq", true); 4649defineSymbol(math, ams, rel, "\ue019", "\\@varsupsetneqq"); 4650defineSymbol(math, ams, rel, "\u22ae", "\\nVdash", true); 4651defineSymbol(math, ams, rel, "\u2ab5", "\\precneqq", true); 4652defineSymbol(math, ams, rel, "\u2ab6", "\\succneqq", true); 4653defineSymbol(math, ams, rel, "\ue016", "\\@nsubseteqq"); 4654defineSymbol(math, ams, bin, "\u22b4", "\\unlhd"); 4655defineSymbol(math, ams, bin, "\u22b5", "\\unrhd"); // AMS Negated Arrows 4656 4657defineSymbol(math, ams, rel, "\u219a", "\\nleftarrow", true); 4658defineSymbol(math, ams, rel, "\u219b", "\\nrightarrow", true); 4659defineSymbol(math, ams, rel, "\u21cd", "\\nLeftarrow", true); 4660defineSymbol(math, ams, rel, "\u21cf", "\\nRightarrow", true); 4661defineSymbol(math, ams, rel, "\u21ae", "\\nleftrightarrow", true); 4662defineSymbol(math, ams, rel, "\u21ce", "\\nLeftrightarrow", true); // AMS Misc 4663 4664defineSymbol(math, ams, rel, "\u25b3", "\\vartriangle"); 4665defineSymbol(math, ams, textord, "\u210f", "\\hslash"); 4666defineSymbol(math, ams, textord, "\u25bd", "\\triangledown"); 4667defineSymbol(math, ams, textord, "\u25ca", "\\lozenge"); 4668defineSymbol(math, ams, textord, "\u24c8", "\\circledS"); 4669defineSymbol(math, ams, textord, "\u00ae", "\\circledR"); 4670defineSymbol(text, ams, textord, "\u00ae", "\\circledR"); 4671defineSymbol(math, ams, textord, "\u2221", "\\measuredangle", true); 4672defineSymbol(math, ams, textord, "\u2204", "\\nexists"); 4673defineSymbol(math, ams, textord, "\u2127", "\\mho"); 4674defineSymbol(math, ams, textord, "\u2132", "\\Finv", true); 4675defineSymbol(math, ams, textord, "\u2141", "\\Game", true); 4676defineSymbol(math, ams, textord, "\u2035", "\\backprime"); 4677defineSymbol(math, ams, textord, "\u25b2", "\\blacktriangle"); 4678defineSymbol(math, ams, textord, "\u25bc", "\\blacktriangledown"); 4679defineSymbol(math, ams, textord, "\u25a0", "\\blacksquare"); 4680defineSymbol(math, ams, textord, "\u29eb", "\\blacklozenge"); 4681defineSymbol(math, ams, textord, "\u2605", "\\bigstar"); 4682defineSymbol(math, ams, textord, "\u2222", "\\sphericalangle", true); 4683defineSymbol(math, ams, textord, "\u2201", "\\complement", true); // unicode-math maps U+F0 to \matheth. We map to AMS function \eth 4684 4685defineSymbol(math, ams, textord, "\u00f0", "\\eth", true); 4686defineSymbol(text, main, textord, "\u00f0", "\u00f0"); 4687defineSymbol(math, ams, textord, "\u2571", "\\diagup"); 4688defineSymbol(math, ams, textord, "\u2572", "\\diagdown"); 4689defineSymbol(math, ams, textord, "\u25a1", "\\square"); 4690defineSymbol(math, ams, textord, "\u25a1", "\\Box"); 4691defineSymbol(math, ams, textord, "\u25ca", "\\Diamond"); // unicode-math maps U+A5 to \mathyen. We map to AMS function \yen 4692 4693defineSymbol(math, ams, textord, "\u00a5", "\\yen", true); 4694defineSymbol(text, ams, textord, "\u00a5", "\\yen", true); 4695defineSymbol(math, ams, textord, "\u2713", "\\checkmark", true); 4696defineSymbol(text, ams, textord, "\u2713", "\\checkmark"); // AMS Hebrew 4697 4698defineSymbol(math, ams, textord, "\u2136", "\\beth", true); 4699defineSymbol(math, ams, textord, "\u2138", "\\daleth", true); 4700defineSymbol(math, ams, textord, "\u2137", "\\gimel", true); // AMS Greek 4701 4702defineSymbol(math, ams, textord, "\u03dd", "\\digamma", true); 4703defineSymbol(math, ams, textord, "\u03f0", "\\varkappa"); // AMS Delimiters 4704 4705defineSymbol(math, ams, open, "\u250c", "\\@ulcorner", true); 4706defineSymbol(math, ams, close, "\u2510", "\\@urcorner", true); 4707defineSymbol(math, ams, open, "\u2514", "\\@llcorner", true); 4708defineSymbol(math, ams, close, "\u2518", "\\@lrcorner", true); // AMS Binary Relations 4709 4710defineSymbol(math, ams, rel, "\u2266", "\\leqq", true); 4711defineSymbol(math, ams, rel, "\u2a7d", "\\leqslant", true); 4712defineSymbol(math, ams, rel, "\u2a95", "\\eqslantless", true); 4713defineSymbol(math, ams, rel, "\u2272", "\\lesssim", true); 4714defineSymbol(math, ams, rel, "\u2a85", "\\lessapprox", true); 4715defineSymbol(math, ams, rel, "\u224a", "\\approxeq", true); 4716defineSymbol(math, ams, bin, "\u22d6", "\\lessdot"); 4717defineSymbol(math, ams, rel, "\u22d8", "\\lll", true); 4718defineSymbol(math, ams, rel, "\u2276", "\\lessgtr", true); 4719defineSymbol(math, ams, rel, "\u22da", "\\lesseqgtr", true); 4720defineSymbol(math, ams, rel, "\u2a8b", "\\lesseqqgtr", true); 4721defineSymbol(math, ams, rel, "\u2251", "\\doteqdot"); 4722defineSymbol(math, ams, rel, "\u2253", "\\risingdotseq", true); 4723defineSymbol(math, ams, rel, "\u2252", "\\fallingdotseq", true); 4724defineSymbol(math, ams, rel, "\u223d", "\\backsim", true); 4725defineSymbol(math, ams, rel, "\u22cd", "\\backsimeq", true); 4726defineSymbol(math, ams, rel, "\u2ac5", "\\subseteqq", true); 4727defineSymbol(math, ams, rel, "\u22d0", "\\Subset", true); 4728defineSymbol(math, ams, rel, "\u228f", "\\sqsubset", true); 4729defineSymbol(math, ams, rel, "\u227c", "\\preccurlyeq", true); 4730defineSymbol(math, ams, rel, "\u22de", "\\curlyeqprec", true); 4731defineSymbol(math, ams, rel, "\u227e", "\\precsim", true); 4732defineSymbol(math, ams, rel, "\u2ab7", "\\precapprox", true); 4733defineSymbol(math, ams, rel, "\u22b2", "\\vartriangleleft"); 4734defineSymbol(math, ams, rel, "\u22b4", "\\trianglelefteq"); 4735defineSymbol(math, ams, rel, "\u22a8", "\\vDash", true); 4736defineSymbol(math, ams, rel, "\u22aa", "\\Vvdash", true); 4737defineSymbol(math, ams, rel, "\u2323", "\\smallsmile"); 4738defineSymbol(math, ams, rel, "\u2322", "\\smallfrown"); 4739defineSymbol(math, ams, rel, "\u224f", "\\bumpeq", true); 4740defineSymbol(math, ams, rel, "\u224e", "\\Bumpeq", true); 4741defineSymbol(math, ams, rel, "\u2267", "\\geqq", true); 4742defineSymbol(math, ams, rel, "\u2a7e", "\\geqslant", true); 4743defineSymbol(math, ams, rel, "\u2a96", "\\eqslantgtr", true); 4744defineSymbol(math, ams, rel, "\u2273", "\\gtrsim", true); 4745defineSymbol(math, ams, rel, "\u2a86", "\\gtrapprox", true); 4746defineSymbol(math, ams, bin, "\u22d7", "\\gtrdot"); 4747defineSymbol(math, ams, rel, "\u22d9", "\\ggg", true); 4748defineSymbol(math, ams, rel, "\u2277", "\\gtrless", true); 4749defineSymbol(math, ams, rel, "\u22db", "\\gtreqless", true); 4750defineSymbol(math, ams, rel, "\u2a8c", "\\gtreqqless", true); 4751defineSymbol(math, ams, rel, "\u2256", "\\eqcirc", true); 4752defineSymbol(math, ams, rel, "\u2257", "\\circeq", true); 4753defineSymbol(math, ams, rel, "\u225c", "\\triangleq", true); 4754defineSymbol(math, ams, rel, "\u223c", "\\thicksim"); 4755defineSymbol(math, ams, rel, "\u2248", "\\thickapprox"); 4756defineSymbol(math, ams, rel, "\u2ac6", "\\supseteqq", true); 4757defineSymbol(math, ams, rel, "\u22d1", "\\Supset", true); 4758defineSymbol(math, ams, rel, "\u2290", "\\sqsupset", true); 4759defineSymbol(math, ams, rel, "\u227d", "\\succcurlyeq", true); 4760defineSymbol(math, ams, rel, "\u22df", "\\curlyeqsucc", true); 4761defineSymbol(math, ams, rel, "\u227f", "\\succsim", true); 4762defineSymbol(math, ams, rel, "\u2ab8", "\\succapprox", true); 4763defineSymbol(math, ams, rel, "\u22b3", "\\vartriangleright"); 4764defineSymbol(math, ams, rel, "\u22b5", "\\trianglerighteq"); 4765defineSymbol(math, ams, rel, "\u22a9", "\\Vdash", true); 4766defineSymbol(math, ams, rel, "\u2223", "\\shortmid"); 4767defineSymbol(math, ams, rel, "\u2225", "\\shortparallel"); 4768defineSymbol(math, ams, rel, "\u226c", "\\between", true); 4769defineSymbol(math, ams, rel, "\u22d4", "\\pitchfork", true); 4770defineSymbol(math, ams, rel, "\u221d", "\\varpropto"); 4771defineSymbol(math, ams, rel, "\u25c0", "\\blacktriangleleft");
4771 // unicode-math says that \therefore is a mathord atom. 4772// We kept the amssymb atom type, which is rel. 4773 4774defineSymbol(math, ams, rel, "\u2234", "\\therefore", true); 4775defineSymbol(math, ams, rel, "\u220d", "\\backepsilon"); 4776defineSymbol(math, ams, rel, "\u25b6", "\\blacktriangleright"); // unicode-math says that \because is a mathord atom. 4777// We kept the amssymb atom type, which is rel. 4778 4779defineSymbol(math, ams, rel, "\u2235", "\\because", true); 4780defineSymbol(math, ams, rel, "\u22d8", "\\llless"); 4781defineSymbol(math, ams, rel, "\u22d9", "\\gggtr"); 4782defineSymbol(math, ams, bin, "\u22b2", "\\lhd"); 4783defineSymbol(math, ams, bin, "\u22b3", "\\rhd"); 4784defineSymbol(math, ams, rel, "\u2242", "\\eqsim", true); 4785defineSymbol(math, main, rel, "\u22c8", "\\Join"); 4786defineSymbol(math, ams, rel, "\u2251", "\\Doteq", true); // AMS Binary Operators 4787 4788defineSymbol(math, ams, bin, "\u2214", "\\dotplus", true); 4789defineSymbol(math, ams, bin, "\u2216", "\\smallsetminus"); 4790defineSymbol(math, ams, bin, "\u22d2", "\\Cap", true); 4791defineSymbol(math, ams, bin, "\u22d3", "\\Cup", true); 4792defineSymbol(math, ams, bin, "\u2a5e", "\\doublebarwedge", true); 4793defineSymbol(math, ams, bin, "\u229f", "\\boxminus", true); 4794defineSymbol(math, ams, bin, "\u229e", "\\boxplus", true); 4795defineSymbol(math, ams, bin, "\u22c7", "\\divideontimes", true); 4796defineSymbol(math, ams, bin, "\u22c9", "\\ltimes", true); 4797defineSymbol(math, ams, bin, "\u22ca", "\\rtimes", true); 4798defineSymbol(math, ams, bin, "\u22cb", "\\leftthreetimes", true); 4799defineSymbol(math, ams, bin, "\u22cc", "\\rightthreetimes", true); 4800defineSymbol(math, ams, bin, "\u22cf", "\\curlywedge", true); 4801defineSymbol(math, ams, bin, "\u22ce", "\\curlyvee", true); 4802defineSymbol(math, ams, bin, "\u229d", "\\circleddash", true); 4803defineSymbol(math, ams, bin, "\u229b", "\\circledast", true); 4804defineSymbol(math, ams, bin, "\u22c5", "\\centerdot"); 4805defineSymbol(math, ams, bin, "\u22ba", "\\intercal", true); 4806defineSymbol(math, ams, bin, "\u22d2", "\\doublecap"); 4807defineSymbol(math, ams, bin, "\u22d3", "\\doublecup"); 4808defineSymbol(math, ams, bin, "\u22a0", "\\boxtimes", true); // AMS Arrows 4809// Note: unicode-math maps \u21e2 to their own function \rightdasharrow. 4810// We'll map it to AMS function \dashrightarrow. It produces the same atom. 4811 4812defineSymbol(math, ams, rel, "\u21e2", "\\dashrightarrow", true); // unicode-math maps \u21e0 to \leftdasharrow. We'll use the AMS synonym. 4813 4814defineSymbol(math, ams, rel, "\u21e0", "\\dashleftarrow", true); 4815defineSymbol(math, ams, rel, "\u21c7", "\\leftleftarrows", true); 4816defineSymbol(math, ams, rel, "\u21c6", "\\leftrightarrows", true); 4817defineSymbol(math, ams, rel, "\u21da", "\\Lleftarrow", true); 4818defineSymbol(math, ams, rel, "\u219e", "\\twoheadleftarrow", true); 4819defineSymbol(math, ams, rel, "\u21a2", "\\leftarrowtail", true); 4820defineSymbol(math, ams, rel, "\u21ab", "\\looparrowleft", true); 4821defineSymbol(math, ams, rel, "\u21cb", "\\leftrightharpoons", true); 4822defineSymbol(math, ams, rel, "\u21b6", "\\curvearrowleft", true); // unicode-math maps \u21ba to \acwopencirclearrow. We'll use the AMS synonym. 4823 4824defineSymbol(math, ams, rel, "\u21ba", "\\circlearrowleft", true); 4825defineSymbol(math, ams, rel, "\u21b0", "\\Lsh", true); 4826defineSymbol(math, ams, rel, "\u21c8", "\\upuparrows", true); 4827defineSymbol(math, ams, rel, "\u21bf", "\\upharpoonleft", true); 4828defineSymbol(math, ams, rel, "\u21c3", "\\downharpoonleft", true); 4829defineSymbol(math, main, rel, "\u22b6", "\\origof", true); // not in font 4830 4831defineSymbol(math, main, rel, "\u22b7", "\\imageof", true); // not in font 4832 4833defineSymbol(math, ams, rel, "\u22b8", "\\multimap", true); 4834defineSymbol(math, ams, rel, "\u21ad", "\\leftrightsquigarrow", true); 4835defineSymbol(math, ams, rel, "\u21c9", "\\rightrightarrows", true); 4836defineSymbol(math, ams, rel, "\u21c4", "\\rightleftarrows", true); 4837defineSymbol(math, ams, rel, "\u21a0", "\\twoheadrightarrow", true); 4838defineSymbol(math, ams, rel, "\u21a3", "\\rightarrowtail", true); 4839defineSymbol(math, ams, rel, "\u21ac", "\\looparrowright", true); 4840defineSymbol(math, ams, rel, "\u21b7", "\\curvearrowright", true); // unicode-math maps \u21bb to \cwopencirclearrow. We'll use the AMS synonym. 4841 4842defineSymbol(math, ams, rel, "\u21bb", "\\circlearrowright", true); 4843defineSymbol(math, ams, rel, "\u21b1", "\\Rsh", true); 4844defineSymbol(math, ams, rel, "\u21ca", "\\downdownarrows", true); 4845defineSymbol(math, ams, rel, "\u21be", "\\upharpoonright", true); 4846defineSymbol(math, ams, rel, "\u21c2", "\\downharpoonright", true); 4847defineSymbol(math, ams, rel, "\u21dd", "\\rightsquigarrow", true); 4848defineSymbol(math, ams, rel, "\u21dd", "\\leadsto"); 4849defineSymbol(math, ams, rel, "\u21db", "\\Rrightarrow", true); 4850defineSymbol(math, ams, rel, "\u21be", "\\restriction"); 4851defineSymbol(math, main, textord, "\u2018", "`"); 4852defineSymbol(math, main, textord, "$", "\\$"); 4853defineSymbol(text, main, textord, "$", "\\$"); 4854defineSymbol(text, main, textord, "$", "\\textdollar"); 4855defineSymbol(math, main, textord, "%", "\\%"); 4856defineSymbol(text, main, textord, "%", "\\%"); 4857defineSymbol(math, main, textord, "_", "\\_"); 4858defineSymbol(text, main, textord, "_", "\\_"); 4859defineSymbol(text, main, textord, "_", "\\textunderscore"); 4860defineSymbol(math, main, textord, "\u2220", "\\angle", true); 4861defineSymbol(math, main, textord, "\u221e", "\\infty", true); 4862defineSymbol(math, main, textord, "\u2032", "\\prime"); 4863defineSymbol(math, main, textord, "\u25b3", "\\triangle"); 4864defineSymbol(math, main, textord, "\u0393", "\\Gamma", true); 4865defineSymbol(math, main, textord, "\u0394", "\\Delta", true); 4866defineSymbol(math, main, textord, "\u0398", "\\Theta", true); 4867defineSymbol(math, main, textord, "\u039b", "\\Lambda", true); 4868defineSymbol(math, main, textord, "\u039e", "\\Xi", true); 4869defineSymbol(math, main, textord, "\u03a0", "\\Pi", true); 4870defineSymbol(math, main, textord, "\u03a3", "\\Sigma", true); 4871defineSymbol(math, main, textord, "\u03a5", "\\Upsilon", true); 4872defineSymbol(math, main, textord, "\u03a6", "\\Phi", true); 4873defineSymbol(math, main, textord, "\u03a8", "\\Psi", true); 4874defineSymbol(math, main, textord, "\u03a9", "\\Omega", true); 4875defineSymbol(math, main, textord, "A", "\u0391"); 4876defineSymbol(math, main, textord, "B", "\u0392"); 4877defineSymbol(math, main, textord, "E", "\u0395"); 4878defineSymbol(math, main, textord, "Z", "\u0396"); 4879defineSymbol(math, main, textord, "H", "\u0397"); 4880defineSymbol(math, main, textord, "I", "\u0399"); 4881defineSymbol(math, main, textord, "K", "\u039A"); 4882defineSymbol(math, main, textord, "M", "\u039C"); 4883defineSymbol(math, main, textord, "N", "\u039D"); 4884defineSymbol(math, main, textord, "O", "\u039F"); 4885defineSymbol(math, main, textord, "P", "\u03A1"); 4886defineSymbol(math, main, textord, "T", "\u03A4"); 4887defineSymbol(math, main, textord, "X", "\u03A7"); 4888defineSymbol(math, main, textord, "\u00ac", "\\neg", true); 4889defineSymbol(math, main, textord, "\u00ac", "\\lnot"); 4890defineSymbol(math, main, textord, "\u22a4", "\\top"); 4891defineSymbol(math, main, textord, "\u22a5", "\\bot"); 4892defineSymbol(math, main, textord, "\u2205", "\\emptyset"); 4893defineSymbol(math, ams, textord, "\u2205", "\\varnothing"); 4894defineSymbol(math, main, mathord, "\u03b1", "\\alpha", true); 4895defineSymbol(math, main, mathord, "\u03b2", "\\beta", true); 4896defineSymbol(math, main, mathord, "\u03b3", "\\gamma", true); 4897defineSymbol(math, main, mathord, "\u03b4", "\\delta", true); 4898defineSymbol(math, main, mathord, "\u03f5", "\\epsilon", true); 4899defineSymbol(math, main, mathord, "\u03b6", "\\zeta", true); 4900defineSymbol(math, main, mathord, "\u03b7", "\\eta", true); 4901defineSymbol(math, main, mathord, "\u03b8", "\\theta", true); 4902defineSymbol(math, main, mathord, "\u03b9", "\\iota", true); 4903defineSymbol(math, main, mathord, "\u03ba", "\\kappa", true); 4904defineSymbol(math, main, mathord, "\u03bb", "\\lambda", true); 4905defineSymbol(math, main, mathord, "\u03bc", "\\mu", true); 4906defineSymbol(math, main, mathord, "\u03bd", "\\nu", true); 4907defineSymbol(math, main, mathord, "\u03be", "\\xi", true); 4908defineSymbol(math, main, mathord, "\u03bf", "\\omicron", true); 4909defineSymbol(math, main, mathord, "\u03c0", "\\pi", true); 4910defineSymbol(math, main, mathord, "\u03c1", "\\rho", true); 4911defineSymbol(math, main, mathord, "\u03c3", "\\sigma", true); 4912defineSymbol(math, main, mathord, "\u03c4", "\\tau", true); 4913defineSymbol(math, main, mathord, "\u03c5", "\\upsilon", true); 4914defineSymbol(math, main, mathord, "\u03d5", "\\phi", true); 4915defineSymbol(math, main, mathord, "\u03c7", "\\chi", true); 4916defineSymbol(math, main, mathord, "\u03c8", "\\psi", true); 4917defineSymbol(math, main, mathord, "\u03c9", "\\omega", true); 4918defineSymbol(math, main, mathord, "\u03b5", "\\varepsilon", true); 4919defineSymbol(math, main, mathord, "\u03d1", "\\vartheta", true); 4920defineSymbol(math, main, mathord, "\u03d6", "\\varpi", true); 4921defineSymbol(math, main, mathord, "\u03f1", "\\varrho", true); 4922defineSymbol(math, main, mathord, "\u03c2", "\\varsigma", true); 4923defineSymbol(math, main, mathord, "\u03c6", "\\varphi", true); 4924defineSymbol(math, main, bin, "\u2217", "*", true); 4925defineSymbol(math, main, bin, "+", "+"); 4926defineSymbol(math, main, bin, "\u2212", "-", true); 4927defineSymbol(math, main, bin, "\u22c5", "\\cdot", true); 4928defineSymbol(math, main, bin, "\u2218", "\\circ", true); 4929defineSymbol(math, main, bin, "\u00f7", "\\div", true); 4930defineSymbol(math, main, bin, "\u00b1", "\\pm", true); 4931defineSymbol(math, main, bin, "\u00d7", "\\times", true); 4932defineSymbol(math, main, bin, "\u2229", "\\cap", true); 4933defineSymbol(math, main, bin, "\u222a", "\\cup", true); 4934defineSymbol(math, main, bin, "\u2216", "\\setminus", true); 4935defineSymbol(math, main, bin, "\u2227", "\\land"); 4936defineSymbol(math, main, bin, "\u2228", "\\lor"); 4937defineSymbol(math, main, bin, "\u2227", "\\wedge", true); 4938defineSymbol(math, main, bin, "\u2228", "\\vee", true); 4939defineSymbol(math, main, textord, "\u221a", "\\surd"); 4940defineSymbol(math, main, open, "\u27e8", "\\langle", true); 4941defineSymbol(math, main, open, "\u2223", "\\lvert"); 4942defineSymbol(math, main, open, "\u2225", "\\lVert"); 4943defineSymbol(math, main, close, "?", "?"); 4944defineSymbol(math, main, close, "!", "!"); 4945defineSymbol(math, main, close, "\u27e9", "\\rangle", true); 4946defineSymbol(math, main, close, "\u2223", "\\rvert"); 4947defineSymbol(math, main, close, "\u2225", "\\rVert"); 4948defineSymbol(math, main, rel, "=", "="); 4949defineSymbol(math, main, rel, ":", ":"); 4950defineSymbol(math, main, rel, "\u2248", "\\approx", true); 4951defineSymbol(math, main, rel, "\u2245", "\\cong", true); 4952defineSymbol(math, main, rel, "\u2265", "\\ge"); 4953defineSymbol(math, main, rel, "\u2265", "\\geq", true); 4954defineSymbol(math, main, rel, "\u2190", "\\gets"); 4955defineSymbol(math, main, rel, ">", "\\gt", true); 4956defineSymbol(math, main, rel, "\u2208", "\\in", true); 4957defineSymbol(math, main, rel, "\ue020", "\\@not"); 4958defineSymbol(math, main, rel, "\u2282", "\\subset", true); 4959defineSymbol(math, main, rel, "\u2283", "\\supset", true); 4960defineSymbol(math, main, rel, "\u2286", "\\subseteq", true); 4961defineSymbol(math, main, rel, "\u2287", "\\supseteq", true); 4962defineSymbol(math, ams, rel, "\u2288", "\\nsubseteq", true); 4963defineSymbol(math, ams, rel, "\u2289", "\\nsupseteq", true); 4964defineSymbol(math, main, rel, "\u22a8", "\\models"); 4965defineSymbol(math, main, rel, "\u2190", "\\leftarrow", true); 4966defineSymbol(math, main, rel, "\u2264", "\\le"); 4967defineSymbol(math, main, rel, "\u2264", "\\leq", true); 4968defineSymbol(math, main, rel, "<", "\\lt", true); 4969defineSymbol(math, main, rel, "\u2192", "\\rightarrow", true); 4970defineSymbol(math, main, rel, "\u2192", "\\to"); 4971defineSymbol(math, ams, rel, "\u2271", "\\ngeq", true); 4972defineSymbol(math, ams, rel, "\u2270", "\\nleq", true); 4973defineSymbol(math, main, spacing, "\u00a0", "\\ "); 4974defineSymbol(math, main, spacing, "\u00a0", "\\space"); // Ref: LaTeX Source 2e: \DeclareRobustCommand{\nobreakspace}{% 4975 4976defineSymbol(math, main, spacing, "\u00a0", "\\nobreakspace"); 4977defineSymbol(text, main, spacing, "\u00a0", "\\ "); 4978defineSymbol(text, main, spacing, "\u00a0", " "); 4979defineSymbol(text, main, spacing, "\u00a0", "\\space"); 4980defineSymbol(text, main, spacing, "\u00a0", "\\nobreakspace"); 4981defineSymbol(math, main, spacing, null, "\\nobreak"); 4982defineSymbol(math, main, spacing, null, "\\allowbreak"); 4983defineSymbol(math, main, punct, ",", ","); 4984defineSymbol(math, main, punct, ";", ";"); 4985defineSymbol(math, ams, bin, "\u22bc", "\\barwedge", true); 4986defineSymbol(math, ams, bin, "\u22bb", "\\veebar", true); 4987defineSymbol(math, main, bin, "\u2299", "\\odot", true); 4988defineSymbol(math, main, bin, "\u2295", "\\oplus", true); 4989defineSymbol(math, main, bin, "\u2297", "\\otimes", true); 4990defineSymbol(math, main, textord, "\u2202", "\\partial", true); 4991defineSymbol(math, main, bin, "\u2298", "\\oslash", true); 4992defineSymbol(math, ams, bin, "\u229a", "\\circledcirc", true); 4993defineSymbol(math, ams, bin, "\u22a1", "\\boxdot", true);
4994defineSymbol(math, main, bin, "\u25b3", "\\bigtriangleup"); 4995defineSymbol(math, main, bin, "\u25bd", "\\bigtriangledown"); 4996defineSymbol(math, main, bin, "\u2020", "\\dagger"); 4997defineSymbol(math, main, bin, "\u22c4", "\\diamond"); 4998defineSymbol(math, main, bin, "\u22c6", "\\star"); 4999defineSymbol(math, main, bin, "\u25c3", "\\triangleleft"); 5000defineSymbol(math, main, bin, "\u25b9", "\\triangleright"); 5001defineSymbol(math, main, open, "{", "\\{"); 5002defineSymbol(text, main, textord, "{", "\\{"); 5003defineSymbol(text, main, textord, "{", "\\textbraceleft"); 5004defineSymbol(math, main, close, "}", "\\}"); 5005defineSymbol(text, main, textord, "}", "\\}"); 5006defineSymbol(text, main, textord, "}", "\\textbraceright"); 5007defineSymbol(math, main, open, "{", "\\lbrace"); 5008defineSymbol(math, main, close, "}", "\\rbrace"); 5009defineSymbol(math, main, open, "[", "\\lbrack", true); 5010defineSymbol(text, main, textord, "[", "\\lbrack", true); 5011defineSymbol(math, main, close, "]", "\\rbrack", true); 5012defineSymbol(text, main, textord, "]", "\\rbrack", true); 5013defineSymbol(math, main, open, "(", "\\lparen", true); 5014defineSymbol(math, main, close, ")", "\\rparen", true); 5015defineSymbol(text, main, textord, "<", "\\textless", true); // in T1 fontenc 5016 5017defineSymbol(text, main, textord, ">", "\\textgreater", true); // in T1 fontenc 5018 5019defineSymbol(math, main, open, "\u230a", "\\lfloor", true); 5020defineSymbol(math, main, close, "\u230b", "\\rfloor", true); 5021defineSymbol(math, main, open, "\u2308", "\\lceil", true); 5022defineSymbol(math, main, close, "\u2309", "\\rceil", true); 5023defineSymbol(math, main, textord, "\\", "\\backslash"); 5024defineSymbol(math, main, textord, "\u2223", "|"); 5025defineSymbol(math, main, textord, "\u2223", "\\vert"); 5026defineSymbol(text, main, textord, "|", "\\textbar", true); // in T1 fontenc 5027 5028defineSymbol(math, main, textord, "\u2225", "\\|"); 5029defineSymbol(math, main, textord, "\u2225", "\\Vert"); 5030defineSymbol(text, main, textord, "\u2225", "\\textbardbl"); 5031defineSymbol(text, main, textord, "~", "\\textasciitilde"); 5032defineSymbol(text, main, textord, "\\", "\\textbackslash"); 5033defineSymbol(text, main, textord, "^", "\\textasciicircum"); 5034defineSymbol(math, main, rel, "\u2191", "\\uparrow", true); 5035defineSymbol(math, main, rel, "\u21d1", "\\Uparrow", true); 5036defineSymbol(math, main, rel, "\u2193", "\\downarrow", true); 5037defineSymbol(math, main, rel, "\u21d3", "\\Downarrow", true); 5038defineSymbol(math, main, rel, "\u2195", "\\updownarrow", true); 5039defineSymbol(math, main, rel, "\u21d5", "\\Updownarrow", true); 5040defineSymbol(math, main, op, "\u2210", "\\coprod"); 5041defineSymbol(math, main, op, "\u22c1", "\\bigvee"); 5042defineSymbol(math, main, op, "\u22c0", "\\bigwedge"); 5043defineSymbol(math, main, op, "\u2a04", "\\biguplus"); 5044defineSymbol(math, main, op, "\u22c2", "\\bigcap"); 5045defineSymbol(math, main, op, "\u22c3", "\\bigcup"); 5046defineSymbol(math, main, op, "\u222b", "\\int"); 5047defineSymbol(math, main, op, "\u222b", "\\intop"); 5048defineSymbol(math, main, op, "\u222c", "\\iint"); 5049defineSymbol(math, main, op, "\u222d", "\\iiint"); 5050defineSymbol(math, main, op, "\u220f", "\\prod"); 5051defineSymbol(math, main, op, "\u2211", "\\sum"); 5052defineSymbol(math, main, op, "\u2a02", "\\bigotimes"); 5053defineSymbol(math, main, op, "\u2a01", "\\bigoplus"); 5054defineSymbol(math, main, op, "\u2a00", "\\bigodot"); 5055defineSymbol(math, main, op, "\u222e", "\\oint"); 5056defineSymbol(math, main, op, "\u222f", "\\oiint"); 5057defineSymbol(math, main, op, "\u2230", "\\oiiint"); 5058defineSymbol(math, main, op, "\u2a06", "\\bigsqcup"); 5059defineSymbol(math, main, op, "\u222b", "\\smallint"); 5060defineSymbol(text, main, inner, "\u2026", "\\textellipsis"); 5061defineSymbol(math, main, inner, "\u2026", "\\mathellipsis"); 5062defineSymbol(text, main, inner, "\u2026", "\\ldots", true); 5063defineSymbol(math, main, inner, "\u2026", "\\ldots", true); 5064defineSymbol(math, main, inner, "\u22ef", "\\@cdots", true); 5065defineSymbol(math, main, inner, "\u22f1", "\\ddots", true); // \vdots is a macro that uses one of these two symbols (with made-up names): 5066 5067defineSymbol(math, main, textord, "\u22ee", "\\varvdots"); 5068defineSymbol(text, main, textord, "\u22ee", "\\varvdots"); 5069defineSymbol(math, main, accent, "\u02ca", "\\acute"); 5070defineSymbol(math, main, accent, "\u02cb", "\\grave"); 5071defineSymbol(math, main, accent, "\u00a8", "\\ddot"); 5072defineSymbol(math, main, accent, "\u007e", "\\tilde"); 5073defineSymbol(math, main, accent, "\u02c9", "\\bar"); 5074defineSymbol(math, main, accent, "\u02d8", "\\breve"); 5075defineSymbol(math, main, accent, "\u02c7", "\\check"); 5076defineSymbol(math, main, accent, "\u005e", "\\hat"); 5077defineSymbol(math, main, accent, "\u20d7", "\\vec"); 5078defineSymbol(math, main, accent, "\u02d9", "\\dot"); 5079defineSymbol(math, main, accent, "\u02da", "\\mathring"); // \imath and \jmath should be invariant to \mathrm, \mathbf, etc., so use PUA 5080 5081defineSymbol(math, main, mathord, "\ue131", "\\@imath"); 5082defineSymbol(math, main, mathord, "\ue237", "\\@jmath"); 5083defineSymbol(math, main, textord, "\u0131", "\u0131"); 5084defineSymbol(math, main, textord, "\u0237", "\u0237"); 5085defineSymbol(text, main, textord, "\u0131", "\\i", true); 5086defineSymbol(text, main, textord, "\u0237", "\\j", true); 5087defineSymbol(text, main, textord, "\u00df", "\\ss", true); 5088defineSymbol(text, main, textord, "\u00e6", "\\ae", true); 5089defineSymbol(text, main, textord, "\u0153", "\\oe", true); 5090defineSymbol(text, main, textord, "\u00f8", "\\o", true); 5091defineSymbol(text, main, textord, "\u00c6", "\\AE", true); 5092defineSymbol(text, main, textord, "\u0152", "\\OE", true); 5093defineSymbol(text, main, textord, "\u00d8", "\\O", true); 5094defineSymbol(text, main, accent, "\u02ca", "\\'"); // acute 5095 5096defineSymbol(text, main, accent, "\u02cb", "\\`"); // grave 5097 5098defineSymbol(text, main, accent, "\u02c6", "\\^"); // circumflex 5099 5100defineSymbol(text, main, accent, "\u02dc", "\\~"); // tilde 5101 5102defineSymbol(text, main, accent, "\u02c9", "\\="); // macron 5103 5104defineSymbol(text, main, accent, "\u02d8", "\\u"); // breve 5105 5106defineSymbol(text, main, accent, "\u02d9", "\\."); // dot above 5107 5108defineSymbol(text, main, accent, "\u00b8", "\\c"); // cedilla 5109 5110defineSymbol(text, main, accent, "\u02da", "\\r"); // ring above 5111 5112defineSymbol(text, main, accent, "\u02c7", "\\v"); // caron 5113 5114defineSymbol(text, main, accent, "\u00a8", '\\"'); // diaresis 5115 5116defineSymbol(text, main, accent, "\u02dd", "\\H"); // double acute 5117 5118defineSymbol(text, main, accent, "\u25ef", "\\textcircled"); // \bigcirc glyph 5119// These ligatures are detected and created in Parser.js's `formLigatures`. 5120 5121var ligatures = { 5122 "--": true, 5123 "---": true, 5124 "``": true, 5125 "''": true 5126};
vendor: 14,159 bytes, lines 5127-5468
5127defineSymbol(text, main, textord, "\u2013", "--", true); 5128defineSymbol(text, main, textord, "\u2013", "\\textendash"); 5129defineSymbol(text, main, textord, "\u2014", "---", true); 5130defineSymbol(text, main, textord, "\u2014", "\\textemdash"); 5131defineSymbol(text, main, textord, "\u2018", "`", true); 5132defineSymbol(text, main, textord, "\u2018", "\\textquoteleft"); 5133defineSymbol(text, main, textord, "\u2019", "'", true); 5134defineSymbol(text, main, textord, "\u2019", "\\textquoteright"); 5135defineSymbol(text, main, textord, "\u201c", "``", true); 5136defineSymbol(text, main, textord, "\u201c", "\\textquotedblleft"); 5137defineSymbol(text, main, textord, "\u201d", "''", true); 5138defineSymbol(text, main, textord, "\u201d", "\\textquotedblright"); // \degree from gensymb package 5139 5140defineSymbol(math, main, textord, "\u00b0", "\\degree", true); 5141defineSymbol(text, main, textord, "\u00b0", "\\degree"); // \textdegree from inputenc package 5142 5143defineSymbol(text, main, textord, "\u00b0", "\\textdegree", true); // TODO: In LaTeX, \pounds can generate a different character in text and math 5144// mode, but among our fonts, only Main-Regular defines this character "163". 5145 5146defineSymbol(math, main, textord, "\u00a3", "\\pounds"); 5147defineSymbol(math, main, textord, "\u00a3", "\\mathsterling", true); 5148defineSymbol(text, main, textord, "\u00a3", "\\pounds"); 5149defineSymbol(text, main, textord, "\u00a3", "\\textsterling", true); 5150defineSymbol(math, ams, textord, "\u2720", "\\maltese"); 5151defineSymbol(text, ams, textord, "\u2720", "\\maltese"); // There are lots of symbols which are the same, so we add them in afterwards. 5152// All of these are textords in math mode 5153 5154var mathTextSymbols = "0123456789/@.\""; 5155 5156for (var i = 0; i < mathTextSymbols.length; i++) { 5157 var ch = mathTextSymbols.charAt(i); 5158 defineSymbol(math, main, textord, ch, ch); 5159} // All of these are textords in text mode 5160 5161 5162var textSymbols = "0123456789!@*()-=+\";:?/.,"; 5163 5164for (var _i = 0; _i < textSymbols.length; _i++) { 5165 var _ch = textSymbols.charAt(_i); 5166 5167 defineSymbol(text, main, textord, _ch, _ch); 5168} // All of these are textords in text mode, and mathords in math mode 5169 5170 5171var letters = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz"; 5172 5173for (var _i2 = 0; _i2 < letters.length; _i2++) { 5174 var _ch2 = letters.charAt(_i2); 5175 5176 defineSymbol(math, main, mathord, _ch2, _ch2); 5177 defineSymbol(text, main, textord, _ch2, _ch2); 5178} // Blackboard bold and script letters in Unicode range 5179 5180 5181defineSymbol(math, ams, textord, "C", "\u2102"); // blackboard bold 5182 5183defineSymbol(text, ams, textord, "C", "\u2102"); 5184defineSymbol(math, ams, textord, "H", "\u210D"); 5185defineSymbol(text, ams, textord, "H", "\u210D"); 5186defineSymbol(math, ams, textord, "N", "\u2115"); 5187defineSymbol(text, ams, textord, "N", "\u2115"); 5188defineSymbol(math, ams, textord, "P", "\u2119"); 5189defineSymbol(text, ams, textord, "P", "\u2119"); 5190defineSymbol(math, ams, textord, "Q", "\u211A"); 5191defineSymbol(text, ams, textord, "Q", "\u211A"); 5192defineSymbol(math, ams, textord, "R", "\u211D"); 5193defineSymbol(text, ams, textord, "R", "\u211D"); 5194defineSymbol(math, ams, textord, "Z", "\u2124"); 5195defineSymbol(text, ams, textord, "Z", "\u2124"); 5196defineSymbol(math, main, mathord, "h", "\u210E"); // italic h, Planck constant 5197 5198defineSymbol(text, main, mathord, "h", "\u210E"); // The next loop loads wide (surrogate pair) characters. 5199// We support some letters in the Unicode range U+1D400 to U+1D7FF, 5200// Mathematical Alphanumeric Symbols. 5201// Some editors do not deal well with wide characters. So don't write the 5202// string into this file. Instead, create the string from the surrogate pair. 5203 5204var wideChar = ""; 5205 5206for (var _i3 = 0; _i3 < letters.length; _i3++) { 5207 var _ch3 = letters.charAt(_i3); // The hex numbers in the next line are a surrogate pair. 5208 // 0xD835 is the high surrogate for all letters in the range we support. 5209 // 0xDC00 is the low surrogate for bold A. 5210 5211 5212 wideChar = String.fromCharCode(0xD835, 0xDC00 + _i3); // A-Z a-z bold 5213 5214 defineSymbol(math, main, mathord, _ch3, wideChar); 5215 defineSymbol(text, main, textord, _ch3, wideChar); 5216 wideChar = String.fromCharCode(0xD835, 0xDC34 + _i3); // A-Z a-z italic 5217 5218 defineSymbol(math, main, mathord, _ch3, wideChar); 5219 defineSymbol(text, main, textord, _ch3, wideChar); 5220 wideChar = String.fromCharCode(0xD835, 0xDC68 + _i3); // A-Z a-z bold italic 5221 5222 defineSymbol(math, main, mathord, _ch3, wideChar); 5223 defineSymbol(text, main, textord, _ch3, wideChar); 5224 wideChar = String.fromCharCode(0xD835, 0xDD04 + _i3); // A-Z a-z Fraktur 5225 5226 defineSymbol(math, main, mathord, _ch3, wideChar); 5227 defineSymbol(text, main, textord, _ch3, wideChar); 5228 wideChar = String.fromCharCode(0xD835, 0xDD6C + _i3); // A-Z a-z bold Fraktur 5229 5230 defineSymbol(math, main, mathord, _ch3, wideChar); 5231 defineSymbol(text, main, textord, _ch3, wideChar); 5232 wideChar = String.fromCharCode(0xD835, 0xDDA0 + _i3); // A-Z a-z sans-serif 5233 5234 defineSymbol(math, main, mathord, _ch3, wideChar); 5235 defineSymbol(text, main, textord, _ch3, wideChar); 5236 wideChar = String.fromCharCode(0xD835, 0xDDD4 + _i3); // A-Z a-z sans bold 5237 5238 defineSymbol(math, main, mathord, _ch3, wideChar); 5239 defineSymbol(text, main, textord, _ch3, wideChar); 5240 wideChar = String.fromCharCode(0xD835, 0xDE08 + _i3); // A-Z a-z sans italic 5241 5242 defineSymbol(math, main, mathord, _ch3, wideChar); 5243 defineSymbol(text, main, textord, _ch3, wideChar); 5244 wideChar = String.fromCharCode(0xD835, 0xDE70 + _i3); // A-Z a-z monospace 5245 5246 defineSymbol(math, main, mathord, _ch3, wideChar); 5247 defineSymbol(text, main, textord, _ch3, wideChar); 5248 5249 if (_i3 < 26) { 5250 // KaTeX fonts have only capital letters for blackboard bold and script. 5251 // See exception for k below. 5252 wideChar = String.fromCharCode(0xD835, 0xDD38 + _i3); // A-Z double struck 5253 5254 defineSymbol(math, main, mathord, _ch3, wideChar); 5255 defineSymbol(text, main, textord, _ch3, wideChar); 5256 wideChar = String.fromCharCode(0xD835, 0xDC9C + _i3); // A-Z script 5257 5258 defineSymbol(math, main, mathord, _ch3, wideChar); 5259 defineSymbol(text, main, textord, _ch3, wideChar); 5260 } // TODO: Add bold script when it is supported by a KaTeX font. 5261 5262} // "k" is the only double struck lower case letter in the KaTeX fonts. 5263 5264 5265wideChar = String.fromCharCode(0xD835, 0xDD5C); // k double struck 5266 5267defineSymbol(math, main, mathord, "k", wideChar); 5268defineSymbol(text, main, textord, "k", wideChar); // Next, some wide character numerals 5269 5270for (var _i4 = 0; _i4 < 10; _i4++) { 5271 var _ch4 = _i4.toString(); 5272 5273 wideChar = String.fromCharCode(0xD835, 0xDFCE + _i4); // 0-9 bold 5274 5275 defineSymbol(math, main, mathord, _ch4, wideChar); 5276 defineSymbol(text, main, textord, _ch4, wideChar); 5277 wideChar = String.fromCharCode(0xD835, 0xDFE2 + _i4); // 0-9 sans serif 5278 5279 defineSymbol(math, main, mathord, _ch4, wideChar); 5280 defineSymbol(text, main, textord, _ch4, wideChar); 5281 wideChar = String.fromCharCode(0xD835, 0xDFEC + _i4); // 0-9 bold sans 5282 5283 defineSymbol(math, main, mathord, _ch4, wideChar); 5284 defineSymbol(text, main, textord, _ch4, wideChar); 5285 wideChar = String.fromCharCode(0xD835, 0xDFF6 + _i4); // 0-9 monospace 5286 5287 defineSymbol(math, main, mathord, _ch4, wideChar); 5288 defineSymbol(text, main, textord, _ch4, wideChar); 5289} // We add these Latin-1 letters as symbols for backwards-compatibility, 5290// but they are not actually in the font, nor are they supported by the 5291// Unicode accent mechanism, so they fall back to Times font and look ugly. 5292// TODO(edemaine): Fix this. 5293 5294 5295var extraLatin = "\u00d0\u00de\u00fe"; 5296 5297for (var _i5 = 0; _i5 < extraLatin.length; _i5++) { 5298 var _ch5 = extraLatin.charAt(_i5); 5299 5300 defineSymbol(math, main, mathord, _ch5, _ch5); 5301 defineSymbol(text, main, textord, _ch5, _ch5); 5302} 5303 5304/** 5305 * This file provides support for Unicode range U+1D400 to U+1D7FF, 5306 * Mathematical Alphanumeric Symbols. 5307 * 5308 * Function wideCharacterFont takes a wide character as input and returns 5309 * the font information necessary to render it properly. 5310 */ 5311/** 5312 * Data below is from https://www.unicode.org/charts/PDF/U1D400.pdf 5313 * That document sorts characters into groups by font type, say bold or italic. 5314 * 5315 * In the arrays below, each subarray consists three elements: 5316 * * The CSS class of that group when in math mode. 5317 * * The CSS class of that group when in text mode. 5318 * * The font name, so that KaTeX can get font metrics. 5319 */ 5320 5321var wideLatinLetterData = [["mathbf", "textbf", "Main-Bold"], // A-Z bold upright 5322["mathbf", "textbf", "Main-Bold"], // a-z bold upright 5323["mathnormal", "textit", "Math-Italic"], // A-Z italic 5324["mathnormal", "textit", "Math-Italic"], // a-z italic 5325["boldsymbol", "boldsymbol", "Main-BoldItalic"], // A-Z bold italic 5326["boldsymbol", "boldsymbol", "Main-BoldItalic"], // a-z bold italic 5327// Map fancy A-Z letters to script, not calligraphic. 5328// This aligns with unicode-math and math fonts (except Cambria Math). 5329["mathscr", "textscr", "Script-Regular"], // A-Z script 5330["", "", ""], // a-z script. No font 5331["", "", ""], // A-Z bold script. No font 5332["", "", ""], // a-z bold script. No font 5333["mathfrak", "textfrak", "Fraktur-Regular"], // A-Z Fraktur 5334["mathfrak", "textfrak", "Fraktur-Regular"], // a-z Fraktur 5335["mathbb", "textbb", "AMS-Regular"], // A-Z double-struck 5336["mathbb", "textbb", "AMS-Regular"], // k double-struck 5337// Note that we are using a bold font, but font metrics for regular Fraktur. 5338["mathboldfrak", "textboldfrak", "Fraktur-Regular"], // A-Z bold Fraktur 5339["mathboldfrak", "textboldfrak", "Fraktur-Regular"], // a-z bold Fraktur 5340["mathsf", "textsf", "SansSerif-Regular"], // A-Z sans-serif 5341["mathsf", "textsf", "SansSerif-Regular"], // a-z sans-serif 5342["mathboldsf", "textboldsf", "SansSerif-Bold"], // A-Z bold sans-serif 5343["mathboldsf", "textboldsf", "SansSerif-Bold"], // a-z bold sans-serif 5344["mathitsf", "textitsf", "SansSerif-Italic"], // A-Z italic sans-serif 5345["mathitsf", "textitsf", "SansSerif-Italic"], // a-z italic sans-serif 5346["", "", ""], // A-Z bold italic sans. No font 5347["", "", ""], // a-z bold italic sans. No font 5348["mathtt", "texttt", "Typewriter-Regular"], // A-Z monospace 5349["mathtt", "texttt", "Typewriter-Regular"] // a-z monospace 5350]; 5351var wideNumeralData = [["mathbf", "textbf", "Main-Bold"], // 0-9 bold 5352["", "", ""], // 0-9 double-struck. No KaTeX font. 5353["mathsf", "textsf", "SansSerif-Regular"], // 0-9 sans-serif 5354["mathboldsf", "textboldsf", "SansSerif-Bold"], // 0-9 bold sans-serif 5355["mathtt", "texttt", "Typewriter-Regular"] // 0-9 monospace 5356]; 5357var wideCharacterFont = function wideCharacterFont(wideChar, mode) { 5358 // IE doesn't support codePointAt(). So work with the surrogate pair. 5359 var H = wideChar.charCodeAt(0); // high surrogate 5360 5361 var L = wideChar.charCodeAt(1); // low surrogate 5362 5363 var codePoint = (H - 0xD800) * 0x400 + (L - 0xDC00) + 0x10000; 5364 var j = mode === "math" ? 0 : 1; // column index for CSS class. 5365 5366 if (0x1D400 <= codePoint && codePoint < 0x1D6A4) { 5367 // wideLatinLetterData contains exactly 26 chars on each row. 5368 // So we can calculate the relevant row. No traverse necessary. 5369 var i = Math.floor((codePoint - 0x1D400) / 26); 5370 return [wideLatinLetterData[i][2], wideLatinLetterData[i][j]]; 5371 } else if (0x1D7CE <= codePoint && codePoint <= 0x1D7FF) { 5372 // Numerals, ten per row. 5373 var _i = Math.floor((codePoint - 0x1D7CE) / 10); 5374 5375 return [wideNumeralData[_i][2], wideNumeralData[_i][j]]; 5376 } else if (codePoint === 0x1D6A5 || codePoint === 0x1D6A6) { 5377 // dotless i or j 5378 return [wideLatinLetterData[0][2], wideLatinLetterData[0][j]]; 5379 } else if (0x1D6A6 < codePoint && codePoint < 0x1D7CE) { 5380 // Greek letters. Not supported, yet. 5381 return ["", ""]; 5382 } else { 5383 // We don't support any wide characters outside 1D400â1D7FF. 5384 throw new ParseError("Unsupported character: " + wideChar); 5385 } 5386}; 5387 5388/* eslint no-console:0 */ 5389 5390/** 5391 * Looks up the given symbol in fontMetrics, after applying any symbol 5392 * replacements defined in symbol.js 5393 */ 5394var lookupSymbol = function lookupSymbol(value, // TODO(#963): Use a union type for this. 5395fontName, mode) { 5396 // Replace the value with its replaced value from symbol.js 5397 if (symbols[mode][value] && symbols[mode][value].replace) { 5398 value = symbols[mode][value].replace; 5399 } 5400 5401 return { 5402 value: value, 5403 metrics: getCharacterMetrics(value, fontName, mode) 5404 }; 5405}; 5406/** 5407 * Makes a symbolNode after translation via the list of symbols in symbols.js. 5408 * Correctly pulls out metrics for the character, and optionally takes a list of 5409 * classes to be attached to the node. 5410 * 5411 * TODO: make argument order closer to makeSpan 5412 * TODO: add a separate argument for math class (e.g. `mop`, `mbin`), which 5413 * should if present come first in `classes`. 5414 * TODO(#953): Make `options` mandatory and always pass it in. 5415 */ 5416 5417 5418var makeSymbol = function makeSymbol(value, fontName, mode, options, classes) { 5419 var lookup = lookupSymbol(value, fontName, mode); 5420 var metrics = lookup.metrics; 5421 value = lookup.value; 5422 var symbolNode; 5423 5424 if (metrics) { 5425 var italic = metrics.italic; 5426 5427 if (mode === "text" || options && options.font === "mathit") { 5428 italic = 0; 5429 } 5430 5431 symbolNode = new SymbolNode(value, metrics.height, metrics.depth, italic, metrics.skew, metrics.width, classes); 5432 } else { 5433 // TODO(emily): Figure out a good way to only print this in development 5434 typeof console !== "undefined" && console.warn("No character metrics " + ("for '" + value + "' in style '" + fontName + "' and mode '" + mode + "'")); 5435 symbolNode = new SymbolNode(value, 0, 0, 0, 0, 0, classes); 5436 } 5437 5438 if (options) { 5439 symbolNode.maxFontSize = options.sizeMultiplier; 5440 5441 if (options.style.isTight()) { 5442 symbolNode.classes.push("mtight"); 5443 } 5444 5445 var color = options.getColor(); 5446 5447 if (color) { 5448 symbolNode.style.color = color; 5449 } 5450 } 5451 5452 return symbolNode; 5453}; 5454/** 5455 * Makes a symbol in Main-Regular or AMS-Regular. 5456 * Used for rel, bin, open, close, inner, and punct. 5457 */ 5458 5459 5460var mathsym = function mathsym(value, mode, options, classes) { 5461 if (classes === void 0) { 5462 classes = []; 5463 } 5464 5465 // Decide what font to render the symbol in by its entry in the symbols 5466 // table. 5467 // Have a special case for when the value = \ because the \ is used as a 5468 // textord in unsupported command errors but cannot be parsed as a regular
vendor: 18,539 bytes, lines 5469-6085
5469 // text ordinal and is therefore not present as a symbol in the symbols 5470 // table for text, as well as a special case for boldsymbol because it 5471 // can be used for bold + and - 5472 if (options.font === "boldsymbol" && lookupSymbol(value, "Main-Bold", mode).metrics) { 5473 return makeSymbol(value, "Main-Bold", mode, options, classes.concat(["mathbf"])); 5474 } else if (value === "\\" || symbols[mode][value].font === "main") { 5475 return makeSymbol(value, "Main-Regular", mode, options, classes); 5476 } else { 5477 return makeSymbol(value, "AMS-Regular", mode, options, classes.concat(["amsrm"])); 5478 } 5479}; 5480/** 5481 * Determines which of the two font names (Main-Bold and Math-BoldItalic) and 5482 * corresponding style tags (mathbf or boldsymbol) to use for font "boldsymbol", 5483 * depending on the symbol. Use this function instead of fontMap for font 5484 * "boldsymbol". 5485 */ 5486 5487 5488var boldsymbol = function boldsymbol(value, mode, options, classes, type) { 5489 if (type !== "textord" && lookupSymbol(value, "Math-BoldItalic", mode).metrics) { 5490 return { 5491 fontName: "Math-BoldItalic", 5492 fontClass: "boldsymbol" 5493 }; 5494 } else { 5495 // Some glyphs do not exist in Math-BoldItalic so we need to use 5496 // Main-Bold instead. 5497 return { 5498 fontName: "Main-Bold", 5499 fontClass: "mathbf" 5500 }; 5501 } 5502}; 5503/** 5504 * Makes either a mathord or textord in the correct font and color. 5505 */ 5506 5507 5508var makeOrd = function makeOrd(group, options, type) { 5509 var mode = group.mode; 5510 var text = group.text; 5511 var classes = ["mord"]; // Math mode or Old font (i.e. \rm) 5512 5513 var isFont = mode === "math" || mode === "text" && options.font; 5514 var fontOrFamily = isFont ? options.font : options.fontFamily; 5515 var wideFontName = ""; 5516 var wideFontClass = ""; 5517 5518 if (text.charCodeAt(0) === 0xD835) { 5519 [wideFontName, wideFontClass] = wideCharacterFont(text, mode); 5520 } 5521 5522 if (wideFontName.length > 0) { 5523 // surrogate pairs get special treatment 5524 return makeSymbol(text, wideFontName, mode, options, classes.concat(wideFontClass)); 5525 } else if (fontOrFamily) { 5526 var fontName; 5527 var fontClasses; 5528 5529 if (fontOrFamily === "boldsymbol") { 5530 var fontData = boldsymbol(text, mode, options, classes, type); 5531 fontName = fontData.fontName; 5532 fontClasses = [fontData.fontClass]; 5533 } else if (isFont) { 5534 fontName = fontMap[fontOrFamily].fontName; 5535 fontClasses = [fontOrFamily]; 5536 } else { 5537 fontName = retrieveTextFontName(fontOrFamily, options.fontWeight, options.fontShape); 5538 fontClasses = [fontOrFamily, options.fontWeight, options.fontShape]; 5539 } 5540 5541 if (lookupSymbol(text, fontName, mode).metrics) { 5542 return makeSymbol(text, fontName, mode, options, classes.concat(fontClasses)); 5543 } else if (ligatures.hasOwnProperty(text) && fontName.slice(0, 10) === "Typewriter") { 5544 // Deconstruct ligatures in monospace fonts (\texttt, \tt). 5545 var parts = []; 5546 5547 for (var i = 0; i < text.length; i++) { 5548 parts.push(makeSymbol(text[i], fontName, mode, options, classes.concat(fontClasses))); 5549 } 5550 5551 return makeFragment(parts); 5552 } 5553 } // Makes a symbol in the default font for mathords and textords. 5554 5555 5556 if (type === "mathord") { 5557 return makeSymbol(text, "Math-Italic", mode, options, classes.concat(["mathnormal"])); 5558 } else if (type === "textord") { 5559 var font = symbols[mode][text] && symbols[mode][text].font; 5560 5561 if (font === "ams") { 5562 var _fontName = retrieveTextFontName("amsrm", options.fontWeight, options.fontShape); 5563 5564 return makeSymbol(text, _fontName, mode, options, classes.concat("amsrm", options.fontWeight, options.fontShape)); 5565 } else if (font === "main" || !font) { 5566 var _fontName2 = retrieveTextFontName("textrm", options.fontWeight, options.fontShape); 5567 5568 return makeSymbol(text, _fontName2, mode, options, classes.concat(options.fontWeight, options.fontShape)); 5569 } else { 5570 // fonts added by plugins 5571 var _fontName3 = retrieveTextFontName(font, options.fontWeight, options.fontShape); // We add font name as a css class 5572 5573 5574 return makeSymbol(text, _fontName3, mode, options, classes.concat(_fontName3, options.fontWeight, options.fontShape)); 5575 } 5576 } else { 5577 throw new Error("unexpected type: " + type + " in makeOrd"); 5578 } 5579}; 5580/** 5581 * Returns true if subsequent symbolNodes have the same classes, skew, maxFont, 5582 * and styles. 5583 */ 5584 5585 5586var canCombine = (prev, next) => { 5587 if (createClass(prev.classes) !== createClass(next.classes) || prev.skew !== next.skew || prev.maxFontSize !== next.maxFontSize) { 5588 return false; 5589 } // If prev and next both are just "mbin"s or "mord"s we don't combine them 5590 // so that the proper spacing can be preserved. 5591 5592 5593 if (prev.classes.length === 1) { 5594 var cls = prev.classes[0]; 5595 5596 if (cls === "mbin" || cls === "mord") { 5597 return false; 5598 } 5599 } 5600 5601 for (var style in prev.style) { 5602 if (prev.style.hasOwnProperty(style) && prev.style[style] !== next.style[style]) { 5603 return false; 5604 } 5605 } 5606 5607 for (var _style in next.style) { 5608 if (next.style.hasOwnProperty(_style) && prev.style[_style] !== next.style[_style]) { 5609 return false; 5610 } 5611 } 5612 5613 return true; 5614}; 5615/** 5616 * Combine consecutive domTree.symbolNodes into a single symbolNode. 5617 * Note: this function mutates the argument. 5618 */ 5619 5620 5621var tryCombineChars = chars => { 5622 for (var i = 0; i < chars.length - 1; i++) { 5623 var prev = chars[i]; 5624 var next = chars[i + 1]; 5625 5626 if (prev instanceof SymbolNode && next instanceof SymbolNode && canCombine(prev, next)) { 5627 prev.text += next.text; 5628 prev.height = Math.max(prev.height, next.height); 5629 prev.depth = Math.max(prev.depth, next.depth); // Use the last character's italic correction since we use 5630 // it to add padding to the right of the span created from 5631 // the combined characters. 5632 5633 prev.italic = next.italic; 5634 chars.splice(i + 1, 1); 5635 i--; 5636 } 5637 } 5638 5639 return chars; 5640}; 5641/** 5642 * Calculate the height, depth, and maxFontSize of an element based on its 5643 * children. 5644 */ 5645 5646 5647var sizeElementFromChildren = function sizeElementFromChildren(elem) { 5648 var height = 0; 5649 var depth = 0; 5650 var maxFontSize = 0; 5651 5652 for (var i = 0; i < elem.children.length; i++) { 5653 var child = elem.children[i]; 5654 5655 if (child.height > height) { 5656 height = child.height; 5657 } 5658 5659 if (child.depth > depth) { 5660 depth = child.depth; 5661 } 5662 5663 if (child.maxFontSize > maxFontSize) { 5664 maxFontSize = child.maxFontSize; 5665 } 5666 } 5667 5668 elem.height = height; 5669 elem.depth = depth; 5670 elem.maxFontSize = maxFontSize; 5671}; 5672/** 5673 * Makes a span with the given list of classes, list of children, and options. 5674 * 5675 * TODO(#953): Ensure that `options` is always provided (currently some call 5676 * sites don't pass it) and make the type below mandatory. 5677 * TODO: add a separate argument for math class (e.g. `mop`, `mbin`), which 5678 * should if present come first in `classes`. 5679 */ 5680 5681 5682var makeSpan$2 = function makeSpan(classes, children, options, style) { 5683 var span = new Span(classes, children, options, style); 5684 sizeElementFromChildren(span); 5685 return span; 5686}; // SVG one is simpler -- doesn't require height, depth, max-font setting. 5687// This is also a separate method for typesafety. 5688 5689 5690var makeSvgSpan = (classes, children, options, style) => new Span(classes, children, options, style); 5691 5692var makeLineSpan = function makeLineSpan(className, options, thickness) { 5693 var line = makeSpan$2([className], [], options); 5694 line.height = Math.max(thickness || options.fontMetrics().defaultRuleThickness, options.minRuleThickness); 5695 line.style.borderBottomWidth = makeEm(line.height); 5696 line.maxFontSize = 1.0; 5697 return line; 5698}; 5699/** 5700 * Makes an anchor with the given href, list of classes, list of children, 5701 * and options. 5702 */ 5703 5704 5705var makeAnchor = function makeAnchor(href, classes, children, options) { 5706 var anchor = new Anchor(href, classes, children, options); 5707 sizeElementFromChildren(anchor); 5708 return anchor; 5709}; 5710/** 5711 * Makes a document fragment with the given list of children. 5712 */ 5713 5714 5715var makeFragment = function makeFragment(children) { 5716 var fragment = new DocumentFragment(children); 5717 sizeElementFromChildren(fragment); 5718 return fragment; 5719}; 5720/** 5721 * Wraps group in a span if it's a document fragment, allowing to apply classes 5722 * and styles 5723 */ 5724 5725 5726var wrapFragment = function wrapFragment(group, options) { 5727 if (group instanceof DocumentFragment) { 5728 return makeSpan$2([], [group], options); 5729 } 5730 5731 return group; 5732}; // These are exact object types to catch typos in the names of the optional fields. 5733 5734 5735// Computes the updated `children` list and the overall depth. 5736// 5737// This helper function for makeVList makes it easier to enforce type safety by 5738// allowing early exits (returns) in the logic. 5739var getVListChildrenAndDepth = function getVListChildrenAndDepth(params) { 5740 if (params.positionType === "individualShift") { 5741 var oldChildren = params.children; 5742 var children = [oldChildren[0]]; // Add in kerns to the list of params.children to get each element to be 5743 // shifted to the correct specified shift 5744 5745 var _depth = -oldChildren[0].shift - oldChildren[0].elem.depth; 5746 5747 var currPos = _depth; 5748 5749 for (var i = 1; i < oldChildren.length; i++) { 5750 var diff = -oldChildren[i].shift - currPos - oldChildren[i].elem.depth; 5751 var size = diff - (oldChildren[i - 1].elem.height + oldChildren[i - 1].elem.depth); 5752 currPos = currPos + diff; 5753 children.push({ 5754 type: "kern", 5755 size 5756 }); 5757 children.push(oldChildren[i]); 5758 } 5759 5760 return { 5761 children, 5762 depth: _depth 5763 }; 5764 } 5765 5766 var depth; 5767 5768 if (params.positionType === "top") { 5769 // We always start at the bottom, so calculate the bottom by adding up 5770 // all the sizes 5771 var bottom = params.positionData; 5772 5773 for (var _i = 0; _i < params.children.length; _i++) { 5774 var child = params.children[_i]; 5775 bottom -= child.type === "kern" ? child.size : child.elem.height + child.elem.depth; 5776 } 5777 5778 depth = bottom; 5779 } else if (params.positionType === "bottom") { 5780 depth = -params.positionData; 5781 } else { 5782 var firstChild = params.children[0]; 5783 5784 if (firstChild.type !== "elem") { 5785 throw new Error('First child must have type "elem".'); 5786 } 5787 5788 if (params.positionType === "shift") { 5789 depth = -firstChild.elem.depth - params.positionData; 5790 } else if (params.positionType === "firstBaseline") { 5791 depth = -firstChild.elem.depth; 5792 } else { 5793 throw new Error("Invalid positionType " + params.positionType + "."); 5794 } 5795 } 5796 5797 return { 5798 children: params.children, 5799 depth 5800 }; 5801}; 5802/** 5803 * Makes a vertical list by stacking elements and kerns on top of each other. 5804 * Allows for many different ways of specifying the positioning method. 5805 * 5806 * See VListParam documentation above. 5807 */ 5808 5809 5810var makeVList = function makeVList(params, options) { 5811 var { 5812 children, 5813 depth 5814 } = getVListChildrenAndDepth(params); // Create a strut that is taller than any list item. The strut is added to 5815 // each item, where it will determine the item's baseline. Since it has 5816 // `overflow:hidden`, the strut's top edge will sit on the item's line box's 5817 // top edge and the strut's bottom edge will sit on the item's baseline, 5818 // with no additional line-height spacing. This allows the item baseline to 5819 // be positioned precisely without worrying about font ascent and 5820 // line-height. 5821 5822 var pstrutSize = 0; 5823 5824 for (var i = 0; i < children.length; i++) { 5825 var child = children[i]; 5826 5827 if (child.type === "elem") { 5828 var elem = child.elem; 5829 pstrutSize = Math.max(pstrutSize, elem.maxFontSize, elem.height); 5830 } 5831 } 5832 5833 pstrutSize += 2; 5834 var pstrut = makeSpan$2(["pstrut"], []); 5835 pstrut.style.height = makeEm(pstrutSize); // Create a new list of actual children at the correct offsets 5836 5837 var realChildren = []; 5838 var minPos = depth; 5839 var maxPos = depth; 5840 var currPos = depth; 5841 5842 for (var _i2 = 0; _i2 < children.length; _i2++) { 5843 var _child = children[_i2]; 5844 5845 if (_child.type === "kern") { 5846 currPos += _child.size; 5847 } else { 5848 var _elem = _child.elem; 5849 var classes = _child.wrapperClasses || []; 5850 var style = _child.wrapperStyle || {}; 5851 var childWrap = makeSpan$2(classes, [pstrut, _elem], undefined, style); 5852 childWrap.style.top = makeEm(-pstrutSize - currPos - _elem.depth); 5853 5854 if (_child.marginLeft) { 5855 childWrap.style.marginLeft = _child.marginLeft; 5856 } 5857 5858 if (_child.marginRight) { 5859 childWrap.style.marginRight = _child.marginRight; 5860 } 5861 5862 realChildren.push(childWrap); 5863 currPos += _elem.height + _elem.depth; 5864 } 5865 5866 minPos = Math.min(minPos, currPos); 5867 maxPos = Math.max(maxPos, currPos); 5868 } // The vlist contents go in a table-cell with `vertical-align:bottom`. 5869 // This cell's bottom edge will determine the containing table's baseline 5870 // without overly expanding the containing line-box. 5871 5872 5873 var vlist = makeSpan$2(["vlist"], realChildren); 5874 vlist.style.height = makeEm(maxPos); // A second row is used if necessary to represent the vlist's depth. 5875 5876 var rows; 5877 5878 if (minPos < 0) { 5879 // We will define depth in an empty span with display: table-cell. 5880 // It should render with the height that we define. But Chrome, in 5881 // contenteditable mode only, treats that span as if it contains some 5882 // text content. And that min-height over-rides our desired height. 5883 // So we put another empty span inside the depth strut span. 5884 var emptySpan = makeSpan$2([], []); 5885 var depthStrut = makeSpan$2(["vlist"], [emptySpan]); 5886 depthStrut.style.height = makeEm(-minPos); // Safari wants the first row to have inline content; otherwise it 5887 // puts the bottom of the *second* row on the baseline. 5888 5889 var topStrut = makeSpan$2(["vlist-s"], [new SymbolNode("\u200b")]); 5890 rows = [makeSpan$2(["vlist-r"], [vlist, topStrut]), makeSpan$2(["vlist-r"], [depthStrut])]; 5891 } else { 5892 rows = [makeSpan$2(["vlist-r"], [vlist])]; 5893 } 5894 5895 var vtable = makeSpan$2(["vlist-t"], rows); 5896 5897 if (rows.length === 2) { 5898 vtable.classes.push("vlist-t2"); 5899 } 5900 5901 vtable.height = maxPos; 5902 vtable.depth = -minPos; 5903 return vtable; 5904}; // Glue is a concept from TeX which is a flexible space between elements in 5905// either a vertical or horizontal list. In KaTeX, at least for now, it's 5906// static space between elements in a horizontal layout. 5907 5908 5909var makeGlue = (measurement, options) => { 5910 // Make an empty span for the space 5911 var rule = makeSpan$2(["mspace"], [], options); 5912 var size = calculateSize(measurement, options); 5913 rule.style.marginRight = makeEm(size); 5914 return rule; 5915}; // Takes font options, and returns the appropriate fontLookup name 5916 5917 5918var retrieveTextFontName = function retrieveTextFontName(fontFamily, fontWeight, fontShape) { 5919 var baseFontName = ""; 5920 5921 switch (fontFamily) { 5922 case "amsrm": 5923 baseFontName = "AMS"; 5924 break; 5925 5926 case "textrm": 5927 baseFontName = "Main"; 5928 break; 5929 5930 case "textsf": 5931 baseFontName = "SansSerif"; 5932 break; 5933 5934 case "texttt": 5935 baseFontName = "Typewriter"; 5936 break; 5937 5938 default: 5939 baseFontName = fontFamily; 5940 // use fonts added by a plugin 5941 } 5942 5943 var fontStylesName; 5944 5945 if (fontWeight === "textbf" && fontShape === "textit") { 5946 fontStylesName = "BoldItalic"; 5947 } else if (fontWeight === "textbf") { 5948 fontStylesName = "Bold"; 5949 } else if (fontWeight === "textit") { 5950 fontStylesName = "Italic"; 5951 } else { 5952 fontStylesName = "Regular"; 5953 } 5954 5955 return baseFontName + "-" + fontStylesName; 5956}; 5957/** 5958 * Maps TeX font commands to objects containing: 5959 * - variant: string used for "mathvariant" attribute in buildMathML.js 5960 * - fontName: the "style" parameter to fontMetrics.getCharacterMetrics 5961 */ 5962// A map between tex font commands an MathML mathvariant attribute values 5963 5964 5965var fontMap = { 5966 // styles 5967 "mathbf": { 5968 variant: "bold", 5969 fontName: "Main-Bold" 5970 }, 5971 "mathrm": { 5972 variant: "normal", 5973 fontName: "Main-Regular" 5974 }, 5975 "textit": { 5976 variant: "italic", 5977 fontName: "Main-Italic" 5978 }, 5979 "mathit": { 5980 variant: "italic", 5981 fontName: "Main-Italic" 5982 }, 5983 "mathnormal": { 5984 variant: "italic", 5985 fontName: "Math-Italic" 5986 }, 5987 "mathsfit": { 5988 variant: "sans-serif-italic", 5989 fontName: "SansSerif-Italic" 5990 }, 5991 // "boldsymbol" is missing because they require the use of multiple fonts: 5992 // Math-BoldItalic and Main-Bold. This is handled by a special case in 5993 // makeOrd which ends up calling boldsymbol. 5994 // families 5995 "mathbb": { 5996 variant: "double-struck", 5997 fontName: "AMS-Regular" 5998 }, 5999 "mathcal": { 6000 variant: "script", 6001 fontName: "Caligraphic-Regular" 6002 }, 6003 "mathfrak": { 6004 variant: "fraktur", 6005 fontName: "Fraktur-Regular" 6006 }, 6007 "mathscr": { 6008 variant: "script", 6009 fontName: "Script-Regular" 6010 }, 6011 "mathsf": { 6012 variant: "sans-serif", 6013 fontName: "SansSerif-Regular" 6014 }, 6015 "mathtt": { 6016 variant: "monospace", 6017 fontName: "Typewriter-Regular" 6018 } 6019}; 6020var svgData = { 6021 // path, width, height 6022 vec: ["vec", 0.471, 0.714], 6023 // values from the font glyph 6024 oiintSize1: ["oiintSize1", 0.957, 0.499], 6025 // oval to overlay the integrand 6026 oiintSize2: ["oiintSize2", 1.472, 0.659], 6027 oiiintSize1: ["oiiintSize1", 1.304, 0.499], 6028 oiiintSize2: ["oiiintSize2", 1.98, 0.659] 6029}; 6030 6031var staticSvg = function staticSvg(value, options) { 6032 // Create a span with inline SVG for the element. 6033 var [pathName, width, height] = svgData[value]; 6034 var path = new PathNode(pathName); 6035 var svgNode = new SvgNode([path], { 6036 "width": makeEm(width), 6037 "height": makeEm(height), 6038 // Override CSS rule `.katex svg { width: 100% }` 6039 "style": "width:" + makeEm(width), 6040 "viewBox": "0 0 " + 1000 * width + " " + 1000 * height, 6041 "preserveAspectRatio": "xMinYMin" 6042 }); 6043 var span = makeSvgSpan(["overlay"], [svgNode], options); 6044 span.height = height; 6045 span.style.height = makeEm(height); 6046 span.style.width = makeEm(width); 6047 return span; 6048}; 6049 6050var buildCommon = { 6051 fontMap, 6052 makeSymbol, 6053 mathsym, 6054 makeSpan: makeSpan$2, 6055 makeSvgSpan, 6056 makeLineSpan, 6057 makeAnchor, 6058 makeFragment, 6059 wrapFragment, 6060 makeVList, 6061 makeOrd, 6062 makeGlue, 6063 staticSvg, 6064 svgData, 6065 tryCombineChars 6066}; 6067 6068/** 6069 * Describes spaces between different classes of atoms. 6070 */ 6071var thinspace = { 6072 number: 3, 6073 unit: "mu" 6074}; 6075var mediumspace = { 6076 number: 4, 6077 unit: "mu" 6078}; 6079var thickspace = { 6080 number: 5, 6081 unit: "mu" 6082}; // Making the type below exact with all optional fields doesn't work due to 6083// - https://github.com/facebook/flow/issues/4582 6084// - https://github.com/facebook/flow/issues/5688 6085// However, since *all* fields are optional, $Shape<> works as suggested in 5688
6086// above. 6087 6088// Spacing relationships for display and text styles 6089var spacings = { 6090 mord: { 6091 mop: thinspace, 6092 mbin: mediumspace, 6093 mrel: thickspace, 6094 minner: thinspace 6095 }, 6096 mop: { 6097 mord: thinspace, 6098 mop: thinspace, 6099 mrel: thickspace, 6100 minner: thinspace 6101 }, 6102 mbin: { 6103 mord: mediumspace, 6104 mop: mediumspace, 6105 mopen: mediumspace, 6106 minner: mediumspace 6107 }, 6108 mrel: { 6109 mord: thickspace, 6110 mop: thickspace, 6111 mopen: thickspace, 6112 minner: thickspace 6113 }, 6114 mopen: {}, 6115 mclose: { 6116 mop: thinspace, 6117 mbin: mediumspace, 6118 mrel: thickspace, 6119 minner: thinspace 6120 }, 6121 mpunct: { 6122 mord: thinspace, 6123 mop: thinspace, 6124 mrel: thickspace, 6125 mopen: thinspace, 6126 mclose: thinspace, 6127 mpunct: thinspace, 6128 minner: thinspace 6129 }, 6130 minner: { 6131 mord: thinspace, 6132 mop: thinspace, 6133 mbin: mediumspace, 6134 mrel: thickspace, 6135 mopen: thinspace, 6136 mpunct: thinspace, 6137 minner: thinspace 6138 } 6139}; // Spacing relationships for script and scriptscript styles 6140 6141var tightSpacings = { 6142 mord: { 6143 mop: thinspace 6144 }, 6145 mop: { 6146 mord: thinspace, 6147 mop: thinspace 6148 }, 6149 mbin: {}, 6150 mrel: {}, 6151 mopen: {}, 6152 mclose: { 6153 mop: thinspace 6154 }, 6155 mpunct: {}, 6156 minner: { 6157 mop: thinspace 6158 } 6159}; 6160 6161/** Context provided to function handlers for error messages. */ 6162// Note: reverse the order of the return type union will cause a flow error. 6163// See https://github.com/facebook/flow/issues/3663. 6164// More general version of `HtmlBuilder` for nodes (e.g. \sum, accent types) 6165// whose presence impacts super/subscripting. In this case, ParseNode<"supsub"> 6166// delegates its HTML building to the HtmlBuilder corresponding to these nodes. 6167 6168/** 6169 * Final function spec for use at parse time. 6170 * This is almost identical to `FunctionPropSpec`, except it 6171 * 1. includes the function handler, and 6172 * 2. requires all arguments except argTypes. 6173 * It is generated by `defineFunction()` below. 6174 */ 6175 6176/** 6177 * All registered functions. 6178 * `functions.js` just exports this same dictionary again and makes it public. 6179 * `Parser.js` requires this dictionary. 6180 */ 6181var _functions = {}; 6182/** 6183 * All HTML builders. Should be only used in the `define*` and the `build*ML` 6184 * functions. 6185 */ 6186 6187var _htmlGroupBuilders = {}; 6188/** 6189 * All MathML builders. Should be only used in the `define*` and the `build*ML` 6190 * functions. 6191 */ 6192 6193var _mathmlGroupBuilders = {}; 6194function defineFunction(_ref) { 6195 var { 6196 type, 6197 names, 6198 props, 6199 handler, 6200 htmlBuilder, 6201 mathmlBuilder 6202 }
6202 = _ref; 6203 // Set default values of functions 6204 var data = { 6205 type, 6206 numArgs: props.numArgs, 6207 argTypes: props.argTypes, 6208 allowedInArgument: !!props.allowedInArgument, 6209 allowedInText: !!props.allowedInText, 6210 allowedInMath: props.allowedInMath === undefined ? true : props.allowedInMath, 6211 numOptionalArgs: props.numOptionalArgs || 0, 6212 infix: !!props.infix, 6213 primitive: !!props.primitive, 6214 handler: handler 6215 }; 6216 6217 for (var i = 0; i < names.length; ++i) { 6218 _functions[names[i]] = data; 6219 } 6220 6221 if (type) { 6222 if (htmlBuilder) { 6223 _htmlGroupBuilders[type] = htmlBuilder; 6224 } 6225 6226 if (mathmlBuilder) { 6227 _mathmlGroupBuilders[type] = mathmlBuilder; 6228 } 6229 } 6230} 6231/** 6232 * Use this to register only the HTML and MathML builders for a function (e.g. 6233 * if the function's ParseNode is generated in Parser.js rather than via a 6234 * stand-alone handler provided to `defineFunction`). 6235 */ 6236 6237function defineFunctionBuilders(_ref2) { 6238 var { 6239 type, 6240 htmlBuilder, 6241 mathmlBuilder 6242 } = _ref2; 6243 defineFunction({ 6244 type, 6245 names: [], 6246 props: { 6247 numArgs: 0 6248 }, 6249 6250 handler() { 6251 throw new Error('Should never be called.'); 6252 }, 6253 6254 htmlBuilder, 6255 mathmlBuilder 6256 }); 6257} 6258var normalizeArgument = function normalizeArgument(arg) { 6259 return arg.type === "ordgroup" && arg.body.length === 1 ? arg.body[0] : arg; 6260}; // Since the corresponding buildHTML/buildMathML function expects a 6261// list of elements, we normalize for different kinds of arguments 6262 6263var ordargument = function ordargument(arg) { 6264 return arg.type === "ordgroup" ? arg.body : [arg]; 6265}; 6266 6267/** 6268 * This file does the main work of building a domTree structure from a parse 6269 * tree. The entry point is the `buildHTML` function, which takes a parse tree. 6270 * Then, the buildExpression, buildGroup, and various groupBuilders functions 6271 * are called, to produce a final HTML tree. 6272 */ 6273var makeSpan$1 = buildCommon.makeSpan; // Binary atoms (first class `mbin`) change into ordinary atoms (`mord`) 6274// depending on their surroundings. See TeXbook pg. 442-446, Rules 5 and 6, 6275// and the text before Rule 19. 6276 6277var binLeftCanceller = ["leftmost", "mbin", "mopen", "mrel", "mop", "mpunct"]; 6278var binRightCanceller = ["rightmost", "mrel", "mclose", "mpunct"]; 6279var styleMap$1 = { 6280 "display": Style$1.DISPLAY, 6281 "text": Style$1.TEXT, 6282 "script": Style$1.SCRIPT, 6283 "scriptscript": Style$1.SCRIPTSCRIPT 6284}; 6285var DomEnum = { 6286 mord: "mord", 6287 mop: "mop", 6288 mbin: "mbin", 6289 mrel: "mrel", 6290 mopen: "mopen", 6291 mclose: "mclose", 6292 mpunct: "mpunct", 6293 minner: "minner" 6294}; 6295 6296/** 6297 * Take a list of nodes, build them in order, and return a list of the built 6298 * nodes. documentFragments are flattened into their contents, so the 6299 * returned list contains no fragments. `isRealGroup` is true if `expression` 6300 * is a real group (no atoms will be added on either side), as opposed to 6301 * a partial group (e.g. one created by \color). `surrounding` is an array 6302 * consisting type of nodes that will be added to the left and right. 6303 */ 6304var buildExpression$1 = function buildExpression(expression, options, isRealGroup, surrounding) { 6305 if (surrounding === void 0) { 6306 surrounding = [null, null]; 6307 } 6308 6309 // Parse expressions into `groups`. 6310 var groups = []; 6311 6312 for (var i = 0; i < expression.length; i++) { 6313 var output = buildGroup$1(expression[i], options); 6314 6315 if (output instanceof DocumentFragment) { 6316 var children = output.children; 6317 groups.push(...children); 6318 } else { 6319 groups.push(output); 6320 } 6321 } // Combine consecutive domTree.symbolNodes into a single symbolNode. 6322 6323 6324 buildCommon.tryCombineChars(groups); // If `expression` is a partial group, let the parent handle spacings 6325 // to avoid processing groups multiple times. 6326 6327 if (!isRealGroup) { 6328 return groups; 6329 } 6330 6331 var glueOptions = options; 6332 6333 if (expression.length === 1) { 6334 var node = expression[0]; 6335 6336 if (node.type === "sizing") { 6337 glueOptions = options.havingSize(node.size); 6338 } else if (node.type === "styling") { 6339 glueOptions = options.havingStyle(styleMap$1[node.style]); 6340 } 6341 } // Dummy spans for determining spacings between surrounding atoms. 6342 // If `expression` has no atoms on the left or right, class "leftmost" 6343 // or "rightmost", respectively, is used to indicate it. 6344 6345 6346 var dummyPrev = makeSpan$1([surrounding[0] || "leftmost"], [], options); 6347 var dummyNext = makeSpan$1([surrounding[1] || "rightmost"], [], options); // TODO: These code assumes that a node's math class is the first element 6348 // of its `classes` array. A later cleanup should ensure this, for 6349 // instance by changing the signature of `makeSpan`. 6350 // Before determining what spaces to insert, perform bin cancellation. 6351 // Binary operators change to ordinary symbols in some contexts. 6352
vendor: 18,533 bytes, lines 6353-6987
6353 var isRoot = isRealGroup === "root"; 6354 traverseNonSpaceNodes(groups, (node, prev) => { 6355 var prevType = prev.classes[0]; 6356 var type = node.classes[0]; 6357 6358 if (prevType === "mbin" && utils.contains(binRightCanceller, type)) { 6359 prev.classes[0] = "mord"; 6360 } else if (type === "mbin" && utils.contains(binLeftCanceller, prevType)) { 6361 node.classes[0] = "mord"; 6362 } 6363 }, { 6364 node: dummyPrev 6365 }, dummyNext, isRoot); 6366 traverseNonSpaceNodes(groups, (node, prev) => { 6367 var prevType = getTypeOfDomTree(prev); 6368 var type = getTypeOfDomTree(node); // 'mtight' indicates that the node is script or scriptscript style. 6369 6370 var space = prevType && type ? node.hasClass("mtight") ? tightSpacings[prevType][type] : spacings[prevType][type] : null; 6371 6372 if (space) { 6373 // Insert glue (spacing) after the `prev`. 6374 return buildCommon.makeGlue(space, glueOptions); 6375 } 6376 }, { 6377 node: dummyPrev 6378 }, dummyNext, isRoot); 6379 return groups; 6380}; // Depth-first traverse non-space `nodes`, calling `callback` with the current and 6381// previous node as arguments, optionally returning a node to insert after the 6382// previous node. `prev` is an object with the previous node and `insertAfter` 6383// function to insert after it. `next` is a node that will be added to the right. 6384// Used for bin cancellation and inserting spacings. 6385 6386var traverseNonSpaceNodes = function traverseNonSpaceNodes(nodes, callback, prev, next, isRoot) { 6387 if (next) { 6388 // temporarily append the right node, if exists 6389 nodes.push(next); 6390 } 6391 6392 var i = 0; 6393 6394 for (; i < nodes.length; i++) { 6395 var node = nodes[i]; 6396 var partialGroup = checkPartialGroup(node); 6397 6398 if (partialGroup) { 6399 // Recursive DFS 6400 // $FlowFixMe: make nodes a $ReadOnlyArray by returning a new array 6401 traverseNonSpaceNodes(partialGroup.children, callback, prev, null, isRoot); 6402 continue; 6403 } // Ignore explicit spaces (e.g., \;, \,) when determining what implicit 6404 // spacing should go between atoms of different classes 6405 6406 6407 var nonspace = !node.hasClass("mspace"); 6408 6409 if (nonspace) { 6410 var result = callback(node, prev.node); 6411 6412 if (result) { 6413 if (prev.insertAfter) { 6414 prev.insertAfter(result); 6415 } else { 6416 // insert at front 6417 nodes.unshift(result); 6418 i++; 6419 } 6420 } 6421 } 6422 6423 if (nonspace) { 6424 prev.node = node; 6425 } else if (isRoot && node.hasClass("newline")) { 6426 prev.node = makeSpan$1(["leftmost"]); // treat like beginning of line 6427 } 6428 6429 prev.insertAfter = (index => n => { 6430 nodes.splice(index + 1, 0, n); 6431 i++; 6432 })(i); 6433 } 6434 6435 if (next) { 6436 nodes.pop(); 6437 } 6438}; // Check if given node is a partial group, i.e., does not affect spacing around. 6439 6440 6441var checkPartialGroup = function checkPartialGroup(node) { 6442 if (node instanceof DocumentFragment || node instanceof Anchor || node instanceof Span && node.hasClass("enclosing")) { 6443 return node; 6444 } 6445 6446 return null; 6447}; // Return the outermost node of a domTree. 6448 6449 6450var getOutermostNode = function getOutermostNode(node, side) { 6451 var partialGroup = checkPartialGroup(node); 6452 6453 if (partialGroup) { 6454 var children = partialGroup.children; 6455 6456 if (children.length) { 6457 if (side === "right") { 6458 return getOutermostNode(children[children.length - 1], "right"); 6459 } else if (side === "left") { 6460 return getOutermostNode(children[0], "left"); 6461 } 6462 } 6463 } 6464 6465 return node; 6466}; // Return math atom class (mclass) of a domTree. 6467// If `side` is given, it will get the type of the outermost node at given side. 6468 6469 6470var getTypeOfDomTree = function getTypeOfDomTree(node, side) { 6471 if (!node) { 6472 return null; 6473 } 6474 6475 if (side) { 6476 node = getOutermostNode(node, side); 6477 } // This makes a lot of assumptions as to where the type of atom 6478 // appears. We should do a better job of enforcing this. 6479 6480 6481 return DomEnum[node.classes[0]] || null; 6482}; 6483var makeNullDelimiter = function makeNullDelimiter(options, classes) { 6484 var moreClasses = ["nulldelimiter"].concat(options.baseSizingClasses()); 6485 return makeSpan$1(classes.concat(moreClasses)); 6486}; 6487/** 6488 * buildGroup is the function that takes a group and calls the correct groupType 6489 * function for it. It also handles the interaction of size and style changes 6490 * between parents and children. 6491 */ 6492 6493var buildGroup$1 = function buildGroup(group, options, baseOptions) { 6494 if (!group) { 6495 return makeSpan$1(); 6496 } 6497 6498 if (_htmlGroupBuilders[group.type]) { 6499 // Call the groupBuilders function 6500 // $FlowFixMe 6501 var groupNode = _htmlGroupBuilders[group.type](group, options); // If the size changed between the parent and the current group, account 6502 // for that size difference. 6503 6504 if (baseOptions && options.size !== baseOptions.size) { 6505 groupNode = makeSpan$1(options.sizingClasses(baseOptions), [groupNode], options); 6506 var multiplier = options.sizeMultiplier / baseOptions.sizeMultiplier; 6507 groupNode.height *= multiplier; 6508 groupNode.depth *= multiplier; 6509 } 6510 6511 return groupNode; 6512 } else { 6513 throw new ParseError("Got group of unknown type: '" + group.type + "'"); 6514 } 6515}; 6516/** 6517 * Combine an array of HTML DOM nodes (e.g., the output of `buildExpression`) 6518 * into an unbreakable HTML node of class .base, with proper struts to 6519 * guarantee correct vertical extent. `buildHTML` calls this repeatedly to 6520 * make up the entire expression as a sequence of unbreakable units. 6521 */ 6522 6523function buildHTMLUnbreakable(children, options) { 6524 // Compute height and depth of this chunk. 6525 var body = makeSpan$1(["base"], children, options); // Add strut, which ensures that the top of the HTML element falls at 6526 // the height of the expression, and the bottom of the HTML element 6527 // falls at the depth of the expression. 6528 6529 var strut = makeSpan$1(["strut"]); 6530 strut.style.height = makeEm(body.height + body.depth); 6531 6532 if (body.depth) { 6533 strut.style.verticalAlign = makeEm(-body.depth); 6534 } 6535 6536 body.children.unshift(strut); 6537 return body; 6538} 6539/** 6540 * Take an entire parse tree, and build it into an appropriate set of HTML 6541 * nodes. 6542 */ 6543 6544 6545function buildHTML(tree, options) { 6546 // Strip off outer tag wrapper for processing below. 6547 var tag = null; 6548 6549 if (tree.length === 1 && tree[0].type === "tag") { 6550 tag = tree[0].tag; 6551 tree = tree[0].body; 6552 } // Build the expression contained in the tree 6553 6554 6555 var expression = buildExpression$1(tree, options, "root"); 6556 var eqnNum; 6557 6558 if (expression.length === 2 && expression[1].hasClass("tag")) { 6559 // An environment with automatic equation numbers, e.g. {gather}. 6560 eqnNum = expression.pop(); 6561 } 6562 6563 var children = []; // Create one base node for each chunk between potential line breaks. 6564 // The TeXBook [p.173] says "A formula will be broken only after a 6565 // relation symbol like $=$ or $<$ or $\rightarrow$, or after a binary 6566 // operation symbol like $+$ or $-$ or $\times$, where the relation or 6567 // binary operation is on the ``outer level'' of the formula (i.e., not 6568 // enclosed in {...} and not part of an \over construction)." 6569 6570 var parts = []; 6571 6572 for (var i = 0; i < expression.length; i++) { 6573 parts.push(expression[i]); 6574 6575 if (expression[i].hasClass("mbin") || expression[i].hasClass("mrel") || expression[i].hasClass("allowbreak")) { 6576 // Put any post-operator glue on same line as operator. 6577 // Watch for \nobreak along the way, and stop at \newline. 6578 var nobreak = false; 6579 6580 while (i < expression.length - 1 && expression[i + 1].hasClass("mspace") && !expression[i + 1].hasClass("newline")) { 6581 i++; 6582 parts.push(expression[i]); 6583 6584 if (expression[i].hasClass("nobreak")) { 6585 nobreak = true; 6586 } 6587 } // Don't allow break if \nobreak among the post-operator glue. 6588 6589 6590 if (!nobreak) { 6591 children.push(buildHTMLUnbreakable(parts, options)); 6592 parts = []; 6593 } 6594 } else if (expression[i].hasClass("newline")) { 6595 // Write the line except the newline 6596 parts.pop(); 6597 6598 if (parts.length > 0) { 6599 children.push(buildHTMLUnbreakable(parts, options)); 6600 parts = []; 6601 } // Put the newline at the top level 6602 6603 6604 children.push(expression[i]); 6605 } 6606 } 6607 6608 if (parts.length > 0) { 6609 children.push(buildHTMLUnbreakable(parts, options)); 6610 } // Now, if there was a tag, build it too and append it as a final child. 6611 6612 6613 var tagChild; 6614 6615 if (tag) { 6616 tagChild = buildHTMLUnbreakable(buildExpression$1(tag, options, true)); 6617 tagChild.classes = ["tag"]; 6618 children.push(tagChild); 6619 } else if (eqnNum) { 6620 children.push(eqnNum); 6621 } 6622 6623 var htmlNode = makeSpan$1(["katex-html"], children); 6624 htmlNode.setAttribute("aria-hidden", "true"); // Adjust the strut of the tag to be the maximum height of all children 6625 // (the height of the enclosing htmlNode) for proper vertical alignment. 6626 6627 if (tagChild) { 6628 var strut = tagChild.children[0]; 6629 strut.style.height = makeEm(htmlNode.height + htmlNode.depth); 6630 6631 if (htmlNode.depth) { 6632 strut.style.verticalAlign = makeEm(-htmlNode.depth); 6633 } 6634 } 6635 6636 return htmlNode; 6637} 6638 6639/** 6640 * These objects store data about MathML nodes. This is the MathML equivalent 6641 * of the types in domTree.js. Since MathML handles its own rendering, and 6642 * since we're mainly using MathML to improve accessibility, we don't manage 6643 * any of the styling state that the plain DOM nodes do. 6644 * 6645 * The `toNode` and `toMarkup` functions work similarly to how they do in 6646 * domTree.js, creating namespaced DOM nodes and HTML text markup respectively. 6647 */ 6648function newDocumentFragment(children) { 6649 return new DocumentFragment(children); 6650} 6651/** 6652 * This node represents a general purpose MathML node of any type. The 6653 * constructor requires the type of node to create (for example, `"mo"` or 6654 * `"mspace"`, corresponding to `<mo>` and `<mspace>` tags). 6655 */ 6656 6657class MathNode { 6658 constructor(type, children, classes) { 6659 this.type = void 0; 6660 this.attributes = void 0; 6661 this.children = void 0; 6662 this.classes = void 0; 6663 this.type = type; 6664 this.attributes = {}; 6665 this.children = children || []; 6666 this.classes = classes || []; 6667 } 6668 /** 6669 * Sets an attribute on a MathML node. MathML depends on attributes to convey a 6670 * semantic content, so this is used heavily. 6671 */ 6672 6673 6674 setAttribute(name, value) { 6675 this.attributes[name] = value; 6676 } 6677 /** 6678 * Gets an attribute on a MathML node. 6679 */ 6680 6681 6682 getAttribute(name) { 6683 return this.attributes[name]; 6684 } 6685 /** 6686 * Converts the math node into a MathML-namespaced DOM element. 6687 */ 6688 6689 6690 toNode() { 6691 var node = document.createElementNS("http://www.w3.org/1998/Math/MathML", this.type); 6692 6693 for (var attr in this.attributes) { 6694 if (Object.prototype.hasOwnProperty.call(this.attributes, attr)) { 6695 node.setAttribute(attr, this.attributes[attr]); 6696 } 6697 } 6698 6699 if (this.classes.length > 0) { 6700 node.className = createClass(this.classes); 6701 } 6702 6703 for (var i = 0; i < this.children.length; i++) { 6704 // Combine multiple TextNodes into one TextNode, to prevent 6705 // screen readers from reading each as a separate word [#3995] 6706 if (this.children[i] instanceof TextNode && this.children[i + 1] instanceof TextNode) { 6707 var text = this.children[i].toText() + this.children[++i].toText(); 6708 6709 while (this.children[i + 1] instanceof TextNode) { 6710 text += this.children[++i].toText(); 6711 } 6712 6713 node.appendChild(new TextNode(text).toNode()); 6714 } else { 6715 node.appendChild(this.children[i].toNode()); 6716 } 6717 } 6718 6719 return node; 6720 } 6721 /** 6722 * Converts the math node into an HTML markup string. 6723 */ 6724 6725 6726 toMarkup() { 6727 var markup = "<" + this.type; // Add the attributes 6728 6729 for (var attr in this.attributes) { 6730 if (Object.prototype.hasOwnProperty.call(this.attributes, attr)) { 6731 markup += " " + attr + "=\""; 6732 markup += utils.escape(this.attributes[attr]); 6733 markup += "\""; 6734 } 6735 } 6736 6737 if (this.classes.length > 0) { 6738 markup += " class =\"" + utils.escape(createClass(this.classes)) + "\""; 6739 } 6740 6741 markup += ">"; 6742 6743 for (var i = 0; i < this.children.length; i++) { 6744 markup += this.children[i].toMarkup(); 6745 } 6746 6747 markup += "</" + this.type + ">"; 6748 return markup; 6749 } 6750 /** 6751 * Converts the math node into a string, similar to innerText, but escaped. 6752 */ 6753 6754 6755 toText() { 6756 return this.children.map(child => child.toText()).join(""); 6757 } 6758 6759} 6760/** 6761 * This node represents a piece of text. 6762 */ 6763 6764class TextNode { 6765 constructor(text) { 6766 this.text = void 0; 6767 this.text = text; 6768 } 6769 /** 6770 * Converts the text node into a DOM text node. 6771 */ 6772 6773 6774 toNode() { 6775 return document.createTextNode(this.text); 6776 } 6777 /** 6778 * Converts the text node into escaped HTML markup 6779 * (representing the text itself). 6780 */ 6781 6782 6783 toMarkup() { 6784 return utils.escape(this.toText()); 6785 } 6786 /** 6787 * Converts the text node into a string 6788 * (representing the text itself). 6789 */ 6790 6791 6792 toText() { 6793 return this.text; 6794 } 6795 6796} 6797/** 6798 * This node represents a space, but may render as <mspace.../> or as text, 6799 * depending on the width. 6800 */ 6801 6802class SpaceNode { 6803 /** 6804 * Create a Space node with width given in CSS ems. 6805 */ 6806 constructor(width) { 6807 this.width = void 0; 6808 this.character = void 0; 6809 this.width = width; // See https://www.w3.org/TR/2000/WD-MathML2-20000328/chapter6.html 6810 // for a table of space-like characters. We use Unicode 6811 // representations instead of &LongNames; as it's not clear how to 6812 // make the latter via document.createTextNode. 6813 6814 if (width >= 0.05555 && width <= 0.05556) { 6815 this.character = "\u200a"; //   6816 } else if (width >= 0.1666 && width <= 0.1667) { 6817 this.character = "\u2009"; //   6818 } else if (width >= 0.2222 && width <= 0.2223) { 6819 this.character = "\u2005"; //   6820 } else if (width >= 0.2777 && width <= 0.2778) { 6821 this.character = "\u2005\u200a"; //    6822 } else if (width >= -0.05556 && width <= -0.05555) { 6823 this.character = "\u200a\u2063"; // ​ 6824 } else if (width >= -0.1667 && width <= -0.1666) { 6825 this.character = "\u2009\u2063"; // ​ 6826 } else if (width >= -0.2223 && width <= -0.2222) { 6827 this.character = "\u205f\u2063"; // ​ 6828 } else if (width >= -0.2778 && width <= -0.2777) { 6829 this.character = "\u2005\u2063"; // ​ 6830 } else { 6831 this.character = null; 6832 } 6833 } 6834 /** 6835 * Converts the math node into a MathML-namespaced DOM element. 6836 */ 6837 6838 6839 toNode() { 6840 if (this.character) { 6841 return document.createTextNode(this.character); 6842 } else { 6843 var node = document.createElementNS("http://www.w3.org/1998/Math/MathML", "mspace"); 6844 node.setAttribute("width", makeEm(this.width)); 6845 return node; 6846 } 6847 } 6848 /** 6849 * Converts the math node into an HTML markup string. 6850 */ 6851 6852 6853 toMarkup() { 6854 if (this.character) { 6855 return "<mtext>" + this.character + "</mtext>"; 6856 } else { 6857 return "<mspace width=\"" + makeEm(this.width) + "\"/>"; 6858 } 6859 } 6860 /** 6861 * Converts the math node into a string, similar to innerText. 6862 */ 6863 6864 6865 toText() { 6866 if (this.character) { 6867 return this.character; 6868 } else { 6869 return " "; 6870 } 6871 } 6872 6873} 6874 6875var mathMLTree = { 6876 MathNode, 6877 TextNode, 6878 SpaceNode, 6879 newDocumentFragment 6880}; 6881 6882/** 6883 * This file converts a parse tree into a corresponding MathML tree. The main 6884 * entry point is the `buildMathML` function, which takes a parse tree from the 6885 * parser. 6886 */ 6887 6888/** 6889 * Takes a symbol and converts it into a MathML text node after performing 6890 * optional replacement from symbols.js. 6891 */ 6892var makeText = function makeText(text, mode, options) { 6893 if (symbols[mode][text] && symbols[mode][text].replace && text.charCodeAt(0) !== 0xD835 && !(ligatures.hasOwnProperty(text) && options && (options.fontFamily && options.fontFamily.slice(4, 6) === "tt" || options.font && options.font.slice(4, 6) === "tt"))) { 6894 text = symbols[mode][text].replace; 6895 } 6896 6897 return new mathMLTree.TextNode(text); 6898}; 6899/** 6900 * Wrap the given array of nodes in an <mrow> node if needed, i.e., 6901 * unless the array has length 1. Always returns a single node. 6902 */ 6903 6904var makeRow = function makeRow(body) { 6905 if (body.length === 1) { 6906 return body[0]; 6907 } else { 6908 return new mathMLTree.MathNode("mrow", body); 6909 } 6910}; 6911/** 6912 * Returns the math variant as a string or null if none is required. 6913 */ 6914 6915var getVariant = function getVariant(group, options) { 6916 // Handle \text... font specifiers as best we can. 6917 // MathML has a limited list of allowable mathvariant specifiers; see 6918 // https://www.w3.org/TR/MathML3/chapter3.html#presm.commatt 6919 if (options.fontFamily === "texttt") { 6920 return "monospace"; 6921 } else if (options.fontFamily === "textsf") { 6922 if (options.fontShape === "textit" && options.fontWeight === "textbf") { 6923 return "sans-serif-bold-italic"; 6924 } else if (options.fontShape === "textit") { 6925 return "sans-serif-italic"; 6926 } else if (options.fontWeight === "textbf") { 6927 return "bold-sans-serif"; 6928 } else { 6929 return "sans-serif"; 6930 } 6931 } else if (options.fontShape === "textit" && options.fontWeight === "textbf") { 6932 return "bold-italic"; 6933 } else if (options.fontShape === "textit") { 6934 return "italic"; 6935 } else if (options.fontWeight === "textbf") { 6936 return "bold"; 6937 } 6938 6939 var font = options.font; 6940 6941 if (!font || font === "mathnormal") { 6942 return null; 6943 } 6944 6945 var mode = group.mode; 6946 6947 if (font === "mathit") { 6948 return "italic"; 6949 } else if (font === "boldsymbol") { 6950 return group.type === "textord" ? "bold" : "bold-italic"; 6951 } else if (font === "mathbf") { 6952 return "bold"; 6953 } else if (font === "mathbb") { 6954 return "double-struck"; 6955 } else if (font === "mathsfit") { 6956 return "sans-serif-italic"; 6957 } else if (font === "mathfrak") { 6958 return "fraktur"; 6959 } else if (font === "mathscr" || font === "mathcal") { 6960 // MathML makes no distinction between script and calligraphic 6961 return "script"; 6962 } else if (font === "mathsf") { 6963 return "sans-serif"; 6964 } else if (font === "mathtt") { 6965 return "monospace"; 6966 } 6967 6968 var text = group.text; 6969 6970 if (utils.contains(["\\imath", "\\jmath"], text)) { 6971 return null; 6972 } 6973 6974 if (symbols[mode][text] && symbols[mode][text].replace) { 6975 text = symbols[mode][text].replace; 6976 } 6977 6978 var fontName = buildCommon.fontMap[font].fontName; 6979 6980 if (getCharacterMetrics(text, fontName, mode)) { 6981 return buildCommon.fontMap[font].variant; 6982 } 6983 6984 return null; 6985}; 6986/** 6987 * Check for <mi>.</mi> which is how a dot renders in MathML,
vendor: 4,662 bytes, lines 6988-7110
6988 * or <mo separator="true" lspace="0em" rspace="0em">,</mo> 6989 * which is how a braced comma {,} renders in MathML 6990 */ 6991 6992function isNumberPunctuation(group) { 6993 if (!group) { 6994 return false; 6995 } 6996 6997 if (group.type === 'mi' && group.children.length === 1) { 6998 var child = group.children[0]; 6999 return child instanceof TextNode && child.text === '.'; 7000 } else if (group.type === 'mo' && group.children.length === 1 && group.getAttribute('separator') === 'true' && group.getAttribute('lspace') === '0em' && group.getAttribute('rspace') === '0em') { 7001 var _child = group.children[0]; 7002 return _child instanceof TextNode && _child.text === ','; 7003 } else { 7004 return false; 7005 } 7006} 7007/** 7008 * Takes a list of nodes, builds them, and returns a list of the generated 7009 * MathML nodes. Also combine consecutive <mtext> outputs into a single 7010 * <mtext> tag. 7011 */ 7012 7013 7014var buildExpression = function buildExpression(expression, options, isOrdgroup) { 7015 if (expression.length === 1) { 7016 var group = buildGroup(expression[0], options); 7017 7018 if (isOrdgroup && group instanceof MathNode && group.type === "mo") { 7019 // When TeX writers want to suppress spacing on an operator, 7020 // they often put the operator by itself inside braces. 7021 group.setAttribute("lspace", "0em"); 7022 group.setAttribute("rspace", "0em"); 7023 } 7024 7025 return [group]; 7026 } 7027 7028 var groups = []; 7029 var lastGroup; 7030 7031 for (var i = 0; i < expression.length; i++) { 7032 var _group = buildGroup(expression[i], options); 7033 7034 if (_group instanceof MathNode && lastGroup instanceof MathNode) { 7035 // Concatenate adjacent <mtext>s 7036 if (_group.type === 'mtext' && lastGroup.type === 'mtext' && _group.getAttribute('mathvariant') === lastGroup.getAttribute('mathvariant')) { 7037 lastGroup.children.push(..._group.children); 7038 continue; // Concatenate adjacent <mn>s 7039 } else if (_group.type === 'mn' && lastGroup.type === 'mn') { 7040 lastGroup.children.push(..._group.children); 7041 continue; // Concatenate <mn>...</mn> followed by <mi>.</mi> 7042 } else if (isNumberPunctuation(_group) && lastGroup.type === 'mn') { 7043 lastGroup.children.push(..._group.children); 7044 continue; // Concatenate <mi>.</mi> followed by <mn>...</mn> 7045 } else if (_group.type === 'mn' && isNumberPunctuation(lastGroup)) { 7046 _group.children = [...lastGroup.children, ..._group.children]; 7047 groups.pop(); // Put preceding <mn>...</mn> or <mi>.</mi> inside base of 7048 // <msup><mn>...base...</mn>...exponent...</msup> (or <msub>) 7049 } else if ((_group.type === 'msup' || _group.type === 'msub') && _group.children.length >= 1 && (lastGroup.type === 'mn' || isNumberPunctuation(lastGroup))) { 7050 var base = _group.children[0]; 7051 7052 if (base instanceof MathNode && base.type === 'mn') { 7053 base.children = [...lastGroup.children, ...base.children]; 7054 groups.pop(); 7055 } // \not 7056 7057 } else if (lastGroup.type === 'mi' && lastGroup.children.length === 1) { 7058 var lastChild = lastGroup.children[0]; 7059 7060 if (lastChild instanceof TextNode && lastChild.text === '\u0338' && (_group.type === 'mo' || _group.type === 'mi' || _group.type === 'mn')) { 7061 var child = _group.children[0]; 7062 7063 if (child instanceof TextNode && child.text.length > 0) { 7064 // Overlay with combining character long solidus 7065 child.text = child.text.slice(0, 1) + "\u0338" + child.text.slice(1); 7066 groups.pop(); 7067 } 7068 } 7069 } 7070 } 7071 7072 groups.push(_group); 7073 lastGroup = _group; 7074 } 7075 7076 return groups; 7077}; 7078/** 7079 * Equivalent to buildExpression, but wraps the elements in an <mrow> 7080 * if there's more than one. Returns a single node instead of an array. 7081 */ 7082 7083var buildExpressionRow = function buildExpressionRow(expression, options, isOrdgroup) { 7084 return makeRow(buildExpression(expression, options, isOrdgroup)); 7085}; 7086/** 7087 * Takes a group from the parser and calls the appropriate groupBuilders function 7088 * on it to produce a MathML node. 7089 */ 7090 7091var buildGroup = function buildGroup(group, options) { 7092 if (!group) { 7093 return new mathMLTree.MathNode("mrow"); 7094 } 7095 7096 if (_mathmlGroupBuilders[group.type]) { 7097 // Call the groupBuilders function 7098 // $FlowFixMe 7099 var result = _mathmlGroupBuilders[group.type](group, options); // $FlowFixMe 7100 7101 return result; 7102 } else { 7103 throw new ParseError("Got group of unknown type: '" + group.type + "'"); 7104 } 7105}; 7106/** 7107 * Takes a full parse tree and settings and builds a MathML representation of 7108 * it. In particular, we put the elements from building the parse tree into a 7109 * <semantics> tag so we can also include that TeX source as an annotation. 7110 *
vendor: 55,190 bytes, lines 7111-8857
7111 * Note that we actually return a domTree element with a `<math>` inside it so 7112 * we can do appropriate styling. 7113 */ 7114 7115function buildMathML(tree, texExpression, options, isDisplayMode, forMathmlOnly) { 7116 var expression = buildExpression(tree, options); // TODO: Make a pass thru the MathML similar to buildHTML.traverseNonSpaceNodes 7117 // and add spacing nodes. This is necessary only adjacent to math operators 7118 // like \sin or \lim or to subsup elements that contain math operators. 7119 // MathML takes care of the other spacing issues. 7120 // Wrap up the expression in an mrow so it is presented in the semantics 7121 // tag correctly, unless it's a single <mrow> or <mtable>. 7122 7123 var wrapper; 7124 7125 if (expression.length === 1 && expression[0] instanceof MathNode && utils.contains(["mrow", "mtable"], expression[0].type)) { 7126 wrapper = expression[0]; 7127 } else { 7128 wrapper = new mathMLTree.MathNode("mrow", expression); 7129 } // Build a TeX annotation of the source 7130 7131 7132 var annotation = new mathMLTree.MathNode("annotation", [new mathMLTree.TextNode(texExpression)]); 7133 annotation.setAttribute("encoding", "application/x-tex"); 7134 var semantics = new mathMLTree.MathNode("semantics", [wrapper, annotation]); 7135 var math = new mathMLTree.MathNode("math", [semantics]); 7136 math.setAttribute("xmlns", "http://www.w3.org/1998/Math/MathML"); 7137 7138 if (isDisplayMode) { 7139 math.setAttribute("display", "block"); 7140 } // You can't style <math> nodes, so we wrap the node in a span. 7141 // NOTE: The span class is not typed to have <math> nodes as children, and 7142 // we don't want to make the children type more generic since the children 7143 // of span are expected to have more fields in `buildHtml` contexts. 7144 7145 7146 var wrapperClass = forMathmlOnly ? "katex" : "katex-mathml"; // $FlowFixMe 7147 7148 return buildCommon.makeSpan([wrapperClass], [math]); 7149} 7150 7151var optionsFromSettings = function optionsFromSettings(settings) { 7152 return new Options({ 7153 style: settings.displayMode ? Style$1.DISPLAY : Style$1.TEXT, 7154 maxSize: settings.maxSize, 7155 minRuleThickness: settings.minRuleThickness 7156 }); 7157}; 7158 7159var displayWrap = function displayWrap(node, settings) { 7160 if (settings.displayMode) { 7161 var classes = ["katex-display"]; 7162 7163 if (settings.leqno) { 7164 classes.push("leqno"); 7165 } 7166 7167 if (settings.fleqn) { 7168 classes.push("fleqn"); 7169 } 7170 7171 node = buildCommon.makeSpan(classes, [node]); 7172 } 7173 7174 return node; 7175}; 7176 7177var buildTree = function buildTree(tree, expression, settings) { 7178 var options = optionsFromSettings(settings); 7179 var katexNode; 7180 7181 if (settings.output === "mathml") { 7182 return buildMathML(tree, expression, options, settings.displayMode, true); 7183 } else if (settings.output === "html") { 7184 var htmlNode = buildHTML(tree, options); 7185 katexNode = buildCommon.makeSpan(["katex"], [htmlNode]); 7186 } else { 7187 var mathMLNode = buildMathML(tree, expression, options, settings.displayMode, false); 7188 7189 var _htmlNode = buildHTML(tree, options); 7190 7191 katexNode = buildCommon.makeSpan(["katex"], [mathMLNode, _htmlNode]); 7192 } 7193 7194 return displayWrap(katexNode, settings); 7195}; 7196var buildHTMLTree = function buildHTMLTree(tree, expression, settings) { 7197 var options = optionsFromSettings(settings); 7198 var htmlNode = buildHTML(tree, options); 7199 var katexNode = buildCommon.makeSpan(["katex"], [htmlNode]); 7200 return displayWrap(katexNode, settings); 7201}; 7202 7203/** 7204 * This file provides support to buildMathML.js and buildHTML.js 7205 * for stretchy wide elements rendered from SVG files 7206 * and other CSS trickery. 7207 */ 7208var stretchyCodePoint = { 7209 widehat: "^", 7210 widecheck: "Ë", 7211 widetilde: "~", 7212 utilde: "~", 7213 overleftarrow: "\u2190", 7214 underleftarrow: "\u2190", 7215 xleftarrow: "\u2190", 7216 overrightarrow: "\u2192", 7217 underrightarrow: "\u2192", 7218 xrightarrow: "\u2192", 7219 underbrace: "\u23df", 7220 overbrace: "\u23de", 7221 overgroup: "\u23e0", 7222 undergroup: "\u23e1", 7223 overleftrightarrow: "\u2194", 7224 underleftrightarrow: "\u2194", 7225 xleftrightarrow: "\u2194", 7226 Overrightarrow: "\u21d2", 7227 xRightarrow: "\u21d2", 7228 overleftharpoon: "\u21bc", 7229 xleftharpoonup: "\u21bc", 7230 overrightharpoon: "\u21c0", 7231 xrightharpoonup: "\u21c0", 7232 xLeftarrow: "\u21d0", 7233 xLeftrightarrow: "\u21d4", 7234 xhookleftarrow: "\u21a9", 7235 xhookrightarrow: "\u21aa", 7236 xmapsto: "\u21a6", 7237 xrightharpoondown: "\u21c1", 7238 xleftharpoondown: "\u21bd", 7239 xrightleftharpoons: "\u21cc", 7240 xleftrightharpoons: "\u21cb", 7241 xtwoheadleftarrow: "\u219e", 7242 xtwoheadrightarrow: "\u21a0", 7243 xlongequal: "=", 7244 xtofrom: "\u21c4", 7245 xrightleftarrows: "\u21c4", 7246 xrightequilibrium: "\u21cc", 7247 // Not a perfect match. 7248 xleftequilibrium: "\u21cb", 7249 // None better available. 7250 "\\cdrightarrow": "\u2192", 7251 "\\cdleftarrow": "\u2190", 7252 "\\cdlongequal": "=" 7253}; 7254 7255var mathMLnode = function mathMLnode(label) { 7256 var node = new mathMLTree.MathNode("mo", [new mathMLTree.TextNode(stretchyCodePoint[label.replace(/^\\/, '')])]); 7257 node.setAttribute("stretchy", "true"); 7258 return node; 7259}; // Many of the KaTeX SVG images have been adapted from glyphs in KaTeX fonts. 7260// Copyright (c) 2009-2010, Design Science, Inc. (<www.mathjax.org>) 7261// Copyright (c) 2014-2017 Khan Academy (<www.khanacademy.org>) 7262// Licensed under the SIL Open Font License, Version 1.1. 7263// See \nhttp://scripts.sil.org/OFL 7264// Very Long SVGs 7265// Many of the KaTeX stretchy wide elements use a long SVG image and an 7266// overflow: hidden tactic to achieve a stretchy image while avoiding 7267// distortion of arrowheads or brace corners. 7268// The SVG typically contains a very long (400 em) arrow. 7269// The SVG is in a container span that has overflow: hidden, so the span 7270// acts like a window that exposes only part of the SVG. 7271// The SVG always has a longer, thinner aspect ratio than the container span. 7272// After the SVG fills 100% of the height of the container span, 7273// there is a long arrow shaft left over. That left-over shaft is not shown. 7274// Instead, it is sliced off because the span's CSS has overflow: hidden. 7275// Thus, the reader sees an arrow that matches the subject matter width 7276// without distortion. 7277// Some functions, such as \cancel, need to vary their aspect ratio. These 7278// functions do not get the overflow SVG treatment. 7279// Second Brush Stroke 7280// Low resolution monitors struggle to display images in fine detail. 7281// So browsers apply anti-aliasing. A long straight arrow shaft therefore 7282// will sometimes appear as if it has a blurred edge. 7283// To mitigate this, these SVG files contain a second "brush-stroke" on the 7284// arrow shafts. That is, a second long thin rectangular SVG path has been 7285// written directly on top of each arrow shaft. This reinforcement causes 7286// some of the screen pixels to display as black instead of the anti-aliased 7287// gray pixel that a single path would generate. So we get arrow shafts 7288// whose edges appear to be sharper. 7289// In the katexImagesData object just below, the dimensions all 7290// correspond to path geometry inside the relevant SVG. 7291// For example, \overrightarrow uses the same arrowhead as glyph U+2192 7292// from the KaTeX Main font. The scaling factor is 1000. 7293// That is, inside the font, that arrowhead is 522 units tall, which 7294// corresponds to 0.522 em inside the document. 7295 7296 7297var katexImagesData = { 7298 // path(s), minWidth, height, align 7299 overrightarrow: [["rightarrow"], 0.888, 522, "xMaxYMin"], 7300 overleftarrow: [["leftarrow"], 0.888, 522, "xMinYMin"], 7301 underrightarrow: [["rightarrow"], 0.888, 522, "xMaxYMin"], 7302 underleftarrow: [["leftarrow"], 0.888, 522, "xMinYMin"], 7303 xrightarrow: [["rightarrow"], 1.469, 522, "xMaxYMin"], 7304 "\\cdrightarrow": [["rightarrow"], 3.0, 522, "xMaxYMin"], 7305 // CD minwwidth2.5pc 7306 xleftarrow: [["leftarrow"], 1.469, 522, "xMinYMin"], 7307 "\\cdleftarrow": [["leftarrow"], 3.0, 522, "xMinYMin"], 7308 Overrightarrow: [["doublerightarrow"], 0.888, 560, "xMaxYMin"], 7309 xRightarrow: [["doublerightarrow"], 1.526, 560, "xMaxYMin"], 7310 xLeftarrow: [["doubleleftarrow"], 1.526, 560, "xMinYMin"], 7311 overleftharpoon: [["leftharpoon"], 0.888, 522, "xMinYMin"], 7312 xleftharpoonup: [["leftharpoon"], 0.888, 522, "xMinYMin"], 7313 xleftharpoondown: [["leftharpoondown"], 0.888, 522, "xMinYMin"], 7314 overrightharpoon: [["rightharpoon"], 0.888, 522, "xMaxYMin"], 7315 xrightharpoonup: [["rightharpoon"], 0.888, 522, "xMaxYMin"], 7316 xrightharpoondown: [["rightharpoondown"], 0.888, 522, "xMaxYMin"], 7317 xlongequal: [["longequal"], 0.888, 334, "xMinYMin"], 7318 "\\cdlongequal": [["longequal"], 3.0, 334, "xMinYMin"], 7319 xtwoheadleftarrow: [["twoheadleftarrow"], 0.888, 334, "xMinYMin"], 7320 xtwoheadrightarrow: [["twoheadrightarrow"], 0.888, 334, "xMaxYMin"], 7321 overleftrightarrow: [["leftarrow", "rightarrow"], 0.888, 522], 7322 overbrace: [["leftbrace", "midbrace", "rightbrace"], 1.6, 548], 7323 underbrace: [["leftbraceunder", "midbraceunder", "rightbraceunder"], 1.6, 548], 7324 underleftrightarrow: [["leftarrow", "rightarrow"], 0.888, 522], 7325 xleftrightarrow: [["leftarrow", "rightarrow"], 1.75, 522], 7326 xLeftrightarrow: [["doubleleftarrow", "doublerightarrow"], 1.75, 560], 7327 xrightleftharpoons: [["leftharpoondownplus", "rightharpoonplus"], 1.75, 716], 7328 xleftrightharpoons: [["leftharpoonplus", "rightharpoondownplus"], 1.75, 716], 7329 xhookleftarrow: [["leftarrow", "righthook"], 1.08, 522], 7330 xhookrightarrow: [["lefthook", "rightarrow"], 1.08, 522], 7331 overlinesegment: [["leftlinesegment", "rightlinesegment"], 0.888, 522], 7332 underlinesegment: [["leftlinesegment", "rightlinesegment"], 0.888, 522], 7333 overgroup: [["leftgroup", "rightgroup"], 0.888, 342], 7334 undergroup: [["leftgroupunder", "rightgroupunder"], 0.888, 342], 7335 xmapsto: [["leftmapsto", "rightarrow"], 1.5, 522], 7336 xtofrom: [["leftToFrom", "rightToFrom"], 1.75, 528], 7337 // The next three arrows are from the mhchem package. 7338 // In mhchem.sty, min-length is 2.0em. But these arrows might appear in the 7339 // document as \xrightarrow or \xrightleftharpoons. Those have 7340 // min-length = 1.75em, so we set min-length on these next three to match. 7341 xrightleftarrows: [["baraboveleftarrow", "rightarrowabovebar"], 1.75, 901], 7342 xrightequilibrium: [["baraboveshortleftharpoon", "rightharpoonaboveshortbar"], 1.75, 716], 7343 xleftequilibrium: [["shortbaraboveleftharpoon", "shortrightharpoonabovebar"], 1.75, 716] 7344}; 7345 7346var groupLength = function groupLength(arg) { 7347 if (arg.type === "ordgroup") { 7348 return arg.body.length; 7349 } else { 7350 return 1; 7351 } 7352}; 7353 7354var svgSpan = function svgSpan(group, options) { 7355 // Create a span with inline SVG for the element. 7356 function buildSvgSpan_() { 7357 var viewBoxWidth = 400000; // default 7358 7359 var label = group.label.slice(1); 7360 7361 if (utils.contains(["widehat", "widecheck", "widetilde", "utilde"], label)) { 7362 // Each type in the `if` statement corresponds to one of the ParseNode 7363 // types below. This narrowing is required to access `grp.base`. 7364 // $FlowFixMe 7365 var grp = group; // There are four SVG images available for each function. 7366 // Choose a taller image when there are more characters. 7367 7368 var numChars = groupLength(grp.base); 7369 var viewBoxHeight; 7370 var pathName; 7371 7372 var _height; 7373 7374 if (numChars > 5) { 7375 if (label === "widehat" || label === "widecheck") { 7376 viewBoxHeight = 420; 7377 viewBoxWidth = 2364; 7378 _height = 0.42; 7379 pathName = label + "4"; 7380 } else { 7381 viewBoxHeight = 312; 7382 viewBoxWidth = 2340; 7383 _height = 0.34; 7384 pathName = "tilde4"; 7385 } 7386 } else { 7387 var imgIndex = [1, 1, 2, 2, 3, 3][numChars]; 7388 7389 if (label === "widehat" || label === "widecheck") { 7390 viewBoxWidth = [0, 1062, 2364, 2364, 2364][imgIndex]; 7391 viewBoxHeight = [0, 239, 300, 360, 420][imgIndex]; 7392 _height = [0, 0.24, 0.3, 0.3, 0.36, 0.42][imgIndex]; 7393 pathName = label + imgIndex; 7394 } else { 7395 viewBoxWidth = [0, 600, 1033, 2339, 2340][imgIndex]; 7396 viewBoxHeight = [0, 260, 286, 306, 312][imgIndex]; 7397 _height = [0, 0.26, 0.286, 0.3, 0.306, 0.34][imgIndex]; 7398 pathName = "tilde" + imgIndex; 7399 } 7400 } 7401 7402 var path = new PathNode(pathName); 7403 var svgNode = new SvgNode([path], { 7404 "width": "100%", 7405 "height": makeEm(_height), 7406 "viewBox": "0 0 " + viewBoxWidth + " " + viewBoxHeight, 7407 "preserveAspectRatio": "none" 7408 }); 7409 return { 7410 span: buildCommon.makeSvgSpan([], [svgNode], options), 7411 minWidth: 0, 7412 height: _height 7413 }; 7414 } else { 7415 var spans = []; 7416 var data = katexImagesData[label]; 7417 var [paths, _minWidth, _viewBoxHeight] = data; 7418 7419 var _height2 = _viewBoxHeight / 1000; 7420 7421 var numSvgChildren = paths.length; 7422 var widthClasses; 7423 var aligns; 7424 7425 if (numSvgChildren === 1) { 7426 // $FlowFixMe: All these cases must be of the 4-tuple type. 7427 var align1 = data[3]; 7428 widthClasses = ["hide-tail"]; 7429 aligns = [align1]; 7430 } else if (numSvgChildren === 2) { 7431 widthClasses = ["halfarrow-left", "halfarrow-right"]; 7432 aligns = ["xMinYMin", "xMaxYMin"]; 7433 } else if (numSvgChildren === 3) { 7434 widthClasses = ["brace-left", "brace-center", "brace-right"]; 7435 aligns = ["xMinYMin", "xMidYMin", "xMaxYMin"]; 7436 } else { 7437 throw new Error("Correct katexImagesData or update code here to support\n " + numSvgChildren + " children."); 7438 } 7439 7440 for (var i = 0; i < numSvgChildren; i++) { 7441 var _path = new PathNode(paths[i]); 7442 7443 var _svgNode = new SvgNode([_path], { 7444 "width": "400em", 7445 "height": makeEm(_height2), 7446 "viewBox": "0 0 " + viewBoxWidth + " " + _viewBoxHeight, 7447 "preserveAspectRatio": aligns[i] + " slice" 7448 }); 7449 7450 var _span = buildCommon.makeSvgSpan([widthClasses[i]], [_svgNode], options); 7451 7452 if (numSvgChildren === 1) { 7453 return { 7454 span: _span, 7455 minWidth: _minWidth, 7456 height: _height2 7457 }; 7458 } else { 7459 _span.style.height = makeEm(_height2); 7460 spans.push(_span); 7461 } 7462 } 7463 7464 return { 7465 span: buildCommon.makeSpan(["stretchy"], spans, options), 7466 minWidth: _minWidth, 7467 height: _height2 7468 }; 7469 } 7470 } // buildSvgSpan_() 7471 7472 7473 var { 7474 span, 7475 minWidth, 7476 height 7477 } = buildSvgSpan_(); // Note that we are returning span.depth = 0. 7478 // Any adjustments relative to the baseline must be done in buildHTML. 7479 7480 span.height = height; 7481 span.style.height = makeEm(height); 7482 7483 if (minWidth > 0) { 7484 span.style.minWidth = makeEm(minWidth); 7485 } 7486 7487 return span; 7488}; 7489 7490var encloseSpan = function encloseSpan(inner, label, topPad, bottomPad, options) { 7491 // Return an image span for \cancel, \bcancel, \xcancel, \fbox, or \angl 7492 var img; 7493 var totalHeight = inner.height + inner.depth + topPad + bottomPad; 7494 7495 if (/fbox|color|angl/.test(label)) { 7496 img = buildCommon.makeSpan(["stretchy", label], [], options); 7497 7498 if (label === "fbox") { 7499 var color = options.color && options.getColor(); 7500 7501 if (color) { 7502 img.style.borderColor = color; 7503 } 7504 } 7505 } else { 7506 // \cancel, \bcancel, or \xcancel 7507 // Since \cancel's SVG is inline and it omits the viewBox attribute, 7508 // its stroke-width will not vary with span area. 7509 var lines = []; 7510 7511 if (/^[bx]cancel$/.test(label)) { 7512 lines.push(new LineNode({ 7513 "x1": "0", 7514 "y1": "0", 7515 "x2": "100%", 7516 "y2": "100%", 7517 "stroke-width": "0.046em" 7518 })); 7519 } 7520 7521 if (/^x?cancel$/.test(label)) { 7522 lines.push(new LineNode({ 7523 "x1": "0", 7524 "y1": "100%", 7525 "x2": "100%", 7526 "y2": "0", 7527 "stroke-width": "0.046em" 7528 })); 7529 } 7530 7531 var svgNode = new SvgNode(lines, { 7532 "width": "100%", 7533 "height": makeEm(totalHeight) 7534 }); 7535 img = buildCommon.makeSvgSpan([], [svgNode], options); 7536 } 7537 7538 img.height = totalHeight; 7539 img.style.height = makeEm(totalHeight); 7540 return img; 7541}; 7542 7543var stretchy = { 7544 encloseSpan, 7545 mathMLnode, 7546 svgSpan 7547}; 7548 7549/** 7550 * Asserts that the node is of the given type and returns it with stricter 7551 * typing. Throws if the node's type does not match. 7552 */ 7553function assertNodeType(node, type) { 7554 if (!node || node.type !== type) { 7555 throw new Error("Expected node of type " + type + ", but got " + (node ? "node of type " + node.type : String(node))); 7556 } // $FlowFixMe, >=0.125 7557 7558 7559 return node; 7560} 7561/** 7562 * Returns the node more strictly typed iff it is of the given type. Otherwise, 7563 * returns null. 7564 */ 7565 7566function assertSymbolNodeType(node) { 7567 var typedNode = checkSymbolNodeType(node); 7568 7569 if (!typedNode) { 7570 throw new Error("Expected node of symbol group type, but got " + (node ? "node of type " + node.type : String(node))); 7571 } 7572 7573 return typedNode; 7574} 7575/** 7576 * Returns the node more strictly typed iff it is of the given type. Otherwise, 7577 * returns null. 7578 */ 7579 7580function checkSymbolNodeType(node) { 7581 if (node && (node.type === "atom" || NON_ATOMS.hasOwnProperty(node.type))) { 7582 // $FlowFixMe 7583 return node; 7584 } 7585 7586 return null; 7587} 7588 7589// NOTE: Unlike most `htmlBuilder`s, this one handles not only "accent", but 7590// also "supsub" since an accent can affect super/subscripting. 7591var htmlBuilder$a = (grp, options) => { 7592 // Accents are handled in the TeXbook pg. 443, rule 12. 7593 var base; 7594 var group; 7595 var supSubGroup; 7596 7597 if (grp && grp.type === "supsub") { 7598 // If our base is a character box, and we have superscripts and 7599 // subscripts, the supsub will defer to us. In particular, we want 7600 // to attach the superscripts and subscripts to the inner body (so 7601 // that the position of the superscripts and subscripts won't be 7602 // affected by the height of the accent). We accomplish this by 7603 // sticking the base of the accent into the base of the supsub, and 7604 // rendering that, while keeping track of where the accent is. 7605 // The real accent group is the base of the supsub group 7606 group = assertNodeType(grp.base, "accent"); // The character box is the base of the accent group 7607 7608 base = group.base; // Stick the character box into the base of the supsub group 7609 7610 grp.base = base; // Rerender the supsub group with its new base, and store that 7611 // result. 7612 7613 supSubGroup = assertSpan(buildGroup$1(grp, options)); // reset original base 7614 7615 grp.base = group; 7616 } else { 7617 group = assertNodeType(grp, "accent"); 7618 base = group.base; 7619 } // Build the base group 7620 7621 7622 var body = buildGroup$1(base, options.havingCrampedStyle()); // Does the accent need to shift for the skew of a character? 7623 7624 var mustShift = group.isShifty && utils.isCharacterBox(base); // Calculate the skew of the accent. This is based on the line "If the 7625 // nucleus is not a single character, let s = 0; otherwise set s to the 7626 // kern amount for the nucleus followed by the \skewchar of its font." 7627 // Note that our skew metrics are just the kern between each character 7628 // and the skewchar. 7629 7630 var skew = 0; 7631 7632 if (mustShift) { 7633 // If the base is a character box, then we want the skew of the 7634 // innermost character. To do that, we find the innermost character: 7635 var baseChar = utils.getBaseElem(base); // Then, we render its group to get the symbol inside it 7636 7637 var baseGroup = buildGroup$1(baseChar, options.havingCrampedStyle()); // Finally, we pull the skew off of the symbol. 7638 7639 skew = assertSymbolDomNode(baseGroup).skew; // Note that we now throw away baseGroup, because the layers we 7640 // removed with getBaseElem might contain things like \color which 7641 // we can't get rid of. 7642 // TODO(emily): Find a better way to get the skew 7643 } 7644 7645 var accentBelow = group.label === "\\c"; // calculate the amount of space between the body and the accent 7646 7647 var clearance = accentBelow ? body.height + body.depth : Math.min(body.height, options.fontMetrics().xHeight); // Build the accent 7648 7649 var accentBody; 7650 7651 if (!group.isStretchy) { 7652 var accent; 7653 var width; 7654 7655 if (group.label === "\\vec") { 7656 // Before version 0.9, \vec used the combining font glyph U+20D7. 7657 // But browsers, especially Safari, are not consistent in how they 7658 // render combining characters when not preceded by a character. 7659 // So now we use an SVG. 7660 // If Safari reforms, we should consider reverting to the glyph. 7661 accent = buildCommon.staticSvg("vec", options); 7662 width = buildCommon.svgData.vec[1]; 7663 } else { 7664 accent = buildCommon.makeOrd({ 7665 mode: group.mode, 7666 text: group.label 7667 }, options, "textord"); 7668 accent = assertSymbolDomNode(accent); // Remove the italic correction of the accent, because it only serves to 7669 // shift the accent over to a place we don't want. 7670 7671 accent.italic = 0; 7672 width = accent.width; 7673 7674 if (accentBelow) { 7675 clearance += accent.depth; 7676 } 7677 } 7678 7679 accentBody = buildCommon.makeSpan(["accent-body"], [accent]); // "Full" accents expand the width of the resulting symbol to be 7680 // at least the width of the accent, and overlap directly onto the 7681 // character without any vertical offset. 7682 7683 var accentFull = group.label === "\\textcircled"; 7684 7685 if (accentFull) { 7686 accentBody.classes.push('accent-full'); 7687 clearance = body.height; 7688 } // Shift the accent over by the skew. 7689 7690 7691 var left = skew; // CSS defines `.katex .accent .accent-body:not(.accent-full) { width: 0 }` 7692 // so that the accent doesn't contribute to the bounding box. 7693 // We need to shift the character by its width (effectively half 7694 // its width) to compensate. 7695 7696 if (!accentFull) { 7697 left -= width / 2; 7698 } 7699 7700 accentBody.style.left = makeEm(left); // \textcircled uses the \bigcirc glyph, so it needs some 7701 // vertical adjustment to match LaTeX. 7702 7703 if (group.label === "\\textcircled") { 7704 accentBody.style.top = ".2em"; 7705 } 7706 7707 accentBody = buildCommon.makeVList({ 7708 positionType: "firstBaseline", 7709 children: [{ 7710 type: "elem", 7711 elem: body 7712 }, { 7713 type: "kern", 7714 size: -clearance 7715 }, { 7716 type: "elem", 7717 elem: accentBody 7718 }] 7719 }, options); 7720 } else { 7721 accentBody = stretchy.svgSpan(group, options); 7722 accentBody = buildCommon.makeVList({ 7723 positionType: "firstBaseline", 7724 children: [{ 7725 type: "elem", 7726 elem: body 7727 }, { 7728 type: "elem", 7729 elem: accentBody, 7730 wrapperClasses: ["svg-align"], 7731 wrapperStyle: skew > 0 ? { 7732 width: "calc(100% - " + makeEm(2 * skew) + ")", 7733 marginLeft: makeEm(2 * skew) 7734 } : undefined 7735 }] 7736 }, options); 7737 } 7738 7739 var accentWrap = buildCommon.makeSpan(["mord", "accent"], [accentBody], options); 7740 7741 if (supSubGroup) { 7742 // Here, we replace the "base" child of the supsub with our newly 7743 // generated accent. 7744 supSubGroup.children[0] = accentWrap; // Since we don't rerun the height calculation after replacing the 7745 // accent, we manually recalculate height. 7746 7747 supSubGroup.height = Math.max(accentWrap.height, supSubGroup.height); // Accents should always be ords, even when their innards are not. 7748 7749 supSubGroup.classes[0] = "mord"; 7750 return supSubGroup; 7751 } else { 7752 return accentWrap; 7753 } 7754}; 7755 7756var mathmlBuilder$9 = (group, options) => { 7757 var accentNode = group.isStretchy ? stretchy.mathMLnode(group.label) : new mathMLTree.MathNode("mo", [makeText(group.label, group.mode)]); 7758 var node = new mathMLTree.MathNode("mover", [buildGroup(group.base, options), accentNode]); 7759 node.setAttribute("accent", "true"); 7760 return node; 7761}; 7762 7763var NON_STRETCHY_ACCENT_REGEX = new RegExp(["\\acute", "\\grave", "\\ddot", "\\tilde", "\\bar", "\\breve", "\\check", "\\hat", "\\vec", "\\dot", "\\mathring"].map(accent => "\\" + accent).join("|")); // Accents 7764 7765defineFunction({ 7766 type: "accent", 7767 names: ["\\acute", "\\grave", "\\ddot", "\\tilde", "\\bar", "\\breve", "\\check", "\\hat", "\\vec", "\\dot", "\\mathring", "\\widecheck", "\\widehat", "\\widetilde", "\\overrightarrow", "\\overleftarrow", "\\Overrightarrow", "\\overleftrightarrow", "\\overgroup", "\\overlinesegment", "\\overleftharpoon", "\\overrightharpoon"], 7768 props: { 7769 numArgs: 1 7770 }, 7771 handler: (context, args) => { 7772 var base = normalizeArgument(args[0]); 7773 var isStretchy = !NON_STRETCHY_ACCENT_REGEX.test(context.funcName); 7774 var isShifty = !isStretchy || context.funcName === "\\widehat" || context.funcName === "\\widetilde" || context.funcName === "\\widecheck"; 7775 return { 7776 type: "accent", 7777 mode: context.parser.mode, 7778 label: context.funcName, 7779 isStretchy: isStretchy, 7780 isShifty: isShifty, 7781 base: base 7782 }; 7783 }, 7784 htmlBuilder: htmlBuilder$a, 7785 mathmlBuilder: mathmlBuilder$9 7786}); // Text-mode accents 7787 7788defineFunction({ 7789 type: "accent", 7790 names: ["\\'", "\\`", "\\^", "\\~", "\\=", "\\u", "\\.", '\\"', "\\c", "\\r", "\\H", "\\v", "\\textcircled"], 7791 props: { 7792 numArgs: 1, 7793 allowedInText: true, 7794 allowedInMath: true, 7795 // unless in strict mode 7796 argTypes: ["primitive"] 7797 }, 7798 handler: (context, args) => { 7799 var base = args[0]; 7800 var mode = context.parser.mode; 7801 7802 if (mode === "math") { 7803 context.parser.settings.reportNonstrict("mathVsTextAccents", "LaTeX's accent " + context.funcName + " works only in text mode"); 7804 mode = "text"; 7805 } 7806 7807 return { 7808 type: "accent", 7809 mode: mode, 7810 label: context.funcName, 7811 isStretchy: false, 7812 isShifty: true, 7813 base: base 7814 }; 7815 }, 7816 htmlBuilder: htmlBuilder$a, 7817 mathmlBuilder: mathmlBuilder$9 7818}); 7819 7820// Horizontal overlap functions 7821defineFunction({ 7822 type: "accentUnder", 7823 names: ["\\underleftarrow", "\\underrightarrow", "\\underleftrightarrow", "\\undergroup", "\\underlinesegment", "\\utilde"], 7824 props: { 7825 numArgs: 1 7826 }, 7827 handler: (_ref, args) => { 7828 var { 7829 parser, 7830 funcName 7831 } = _ref; 7832 var base = args[0]; 7833 return { 7834 type: "accentUnder", 7835 mode: parser.mode, 7836 label: funcName, 7837 base: base 7838 }; 7839 }, 7840 htmlBuilder: (group, options) => { 7841 // Treat under accents much like underlines. 7842 var innerGroup = buildGroup$1(group.base, options); 7843 var accentBody = stretchy.svgSpan(group, options); 7844 var kern = group.label === "\\utilde" ? 0.12 : 0; // Generate the vlist, with the appropriate kerns 7845 7846 var vlist = buildCommon.makeVList({ 7847 positionType: "top", 7848 positionData: innerGroup.height, 7849 children: [{ 7850 type: "elem", 7851 elem: accentBody, 7852 wrapperClasses: ["svg-align"] 7853 }, { 7854 type: "kern", 7855 size: kern 7856 }, { 7857 type: "elem", 7858 elem: innerGroup 7859 }] 7860 }, options); 7861 return buildCommon.makeSpan(["mord", "accentunder"], [vlist], options); 7862 }, 7863 mathmlBuilder: (group, options) => { 7864 var accentNode = stretchy.mathMLnode(group.label); 7865 var node = new mathMLTree.MathNode("munder", [buildGroup(group.base, options), accentNode]); 7866 node.setAttribute("accentunder", "true"); 7867 return node; 7868 } 7869}); 7870 7871// Helper function 7872var paddedNode = group => { 7873 var node = new mathMLTree.MathNode("mpadded", group ? [group] : []); 7874 node.setAttribute("width", "+0.6em"); 7875 node.setAttribute("lspace", "0.3em"); 7876 return node; 7877}; // Stretchy arrows with an optional argument 7878 7879 7880defineFunction({ 7881 type: "xArrow", 7882 names: ["\\xleftarrow", "\\xrightarrow", "\\xLeftarrow", "\\xRightarrow", "\\xleftrightarrow", "\\xLeftrightarrow", "\\xhookleftarrow", "\\xhookrightarrow", "\\xmapsto", "\\xrightharpoondown", "\\xrightharpoonup", "\\xleftharpoondown", "\\xleftharpoonup", "\\xrightleftharpoons", "\\xleftrightharpoons", "\\xlongequal", "\\xtwoheadrightarrow", "\\xtwoheadleftarrow", "\\xtofrom", // The next 3 functions are here to support the mhchem extension. 7883 // Direct use of these functions is discouraged and may break someday. 7884 "\\xrightleftarrows", "\\xrightequilibrium", "\\xleftequilibrium", // The next 3 functions are here only to support the {CD} environment. 7885 "\\\\cdrightarrow", "\\\\cdleftarrow", "\\\\cdlongequal"], 7886 props: { 7887 numArgs: 1, 7888 numOptionalArgs: 1 7889 }, 7890 7891 handler(_ref, args, optArgs) { 7892 var { 7893 parser, 7894 funcName 7895 } = _ref; 7896 return { 7897 type: "xArrow", 7898 mode: parser.mode, 7899 label: funcName, 7900 body: args[0], 7901 below: optArgs[0] 7902 }; 7903 }, 7904 7905 // Flow is unable to correctly infer the type of `group`, even though it's 7906 // unambiguously determined from the passed-in `type` above. 7907 htmlBuilder(group, options) { 7908 var style = options.style; // Build the argument groups in the appropriate style. 7909 // Ref: amsmath.dtx: \hbox{$\scriptstyle\mkern#3mu{#6}\mkern#4mu$}% 7910 // Some groups can return document fragments. Handle those by wrapping 7911 // them in a span. 7912 7913 var newOptions = options.havingStyle(style.sup()); 7914 var upperGroup = buildCommon.wrapFragment(buildGroup$1(group.body, newOptions, options), options); 7915 var arrowPrefix = group.label.slice(0, 2) === "\\x" ? "x" : "cd"; 7916 upperGroup.classes.push(arrowPrefix + "-arrow-pad"); 7917 var lowerGroup; 7918 7919 if (group.below) { 7920 // Build the lower group 7921 newOptions = options.havingStyle(style.sub()); 7922 lowerGroup = buildCommon.wrapFragment(buildGroup$1(group.below, newOptions, options), options); 7923 lowerGroup.classes.push(arrowPrefix + "-arrow-pad"); 7924 } 7925 7926 var arrowBody = stretchy.svgSpan(group, options); // Re shift: Note that stretchy.svgSpan returned arrowBody.depth = 0. 7927 // The point we want on the math axis is at 0.5 * arrowBody.height. 7928 7929 var arrowShift = -options.fontMetrics().axisHeight + 0.5 * arrowBody.height; // 2 mu kern. Ref: amsmath.dtx: #7\if0#2\else\mkern#2mu\fi 7930 7931 var upperShift = -options.fontMetrics().axisHeight - 0.5 * arrowBody.height - 0.111; // 0.111 em = 2 mu 7932 7933 if (upperGroup.depth > 0.25 || group.label === "\\xleftequilibrium") { 7934 upperShift -= upperGroup.depth; // shift up if depth encroaches 7935 } // Generate the vlist 7936 7937 7938 var vlist; 7939 7940 if (lowerGroup) { 7941 var lowerShift = -options.fontMetrics().axisHeight + lowerGroup.height + 0.5 * arrowBody.height + 0.111; 7942 vlist = buildCommon.makeVList({ 7943 positionType: "individualShift", 7944 children: [{ 7945 type: "elem", 7946 elem: upperGroup, 7947 shift: upperShift 7948 }, { 7949 type: "elem", 7950 elem: arrowBody, 7951 shift: arrowShift 7952 }, { 7953 type: "elem", 7954 elem: lowerGroup, 7955 shift: lowerShift 7956 }] 7957 }, options); 7958 } else { 7959 vlist = buildCommon.makeVList({ 7960 positionType: "individualShift", 7961 children: [{ 7962 type: "elem", 7963 elem: upperGroup, 7964 shift: upperShift 7965 }, { 7966 type: "elem", 7967 elem: arrowBody, 7968 shift: arrowShift 7969 }] 7970 }, options); 7971 } // $FlowFixMe: Replace this with passing "svg-align" into makeVList. 7972 7973 7974 vlist.children[0].children[0].children[1].classes.push("svg-align"); 7975 return buildCommon.makeSpan(["mrel", "x-arrow"], [vlist], options); 7976 }, 7977 7978 mathmlBuilder(group, options) { 7979 var arrowNode = stretchy.mathMLnode(group.label); 7980 arrowNode.setAttribute("minsize", group.label.charAt(0) === "x" ? "1.75em" : "3.0em"); 7981 var node; 7982 7983 if (group.body) { 7984 var upperNode = paddedNode(buildGroup(group.body, options)); 7985 7986 if (group.below) { 7987 var lowerNode = paddedNode(buildGroup(group.below, options)); 7988 node = new mathMLTree.MathNode("munderover", [arrowNode, lowerNode, upperNode]); 7989 } else { 7990 node = new mathMLTree.MathNode("mover", [arrowNode, upperNode]); 7991 } 7992 } else if (group.below) { 7993 var _lowerNode = paddedNode(buildGroup(group.below, options)); 7994 7995 node = new mathMLTree.MathNode("munder", [arrowNode, _lowerNode]); 7996 } else { 7997 // This should never happen. 7998 // Parser.js throws an error if there is no argument. 7999 node = paddedNode(); 8000 node = new mathMLTree.MathNode("mover", [arrowNode, node]); 8001 } 8002 8003 return node; 8004 } 8005 8006}); 8007 8008var makeSpan = buildCommon.makeSpan; 8009 8010function htmlBuilder$9(group, options) { 8011 var elements = buildExpression$1(group.body, options, true); 8012 return makeSpan([group.mclass], elements, options); 8013} 8014 8015function mathmlBuilder$8(group, options) { 8016 var node; 8017 var inner = buildExpression(group.body, options); 8018 8019 if (group.mclass === "minner") { 8020 node = new mathMLTree.MathNode("mpadded", inner); 8021 } else if (group.mclass === "mord") { 8022 if (group.isCharacterBox) { 8023 node = inner[0]; 8024 node.type = "mi"; 8025 } else { 8026 node = new mathMLTree.MathNode("mi", inner); 8027 } 8028 } else { 8029 if (group.isCharacterBox) { 8030 node = inner[0]; 8031 node.type = "mo"; 8032 } else { 8033 node = new mathMLTree.MathNode("mo", inner); 8034 } // Set spacing based on what is the most likely adjacent atom type. 8035 // See TeXbook p170. 8036 8037 8038 if (group.mclass === "mbin") { 8039 node.attributes.lspace = "0.22em"; // medium space 8040 8041 node.attributes.rspace = "0.22em"; 8042 } else if (group.mclass === "mpunct") { 8043 node.attributes.lspace = "0em"; 8044 node.attributes.rspace = "0.17em"; // thinspace 8045 } else if (group.mclass === "mopen" || group.mclass === "mclose") { 8046 node.attributes.lspace = "0em"; 8047 node.attributes.rspace = "0em"; 8048 } else if (group.mclass === "minner") { 8049 node.attributes.lspace = "0.0556em"; // 1 mu is the most likely option 8050 8051 node.attributes.width = "+0.1111em"; 8052 } // MathML <mo> default space is 5/18 em, so <mrel> needs no action. 8053 // Ref: https://developer.mozilla.org/en-US/docs/Web/MathML/Element/mo 8054 8055 } 8056 8057 return node; 8058} // Math class commands except \mathop 8059 8060 8061defineFunction({ 8062 type: "mclass", 8063 names: ["\\mathord", "\\mathbin", "\\mathrel", "\\mathopen", "\\mathclose", "\\mathpunct", "\\mathinner"], 8064 props: { 8065 numArgs: 1, 8066 primitive: true 8067 }, 8068 8069 handler(_ref, args) { 8070 var { 8071 parser, 8072 funcName 8073 } = _ref; 8074 var body = args[0]; 8075 return { 8076 type: "mclass", 8077 mode: parser.mode, 8078 mclass: "m" + funcName.slice(5), 8079 // TODO(kevinb): don't prefix with 'm' 8080 body: ordargument(body), 8081 isCharacterBox: utils.isCharacterBox(body) 8082 }; 8083 }, 8084 8085 htmlBuilder: htmlBuilder$9, 8086 mathmlBuilder: mathmlBuilder$8 8087}); 8088var binrelClass = arg => { 8089 // \binrel@ spacing varies with (bin|rel|ord) of the atom in the argument. 8090 // (by rendering separately and with {}s before and after, and measuring 8091 // the change in spacing). We'll do roughly the same by detecting the 8092 // atom type directly. 8093 var atom = arg.type === "ordgroup" && arg.body.length ? arg.body[0] : arg; 8094 8095 if (atom.type === "atom" && (atom.family === "bin" || atom.family === "rel")) { 8096 return "m" + atom.family; 8097 } else { 8098 return "mord"; 8099 } 8100}; // \@binrel{x}{y} renders like y but as mbin/mrel/mord if x is mbin/mrel/mord. 8101// This is equivalent to \binrel@{x}\binrel@@{y} in AMSTeX. 8102 8103defineFunction({ 8104 type: "mclass", 8105 names: ["\\@binrel"], 8106 props: { 8107 numArgs: 2 8108 }, 8109 8110 handler(_ref2, args) { 8111 var { 8112 parser 8113 } = _ref2; 8114 return { 8115 type: "mclass", 8116 mode: parser.mode, 8117 mclass: binrelClass(args[0]), 8118 body: ordargument(args[1]), 8119 isCharacterBox: utils.isCharacterBox(args[1]) 8120 }; 8121 } 8122 8123}); // Build a relation or stacked op by placing one symbol on top of another 8124 8125defineFunction({ 8126 type: "mclass", 8127 names: ["\\stackrel", "\\overset", "\\underset"], 8128 props: { 8129 numArgs: 2 8130 }, 8131 8132 handler(_ref3, args) { 8133 var { 8134 parser, 8135 funcName 8136 } = _ref3; 8137 var baseArg = args[1]; 8138 var shiftedArg = args[0]; 8139 var mclass; 8140 8141 if (funcName !== "\\stackrel") { 8142 // LaTeX applies \binrel spacing to \overset and \underset. 8143 mclass = binrelClass(baseArg); 8144 } else { 8145 mclass = "mrel"; // for \stackrel 8146 } 8147 8148 var baseOp = { 8149 type: "op", 8150 mode: baseArg.mode, 8151 limits: true, 8152 alwaysHandleSupSub: true, 8153 parentIsSupSub: false, 8154 symbol: false, 8155 suppressBaseShift: funcName !== "\\stackrel", 8156 body: ordargument(baseArg) 8157 }; 8158 var supsub = { 8159 type: "supsub", 8160 mode: shiftedArg.mode, 8161 base: baseOp, 8162 sup: funcName === "\\underset" ? null : shiftedArg, 8163 sub: funcName === "\\underset" ? shiftedArg : null 8164 }; 8165 return { 8166 type: "mclass", 8167 mode: parser.mode, 8168 mclass, 8169 body: [supsub], 8170 isCharacterBox: utils.isCharacterBox(supsub) 8171 }; 8172 }, 8173 8174 htmlBuilder: htmlBuilder$9, 8175 mathmlBuilder: mathmlBuilder$8 8176}); 8177 8178// \pmb is a simulation of bold font. 8179// The version of \pmb in ambsy.sty works by typesetting three copies 8180// with small offsets. We use CSS text-shadow. 8181// It's a hack. Not as good as a real bold font. Better than nothing. 8182defineFunction({ 8183 type: "pmb", 8184 names: ["\\pmb"], 8185 props: { 8186 numArgs: 1, 8187 allowedInText: true 8188 }, 8189 8190 handler(_ref, args) { 8191 var { 8192 parser 8193 } = _ref; 8194 return { 8195 type: "pmb", 8196 mode: parser.mode, 8197 mclass: binrelClass(args[0]), 8198 body: ordargument(args[0]) 8199 }; 8200 }, 8201 8202 htmlBuilder(group, options) { 8203 var elements = buildExpression$1(group.body, options, true); 8204 var node = buildCommon.makeSpan([group.mclass], elements, options); 8205 node.style.textShadow = "0.02em 0.01em 0.04px"; 8206 return node; 8207 }, 8208 8209 mathmlBuilder(group, style) { 8210 var inner = buildExpression(group.body, style); // Wrap with an <mstyle> element. 8211 8212 var node = new mathMLTree.MathNode("mstyle", inner); 8213 node.setAttribute("style", "text-shadow: 0.02em 0.01em 0.04px"); 8214 return node; 8215 } 8216 8217}); 8218 8219var cdArrowFunctionName = { 8220 ">": "\\\\cdrightarrow", 8221 "<": "\\\\cdleftarrow", 8222 "=": "\\\\cdlongequal", 8223 "A": "\\uparrow", 8224 "V": "\\downarrow", 8225 "|": "\\Vert", 8226 ".": "no arrow" 8227}; 8228 8229var newCell = () => { 8230 // Create an empty cell, to be filled below with parse nodes. 8231 // The parseTree from this module must be constructed like the 8232 // one created by parseArray(), so an empty CD cell must 8233 // be a ParseNode<"styling">. And CD is always displaystyle. 8234 // So these values are fixed and flow can do implicit typing. 8235 return { 8236 type: "styling", 8237 body: [], 8238 mode: "math", 8239 style: "display" 8240 }; 8241}; 8242 8243var isStartOfArrow = node => { 8244 return node.type === "textord" && node.text === "@"; 8245}; 8246 8247var isLabelEnd = (node, endChar) => { 8248 return (node.type === "mathord" || node.type === "atom") && node.text === endChar; 8249}; 8250 8251function cdArrow(arrowChar, labels, parser) { 8252 // Return a parse tree of an arrow and its labels. 8253 // This acts in a way similar to a macro expansion. 8254 var funcName = cdArrowFunctionName[arrowChar]; 8255 8256 switch (funcName) { 8257 case "\\\\cdrightarrow": 8258 case "\\\\cdleftarrow": 8259 return parser.callFunction(funcName, [labels[0]], [labels[1]]); 8260 8261 case "\\uparrow": 8262 case "\\downarrow": 8263 { 8264 var leftLabel = parser.callFunction("\\\\cdleft", [labels[0]], []); 8265 var bareArrow = { 8266 type: "atom", 8267 text: funcName, 8268 mode: "math", 8269 family: "rel" 8270 }; 8271 var sizedArrow = parser.callFunction("\\Big", [bareArrow], []); 8272 var rightLabel = parser.callFunction("\\\\cdright", [labels[1]], []); 8273 var arrowGroup = { 8274 type: "ordgroup", 8275 mode: "math", 8276 body: [leftLabel, sizedArrow, rightLabel] 8277 }; 8278 return parser.callFunction("\\\\cdparent", [arrowGroup], []); 8279 } 8280 8281 case "\\\\cdlongequal": 8282 return parser.callFunction("\\\\cdlongequal", [], []); 8283 8284 case "\\Vert": 8285 { 8286 var arrow = { 8287 type: "textord", 8288 text: "\\Vert", 8289 mode: "math" 8290 }; 8291 return parser.callFunction("\\Big", [arrow], []); 8292 } 8293 8294 default: 8295 return { 8296 type: "textord", 8297 text: " ", 8298 mode: "math" 8299 }; 8300 } 8301} 8302 8303function parseCD(parser) { 8304 // Get the array's parse nodes with \\ temporarily mapped to \cr. 8305 var parsedRows = []; 8306 parser.gullet.beginGroup(); 8307 parser.gullet.macros.set("\\cr", "\\\\\\relax"); 8308 parser.gullet.beginGroup(); 8309 8310 while (true) { 8311 // eslint-disable-line no-constant-condition 8312 // Get the parse nodes for the next row. 8313 parsedRows.push(parser.parseExpression(false, "\\\\")); 8314 parser.gullet.endGroup(); 8315 parser.gullet.beginGroup(); 8316 var next = parser.fetch().text; 8317 8318 if (next === "&" || next === "\\\\") { 8319 parser.consume(); 8320 } else if (next === "\\end") { 8321 if (parsedRows[parsedRows.length - 1].length === 0) { 8322 parsedRows.pop(); // final row ended in \\ 8323 } 8324 8325 break; 8326 } else { 8327 throw new ParseError("Expected \\\\ or \\cr or \\end", parser.nextToken); 8328 } 8329 } 8330 8331 var row = []; 8332 var body = [row]; // Loop thru the parse nodes. Collect them into cells and arrows. 8333 8334 for (var i = 0; i < parsedRows.length; i++) { 8335 // Start a new row. 8336 var rowNodes = parsedRows[i]; // Create the first cell. 8337 8338 var cell = newCell(); 8339 8340 for (var j = 0; j < rowNodes.length; j++) { 8341 if (!isStartOfArrow(rowNodes[j])) { 8342 // If a parseNode is not an arrow, it goes into a cell. 8343 cell.body.push(rowNodes[j]); 8344 } else { 8345 // Parse node j is an "@", the start of an arrow. 8346 // Before starting on the arrow, push the cell into `row`. 8347 row.push(cell); // Now collect parseNodes into an arrow. 8348 // The character after "@" defines the arrow type. 8349 8350 j += 1; 8351 var arrowChar = assertSymbolNodeType(rowNodes[j]).text; // Create two empty label nodes. We may or may not use them. 8352 8353 var labels = new Array(2); 8354 labels[0] = { 8355 type: "ordgroup", 8356 mode: "math", 8357 body: [] 8358 }; 8359 labels[1] = { 8360 type: "ordgroup", 8361 mode: "math", 8362 body: [] 8363 }; // Process the arrow. 8364 8365 if ("=|.".indexOf(arrowChar) > -1) ; else if ("<>AV".indexOf(arrowChar) > -1) { 8366 // Four arrows, `@>>>`, `@<<<`, `@AAA`, and `@VVV`, each take 8367 // two optional labels. E.g. the right-point arrow syntax is 8368 // really: @>{optional label}>{optional label}> 8369 // Collect parseNodes into labels. 8370 for (var labelNum = 0; labelNum < 2; labelNum++) { 8371 var inLabel = true; 8372 8373 for (var k = j + 1; k < rowNodes.length; k++) { 8374 if (isLabelEnd(rowNodes[k], arrowChar)) { 8375 inLabel = false; 8376 j = k; 8377 break; 8378 } 8379 8380 if (isStartOfArrow(rowNodes[k])) { 8381 throw new ParseError("Missing a " + arrowChar + " character to complete a CD arrow.", rowNodes[k]); 8382 } 8383 8384 labels[labelNum].body.push(rowNodes[k]); 8385 } 8386 8387 if (inLabel) { 8388 // isLabelEnd never returned a true. 8389 throw new ParseError("Missing a " + arrowChar + " character to complete a CD arrow.", rowNodes[j]); 8390 } 8391 } 8392 } else { 8393 throw new ParseError("Expected one of \"<>AV=|.\" after @", rowNodes[j]); 8394 } // Now join the arrow to its labels. 8395 8396 8397 var arrow = cdArrow(arrowChar, labels, parser); // Wrap the arrow in ParseNode<"styling">. 8398 // This is done to match parseArray() behavior. 8399 8400 var wrappedArrow = { 8401 type: "styling", 8402 body: [arrow], 8403 mode: "math", 8404 style: "display" // CD is always displaystyle. 8405 8406 }; 8407 row.push(wrappedArrow); // In CD's syntax, cells are implicit. That is, everything that 8408 // is not an arrow gets collected into a cell. So create an empty 8409 // cell now. It will collect upcoming parseNodes. 8410 8411 cell = newCell(); 8412 } 8413 } 8414 8415 if (i % 2 === 0) { 8416 // Even-numbered rows consist of: cell, arrow, cell, arrow, ... cell 8417 // The last cell is not yet pushed into `row`, so: 8418 row.push(cell); 8419 } else { 8420 // Odd-numbered rows consist of: vert arrow, empty cell, ... vert arrow 8421 // Remove the empty cell that was placed at the beginning of `row`. 8422 row.shift(); 8423 } 8424 8425 row = []; 8426 body.push(row); 8427 } // End row group 8428 8429 8430 parser.gullet.endGroup(); // End array group defining \\ 8431 8432 parser.gullet.endGroup(); // define column separation. 8433 8434 var cols = new Array(body[0].length).fill({ 8435 type: "align", 8436 align: "c", 8437 pregap: 0.25, 8438 // CD package sets \enskip between columns. 8439 postgap: 0.25 // So pre and post each get half an \enskip, i.e. 0.25em. 8440 8441 }); 8442 return { 8443 type: "array", 8444 mode: "math", 8445 body, 8446 arraystretch: 1, 8447 addJot: true, 8448 rowGaps: [null], 8449 cols, 8450 colSeparationType: "CD", 8451 hLinesBeforeRow: new Array(body.length + 1).fill([]) 8452 }; 8453} // The functions below are not available for general use. 8454// They are here only for internal use by the {CD} environment in placing labels 8455// next to vertical arrows. 8456// We don't need any such functions for horizontal arrows because we can reuse 8457// the functionality that already exists for extensible arrows. 8458 8459defineFunction({ 8460 type: "cdlabel", 8461 names: ["\\\\cdleft", "\\\\cdright"], 8462 props: { 8463 numArgs: 1 8464 }, 8465 8466 handler(_ref, args) { 8467 var { 8468 parser, 8469 funcName 8470 } = _ref; 8471 return { 8472 type: "cdlabel", 8473 mode: parser.mode, 8474 side: funcName.slice(4), 8475 label: args[0] 8476 }; 8477 }, 8478 8479 htmlBuilder(group, options) { 8480 var newOptions = options.havingStyle(options.style.sup()); 8481 var label = buildCommon.wrapFragment(buildGroup$1(group.label, newOptions, options), options); 8482 label.classes.push("cd-label-" + group.side); 8483 label.style.bottom = makeEm(0.8 - label.depth); // Zero out label height & depth, so vertical align of arrow is set 8484 // by the arrow height, not by the label. 8485 8486 label.height = 0; 8487 label.depth = 0; 8488 return label; 8489 }, 8490 8491 mathmlBuilder(group, options) { 8492 var label = new mathMLTree.MathNode("mrow", [buildGroup(group.label, options)]); 8493 label = new mathMLTree.MathNode("mpadded", [label]); 8494 label.setAttribute("width", "0"); 8495 8496 if (group.side === "left") { 8497 label.setAttribute("lspace", "-1width"); 8498 } // We have to guess at vertical alignment. We know the arrow is 1.8em tall, 8499 // But we don't know the height or depth of the label. 8500 8501 8502 label.setAttribute("voffset", "0.7em"); 8503 label = new mathMLTree.MathNode("mstyle", [label]); 8504 label.setAttribute("displaystyle", "false"); 8505 label.setAttribute("scriptlevel", "1"); 8506 return label; 8507 } 8508 8509}); 8510defineFunction({ 8511 type: "cdlabelparent", 8512 names: ["\\\\cdparent"], 8513 props: { 8514 numArgs: 1 8515 }, 8516 8517 handler(_ref2, args) { 8518 var { 8519 parser 8520 } = _ref2; 8521 return { 8522 type: "cdlabelparent", 8523 mode: parser.mode, 8524 fragment: args[0] 8525 }; 8526 }, 8527 8528 htmlBuilder(group, options) { 8529 // Wrap the vertical arrow and its labels. 8530 // The parent gets position: relative. The child gets position: absolute. 8531 // So CSS can locate the label correctly. 8532 var parent = buildCommon.wrapFragment(buildGroup$1(group.fragment, options), options); 8533 parent.classes.push("cd-vert-arrow"); 8534 return parent; 8535 }, 8536 8537 mathmlBuilder(group, options) { 8538 return new mathMLTree.MathNode("mrow", [buildGroup(group.fragment, options)]); 8539 } 8540 8541}); 8542 8543// {123} and converts into symbol with code 123. It is used by the *macro* 8544// \char defined in macros.js. 8545 8546defineFunction({ 8547 type: "textord", 8548 names: ["\\@char"], 8549 props: { 8550 numArgs: 1, 8551 allowedInText: true 8552 }, 8553 8554 handler(_ref, args) { 8555 var { 8556 parser 8557 } = _ref; 8558 var arg = assertNodeType(args[0], "ordgroup"); 8559 var group = arg.body; 8560 var number = ""; 8561 8562 for (var i = 0; i < group.length; i++) { 8563 var node = assertNodeType(group[i], "textord"); 8564 number += node.text; 8565 } 8566 8567 var code = parseInt(number); 8568 var text; 8569 8570 if (isNaN(code)) { 8571 throw new ParseError("\\@char has non-numeric argument " + number); // If we drop IE support, the following code could be replaced with 8572 // text = String.fromCodePoint(code) 8573 } else if (code < 0 || code >= 0x10ffff) { 8574 throw new ParseError("\\@char with invalid code point " + number); 8575 } else if (code <= 0xffff) { 8576 text = String.fromCharCode(code); 8577 } else { 8578 // Astral code point; split into surrogate halves 8579 code -= 0x10000; 8580 text = String.fromCharCode((code >> 10) + 0xd800, (code & 0x3ff) + 0xdc00); 8581 } 8582 8583 return { 8584 type: "textord", 8585 mode: parser.mode, 8586 text: text 8587 }; 8588 } 8589 8590}); 8591 8592var htmlBuilder$8 = (group, options) => { 8593 var elements = buildExpression$1(group.body, options.withColor(group.color), false); // \color isn't supposed to affect the type of the elements it contains. 8594 // To accomplish this, we wrap the results in a fragment, so the inner 8595 // elements will be able to directly interact with their neighbors. For 8596 // example, `\color{red}{2 +} 3` has the same spacing as `2 + 3` 8597 8598 return buildCommon.makeFragment(elements); 8599}; 8600 8601var mathmlBuilder$7 = (group, options) => { 8602 var inner = buildExpression(group.body, options.withColor(group.color)); 8603 var node = new mathMLTree.MathNode("mstyle", inner); 8604 node.setAttribute("mathcolor", group.color); 8605 return node; 8606}; 8607 8608defineFunction({ 8609 type: "color", 8610 names: ["\\textcolor"], 8611 props: { 8612 numArgs: 2, 8613 allowedInText: true, 8614 argTypes: ["color", "original"] 8615 }, 8616 8617 handler(_ref, args) { 8618 var { 8619 parser 8620 } = _ref; 8621 var color = assertNodeType(args[0], "color-token").color; 8622 var body = args[1]; 8623 return { 8624 type: "color", 8625 mode: parser.mode, 8626 color, 8627 body: ordargument(body) 8628 }; 8629 }, 8630 8631 htmlBuilder: htmlBuilder$8, 8632 mathmlBuilder: mathmlBuilder$7 8633}); 8634defineFunction({ 8635 type: "color", 8636 names: ["\\color"], 8637 props: { 8638 numArgs: 1, 8639 allowedInText: true, 8640 argTypes: ["color"] 8641 }, 8642 8643 handler(_ref2, args) { 8644 var { 8645 parser, 8646 breakOnTokenText 8647 } = _ref2; 8648 var color = assertNodeType(args[0], "color-token").color; // Set macro \current@color in current namespace to store the current 8649 // color, mimicking the behavior of color.sty. 8650 // This is currently used just to correctly color a \right 8651 // that follows a \color command. 8652 8653 parser.gullet.macros.set("\\current@color", color); // Parse out the implicit body that should be colored. 8654 8655 var body = parser.parseExpression(true, breakOnTokenText); 8656 return { 8657 type: "color", 8658 mode: parser.mode, 8659 color, 8660 body 8661 }; 8662 }, 8663 8664 htmlBuilder: htmlBuilder$8, 8665 mathmlBuilder: mathmlBuilder$7 8666}); 8667 8668// Row breaks within tabular environments, and line breaks at top level 8669 8670defineFunction({ 8671 type: "cr", 8672 names: ["\\\\"], 8673 props: { 8674 numArgs: 0, 8675 numOptionalArgs: 0, 8676 allowedInText: true 8677 }, 8678 8679 handler(_ref, args, optArgs) { 8680 var { 8681 parser 8682 } = _ref; 8683 var size = parser.gullet.future().text === "[" ? parser.parseSizeGroup(true) : null; 8684 var newLine = !parser.settings.displayMode || !parser.settings.useStrictBehavior("newLineInDisplayMode", "In LaTeX, \\\\ or \\newline " + "does nothing in display mode"); 8685 return { 8686 type: "cr", 8687 mode: parser.mode, 8688 newLine, 8689 size: size && assertNodeType(size, "size").value 8690 }; 8691 }, 8692 8693 // The following builders are called only at the top level, 8694 // not within tabular/array environments. 8695 htmlBuilder(group, options) { 8696 var span = buildCommon.makeSpan(["mspace"], [], options); 8697 8698 if (group.newLine) { 8699 span.classes.push("newline"); 8700 8701 if (group.size) { 8702 span.style.marginTop = makeEm(calculateSize(group.size, options)); 8703 } 8704 } 8705 8706 return span; 8707 }, 8708 8709 mathmlBuilder(group, options) { 8710 var node = new mathMLTree.MathNode("mspace"); 8711 8712 if (group.newLine) { 8713 node.setAttribute("linebreak", "newline"); 8714 8715 if (group.size) { 8716 node.setAttribute("height", makeEm(calculateSize(group.size, options))); 8717 } 8718 } 8719 8720 return node; 8721 } 8722 8723}); 8724 8725var globalMap = { 8726 "\\global": "\\global", 8727 "\\long": "\\\\globallong", 8728 "\\\\globallong": "\\\\globallong", 8729 "\\def": "\\gdef", 8730 "\\gdef": "\\gdef", 8731 "\\edef": "\\xdef", 8732 "\\xdef": "\\xdef", 8733 "\\let": "\\\\globallet", 8734 "\\futurelet": "\\\\globalfuture" 8735}; 8736 8737var checkControlSequence = tok => { 8738 var name = tok.text; 8739 8740 if (/^(?:[\\{}$&#^_]|EOF)$/.test(name)) { 8741 throw new ParseError("Expected a control sequence", tok); 8742 } 8743 8744 return name; 8745}; 8746 8747var getRHS = parser => { 8748 var tok = parser.gullet.popToken(); 8749 8750 if (tok.text === "=") { 8751 // consume optional equals 8752 tok = parser.gullet.popToken(); 8753 8754 if (tok.text === " ") { 8755 // consume one optional space 8756 tok = parser.gullet.popToken(); 8757 } 8758 } 8759 8760 return tok; 8761}; 8762 8763var letCommand = (parser, name, tok, global) => { 8764 var macro = parser.gullet.macros.get(tok.text); 8765 8766 if (macro == null) { 8767 // don't expand it later even if a macro with the same name is defined 8768 // e.g., \let\foo=\frac \def\frac{\relax} \frac12 8769 tok.noexpand = true; 8770 macro = { 8771 tokens: [tok], 8772 numArgs: 0, 8773 // reproduce the same behavior in expansion 8774 unexpandable: !parser.gullet.isExpandable(tok.text) 8775 }; 8776 } 8777 8778 parser.gullet.macros.set(name, macro, global); 8779}; // <assignment> -> <non-macro assignment>|<macro assignment> 8780// <non-macro assignment> -> <simple assignment>|\global<non-macro assignment> 8781// <macro assignment> -> <definition>|<prefix><macro assignment> 8782// <prefix> -> \global|\long|\outer 8783 8784 8785defineFunction({ 8786 type: "internal", 8787 names: ["\\global", "\\long", "\\\\globallong" // canât be entered directly 8788 ], 8789 props: { 8790 numArgs: 0, 8791 allowedInText: true 8792 }, 8793 8794 handler(_ref) { 8795 var { 8796 parser, 8797 funcName 8798 } = _ref; 8799 parser.consumeSpaces(); 8800 var token = parser.fetch(); 8801 8802 if (globalMap[token.text]) { 8803 // KaTeX doesn't have \par, so ignore \long 8804 if (funcName === "\\global" || funcName === "\\\\globallong") { 8805 token.text = globalMap[token.text]; 8806 } 8807 8808 return assertNodeType(parser.parseFunction(), "internal"); 8809 } 8810 8811 throw new ParseError("Invalid token after macro prefix", token); 8812 } 8813 8814}); // Basic support for macro definitions: \def, \gdef, \edef, \xdef 8815// <definition> -> <def><control sequence><definition text> 8816// <def> -> \def|\gdef|\edef|\xdef 8817// <definition text> -> <parameter text><left brace><balanced text><right brace> 8818 8819defineFunction({ 8820 type: "internal", 8821 names: ["\\def", "\\gdef", "\\edef", "\\xdef"], 8822 props: { 8823 numArgs: 0, 8824 allowedInText: true, 8825 primitive: true 8826 }, 8827 8828 handler(_ref2) { 8829 var { 8830 parser, 8831 funcName 8832 } = _ref2; 8833 var tok = parser.gullet.popToken(); 8834 var name = tok.text; 8835 8836 if (/^(?:[\\{}$&#^_]|EOF)$/.test(name)) { 8837 throw new ParseError("Expected a control sequence", tok); 8838 } 8839 8840 var numArgs = 0; 8841 var insert; 8842 var delimiters = [[]]; // <parameter text> contains no braces 8843 8844 while (parser.gullet.future().text !== "{") { 8845 tok = parser.gullet.popToken(); 8846 8847 if (tok.text === "#") { 8848 // If the very last character of the <parameter text> is #, so that 8849 // this # is immediately followed by {, TeX will behave as if the { 8850 // had been inserted at the right end of both the parameter text 8851 // and the replacement text. 8852 if (parser.gullet.future().text === "{") { 8853 insert = parser.gullet.future(); 8854 delimiters[numArgs].push("{"); 8855 break; 8856 } // A parameter, the first appearance of # must be followed by 1, 8857 // the next by 2, and so on;
vendor: 4,192 bytes, lines 8857-9002
8857 up to nine #âs are allowed 8858 8859 8860 tok = parser.gullet.popToken(); 8861 8862 if (!/^[1-9]$/.test(tok.text)) { 8863 throw new ParseError("Invalid argument number \"" + tok.text + "\""); 8864 } 8865 8866 if (parseInt(tok.text) !== numArgs + 1) { 8867 throw new ParseError("Argument number \"" + tok.text + "\" out of order"); 8868 } 8869 8870 numArgs++; 8871 delimiters.push([]); 8872 } else if (tok.text === "EOF") { 8873 throw new ParseError("Expected a macro definition"); 8874 } else { 8875 delimiters[numArgs].push(tok.text); 8876 } 8877 } // replacement text, enclosed in '{' and '}' and properly nested 8878 8879 8880 var { 8881 tokens 8882 } = parser.gullet.consumeArg(); 8883 8884 if (insert) { 8885 tokens.unshift(insert); 8886 } 8887 8888 if (funcName === "\\edef" || funcName === "\\xdef") { 8889 tokens = parser.gullet.expandTokens(tokens); 8890 tokens.reverse(); // to fit in with stack order 8891 } // Final arg is the expansion of the macro 8892 8893 8894 parser.gullet.macros.set(name, { 8895 tokens, 8896 numArgs, 8897 delimiters 8898 }, funcName === globalMap[funcName]); 8899 return { 8900 type: "internal", 8901 mode: parser.mode 8902 }; 8903 } 8904 8905}); // <simple assignment> -> <let assignment> 8906// <let assignment> -> \futurelet<control sequence><token><token> 8907// | \let<control sequence><equals><one optional space><token> 8908// <equals> -> <optional spaces>|<optional spaces>= 8909 8910defineFunction({ 8911 type: "internal", 8912 names: ["\\let", "\\\\globallet" // canât be entered directly 8913 ], 8914 props: { 8915 numArgs: 0, 8916 allowedInText: true, 8917 primitive: true 8918 }, 8919 8920 handler(_ref3) { 8921 var { 8922 parser, 8923 funcName 8924 } = _ref3; 8925 var name = checkControlSequence(parser.gullet.popToken()); 8926 parser.gullet.consumeSpaces(); 8927 var tok = getRHS(parser); 8928 letCommand(parser, name, tok, funcName === "\\\\globallet"); 8929 return { 8930 type: "internal", 8931 mode: parser.mode 8932 }; 8933 } 8934 8935}); // ref: https://www.tug.org/TUGboat/tb09-3/tb22bechtolsheim.pdf 8936 8937defineFunction({ 8938 type: "internal", 8939 names: ["\\futurelet", "\\\\globalfuture" // canât be entered directly 8940 ], 8941 props: { 8942 numArgs: 0, 8943 allowedInText: true, 8944 primitive: true 8945 }, 8946 8947 handler(_ref4) { 8948 var { 8949 parser, 8950 funcName 8951 } = _ref4; 8952 var name = checkControlSequence(parser.gullet.popToken()); 8953 var middle = parser.gullet.popToken(); 8954 var tok = parser.gullet.popToken(); 8955 letCommand(parser, name, tok, funcName === "\\\\globalfuture"); 8956 parser.gullet.pushToken(tok); 8957 parser.gullet.pushToken(middle); 8958 return { 8959 type: "internal", 8960 mode: parser.mode 8961 }; 8962 } 8963 8964}); 8965 8966/** 8967 * This file deals with creating delimiters of various sizes. The TeXbook 8968 * discusses these routines on page 441-442, in the "Another subroutine sets box 8969 * x to a specified variable delimiter" paragraph. 8970 * 8971 * There are three main routines here. `makeSmallDelim` makes a delimiter in the 8972 * normal font, but in either text, script, or scriptscript style. 8973 * `makeLargeDelim` makes a delimiter in textstyle, but in one of the Size1, 8974 * Size2, Size3, or Size4 fonts. `makeStackedDelim` makes a delimiter out of 8975 * smaller pieces that are stacked on top of one another. 8976 * 8977 * The functions take a parameter `center`, which determines if the delimiter 8978 * should be centered around the axis. 8979 * 8980 * Then, there are three exposed functions. `sizedDelim` makes a delimiter in 8981 * one of the given sizes. This is used for things like `\bigl`. 8982 * `customSizedDelim` makes a delimiter with a given total height+depth. It is 8983 * called in places like `\sqrt`. `leftRightDelim` makes an appropriate 8984 * delimiter which surrounds an expression of a given height an depth. It is 8985 * used in `\left` and `\right`. 8986 */ 8987 8988/** 8989 * Get the metrics for a given symbol and font, after transformation (i.e. 8990 * after following replacement from symbols.js) 8991 */ 8992var getMetrics = function getMetrics(symbol, font, mode) { 8993 var replace = symbols.math[symbol] && symbols.math[symbol].replace; 8994 var metrics = getCharacterMetrics(replace || symbol, font, mode); 8995 8996 if (!metrics) { 8997 throw new Error("Unsupported symbol " + symbol + " and font size " + font + "."); 8998 } 8999 9000 return metrics; 9001}; 9002/**
vendor: 173,327 bytes, lines 9003-15080
9003 * Puts a delimiter span in a given style, and adds appropriate height, depth, 9004 * and maxFontSizes. 9005 */ 9006 9007 9008var styleWrap = function styleWrap(delim, toStyle, options, classes) { 9009 var newOptions = options.havingBaseStyle(toStyle); 9010 var span = buildCommon.makeSpan(classes.concat(newOptions.sizingClasses(options)), [delim], options); 9011 var delimSizeMultiplier = newOptions.sizeMultiplier / options.sizeMultiplier; 9012 span.height *= delimSizeMultiplier; 9013 span.depth *= delimSizeMultiplier; 9014 span.maxFontSize = newOptions.sizeMultiplier; 9015 return span; 9016}; 9017 9018var centerSpan = function centerSpan(span, options, style) { 9019 var newOptions = options.havingBaseStyle(style); 9020 var shift = (1 - options.sizeMultiplier / newOptions.sizeMultiplier) * options.fontMetrics().axisHeight; 9021 span.classes.push("delimcenter"); 9022 span.style.top = makeEm(shift); 9023 span.height -= shift; 9024 span.depth += shift; 9025}; 9026/** 9027 * Makes a small delimiter. This is a delimiter that comes in the Main-Regular 9028 * font, but is restyled to either be in textstyle, scriptstyle, or 9029 * scriptscriptstyle. 9030 */ 9031 9032 9033var makeSmallDelim = function makeSmallDelim(delim, style, center, options, mode, classes) { 9034 var text = buildCommon.makeSymbol(delim, "Main-Regular", mode, options); 9035 var span = styleWrap(text, style, options, classes); 9036 9037 if (center) { 9038 centerSpan(span, options, style); 9039 } 9040 9041 return span; 9042}; 9043/** 9044 * Builds a symbol in the given font size (note size is an integer) 9045 */ 9046 9047 9048var mathrmSize = function mathrmSize(value, size, mode, options) { 9049 return buildCommon.makeSymbol(value, "Size" + size + "-Regular", mode, options); 9050}; 9051/** 9052 * Makes a large delimiter. This is a delimiter that comes in the Size1, Size2, 9053 * Size3, or Size4 fonts. It is always rendered in textstyle. 9054 */ 9055 9056 9057var makeLargeDelim = function makeLargeDelim(delim, size, center, options, mode, classes) { 9058 var inner = mathrmSize(delim, size, mode, options); 9059 var span = styleWrap(buildCommon.makeSpan(["delimsizing", "size" + size], [inner], options), Style$1.TEXT, options, classes); 9060 9061 if (center) { 9062 centerSpan(span, options, Style$1.TEXT); 9063 } 9064 9065 return span; 9066}; 9067/** 9068 * Make a span from a font glyph with the given offset and in the given font. 9069 * This is used in makeStackedDelim to make the stacking pieces for the delimiter. 9070 */ 9071 9072 9073var makeGlyphSpan = function makeGlyphSpan(symbol, font, mode) { 9074 var sizeClass; // Apply the correct CSS class to choose the right font. 9075 9076 if (font === "Size1-Regular") { 9077 sizeClass = "delim-size1"; 9078 } else 9079 /* if (font === "Size4-Regular") */ 9080 { 9081 sizeClass = "delim-size4"; 9082 } 9083 9084 var corner = buildCommon.makeSpan(["delimsizinginner", sizeClass], [buildCommon.makeSpan([], [buildCommon.makeSymbol(symbol, font, mode)])]); // Since this will be passed into `makeVList` in the end, wrap the element 9085 // in the appropriate tag that VList uses. 9086 9087 return { 9088 type: "elem", 9089 elem: corner 9090 }; 9091}; 9092 9093var makeInner = function makeInner(ch, height, options) { 9094 // Create a span with inline SVG for the inner part of a tall stacked delimiter. 9095 var width = fontMetricsData['Size4-Regular'][ch.charCodeAt(0)] ? fontMetricsData['Size4-Regular'][ch.charCodeAt(0)][4] : fontMetricsData['Size1-Regular'][ch.charCodeAt(0)][4]; 9096 var path = new PathNode("inner", innerPath(ch, Math.round(1000 * height))); 9097 var svgNode = new SvgNode([path], { 9098 "width": makeEm(width), 9099 "height": makeEm(height), 9100 // Override CSS rule `.katex svg { width: 100% }` 9101 "style": "width:" + makeEm(width), 9102 "viewBox": "0 0 " + 1000 * width + " " + Math.round(1000 * height), 9103 "preserveAspectRatio": "xMinYMin" 9104 }); 9105 var span = buildCommon.makeSvgSpan([], [svgNode], options); 9106 span.height = height; 9107 span.style.height = makeEm(height); 9108 span.style.width = makeEm(width); 9109 return { 9110 type: "elem", 9111 elem: span 9112 }; 9113}; // Helpers for makeStackedDelim 9114 9115 9116var lapInEms = 0.008; 9117var lap = { 9118 type: "kern", 9119 size: -1 * lapInEms 9120}; 9121var verts = ["|", "\\lvert", "\\rvert", "\\vert"]; 9122var doubleVerts = ["\\|", "\\lVert", "\\rVert", "\\Vert"]; 9123/** 9124 * Make a stacked delimiter out of a given delimiter, with the total height at 9125 * least `heightTotal`. This routine is mentioned on page 442 of the TeXbook. 9126 */ 9127 9128var makeStackedDelim = function makeStackedDelim(delim, heightTotal, center, options, mode, classes) { 9129 // There are four parts, the top, an optional middle, a repeated part, and a 9130 // bottom. 9131 var top; 9132 var middle; 9133 var repeat; 9134 var bottom; 9135 var svgLabel = ""; 9136 var viewBoxWidth = 0; 9137 top = repeat = bottom = delim; 9138 middle = null; // Also keep track of what font the delimiters are in 9139 9140 var font = "Size1-Regular"; // We set the parts and font based on the symbol. Note that we use 9141 // '\u23d0' instead of '|' and '\u2016' instead of '\\|' for the 9142 // repeats of the arrows 9143 9144 if (delim === "\\uparrow") { 9145 repeat = bottom = "\u23d0"; 9146 } else if (delim === "\\Uparrow") { 9147 repeat = bottom = "\u2016"; 9148 } else if (delim === "\\downarrow") { 9149 top = repeat = "\u23d0"; 9150 } else if (delim === "\\Downarrow") { 9151 top = repeat = "\u2016"; 9152 } else if (delim === "\\updownarrow") { 9153 top = "\\uparrow"; 9154 repeat = "\u23d0"; 9155 bottom = "\\downarrow"; 9156 } else if (delim === "\\Updownarrow") { 9157 top = "\\Uparrow"; 9158 repeat = "\u2016"; 9159 bottom = "\\Downarrow"; 9160 } else if (utils.contains(verts, delim)) { 9161 repeat = "\u2223"; 9162 svgLabel = "vert"; 9163 viewBoxWidth = 333; 9164 } else if (utils.contains(doubleVerts, delim)) { 9165 repeat = "\u2225"; 9166 svgLabel = "doublevert"; 9167 viewBoxWidth = 556; 9168 } else if (delim === "[" || delim === "\\lbrack") { 9169 top = "\u23a1"; 9170 repeat = "\u23a2"; 9171 bottom = "\u23a3"; 9172 font = "Size4-Regular"; 9173 svgLabel = "lbrack"; 9174 viewBoxWidth = 667; 9175 } else if (delim === "]" || delim === "\\rbrack") { 9176 top = "\u23a4"; 9177 repeat = "\u23a5"; 9178 bottom = "\u23a6"; 9179 font = "Size4-Regular"; 9180 svgLabel = "rbrack"; 9181 viewBoxWidth = 667; 9182 } else if (delim === "\\lfloor" || delim === "\u230a") { 9183 repeat = top = "\u23a2"; 9184 bottom = "\u23a3"; 9185 font = "Size4-Regular"; 9186 svgLabel = "lfloor"; 9187 viewBoxWidth = 667; 9188 } else if (delim === "\\lceil" || delim === "\u2308") { 9189 top = "\u23a1"; 9190 repeat = bottom = "\u23a2"; 9191 font = "Size4-Regular"; 9192 svgLabel = "lceil"; 9193 viewBoxWidth = 667; 9194 } else if (delim === "\\rfloor" || delim === "\u230b") { 9195 repeat = top = "\u23a5"; 9196 bottom = "\u23a6"; 9197 font = "Size4-Regular"; 9198 svgLabel = "rfloor"; 9199 viewBoxWidth = 667; 9200 } else if (delim === "\\rceil" || delim === "\u2309") { 9201 top = "\u23a4"; 9202 repeat = bottom = "\u23a5"; 9203 font = "Size4-Regular"; 9204 svgLabel = "rceil"; 9205 viewBoxWidth = 667; 9206 } else if (delim === "(" || delim === "\\lparen") { 9207 top = "\u239b"; 9208 repeat = "\u239c"; 9209 bottom = "\u239d"; 9210 font = "Size4-Regular"; 9211 svgLabel = "lparen"; 9212 viewBoxWidth = 875; 9213 } else if (delim === ")" || delim === "\\rparen") { 9214 top = "\u239e"; 9215 repeat = "\u239f"; 9216 bottom = "\u23a0"; 9217 font = "Size4-Regular"; 9218 svgLabel = "rparen"; 9219 viewBoxWidth = 875; 9220 } else if (delim === "\\{" || delim === "\\lbrace") { 9221 top = "\u23a7"; 9222 middle = "\u23a8"; 9223 bottom = "\u23a9"; 9224 repeat = "\u23aa"; 9225 font = "Size4-Regular"; 9226 } else if (delim === "\\}" || delim === "\\rbrace") { 9227 top = "\u23ab"; 9228 middle = "\u23ac"; 9229 bottom = "\u23ad"; 9230 repeat = "\u23aa"; 9231 font = "Size4-Regular"; 9232 } else if (delim === "\\lgroup" || delim === "\u27ee") { 9233 top = "\u23a7"; 9234 bottom = "\u23a9"; 9235 repeat = "\u23aa"; 9236 font = "Size4-Regular"; 9237 } else if (delim === "\\rgroup" || delim === "\u27ef") { 9238 top = "\u23ab"; 9239 bottom = "\u23ad"; 9240 repeat = "\u23aa"; 9241 font = "Size4-Regular"; 9242 } else if (delim === "\\lmoustache" || delim === "\u23b0") { 9243 top = "\u23a7"; 9244 bottom = "\u23ad"; 9245 repeat = "\u23aa"; 9246 font = "Size4-Regular"; 9247 } else if (delim === "\\rmoustache" || delim === "\u23b1") { 9248 top = "\u23ab"; 9249 bottom = "\u23a9"; 9250 repeat = "\u23aa"; 9251 font = "Size4-Regular"; 9252 } // Get the metrics of the four sections 9253 9254 9255 var topMetrics = getMetrics(top, font, mode); 9256 var topHeightTotal = topMetrics.height + topMetrics.depth; 9257 var repeatMetrics = getMetrics(repeat, font, mode); 9258 var repeatHeightTotal = repeatMetrics.height + repeatMetrics.depth; 9259 var bottomMetrics = getMetrics(bottom, font, mode); 9260 var bottomHeightTotal = bottomMetrics.height + bottomMetrics.depth; 9261 var middleHeightTotal = 0; 9262 var middleFactor = 1; 9263 9264 if (middle !== null) { 9265 var middleMetrics = getMetrics(middle, font, mode); 9266 middleHeightTotal = middleMetrics.height + middleMetrics.depth; 9267 middleFactor = 2; // repeat symmetrically above and below middle 9268 } // Calculate the minimal height that the delimiter can have. 9269 // It is at least the size of the top, bottom, and optional middle combined. 9270 9271 9272 var minHeight = topHeightTotal + bottomHeightTotal + middleHeightTotal; // Compute the number of copies of the repeat symbol we will need 9273 9274 var repeatCount = Math.max(0, Math.ceil((heightTotal - minHeight) / (middleFactor * repeatHeightTotal))); // Compute the total height of the delimiter including all the symbols 9275 9276 var realHeightTotal = minHeight + repeatCount * middleFactor * repeatHeightTotal; // The center of the delimiter is placed at the center of the axis. Note 9277 // that in this context, "center" means that the delimiter should be 9278 // centered around the axis in the current style, while normally it is 9279 // centered around the axis in textstyle. 9280 9281 var axisHeight = options.fontMetrics().axisHeight; 9282 9283 if (center) { 9284 axisHeight *= options.sizeMultiplier; 9285 } // Calculate the depth 9286 9287 9288 var depth = realHeightTotal / 2 - axisHeight; // Now, we start building the pieces that will go into the vlist 9289 // Keep a list of the pieces of the stacked delimiter 9290 9291 var stack = []; 9292 9293 if (svgLabel.length > 0) { 9294 // Instead of stacking glyphs, create a single SVG. 9295 // This evades browser problems with imprecise positioning of spans. 9296 var midHeight = realHeightTotal - topHeightTotal - bottomHeightTotal; 9297 var viewBoxHeight = Math.round(realHeightTotal * 1000); 9298 var pathStr = tallDelim(svgLabel, Math.round(midHeight * 1000)); 9299 var path = new PathNode(svgLabel, pathStr); 9300 var width = (viewBoxWidth / 1000).toFixed(3) + "em"; 9301 var height = (viewBoxHeight / 1000).toFixed(3) + "em"; 9302 var svg = new SvgNode([path], { 9303 "width": width, 9304 "height": height, 9305 "viewBox": "0 0 " + viewBoxWidth + " " + viewBoxHeight 9306 }); 9307 var wrapper = buildCommon.makeSvgSpan([], [svg], options); 9308 wrapper.height = viewBoxHeight / 1000; 9309 wrapper.style.width = width; 9310 wrapper.style.height = height; 9311 stack.push({ 9312 type: "elem", 9313 elem: wrapper 9314 }); 9315 } else { 9316 // Stack glyphs 9317 // Start by adding the bottom symbol 9318 stack.push(makeGlyphSpan(bottom, font, mode)); 9319 stack.push(lap); // overlap 9320 9321 if (middle === null) { 9322 // The middle section will be an SVG. Make it an extra 0.016em tall. 9323 // We'll overlap by 0.008em at top and bottom. 9324 var innerHeight = realHeightTotal - topHeightTotal - bottomHeightTotal + 2 * lapInEms; 9325 stack.push(makeInner(repeat, innerHeight, options)); 9326 } else { 9327 // When there is a middle bit, we need the middle part and two repeated 9328 // sections 9329 var _innerHeight = (realHeightTotal - topHeightTotal - bottomHeightTotal - middleHeightTotal) / 2 + 2 * lapInEms; 9330 9331 stack.push(makeInner(repeat, _innerHeight, options)); // Now insert the middle of the brace. 9332 9333 stack.push(lap); 9334 stack.push(makeGlyphSpan(middle, font, mode)); 9335 stack.push(lap); 9336 stack.push(makeInner(repeat, _innerHeight, options)); 9337 } // Add the top symbol 9338 9339 9340 stack.push(lap); 9341 stack.push(makeGlyphSpan(top, font, mode)); 9342 } // Finally, build the vlist 9343 9344 9345 var newOptions = options.havingBaseStyle(Style$1.TEXT); 9346 var inner = buildCommon.makeVList({ 9347 positionType: "bottom", 9348 positionData: depth, 9349 children: stack 9350 }, newOptions); 9351 return styleWrap(buildCommon.makeSpan(["delimsizing", "mult"], [inner], newOptions), Style$1.TEXT, options, classes); 9352}; // All surds have 0.08em padding above the vinculum inside the SVG. 9353// That keeps browser span height rounding error from pinching the line. 9354 9355 9356var vbPad = 80; // padding above the surd, measured inside the viewBox. 9357 9358var emPad = 0.08; // padding, in ems, measured in the document. 9359 9360var sqrtSvg = function sqrtSvg(sqrtName, height, viewBoxHeight, extraVinculum, options) { 9361 var path = sqrtPath(sqrtName, extraVinculum, viewBoxHeight); 9362 var pathNode = new PathNode(sqrtName, path); 9363 var svg = new SvgNode([pathNode], { 9364 // Note: 1000:1 ratio of viewBox to document em width. 9365 "width": "400em", 9366 "height": makeEm(height), 9367 "viewBox": "0 0 400000 " + viewBoxHeight, 9368 "preserveAspectRatio": "xMinYMin slice" 9369 }); 9370 return buildCommon.makeSvgSpan(["hide-tail"], [svg], options); 9371}; 9372/** 9373 * Make a sqrt image of the given height, 9374 */ 9375 9376 9377var makeSqrtImage = function makeSqrtImage(height, options) { 9378 // Define a newOptions that removes the effect of size changes such as \Huge. 9379 // We don't pick different a height surd for \Huge. For it, we scale up. 9380 var newOptions = options.havingBaseSizing(); // Pick the desired surd glyph from a sequence of surds. 9381 9382 var delim = traverseSequence("\\surd", height * newOptions.sizeMultiplier, stackLargeDelimiterSequence, newOptions); 9383 var sizeMultiplier = newOptions.sizeMultiplier; // default 9384 // The standard sqrt SVGs each have a 0.04em thick vinculum. 9385 // If Settings.minRuleThickness is larger than that, we add extraVinculum. 9386 9387 var extraVinculum = Math.max(0, options.minRuleThickness - options.fontMetrics().sqrtRuleThickness); // Create a span containing an SVG image of a sqrt symbol. 9388 9389 var span; 9390 var spanHeight = 0; 9391 var texHeight = 0; 9392 var viewBoxHeight = 0; 9393 var advanceWidth; // We create viewBoxes with 80 units of "padding" above each surd. 9394 // Then browser rounding error on the parent span height will not 9395 // encroach on the ink of the vinculum. But that padding is not 9396 // included in the TeX-like `height` used for calculation of 9397 // vertical alignment. So texHeight = span.height < span.style.height. 9398 9399 if (delim.type === "small") { 9400 // Get an SVG that is derived from glyph U+221A in font KaTeX-Main. 9401 // 1000 unit normal glyph height. 9402 viewBoxHeight = 1000 + 1000 * extraVinculum + vbPad; 9403 9404 if (height < 1.0) { 9405 sizeMultiplier = 1.0; // mimic a \textfont radical 9406 } else if (height < 1.4) { 9407 sizeMultiplier = 0.7; // mimic a \scriptfont radical 9408 } 9409 9410 spanHeight = (1.0 + extraVinculum + emPad) / sizeMultiplier; 9411 texHeight = (1.00 + extraVinculum) / sizeMultiplier; 9412 span = sqrtSvg("sqrtMain", spanHeight, viewBoxHeight, extraVinculum, options); 9413 span.style.minWidth = "0.853em"; 9414 advanceWidth = 0.833 / sizeMultiplier; // from the font. 9415 } else if (delim.type === "large") { 9416 // These SVGs come from fonts: KaTeX_Size1, _Size2, etc. 9417 viewBoxHeight = (1000 + vbPad) * sizeToMaxHeight[delim.size]; 9418 texHeight = (sizeToMaxHeight[delim.size] + extraVinculum) / sizeMultiplier; 9419 spanHeight = (sizeToMaxHeight[delim.size] + extraVinculum + emPad) / sizeMultiplier; 9420 span = sqrtSvg("sqrtSize" + delim.size, spanHeight, viewBoxHeight, extraVinculum, options); 9421 span.style.minWidth = "1.02em"; 9422 advanceWidth = 1.0 / sizeMultiplier; // 1.0 from the font. 9423 } else { 9424 // Tall sqrt. In TeX, this would be stacked using multiple glyphs. 9425 // We'll use a single SVG to accomplish the same thing. 9426 spanHeight = height + extraVinculum + emPad; 9427 texHeight = height + extraVinculum; 9428 viewBoxHeight = Math.floor(1000 * height + extraVinculum) + vbPad; 9429 span = sqrtSvg("sqrtTall", spanHeight, viewBoxHeight, extraVinculum, options); 9430 span.style.minWidth = "0.742em"; 9431 advanceWidth = 1.056; 9432 } 9433 9434 span.height = texHeight; 9435 span.style.height = makeEm(spanHeight); 9436 return { 9437 span, 9438 advanceWidth, 9439 // Calculate the actual line width. 9440 // This actually should depend on the chosen font -- e.g. \boldmath 9441 // should use the thicker surd symbols from e.g. KaTeX_Main-Bold, and 9442 // have thicker rules. 9443 ruleWidth: (options.fontMetrics().sqrtRuleThickness + extraVinculum) * sizeMultiplier 9444 }; 9445}; // There are three kinds of delimiters, delimiters that stack when they become 9446// too large 9447 9448 9449var stackLargeDelimiters = ["(", "\\lparen", ")", "\\rparen", "[", "\\lbrack", "]", "\\rbrack", "\\{", "\\lbrace", "\\}", "\\rbrace", "\\lfloor", "\\rfloor", "\u230a", "\u230b", "\\lceil", "\\rceil", "\u2308", "\u2309", "\\surd"]; // delimiters that always stack 9450 9451var stackAlwaysDelimiters = ["\\uparrow", "\\downarrow", "\\updownarrow", "\\Uparrow", "\\Downarrow", "\\Updownarrow", "|", "\\|", "\\vert", "\\Vert", "\\lvert", "\\rvert", "\\lVert", "\\rVert", "\\lgroup", "\\rgroup", "\u27ee", "\u27ef", "\\lmoustache", "\\rmoustache", "\u23b0", "\u23b1"]; // and delimiters that never stack 9452 9453var stackNeverDelimiters = ["<", ">", "\\langle", "\\rangle", "/", "\\backslash", "\\lt", "\\gt"]; // Metrics of the different sizes. Found by looking at TeX's output of 9454// $\bigl| // \Bigl| \biggl| \Biggl| \showlists$ 9455// Used to create stacked delimiters of appropriate sizes in makeSizedDelim. 9456 9457var sizeToMaxHeight = [0, 1.2, 1.8, 2.4, 3.0]; 9458/** 9459 * Used to create a delimiter of a specific size, where `size` is 1, 2, 3, or 4. 9460 */ 9461 9462var makeSizedDelim = function makeSizedDelim(delim, size, options, mode, classes) { 9463 // < and > turn into \langle and \rangle in delimiters 9464 if (delim === "<" || delim === "\\lt" || delim === "\u27e8") { 9465 delim = "\\langle"; 9466 } else if (delim === ">" || delim === "\\gt" || delim === "\u27e9") { 9467 delim = "\\rangle"; 9468 } // Sized delimiters are never centered. 9469 9470 9471 if (utils.contains(stackLargeDelimiters, delim) || utils.contains(stackNeverDelimiters, delim)) { 9472 return makeLargeDelim(delim, size, false, options, mode, classes); 9473 } else if (utils.contains(stackAlwaysDelimiters, delim)) { 9474 return makeStackedDelim(delim, sizeToMaxHeight[size], false, options, mode, classes); 9475 } else { 9476 throw new ParseError("Illegal delimiter: '" + delim + "'"); 9477 } 9478}; 9479/** 9480 * There are three different sequences of delimiter sizes that the delimiters 9481 * follow depending on the kind of delimiter. This is used when creating custom 9482 * sized delimiters to decide whether to create a small, large, or stacked 9483 * delimiter. 9484 * 9485 * In real TeX, these sequences aren't explicitly defined, but are instead 9486 * defined inside the font metrics. Since there are only three sequences that 9487 * are possible for the delimiters that TeX defines, it is easier to just encode 9488 * them explicitly here. 9489 */ 9490 9491 9492// Delimiters that never stack try small delimiters and large delimiters only 9493var stackNeverDelimiterSequence = [{ 9494 type: "small", 9495 style: Style$1.SCRIPTSCRIPT 9496}, { 9497 type: "small", 9498 style: Style$1.SCRIPT 9499}, { 9500 type: "small", 9501 style: Style$1.TEXT 9502}, { 9503 type: "large", 9504 size: 1 9505}, { 9506 type: "large", 9507 size: 2 9508}, { 9509 type: "large", 9510 size: 3 9511}, { 9512 type: "large", 9513 size: 4 9514}]; // Delimiters that always stack try the small delimiters first, then stack 9515 9516var stackAlwaysDelimiterSequence = [{ 9517 type: "small", 9518 style: Style$1.SCRIPTSCRIPT 9519}, { 9520 type: "small", 9521 style: Style$1.SCRIPT 9522}, { 9523 type: "small", 9524 style: Style$1.TEXT 9525}, { 9526 type: "stack" 9527}]; // Delimiters that stack when large try the small and then large delimiters, and 9528// stack afterwards 9529 9530var stackLargeDelimiterSequence = [{ 9531 type: "small", 9532 style: Style$1.SCRIPTSCRIPT 9533}, { 9534 type: "small", 9535 style: Style$1.SCRIPT 9536}, { 9537 type: "small", 9538 style: Style$1.TEXT 9539}, { 9540 type: "large", 9541 size: 1 9542}, { 9543 type: "large", 9544 size: 2 9545}, { 9546 type: "large", 9547 size: 3 9548}, { 9549 type: "large", 9550 size: 4 9551}, { 9552 type: "stack" 9553}]; 9554/** 9555 * Get the font used in a delimiter based on what kind of delimiter it is. 9556 * TODO(#963) Use more specific font family return type once that is introduced. 9557 */ 9558 9559var delimTypeToFont = function delimTypeToFont(type) { 9560 if (type.type === "small") { 9561 return "Main-Regular"; 9562 } else if (type.type === "large") { 9563 return "Size" + type.size + "-Regular"; 9564 } else if (type.type === "stack") { 9565 return "Size4-Regular"; 9566 } else { 9567 throw new Error("Add support for delim type '" + type.type + "' here."); 9568 } 9569}; 9570/** 9571 * Traverse a sequence of types of delimiters to decide what kind of delimiter 9572 * should be used to create a delimiter of the given height+depth. 9573 */ 9574 9575 9576var traverseSequence = function traverseSequence(delim, height, sequence, options) { 9577 // Here, we choose the index we should start at in the sequences. In smaller 9578 // sizes (which correspond to larger numbers in style.size) we start earlier 9579 // in the sequence. Thus, scriptscript starts at index 3-3=0, script starts 9580 // at index 3-2=1, text starts at 3-1=2, and display starts at min(2,3-0)=2 9581 var start = Math.min(2, 3 - options.style.size); 9582 9583 for (var i = start; i < sequence.length; i++) { 9584 if (sequence[i].type === "stack") { 9585 // This is always the last delimiter, so we just break the loop now. 9586 break; 9587 } 9588 9589 var metrics = getMetrics(delim, delimTypeToFont(sequence[i]), "math"); 9590 var heightDepth = metrics.height + metrics.depth; // Small delimiters are scaled down versions of the same font, so we 9591 // account for the style change size. 9592 9593 if (sequence[i].type === "small") { 9594 var newOptions = options.havingBaseStyle(sequence[i].style); 9595 heightDepth *= newOptions.sizeMultiplier; 9596 } // Check if the delimiter at this size works for the given height. 9597 9598 9599 if (heightDepth > height) { 9600 return sequence[i]; 9601 } 9602 } // If we reached the end of the sequence, return the last sequence element. 9603 9604 9605 return sequence[sequence.length - 1]; 9606}; 9607/** 9608 * Make a delimiter of a given height+depth, with optional centering. Here, we 9609 * traverse the sequences, and create a delimiter that the sequence tells us to. 9610 */ 9611 9612 9613var makeCustomSizedDelim = function makeCustomSizedDelim(delim, height, center, options, mode, classes) { 9614 if (delim === "<" || delim === "\\lt" || delim === "\u27e8") { 9615 delim = "\\langle"; 9616 } else if (delim === ">" || delim === "\\gt" || delim === "\u27e9") { 9617 delim = "\\rangle"; 9618 } // Decide what sequence to use 9619 9620 9621 var sequence; 9622 9623 if (utils.contains(stackNeverDelimiters, delim)) { 9624 sequence = stackNeverDelimiterSequence; 9625 } else if (utils.contains(stackLargeDelimiters, delim)) { 9626 sequence = stackLargeDelimiterSequence; 9627 } else { 9628 sequence = stackAlwaysDelimiterSequence; 9629 } // Look through the sequence 9630 9631 9632 var delimType = traverseSequence(delim, height, sequence, options); // Get the delimiter from font glyphs. 9633 // Depending on the sequence element we decided on, call the 9634 // appropriate function. 9635 9636 if (delimType.type === "small") { 9637 return makeSmallDelim(delim, delimType.style, center, options, mode, classes); 9638 } else if (delimType.type === "large") { 9639 return makeLargeDelim(delim, delimType.size, center, options, mode, classes); 9640 } else 9641 /* if (delimType.type === "stack") */ 9642 { 9643 return makeStackedDelim(delim, height, center, options, mode, classes); 9644 } 9645}; 9646/** 9647 * Make a delimiter for use with `\left` and `\right`, given a height and depth 9648 * of an expression that the delimiters surround. 9649 */ 9650 9651 9652var makeLeftRightDelim = function makeLeftRightDelim(delim, height, depth, options, mode, classes) { 9653 // We always center \left/\right delimiters, so the axis is always shifted 9654 var axisHeight = options.fontMetrics().axisHeight * options.sizeMultiplier; // Taken from TeX source, tex.web, function make_left_right 9655 9656 var delimiterFactor = 901; 9657 var delimiterExtend = 5.0 / options.fontMetrics().ptPerEm; 9658 var maxDistFromAxis = Math.max(height - axisHeight, depth + axisHeight); 9659 var totalHeight = Math.max( // In real TeX, calculations are done using integral values which are 9660 // 65536 per pt, or 655360 per em. So, the division here truncates in 9661 // TeX but doesn't here, producing different results. If we wanted to 9662 // exactly match TeX's calculation, we could do 9663 // Math.floor(655360 * maxDistFromAxis / 500) * 9664 // delimiterFactor / 655360 9665 // (To see the difference, compare 9666 // x^{x^{\left(\rule{0.1em}{0.68em}\right)}} 9667 // in TeX and KaTeX) 9668 maxDistFromAxis / 500 * delimiterFactor, 2 * maxDistFromAxis - delimiterExtend); // Finally, we defer to `makeCustomSizedDelim` with our calculated total 9669 // height 9670 9671 return makeCustomSizedDelim(delim, totalHeight, true, options, mode, classes); 9672}; 9673 9674var delimiter = { 9675 sqrtImage: makeSqrtImage, 9676 sizedDelim: makeSizedDelim, 9677 sizeToMaxHeight: sizeToMaxHeight, 9678 customSizedDelim: makeCustomSizedDelim, 9679 leftRightDelim: makeLeftRightDelim 9680}; 9681 9682// Extra data needed for the delimiter handler down below 9683var delimiterSizes = { 9684 "\\bigl": { 9685 mclass: "mopen", 9686 size: 1 9687 }, 9688 "\\Bigl": { 9689 mclass: "mopen", 9690 size: 2 9691 }, 9692 "\\biggl": { 9693 mclass: "mopen", 9694 size: 3 9695 }, 9696 "\\Biggl": { 9697 mclass: "mopen", 9698 size: 4 9699 }, 9700 "\\bigr": { 9701 mclass: "mclose", 9702 size: 1 9703 }, 9704 "\\Bigr": { 9705 mclass: "mclose", 9706 size: 2 9707 }, 9708 "\\biggr": { 9709 mclass: "mclose", 9710 size: 3 9711 }, 9712 "\\Biggr": { 9713 mclass: "mclose", 9714 size: 4 9715 }, 9716 "\\bigm": { 9717 mclass: "mrel", 9718 size: 1 9719 }, 9720 "\\Bigm": { 9721 mclass: "mrel", 9722 size: 2 9723 }, 9724 "\\biggm": { 9725 mclass: "mrel", 9726 size: 3 9727 }, 9728 "\\Biggm": { 9729 mclass: "mrel", 9730 size: 4 9731 }, 9732 "\\big": { 9733 mclass: "mord", 9734 size: 1 9735 }, 9736 "\\Big": { 9737 mclass: "mord", 9738 size: 2 9739 }, 9740 "\\bigg": { 9741 mclass: "mord", 9742 size: 3 9743 }, 9744 "\\Bigg": { 9745 mclass: "mord", 9746 size: 4 9747 } 9748}; 9749var delimiters = ["(", "\\lparen", ")", "\\rparen", "[", "\\lbrack", "]", "\\rbrack", "\\{", "\\lbrace", "\\}", "\\rbrace", "\\lfloor", "\\rfloor", "\u230a", "\u230b", "\\lceil", "\\rceil", "\u2308", "\u2309", "<", ">", "\\langle", "\u27e8", "\\rangle", "\u27e9", "\\lt", "\\gt", "\\lvert", "\\rvert", "\\lVert", "\\rVert", "\\lgroup", "\\rgroup", "\u27ee", "\u27ef", "\\lmoustache", "\\rmoustache", "\u23b0", "\u23b1", "/", "\\backslash", "|", "\\vert", "\\|", "\\Vert", "\\uparrow", "\\Uparrow", "\\downarrow", "\\Downarrow", "\\updownarrow", "\\Updownarrow", "."]; 9750 9751// Delimiter functions 9752function checkDelimiter(delim, context) { 9753 var symDelim = checkSymbolNodeType(delim); 9754 9755 if (symDelim && utils.contains(delimiters, symDelim.text)) { 9756 return symDelim; 9757 } else if (symDelim) { 9758 throw new ParseError("Invalid delimiter '" + symDelim.text + "' after '" + context.funcName + "'", delim); 9759 } else { 9760 throw new ParseError("Invalid delimiter type '" + delim.type + "'", delim); 9761 } 9762} 9763 9764defineFunction({ 9765 type: "delimsizing", 9766 names: ["\\bigl", "\\Bigl", "\\biggl", "\\Biggl", "\\bigr", "\\Bigr", "\\biggr", "\\Biggr", "\\bigm", "\\Bigm", "\\biggm", "\\Biggm", "\\big", "\\Big", "\\bigg", "\\Bigg"], 9767 props: { 9768 numArgs: 1, 9769 argTypes: ["primitive"] 9770 }, 9771 handler: (context, args) => { 9772 var delim = checkDelimiter(args[0], context); 9773 return { 9774 type: "delimsizing", 9775 mode: context.parser.mode, 9776 size: delimiterSizes[context.funcName].size, 9777 mclass: delimiterSizes[context.funcName].mclass, 9778 delim: delim.text 9779 }; 9780 }, 9781 htmlBuilder: (group, options) => { 9782 if (group.delim === ".") { 9783 // Empty delimiters still count as elements, even though they don't 9784 // show anything. 9785 return buildCommon.makeSpan([group.mclass]); 9786 } // Use delimiter.sizedDelim to generate the delimiter. 9787 9788 9789 return delimiter.sizedDelim(group.delim, group.size, options, group.mode, [group.mclass]); 9790 }, 9791 mathmlBuilder: group => { 9792 var children = []; 9793 9794 if (group.delim !== ".") { 9795 children.push(makeText(group.delim, group.mode)); 9796 } 9797 9798 var node = new mathMLTree.MathNode("mo", children); 9799 9800 if (group.mclass === "mopen" || group.mclass === "mclose") { 9801 // Only some of the delimsizing functions act as fences, and they 9802 // return "mopen" or "mclose" mclass. 9803 node.setAttribute("fence", "true"); 9804 } else { 9805 // Explicitly disable fencing if it's not a fence, to override the 9806 // defaults. 9807 node.setAttribute("fence", "false"); 9808 } 9809 9810 node.setAttribute("stretchy", "true"); 9811 var size = makeEm(delimiter.sizeToMaxHeight[group.size]); 9812 node.setAttribute("minsize", size); 9813 node.setAttribute("maxsize", size); 9814 return node; 9815 } 9816}); 9817 9818function assertParsed(group) { 9819 if (!group.body) { 9820 throw new Error("Bug: The leftright ParseNode wasn't fully parsed."); 9821 } 9822} 9823 9824defineFunction({ 9825 type: "leftright-right", 9826 names: ["\\right"], 9827 props: { 9828 numArgs: 1, 9829 primitive: true 9830 }, 9831 handler: (context, args) => { 9832 // \left case below triggers parsing of \right in 9833 // `const right = parser.parseFunction();` 9834 // uses this return value. 9835 var color = context.parser.gullet.macros.get("\\current@color"); 9836 9837 if (color && typeof color !== "string") { 9838 throw new ParseError("\\current@color set to non-string in \\right"); 9839 } 9840 9841 return { 9842 type: "leftright-right", 9843 mode: context.parser.mode, 9844 delim: checkDelimiter(args[0], context).text, 9845 color // undefined if not set via \color 9846 9847 }; 9848 } 9849}); 9850defineFunction({ 9851 type: "leftright", 9852 names: ["\\left"], 9853 props: { 9854 numArgs: 1, 9855 primitive: true 9856 }, 9857 handler: (context, args) => { 9858 var delim = checkDelimiter(args[0], context); 9859 var parser = context.parser; // Parse out the implicit body 9860 9861 ++parser.leftrightDepth; // parseExpression stops before '\\right' 9862 9863 var body = parser.parseExpression(false); 9864 --parser.leftrightDepth; // Check the next token 9865 9866 parser.expect("\\right", false); 9867 var right = assertNodeType(parser.parseFunction(), "leftright-right"); 9868 return { 9869 type: "leftright", 9870 mode: parser.mode, 9871 body, 9872 left: delim.text, 9873 right: right.delim, 9874 rightColor: right.color 9875 }; 9876 }, 9877 htmlBuilder: (group, options) => { 9878 assertParsed(group); // Build the inner expression 9879 9880 var inner = buildExpression$1(group.body, options, true, ["mopen", "mclose"]); 9881 var innerHeight = 0; 9882 var innerDepth = 0; 9883 var hadMiddle = false; // Calculate its height and depth 9884 9885 for (var i = 0; i < inner.length; i++) { 9886 // Property `isMiddle` not defined on `span`. See comment in 9887 // "middle"'s htmlBuilder. 9888 // $FlowFixMe 9889 if (inner[i].isMiddle) { 9890 hadMiddle = true; 9891 } else { 9892 innerHeight = Math.max(inner[i].height, innerHeight); 9893 innerDepth = Math.max(inner[i].depth, innerDepth); 9894 } 9895 } // The size of delimiters is the same, regardless of what style we are 9896 // in. Thus, to correctly calculate the size of delimiter we need around 9897 // a group, we scale down the inner size based on the size. 9898 9899 9900 innerHeight *= options.sizeMultiplier; 9901 innerDepth *= options.sizeMultiplier; 9902 var leftDelim; 9903 9904 if (group.left === ".") { 9905 // Empty delimiters in \left and \right make null delimiter spaces. 9906 leftDelim = makeNullDelimiter(options, ["mopen"]); 9907 } else { 9908 // Otherwise, use leftRightDelim to generate the correct sized 9909 // delimiter. 9910 leftDelim = delimiter.leftRightDelim(group.left, innerHeight, innerDepth, options, group.mode, ["mopen"]); 9911 } // Add it to the beginning of the expression 9912 9913 9914 inner.unshift(leftDelim); // Handle middle delimiters 9915 9916 if (hadMiddle) { 9917 for (var _i = 1; _i < inner.length; _i++) { 9918 var middleDelim = inner[_i]; // Property `isMiddle` not defined on `span`. See comment in 9919 // "middle"'s htmlBuilder. 9920 // $FlowFixMe 9921 9922 var isMiddle = middleDelim.isMiddle; 9923 9924 if (isMiddle) { 9925 // Apply the options that were active when \middle was called 9926 inner[_i] = delimiter.leftRightDelim(isMiddle.delim, innerHeight, innerDepth, isMiddle.options, group.mode, []); 9927 } 9928 } 9929 } 9930 9931 var rightDelim; // Same for the right delimiter, but using color specified by \color 9932 9933 if (group.right === ".") { 9934 rightDelim = makeNullDelimiter(options, ["mclose"]); 9935 } else { 9936 var colorOptions = group.rightColor ? options.withColor(group.rightColor) : options; 9937 rightDelim = delimiter.leftRightDelim(group.right, innerHeight, innerDepth, colorOptions, group.mode, ["mclose"]); 9938 } // Add it to the end of the expression. 9939 9940 9941 inner.push(rightDelim); 9942 return buildCommon.makeSpan(["minner"], inner, options); 9943 }, 9944 mathmlBuilder: (group, options) => { 9945 assertParsed(group); 9946 var inner = buildExpression(group.body, options); 9947 9948 if (group.left !== ".") { 9949 var leftNode = new mathMLTree.MathNode("mo", [makeText(group.left, group.mode)]); 9950 leftNode.setAttribute("fence", "true"); 9951 inner.unshift(leftNode); 9952 } 9953 9954 if (group.right !== ".") { 9955 var rightNode = new mathMLTree.MathNode("mo", [makeText(group.right, group.mode)]); 9956 rightNode.setAttribute("fence", "true"); 9957 9958 if (group.rightColor) { 9959 rightNode.setAttribute("mathcolor", group.rightColor); 9960 } 9961 9962 inner.push(rightNode); 9963 } 9964 9965 return makeRow(inner); 9966 } 9967}); 9968defineFunction({ 9969 type: "middle", 9970 names: ["\\middle"], 9971 props: { 9972 numArgs: 1, 9973 primitive: true 9974 }, 9975 handler: (context, args) => { 9976 var delim = checkDelimiter(args[0], context); 9977 9978 if (!context.parser.leftrightDepth) { 9979 throw new ParseError("\\middle without preceding \\left", delim); 9980 } 9981 9982 return { 9983 type: "middle", 9984 mode: context.parser.mode, 9985 delim: delim.text 9986 }; 9987 }, 9988 htmlBuilder: (group, options) => { 9989 var middleDelim; 9990 9991 if (group.delim === ".") { 9992 middleDelim = makeNullDelimiter(options, []); 9993 } else { 9994 middleDelim = delimiter.sizedDelim(group.delim, 1, options, group.mode, []); 9995 var isMiddle = { 9996 delim: group.delim, 9997 options 9998 }; // Property `isMiddle` not defined on `span`. It is only used in 9999 // this file above. 10000 // TODO: Fix this violation of the `span` type and possibly rename 10001 // things since `isMiddle` sounds like a boolean, but is a struct. 10002 // $FlowFixMe 10003 10004 middleDelim.isMiddle = isMiddle; 10005 } 10006 10007 return middleDelim; 10008 }, 10009 mathmlBuilder: (group, options) => { 10010 // A Firefox \middle will stretch a character vertically only if it 10011 // is in the fence part of the operator dictionary at: 10012 // https://www.w3.org/TR/MathML3/appendixc.html. 10013 // So we need to avoid U+2223 and use plain "|" instead. 10014 var textNode = group.delim === "\\vert" || group.delim === "|" ? makeText("|", "text") : makeText(group.delim, group.mode); 10015 var middleNode = new mathMLTree.MathNode("mo", [textNode]); 10016 middleNode.setAttribute("fence", "true"); // MathML gives 5/18em spacing to each <mo> element. 10017 // \middle should get delimiter spacing instead. 10018 10019 middleNode.setAttribute("lspace", "0.05em"); 10020 middleNode.setAttribute("rspace", "0.05em"); 10021 return middleNode; 10022 } 10023}); 10024 10025var htmlBuilder$7 = (group, options) => { 10026 // \cancel, \bcancel, \xcancel, \sout, \fbox, \colorbox, \fcolorbox, \phase 10027 // Some groups can return document fragments. Handle those by wrapping 10028 // them in a span. 10029 var inner = buildCommon.wrapFragment(buildGroup$1(group.body, options), options); 10030 var label = group.label.slice(1); 10031 var scale = options.sizeMultiplier; 10032 var img; 10033 var imgShift = 0; // In the LaTeX cancel package, line geometry is slightly different 10034 // depending on whether the subject is wider than it is tall, or vice versa. 10035 // We don't know the width of a group, so as a proxy, we test if 10036 // the subject is a single character. This captures most of the 10037 // subjects that should get the "tall" treatment. 10038 10039 var isSingleChar = utils.isCharacterBox(group.body); 10040 10041 if (label === "sout") { 10042 img = buildCommon.makeSpan(["stretchy", "sout"]); 10043 img.height = options.fontMetrics().defaultRuleThickness / scale; 10044 imgShift = -0.5 * options.fontMetrics().xHeight; 10045 } else if (label === "phase") { 10046 // Set a couple of dimensions from the steinmetz package. 10047 var lineWeight = calculateSize({ 10048 number: 0.6, 10049 unit: "pt" 10050 }, options); 10051 var clearance = calculateSize({ 10052 number: 0.35, 10053 unit: "ex" 10054 }, options); // Prevent size changes like \Huge from affecting line thickness 10055 10056 var newOptions = options.havingBaseSizing(); 10057 scale = scale / newOptions.sizeMultiplier; 10058 var angleHeight = inner.height + inner.depth + lineWeight + clearance; // Reserve a left pad for the angle. 10059 10060 inner.style.paddingLeft = makeEm(angleHeight / 2 + lineWeight); // Create an SVG 10061 10062 var viewBoxHeight = Math.floor(1000 * angleHeight * scale); 10063 var path = phasePath(viewBoxHeight); 10064 var svgNode = new SvgNode([new PathNode("phase", path)], { 10065 "width": "400em", 10066 "height": makeEm(viewBoxHeight / 1000), 10067 "viewBox": "0 0 400000 " + viewBoxHeight, 10068 "preserveAspectRatio": "xMinYMin slice" 10069 }); // Wrap it in a span with overflow: hidden. 10070 10071 img = buildCommon.makeSvgSpan(["hide-tail"], [svgNode], options); 10072 img.style.height = makeEm(angleHeight); 10073 imgShift = inner.depth + lineWeight + clearance; 10074 } else { 10075 // Add horizontal padding 10076 if (/cancel/.test(label)) { 10077 if (!isSingleChar) { 10078 inner.classes.push("cancel-pad"); 10079 } 10080 } else if (label === "angl") { 10081 inner.classes.push("anglpad"); 10082 } else { 10083 inner.classes.push("boxpad"); 10084 } // Add vertical padding 10085 10086 10087 var topPad = 0; 10088 var bottomPad = 0; 10089 var ruleThickness = 0; // ref: cancel package: \advance\totalheight2\p@ % "+2" 10090 10091 if (/box/.test(label)) { 10092 ruleThickness = Math.max(options.fontMetrics().fboxrule, // default 10093 options.minRuleThickness // User override. 10094 ); 10095 topPad = options.fontMetrics().fboxsep + (label === "colorbox" ? 0 : ruleThickness); 10096 bottomPad = topPad; 10097 } else if (label === "angl") { 10098 ruleThickness = Math.max(options.fontMetrics().defaultRuleThickness, options.minRuleThickness); 10099 topPad = 4 * ruleThickness; // gap = 3 à line, plus the line itself. 10100 10101 bottomPad = Math.max(0, 0.25 - inner.depth); 10102 } else { 10103 topPad = isSingleChar ? 0.2 : 0; 10104 bottomPad = topPad; 10105 } 10106 10107 img = stretchy.encloseSpan(inner, label, topPad, bottomPad, options); 10108 10109 if (/fbox|boxed|fcolorbox/.test(label)) { 10110 img.style.borderStyle = "solid"; 10111 img.style.borderWidth = makeEm(ruleThickness); 10112 } else if (label === "angl" && ruleThickness !== 0.049) { 10113 img.style.borderTopWidth = makeEm(ruleThickness); 10114 img.style.borderRightWidth = makeEm(ruleThickness); 10115 } 10116 10117 imgShift = inner.depth + bottomPad; 10118 10119 if (group.backgroundColor) { 10120 img.style.backgroundColor = group.backgroundColor; 10121 10122 if (group.borderColor) { 10123 img.style.borderColor = group.borderColor; 10124 } 10125 } 10126 } 10127 10128 var vlist; 10129 10130 if (group.backgroundColor) { 10131 vlist = buildCommon.makeVList({ 10132 positionType: "individualShift", 10133 children: [// Put the color background behind inner; 10134 { 10135 type: "elem", 10136 elem: img, 10137 shift: imgShift 10138 }, { 10139 type: "elem", 10140 elem: inner, 10141 shift: 0 10142 }] 10143 }, options); 10144 } else { 10145 var classes = /cancel|phase/.test(label) ? ["svg-align"] : []; 10146 vlist = buildCommon.makeVList({ 10147 positionType: "individualShift", 10148 children: [// Write the \cancel stroke on top of inner. 10149 { 10150 type: "elem", 10151 elem: inner, 10152 shift: 0 10153 }, { 10154 type: "elem", 10155 elem: img, 10156 shift: imgShift, 10157 wrapperClasses: classes 10158 }] 10159 }, options); 10160 } 10161 10162 if (/cancel/.test(label)) { 10163 // The cancel package documentation says that cancel lines add their height 10164 // to the expression, but tests show that isn't how it actually works. 10165 vlist.height = inner.height; 10166 vlist.depth = inner.depth; 10167 } 10168 10169 if (/cancel/.test(label) && !isSingleChar) { 10170 // cancel does not create horiz space for its line extension. 10171 return buildCommon.makeSpan(["mord", "cancel-lap"], [vlist], options); 10172 } else { 10173 return buildCommon.makeSpan(["mord"], [vlist], options); 10174 } 10175}; 10176 10177var mathmlBuilder$6 = (group, options) => { 10178 var fboxsep = 0; 10179 var node = new mathMLTree.MathNode(group.label.indexOf("colorbox") > -1 ? "mpadded" : "menclose", [buildGroup(group.body, options)]); 10180 10181 switch (group.label) { 10182 case "\\cancel": 10183 node.setAttribute("notation", "updiagonalstrike"); 10184 break; 10185 10186 case "\\bcancel": 10187 node.setAttribute("notation", "downdiagonalstrike"); 10188 break; 10189 10190 case "\\phase": 10191 node.setAttribute("notation", "phasorangle"); 10192 break; 10193 10194 case "\\sout": 10195 node.setAttribute("notation", "horizontalstrike"); 10196 break; 10197 10198 case "\\fbox": 10199 node.setAttribute("notation", "box"); 10200 break; 10201 10202 case "\\angl": 10203 node.setAttribute("notation", "actuarial"); 10204 break; 10205 10206 case "\\fcolorbox": 10207 case "\\colorbox": 10208 // <menclose> doesn't have a good notation option. So use <mpadded> 10209 // instead. Set some attributes that come included with <menclose>. 10210 fboxsep = options.fontMetrics().fboxsep * options.fontMetrics().ptPerEm; 10211 node.setAttribute("width", "+" + 2 * fboxsep + "pt"); 10212 node.setAttribute("height", "+" + 2 * fboxsep + "pt"); 10213 node.setAttribute("lspace", fboxsep + "pt"); // 10214 10215 node.setAttribute("voffset", fboxsep + "pt"); 10216 10217 if (group.label === "\\fcolorbox") { 10218 var thk = Math.max(options.fontMetrics().fboxrule, // default 10219 options.minRuleThickness // user override 10220 ); 10221 node.setAttribute("style", "border: " + thk + "em solid " + String(group.borderColor)); 10222 } 10223 10224 break; 10225 10226 case "\\xcancel": 10227 node.setAttribute("notation", "updiagonalstrike downdiagonalstrike"); 10228 break; 10229 } 10230 10231 if (group.backgroundColor) { 10232 node.setAttribute("mathbackground", group.backgroundColor); 10233 } 10234 10235 return node; 10236}; 10237 10238defineFunction({ 10239 type: "enclose", 10240 names: ["\\colorbox"], 10241 props: { 10242 numArgs: 2, 10243 allowedInText: true, 10244 argTypes: ["color", "text"] 10245 }, 10246 10247 handler(_ref, args, optArgs) { 10248 var { 10249 parser, 10250 funcName 10251 } = _ref; 10252 var color = assertNodeType(args[0], "color-token").color; 10253 var body = args[1]; 10254 return { 10255 type: "enclose", 10256 mode: parser.mode, 10257 label: funcName, 10258 backgroundColor: color, 10259 body 10260 }; 10261 }, 10262 10263 htmlBuilder: htmlBuilder$7, 10264 mathmlBuilder: mathmlBuilder$6 10265}); 10266defineFunction({ 10267 type: "enclose", 10268 names: ["\\fcolorbox"], 10269 props: { 10270 numArgs: 3, 10271 allowedInText: true, 10272 argTypes: ["color", "color", "text"] 10273 }, 10274 10275 handler(_ref2, args, optArgs) { 10276 var { 10277 parser, 10278 funcName 10279 } = _ref2; 10280 var borderColor = assertNodeType(args[0], "color-token").color; 10281 var backgroundColor = assertNodeType(args[1], "color-token").color; 10282 var body = args[2]; 10283 return { 10284 type: "enclose", 10285 mode: parser.mode, 10286 label: funcName, 10287 backgroundColor, 10288 borderColor, 10289 body 10290 }; 10291 }, 10292 10293 htmlBuilder: htmlBuilder$7, 10294 mathmlBuilder: mathmlBuilder$6 10295}); 10296defineFunction({ 10297 type: "enclose", 10298 names: ["\\fbox"], 10299 props: { 10300 numArgs: 1, 10301 argTypes: ["hbox"], 10302 allowedInText: true 10303 }, 10304 10305 handler(_ref3, args) { 10306 var { 10307 parser 10308 } = _ref3; 10309 return { 10310 type: "enclose", 10311 mode: parser.mode, 10312 label: "\\fbox", 10313 body: args[0] 10314 }; 10315 } 10316 10317}); 10318defineFunction({ 10319 type: "enclose", 10320 names: ["\\cancel", "\\bcancel", "\\xcancel", "\\sout", "\\phase"], 10321 props: { 10322 numArgs: 1 10323 }, 10324 10325 handler(_ref4, args) { 10326 var { 10327 parser, 10328 funcName 10329 } = _ref4; 10330 var body = args[0]; 10331 return { 10332 type: "enclose", 10333 mode: parser.mode, 10334 label: funcName, 10335 body 10336 }; 10337 }, 10338 10339 htmlBuilder: htmlBuilder$7, 10340 mathmlBuilder: mathmlBuilder$6 10341}); 10342defineFunction({ 10343 type: "enclose", 10344 names: ["\\angl"], 10345 props: { 10346 numArgs: 1, 10347 argTypes: ["hbox"], 10348 allowedInText: false 10349 }, 10350 10351 handler(_ref5, args) { 10352 var { 10353 parser 10354 } = _ref5; 10355 return { 10356 type: "enclose", 10357 mode: parser.mode, 10358 label: "\\angl", 10359 body: args[0] 10360 }; 10361 } 10362 10363}); 10364 10365/** 10366 * All registered environments. 10367 * `environments.js` exports this same dictionary again and makes it public. 10368 * `Parser.js` requires this dictionary via `environments.js`. 10369 */ 10370var _environments = {}; 10371function defineEnvironment(_ref) { 10372 var { 10373 type, 10374 names, 10375 props, 10376 handler, 10377 htmlBuilder, 10378 mathmlBuilder 10379 } = _ref; 10380 // Set default values of environments. 10381 var data = { 10382 type, 10383 numArgs: props.numArgs || 0, 10384 allowedInText: false, 10385 numOptionalArgs: 0, 10386 handler 10387 }; 10388 10389 for (var i = 0; i < names.length; ++i) { 10390 // TODO: The value type of _environments should be a type union of all 10391 // possible `EnvSpec<>` possibilities instead of `EnvSpec<*>`, which is 10392 // an existential type. 10393 _environments[names[i]] = data; 10394 } 10395 10396 if (htmlBuilder) { 10397 _htmlGroupBuilders[type] = htmlBuilder; 10398 } 10399 10400 if (mathmlBuilder) { 10401 _mathmlGroupBuilders[type] = mathmlBuilder; 10402 } 10403} 10404 10405/** 10406 * All registered global/built-in macros. 10407 * `macros.js` exports this same dictionary again and makes it public. 10408 * `Parser.js` requires this dictionary via `macros.js`. 10409 */ 10410var _macros = {}; // This function might one day accept an additional argument and do more things. 10411 10412function defineMacro(name, body) { 10413 _macros[name] = body; 10414} 10415 10416// Helper functions 10417function getHLines(parser) { 10418 // Return an array. The array length = number of hlines. 10419 // Each element in the array tells if the line is dashed. 10420 var hlineInfo = []; 10421 parser.consumeSpaces(); 10422 var nxt = parser.fetch().text; 10423 10424 if (nxt === "\\relax") { 10425 // \relax is an artifact of the \cr macro below 10426 parser.consume(); 10427 parser.consumeSpaces(); 10428 nxt = parser.fetch().text; 10429 } 10430 10431 while (nxt === "\\hline" || nxt === "\\hdashline") { 10432 parser.consume(); 10433 hlineInfo.push(nxt === "\\hdashline"); 10434 parser.consumeSpaces(); 10435 nxt = parser.fetch().text; 10436 } 10437 10438 return hlineInfo; 10439} 10440 10441var validateAmsEnvironmentContext = context => { 10442 var settings = context.parser.settings; 10443 10444 if (!settings.displayMode) { 10445 throw new ParseError("{" + context.envName + "} can be used only in" + " display mode."); 10446 } 10447}; // autoTag (an argument to parseArray) can be one of three values: 10448// * undefined: Regular (not-top-level) array; no tags on each row 10449// * true: Automatic equation numbering, overridable by \tag 10450// * false: Tags allowed on each row, but no automatic numbering 10451// This function *doesn't* work with the "split" environment name. 10452 10453 10454function getAutoTag(name) { 10455 if (name.indexOf("ed") === -1) { 10456 return name.indexOf("*") === -1; 10457 } // return undefined; 10458 10459} 10460/** 10461 * Parse the body of the environment, with rows delimited by \\ and 10462 * columns delimited by &, and create a nested list in row-major order 10463 * with one group per cell. If given an optional argument style 10464 * ("text", "display", etc.), then each cell is cast into that style. 10465 */ 10466 10467 10468function parseArray(parser, _ref, style) { 10469 var { 10470 hskipBeforeAndAfter, 10471 addJot, 10472 cols, 10473 arraystretch, 10474 colSeparationType, 10475 autoTag, 10476 singleRow, 10477 emptySingleRow, 10478 maxNumCols, 10479 leqno 10480 } = _ref; 10481 parser.gullet.beginGroup(); 10482 10483 if (!singleRow) { 10484 // \cr is equivalent to \\ without the optional size argument (see below) 10485 // TODO: provide helpful error when \cr is used outside array environment 10486 parser.gullet.macros.set("\\cr", "\\\\\\relax"); 10487 } // Get current arraystretch if it's not set by the environment 10488 10489 10490 if (!arraystretch) { 10491 var stretch = parser.gullet.expandMacroAsText("\\arraystretch"); 10492 10493 if (stretch == null) { 10494 // Default \arraystretch from lttab.dtx 10495 arraystretch = 1; 10496 } else { 10497 arraystretch = parseFloat(stretch); 10498 10499 if (!arraystretch || arraystretch < 0) { 10500 throw new ParseError("Invalid \\arraystretch: " + stretch); 10501 } 10502 } 10503 } // Start group for first cell 10504 10505 10506 parser.gullet.beginGroup(); 10507 var row = []; 10508 var body = [row]; 10509 var rowGaps = []; 10510 var hLinesBeforeRow = []; 10511 var tags = autoTag != null ? [] : undefined; // amsmath uses \global\@eqnswtrue and \global\@eqnswfalse to represent 10512 // whether this row should have an equation number. Simulate this with 10513 // a \@eqnsw macro set to 1 or 0. 10514 10515 function beginRow() { 10516 if (autoTag) { 10517 parser.gullet.macros.set("\\@eqnsw", "1", true); 10518 } 10519 } 10520 10521 function endRow() { 10522 if (tags) { 10523 if (parser.gullet.macros.get("\\df@tag")) { 10524 tags.push(parser.subparse([new Token("\\df@tag")])); 10525 parser.gullet.macros.set("\\df@tag", undefined, true); 10526 } else { 10527 tags.push(Boolean(autoTag) && parser.gullet.macros.get("\\@eqnsw") === "1"); 10528 } 10529 } 10530 } 10531 10532 beginRow(); // Test for \hline at the top of the array. 10533 10534 hLinesBeforeRow.push(getHLines(parser)); 10535 10536 while (true) { 10537 // eslint-disable-line no-constant-condition 10538 // Parse each cell in its own group (namespace) 10539 var cell = parser.parseExpression(false, singleRow ? "\\end" : "\\\\"); 10540 parser.gullet.endGroup(); 10541 parser.gullet.beginGroup(); 10542 cell = { 10543 type: "ordgroup", 10544 mode: parser.mode, 10545 body: cell 10546 }; 10547 10548 if (style) { 10549 cell = { 10550 type: "styling", 10551 mode: parser.mode, 10552 style, 10553 body: [cell] 10554 }; 10555 } 10556 10557 row.push(cell); 10558 var next = parser.fetch().text; 10559 10560 if (next === "&") { 10561 if (maxNumCols && row.length === maxNumCols) { 10562 if (singleRow || colSeparationType) { 10563 // {equation} or {split} 10564 throw new ParseError("Too many tab characters: &", parser.nextToken); 10565 } else { 10566 // {array} environment 10567 parser.settings.reportNonstrict("textEnv", "Too few columns " + "specified in the {array} column argument."); 10568 } 10569 } 10570 10571 parser.consume(); 10572 } else if (next === "\\end") { 10573 endRow(); // Arrays terminate newlines with `\crcr` which consumes a `\cr` if 10574 // the last line is empty. However, AMS environments keep the 10575 // empty row if it's the only one. 10576 // NOTE: Currently, `cell` is the last item added into `row`. 10577 10578 if (row.length === 1 && cell.type === "styling" && cell.body[0].body.length === 0 && (body.length > 1 || !emptySingleRow)) { 10579 body.pop(); 10580 } 10581 10582 if (hLinesBeforeRow.length < body.length + 1) { 10583 hLinesBeforeRow.push([]); 10584 } 10585 10586 break; 10587 } else if (next === "\\\\") { 10588 parser.consume(); 10589 var size = void 0; // \def\Let@{\let\\\math@cr} 10590 // \def\math@cr{...\math@cr@} 10591 // \def\math@cr@{\new@ifnextchar[\math@cr@@{\math@cr@@[\z@]}} 10592 // \def\math@cr@@[#1]{...\math@cr@@@...} 10593 // \def\math@cr@@@{\cr} 10594 10595 if (parser.gullet.future().text !== " ") { 10596 size = parser.parseSizeGroup(true); 10597 } 10598 10599 rowGaps.push(size ? size.value : null); 10600 endRow(); // check for \hline(s) following the row separator 10601 10602 hLinesBeforeRow.push(getHLines(parser)); 10603 row = []; 10604 body.push(row); 10605 beginRow(); 10606 } else { 10607 throw new ParseError("Expected & or \\\\ or \\cr or \\end", parser.nextToken); 10608 } 10609 } // End cell group 10610 10611 10612 parser.gullet.endGroup(); // End array group defining \cr 10613 10614 parser.gullet.endGroup(); 10615 return { 10616 type: "array", 10617 mode: parser.mode, 10618 addJot, 10619 arraystretch, 10620 body, 10621 cols, 10622 rowGaps, 10623 hskipBeforeAndAfter, 10624 hLinesBeforeRow, 10625 colSeparationType, 10626 tags, 10627 leqno 10628 }; 10629} // Decides on a style for cells in an array according to whether the given 10630// environment name starts with the letter 'd'. 10631 10632 10633function dCellStyle(envName) { 10634 if (envName.slice(0, 1) === "d") { 10635 return "display"; 10636 } else { 10637 return "text"; 10638 } 10639} 10640 10641var htmlBuilder$6 = function htmlBuilder(group, options) { 10642 var r; 10643 var c; 10644 var nr = group.body.length; 10645 var hLinesBeforeRow = group.hLinesBeforeRow; 10646 var nc = 0; 10647 var body = new Array(nr); 10648 var hlines = []; 10649 var ruleThickness = Math.max( // From LaTeX \showthe\arrayrulewidth. Equals 0.04 em. 10650 options.fontMetrics().arrayRuleWidth, options.minRuleThickness // User override. 10651 ); // Horizontal spacing 10652 10653 var pt = 1 / options.fontMetrics().ptPerEm; 10654 var arraycolsep = 5 * pt; // default value, i.e. \arraycolsep in article.cls 10655 10656 if (group.colSeparationType && group.colSeparationType === "small") { 10657 // We're in a {smallmatrix}. Default column space is \thickspace, 10658 // i.e. 5/18em = 0.2778em, per amsmath.dtx for {smallmatrix}. 10659 // But that needs adjustment because LaTeX applies \scriptstyle to the 10660 // entire array, including the colspace, but this function applies 10661 // \scriptstyle only inside each element. 10662 var localMultiplier = options.havingStyle(Style$1.SCRIPT).sizeMultiplier; 10663 arraycolsep = 0.2778 * (localMultiplier / options.sizeMultiplier); 10664 } // Vertical spacing 10665 10666 10667 var baselineskip = group.colSeparationType === "CD" ? calculateSize({ 10668 number: 3, 10669 unit: "ex" 10670 }, options) : 12 * pt; // see size10.clo 10671 // Default \jot from ltmath.dtx 10672 // TODO(edemaine): allow overriding \jot via \setlength (#687) 10673 10674 var jot = 3 * pt; 10675 var arrayskip = group.arraystretch * baselineskip; 10676 var arstrutHeight = 0.7 * arrayskip; // \strutbox in ltfsstrc.dtx and 10677 10678 var arstrutDepth = 0.3 * arrayskip; // \@arstrutbox in lttab.dtx 10679 10680 var totalHeight = 0; // Set a position for \hline(s) at the top of the array, if any. 10681 10682 function setHLinePos(hlinesInGap) { 10683 for (var i = 0; i < hlinesInGap.length; ++i) { 10684 if (i > 0) { 10685 totalHeight += 0.25; 10686 } 10687 10688 hlines.push({ 10689 pos: totalHeight, 10690 isDashed: hlinesInGap[i] 10691 }); 10692 } 10693 } 10694 10695 setHLinePos(hLinesBeforeRow[0]); 10696 10697 for (r = 0; r < group.body.length; ++r) { 10698 var inrow = group.body[r]; 10699 var height = arstrutHeight; // \@array adds an \@arstrut 10700 10701 var depth = arstrutDepth; // to each tow (via the template) 10702 10703 if (nc < inrow.length) { 10704 nc = inrow.length; 10705 } 10706 10707 var outrow = new Array(inrow.length); 10708 10709 for (c = 0; c < inrow.length; ++c) { 10710 var elt = buildGroup$1(inrow[c], options); 10711 10712 if (depth < elt.depth) { 10713 depth = elt.depth; 10714 } 10715 10716 if (height < elt.height) { 10717 height = elt.height; 10718 } 10719 10720 outrow[c] = elt; 10721 } 10722 10723 var rowGap = group.rowGaps[r]; 10724 var gap = 0; 10725 10726 if (rowGap) { 10727 gap = calculateSize(rowGap, options); 10728 10729 if (gap > 0) { 10730 // \@argarraycr 10731 gap += arstrutDepth; 10732 10733 if (depth < gap) { 10734 depth = gap; // \@xargarraycr 10735 } 10736 10737 gap = 0; 10738 } 10739 } // In AMS multiline environments such as aligned and gathered, rows 10740 // correspond to lines that have additional \jot added to the 10741 // \baselineskip via \openup. 10742 10743 10744 if (group.addJot) { 10745 depth += jot; 10746 } 10747 10748 outrow.height = height; 10749 outrow.depth = depth; 10750 totalHeight += height; 10751 outrow.pos = totalHeight; 10752 totalHeight += depth + gap; // \@yargarraycr 10753 10754 body[r] = outrow; // Set a position for \hline(s), if any. 10755 10756 setHLinePos(hLinesBeforeRow[r + 1]); 10757 } 10758 10759 var offset = totalHeight / 2 + options.fontMetrics().axisHeight; 10760 var colDescriptions = group.cols || []; 10761 var cols = []; 10762 var colSep; 10763 var colDescrNum; 10764 var tagSpans = []; 10765 10766 if (group.tags && group.tags.some(tag => tag)) { 10767 // An environment with manual tags and/or automatic equation numbers. 10768 // Create node(s), the latter of which trigger CSS counter increment. 10769 for (r = 0; r < nr; ++r) { 10770 var rw = body[r]; 10771 var shift = rw.pos - offset; 10772 var tag = group.tags[r]; 10773 var tagSpan = void 0; 10774 10775 if (tag === true) { 10776 // automatic numbering 10777 tagSpan = buildCommon.makeSpan(["eqn-num"], [], options); 10778 } else if (tag === false) { 10779 // \nonumber/\notag or starred environment 10780 tagSpan = buildCommon.makeSpan([], [], options); 10781 } else { 10782 // manual \tag 10783 tagSpan = buildCommon.makeSpan([], buildExpression$1(tag, options, true), options); 10784 } 10785 10786 tagSpan.depth = rw.depth; 10787 tagSpan.height = rw.height; 10788 tagSpans.push({ 10789 type: "elem", 10790 elem: tagSpan, 10791 shift 10792 }); 10793 } 10794 } 10795 10796 for (c = 0, colDescrNum = 0; // Continue while either there are more columns or more column 10797 // descriptions, so trailing separators don't get lost. 10798 c < nc || colDescrNum < colDescriptions.length; ++c, ++colDescrNum) { 10799 var colDescr = colDescriptions[colDescrNum] || {}; 10800 var firstSeparator = true; 10801 10802 while (colDescr.type === "separator") { 10803 // If there is more than one separator in a row, add a space 10804 // between them. 10805 if (!firstSeparator) { 10806 colSep = buildCommon.makeSpan(["arraycolsep"], []); 10807 colSep.style.width = makeEm(options.fontMetrics().doubleRuleSep); 10808 cols.push(colSep); 10809 } 10810 10811 if (colDescr.separator === "|" || colDescr.separator === ":") { 10812 var lineType = colDescr.separator === "|" ? "solid" : "dashed"; 10813 var separator = buildCommon.makeSpan(["vertical-separator"], [], options); 10814 separator.style.height = makeEm(totalHeight); 10815 separator.style.borderRightWidth = makeEm(ruleThickness); 10816 separator.style.borderRightStyle = lineType; 10817 separator.style.margin = "0 " + makeEm(-ruleThickness / 2); 10818 10819 var _shift = totalHeight - offset; 10820 10821 if (_shift) { 10822 separator.style.verticalAlign = makeEm(-_shift); 10823 } 10824 10825 cols.push(separator); 10826 } else { 10827 throw new ParseError("Invalid separator type: " + colDescr.separator); 10828 } 10829 10830 colDescrNum++; 10831 colDescr = colDescriptions[colDescrNum] || {}; 10832 firstSeparator = false; 10833 } 10834 10835 if (c >= nc) { 10836 continue; 10837 } 10838 10839 var sepwidth = void 0; 10840 10841 if (c > 0 || group.hskipBeforeAndAfter) { 10842 sepwidth = utils.deflt(colDescr.pregap, arraycolsep); 10843 10844 if (sepwidth !== 0) { 10845 colSep = buildCommon.makeSpan(["arraycolsep"], []); 10846 colSep.style.width = makeEm(sepwidth); 10847 cols.push(colSep); 10848 } 10849 } 10850 10851 var col = []; 10852 10853 for (r = 0; r < nr; ++r) { 10854 var row = body[r]; 10855 var elem = row[c]; 10856 10857 if (!elem) { 10858 continue; 10859 } 10860 10861 var _shift2 = row.pos - offset; 10862 10863 elem.depth = row.depth; 10864 elem.height = row.height; 10865 col.push({ 10866 type: "elem", 10867 elem: elem, 10868 shift: _shift2 10869 }); 10870 } 10871 10872 col = buildCommon.makeVList({ 10873 positionType: "individualShift", 10874 children: col 10875 }, options); 10876 col = buildCommon.makeSpan(["col-align-" + (colDescr.align || "c")], [col]); 10877 cols.push(col); 10878 10879 if (c < nc - 1 || group.hskipBeforeAndAfter) { 10880 sepwidth = utils.deflt(colDescr.postgap, arraycolsep); 10881 10882 if (sepwidth !== 0) { 10883 colSep = buildCommon.makeSpan(["arraycolsep"], []); 10884 colSep.style.width = makeEm(sepwidth); 10885 cols.push(colSep); 10886 } 10887 } 10888 } 10889 10890 body = buildCommon.makeSpan(["mtable"], cols); // Add \hline(s), if any. 10891 10892 if (hlines.length > 0) { 10893 var line = buildCommon.makeLineSpan("hline", options, ruleThickness); 10894 var dashes = buildCommon.makeLineSpan("hdashline", options, ruleThickness); 10895 var vListElems = [{ 10896 type: "elem", 10897 elem: body, 10898 shift: 0 10899 }]; 10900 10901 while (hlines.length > 0) { 10902 var hline = hlines.pop(); 10903 var lineShift = hline.pos - offset; 10904 10905 if (hline.isDashed) { 10906 vListElems.push({ 10907 type: "elem", 10908 elem: dashes, 10909 shift: lineShift 10910 }); 10911 } else { 10912 vListElems.push({ 10913 type: "elem", 10914 elem: line, 10915 shift: lineShift 10916 }); 10917 } 10918 } 10919 10920 body = buildCommon.makeVList({ 10921 positionType: "individualShift", 10922 children: vListElems 10923 }, options); 10924 } 10925 10926 if (tagSpans.length === 0) { 10927 return buildCommon.makeSpan(["mord"], [body], options); 10928 } else { 10929 var eqnNumCol = buildCommon.makeVList({ 10930 positionType: "individualShift", 10931 children: tagSpans 10932 }, options); 10933 eqnNumCol = buildCommon.makeSpan(["tag"], [eqnNumCol], options); 10934 return buildCommon.makeFragment([body, eqnNumCol]); 10935 } 10936}; 10937 10938var alignMap = { 10939 c: "center ", 10940 l: "left ", 10941 r: "right " 10942}; 10943 10944var mathmlBuilder$5 = function mathmlBuilder(group, options) { 10945 var tbl = []; 10946 var glue = new mathMLTree.MathNode("mtd", [], ["mtr-glue"]); 10947 var tag = new mathMLTree.MathNode("mtd", [], ["mml-eqn-num"]); 10948 10949 for (var i = 0; i < group.body.length; i++) { 10950 var rw = group.body[i]; 10951 var row = []; 10952 10953 for (var j = 0; j < rw.length; j++) { 10954 row.push(new mathMLTree.MathNode("mtd", [buildGroup(rw[j], options)])); 10955 } 10956 10957 if (group.tags && group.tags[i]) { 10958 row.unshift(glue); 10959 row.push(glue); 10960 10961 if (group.leqno) { 10962 row.unshift(tag); 10963 } else { 10964 row.push(tag); 10965 } 10966 } 10967 10968 tbl.push(new mathMLTree.MathNode("mtr", row)); 10969 } 10970 10971 var table = new mathMLTree.MathNode("mtable", tbl); // Set column alignment, row spacing, column spacing, and 10972 // array lines by setting attributes on the table element. 10973 // Set the row spacing. In MathML, we specify a gap distance. 10974 // We do not use rowGap[] because MathML automatically increases 10975 // cell height with the height/depth of the element content. 10976 // LaTeX \arraystretch multiplies the row baseline-to-baseline distance. 10977 // We simulate this by adding (arraystretch - 1)em to the gap. This 10978 // does a reasonable job of adjusting arrays containing 1 em tall content. 10979 // The 0.16 and 0.09 values are found empirically. They produce an array 10980 // similar to LaTeX and in which content does not interfere with \hlines. 10981 10982 var gap = group.arraystretch === 0.5 ? 0.1 // {smallmatrix}, {subarray} 10983 : 0.16 + group.arraystretch - 1 + (group.addJot ? 0.09 : 0); 10984 table.setAttribute("rowspacing", makeEm(gap)); // MathML table lines go only between cells. 10985 // To place a line on an edge we'll use <menclose>, if necessary. 10986 10987 var menclose = ""; 10988 var align = ""; 10989 10990 if (group.cols && group.cols.length > 0) { 10991 // Find column alignment, column spacing, and vertical lines. 10992 var cols = group.cols; 10993 var columnLines = ""; 10994 var prevTypeWasAlign = false; 10995 var iStart = 0; 10996 var iEnd = cols.length; 10997 10998 if (cols[0].type === "separator") { 10999 menclose += "top "; 11000 iStart = 1; 11001 } 11002 11003 if (cols[cols.length - 1].type === "separator") { 11004 menclose += "bottom "; 11005 iEnd -= 1; 11006 } 11007 11008 for (var _i = iStart; _i < iEnd; _i++) { 11009 if (cols[_i].type === "align") { 11010 align += alignMap[cols[_i].align]; 11011 11012 if (prevTypeWasAlign) { 11013 columnLines += "none "; 11014 } 11015 11016 prevTypeWasAlign = true; 11017 } else if (cols[_i].type === "separator") { 11018 // MathML accepts only single lines between cells. 11019 // So we read only the first of consecutive separators. 11020 if (prevTypeWasAlign) { 11021 columnLines += cols[_i].separator === "|" ? "solid " : "dashed "; 11022 prevTypeWasAlign = false; 11023 } 11024 } 11025 } 11026 11027 table.setAttribute("columnalign", align.trim()); 11028 11029 if (/[sd]/.test(columnLines)) { 11030 table.setAttribute("columnlines", columnLines.trim()); 11031 } 11032 } // Set column spacing. 11033 11034 11035 if (group.colSeparationType === "align") { 11036 var _cols = group.cols || []; 11037 11038 var spacing = ""; 11039 11040 for (var _i2 = 1; _i2 < _cols.length; _i2++) { 11041 spacing += _i2 % 2 ? "0em " : "1em "; 11042 } 11043 11044 table.setAttribute("columnspacing", spacing.trim()); 11045 } else if (group.colSeparationType === "alignat" || group.colSeparationType === "gather") { 11046 table.setAttribute("columnspacing", "0em"); 11047 } else if (group.colSeparationType === "small") { 11048 table.setAttribute("columnspacing", "0.2778em"); 11049 } else if (group.colSeparationType === "CD") { 11050 table.setAttribute("columnspacing", "0.5em"); 11051 } else { 11052 table.setAttribute("columnspacing", "1em"); 11053 } // Address \hline and \hdashline 11054 11055 11056 var rowLines = ""; 11057 var hlines = group.hLinesBeforeRow; 11058 menclose += hlines[0].length > 0 ? "left " : ""; 11059 menclose += hlines[hlines.length - 1].length > 0 ? "right " : ""; 11060 11061 for (var _i3 = 1; _i3 < hlines.length - 1; _i3++) { 11062 rowLines += hlines[_i3].length === 0 ? "none " // MathML accepts only a single line between rows. Read one element. 11063 : hlines[_i3][0] ? "dashed " : "solid "; 11064 } 11065 11066 if (/[sd]/.test(rowLines)) { 11067 table.setAttribute("rowlines", rowLines.trim()); 11068 } 11069 11070 if (menclose !== "") { 11071 table = new mathMLTree.MathNode("menclose", [table]); 11072 table.setAttribute("notation", menclose.trim()); 11073 } 11074 11075 if (group.arraystretch && group.arraystretch < 1) { 11076 // A small array. Wrap in scriptstyle so row gap is not too large. 11077 table = new mathMLTree.MathNode("mstyle", [table]); 11078 table.setAttribute("scriptlevel", "1"); 11079 } 11080 11081 return table; 11082}; // Convenience function for align, align*, aligned, alignat, alignat*, alignedat. 11083 11084 11085var alignedHandler = function alignedHandler(context, args) { 11086 if (context.envName.indexOf("ed") === -1) { 11087 validateAmsEnvironmentContext(context); 11088 } 11089 11090 var cols = []; 11091 var separationType = context.envName.indexOf("at") > -1 ? "alignat" : "align"; 11092 var isSplit = context.envName === "split"; 11093 var res = parseArray(context.parser, { 11094 cols, 11095 addJot: true, 11096 autoTag: isSplit ? undefined : getAutoTag(context.envName), 11097 emptySingleRow: true, 11098 colSeparationType: separationType, 11099 maxNumCols: isSplit ? 2 : undefined, 11100 leqno: context.parser.settings.leqno 11101 }, "display"); // Determining number of columns. 11102 // 1. If the first argument is given, we use it as a number of columns, 11103 // and makes sure that each row doesn't exceed that number. 11104 // 2. Otherwise, just count number of columns = maximum number 11105 // of cells in each row ("aligned" mode -- isAligned will be true). 11106 // 11107 // At the same time, prepend empty group {} at beginning of every second 11108 // cell in each row (starting with second cell) so that operators become 11109 // binary. This behavior is implemented in amsmath's \start@aligned. 11110 11111 var numMaths; 11112 var numCols = 0; 11113 var emptyGroup = { 11114 type: "ordgroup", 11115 mode: context.mode, 11116 body: [] 11117 }; 11118 11119 if (args[0] && args[0].type === "ordgroup") { 11120 var arg0 = ""; 11121 11122 for (var i = 0; i < args[0].body.length; i++) { 11123 var textord = assertNodeType(args[0].body[i], "textord"); 11124 arg0 += textord.text; 11125 } 11126 11127 numMaths = Number(arg0); 11128 numCols = numMaths * 2; 11129 } 11130 11131 var isAligned = !numCols; 11132 res.body.forEach(function (row) { 11133 for (var _i4 = 1; _i4 < row.length; _i4 += 2) { 11134 // Modify ordgroup node within styling node 11135 var styling = assertNodeType(row[_i4], "styling"); 11136 var ordgroup = assertNodeType(styling.body[0], "ordgroup"); 11137 ordgroup.body.unshift(emptyGroup); 11138 } 11139 11140 if (!isAligned) { 11141 // Case 1 11142 var curMaths = row.length / 2; 11143 11144 if (numMaths < curMaths) { 11145 throw new ParseError("Too many math in a row: " + ("expected " + numMaths + ", but got " + curMaths), row[0]); 11146 } 11147 } else if (numCols < row.length) { 11148 // Case 2 11149 numCols = row.length; 11150 } 11151 }); // Adjusting alignment. 11152 // In aligned mode, we add one \qquad between columns; 11153 // otherwise we add nothing. 11154 11155 for (var _i5 = 0; _i5 < numCols; ++_i5) { 11156 var align = "r"; 11157 var pregap = 0; 11158 11159 if (_i5 % 2 === 1) { 11160 align = "l"; 11161 } else if (_i5 > 0 && isAligned) { 11162 // "aligned" mode. 11163 pregap = 1; // add one \quad 11164 } 11165 11166 cols[_i5] = { 11167 type: "align", 11168 align: align, 11169 pregap: pregap, 11170 postgap: 0 11171 }; 11172 } 11173 11174 res.colSeparationType = isAligned ? "align" : "alignat"; 11175 return res; 11176}; // Arrays are part of LaTeX, defined in lttab.dtx so its documentation 11177// is part of the source2e.pdf file of LaTeX2e source documentation. 11178// {darray} is an {array} environment where cells are set in \displaystyle, 11179// as defined in nccmath.sty. 11180 11181 11182defineEnvironment({ 11183 type: "array", 11184 names: ["array", "darray"], 11185 props: { 11186 numArgs: 1 11187 }, 11188 11189 handler(context, args) { 11190 // Since no types are specified above, the two possibilities are 11191 // - The argument is wrapped in {} or [], in which case Parser's 11192 // parseGroup() returns an "ordgroup" wrapping some symbol node. 11193 // - The argument is a bare symbol node. 11194 var symNode = checkSymbolNodeType(args[0]); 11195 var colalign = symNode ? [args[0]] : assertNodeType(args[0], "ordgroup").body; 11196 var cols = colalign.map(function (nde) { 11197 var node = assertSymbolNodeType(nde); 11198 var ca = node.text; 11199 11200 if ("lcr".indexOf(ca) !== -1) { 11201 return { 11202 type: "align", 11203 align: ca 11204 }; 11205 } else if (ca === "|") { 11206 return { 11207 type: "separator", 11208 separator: "|" 11209 }; 11210 } else if (ca === ":") { 11211 return { 11212 type: "separator", 11213 separator: ":" 11214 }; 11215 } 11216 11217 throw new ParseError("Unknown column alignment: " + ca, nde); 11218 }); 11219 var res = { 11220 cols, 11221 hskipBeforeAndAfter: true, 11222 // \@preamble in lttab.dtx 11223 maxNumCols: cols.length 11224 }; 11225 return parseArray(context.parser, res, dCellStyle(context.envName)); 11226 }, 11227 11228 htmlBuilder: htmlBuilder$6, 11229 mathmlBuilder: mathmlBuilder$5 11230}); // The matrix environments of amsmath builds on the array environment 11231// of LaTeX, which is discussed above. 11232// The mathtools package adds starred versions of the same environments. 11233// These have an optional argument to choose left|center|right justification. 11234 11235defineEnvironment({ 11236 type: "array", 11237 names: ["matrix", "pmatrix", "bmatrix", "Bmatrix", "vmatrix", "Vmatrix", "matrix*", "pmatrix*", "bmatrix*", "Bmatrix*", "vmatrix*", "Vmatrix*"], 11238 props: { 11239 numArgs: 0 11240 }, 11241 11242 handler(context) { 11243 var delimiters = { 11244 "matrix": null, 11245 "pmatrix": ["(", ")"], 11246 "bmatrix": ["[", "]"], 11247 "Bmatrix": ["\\{", "\\}"], 11248 "vmatrix": ["|", "|"], 11249 "Vmatrix": ["\\Vert", "\\Vert"] 11250 }[context.envName.replace("*", "")]; // \hskip -\arraycolsep in amsmath 11251 11252 var colAlign = "c"; 11253 var payload = { 11254 hskipBeforeAndAfter: false, 11255 cols: [{ 11256 type: "align", 11257 align: colAlign 11258 }] 11259 }; 11260 11261 if (context.envName.charAt(context.envName.length - 1) === "*") { 11262 // It's one of the mathtools starred functions. 11263 // Parse the optional alignment argument. 11264 var parser = context.parser; 11265 parser.consumeSpaces(); 11266 11267 if (parser.fetch().text === "[") { 11268 parser.consume(); 11269 parser.consumeSpaces(); 11270 colAlign = parser.fetch().text; 11271 11272 if ("lcr".indexOf(colAlign) === -1) { 11273 throw new ParseError("Expected l or c or r", parser.nextToken); 11274 } 11275 11276 parser.consume(); 11277 parser.consumeSpaces(); 11278 parser.expect("]"); 11279 parser.consume(); 11280 payload.cols = [{ 11281 type: "align", 11282 align: colAlign 11283 }]; 11284 } 11285 } 11286 11287 var res = parseArray(context.parser, payload, dCellStyle(context.envName)); // Populate cols with the correct number of column alignment specs. 11288 11289 var numCols = Math.max(0, ...res.body.map(row => row.length)); 11290 res.cols = new Array(numCols).fill({ 11291 type: "align", 11292 align: colAlign 11293 }); 11294 return delimiters ? { 11295 type: "leftright", 11296 mode: context.mode, 11297 body: [res], 11298 left: delimiters[0], 11299 right: delimiters[1], 11300 rightColor: undefined // \right uninfluenced by \color in array 11301 11302 } : res; 11303 }, 11304 11305 htmlBuilder: htmlBuilder$6, 11306 mathmlBuilder: mathmlBuilder$5 11307}); 11308defineEnvironment({ 11309 type: "array", 11310 names: ["smallmatrix"], 11311 props: { 11312 numArgs: 0 11313 }, 11314 11315 handler(context) { 11316 var payload = { 11317 arraystretch: 0.5 11318 }; 11319 var res = parseArray(context.parser, payload, "script"); 11320 res.colSeparationType = "small"; 11321 return res; 11322 }, 11323 11324 htmlBuilder: htmlBuilder$6, 11325 mathmlBuilder: mathmlBuilder$5 11326}); 11327defineEnvironment({ 11328 type: "array", 11329 names: ["subarray"], 11330 props: { 11331 numArgs: 1 11332 }, 11333 11334 handler(context, args) { 11335 // Parsing of {subarray} is similar to {array} 11336 var symNode = checkSymbolNodeType(args[0]); 11337 var colalign = symNode ? [args[0]] : assertNodeType(args[0], "ordgroup").body; 11338 var cols = colalign.map(function (nde) { 11339 var node = assertSymbolNodeType(nde); 11340 var ca = node.text; // {subarray} only recognizes "l" & "c" 11341 11342 if ("lc".indexOf(ca) !== -1) { 11343 return { 11344 type: "align", 11345 align: ca 11346 }; 11347 } 11348 11349 throw new ParseError("Unknown column alignment: " + ca, nde); 11350 }); 11351 11352 if (cols.length > 1) { 11353 throw new ParseError("{subarray} can contain only one column"); 11354 } 11355 11356 var res = { 11357 cols, 11358 hskipBeforeAndAfter: false, 11359 arraystretch: 0.5 11360 }; 11361 res = parseArray(context.parser, res, "script"); 11362 11363 if (res.body.length > 0 && res.body[0].length > 1) { 11364 throw new ParseError("{subarray} can contain only one column"); 11365 } 11366 11367 return res; 11368 }, 11369 11370 htmlBuilder: htmlBuilder$6, 11371 mathmlBuilder: mathmlBuilder$5 11372}); // A cases environment (in amsmath.sty) is almost equivalent to 11373// \def\arraystretch{1.2}% 11374// \left\{\begin{array}{@{}l@{\quad}l@{}} ⦠\end{array}\right. 11375// {dcases} is a {cases} environment where cells are set in \displaystyle, 11376// as defined in mathtools.sty. 11377// {rcases} is another mathtools environment. It's brace is on the right side. 11378 11379defineEnvironment({ 11380 type: "array", 11381 names: ["cases", "dcases", "rcases", "drcases"], 11382 props: { 11383 numArgs: 0 11384 }, 11385 11386 handler(context) { 11387 var payload = { 11388 arraystretch: 1.2, 11389 cols: [{ 11390 type: "align", 11391 align: "l", 11392 pregap: 0, 11393 // TODO(kevinb) get the current style. 11394 // For now we use the metrics for TEXT style which is what we were 11395 // doing before. Before attempting to get the current style we 11396 // should look at TeX's behavior especially for \over and matrices. 11397 postgap: 1.0 11398 /* 1em quad */ 11399 11400 }, { 11401 type: "align", 11402 align: "l", 11403 pregap: 0, 11404 postgap: 0 11405 }] 11406 }; 11407 var res = parseArray(context.parser, payload, dCellStyle(context.envName)); 11408 return { 11409 type: "leftright", 11410 mode: context.mode, 11411 body: [res], 11412 left: context.envName.indexOf("r") > -1 ? "." : "\\{", 11413 right: context.envName.indexOf("r") > -1 ? "\\}" : ".", 11414 rightColor: undefined 11415 }; 11416 }, 11417 11418 htmlBuilder: htmlBuilder$6, 11419 mathmlBuilder: mathmlBuilder$5 11420}); // In the align environment, one uses ampersands, &, to specify number of 11421// columns in each row, and to locate spacing between each column. 11422// align gets automatic numbering. align* and aligned do not. 11423// The alignedat environment can be used in math mode. 11424// Note that we assume \nomallineskiplimit to be zero, 11425// so that \strut@ is the same as \strut. 11426 11427defineEnvironment({ 11428 type: "array", 11429 names: ["align", "align*", "aligned", "split"], 11430 props: { 11431 numArgs: 0 11432 }, 11433 handler: alignedHandler, 11434 htmlBuilder: htmlBuilder$6, 11435 mathmlBuilder: mathmlBuilder$5 11436}); // A gathered environment is like an array environment with one centered 11437// column, but where rows are considered lines so get \jot line spacing 11438// and contents are set in \displaystyle. 11439 11440defineEnvironment({ 11441 type: "array", 11442 names: ["gathered", "gather", "gather*"], 11443 props: { 11444 numArgs: 0 11445 }, 11446 11447 handler(context) { 11448 if (utils.contains(["gather", "gather*"], context.envName)) { 11449 validateAmsEnvironmentContext(context); 11450 } 11451 11452 var res = { 11453 cols: [{ 11454 type: "align", 11455 align: "c" 11456 }], 11457 addJot: true, 11458 colSeparationType: "gather", 11459 autoTag: getAutoTag(context.envName), 11460 emptySingleRow: true, 11461 leqno: context.parser.settings.leqno 11462 }; 11463 return parseArray(context.parser, res, "display"); 11464 }, 11465 11466 htmlBuilder: htmlBuilder$6, 11467 mathmlBuilder: mathmlBuilder$5 11468}); // alignat environment is like an align environment, but one must explicitly 11469// specify maximum number of columns in each row, and can adjust spacing between 11470// each columns. 11471 11472defineEnvironment({ 11473 type: "array", 11474 names: ["alignat", "alignat*", "alignedat"], 11475 props: { 11476 numArgs: 1 11477 }, 11478 handler: alignedHandler, 11479 htmlBuilder: htmlBuilder$6, 11480 mathmlBuilder: mathmlBuilder$5 11481}); 11482defineEnvironment({ 11483 type: "array", 11484 names: ["equation", "equation*"], 11485 props: { 11486 numArgs: 0 11487 }, 11488 11489 handler(context) { 11490 validateAmsEnvironmentContext(context); 11491 var res = { 11492 autoTag: getAutoTag(context.envName), 11493 emptySingleRow: true, 11494 singleRow: true, 11495 maxNumCols: 1, 11496 leqno: context.parser.settings.leqno 11497 }; 11498 return parseArray(context.parser, res, "display"); 11499 }, 11500 11501 htmlBuilder: htmlBuilder$6, 11502 mathmlBuilder: mathmlBuilder$5 11503}); 11504defineEnvironment({ 11505 type: "array", 11506 names: ["CD"], 11507 props: { 11508 numArgs: 0 11509 }, 11510 11511 handler(context) { 11512 validateAmsEnvironmentContext(context); 11513 return parseCD(context.parser); 11514 }, 11515 11516 htmlBuilder: htmlBuilder$6, 11517 mathmlBuilder: mathmlBuilder$5 11518}); 11519defineMacro("\\nonumber", "\\gdef\\@eqnsw{0}"); 11520defineMacro("\\notag", "\\nonumber"); // Catch \hline outside array environment 11521 11522defineFunction({ 11523 type: "text", 11524 // Doesn't matter what this is. 11525 names: ["\\hline", "\\hdashline"], 11526 props: { 11527 numArgs: 0, 11528 allowedInText: true, 11529 allowedInMath: true 11530 }, 11531 11532 handler(context, args) { 11533 throw new ParseError(context.funcName + " valid only within array environment"); 11534 } 11535 11536}); 11537 11538var environments = _environments; 11539 11540// defineEnvironment definitions. 11541 11542defineFunction({ 11543 type: "environment", 11544 names: ["\\begin", "\\end"], 11545 props: { 11546 numArgs: 1, 11547 argTypes: ["text"] 11548 }, 11549 11550 handler(_ref, args) { 11551 var { 11552 parser, 11553 funcName 11554 } = _ref; 11555 var nameGroup = args[0]; 11556 11557 if (nameGroup.type !== "ordgroup") { 11558 throw new ParseError("Invalid environment name", nameGroup); 11559 } 11560 11561 var envName = ""; 11562 11563 for (var i = 0; i < nameGroup.body.length; ++i) { 11564 envName += assertNodeType(nameGroup.body[i], "textord").text; 11565 } 11566 11567 if (funcName === "\\begin") { 11568 // begin...end is similar to left...right 11569 if (!environments.hasOwnProperty(envName)) { 11570 throw new ParseError("No such environment: " + envName, nameGroup); 11571 } // Build the environment object. Arguments and other information will 11572 // be made available to the begin and end methods using properties. 11573 11574 11575 var env = environments[envName]; 11576 var { 11577 args: _args, 11578 optArgs 11579 } = parser.parseArguments("\\begin{" + envName + "}", env); 11580 var context = { 11581 mode: parser.mode, 11582 envName, 11583 parser 11584 }; 11585 var result = env.handler(context, _args, optArgs); 11586 parser.expect("\\end", false); 11587 var endNameToken = parser.nextToken; 11588 var end = assertNodeType(parser.parseFunction(), "environment"); 11589 11590 if (end.name !== envName) { 11591 throw new ParseError("Mismatch: \\begin{" + envName + "} matched by \\end{" + end.name + "}", endNameToken); 11592 } // $FlowFixMe, "environment" handler returns an environment ParseNode 11593 11594 11595 return result; 11596 } 11597 11598 return { 11599 type: "environment", 11600 mode: parser.mode, 11601 name: envName, 11602 nameGroup 11603 }; 11604 } 11605 11606}); 11607 11608// TODO(kevinb): implement \\sl and \\sc 11609 11610var htmlBuilder$5 = (group, options) => { 11611 var font = group.font; 11612 var newOptions = options.withFont(font); 11613 return buildGroup$1(group.body, newOptions); 11614}; 11615 11616var mathmlBuilder$4 = (group, options) => { 11617 var font = group.font; 11618 var newOptions = options.withFont(font); 11619 return buildGroup(group.body, newOptions); 11620}; 11621 11622var fontAliases = { 11623 "\\Bbb": "\\mathbb", 11624 "\\bold": "\\mathbf", 11625 "\\frak": "\\mathfrak", 11626 "\\bm": "\\boldsymbol" 11627}; 11628defineFunction({ 11629 type: "font", 11630 names: [// styles, except \boldsymbol defined below 11631 "\\mathrm", "\\mathit", "\\mathbf", "\\mathnormal", "\\mathsfit", // families 11632 "\\mathbb", "\\mathcal", "\\mathfrak", "\\mathscr", "\\mathsf", "\\mathtt", // aliases, except \bm defined below 11633 "\\Bbb", "\\bold", "\\frak"], 11634 props: { 11635 numArgs: 1, 11636 allowedInArgument: true 11637 }, 11638 handler: (_ref, args) => { 11639 var { 11640 parser, 11641 funcName 11642 } = _ref; 11643 var body = normalizeArgument(args[0]); 11644 var func = funcName; 11645 11646 if (func in fontAliases) { 11647 func = fontAliases[func]; 11648 } 11649 11650 return { 11651 type: "font", 11652 mode: parser.mode, 11653 font: func.slice(1), 11654 body 11655 }; 11656 }, 11657 htmlBuilder: htmlBuilder$5, 11658 mathmlBuilder: mathmlBuilder$4 11659}); 11660defineFunction({ 11661 type: "mclass", 11662 names: ["\\boldsymbol", "\\bm"], 11663 props: { 11664 numArgs: 1 11665 }, 11666 handler: (_ref2, args) => { 11667 var { 11668 parser 11669 } = _ref2; 11670 var body = args[0]; 11671 var isCharacterBox = utils.isCharacterBox(body); // amsbsy.sty's \boldsymbol uses \binrel spacing to inherit the 11672 // argument's bin|rel|ord status 11673 11674 return { 11675 type: "mclass", 11676 mode: parser.mode, 11677 mclass: binrelClass(body), 11678 body: [{ 11679 type: "font", 11680 mode: parser.mode, 11681 font: "boldsymbol", 11682 body 11683 }], 11684 isCharacterBox: isCharacterBox 11685 }; 11686 } 11687}); // Old font changing functions 11688 11689defineFunction({ 11690 type: "font", 11691 names: ["\\rm", "\\sf", "\\tt", "\\bf", "\\it", "\\cal"], 11692 props: { 11693 numArgs: 0, 11694 allowedInText: true 11695 }, 11696 handler: (_ref3, args) => { 11697 var { 11698 parser, 11699 funcName, 11700 breakOnTokenText 11701 } = _ref3; 11702 var { 11703 mode 11704 } = parser; 11705 var body = parser.parseExpression(true, breakOnTokenText); 11706 var style = "math" + funcName.slice(1); 11707 return { 11708 type: "font", 11709 mode: mode, 11710 font: style, 11711 body: { 11712 type: "ordgroup", 11713 mode: parser.mode, 11714 body 11715 } 11716 }; 11717 }, 11718 htmlBuilder: htmlBuilder$5, 11719 mathmlBuilder: mathmlBuilder$4 11720}); 11721 11722var adjustStyle = (size, originalStyle) => { 11723 // Figure out what style this fraction should be in based on the 11724 // function used 11725 var style = originalStyle; 11726 11727 if (size === "display") { 11728 // Get display style as a default. 11729 // If incoming style is sub/sup, use style.text() to get correct size. 11730 style = style.id >= Style$1.SCRIPT.id ? style.text() : Style$1.DISPLAY; 11731 } else if (size === "text" && style.size === Style$1.DISPLAY.size) { 11732 // We're in a \tfrac but incoming style is displaystyle, so: 11733 style = Style$1.TEXT; 11734 } else if (size === "script") { 11735 style = Style$1.SCRIPT; 11736 } else if (size === "scriptscript") { 11737 style = Style$1.SCRIPTSCRIPT; 11738 } 11739 11740 return style; 11741}; 11742 11743var htmlBuilder$4 = (group, options) => { 11744 // Fractions are handled in the TeXbook on pages 444-445, rules 15(a-e). 11745 var style = adjustStyle(group.size, options.style); 11746 var nstyle = style.fracNum(); 11747 var dstyle = style.fracDen(); 11748 var newOptions; 11749 newOptions = options.havingStyle(nstyle); 11750 var numerm = buildGroup$1(group.numer, newOptions, options); 11751 11752 if (group.continued) { 11753 // \cfrac inserts a \strut into the numerator. 11754 // Get \strut dimensions from TeXbook page 353. 11755 var hStrut = 8.5 / options.fontMetrics().ptPerEm; 11756 var dStrut = 3.5 / options.fontMetrics().ptPerEm; 11757 numerm.height = numerm.height < hStrut ? hStrut : numerm.height; 11758 numerm.depth = numerm.depth < dStrut ? dStrut : numerm.depth; 11759 } 11760 11761 newOptions = options.havingStyle(dstyle); 11762 var denomm = buildGroup$1(group.denom, newOptions, options); 11763 var rule; 11764 var ruleWidth; 11765 var ruleSpacing; 11766 11767 if (group.hasBarLine) { 11768 if (group.barSize) { 11769 ruleWidth = calculateSize(group.barSize, options); 11770 rule = buildCommon.makeLineSpan("frac-line", options, ruleWidth); 11771 } else { 11772 rule = buildCommon.makeLineSpan("frac-line", options); 11773 } 11774 11775 ruleWidth = rule.height; 11776 ruleSpacing = rule.height; 11777 } else { 11778 rule = null; 11779 ruleWidth = 0; 11780 ruleSpacing = options.fontMetrics().defaultRuleThickness; 11781 } // Rule 15b 11782 11783 11784 var numShift; 11785 var clearance; 11786 var denomShift; 11787 11788 if (style.size === Style$1.DISPLAY.size || group.size === "display") { 11789 numShift = options.fontMetrics().num1; 11790 11791 if (ruleWidth > 0) { 11792 clearance = 3 * ruleSpacing; 11793 } else { 11794 clearance = 7 * ruleSpacing; 11795 } 11796 11797 denomShift = options.fontMetrics().denom1; 11798 } else { 11799 if (ruleWidth > 0) { 11800 numShift = options.fontMetrics().num2; 11801 clearance = ruleSpacing; 11802 } else { 11803 numShift = options.fontMetrics().num3; 11804 clearance = 3 * ruleSpacing; 11805 } 11806 11807 denomShift = options.fontMetrics().denom2; 11808 } 11809 11810 var frac; 11811 11812 if (!rule) { 11813 // Rule 15c 11814 var candidateClearance = numShift - numerm.depth - (denomm.height - denomShift); 11815 11816 if (candidateClearance < clearance) { 11817 numShift += 0.5 * (clearance - candidateClearance); 11818 denomShift += 0.5 * (clearance - candidateClearance); 11819 } 11820 11821 frac = buildCommon.makeVList({ 11822 positionType: "individualShift", 11823 children: [{ 11824 type: "elem", 11825 elem: denomm, 11826 shift: denomShift 11827 }, { 11828 type: "elem", 11829 elem: numerm, 11830 shift: -numShift 11831 }] 11832 }, options); 11833 } else { 11834 // Rule 15d 11835 var axisHeight = options.fontMetrics().axisHeight; 11836 11837 if (numShift - numerm.depth - (axisHeight + 0.5 * ruleWidth) < clearance) { 11838 numShift += clearance - (numShift - numerm.depth - (axisHeight + 0.5 * ruleWidth)); 11839 } 11840 11841 if (axisHeight - 0.5 * ruleWidth - (denomm.height - denomShift) < clearance) { 11842 denomShift += clearance - (axisHeight - 0.5 * ruleWidth - (denomm.height - denomShift)); 11843 } 11844 11845 var midShift = -(axisHeight - 0.5 * ruleWidth); 11846 frac = buildCommon.makeVList({ 11847 positionType: "individualShift", 11848 children: [{ 11849 type: "elem", 11850 elem: denomm, 11851 shift: denomShift 11852 }, { 11853 type: "elem", 11854 elem: rule, 11855 shift: midShift 11856 }, { 11857 type: "elem", 11858 elem: numerm, 11859 shift: -numShift 11860 }] 11861 }, options); 11862 } // Since we manually change the style sometimes (with \dfrac or \tfrac), 11863 // account for the possible size change here. 11864 11865 11866 newOptions = options.havingStyle(style); 11867 frac.height *= newOptions.sizeMultiplier / options.sizeMultiplier; 11868 frac.depth *= newOptions.sizeMultiplier / options.sizeMultiplier; // Rule 15e 11869 11870 var delimSize; 11871 11872 if (style.size === Style$1.DISPLAY.size) { 11873 delimSize = options.fontMetrics().delim1; 11874 } else if (style.size === Style$1.SCRIPTSCRIPT.size) { 11875 delimSize = options.havingStyle(Style$1.SCRIPT).fontMetrics().delim2; 11876 } else { 11877 delimSize = options.fontMetrics().delim2; 11878 } 11879 11880 var leftDelim; 11881 var rightDelim; 11882 11883 if (group.leftDelim == null) { 11884 leftDelim = makeNullDelimiter(options, ["mopen"]); 11885 } else { 11886 leftDelim = delimiter.customSizedDelim(group.leftDelim, delimSize, true, options.havingStyle(style), group.mode, ["mopen"]); 11887 } 11888 11889 if (group.continued) { 11890 rightDelim = buildCommon.makeSpan([]); // zero width for \cfrac 11891 } else if (group.rightDelim == null) { 11892 rightDelim = makeNullDelimiter(options, ["mclose"]); 11893 } else { 11894 rightDelim = delimiter.customSizedDelim(group.rightDelim, delimSize, true, options.havingStyle(style), group.mode, ["mclose"]); 11895 } 11896 11897 return buildCommon.makeSpan(["mord"].concat(newOptions.sizingClasses(options)), [leftDelim, buildCommon.makeSpan(["mfrac"], [frac]), rightDelim], options); 11898}; 11899 11900var mathmlBuilder$3 = (group, options) => { 11901 var node = new mathMLTree.MathNode("mfrac", [buildGroup(group.numer, options), buildGroup(group.denom, options)]); 11902 11903 if (!group.hasBarLine) { 11904 node.setAttribute("linethickness", "0px"); 11905 } else if (group.barSize) { 11906 var ruleWidth = calculateSize(group.barSize, options); 11907 node.setAttribute("linethickness", makeEm(ruleWidth)); 11908 } 11909 11910 var style = adjustStyle(group.size, options.style); 11911 11912 if (style.size !== options.style.size) { 11913 node = new mathMLTree.MathNode("mstyle", [node]); 11914 var isDisplay = style.size === Style$1.DISPLAY.size ? "true" : "false"; 11915 node.setAttribute("displaystyle", isDisplay); 11916 node.setAttribute("scriptlevel", "0"); 11917 } 11918 11919 if (group.leftDelim != null || group.rightDelim != null) { 11920 var withDelims = []; 11921 11922 if (group.leftDelim != null) { 11923 var leftOp = new mathMLTree.MathNode("mo", [new mathMLTree.TextNode(group.leftDelim.replace("\\", ""))]); 11924 leftOp.setAttribute("fence", "true"); 11925 withDelims.push(leftOp); 11926 } 11927 11928 withDelims.push(node); 11929 11930 if (group.rightDelim != null) { 11931 var rightOp = new mathMLTree.MathNode("mo", [new mathMLTree.TextNode(group.rightDelim.replace("\\", ""))]); 11932 rightOp.setAttribute("fence", "true"); 11933 withDelims.push(rightOp); 11934 } 11935 11936 return makeRow(withDelims); 11937 } 11938 11939 return node; 11940}; 11941 11942defineFunction({ 11943 type: "genfrac", 11944 names: ["\\dfrac", "\\frac", "\\tfrac", "\\dbinom", "\\binom", "\\tbinom", "\\\\atopfrac", // canât be entered directly 11945 "\\\\bracefrac", "\\\\brackfrac" // ditto 11946 ], 11947 props: { 11948 numArgs: 2, 11949 allowedInArgument: true 11950 }, 11951 handler: (_ref, args) => { 11952 var { 11953 parser, 11954 funcName 11955 } = _ref; 11956 var numer = args[0]; 11957 var denom = args[1]; 11958 var hasBarLine; 11959 var leftDelim = null; 11960 var rightDelim = null; 11961 var size = "auto"; 11962 11963 switch (funcName) { 11964 case "\\dfrac": 11965 case "\\frac": 11966 case "\\tfrac": 11967 hasBarLine = true; 11968 break; 11969 11970 case "\\\\atopfrac": 11971 hasBarLine = false; 11972 break; 11973 11974 case "\\dbinom": 11975 case "\\binom": 11976 case "\\tbinom": 11977 hasBarLine = false; 11978 leftDelim = "("; 11979 rightDelim = ")"; 11980 break; 11981 11982 case "\\\\bracefrac": 11983 hasBarLine = false; 11984 leftDelim = "\\{"; 11985 rightDelim = "\\}"; 11986 break; 11987 11988 case "\\\\brackfrac": 11989 hasBarLine = false; 11990 leftDelim = "["; 11991 rightDelim = "]"; 11992 break; 11993 11994 default: 11995 throw new Error("Unrecognized genfrac command"); 11996 } 11997 11998 switch (funcName) { 11999 case "\\dfrac": 12000 case "\\dbinom": 12001 size = "display"; 12002 break; 12003 12004 case "\\tfrac": 12005 case "\\tbinom": 12006 size = "text"; 12007 break; 12008 } 12009 12010 return { 12011 type: "genfrac", 12012 mode: parser.mode, 12013 continued: false, 12014 numer, 12015 denom, 12016 hasBarLine, 12017 leftDelim, 12018 rightDelim, 12019 size, 12020 barSize: null 12021 }; 12022 }, 12023 htmlBuilder: htmlBuilder$4, 12024 mathmlBuilder: mathmlBuilder$3 12025}); 12026defineFunction({ 12027 type: "genfrac", 12028 names: ["\\cfrac"], 12029 props: { 12030 numArgs: 2 12031 }, 12032 handler: (_ref2, args) => { 12033 var { 12034 parser, 12035 funcName 12036 } = _ref2; 12037 var numer = args[0]; 12038 var denom = args[1]; 12039 return { 12040 type: "genfrac", 12041 mode: parser.mode, 12042 continued: true, 12043 numer, 12044 denom, 12045 hasBarLine: true, 12046 leftDelim: null, 12047 rightDelim: null, 12048 size: "display", 12049 barSize: null 12050 }; 12051 } 12052}); // Infix generalized fractions -- these are not rendered directly, but replaced 12053// immediately by one of the variants above. 12054 12055defineFunction({ 12056 type: "infix", 12057 names: ["\\over", "\\choose", "\\atop", "\\brace", "\\brack"], 12058 props: { 12059 numArgs: 0, 12060 infix: true 12061 }, 12062 12063 handler(_ref3) { 12064 var { 12065 parser, 12066 funcName, 12067 token 12068 } = _ref3; 12069 var replaceWith; 12070 12071 switch (funcName) { 12072 case "\\over": 12073 replaceWith = "\\frac"; 12074 break; 12075 12076 case "\\choose": 12077 replaceWith = "\\binom"; 12078 break; 12079 12080 case "\\atop": 12081 replaceWith = "\\\\atopfrac"; 12082 break; 12083 12084 case "\\brace": 12085 replaceWith = "\\\\bracefrac"; 12086 break; 12087 12088 case "\\brack": 12089 replaceWith = "\\\\brackfrac"; 12090 break; 12091 12092 default: 12093 throw new Error("Unrecognized infix genfrac command"); 12094 } 12095 12096 return { 12097 type: "infix", 12098 mode: parser.mode, 12099 replaceWith, 12100 token 12101 }; 12102 } 12103 12104}); 12105var stylArray = ["display", "text", "script", "scriptscript"]; 12106 12107var delimFromValue = function delimFromValue(delimString) { 12108 var delim = null; 12109 12110 if (delimString.length > 0) { 12111 delim = delimString; 12112 delim = delim === "." ? null : delim; 12113 } 12114 12115 return delim; 12116}; 12117 12118defineFunction({ 12119 type: "genfrac", 12120 names: ["\\genfrac"], 12121 props: { 12122 numArgs: 6, 12123 allowedInArgument: true, 12124 argTypes: ["math", "math", "size", "text", "math", "math"] 12125 }, 12126 12127 handler(_ref4, args) { 12128 var { 12129 parser 12130 } = _ref4; 12131 var numer = args[4]; 12132 var denom = args[5]; // Look into the parse nodes to get the desired delimiters. 12133 12134 var leftNode = normalizeArgument(args[0]); 12135 var leftDelim = leftNode.type === "atom" && leftNode.family === "open" ? delimFromValue(leftNode.text) : null; 12136 var rightNode = normalizeArgument(args[1]); 12137 var rightDelim = rightNode.type === "atom" && rightNode.family === "close" ? delimFromValue(rightNode.text) : null; 12138 var barNode = assertNodeType(args[2], "size"); 12139 var hasBarLine; 12140 var barSize = null; 12141 12142 if (barNode.isBlank) { 12143 // \genfrac acts differently than \above. 12144 // \genfrac treats an empty size group as a signal to use a 12145 // standard bar size. \above would see size = 0 and omit the bar. 12146 hasBarLine = true; 12147 } else { 12148 barSize = barNode.value; 12149 hasBarLine = barSize.number > 0; 12150 } // Find out if we want displaystyle, textstyle, etc. 12151 12152 12153 var size = "auto"; 12154 var styl = args[3]; 12155 12156 if (styl.type === "ordgroup") { 12157 if (styl.body.length > 0) { 12158 var textOrd = assertNodeType(styl.body[0], "textord"); 12159 size = stylArray[Number(textOrd.text)]; 12160 } 12161 } else { 12162 styl = assertNodeType(styl, "textord"); 12163 size = stylArray[Number(styl.text)]; 12164 } 12165 12166 return { 12167 type: "genfrac", 12168 mode: parser.mode, 12169 numer, 12170 denom, 12171 continued: false, 12172 hasBarLine, 12173 barSize, 12174 leftDelim, 12175 rightDelim, 12176 size 12177 }; 12178 }, 12179 12180 htmlBuilder: htmlBuilder$4, 12181 mathmlBuilder: mathmlBuilder$3 12182}); // \above is an infix fraction that also defines a fraction bar size. 12183 12184defineFunction({ 12185 type: "infix", 12186 names: ["\\above"], 12187 props: { 12188 numArgs: 1, 12189 argTypes: ["size"], 12190 infix: true 12191 }, 12192 12193 handler(_ref5, args) { 12194 var { 12195 parser, 12196 funcName, 12197 token 12198 } = _ref5; 12199 return { 12200 type: "infix", 12201 mode: parser.mode, 12202 replaceWith: "\\\\abovefrac", 12203 size: assertNodeType(args[0], "size").value, 12204 token 12205 }; 12206 } 12207 12208}); 12209defineFunction({ 12210 type: "genfrac", 12211 names: ["\\\\abovefrac"], 12212 props: { 12213 numArgs: 3, 12214 argTypes: ["math", "size", "math"] 12215 }, 12216 handler: (_ref6, args) => { 12217 var { 12218 parser, 12219 funcName 12220 } = _ref6; 12221 var numer = args[0]; 12222 var barSize = assert(assertNodeType(args[1], "infix").size); 12223 var denom = args[2]; 12224 var hasBarLine = barSize.number > 0; 12225 return { 12226 type: "genfrac", 12227 mode: parser.mode, 12228 numer, 12229 denom, 12230 continued: false, 12231 hasBarLine, 12232 barSize, 12233 leftDelim: null, 12234 rightDelim: null, 12235 size: "auto" 12236 }; 12237 }, 12238 htmlBuilder: htmlBuilder$4, 12239 mathmlBuilder: mathmlBuilder$3 12240}); 12241 12242// NOTE: Unlike most `htmlBuilder`s, this one handles not only "horizBrace", but 12243// also "supsub" since an over/underbrace can affect super/subscripting. 12244var htmlBuilder$3 = (grp, options) => { 12245 var style = options.style; // Pull out the `ParseNode<"horizBrace">` if `grp` is a "supsub" node. 12246 12247 var supSubGroup; 12248 var group; 12249 12250 if (grp.type === "supsub") { 12251 // Ref: LaTeX source2e: }}}}\limits} 12252 // i.e. LaTeX treats the brace similar to an op and passes it 12253 // with \limits, so we need to assign supsub style. 12254 supSubGroup = grp.sup ? buildGroup$1(grp.sup, options.havingStyle(style.sup()), options) : buildGroup$1(grp.sub, options.havingStyle(style.sub()), options); 12255 group = assertNodeType(grp.base, "horizBrace"); 12256 } else { 12257 group = assertNodeType(grp, "horizBrace"); 12258 } // Build the base group 12259 12260 12261 var body = buildGroup$1(group.base, options.havingBaseStyle(Style$1.DISPLAY)); // Create the stretchy element 12262 12263 var braceBody = stretchy.svgSpan(group, options); // Generate the vlist, with the appropriate kerns ââââââââââ 12264 // This first vlist contains the content and the brace: equation 12265 12266 var vlist; 12267 12268 if (group.isOver) { 12269 vlist = buildCommon.makeVList({ 12270 positionType: "firstBaseline", 12271 children: [{ 12272 type: "elem", 12273 elem: body 12274 }, { 12275 type: "kern", 12276 size: 0.1 12277 }, { 12278 type: "elem", 12279 elem: braceBody 12280 }] 12281 }, options); // $FlowFixMe: Replace this with passing "svg-align" into makeVList. 12282 12283 vlist.children[0].children[0].children[1].classes.push("svg-align"); 12284 } else { 12285 vlist = buildCommon.makeVList({ 12286 positionType: "bottom", 12287 positionData: body.depth + 0.1 + braceBody.height, 12288 children: [{ 12289 type: "elem", 12290 elem: braceBody 12291 }, { 12292 type: "kern", 12293 size: 0.1 12294 }, { 12295 type: "elem", 12296 elem: body 12297 }] 12298 }, options); // $FlowFixMe: Replace this with passing "svg-align" into makeVList. 12299 12300 vlist.children[0].children[0].children[0].classes.push("svg-align"); 12301 } 12302 12303 if (supSubGroup) { 12304 // To write the supsub, wrap the first vlist in another vlist: 12305 // They can't all go in the same vlist, because the note might be 12306 // wider than the equation. We want the equation to control the 12307 // brace width. 12308 // note long note long note 12309 // ââââââââââ or âââââ not âââââââââââ 12310 // equation eqn eqn 12311 var vSpan = buildCommon.makeSpan(["mord", group.isOver ? "mover" : "munder"], [vlist], options); 12312 12313 if (group.isOver) { 12314 vlist = buildCommon.makeVList({ 12315 positionType: "firstBaseline", 12316 children: [{ 12317 type: "elem", 12318 elem: vSpan 12319 }, { 12320 type: "kern", 12321 size: 0.2 12322 }, { 12323 type: "elem", 12324 elem: supSubGroup 12325 }] 12326 }, options); 12327 } else { 12328 vlist = buildCommon.makeVList({ 12329 positionType: "bottom", 12330 positionData: vSpan.depth + 0.2 + supSubGroup.height + supSubGroup.depth, 12331 children: [{ 12332 type: "elem", 12333 elem: supSubGroup 12334 }, { 12335 type: "kern", 12336 size: 0.2 12337 }, { 12338 type: "elem", 12339 elem: vSpan 12340 }] 12341 }, options); 12342 } 12343 } 12344 12345 return buildCommon.makeSpan(["mord", group.isOver ? "mover" : "munder"], [vlist], options); 12346}; 12347 12348var mathmlBuilder$2 = (group, options) => { 12349 var accentNode = stretchy.mathMLnode(group.label); 12350 return new mathMLTree.MathNode(group.isOver ? "mover" : "munder", [buildGroup(group.base, options), accentNode]); 12351}; // Horizontal stretchy braces 12352 12353 12354defineFunction({ 12355 type: "horizBrace", 12356 names: ["\\overbrace", "\\underbrace"], 12357 props: { 12358 numArgs: 1 12359 }, 12360 12361 handler(_ref, args) { 12362 var { 12363 parser, 12364 funcName 12365 } = _ref; 12366 return { 12367 type: "horizBrace", 12368 mode: parser.mode, 12369 label: funcName, 12370 isOver: /^\\over/.test(funcName), 12371 base: args[0] 12372 }; 12373 }, 12374 12375 htmlBuilder: htmlBuilder$3, 12376 mathmlBuilder: mathmlBuilder$2 12377}); 12378 12379defineFunction({ 12380 type: "href", 12381 names: ["\\href"], 12382 props: { 12383 numArgs: 2, 12384 argTypes: ["url", "original"], 12385 allowedInText: true 12386 }, 12387 handler: (_ref, args) => { 12388 var { 12389 parser 12390 } = _ref; 12391 var body = args[1]; 12392 var href = assertNodeType(args[0], "url").url; 12393 12394 if (!parser.settings.isTrusted({ 12395 command: "\\href", 12396 url: href 12397 })) { 12398 return parser.formatUnsupportedCmd("\\href"); 12399 } 12400 12401 return { 12402 type: "href", 12403 mode: parser.mode, 12404 href, 12405 body: ordargument(body) 12406 }; 12407 }, 12408 htmlBuilder: (group, options) => { 12409 var elements = buildExpression$1(group.body, options, false); 12410 return buildCommon.makeAnchor(group.href, [], elements, options); 12411 }, 12412 mathmlBuilder: (group, options) => { 12413 var math = buildExpressionRow(group.body, options); 12414 12415 if (!(math instanceof MathNode)) { 12416 math = new MathNode("mrow", [math]); 12417 } 12418 12419 math.setAttribute("href", group.href); 12420 return math; 12421 } 12422}); 12423defineFunction({ 12424 type: "href", 12425 names: ["\\url"], 12426 props: { 12427 numArgs: 1, 12428 argTypes: ["url"], 12429 allowedInText: true 12430 }, 12431 handler: (_ref2, args) => { 12432 var { 12433 parser 12434 } = _ref2; 12435 var href = assertNodeType(args[0], "url").url; 12436 12437 if (!parser.settings.isTrusted({ 12438 command: "\\url", 12439 url: href 12440 })) { 12441 return parser.formatUnsupportedCmd("\\url"); 12442 } 12443 12444 var chars = []; 12445 12446 for (var i = 0; i < href.length; i++) { 12447 var c = href[i]; 12448 12449 if (c === "~") { 12450 c = "\\textasciitilde"; 12451 } 12452 12453 chars.push({ 12454 type: "textord", 12455 mode: "text", 12456 text: c 12457 }); 12458 } 12459 12460 var body = { 12461 type: "text", 12462 mode: parser.mode, 12463 font: "\\texttt", 12464 body: chars 12465 }; 12466 return { 12467 type: "href", 12468 mode: parser.mode, 12469 href, 12470 body: ordargument(body) 12471 }; 12472 } 12473}); 12474 12475// In LaTeX, \vcenter can act only on a box, as in 12476// \vcenter{\hbox{$\frac{a+b}{\dfrac{c}{d}}$}} 12477// This function by itself doesn't do anything but prevent a soft line break. 12478 12479defineFunction({ 12480 type: "hbox", 12481 names: ["\\hbox"], 12482 props: { 12483 numArgs: 1, 12484 argTypes: ["text"], 12485 allowedInText: true, 12486 primitive: true 12487 }, 12488 12489 handler(_ref, args) { 12490 var { 12491 parser 12492 } = _ref; 12493 return { 12494 type: "hbox", 12495 mode: parser.mode, 12496 body: ordargument(args[0]) 12497 }; 12498 }, 12499 12500 htmlBuilder(group, options) { 12501 var elements = buildExpression$1(group.body, options, false); 12502 return buildCommon.makeFragment(elements); 12503 }, 12504 12505 mathmlBuilder(group, options) { 12506 return new mathMLTree.MathNode("mrow", buildExpression(group.body, options)); 12507 } 12508 12509}); 12510 12511defineFunction({ 12512 type: "html", 12513 names: ["\\htmlClass", "\\htmlId", "\\htmlStyle", "\\htmlData"], 12514 props: { 12515 numArgs: 2, 12516 argTypes: ["raw", "original"], 12517 allowedInText: true 12518 }, 12519 handler: (_ref, args) => { 12520 var { 12521 parser, 12522 funcName, 12523 token 12524 } = _ref; 12525 var value = assertNodeType(args[0], "raw").string; 12526 var body = args[1]; 12527 12528 if (parser.settings.strict) { 12529 parser.settings.reportNonstrict("htmlExtension", "HTML extension is disabled on strict mode"); 12530 } 12531 12532 var trustContext; 12533 var attributes = {}; 12534 12535 switch (funcName) { 12536 case "\\htmlClass": 12537 attributes.class = value; 12538 trustContext = { 12539 command: "\\htmlClass", 12540 class: value 12541 }; 12542 break; 12543 12544 case "\\htmlId": 12545 attributes.id = value; 12546 trustContext = { 12547 command: "\\htmlId", 12548 id: value 12549 }; 12550 break; 12551 12552 case "\\htmlStyle": 12553 attributes.style = value; 12554 trustContext = { 12555 command: "\\htmlStyle", 12556 style: value 12557 }; 12558 break; 12559 12560 case "\\htmlData": 12561 { 12562 var data = value.split(","); 12563 12564 for (var i = 0; i < data.length; i++) { 12565 var keyVal = data[i].split("="); 12566 12567 if (keyVal.length !== 2) { 12568 throw new ParseError("Error parsing key-value for \\htmlData"); 12569 } 12570 12571 attributes["data-" + keyVal[0].trim()] = keyVal[1].trim(); 12572 } 12573 12574 trustContext = { 12575 command: "\\htmlData", 12576 attributes 12577 }; 12578 break; 12579 } 12580 12581 default: 12582 throw new Error("Unrecognized html command"); 12583 } 12584 12585 if (!parser.settings.isTrusted(trustContext)) { 12586 return parser.formatUnsupportedCmd(funcName); 12587 } 12588 12589 return { 12590 type: "html", 12591 mode: parser.mode, 12592 attributes, 12593 body: ordargument(body) 12594 }; 12595 }, 12596 htmlBuilder: (group, options) => { 12597 var elements = buildExpression$1(group.body, options, false); 12598 var classes = ["enclosing"]; 12599 12600 if (group.attributes.class) { 12601 classes.push(...group.attributes.class.trim().split(/\s+/)); 12602 } 12603 12604 var span = buildCommon.makeSpan(classes, elements, options); 12605 12606 for (var attr in group.attributes) { 12607 if (attr !== "class" && group.attributes.hasOwnProperty(attr)) { 12608 span.setAttribute(attr, group.attributes[attr]); 12609 } 12610 } 12611 12612 return span; 12613 }, 12614 mathmlBuilder: (group, options) => { 12615 return buildExpressionRow(group.body, options); 12616 } 12617}); 12618 12619defineFunction({ 12620 type: "htmlmathml", 12621 names: ["\\html@mathml"], 12622 props: { 12623 numArgs: 2, 12624 allowedInText: true 12625 }, 12626 handler: (_ref, args) => { 12627 var { 12628 parser 12629 } = _ref; 12630 return { 12631 type: "htmlmathml", 12632 mode: parser.mode, 12633 html: ordargument(args[0]), 12634 mathml: ordargument(args[1]) 12635 }; 12636 }, 12637 htmlBuilder: (group, options) => { 12638 var elements = buildExpression$1(group.html, options, false); 12639 return buildCommon.makeFragment(elements); 12640 }, 12641 mathmlBuilder: (group, options) => { 12642 return buildExpressionRow(group.mathml, options); 12643 } 12644}); 12645 12646var sizeData = function sizeData(str) { 12647 if (/^[-+]? *(\d+(\.\d*)?|\.\d+)$/.test(str)) { 12648 // str is a number with no unit specified. 12649 // default unit is bp, per graphix package. 12650 return { 12651 number: +str, 12652 unit: "bp" 12653 }; 12654 } else { 12655 var match = /([-+]?) *(\d+(?:\.\d*)?|\.\d+) *([a-z]{2})/.exec(str); 12656 12657 if (!match) { 12658 throw new ParseError("Invalid size: '" + str + "' in \\includegraphics"); 12659 } 12660 12661 var data = { 12662 number: +(match[1] + match[2]), 12663 // sign + magnitude, cast to number 12664 unit: match[3] 12665 }; 12666 12667 if (!validUnit(data)) { 12668 throw new ParseError("Invalid unit: '" + data.unit + "' in \\includegraphics."); 12669 } 12670 12671 return data; 12672 } 12673}; 12674 12675defineFunction({ 12676 type: "includegraphics", 12677 names: ["\\includegraphics"], 12678 props: { 12679 numArgs: 1, 12680 numOptionalArgs: 1, 12681 argTypes: ["raw", "url"], 12682 allowedInText: false 12683 }, 12684 handler: (_ref, args, optArgs) => { 12685 var { 12686 parser 12687 } = _ref; 12688 var width = { 12689 number: 0, 12690 unit: "em" 12691 }; 12692 var height = { 12693 number: 0.9, 12694 unit: "em" 12695 }; // sorta character sized. 12696 12697 var totalheight = { 12698 number: 0, 12699 unit: "em" 12700 }; 12701 var alt = ""; 12702 12703 if (optArgs[0]) { 12704 var attributeStr = assertNodeType(optArgs[0], "raw").string; // Parser.js does not parse key/value pairs. We get a string. 12705 12706 var attributes = attributeStr.split(","); 12707 12708 for (var i = 0; i < attributes.length; i++) { 12709 var keyVal = attributes[i].split("="); 12710 12711 if (keyVal.length === 2) { 12712 var str = keyVal[1].trim(); 12713 12714 switch (keyVal[0].trim()) { 12715 case "alt": 12716 alt = str; 12717 break; 12718 12719 case "width": 12720 width = sizeData(str); 12721 break; 12722 12723 case "height": 12724 height = sizeData(str); 12725 break; 12726 12727 case "totalheight": 12728 totalheight = sizeData(str); 12729 break; 12730 12731 default: 12732 throw new ParseError("Invalid key: '" + keyVal[0] + "' in \\includegraphics."); 12733 } 12734 } 12735 } 12736 } 12737 12738 var src = assertNodeType(args[0], "url").url; 12739 12740 if (alt === "") { 12741 // No alt given. Use the file name. Strip away the path. 12742 alt = src; 12743 alt = alt.replace(/^.*[\\/]/, ''); 12744 alt = alt.substring(0, alt.lastIndexOf('.')); 12745 } 12746 12747 if (!parser.settings.isTrusted({ 12748 command: "\\includegraphics", 12749 url: src 12750 })) { 12751 return parser.formatUnsupportedCmd("\\includegraphics"); 12752 } 12753 12754 return { 12755 type: "includegraphics", 12756 mode: parser.mode, 12757 alt: alt, 12758 width: width, 12759 height: height, 12760 totalheight: totalheight, 12761 src: src 12762 }; 12763 }, 12764 htmlBuilder: (group, options) => { 12765 var height = calculateSize(group.height, options); 12766 var depth = 0; 12767 12768 if (group.totalheight.number > 0) { 12769 depth = calculateSize(group.totalheight, options) - height; 12770 } 12771 12772 var width = 0; 12773 12774 if (group.width.number > 0) { 12775 width = calculateSize(group.width, options); 12776 } 12777 12778 var style = { 12779 height: makeEm(height + depth) 12780 }; 12781 12782 if (width > 0) { 12783 style.width = makeEm(width); 12784 } 12785 12786 if (depth > 0) { 12787 style.verticalAlign = makeEm(-depth); 12788 } 12789 12790 var node = new Img(group.src, group.alt, style); 12791 node.height = height; 12792 node.depth = depth; 12793 return node; 12794 }, 12795 mathmlBuilder: (group, options) => { 12796 var node = new mathMLTree.MathNode("mglyph", []); 12797 node.setAttribute("alt", group.alt); 12798 var height = calculateSize(group.height, options); 12799 var depth = 0; 12800 12801 if (group.totalheight.number > 0) { 12802 depth = calculateSize(group.totalheight, options) - height; 12803 node.setAttribute("valign", makeEm(-depth)); 12804 } 12805 12806 node.setAttribute("height", makeEm(height + depth)); 12807 12808 if (group.width.number > 0) { 12809 var width = calculateSize(group.width, options); 12810 node.setAttribute("width", makeEm(width)); 12811 } 12812 12813 node.setAttribute("src", group.src); 12814 return node; 12815 } 12816}); 12817 12818// Horizontal spacing commands 12819 12820defineFunction({ 12821 type: "kern", 12822 names: ["\\kern", "\\mkern", "\\hskip", "\\mskip"], 12823 props: { 12824 numArgs: 1, 12825 argTypes: ["size"], 12826 primitive: true, 12827 allowedInText: true 12828 }, 12829 12830 handler(_ref, args) { 12831 var { 12832 parser, 12833 funcName 12834 } = _ref; 12835 var size = assertNodeType(args[0], "size"); 12836 12837 if (parser.settings.strict) { 12838 var mathFunction = funcName[1] === 'm'; // \mkern, \mskip 12839 12840 var muUnit = size.value.unit === 'mu'; 12841 12842 if (mathFunction) { 12843 if (!muUnit) { 12844 parser.settings.reportNonstrict("mathVsTextUnits", "LaTeX's " + funcName + " supports only mu units, " + ("not " + size.value.unit + " units")); 12845 } 12846 12847 if (parser.mode !== "math") { 12848 parser.settings.reportNonstrict("mathVsTextUnits", "LaTeX's " + funcName + " works only in math mode"); 12849 } 12850 } else { 12851 // !mathFunction 12852 if (muUnit) { 12853 parser.settings.reportNonstrict("mathVsTextUnits", "LaTeX's " + funcName + " doesn't support mu units"); 12854 } 12855 } 12856 } 12857 12858 return { 12859 type: "kern", 12860 mode: parser.mode, 12861 dimension: size.value 12862 }; 12863 }, 12864 12865 htmlBuilder(group, options) { 12866 return buildCommon.makeGlue(group.dimension, options); 12867 }, 12868 12869 mathmlBuilder(group, options) { 12870 var dimension = calculateSize(group.dimension, options); 12871 return new mathMLTree.SpaceNode(dimension); 12872 } 12873 12874}); 12875 12876// Horizontal overlap functions 12877defineFunction({ 12878 type: "lap", 12879 names: ["\\mathllap", "\\mathrlap", "\\mathclap"], 12880 props: { 12881 numArgs: 1, 12882 allowedInText: true 12883 }, 12884 handler: (_ref, args) => { 12885 var { 12886 parser, 12887 funcName 12888 } = _ref; 12889 var body = args[0]; 12890 return { 12891 type: "lap", 12892 mode: parser.mode, 12893 alignment: funcName.slice(5), 12894 body 12895 }; 12896 }, 12897 htmlBuilder: (group, options) => { 12898 // mathllap, mathrlap, mathclap 12899 var inner; 12900 12901 if (group.alignment === "clap") { 12902 // ref: https://www.math.lsu.edu/~aperlis/publications/mathclap/ 12903 inner = buildCommon.makeSpan([], [buildGroup$1(group.body, options)]); // wrap, since CSS will center a .clap > .inner > span 12904 12905 inner = buildCommon.makeSpan(["inner"], [inner], options); 12906 } else { 12907 inner = buildCommon.makeSpan(["inner"], [buildGroup$1(group.body, options)]); 12908 } 12909 12910 var fix = buildCommon.makeSpan(["fix"], []); 12911 var node = buildCommon.makeSpan([group.alignment], [inner, fix], options); // At this point, we have correctly set horizontal alignment of the 12912 // two items involved in the lap. 12913 // Next, use a strut to set the height of the HTML bounding box. 12914 // Otherwise, a tall argument may be misplaced. 12915 // This code resolved issue #1153 12916 12917 var strut = buildCommon.makeSpan(["strut"]); 12918 strut.style.height = makeEm(node.height + node.depth); 12919 12920 if (node.depth) { 12921 strut.style.verticalAlign = makeEm(-node.depth); 12922 } 12923 12924 node.children.unshift(strut); // Next, prevent vertical misplacement when next to something tall. 12925 // This code resolves issue #1234 12926 12927 node = buildCommon.makeSpan(["thinbox"], [node], options); 12928 return buildCommon.makeSpan(["mord", "vbox"], [node], options); 12929 }, 12930 mathmlBuilder: (group, options) => { 12931 // mathllap, mathrlap, mathclap 12932 var node = new mathMLTree.MathNode("mpadded", [buildGroup(group.body, options)]); 12933 12934 if (group.alignment !== "rlap") { 12935 var offset = group.alignment === "llap" ? "-1" : "-0.5"; 12936 node.setAttribute("lspace", offset + "width"); 12937 } 12938 12939 node.setAttribute("width", "0px"); 12940 return node; 12941 } 12942}); 12943 12944defineFunction({ 12945 type: "styling", 12946 names: ["\\(", "$"], 12947 props: { 12948 numArgs: 0, 12949 allowedInText: true, 12950 allowedInMath: false 12951 }, 12952 12953 handler(_ref, args) { 12954 var { 12955 funcName, 12956 parser 12957 } = _ref; 12958 var outerMode = parser.mode; 12959 parser.switchMode("math"); 12960 var close = funcName === "\\(" ? "\\)" : "$"; 12961 var body = parser.parseExpression(false, close); 12962 parser.expect(close); 12963 parser.switchMode(outerMode); 12964 return { 12965 type: "styling", 12966 mode: parser.mode, 12967 style: "text", 12968 body 12969 }; 12970 } 12971 12972}); // Check for extra closing math delimiters 12973 12974defineFunction({ 12975 type: "text", 12976 // Doesn't matter what this is. 12977 names: ["\\)", "\\]"], 12978 props: { 12979 numArgs: 0, 12980 allowedInText: true, 12981 allowedInMath: false 12982 }, 12983 12984 handler(context, args) { 12985 throw new ParseError("Mismatched " + context.funcName); 12986 } 12987 12988}); 12989 12990var chooseMathStyle = (group, options) => { 12991 switch (options.style.size) { 12992 case Style$1.DISPLAY.size: 12993 return group.display; 12994 12995 case Style$1.TEXT.size: 12996 return group.text; 12997 12998 case Style$1.SCRIPT.size: 12999 return group.script; 13000 13001 case Style$1.SCRIPTSCRIPT.size: 13002 return group.scriptscript; 13003 13004 default: 13005 return group.text; 13006 } 13007}; 13008 13009defineFunction({ 13010 type: "mathchoice", 13011 names: ["\\mathchoice"], 13012 props: { 13013 numArgs: 4, 13014 primitive: true 13015 }, 13016 handler: (_ref, args) => { 13017 var { 13018 parser 13019 } = _ref; 13020 return { 13021 type: "mathchoice", 13022 mode: parser.mode, 13023 display: ordargument(args[0]), 13024 text: ordargument(args[1]), 13025 script: ordargument(args[2]), 13026 scriptscript: ordargument(args[3]) 13027 }; 13028 }, 13029 htmlBuilder: (group, options) => { 13030 var body = chooseMathStyle(group, options); 13031 var elements = buildExpression$1(body, options, false); 13032 return buildCommon.makeFragment(elements); 13033 }, 13034 mathmlBuilder: (group, options) => { 13035 var body = chooseMathStyle(group, options); 13036 return buildExpressionRow(body, options); 13037 } 13038}); 13039 13040var assembleSupSub = (base, supGroup, subGroup, options, style, slant, baseShift) => { 13041 base = buildCommon.makeSpan([], [base]); 13042 var subIsSingleCharacter = subGroup && utils.isCharacterBox(subGroup); 13043 var sub; 13044 var sup; // We manually have to handle the superscripts and subscripts. This, 13045 // aside from the kern calculations, is copied from supsub. 13046 13047 if (supGroup) { 13048 var elem = buildGroup$1(supGroup, options.havingStyle(style.sup()), options); 13049 sup = { 13050 elem, 13051 kern: Math.max(options.fontMetrics().bigOpSpacing1, options.fontMetrics().bigOpSpacing3 - elem.depth) 13052 }; 13053 } 13054 13055 if (subGroup) { 13056 var _elem = buildGroup$1(subGroup, options.havingStyle(style.sub()), options); 13057 13058 sub = { 13059 elem: _elem, 13060 kern: Math.max(options.fontMetrics().bigOpSpacing2, options.fontMetrics().bigOpSpacing4 - _elem.height) 13061 }; 13062 } // Build the final group as a vlist of the possible subscript, base, 13063 // and possible superscript. 13064 13065 13066 var finalGroup; 13067 13068 if (sup && sub) { 13069 var bottom = options.fontMetrics().bigOpSpacing5 + sub.elem.height + sub.elem.depth + sub.kern + base.depth + baseShift; 13070 finalGroup = buildCommon.makeVList({ 13071 positionType: "bottom", 13072 positionData: bottom, 13073 children: [{ 13074 type: "kern", 13075 size: options.fontMetrics().bigOpSpacing5 13076 }, { 13077 type: "elem", 13078 elem: sub.elem, 13079 marginLeft: makeEm(-slant) 13080 }, { 13081 type: "kern", 13082 size: sub.kern 13083 }, { 13084 type: "elem", 13085 elem: base 13086 }, { 13087 type: "kern", 13088 size: sup.kern 13089 }, { 13090 type: "elem", 13091 elem: sup.elem, 13092 marginLeft: makeEm(slant) 13093 }, { 13094 type: "kern", 13095 size: options.fontMetrics().bigOpSpacing5 13096 }] 13097 }, options); 13098 } else if (sub) { 13099 var top = base.height - baseShift; // Shift the limits by the slant of the symbol. Note 13100 // that we are supposed to shift the limits by 1/2 of the slant, 13101 // but since we are centering the limits adding a full slant of 13102 // margin will shift by 1/2 that. 13103 13104 finalGroup = buildCommon.makeVList({ 13105 positionType: "top", 13106 positionData: top, 13107 children: [{ 13108 type: "kern", 13109 size: options.fontMetrics().bigOpSpacing5 13110 }, { 13111 type: "elem", 13112 elem: sub.elem, 13113 marginLeft: makeEm(-slant) 13114 }, { 13115 type: "kern", 13116 size: sub.kern 13117 }, { 13118 type: "elem", 13119 elem: base 13120 }] 13121 }, options); 13122 } else if (sup) { 13123 var _bottom = base.depth + baseShift; 13124 13125 finalGroup = buildCommon.makeVList({ 13126 positionType: "bottom", 13127 positionData: _bottom, 13128 children: [{ 13129 type: "elem", 13130 elem: base 13131 }, { 13132 type: "kern", 13133 size: sup.kern 13134 }, { 13135 type: "elem", 13136 elem: sup.elem, 13137 marginLeft: makeEm(slant) 13138 }, { 13139 type: "kern", 13140 size: options.fontMetrics().bigOpSpacing5 13141 }] 13142 }, options); 13143 } else { 13144 // This case probably shouldn't occur (this would mean the 13145 // supsub was sending us a group with no superscript or 13146 // subscript) but be safe. 13147 return base; 13148 } 13149 13150 var parts = [finalGroup]; 13151 13152 if (sub && slant !== 0 && !subIsSingleCharacter) { 13153 // A negative margin-left was applied to the lower limit. 13154 // Avoid an overlap by placing a spacer on the left on the group. 13155 var spacer = buildCommon.makeSpan(["mspace"], [], options); 13156 spacer.style.marginRight = makeEm(slant); 13157 parts.unshift(spacer); 13158 } 13159 13160 return buildCommon.makeSpan(["mop", "op-limits"], parts, options); 13161}; 13162 13163// Limits, symbols 13164// Most operators have a large successor symbol, but these don't. 13165var noSuccessor = ["\\smallint"]; // NOTE: Unlike most `htmlBuilder`s, this one handles not only "op", but also 13166// "supsub" since some of them (like \int) can affect super/subscripting. 13167 13168var htmlBuilder$2 = (grp, options) => { 13169 // Operators are handled in the TeXbook pg. 443-444, rule 13(a). 13170 var supGroup; 13171 var subGroup; 13172 var hasLimits = false; 13173 var group; 13174 13175 if (grp.type === "supsub") { 13176 // If we have limits, supsub will pass us its group to handle. Pull 13177 // out the superscript and subscript and set the group to the op in 13178 // its base. 13179 supGroup = grp.sup; 13180 subGroup = grp.sub; 13181 group = assertNodeType(grp.base, "op"); 13182 hasLimits = true; 13183 } else { 13184 group = assertNodeType(grp, "op"); 13185 } 13186 13187 var style = options.style; 13188 var large = false; 13189 13190 if (style.size === Style$1.DISPLAY.size && group.symbol && !utils.contains(noSuccessor, group.name)) { 13191 // Most symbol operators get larger in displaystyle (rule 13) 13192 large = true; 13193 } 13194 13195 var base; 13196 13197 if (group.symbol) { 13198 // If this is a symbol, create the symbol. 13199 var fontName = large ? "Size2-Regular" : "Size1-Regular"; 13200 var stash = ""; 13201 13202 if (group.name === "\\oiint" || group.name === "\\oiiint") { 13203 // No font glyphs yet, so use a glyph w/o the oval. 13204 // TODO: When font glyphs are available, delete this code. 13205 stash = group.name.slice(1); 13206 group.name = stash === "oiint" ? "\\iint" : "\\iiint"; 13207 } 13208 13209 base = buildCommon.makeSymbol(group.name, fontName, "math", options, ["mop", "op-symbol", large ? "large-op" : "small-op"]); 13210 13211 if (stash.length > 0) { 13212 // We're in \oiint or \oiiint. Overlay the oval. 13213 // TODO: When font glyphs are available, delete this code. 13214 var italic = base.italic; 13215 var oval = buildCommon.staticSvg(stash + "Size" + (large ? "2" : "1"), options); 13216 base = buildCommon.makeVList({ 13217 positionType: "individualShift", 13218 children: [{ 13219 type: "elem", 13220 elem: base, 13221 shift: 0 13222 }, { 13223 type: "elem", 13224 elem: oval, 13225 shift: large ? 0.08 : 0 13226 }] 13227 }, options); 13228 group.name = "\\" + stash; 13229 base.classes.unshift("mop"); // $FlowFixMe 13230 13231 base.italic = italic; 13232 } 13233 } else if (group.body) { 13234 // If this is a list, compose that list. 13235 var inner = buildExpression$1(group.body, options, true); 13236 13237 if (inner.length === 1 && inner[0] instanceof SymbolNode) { 13238 base = inner[0]; 13239 base.classes[0] = "mop"; // replace old mclass 13240 } else { 13241 base = buildCommon.makeSpan(["mop"], inner, options); 13242 } 13243 } else { 13244 // Otherwise, this is a text operator. Build the text from the 13245 // operator's name. 13246 var output = []; 13247 13248 for (var i = 1; i < group.name.length; i++) { 13249 output.push(buildCommon.mathsym(group.name[i], group.mode, options)); 13250 } 13251 13252 base = buildCommon.makeSpan(["mop"], output, options); 13253 } // If content of op is a single symbol, shift it vertically. 13254 13255 13256 var baseShift = 0; 13257 var slant = 0; 13258 13259 if ((base instanceof SymbolNode || group.name === "\\oiint" || group.name === "\\oiiint") && !group.suppressBaseShift) { 13260 // We suppress the shift of the base of \overset and \underset. Otherwise, 13261 // shift the symbol so its center lies on the axis (rule 13). It 13262 // appears that our fonts have the centers of the symbols already 13263 // almost on the axis, so these numbers are very small. Note we 13264 // don't actually apply this here, but instead it is used either in 13265 // the vlist creation or separately when there are no limits. 13266 baseShift = (base.height - base.depth) / 2 - options.fontMetrics().axisHeight; // The slant of the symbol is just its italic correction. 13267 // $FlowFixMe 13268 13269 slant = base.italic; 13270 } 13271 13272 if (hasLimits) { 13273 return assembleSupSub(base, supGroup, subGroup, options, style, slant, baseShift); 13274 } else { 13275 if (baseShift) { 13276 base.style.position = "relative"; 13277 base.style.top = makeEm(baseShift); 13278 } 13279 13280 return base; 13281 } 13282}; 13283 13284var mathmlBuilder$1 = (group, options) => { 13285 var node; 13286 13287 if (group.symbol) { 13288 // This is a symbol. Just add the symbol. 13289 node = new MathNode("mo", [makeText(group.name, group.mode)]); 13290 13291 if (utils.contains(noSuccessor, group.name)) { 13292 node.setAttribute("largeop", "false"); 13293 } 13294 } else if (group.body) { 13295 // This is an operator with children. Add them. 13296 node = new MathNode("mo", buildExpression(group.body, options)); 13297 } else { 13298 // This is a text operator. Add all of the characters from the 13299 // operator's name. 13300 node = new MathNode("mi", [new TextNode(group.name.slice(1))]); // Append an <mo>⁡</mo>. 13301 // ref: https://www.w3.org/TR/REC-MathML/chap3_2.html#sec3.2.4 13302 13303 var operator = new MathNode("mo", [makeText("\u2061", "text")]); 13304 13305 if (group.parentIsSupSub) { 13306 node = new MathNode("mrow", [node, operator]); 13307 } else { 13308 node = newDocumentFragment([node, operator]); 13309 } 13310 } 13311 13312 return node; 13313}; 13314 13315var singleCharBigOps = { 13316 "\u220F": "\\prod", 13317 "\u2210": "\\coprod", 13318 "\u2211": "\\sum", 13319 "\u22c0": "\\bigwedge", 13320 "\u22c1": "\\bigvee", 13321 "\u22c2": "\\bigcap", 13322 "\u22c3": "\\bigcup", 13323 "\u2a00": "\\bigodot", 13324 "\u2a01": "\\bigoplus", 13325 "\u2a02": "\\bigotimes", 13326 "\u2a04": "\\biguplus", 13327 "\u2a06": "\\bigsqcup" 13328}; 13329defineFunction({ 13330 type: "op", 13331 names: ["\\coprod", "\\bigvee", "\\bigwedge", "\\biguplus", "\\bigcap", "\\bigcup", "\\intop", "\\prod", "\\sum", "\\bigotimes", "\\bigoplus", "\\bigodot", "\\bigsqcup", "\\smallint", "\u220F", "\u2210", "\u2211", "\u22c0", "\u22c1", "\u22c2", "\u22c3", "\u2a00", "\u2a01", "\u2a02", "\u2a04", "\u2a06"], 13332 props: { 13333 numArgs: 0 13334 }, 13335 handler: (_ref, args) => { 13336 var { 13337 parser, 13338 funcName 13339 } = _ref; 13340 var fName = funcName; 13341 13342 if (fName.length === 1) { 13343 fName = singleCharBigOps[fName]; 13344 } 13345 13346 return { 13347 type: "op", 13348 mode: parser.mode, 13349 limits: true, 13350 parentIsSupSub: false, 13351 symbol: true, 13352 name: fName 13353 }; 13354 }, 13355 htmlBuilder: htmlBuilder$2, 13356 mathmlBuilder: mathmlBuilder$1 13357}); // Note: calling defineFunction with a type that's already been defined only 13358// works because the same htmlBuilder and mathmlBuilder are being used. 13359 13360defineFunction({ 13361 type: "op", 13362 names: ["\\mathop"], 13363 props: { 13364 numArgs: 1, 13365 primitive: true 13366 }, 13367 handler: (_ref2, args) => { 13368 var { 13369 parser 13370 } = _ref2; 13371 var body = args[0]; 13372 return { 13373 type: "op", 13374 mode: parser.mode, 13375 limits: false, 13376 parentIsSupSub: false, 13377 symbol: false, 13378 body: ordargument(body) 13379 }; 13380 }, 13381 htmlBuilder: htmlBuilder$2, 13382 mathmlBuilder: mathmlBuilder$1 13383}); // There are 2 flags for operators; whether they produce limits in 13384// displaystyle, and whether they are symbols and should grow in 13385// displaystyle. These four groups cover the four possible choices. 13386 13387var singleCharIntegrals = { 13388 "\u222b": "\\int", 13389 "\u222c": "\\iint", 13390 "\u222d": "\\iiint", 13391 "\u222e": "\\oint", 13392 "\u222f": "\\oiint", 13393 "\u2230": "\\oiiint" 13394}; // No limits, not symbols 13395 13396defineFunction({ 13397 type: "op", 13398 names: ["\\arcsin", "\\arccos", "\\arctan", "\\arctg", "\\arcctg", "\\arg", "\\ch", "\\cos", "\\cosec", "\\cosh", "\\cot", "\\cotg", "\\coth", "\\csc", "\\ctg", "\\cth", "\\deg", "\\dim", "\\exp", "\\hom", "\\ker", "\\lg", "\\ln", "\\log", "\\sec", "\\sin", "\\sinh", "\\sh", "\\tan", "\\tanh", "\\tg", "\\th"], 13399 props: { 13400 numArgs: 0 13401 }, 13402 13403 handler(_ref3) { 13404 var { 13405 parser, 13406 funcName 13407 } = _ref3; 13408 return { 13409 type: "op", 13410 mode: parser.mode, 13411 limits: false, 13412 parentIsSupSub: false, 13413 symbol: false, 13414 name: funcName 13415 }; 13416 }, 13417 13418 htmlBuilder: htmlBuilder$2, 13419 mathmlBuilder: mathmlBuilder$1 13420}); // Limits, not symbols 13421 13422defineFunction({ 13423 type: "op", 13424 names: ["\\det", "\\gcd", "\\inf", "\\lim", "\\max", "\\min", "\\Pr", "\\sup"], 13425 props: { 13426 numArgs: 0 13427 }, 13428 13429 handler(_ref4) { 13430 var { 13431 parser, 13432 funcName 13433 } = _ref4; 13434 return { 13435 type: "op", 13436 mode: parser.mode, 13437 limits: true, 13438 parentIsSupSub: false, 13439 symbol: false, 13440 name: funcName 13441 }; 13442 }, 13443 13444 htmlBuilder: htmlBuilder$2, 13445 mathmlBuilder: mathmlBuilder$1 13446}); // No limits, symbols 13447 13448defineFunction({ 13449 type: "op", 13450 names: ["\\int", "\\iint", "\\iiint", "\\oint", "\\oiint", "\\oiiint", "\u222b", "\u222c", "\u222d", "\u222e", "\u222f", "\u2230"], 13451 props: { 13452 numArgs: 0 13453 }, 13454 13455 handler(_ref5) { 13456 var { 13457 parser, 13458 funcName 13459 } = _ref5; 13460 var fName = funcName; 13461 13462 if (fName.length === 1) { 13463 fName = singleCharIntegrals[fName]; 13464 } 13465 13466 return { 13467 type: "op", 13468 mode: parser.mode, 13469 limits: false, 13470 parentIsSupSub: false, 13471 symbol: true, 13472 name: fName 13473 }; 13474 }, 13475 13476 htmlBuilder: htmlBuilder$2, 13477 mathmlBuilder: mathmlBuilder$1 13478}); 13479 13480// NOTE: Unlike most `htmlBuilder`s, this one handles not only 13481// "operatorname", but also "supsub" since \operatorname* can 13482// affect super/subscripting. 13483var htmlBuilder$1 = (grp, options) => { 13484 // Operators are handled in the TeXbook pg. 443-444, rule 13(a). 13485 var supGroup; 13486 var subGroup; 13487 var hasLimits = false; 13488 var group; 13489 13490 if (grp.type === "supsub") { 13491 // If we have limits, supsub will pass us its group to handle. Pull 13492 // out the superscript and subscript and set the group to the op in 13493 // its base. 13494 supGroup = grp.sup; 13495 subGroup = grp.sub; 13496 group = assertNodeType(grp.base, "operatorname"); 13497 hasLimits = true; 13498 } else { 13499 group = assertNodeType(grp, "operatorname"); 13500 } 13501 13502 var base; 13503 13504 if (group.body.length > 0) { 13505 var body = group.body.map(child => { 13506 // $FlowFixMe: Check if the node has a string `text` property. 13507 var childText = child.text; 13508 13509 if (typeof childText === "string") { 13510 return { 13511 type: "textord", 13512 mode: child.mode, 13513 text: childText 13514 }; 13515 } else { 13516 return child; 13517 } 13518 }); // Consolidate function names into symbol characters. 13519 13520 var expression = buildExpression$1(body, options.withFont("mathrm"), true); 13521 13522 for (var i = 0; i < expression.length; i++) { 13523 var child = expression[i]; 13524 13525 if (child instanceof SymbolNode) { 13526 // Per amsopn package, 13527 // change minus to hyphen and \ast to asterisk 13528 child.text = child.text.replace(/\u2212/, "-").replace(/\u2217/, "*"); 13529 } 13530 } 13531 13532 base = buildCommon.makeSpan(["mop"], expression, options); 13533 } else { 13534 base = buildCommon.makeSpan(["mop"], [], options); 13535 } 13536 13537 if (hasLimits) { 13538 return assembleSupSub(base, supGroup, subGroup, options, options.style, 0, 0); 13539 } else { 13540 return base; 13541 } 13542}; 13543 13544var mathmlBuilder = (group, options) => { 13545 // The steps taken here are similar to the html version. 13546 var expression = buildExpression(group.body, options.withFont("mathrm")); // Is expression a string or has it something like a fraction? 13547 13548 var isAllString = true; // default 13549 13550 for (var i = 0; i < expression.length; i++) { 13551 var node = expression[i]; 13552 13553 if (node instanceof mathMLTree.SpaceNode) ; else if (node instanceof mathMLTree.MathNode) { 13554 switch (node.type) { 13555 case "mi": 13556 case "mn": 13557 case "ms": 13558 case "mspace": 13559 case "mtext": 13560 break; 13561 // Do nothing yet. 13562 13563 case "mo": 13564 { 13565 var child = node.children[0]; 13566 13567 if (node.children.length === 1 && child instanceof mathMLTree.TextNode) { 13568 child.text = child.text.replace(/\u2212/, "-").replace(/\u2217/, "*"); 13569 } else { 13570 isAllString = false; 13571 } 13572 13573 break; 13574 } 13575 13576 default: 13577 isAllString = false; 13578 } 13579 } else { 13580 isAllString = false; 13581 } 13582 } 13583 13584 if (isAllString) { 13585 // Write a single TextNode instead of multiple nested tags. 13586 var word = expression.map(node => node.toText()).join(""); 13587 expression = [new mathMLTree.TextNode(word)]; 13588 } 13589 13590 var identifier = new mathMLTree.MathNode("mi", expression); 13591 identifier.setAttribute("mathvariant", "normal"); // \u2061 is the same as ⁡ 13592 // ref: https://www.w3schools.com/charsets/ref_html_entities_a.asp 13593 13594 var operator = new mathMLTree.MathNode("mo", [makeText("\u2061", "text")]); 13595 13596 if (group.parentIsSupSub) { 13597 return new mathMLTree.MathNode("mrow", [identifier, operator]); 13598 } else { 13599 return mathMLTree.newDocumentFragment([identifier, operator]); 13600 } 13601}; // \operatorname 13602// amsopn.dtx: \mathop{#1\kern\z@\operator@font#3}\newmcodes@ 13603 13604 13605defineFunction({ 13606 type: "operatorname", 13607 names: ["\\operatorname@", "\\operatornamewithlimits"], 13608 props: { 13609 numArgs: 1 13610 }, 13611 handler: (_ref, args) => { 13612 var { 13613 parser, 13614 funcName 13615 } = _ref; 13616 var body = args[0]; 13617 return { 13618 type: "operatorname", 13619 mode: parser.mode, 13620 body: ordargument(body), 13621 alwaysHandleSupSub: funcName === "\\operatornamewithlimits", 13622 limits: false, 13623 parentIsSupSub: false 13624 }; 13625 }, 13626 htmlBuilder: htmlBuilder$1, 13627 mathmlBuilder 13628}); 13629defineMacro("\\operatorname", "\\@ifstar\\operatornamewithlimits\\operatorname@"); 13630 13631defineFunctionBuilders({ 13632 type: "ordgroup", 13633 13634 htmlBuilder(group, options) { 13635 if (group.semisimple) { 13636 return buildCommon.makeFragment(buildExpression$1(group.body, options, false)); 13637 } 13638 13639 return buildCommon.makeSpan(["mord"], buildExpression$1(group.body, options, true), options); 13640 }, 13641 13642 mathmlBuilder(group, options) { 13643 return buildExpressionRow(group.body, options, true); 13644 } 13645 13646}); 13647 13648defineFunction({ 13649 type: "overline", 13650 names: ["\\overline"], 13651 props: { 13652 numArgs: 1 13653 }, 13654 13655 handler(_ref, args) { 13656 var { 13657 parser 13658 } = _ref; 13659 var body = args[0]; 13660 return { 13661 type: "overline", 13662 mode: parser.mode, 13663 body 13664 }; 13665 }, 13666 13667 htmlBuilder(group, options) { 13668 // Overlines are handled in the TeXbook pg 443, Rule 9. 13669 // Build the inner group in the cramped style. 13670 var innerGroup = buildGroup$1(group.body, options.havingCrampedStyle()); // Create the line above the body 13671 13672 var line = buildCommon.makeLineSpan("overline-line", options); // Generate the vlist, with the appropriate kerns 13673 13674 var defaultRuleThickness = options.fontMetrics().defaultRuleThickness; 13675 var vlist = buildCommon.makeVList({ 13676 positionType: "firstBaseline", 13677 children: [{ 13678 type: "elem", 13679 elem: innerGroup 13680 }, { 13681 type: "kern", 13682 size: 3 * defaultRuleThickness 13683 }, { 13684 type: "elem", 13685 elem: line 13686 }, { 13687 type: "kern", 13688 size: defaultRuleThickness 13689 }] 13690 }, options); 13691 return buildCommon.makeSpan(["mord", "overline"], [vlist], options); 13692 }, 13693 13694 mathmlBuilder(group, options) { 13695 var operator = new mathMLTree.MathNode("mo", [new mathMLTree.TextNode("\u203e")]); 13696 operator.setAttribute("stretchy", "true"); 13697 var node = new mathMLTree.MathNode("mover", [buildGroup(group.body, options), operator]); 13698 node.setAttribute("accent", "true"); 13699 return node; 13700 } 13701 13702}); 13703 13704defineFunction({ 13705 type: "phantom", 13706 names: ["\\phantom"], 13707 props: { 13708 numArgs: 1, 13709 allowedInText: true 13710 }, 13711 handler: (_ref, args) => { 13712 var { 13713 parser 13714 } = _ref; 13715 var body = args[0]; 13716 return { 13717 type: "phantom", 13718 mode: parser.mode, 13719 body: ordargument(body) 13720 }; 13721 }, 13722 htmlBuilder: (group, options) => { 13723 var elements = buildExpression$1(group.body, options.withPhantom(), false); // \phantom isn't supposed to affect the elements it contains. 13724 // See "color" for more details. 13725 13726 return buildCommon.makeFragment(elements); 13727 }, 13728 mathmlBuilder: (group, options) => { 13729 var inner = buildExpression(group.body, options); 13730 return new mathMLTree.MathNode("mphantom", inner); 13731 } 13732}); 13733defineFunction({ 13734 type: "hphantom", 13735 names: ["\\hphantom"], 13736 props: { 13737 numArgs: 1, 13738 allowedInText: true 13739 }, 13740 handler: (_ref2, args) => { 13741 var { 13742 parser 13743 } = _ref2; 13744 var body = args[0]; 13745 return { 13746 type: "hphantom", 13747 mode: parser.mode, 13748 body 13749 }; 13750 }, 13751 htmlBuilder: (group, options) => { 13752 var node = buildCommon.makeSpan([], [buildGroup$1(group.body, options.withPhantom())]); 13753 node.height = 0; 13754 node.depth = 0; 13755 13756 if (node.children) { 13757 for (var i = 0; i < node.children.length; i++) { 13758 node.children[i].height = 0; 13759 node.children[i].depth = 0; 13760 } 13761 } // See smash for comment re: use of makeVList 13762 13763 13764 node = buildCommon.makeVList({ 13765 positionType: "firstBaseline", 13766 children: [{ 13767 type: "elem", 13768 elem: node 13769 }] 13770 }, options); // For spacing, TeX treats \smash as a math group (same spacing as ord). 13771 13772 return buildCommon.makeSpan(["mord"], [node], options); 13773 }, 13774 mathmlBuilder: (group, options) => { 13775 var inner = buildExpression(ordargument(group.body), options); 13776 var phantom = new mathMLTree.MathNode("mphantom", inner); 13777 var node = new mathMLTree.MathNode("mpadded", [phantom]); 13778 node.setAttribute("height", "0px"); 13779 node.setAttribute("depth", "0px"); 13780 return node; 13781 } 13782}); 13783defineFunction({ 13784 type: "vphantom", 13785 names: ["\\vphantom"], 13786 props: { 13787 numArgs: 1, 13788 allowedInText: true 13789 }, 13790 handler: (_ref3, args) => { 13791 var { 13792 parser 13793 } = _ref3; 13794 var body = args[0]; 13795 return { 13796 type: "vphantom", 13797 mode: parser.mode, 13798 body 13799 }; 13800 }, 13801 htmlBuilder: (group, options) => { 13802 var inner = buildCommon.makeSpan(["inner"], [buildGroup$1(group.body, options.withPhantom())]); 13803 var fix = buildCommon.makeSpan(["fix"], []); 13804 return buildCommon.makeSpan(["mord", "rlap"], [inner, fix], options); 13805 }, 13806 mathmlBuilder: (group, options) => { 13807 var inner = buildExpression(ordargument(group.body), options); 13808 var phantom = new mathMLTree.MathNode("mphantom", inner); 13809 var node = new mathMLTree.MathNode("mpadded", [phantom]); 13810 node.setAttribute("width", "0px"); 13811 return node; 13812 } 13813}); 13814 13815defineFunction({ 13816 type: "raisebox", 13817 names: ["\\raisebox"], 13818 props: { 13819 numArgs: 2, 13820 argTypes: ["size", "hbox"], 13821 allowedInText: true 13822 }, 13823 13824 handler(_ref, args) { 13825 var { 13826 parser 13827 } = _ref; 13828 var amount = assertNodeType(args[0], "size").value; 13829 var body = args[1]; 13830 return { 13831 type: "raisebox", 13832 mode: parser.mode, 13833 dy: amount, 13834 body 13835 }; 13836 }, 13837 13838 htmlBuilder(group, options) { 13839 var body = buildGroup$1(group.body, options); 13840 var dy = calculateSize(group.dy, options); 13841 return buildCommon.makeVList({ 13842 positionType: "shift", 13843 positionData: -dy, 13844 children: [{ 13845 type: "elem", 13846 elem: body 13847 }] 13848 }, options); 13849 }, 13850 13851 mathmlBuilder(group, options) { 13852 var node = new mathMLTree.MathNode("mpadded", [buildGroup(group.body, options)]); 13853 var dy = group.dy.number + group.dy.unit; 13854 node.setAttribute("voffset", dy); 13855 return node; 13856 } 13857 13858}); 13859 13860defineFunction({ 13861 type: "internal", 13862 names: ["\\relax"], 13863 props: { 13864 numArgs: 0, 13865 allowedInText: true 13866 }, 13867 13868 handler(_ref) { 13869 var { 13870 parser 13871 } = _ref; 13872 return { 13873 type: "internal", 13874 mode: parser.mode 13875 }; 13876 } 13877 13878}); 13879 13880defineFunction({ 13881 type: "rule", 13882 names: ["\\rule"], 13883 props: { 13884 numArgs: 2, 13885 numOptionalArgs: 1, 13886 allowedInText: true, 13887 allowedInMath: true, 13888 argTypes: ["size", "size", "size"] 13889 }, 13890 13891 handler(_ref, args, optArgs) { 13892 var { 13893 parser 13894 } = _ref; 13895 var shift = optArgs[0]; 13896 var width = assertNodeType(args[0], "size"); 13897 var height = assertNodeType(args[1], "size"); 13898 return { 13899 type: "rule", 13900 mode: parser.mode, 13901 shift: shift && assertNodeType(shift, "size").value, 13902 width: width.value, 13903 height: height.value 13904 }; 13905 }, 13906 13907 htmlBuilder(group, options) { 13908 // Make an empty span for the rule 13909 var rule = buildCommon.makeSpan(["mord", "rule"], [], options); // Calculate the shift, width, and height of the rule, and account for units 13910 13911 var width = calculateSize(group.width, options); 13912 var height = calculateSize(group.height, options); 13913 var shift = group.shift ? calculateSize(group.shift, options) : 0; // Style the rule to the right size 13914 13915 rule.style.borderRightWidth = makeEm(width); 13916 rule.style.borderTopWidth = makeEm(height); 13917 rule.style.bottom = makeEm(shift); // Record the height and width 13918 13919 rule.width = width; 13920 rule.height = height + shift; 13921 rule.depth = -shift; // Font size is the number large enough that the browser will 13922 // reserve at least `absHeight` space above the baseline. 13923 // The 1.125 factor was empirically determined 13924 13925 rule.maxFontSize = height * 1.125 * options.sizeMultiplier; 13926 return rule; 13927 }, 13928 13929 mathmlBuilder(group, options) { 13930 var width = calculateSize(group.width, options); 13931 var height = calculateSize(group.height, options); 13932 var shift = group.shift ? calculateSize(group.shift, options) : 0; 13933 var color = options.color && options.getColor() || "black"; 13934 var rule = new mathMLTree.MathNode("mspace"); 13935 rule.setAttribute("mathbackground", color); 13936 rule.setAttribute("width", makeEm(width)); 13937 rule.setAttribute("height", makeEm(height)); 13938 var wrapper = new mathMLTree.MathNode("mpadded", [rule]); 13939 13940 if (shift >= 0) { 13941 wrapper.setAttribute("height", makeEm(shift)); 13942 } else { 13943 wrapper.setAttribute("height", makeEm(shift)); 13944 wrapper.setAttribute("depth", makeEm(-shift)); 13945 } 13946 13947 wrapper.setAttribute("voffset", makeEm(shift)); 13948 return wrapper; 13949 } 13950 13951}); 13952 13953function sizingGroup(value, options, baseOptions) { 13954 var inner = buildExpression$1(value, options, false); 13955 var multiplier = options.sizeMultiplier / baseOptions.sizeMultiplier; // Add size-resetting classes to the inner list and set maxFontSize 13956 // manually. Handle nested size changes. 13957 13958 for (var i = 0; i < inner.length; i++) { 13959 var pos = inner[i].classes.indexOf("sizing"); 13960 13961 if (pos < 0) { 13962 Array.prototype.push.apply(inner[i].classes, options.sizingClasses(baseOptions)); 13963 } else if (inner[i].classes[pos + 1] === "reset-size" + options.size) { 13964 // This is a nested size change: e.g., inner[i] is the "b" in 13965 // `\Huge a \small b`. Override the old size (the `reset-` class) 13966 // but not the new size. 13967 inner[i].classes[pos + 1] = "reset-size" + baseOptions.size; 13968 } 13969 13970 inner[i].height *= multiplier; 13971 inner[i].depth *= multiplier; 13972 } 13973 13974 return buildCommon.makeFragment(inner); 13975} 13976var sizeFuncs = ["\\tiny", "\\sixptsize", "\\scriptsize", "\\footnotesize", "\\small", "\\normalsize", "\\large", "\\Large", "\\LARGE", "\\huge", "\\Huge"]; 13977var htmlBuilder = (group, options) => { 13978 // Handle sizing operators like \Huge. Real TeX doesn't actually allow 13979 // these functions inside of math expressions, so we do some special 13980 // handling. 13981 var newOptions = options.havingSize(group.size); 13982 return sizingGroup(group.body, newOptions, options); 13983}; 13984defineFunction({ 13985 type: "sizing", 13986 names: sizeFuncs, 13987 props: { 13988 numArgs: 0, 13989 allowedInText: true 13990 }, 13991 handler: (_ref, args) => { 13992 var { 13993 breakOnTokenText, 13994 funcName, 13995 parser 13996 } = _ref; 13997 var body = parser.parseExpression(false, breakOnTokenText); 13998 return { 13999 type: "sizing", 14000 mode: parser.mode, 14001 // Figure out what size to use based on the list of functions above 14002 size: sizeFuncs.indexOf(funcName) + 1, 14003 body 14004 }; 14005 }, 14006 htmlBuilder, 14007 mathmlBuilder: (group, options) => { 14008 var newOptions = options.havingSize(group.size); 14009 var inner = buildExpression(group.body, newOptions); 14010 var node = new mathMLTree.MathNode("mstyle", inner); // TODO(emily): This doesn't produce the correct size for nested size 14011 // changes, because we don't keep state of what style we're currently 14012 // in, so we can't reset the size to normal before changing it. Now 14013 // that we're passing an options parameter we should be able to fix 14014 // this. 14015 14016 node.setAttribute("mathsize", makeEm(newOptions.sizeMultiplier)); 14017 return node; 14018 } 14019}); 14020 14021// smash, with optional [tb], as in AMS 14022defineFunction({ 14023 type: "smash", 14024 names: ["\\smash"], 14025 props: { 14026 numArgs: 1, 14027 numOptionalArgs: 1, 14028 allowedInText: true 14029 }, 14030 handler: (_ref, args, optArgs) => { 14031 var { 14032 parser 14033 } = _ref; 14034 var smashHeight = false; 14035 var smashDepth = false; 14036 var tbArg = optArgs[0] && assertNodeType(optArgs[0], "ordgroup"); 14037 14038 if (tbArg) { 14039 // Optional [tb] argument is engaged. 14040 // ref: amsmath: \renewcommand{\smash}[1][tb]{% 14041 // def\mb@t{\ht}\def\mb@b{\dp}\def\mb@tb{\ht\z@\z@\dp}% 14042 var letter = ""; 14043 14044 for (var i = 0; i < tbArg.body.length; ++i) { 14045 var node = tbArg.body[i]; // $FlowFixMe: Not every node type has a `text` property. 14046 14047 letter = node.text; 14048 14049 if (letter === "t") { 14050 smashHeight = true; 14051 } else if (letter === "b") { 14052 smashDepth = true; 14053 } else { 14054 smashHeight = false; 14055 smashDepth = false; 14056 break; 14057 } 14058 } 14059 } else { 14060 smashHeight = true; 14061 smashDepth = true; 14062 } 14063 14064 var body = args[0]; 14065 return { 14066 type: "smash", 14067 mode: parser.mode, 14068 body, 14069 smashHeight, 14070 smashDepth 14071 }; 14072 }, 14073 htmlBuilder: (group, options) => { 14074 var node = buildCommon.makeSpan([], [buildGroup$1(group.body, options)]); 14075 14076 if (!group.smashHeight && !group.smashDepth) { 14077 return node; 14078 } 14079 14080 if (group.smashHeight) { 14081 node.height = 0; // In order to influence makeVList, we have to reset the children. 14082 14083 if (node.children) { 14084 for (var i = 0; i < node.children.length; i++) { 14085 node.children[i].height = 0; 14086 } 14087 } 14088 } 14089 14090 if (group.smashDepth) { 14091 node.depth = 0; 14092 14093 if (node.children) { 14094 for (var _i = 0; _i < node.children.length; _i++) { 14095 node.children[_i].depth = 0; 14096 } 14097 } 14098 } // At this point, we've reset the TeX-like height and depth values. 14099 // But the span still has an HTML line height. 14100 // makeVList applies "display: table-cell", which prevents the browser 14101 // from acting on that line height. So we'll call makeVList now. 14102 14103 14104 var smashedNode = buildCommon.makeVList({ 14105 positionType: "firstBaseline", 14106 children: [{ 14107 type: "elem", 14108 elem: node 14109 }] 14110 }, options); // For spacing, TeX treats \hphantom as a math group (same spacing as ord). 14111 14112 return buildCommon.makeSpan(["mord"], [smashedNode], options); 14113 }, 14114 mathmlBuilder: (group, options) => { 14115 var node = new mathMLTree.MathNode("mpadded", [buildGroup(group.body, options)]); 14116 14117 if (group.smashHeight) { 14118 node.setAttribute("height", "0px"); 14119 } 14120 14121 if (group.smashDepth) { 14122 node.setAttribute("depth", "0px"); 14123 } 14124 14125 return node; 14126 } 14127}); 14128 14129defineFunction({ 14130 type: "sqrt", 14131 names: ["\\sqrt"], 14132 props: { 14133 numArgs: 1, 14134 numOptionalArgs: 1 14135 }, 14136 14137 handler(_ref, args, optArgs) { 14138 var { 14139 parser 14140 } = _ref; 14141 var index = optArgs[0]; 14142 var body = args[0]; 14143 return { 14144 type: "sqrt", 14145 mode: parser.mode, 14146 body, 14147 index 14148 }; 14149 }, 14150 14151 htmlBuilder(group, options) { 14152 // Square roots are handled in the TeXbook pg. 443, Rule 11. 14153 // First, we do the same steps as in overline to build the inner group 14154 // and line 14155 var inner = buildGroup$1(group.body, options.havingCrampedStyle()); 14156 14157 if (inner.height === 0) { 14158 // Render a small surd. 14159 inner.height = options.fontMetrics().xHeight; 14160 } // Some groups can return document fragments. Handle those by wrapping 14161 // them in a span. 14162 14163 14164 inner = buildCommon.wrapFragment(inner, options); // Calculate the minimum size for the \surd delimiter 14165 14166 var metrics = options.fontMetrics(); 14167 var theta = metrics.defaultRuleThickness; 14168 var phi = theta; 14169 14170 if (options.style.id < Style$1.TEXT.id) { 14171 phi = options.fontMetrics().xHeight; 14172 } // Calculate the clearance between the body and line 14173 14174 14175 var lineClearance = theta + phi / 4; 14176 var minDelimiterHeight = inner.height + inner.depth + lineClearance + theta; // Create a sqrt SVG of the required minimum size 14177 14178 var { 14179 span: img, 14180 ruleWidth, 14181 advanceWidth 14182 } = delimiter.sqrtImage(minDelimiterHeight, options); 14183 var delimDepth = img.height - ruleWidth; // Adjust the clearance based on the delimiter size 14184 14185 if (delimDepth > inner.height + inner.depth + lineClearance) { 14186 lineClearance = (lineClearance + delimDepth - inner.height - inner.depth) / 2; 14187 } // Shift the sqrt image 14188 14189 14190 var imgShift = img.height - inner.height - lineClearance - ruleWidth; 14191 inner.style.paddingLeft = makeEm(advanceWidth); // Overlay the image and the argument. 14192 14193 var body = buildCommon.makeVList({ 14194 positionType: "firstBaseline", 14195 children: [{ 14196 type: "elem", 14197 elem: inner, 14198 wrapperClasses: ["svg-align"] 14199 }, { 14200 type: "kern", 14201 size: -(inner.height + imgShift) 14202 }, { 14203 type: "elem", 14204 elem: img 14205 }, { 14206 type: "kern", 14207 size: ruleWidth 14208 }] 14209 }, options); 14210 14211 if (!group.index) { 14212 return buildCommon.makeSpan(["mord", "sqrt"], [body], options); 14213 } else { 14214 // Handle the optional root index 14215 // The index is always in scriptscript style 14216 var newOptions = options.havingStyle(Style$1.SCRIPTSCRIPT); 14217 var rootm = buildGroup$1(group.index, newOptions, options); // The amount the index is shifted by. This is taken from the TeX 14218 // source, in the definition of `\r@@t`. 14219 14220 var toShift = 0.6 * (body.height - body.depth); // Build a VList with the superscript shifted up correctly 14221 14222 var rootVList = buildCommon.makeVList({ 14223 positionType: "shift", 14224 positionData: -toShift, 14225 children: [{ 14226 type: "elem", 14227 elem: rootm 14228 }] 14229 }, options); // Add a class surrounding it so we can add on the appropriate 14230 // kerning 14231 14232 var rootVListWrap = buildCommon.makeSpan(["root"], [rootVList]); 14233 return buildCommon.makeSpan(["mord", "sqrt"], [rootVListWrap, body], options); 14234 } 14235 }, 14236 14237 mathmlBuilder(group, options) { 14238 var { 14239 body, 14240 index 14241 } = group; 14242 return index ? new mathMLTree.MathNode("mroot", [buildGroup(body, options), buildGroup(index, options)]) : new mathMLTree.MathNode("msqrt", [buildGroup(body, options)]); 14243 } 14244 14245}); 14246 14247var styleMap = { 14248 "display": Style$1.DISPLAY, 14249 "text": Style$1.TEXT, 14250 "script": Style$1.SCRIPT, 14251 "scriptscript": Style$1.SCRIPTSCRIPT 14252}; 14253defineFunction({ 14254 type: "styling", 14255 names: ["\\displaystyle", "\\textstyle", "\\scriptstyle", "\\scriptscriptstyle"], 14256 props: { 14257 numArgs: 0, 14258 allowedInText: true, 14259 primitive: true 14260 }, 14261 14262 handler(_ref, args) { 14263 var { 14264 breakOnTokenText, 14265 funcName, 14266 parser 14267 } = _ref; 14268 // parse out the implicit body 14269 var body = parser.parseExpression(true, breakOnTokenText); // TODO: Refactor to avoid duplicating styleMap in multiple places (e.g. 14270 // here and in buildHTML and de-dupe the enumeration of all the styles). 14271 // $FlowFixMe: The names above exactly match the styles. 14272 14273 var style = funcName.slice(1, funcName.length - 5); 14274 return { 14275 type: "styling", 14276 mode: parser.mode, 14277 // Figure out what style to use by pulling out the style from 14278 // the function name 14279 style, 14280 body 14281 }; 14282 }, 14283 14284 htmlBuilder(group, options) { 14285 // Style changes are handled in the TeXbook on pg. 442, Rule 3. 14286 var newStyle = styleMap[group.style]; 14287 var newOptions = options.havingStyle(newStyle).withFont(''); 14288 return sizingGroup(group.body, newOptions, options); 14289 }, 14290 14291 mathmlBuilder(group, options) { 14292 // Figure out what style we're changing to. 14293 var newStyle = styleMap[group.style]; 14294 var newOptions = options.havingStyle(newStyle); 14295 var inner = buildExpression(group.body, newOptions); 14296 var node = new mathMLTree.MathNode("mstyle", inner); 14297 var styleAttributes = { 14298 "display": ["0", "true"], 14299 "text": ["0", "false"], 14300 "script": ["1", "false"], 14301 "scriptscript": ["2", "false"] 14302 }; 14303 var attr = styleAttributes[group.style]; 14304 node.setAttribute("scriptlevel", attr[0]); 14305 node.setAttribute("displaystyle", attr[1]); 14306 return node; 14307 } 14308 14309}); 14310 14311/** 14312 * Sometimes, groups perform special rules when they have superscripts or 14313 * subscripts attached to them. This function lets the `supsub` group know that 14314 * Sometimes, groups perform special rules when they have superscripts or 14315 * its inner element should handle the superscripts and subscripts instead of 14316 * handling them itself. 14317 */ 14318var htmlBuilderDelegate = function htmlBuilderDelegate(group, options) { 14319 var base = group.base; 14320 14321 if (!base) { 14322 return null; 14323 } else if (base.type === "op") { 14324 // Operators handle supsubs differently when they have limits 14325 // (e.g. `\displaystyle\sum_2^3`) 14326 var delegate = base.limits && (options.style.size === Style$1.DISPLAY.size || base.alwaysHandleSupSub); 14327 return delegate ? htmlBuilder$2 : null; 14328 } else if (base.type === "operatorname") { 14329 var _delegate = base.alwaysHandleSupSub && (options.style.size === Style$1.DISPLAY.size || base.limits); 14330 14331 return _delegate ? htmlBuilder$1 : null; 14332 } else if (base.type === "accent") { 14333 return utils.isCharacterBox(base.base) ? htmlBuilder$a : null; 14334 } else if (base.type === "horizBrace") { 14335 var isSup = !group.sub; 14336 return isSup === base.isOver ? htmlBuilder$3 : null; 14337 } else { 14338 return null; 14339 } 14340}; // Super scripts and subscripts, whose precise placement can depend on other 14341// functions that precede them. 14342 14343 14344defineFunctionBuilders({ 14345 type: "supsub", 14346 14347 htmlBuilder(group, options) { 14348 // Superscript and subscripts are handled in the TeXbook on page 14349 // 445-446, rules 18(a-f). 14350 // Here is where we defer to the inner group if it should handle 14351 // superscripts and subscripts itself. 14352 var builderDelegate = htmlBuilderDelegate(group, options); 14353 14354 if (builderDelegate) { 14355 return builderDelegate(group, options); 14356 } 14357 14358 var { 14359 base: valueBase, 14360 sup: valueSup, 14361 sub: valueSub 14362 } = group; 14363 var base = buildGroup$1(valueBase, options); 14364 var supm; 14365 var subm; 14366 var metrics = options.fontMetrics(); // Rule 18a 14367 14368 var supShift = 0; 14369 var subShift = 0; 14370 var isCharacterBox = valueBase && utils.isCharacterBox(valueBase); 14371 14372 if (valueSup) { 14373 var newOptions = options.havingStyle(options.style.sup()); 14374 supm = buildGroup$1(valueSup, newOptions, options); 14375 14376 if (!isCharacterBox) { 14377 supShift = base.height - newOptions.fontMetrics().supDrop * newOptions.sizeMultiplier / options.sizeMultiplier; 14378 } 14379 } 14380 14381 if (valueSub) { 14382 var _newOptions = options.havingStyle(options.style.sub()); 14383 14384 subm = buildGroup$1(valueSub, _newOptions, options); 14385 14386 if (!isCharacterBox) { 14387 subShift = base.depth + _newOptions.fontMetrics().subDrop * _newOptions.sizeMultiplier / options.sizeMultiplier; 14388 } 14389 } // Rule 18c 14390 14391 14392 var minSupShift; 14393 14394 if (options.style === Style$1.DISPLAY) { 14395 minSupShift = metrics.sup1; 14396 } else if (options.style.cramped) { 14397 minSupShift = metrics.sup3; 14398 } else { 14399 minSupShift = metrics.sup2; 14400 } // scriptspace is a font-size-independent size, so scale it 14401 // appropriately for use as the marginRight. 14402 14403 14404 var multiplier = options.sizeMultiplier; 14405 var marginRight = makeEm(0.5 / metrics.ptPerEm / multiplier); 14406 var marginLeft = null; 14407 14408 if (subm) { 14409 // Subscripts shouldn't be shifted by the base's italic correction. 14410 // Account for that by shifting the subscript back the appropriate 14411 // amount. Note we only do this when the base is a single symbol. 14412 var isOiint = group.base && group.base.type === "op" && group.base.name && (group.base.name === "\\oiint" || group.base.name === "\\oiiint"); 14413 14414 if (base instanceof SymbolNode || isOiint) { 14415 // $FlowFixMe 14416 marginLeft = makeEm(-base.italic); 14417 } 14418 } 14419 14420 var supsub; 14421 14422 if (supm && subm) { 14423 supShift = Math.max(supShift, minSupShift, supm.depth + 0.25 * metrics.xHeight); 14424 subShift = Math.max(subShift, metrics.sub2); 14425 var ruleWidth = metrics.defaultRuleThickness; // Rule 18e 14426 14427 var maxWidth = 4 * ruleWidth; 14428 14429 if (supShift - supm.depth - (subm.height - subShift) < maxWidth) { 14430 subShift = maxWidth - (supShift - supm.depth) + subm.height; 14431 var psi = 0.8 * metrics.xHeight - (supShift - supm.depth); 14432 14433 if (psi > 0) { 14434 supShift += psi; 14435 subShift -= psi; 14436 } 14437 } 14438 14439 var vlistElem = [{ 14440 type: "elem", 14441 elem: subm, 14442 shift: subShift, 14443 marginRight, 14444 marginLeft 14445 }, { 14446 type: "elem", 14447 elem: supm, 14448 shift: -supShift, 14449 marginRight 14450 }]; 14451 supsub = buildCommon.makeVList({ 14452 positionType: "individualShift", 14453 children: vlistElem 14454 }, options); 14455 } else if (subm) { 14456 // Rule 18b 14457 subShift = Math.max(subShift, metrics.sub1, subm.height - 0.8 * metrics.xHeight); 14458 var _vlistElem = [{ 14459 type: "elem", 14460 elem: subm, 14461 marginLeft, 14462 marginRight 14463 }]; 14464 supsub = buildCommon.makeVList({ 14465 positionType: "shift", 14466 positionData: subShift, 14467 children: _vlistElem 14468 }, options); 14469 } else if (supm) { 14470 // Rule 18c, d 14471 supShift = Math.max(supShift, minSupShift, supm.depth + 0.25 * metrics.xHeight); 14472 supsub = buildCommon.makeVList({ 14473 positionType: "shift", 14474 positionData: -supShift, 14475 children: [{ 14476 type: "elem", 14477 elem: supm, 14478 marginRight 14479 }] 14480 }, options); 14481 } else { 14482 throw new Error("supsub must have either sup or sub."); 14483 } // Wrap the supsub vlist in a span.msupsub to reset text-align. 14484 14485 14486 var mclass = getTypeOfDomTree(base, "right") || "mord"; 14487 return buildCommon.makeSpan([mclass], [base, buildCommon.makeSpan(["msupsub"], [supsub])], options); 14488 }, 14489 14490 mathmlBuilder(group, options) { 14491 // Is the inner group a relevant horizonal brace? 14492 var isBrace = false; 14493 var isOver; 14494 var isSup; 14495 14496 if (group.base && group.base.type === "horizBrace") { 14497 isSup = !!group.sup; 14498 14499 if (isSup === group.base.isOver) { 14500 isBrace = true; 14501 isOver = group.base.isOver; 14502 } 14503 } 14504 14505 if (group.base && (group.base.type === "op" || group.base.type === "operatorname")) { 14506 group.base.parentIsSupSub = true; 14507 } 14508 14509 var children = [buildGroup(group.base, options)]; 14510 14511 if (group.sub) { 14512 children.push(buildGroup(group.sub, options)); 14513 } 14514 14515 if (group.sup) { 14516 children.push(buildGroup(group.sup, options)); 14517 } 14518 14519 var nodeType; 14520 14521 if (isBrace) { 14522 nodeType = isOver ? "mover" : "munder"; 14523 } else if (!group.sub) { 14524 var base = group.base; 14525 14526 if (base && base.type === "op" && base.limits && (options.style === Style$1.DISPLAY || base.alwaysHandleSupSub)) { 14527 nodeType = "mover"; 14528 } else if (base && base.type === "operatorname" && base.alwaysHandleSupSub && (base.limits || options.style === Style$1.DISPLAY)) { 14529 nodeType = "mover"; 14530 } else { 14531 nodeType = "msup"; 14532 } 14533 } else if (!group.sup) { 14534 var _base = group.base; 14535 14536 if (_base && _base.type === "op" && _base.limits && (options.style === Style$1.DISPLAY || _base.alwaysHandleSupSub)) { 14537 nodeType = "munder"; 14538 } else if (_base && _base.type === "operatorname" && _base.alwaysHandleSupSub && (_base.limits || options.style === Style$1.DISPLAY)) { 14539 nodeType = "munder"; 14540 } else { 14541 nodeType = "msub"; 14542 } 14543 } else { 14544 var _base2 = group.base; 14545 14546 if (_base2 && _base2.type === "op" && _base2.limits && options.style === Style$1.DISPLAY) { 14547 nodeType = "munderover"; 14548 } else if (_base2 && _base2.type === "operatorname" && _base2.alwaysHandleSupSub && (options.style === Style$1.DISPLAY || _base2.limits)) { 14549 nodeType = "munderover"; 14550 } else { 14551 nodeType = "msubsup"; 14552 } 14553 } 14554 14555 return new mathMLTree.MathNode(nodeType, children); 14556 } 14557 14558}); 14559 14560defineFunctionBuilders({ 14561 type: "atom", 14562 14563 htmlBuilder(group, options) { 14564 return buildCommon.mathsym(group.text, group.mode, options, ["m" + group.family]); 14565 }, 14566 14567 mathmlBuilder(group, options) { 14568 var node = new mathMLTree.MathNode("mo", [makeText(group.text, group.mode)]); 14569 14570 if (group.family === "bin") { 14571 var variant = getVariant(group, options); 14572 14573 if (variant === "bold-italic") { 14574 node.setAttribute("mathvariant", variant); 14575 } 14576 } else if (group.family === "punct") { 14577 node.setAttribute("separator", "true"); 14578 } else if (group.family === "open" || group.family === "close") { 14579 // Delims built here should not stretch vertically. 14580 // See delimsizing.js for stretchy delims. 14581 node.setAttribute("stretchy", "false"); 14582 } 14583 14584 return node; 14585 } 14586 14587}); 14588 14589// "mathord" and "textord" ParseNodes created in Parser.js from symbol Groups in 14590// src/symbols.js. 14591var defaultVariant = { 14592 "mi": "italic", 14593 "mn": "normal", 14594 "mtext": "normal" 14595}; 14596defineFunctionBuilders({ 14597 type: "mathord", 14598 14599 htmlBuilder(group, options) { 14600 return buildCommon.makeOrd(group, options, "mathord"); 14601 }, 14602 14603 mathmlBuilder(group, options) { 14604 var node = new mathMLTree.MathNode("mi", [makeText(group.text, group.mode, options)]); 14605 var variant = getVariant(group, options) || "italic"; 14606 14607 if (variant !== defaultVariant[node.type]) { 14608 node.setAttribute("mathvariant", variant); 14609 } 14610 14611 return node; 14612 } 14613 14614}); 14615defineFunctionBuilders({ 14616 type: "textord", 14617 14618 htmlBuilder(group, options) { 14619 return buildCommon.makeOrd(group, options, "textord"); 14620 }, 14621 14622 mathmlBuilder(group, options) { 14623 var text = makeText(group.text, group.mode, options); 14624 var variant = getVariant(group, options) || "normal"; 14625 var node; 14626 14627 if (group.mode === 'text') { 14628 node = new mathMLTree.MathNode("mtext", [text]); 14629 } else if (/[0-9]/.test(group.text)) { 14630 node = new mathMLTree.MathNode("mn", [text]); 14631 } else if (group.text === "\\prime") { 14632 node = new mathMLTree.MathNode("mo", [text]); 14633 } else { 14634 node = new mathMLTree.MathNode("mi", [text]); 14635 } 14636 14637 if (variant !== defaultVariant[node.type]) { 14638 node.setAttribute("mathvariant", variant); 14639 } 14640 14641 return node; 14642 } 14643 14644}); 14645 14646var cssSpace = { 14647 "\\nobreak": "nobreak", 14648 "\\allowbreak": "allowbreak" 14649}; // A lookup table to determine whether a spacing function/symbol should be 14650// treated like a regular space character. If a symbol or command is a key 14651// in this table, then it should be a regular space character. Furthermore, 14652// the associated value may have a `className` specifying an extra CSS class 14653// to add to the created `span`. 14654 14655var regularSpace = { 14656 " ": {}, 14657 "\\ ": {}, 14658 "~": { 14659 className: "nobreak" 14660 }, 14661 "\\space": {}, 14662 "\\nobreakspace": { 14663 className: "nobreak" 14664 } 14665}; // ParseNode<"spacing"> created in Parser.js from the "spacing" symbol Groups in 14666// src/symbols.js. 14667 14668defineFunctionBuilders({ 14669 type: "spacing", 14670 14671 htmlBuilder(group, options) { 14672 if (regularSpace.hasOwnProperty(group.text)) { 14673 var className = regularSpace[group.text].className || ""; // Spaces are generated by adding an actual space. Each of these 14674 // things has an entry in the symbols table, so these will be turned 14675 // into appropriate outputs. 14676 14677 if (group.mode === "text") { 14678 var ord = buildCommon.makeOrd(group, options, "textord"); 14679 ord.classes.push(className); 14680 return ord; 14681 } else { 14682 return buildCommon.makeSpan(["mspace", className], [buildCommon.mathsym(group.text, group.mode, options)], options); 14683 } 14684 } else if (cssSpace.hasOwnProperty(group.text)) { 14685 // Spaces based on just a CSS class. 14686 return buildCommon.makeSpan(["mspace", cssSpace[group.text]], [], options); 14687 } else { 14688 throw new ParseError("Unknown type of space \"" + group.text + "\""); 14689 } 14690 }, 14691 14692 mathmlBuilder(group, options) { 14693 var node; 14694 14695 if (regularSpace.hasOwnProperty(group.text)) { 14696 node = new mathMLTree.MathNode("mtext", [new mathMLTree.TextNode("\u00a0")]); 14697 } else if (cssSpace.hasOwnProperty(group.text)) { 14698 // CSS-based MathML spaces (\nobreak, \allowbreak) are ignored 14699 return new mathMLTree.MathNode("mspace"); 14700 } else { 14701 throw new ParseError("Unknown type of space \"" + group.text + "\""); 14702 } 14703 14704 return node; 14705 } 14706 14707}); 14708 14709var pad = () => { 14710 var padNode = new mathMLTree.MathNode("mtd", []); 14711 padNode.setAttribute("width", "50%"); 14712 return padNode; 14713}; 14714 14715defineFunctionBuilders({ 14716 type: "tag", 14717 14718 mathmlBuilder(group, options) { 14719 var table = new mathMLTree.MathNode("mtable", [new mathMLTree.MathNode("mtr", [pad(), new mathMLTree.MathNode("mtd", [buildExpressionRow(group.body, options)]), pad(), new mathMLTree.MathNode("mtd", [buildExpressionRow(group.tag, options)])])]); 14720 table.setAttribute("width", "100%"); 14721 return table; // TODO: Left-aligned tags. 14722 // Currently, the group and options passed here do not contain 14723 // enough info to set tag alignment. `leqno` is in Settings but it is 14724 // not passed to Options. On the HTML side, leqno is 14725 // set by a CSS class applied in buildTree.js. That would have worked 14726 // in MathML if browsers supported <mlabeledtr>. Since they don't, we 14727 // need to rewrite the way this function is called. 14728 } 14729 14730}); 14731 14732var textFontFamilies = { 14733 "\\text": undefined, 14734 "\\textrm": "textrm", 14735 "\\textsf": "textsf", 14736 "\\texttt": "texttt", 14737 "\\textnormal": "textrm" 14738}; 14739var textFontWeights = { 14740 "\\textbf": "textbf", 14741 "\\textmd": "textmd" 14742}; 14743var textFontShapes = { 14744 "\\textit": "textit", 14745 "\\textup": "textup" 14746}; 14747 14748var optionsWithFont = (group, options) => { 14749 var font = group.font; // Checks if the argument is a font family or a font style. 14750 14751 if (!font) { 14752 return options; 14753 } else if (textFontFamilies[font]) { 14754 return options.withTextFontFamily(textFontFamilies[font]); 14755 } else if (textFontWeights[font]) { 14756 return options.withTextFontWeight(textFontWeights[font]); 14757 } else if (font === "\\emph") { 14758 return options.fontShape === "textit" ? options.withTextFontShape("textup") : options.withTextFontShape("textit"); 14759 } 14760 14761 return options.withTextFontShape(textFontShapes[font]); 14762}; 14763 14764defineFunction({ 14765 type: "text", 14766 names: [// Font families 14767 "\\text", "\\textrm", "\\textsf", "\\texttt", "\\textnormal", // Font weights 14768 "\\textbf", "\\textmd", // Font Shapes 14769 "\\textit", "\\textup", "\\emph"], 14770 props: { 14771 numArgs: 1, 14772 argTypes: ["text"], 14773 allowedInArgument: true, 14774 allowedInText: true 14775 }, 14776 14777 handler(_ref, args) { 14778 var { 14779 parser, 14780 funcName 14781 } = _ref; 14782 var body = args[0]; 14783 return { 14784 type: "text", 14785 mode: parser.mode, 14786 body: ordargument(body), 14787 font: funcName 14788 }; 14789 }, 14790 14791 htmlBuilder(group, options) { 14792 var newOptions = optionsWithFont(group, options); 14793 var inner = buildExpression$1(group.body, newOptions, true); 14794 return buildCommon.makeSpan(["mord", "text"], inner, newOptions); 14795 }, 14796 14797 mathmlBuilder(group, options) { 14798 var newOptions = optionsWithFont(group, options); 14799 return buildExpressionRow(group.body, newOptions); 14800 } 14801 14802}); 14803 14804defineFunction({ 14805 type: "underline", 14806 names: ["\\underline"], 14807 props: { 14808 numArgs: 1, 14809 allowedInText: true 14810 }, 14811 14812 handler(_ref, args) { 14813 var { 14814 parser 14815 } = _ref; 14816 return { 14817 type: "underline", 14818 mode: parser.mode, 14819 body: args[0] 14820 }; 14821 }, 14822 14823 htmlBuilder(group, options) { 14824 // Underlines are handled in the TeXbook pg 443, Rule 10. 14825 // Build the inner group. 14826 var innerGroup = buildGroup$1(group.body, options); // Create the line to go below the body 14827 14828 var line = buildCommon.makeLineSpan("underline-line", options); // Generate the vlist, with the appropriate kerns 14829 14830 var defaultRuleThickness = options.fontMetrics().defaultRuleThickness; 14831 var vlist = buildCommon.makeVList({ 14832 positionType: "top", 14833 positionData: innerGroup.height, 14834 children: [{ 14835 type: "kern", 14836 size: defaultRuleThickness 14837 }, { 14838 type: "elem", 14839 elem: line 14840 }, { 14841 type: "kern", 14842 size: 3 * defaultRuleThickness 14843 }, { 14844 type: "elem", 14845 elem: innerGroup 14846 }] 14847 }, options); 14848 return buildCommon.makeSpan(["mord", "underline"], [vlist], options); 14849 }, 14850 14851 mathmlBuilder(group, options) { 14852 var operator = new mathMLTree.MathNode("mo", [new mathMLTree.TextNode("\u203e")]); 14853 operator.setAttribute("stretchy", "true"); 14854 var node = new mathMLTree.MathNode("munder", [buildGroup(group.body, options), operator]); 14855 node.setAttribute("accentunder", "true"); 14856 return node; 14857 } 14858 14859}); 14860 14861defineFunction({ 14862 type: "vcenter", 14863 names: ["\\vcenter"], 14864 props: { 14865 numArgs: 1, 14866 argTypes: ["original"], 14867 // In LaTeX, \vcenter can act only on a box. 14868 allowedInText: false 14869 }, 14870 14871 handler(_ref, args) { 14872 var { 14873 parser 14874 } = _ref; 14875 return { 14876 type: "vcenter", 14877 mode: parser.mode, 14878 body: args[0] 14879 }; 14880 }, 14881 14882 htmlBuilder(group, options) { 14883 var body = buildGroup$1(group.body, options); 14884 var axisHeight = options.fontMetrics().axisHeight; 14885 var dy = 0.5 * (body.height - axisHeight - (body.depth + axisHeight)); 14886 return buildCommon.makeVList({ 14887 positionType: "shift", 14888 positionData: dy, 14889 children: [{ 14890 type: "elem", 14891 elem: body 14892 }] 14893 }, options); 14894 }, 14895 14896 mathmlBuilder(group, options) { 14897 // There is no way to do this in MathML. 14898 // Write a class as a breadcrumb in case some post-processor wants 14899 // to perform a vcenter adjustment. 14900 return new mathMLTree.MathNode("mpadded", [buildGroup(group.body, options)], ["vcenter"]); 14901 } 14902 14903}); 14904 14905defineFunction({ 14906 type: "verb", 14907 names: ["\\verb"], 14908 props: { 14909 numArgs: 0, 14910 allowedInText: true 14911 }, 14912 14913 handler(context, args, optArgs) { 14914 // \verb and \verb* are dealt with directly in Parser.js. 14915 // If we end up here, it's because of a failure to match the two delimiters 14916 // in the regex in Lexer.js. LaTeX raises the following error when \verb is 14917 // terminated by end of line (or file). 14918 throw new ParseError("\\verb ended by end of line instead of matching delimiter"); 14919 }, 14920 14921 htmlBuilder(group, options) { 14922 var text = makeVerb(group); 14923 var body = []; // \verb enters text mode and therefore is sized like \textstyle 14924 14925 var newOptions = options.havingStyle(options.style.text()); 14926 14927 for (var i = 0; i < text.length; i++) { 14928 var c = text[i]; 14929 14930 if (c === '~') { 14931 c = '\\textasciitilde'; 14932 } 14933 14934 body.push(buildCommon.makeSymbol(c, "Typewriter-Regular", group.mode, newOptions, ["mord", "texttt"])); 14935 } 14936 14937 return buildCommon.makeSpan(["mord", "text"].concat(newOptions.sizingClasses(options)), buildCommon.tryCombineChars(body), newOptions); 14938 }, 14939 14940 mathmlBuilder(group, options) { 14941 var text = new mathMLTree.TextNode(makeVerb(group)); 14942 var node = new mathMLTree.MathNode("mtext", [text]); 14943 node.setAttribute("mathvariant", "monospace"); 14944 return node; 14945 } 14946 14947}); 14948/** 14949 * Converts verb group into body string. 14950 * 14951 * \verb* replaces each space with an open box \u2423 14952 * \verb replaces each space with a no-break space \xA0 14953 */ 14954 14955var makeVerb = group => group.body.replace(/ /g, group.star ? '\u2423' : '\xA0'); 14956 14957/** Include this to ensure that all functions are defined. */ 14958var functions = _functions; 14959 14960/** 14961 * The Lexer class handles tokenizing the input in various ways. Since our 14962 * parser expects us to be able to backtrack, the lexer allows lexing from any 14963 * given starting point. 14964 * 14965 * Its main exposed function is the `lex` function, which takes a position to 14966 * lex from and a type of token to lex. It defers to the appropriate `_innerLex` 14967 * function. 14968 * 14969 * The various `_innerLex` functions perform the actual lexing of different 14970 * kinds. 14971 */ 14972 14973/* The following tokenRegex 14974 * - matches typical whitespace (but not NBSP etc.) using its first group 14975 * - does not match any control character \x00-\x1f except whitespace 14976 * - does not match a bare backslash 14977 * - matches any ASCII character except those just mentioned 14978 * - does not match the BMP private use area \uE000-\uF8FF 14979 * - does not match bare surrogate code units 14980 * - matches any BMP character except for those just described 14981 * - matches any valid Unicode surrogate pair 14982 * - matches a backslash followed by one or more whitespace characters 14983 * - matches a backslash followed by one or more letters then whitespace 14984 * - matches a backslash followed by any BMP character 14985 * Capturing groups: 14986 * [1] regular whitespace 14987 * [2] backslash followed by whitespace 14988 * [3] anything else, which may include: 14989 * [4] left character of \verb* 14990 * [5] left character of \verb 14991 * [6] backslash followed by word, excluding any trailing whitespace 14992 * Just because the Lexer matches something doesn't mean it's valid input: 14993 * If there is no matching function or symbol definition, the Parser will 14994 * still reject the input. 14995 */ 14996var spaceRegexString = "[ \r\n\t]"; 14997var controlWordRegexString = "\\\\[a-zA-Z@]+"; 14998var controlSymbolRegexString = "\\\\[^\uD800-\uDFFF]"; 14999var controlWordWhitespaceRegexString = "(" + controlWordRegexString + ")" + spaceRegexString + "*"; 15000var controlSpaceRegexString = "\\\\(\n|[ \r\t]+\n?)[ \r\t]*"; 15001var combiningDiacriticalMarkString = "[\u0300-\u036f]"; 15002var combiningDiacriticalMarksEndRegex = new RegExp(combiningDiacriticalMarkString + "+$"); 15003var tokenRegexString = "(" + spaceRegexString + "+)|" + ( // whitespace 15004controlSpaceRegexString + "|") + // \whitespace 15005"([!-\\[\\]-\u2027\u202A-\uD7FF\uF900-\uFFFF]" + ( // single codepoint 15006combiningDiacriticalMarkString + "*") + // ...plus accents 15007"|[\uD800-\uDBFF][\uDC00-\uDFFF]" + ( // surrogate pair 15008combiningDiacriticalMarkString + "*") + // ...plus accents 15009"|\\\\verb\\*([^]).*?\\4" + // \verb* 15010"|\\\\verb([^*a-zA-Z]).*?\\5" + ( // \verb unstarred 15011"|" + controlWordWhitespaceRegexString) + ( // \macroName + spaces 15012"|" + controlSymbolRegexString + ")"); // \\, \', etc. 15013 15014/** Main Lexer class */ 15015 15016class Lexer { 15017 // Category codes. The lexer only supports comment characters (14) for now. 15018 // MacroExpander additionally distinguishes active (13). 15019 constructor(input, settings) { 15020 this.input = void 0; 15021 this.settings = void 0; 15022 this.tokenRegex = void 0; 15023 this.catcodes = void 0; 15024 // Separate accents from characters 15025 this.input = input; 15026 this.settings = settings; 15027 this.tokenRegex = new RegExp(tokenRegexString, 'g'); 15028 this.catcodes = { 15029 "%": 14, 15030 // comment character 15031 "~": 13 // active character 15032 15033 }; 15034 } 15035 15036 setCatcode(char, code) { 15037 this.catcodes[char] = code; 15038 } 15039 /** 15040 * This function lexes a single token. 15041 */ 15042 15043 15044 lex() { 15045 var input = this.input; 15046 var pos = this.tokenRegex.lastIndex; 15047 15048 if (pos === input.length) { 15049 return new Token("EOF", new SourceLocation(this, pos, pos)); 15050 } 15051 15052 var match = this.tokenRegex.exec(input); 15053 15054 if (match === null || match.index !== pos) { 15055 throw new ParseError("Unexpected character: '" + input[pos] + "'", new Token(input[pos], new SourceLocation(this, pos, pos + 1))); 15056 } 15057 15058 var text = match[6] || match[3] || (match[2] ? "\\ " : " "); 15059 15060 if (this.catcodes[text] === 14) { 15061 // comment character 15062 var nlIndex = input.indexOf('\n', this.tokenRegex.lastIndex); 15063 15064 if (nlIndex === -1) { 15065 this.tokenRegex.lastIndex = input.length; // EOF 15066 15067 this.settings.reportNonstrict("commentAtEnd", "% comment has no terminating newline; LaTeX would " + "fail because of commenting the end of math mode (e.g. $)"); 15068 } else { 15069 this.tokenRegex.lastIndex = nlIndex + 1; 15070 } 15071 15072 return this.lex(); 15073 } 15074 15075 return new Token(text, new SourceLocation(this, pos, this.tokenRegex.lastIndex)); 15076 } 15077 15078} 15079 15080/**
15081 * A `Namespace` refers to a space of nameable things like macros or lengths, 15082 * which can be `set` either globally or local to a nested group, using an 15083 * undo stack similar to how TeX implements this functionality. 15084 * Performance-wise, `get` and local `set` take constant time, while global 15085 * `set` takes time proportional to the depth of group nesting. 15086 */ 15087class Namespace { 15088 /** 15089 * Both arguments are optional. The first argument is an object of 15090 * built-in mappings which never change. The second argument is an object 15091 * of initial (global-level) mappings, which will constantly change 15092 * according to any global/top-level `set`s done. 15093 */ 15094 constructor(builtins, globalMacros) { 15095 if (builtins === void 0) { 15096 builtins = {}; 15097 } 15098 15099 if (globalMacros === void 0) { 15100 globalMacros = {}; 15101 } 15102 15103 this.current = void 0; 15104 this.builtins = void 0; 15105 this.undefStack = void 0; 15106 this.current = globalMacros; 15107 this.builtins = builtins; 15108 this.undefStack = []; 15109 } 15110 /** 15111 * Start a new nested group, affecting future local `set`s. 15112 */ 15113 15114 15115 beginGroup() { 15116 this.undefStack.push({}); 15117 } 15118 /** 15119 * End current nested group, restoring values before the group began. 15120 */ 15121 15122 15123 endGroup() { 15124 if (this.undefStack.length === 0) { 15125 throw new ParseError("Unbalanced namespace destruction: attempt " + "to pop global namespace; please report this as a bug"); 15126 } 15127 15128 var undefs = this.undefStack.pop(); 15129 15130 for (var undef in undefs) {
vendor: 7,756 bytes, lines 15131-15409
15131 if (undefs.hasOwnProperty(undef)) { 15132 if (undefs[undef] == null) { 15133 delete this.current[undef]; 15134 } else { 15135 this.current[undef] = undefs[undef]; 15136 } 15137 } 15138 } 15139 } 15140 /** 15141 * Ends all currently nested groups (if any), restoring values before the 15142 * groups began. Useful in case of an error in the middle of parsing. 15143 */ 15144 15145 15146 endGroups() { 15147 while (this.undefStack.length > 0) { 15148 this.endGroup(); 15149 } 15150 } 15151 /** 15152 * Detect whether `name` has a definition. Equivalent to 15153 * `get(name) != null`. 15154 */ 15155 15156 15157 has(name) { 15158 return this.current.hasOwnProperty(name) || this.builtins.hasOwnProperty(name); 15159 } 15160 /** 15161 * Get the current value of a name, or `undefined` if there is no value. 15162 * 15163 * Note: Do not use `if (namespace.get(...))` to detect whether a macro 15164 * is defined, as the definition may be the empty string which evaluates 15165 * to `false` in JavaScript. Use `if (namespace.get(...) != null)` or 15166 * `if (namespace.has(...))`. 15167 */ 15168 15169 15170 get(name) { 15171 if (this.current.hasOwnProperty(name)) { 15172 return this.current[name]; 15173 } else { 15174 return this.builtins[name]; 15175 } 15176 } 15177 /** 15178 * Set the current value of a name, and optionally set it globally too. 15179 * Local set() sets the current value and (when appropriate) adds an undo 15180 * operation to the undo stack. Global set() may change the undo 15181 * operation at every level, so takes time linear in their number. 15182 * A value of undefined means to delete existing definitions. 15183 */ 15184 15185 15186 set(name, value, global) { 15187 if (global === void 0) { 15188 global = false; 15189 } 15190 15191 if (global) { 15192 // Global set is equivalent to setting in all groups. Simulate this 15193 // by destroying any undos currently scheduled for this name, 15194 // and adding an undo with the *new* value (in case it later gets 15195 // locally reset within this environment). 15196 for (var i = 0; i < this.undefStack.length; i++) { 15197 delete this.undefStack[i][name]; 15198 } 15199 15200 if (this.undefStack.length > 0) { 15201 this.undefStack[this.undefStack.length - 1][name] = value; 15202 } 15203 } else { 15204 // Undo this set at end of this group (possibly to `undefined`), 15205 // unless an undo is already in place, in which case that older 15206 // value is the correct one. 15207 var top = this.undefStack[this.undefStack.length - 1]; 15208 15209 if (top && !top.hasOwnProperty(name)) { 15210 top[name] = this.current[name]; 15211 } 15212 } 15213 15214 if (value == null) { 15215 delete this.current[name]; 15216 } else { 15217 this.current[name] = value; 15218 } 15219 } 15220 15221} 15222 15223/** 15224 * Predefined macros for KaTeX. 15225 * This can be used to define some commands in terms of others. 15226 */ 15227var macros = _macros; 15228// macro tools 15229 15230defineMacro("\\noexpand", function (context) { 15231 // The expansion is the token itself; but that token is interpreted 15232 // as if its meaning were â\relaxâ if it is a control sequence that 15233 // would ordinarily be expanded by TeXâs expansion rules. 15234 var t = context.popToken(); 15235 15236 if (context.isExpandable(t.text)) { 15237 t.noexpand = true; 15238 t.treatAsRelax = true; 15239 } 15240 15241 return { 15242 tokens: [t], 15243 numArgs: 0 15244 }; 15245}); 15246defineMacro("\\expandafter", function (context) { 15247 // TeX first reads the token that comes immediately after \expandafter, 15248 // without expanding it; letâs call this token t. Then TeX reads the 15249 // token that comes after t (and possibly more tokens, if that token 15250 // has an argument), replacing it by its expansion. Finally TeX puts 15251 // t back in front of that expansion. 15252 var t = context.popToken(); 15253 context.expandOnce(true); // expand only an expandable token 15254 15255 return { 15256 tokens: [t], 15257 numArgs: 0 15258 }; 15259}); // LaTeX's \@firstoftwo{#1}{#2} expands to #1, skipping #2 15260// TeX source: \long\def\@firstoftwo#1#2{#1} 15261 15262defineMacro("\\@firstoftwo", function (context) { 15263 var args = context.consumeArgs(2); 15264 return { 15265 tokens: args[0], 15266 numArgs: 0 15267 }; 15268}); // LaTeX's \@secondoftwo{#1}{#2} expands to #2, skipping #1 15269// TeX source: \long\def\@secondoftwo#1#2{#2} 15270 15271defineMacro("\\@secondoftwo", function (context) { 15272 var args = context.consumeArgs(2); 15273 return { 15274 tokens: args[1], 15275 numArgs: 0 15276 }; 15277}); // LaTeX's \@ifnextchar{#1}{#2}{#3} looks ahead to the next (unexpanded) 15278// symbol that isn't a space, consuming any spaces but not consuming the 15279// first nonspace character. If that nonspace character matches #1, then 15280// the macro expands to #2; otherwise, it expands to #3. 15281 15282defineMacro("\\@ifnextchar", function (context) { 15283 var args = context.consumeArgs(3); // symbol, if, else 15284 15285 context.consumeSpaces(); 15286 var nextToken = context.future(); 15287 15288 if (args[0].length === 1 && args[0][0].text === nextToken.text) { 15289 return { 15290 tokens: args[1], 15291 numArgs: 0 15292 }; 15293 } else { 15294 return { 15295 tokens: args[2], 15296 numArgs: 0 15297 }; 15298 } 15299}); // LaTeX's \@ifstar{#1}{#2} looks ahead to the next (unexpanded) symbol. 15300// If it is `*`, then it consumes the symbol, and the macro expands to #1; 15301// otherwise, the macro expands to #2 (without consuming the symbol). 15302// TeX source: \def\@ifstar#1{\@ifnextchar *{\@firstoftwo{#1}}} 15303 15304defineMacro("\\@ifstar", "\\@ifnextchar *{\\@firstoftwo{#1}}"); // LaTeX's \TextOrMath{#1}{#2} expands to #1 in text mode, #2 in math mode 15305 15306defineMacro("\\TextOrMath", function (context) { 15307 var args = context.consumeArgs(2); 15308 15309 if (context.mode === 'text') { 15310 return { 15311 tokens: args[0], 15312 numArgs: 0 15313 }; 15314 } else { 15315 return { 15316 tokens: args[1], 15317 numArgs: 0 15318 }; 15319 } 15320}); // Lookup table for parsing numbers in base 8 through 16 15321 15322var digitToNumber = { 15323 "0": 0, 15324 "1": 1, 15325 "2": 2, 15326 "3": 3, 15327 "4": 4, 15328 "5": 5, 15329 "6": 6, 15330 "7": 7, 15331 "8": 8, 15332 "9": 9, 15333 "a": 10, 15334 "A": 10, 15335 "b": 11, 15336 "B": 11, 15337 "c": 12, 15338 "C": 12, 15339 "d": 13, 15340 "D": 13, 15341 "e": 14, 15342 "E": 14, 15343 "f": 15, 15344 "F": 15 15345}; // TeX \char makes a literal character (catcode 12) using the following forms: 15346// (see The TeXBook, p. 43) 15347// \char123 -- decimal 15348// \char'123 -- octal 15349// \char"123 -- hex 15350// \char`x -- character that can be written (i.e. isn't active) 15351// \char`\x -- character that cannot be written (e.g. %) 15352// These all refer to characters from the font, so we turn them into special 15353// calls to a function \@char dealt with in the Parser. 15354 15355defineMacro("\\char", function (context) { 15356 var token = context.popToken(); 15357 var base; 15358 var number = ''; 15359 15360 if (token.text === "'") { 15361 base = 8; 15362 token = context.popToken(); 15363 } else if (token.text === '"') { 15364 base = 16; 15365 token = context.popToken(); 15366 } else if (token.text === "`") { 15367 token = context.popToken(); 15368 15369 if (token.text[0] === "\\") { 15370 number = token.text.charCodeAt(1); 15371 } else if (token.text === "EOF") { 15372 throw new ParseError("\\char` missing argument"); 15373 } else { 15374 number = token.text.charCodeAt(0); 15375 } 15376 } else { 15377 base = 10; 15378 } 15379 15380 if (base) { 15381 // Parse a number in the given base, starting with first `token`. 15382 number = digitToNumber[token.text]; 15383 15384 if (number == null || number >= base) { 15385 throw new ParseError("Invalid base-" + base + " digit " + token.text); 15386 } 15387 15388 var digit; 15389 15390 while ((digit = digitToNumber[context.future().text]) != null && digit < base) { 15391 number *= base; 15392 number += digit; 15393 context.popToken(); 15394 } 15395 } 15396 15397 return "\\@char{" + number + "}"; 15398}); // \newcommand{\macro}[args]{definition} 15399// \renewcommand{\macro}[args]{definition} 15400// TODO: Optional arguments: \newcommand{\macro}[args][default]{definition} 15401 15402var newcommand = (context, existsOK, nonexistsOK, skipIfExists) => { 15403 var arg = context.consumeArg().tokens; 15404 15405 if (arg.length !== 1) { 15406 throw new ParseError("\\newcommand's first argument must be a macro name"); 15407 } 15408 15409 var name = arg[0].text;
vendor: 4,885 bytes, lines 15410-15538
15410 var exists = context.isDefined(name); 15411 15412 if (exists && !existsOK) { 15413 throw new ParseError("\\newcommand{" + name + "} attempting to redefine " + (name + "; use \\renewcommand")); 15414 } 15415 15416 if (!exists && !nonexistsOK) { 15417 throw new ParseError("\\renewcommand{" + name + "} when command " + name + " " + "does not yet exist; use \\newcommand"); 15418 } 15419 15420 var numArgs = 0; 15421 arg = context.consumeArg().tokens; 15422 15423 if (arg.length === 1 && arg[0].text === "[") { 15424 var argText = ''; 15425 var token = context.expandNextToken(); 15426 15427 while (token.text !== "]" && token.text !== "EOF") { 15428 // TODO: Should properly expand arg, e.g., ignore {}s 15429 argText += token.text; 15430 token = context.expandNextToken(); 15431 } 15432 15433 if (!argText.match(/^\s*[0-9]+\s*$/)) { 15434 throw new ParseError("Invalid number of arguments: " + argText); 15435 } 15436 15437 numArgs = parseInt(argText); 15438 arg = context.consumeArg().tokens; 15439 } 15440 15441 if (!(exists && skipIfExists)) { 15442 // Final arg is the expansion of the macro 15443 context.macros.set(name, { 15444 tokens: arg, 15445 numArgs 15446 }); 15447 } 15448 15449 return ''; 15450}; 15451 15452defineMacro("\\newcommand", context => newcommand(context, false, true, false)); 15453defineMacro("\\renewcommand", context => newcommand(context, true, false, false)); 15454defineMacro("\\providecommand", context => newcommand(context, true, true, true)); // terminal (console) tools 15455 15456defineMacro("\\message", context => { 15457 var arg = context.consumeArgs(1)[0]; // eslint-disable-next-line no-console 15458 15459 console.log(arg.reverse().map(token => token.text).join("")); 15460 return ''; 15461}); 15462defineMacro("\\errmessage", context => { 15463 var arg = context.consumeArgs(1)[0]; // eslint-disable-next-line no-console 15464 15465 console.error(arg.reverse().map(token => token.text).join("")); 15466 return ''; 15467}); 15468defineMacro("\\show", context => { 15469 var tok = context.popToken(); 15470 var name = tok.text; // eslint-disable-next-line no-console 15471 15472 console.log(tok, context.macros.get(name), functions[name], symbols.math[name], symbols.text[name]); 15473 return ''; 15474}); ////////////////////////////////////////////////////////////////////// 15475// Grouping 15476// \let\bgroup={ \let\egroup=} 15477 15478defineMacro("\\bgroup", "{"); 15479defineMacro("\\egroup", "}"); // Symbols from latex.ltx: 15480// \def~{\nobreakspace{}} 15481// \def\lq{`} 15482// \def\rq{'} 15483// \def \aa {\r a} 15484// \def \AA {\r A} 15485 15486defineMacro("~", "\\nobreakspace"); 15487defineMacro("\\lq", "`"); 15488defineMacro("\\rq", "'"); 15489defineMacro("\\aa", "\\r a"); 15490defineMacro("\\AA", "\\r A"); // Copyright (C) and registered (R) symbols. Use raw symbol in MathML. 15491// \DeclareTextCommandDefault{\textcopyright}{\textcircled{c}} 15492// \DeclareTextCommandDefault{\textregistered}{\textcircled{% 15493// \check@mathfonts\fontsize\sf@size\z@\math@fontsfalse\selectfont R}} 15494// \DeclareRobustCommand{\copyright}{% 15495// \ifmmode{\nfss@text{\textcopyright}}\else\textcopyright\fi} 15496 15497defineMacro("\\textcopyright", "\\html@mathml{\\textcircled{c}}{\\char`©}"); 15498defineMacro("\\copyright", "\\TextOrMath{\\textcopyright}{\\text{\\textcopyright}}"); 15499defineMacro("\\textregistered", "\\html@mathml{\\textcircled{\\scriptsize R}}{\\char`®}"); // Characters omitted from Unicode range 1D400â1D7FF 15500 15501defineMacro("\u212C", "\\mathscr{B}"); // script 15502 15503defineMacro("\u2130", "\\mathscr{E}"); 15504defineMacro("\u2131", "\\mathscr{F}"); 15505defineMacro("\u210B", "\\mathscr{H}"); 15506defineMacro("\u2110", "\\mathscr{I}"); 15507defineMacro("\u2112", "\\mathscr{L}"); 15508defineMacro("\u2133", "\\mathscr{M}"); 15509defineMacro("\u211B", "\\mathscr{R}"); 15510defineMacro("\u212D", "\\mathfrak{C}"); // Fraktur 15511 15512defineMacro("\u210C", "\\mathfrak{H}"); 15513defineMacro("\u2128", "\\mathfrak{Z}"); // Define \Bbbk with a macro that works in both HTML and MathML. 15514 15515defineMacro("\\Bbbk", "\\Bbb{k}"); // Unicode middle dot 15516// The KaTeX fonts do not contain U+00B7. Instead, \cdotp displays 15517// the dot at U+22C5 and gives it punct spacing. 15518 15519defineMacro("\u00b7", "\\cdotp"); // \llap and \rlap render their contents in text mode 15520 15521defineMacro("\\llap", "\\mathllap{\\textrm{#1}}"); 15522defineMacro("\\rlap", "\\mathrlap{\\textrm{#1}}"); 15523defineMacro("\\clap", "\\mathclap{\\textrm{#1}}"); // \mathstrut from the TeXbook, p 360 15524 15525defineMacro("\\mathstrut", "\\vphantom{(}"); // \underbar from TeXbook p 353 15526 15527defineMacro("\\underbar", "\\underline{\\text{#1}}"); // \not is defined by base/fontmath.ltx via 15528// \DeclareMathSymbol{\not}{\mathrel}{symbols}{"36} 15529// It's thus treated like a \mathrel, but defined by a symbol that has zero 15530// width but extends to the right. We use \rlap to get that spacing. 15531// For MathML we write U+0338 here. buildMathML.js will then do the overlay. 15532 15533defineMacro("\\not", '\\html@mathml{\\mathrel{\\mathrlap\\@not}}{\\char"338}'); // Negated symbols from base/fontmath.ltx: 15534// \def\neq{\not=} \let\ne=\neq 15535// \DeclareRobustCommand 15536// \notin{\mathrel{\m@th\mathpalette\c@ncel\in}} 15537// \def\c@ncel#1#2{\m@th\ooalign{$\hfil#1\mkern1mu/\hfil$\crcr$#1#2$}} 15538
vendor: 6,725 bytes, lines 15539-15695
15539defineMacro("\\neq", "\\html@mathml{\\mathrel{\\not=}}{\\mathrel{\\char`â }}"); 15540defineMacro("\\ne", "\\neq"); 15541defineMacro("\u2260", "\\neq"); 15542defineMacro("\\notin", "\\html@mathml{\\mathrel{{\\in}\\mathllap{/\\mskip1mu}}}" + "{\\mathrel{\\char`â}}"); 15543defineMacro("\u2209", "\\notin"); // Unicode stacked relations 15544 15545defineMacro("\u2258", "\\html@mathml{" + "\\mathrel{=\\kern{-1em}\\raisebox{0.4em}{$\\scriptsize\\frown$}}" + "}{\\mathrel{\\char`\u2258}}"); 15546defineMacro("\u2259", "\\html@mathml{\\stackrel{\\tiny\\wedge}{=}}{\\mathrel{\\char`\u2258}}"); 15547defineMacro("\u225A", "\\html@mathml{\\stackrel{\\tiny\\vee}{=}}{\\mathrel{\\char`\u225A}}"); 15548defineMacro("\u225B", "\\html@mathml{\\stackrel{\\scriptsize\\star}{=}}" + "{\\mathrel{\\char`\u225B}}"); 15549defineMacro("\u225D", "\\html@mathml{\\stackrel{\\tiny\\mathrm{def}}{=}}" + "{\\mathrel{\\char`\u225D}}"); 15550defineMacro("\u225E", "\\html@mathml{\\stackrel{\\tiny\\mathrm{m}}{=}}" + "{\\mathrel{\\char`\u225E}}"); 15551defineMacro("\u225F", "\\html@mathml{\\stackrel{\\tiny?}{=}}{\\mathrel{\\char`\u225F}}"); // Misc Unicode 15552 15553defineMacro("\u27C2", "\\perp"); 15554defineMacro("\u203C", "\\mathclose{!\\mkern-0.8mu!}"); 15555defineMacro("\u220C", "\\notni"); 15556defineMacro("\u231C", "\\ulcorner"); 15557defineMacro("\u231D", "\\urcorner"); 15558defineMacro("\u231E", "\\llcorner"); 15559defineMacro("\u231F", "\\lrcorner"); 15560defineMacro("\u00A9", "\\copyright"); 15561defineMacro("\u00AE", "\\textregistered"); 15562defineMacro("\uFE0F", "\\textregistered"); // The KaTeX fonts have corners at codepoints that don't match Unicode. 15563// For MathML purposes, use the Unicode code point. 15564 15565defineMacro("\\ulcorner", "\\html@mathml{\\@ulcorner}{\\mathop{\\char\"231c}}"); 15566defineMacro("\\urcorner", "\\html@mathml{\\@urcorner}{\\mathop{\\char\"231d}}"); 15567defineMacro("\\llcorner", "\\html@mathml{\\@llcorner}{\\mathop{\\char\"231e}}"); 15568defineMacro("\\lrcorner", "\\html@mathml{\\@lrcorner}{\\mathop{\\char\"231f}}"); ////////////////////////////////////////////////////////////////////// 15569// LaTeX_2ε 15570// \vdots{\vbox{\baselineskip4\p@ \lineskiplimit\z@ 15571// \kern6\p@\hbox{.}\hbox{.}\hbox{.}}} 15572// We'll call \varvdots, which gets a glyph from symbols.js. 15573// The zero-width rule gets us an equivalent to the vertical 6pt kern. 15574 15575defineMacro("\\vdots", "{\\varvdots\\rule{0pt}{15pt}}"); 15576defineMacro("\u22ee", "\\vdots"); ////////////////////////////////////////////////////////////////////// 15577// amsmath.sty 15578// http://mirrors.concertpass.com/tex-archive/macros/latex/required/amsmath/amsmath.pdf 15579// Italic Greek capital letters. AMS defines these with \DeclareMathSymbol, 15580// but they are equivalent to \mathit{\Letter}. 15581 15582defineMacro("\\varGamma", "\\mathit{\\Gamma}"); 15583defineMacro("\\varDelta", "\\mathit{\\Delta}"); 15584defineMacro("\\varTheta", "\\mathit{\\Theta}"); 15585defineMacro("\\varLambda", "\\mathit{\\Lambda}"); 15586defineMacro("\\varXi", "\\mathit{\\Xi}"); 15587defineMacro("\\varPi", "\\mathit{\\Pi}"); 15588defineMacro("\\varSigma", "\\mathit{\\Sigma}"); 15589defineMacro("\\varUpsilon", "\\mathit{\\Upsilon}"); 15590defineMacro("\\varPhi", "\\mathit{\\Phi}"); 15591defineMacro("\\varPsi", "\\mathit{\\Psi}"); 15592defineMacro("\\varOmega", "\\mathit{\\Omega}"); //\newcommand{\substack}[1]{\subarray{c}#1\endsubarray} 15593 15594defineMacro("\\substack", "\\begin{subarray}{c}#1\\end{subarray}"); // \renewcommand{\colon}{\nobreak\mskip2mu\mathpunct{}\nonscript 15595// \mkern-\thinmuskip{:}\mskip6muplus1mu\relax} 15596 15597defineMacro("\\colon", "\\nobreak\\mskip2mu\\mathpunct{}" + "\\mathchoice{\\mkern-3mu}{\\mkern-3mu}{}{}{:}\\mskip6mu\\relax"); // \newcommand{\boxed}[1]{\fbox{\m@th$\displaystyle#1$}} 15598 15599defineMacro("\\boxed", "\\fbox{$\\displaystyle{#1}$}"); // \def\iff{\DOTSB\;\Longleftrightarrow\;} 15600// \def\implies{\DOTSB\;\Longrightarrow\;} 15601// \def\impliedby{\DOTSB\;\Longleftarrow\;} 15602 15603defineMacro("\\iff", "\\DOTSB\\;\\Longleftrightarrow\\;"); 15604defineMacro("\\implies", "\\DOTSB\\;\\Longrightarrow\\;"); 15605defineMacro("\\impliedby", "\\DOTSB\\;\\Longleftarrow\\;"); // \def\dddot#1{{\mathop{#1}\limits^{\vbox to-1.4\ex@{\kern-\tw@\ex@ 15606// \hbox{\normalfont ...}\vss}}}} 15607// We use \overset which avoids the vertical shift of \mathop. 15608 15609defineMacro("\\dddot", "{\\overset{\\raisebox{-0.1ex}{\\normalsize ...}}{#1}}"); 15610defineMacro("\\ddddot", "{\\overset{\\raisebox{-0.1ex}{\\normalsize ....}}{#1}}"); // AMSMath's automatic \dots, based on \mdots@@ macro. 15611 15612var dotsByToken = { 15613 ',': '\\dotsc', 15614 '\\not': '\\dotsb', 15615 // \keybin@ checks for the following: 15616 '+': '\\dotsb', 15617 '=': '\\dotsb', 15618 '<': '\\dotsb', 15619 '>': '\\dotsb', 15620 '-': '\\dotsb', 15621 '*': '\\dotsb', 15622 ':': '\\dotsb', 15623 // Symbols whose definition starts with \DOTSB: 15624 '\\DOTSB': '\\dotsb', 15625 '\\coprod': '\\dotsb', 15626 '\\bigvee': '\\dotsb', 15627 '\\bigwedge': '\\dotsb', 15628 '\\biguplus': '\\dotsb', 15629 '\\bigcap': '\\dotsb', 15630 '\\bigcup': '\\dotsb', 15631 '\\prod': '\\dotsb', 15632 '\\sum': '\\dotsb', 15633 '\\bigotimes': '\\dotsb', 15634 '\\bigoplus': '\\dotsb', 15635 '\\bigodot': '\\dotsb', 15636 '\\bigsqcup': '\\dotsb', 15637 '\\And': '\\dotsb', 15638 '\\longrightarrow': '\\dotsb', 15639 '\\Longrightarrow': '\\dotsb', 15640 '\\longleftarrow': '\\dotsb', 15641 '\\Longleftarrow': '\\dotsb', 15642 '\\longleftrightarrow': '\\dotsb', 15643 '\\Longleftrightarrow': '\\dotsb', 15644 '\\mapsto': '\\dotsb', 15645 '\\longmapsto': '\\dotsb', 15646 '\\hookrightarrow': '\\dotsb', 15647 '\\doteq': '\\dotsb', 15648 // Symbols whose definition starts with \mathbin: 15649 '\\mathbin': '\\dotsb', 15650 // Symbols whose definition starts with \mathrel: 15651 '\\mathrel': '\\dotsb', 15652 '\\relbar': '\\dotsb', 15653 '\\Relbar': '\\dotsb', 15654 '\\xrightarrow': '\\dotsb', 15655 '\\xleftarrow': '\\dotsb', 15656 // Symbols whose definition starts with \DOTSI: 15657 '\\DOTSI': '\\dotsi', 15658 '\\int': '\\dotsi', 15659 '\\oint': '\\dotsi', 15660 '\\iint': '\\dotsi', 15661 '\\iiint': '\\dotsi', 15662 '\\iiiint': '\\dotsi', 15663 '\\idotsint': '\\dotsi', 15664 // Symbols whose definition starts with \DOTSX: 15665 '\\DOTSX': '\\dotsx' 15666}; 15667defineMacro("\\dots", function (context) { 15668 // TODO: If used in text mode, should expand to \textellipsis. 15669 // However, in KaTeX, \textellipsis and \ldots behave the same 15670 // (in text mode), and it's unlikely we'd see any of the math commands 15671 // that affect the behavior of \dots when in text mode. So fine for now 15672 // (until we support \ifmmode ... \else ... \fi). 15673 var thedots = '\\dotso'; 15674 var next = context.expandAfterFuture().text; 15675 15676 if (next in dotsByToken) { 15677 thedots = dotsByToken[next]; 15678 } else if (next.slice(0, 4) === '\\not') { 15679 thedots = '\\dotsb'; 15680 } else if (next in symbols.math) { 15681 if (utils.contains(['bin', 'rel'], symbols.math[next].group)) { 15682 thedots = '\\dotsb'; 15683 } 15684 } 15685 15686 return thedots; 15687}); 15688var spaceAfterDots = { 15689 // \rightdelim@ checks for the following: 15690 ')': true, 15691 ']': true, 15692 '\\rbrack': true, 15693 '\\}': true, 15694 '\\rbrace': true, 15695 '\\rangle': true,
vendor: 10,049 bytes, lines 15696-15896
15696 '\\rceil': true, 15697 '\\rfloor': true, 15698 '\\rgroup': true, 15699 '\\rmoustache': true, 15700 '\\right': true, 15701 '\\bigr': true, 15702 '\\biggr': true, 15703 '\\Bigr': true, 15704 '\\Biggr': true, 15705 // \extra@ also tests for the following: 15706 '$': true, 15707 // \extrap@ checks for the following: 15708 ';': true, 15709 '.': true, 15710 ',': true 15711}; 15712defineMacro("\\dotso", function (context) { 15713 var next = context.future().text; 15714 15715 if (next in spaceAfterDots) { 15716 return "\\ldots\\,"; 15717 } else { 15718 return "\\ldots"; 15719 } 15720}); 15721defineMacro("\\dotsc", function (context) { 15722 var next = context.future().text; // \dotsc uses \extra@ but not \extrap@, instead specially checking for 15723 // ';' and '.', but doesn't check for ','. 15724 15725 if (next in spaceAfterDots && next !== ',') { 15726 return "\\ldots\\,"; 15727 } else { 15728 return "\\ldots"; 15729 } 15730}); 15731defineMacro("\\cdots", function (context) { 15732 var next = context.future().text; 15733 15734 if (next in spaceAfterDots) { 15735 return "\\@cdots\\,"; 15736 } else { 15737 return "\\@cdots"; 15738 } 15739}); 15740defineMacro("\\dotsb", "\\cdots"); 15741defineMacro("\\dotsm", "\\cdots"); 15742defineMacro("\\dotsi", "\\!\\cdots"); // amsmath doesn't actually define \dotsx, but \dots followed by a macro 15743// starting with \DOTSX implies \dotso, and then \extra@ detects this case 15744// and forces the added `\,`. 15745 15746defineMacro("\\dotsx", "\\ldots\\,"); // \let\DOTSI\relax 15747// \let\DOTSB\relax 15748// \let\DOTSX\relax 15749 15750defineMacro("\\DOTSI", "\\relax"); 15751defineMacro("\\DOTSB", "\\relax"); 15752defineMacro("\\DOTSX", "\\relax"); // Spacing, based on amsmath.sty's override of LaTeX defaults 15753// \DeclareRobustCommand{\tmspace}[3]{% 15754// \ifmmode\mskip#1#2\else\kern#1#3\fi\relax} 15755 15756defineMacro("\\tmspace", "\\TextOrMath{\\kern#1#3}{\\mskip#1#2}\\relax"); // \renewcommand{\,}{\tmspace+\thinmuskip{.1667em}} 15757// TODO: math mode should use \thinmuskip 15758 15759defineMacro("\\,", "\\tmspace+{3mu}{.1667em}"); // \let\thinspace\, 15760 15761defineMacro("\\thinspace", "\\,"); // \def\>{\mskip\medmuskip} 15762// \renewcommand{\:}{\tmspace+\medmuskip{.2222em}} 15763// TODO: \> and math mode of \: should use \medmuskip = 4mu plus 2mu minus 4mu 15764 15765defineMacro("\\>", "\\mskip{4mu}"); 15766defineMacro("\\:", "\\tmspace+{4mu}{.2222em}"); // \let\medspace\: 15767 15768defineMacro("\\medspace", "\\:"); // \renewcommand{\;}{\tmspace+\thickmuskip{.2777em}} 15769// TODO: math mode should use \thickmuskip = 5mu plus 5mu 15770 15771defineMacro("\\;", "\\tmspace+{5mu}{.2777em}"); // \let\thickspace\; 15772 15773defineMacro("\\thickspace", "\\;"); // \renewcommand{\!}{\tmspace-\thinmuskip{.1667em}} 15774// TODO: math mode should use \thinmuskip 15775 15776defineMacro("\\!", "\\tmspace-{3mu}{.1667em}"); // \let\negthinspace\! 15777 15778defineMacro("\\negthinspace", "\\!"); // \newcommand{\negmedspace}{\tmspace-\medmuskip{.2222em}} 15779// TODO: math mode should use \medmuskip 15780 15781defineMacro("\\negmedspace", "\\tmspace-{4mu}{.2222em}"); // \newcommand{\negthickspace}{\tmspace-\thickmuskip{.2777em}} 15782// TODO: math mode should use \thickmuskip 15783 15784defineMacro("\\negthickspace", "\\tmspace-{5mu}{.277em}"); // \def\enspace{\kern.5em } 15785 15786defineMacro("\\enspace", "\\kern.5em "); // \def\enskip{\hskip.5em\relax} 15787 15788defineMacro("\\enskip", "\\hskip.5em\\relax"); // \def\quad{\hskip1em\relax} 15789 15790defineMacro("\\quad", "\\hskip1em\\relax"); // \def\qquad{\hskip2em\relax} 15791 15792defineMacro("\\qquad", "\\hskip2em\\relax"); // \tag@in@display form of \tag 15793 15794defineMacro("\\tag", "\\@ifstar\\tag@literal\\tag@paren"); 15795defineMacro("\\tag@paren", "\\tag@literal{({#1})}"); 15796defineMacro("\\tag@literal", context => { 15797 if (context.macros.get("\\df@tag")) { 15798 throw new ParseError("Multiple \\tag"); 15799 } 15800 15801 return "\\gdef\\df@tag{\\text{#1}}"; 15802}); // \renewcommand{\bmod}{\nonscript\mskip-\medmuskip\mkern5mu\mathbin 15803// {\operator@font mod}\penalty900 15804// \mkern5mu\nonscript\mskip-\medmuskip} 15805// \newcommand{\pod}[1]{\allowbreak 15806// \if@display\mkern18mu\else\mkern8mu\fi(#1)} 15807// \renewcommand{\pmod}[1]{\pod{{\operator@font mod}\mkern6mu#1}} 15808// \newcommand{\mod}[1]{\allowbreak\if@display\mkern18mu 15809// \else\mkern12mu\fi{\operator@font mod}\,\,#1} 15810// TODO: math mode should use \medmuskip = 4mu plus 2mu minus 4mu 15811 15812defineMacro("\\bmod", "\\mathchoice{\\mskip1mu}{\\mskip1mu}{\\mskip5mu}{\\mskip5mu}" + "\\mathbin{\\rm mod}" + "\\mathchoice{\\mskip1mu}{\\mskip1mu}{\\mskip5mu}{\\mskip5mu}"); 15813defineMacro("\\pod", "\\allowbreak" + "\\mathchoice{\\mkern18mu}{\\mkern8mu}{\\mkern8mu}{\\mkern8mu}(#1)"); 15814defineMacro("\\pmod", "\\pod{{\\rm mod}\\mkern6mu#1}"); 15815defineMacro("\\mod", "\\allowbreak" + "\\mathchoice{\\mkern18mu}{\\mkern12mu}{\\mkern12mu}{\\mkern12mu}" + "{\\rm mod}\\,\\,#1"); ////////////////////////////////////////////////////////////////////// 15816// LaTeX source2e 15817// \expandafter\let\expandafter\@normalcr 15818// \csname\expandafter\@gobble\string\\ \endcsname 15819// \DeclareRobustCommand\newline{\@normalcr\relax} 15820 15821defineMacro("\\newline", "\\\\\\relax"); // \def\TeX{T\kern-.1667em\lower.5ex\hbox{E}\kern-.125emX\@} 15822// TODO: Doesn't normally work in math mode because \@ fails. KaTeX doesn't 15823// support \@ yet, so that's omitted, and we add \text so that the result 15824// doesn't look funny in math mode. 15825 15826defineMacro("\\TeX", "\\textrm{\\html@mathml{" + "T\\kern-.1667em\\raisebox{-.5ex}{E}\\kern-.125emX" + "}{TeX}}"); // \DeclareRobustCommand{\LaTeX}{L\kern-.36em% 15827// {\sbox\z@ T% 15828// \vbox to\ht\z@{\hbox{\check@mathfonts 15829// \fontsize\sf@size\z@ 15830// \math@fontsfalse\selectfont 15831// A}% 15832// \vss}% 15833// }% 15834// \kern-.15em% 15835// \TeX} 15836// This code aligns the top of the A with the T (from the perspective of TeX's 15837// boxes, though visually the A appears to extend above slightly). 15838// We compute the corresponding \raisebox when A is rendered in \normalsize 15839// \scriptstyle, which has a scale factor of 0.7 (see Options.js). 15840 15841var latexRaiseA = makeEm(fontMetricsData['Main-Regular']["T".charCodeAt(0)][1] - 0.7 * fontMetricsData['Main-Regular']["A".charCodeAt(0)][1]); 15842defineMacro("\\LaTeX", "\\textrm{\\html@mathml{" + ("L\\kern-.36em\\raisebox{" + latexRaiseA + "}{\\scriptstyle A}") + "\\kern-.15em\\TeX}{LaTeX}}"); // New KaTeX logo based on tweaking LaTeX logo 15843 15844defineMacro("\\KaTeX", "\\textrm{\\html@mathml{" + ("K\\kern-.17em\\raisebox{" + latexRaiseA + "}{\\scriptstyle A}") + "\\kern-.15em\\TeX}{KaTeX}}"); // \DeclareRobustCommand\hspace{\@ifstar\@hspacer\@hspace} 15845// \def\@hspace#1{\hskip #1\relax} 15846// \def\@hspacer#1{\vrule \@width\z@\nobreak 15847// \hskip #1\hskip \z@skip} 15848 15849defineMacro("\\hspace", "\\@ifstar\\@hspacer\\@hspace"); 15850defineMacro("\\@hspace", "\\hskip #1\\relax"); 15851defineMacro("\\@hspacer", "\\rule{0pt}{0pt}\\hskip #1\\relax"); ////////////////////////////////////////////////////////////////////// 15852// mathtools.sty 15853//\providecommand\ordinarycolon{:} 15854 15855defineMacro("\\ordinarycolon", ":"); //\def\vcentcolon{\mathrel{\mathop\ordinarycolon}} 15856//TODO(edemaine): Not yet centered. Fix via \raisebox or #726 15857 15858defineMacro("\\vcentcolon", "\\mathrel{\\mathop\\ordinarycolon}"); // \providecommand*\dblcolon{\vcentcolon\mathrel{\mkern-.9mu}\vcentcolon} 15859 15860defineMacro("\\dblcolon", "\\html@mathml{" + "\\mathrel{\\vcentcolon\\mathrel{\\mkern-.9mu}\\vcentcolon}}" + "{\\mathop{\\char\"2237}}"); // \providecommand*\coloneqq{\vcentcolon\mathrel{\mkern-1.2mu}=} 15861 15862defineMacro("\\coloneqq", "\\html@mathml{" + "\\mathrel{\\vcentcolon\\mathrel{\\mkern-1.2mu}=}}" + "{\\mathop{\\char\"2254}}"); // â 15863// \providecommand*\Coloneqq{\dblcolon\mathrel{\mkern-1.2mu}=} 15864 15865defineMacro("\\Coloneqq", "\\html@mathml{" + "\\mathrel{\\dblcolon\\mathrel{\\mkern-1.2mu}=}}" + "{\\mathop{\\char\"2237\\char\"3d}}"); // \providecommand*\coloneq{\vcentcolon\mathrel{\mkern-1.2mu}\mathrel{-}} 15866 15867defineMacro("\\coloneq", "\\html@mathml{" + "\\mathrel{\\vcentcolon\\mathrel{\\mkern-1.2mu}\\mathrel{-}}}" + "{\\mathop{\\char\"3a\\char\"2212}}"); // \providecommand*\Coloneq{\dblcolon\mathrel{\mkern-1.2mu}\mathrel{-}} 15868 15869defineMacro("\\Coloneq", "\\html@mathml{" + "\\mathrel{\\dblcolon\\mathrel{\\mkern-1.2mu}\\mathrel{-}}}" + "{\\mathop{\\char\"2237\\char\"2212}}"); // \providecommand*\eqqcolon{=\mathrel{\mkern-1.2mu}\vcentcolon} 15870 15871defineMacro("\\eqqcolon", "\\html@mathml{" + "\\mathrel{=\\mathrel{\\mkern-1.2mu}\\vcentcolon}}" + "{\\mathop{\\char\"2255}}"); // â 15872// \providecommand*\Eqqcolon{=\mathrel{\mkern-1.2mu}\dblcolon} 15873 15874defineMacro("\\Eqqcolon", "\\html@mathml{" + "\\mathrel{=\\mathrel{\\mkern-1.2mu}\\dblcolon}}" + "{\\mathop{\\char\"3d\\char\"2237}}"); // \providecommand*\eqcolon{\mathrel{-}\mathrel{\mkern-1.2mu}\vcentcolon} 15875 15876defineMacro("\\eqcolon", "\\html@mathml{" + "\\mathrel{\\mathrel{-}\\mathrel{\\mkern-1.2mu}\\vcentcolon}}" + "{\\mathop{\\char\"2239}}"); // \providecommand*\Eqcolon{\mathrel{-}\mathrel{\mkern-1.2mu}\dblcolon} 15877 15878defineMacro("\\Eqcolon", "\\html@mathml{" + "\\mathrel{\\mathrel{-}\\mathrel{\\mkern-1.2mu}\\dblcolon}}" + "{\\mathop{\\char\"2212\\char\"2237}}"); // \providecommand*\colonapprox{\vcentcolon\mathrel{\mkern-1.2mu}\approx} 15879 15880defineMacro("\\colonapprox", "\\html@mathml{" + "\\mathrel{\\vcentcolon\\mathrel{\\mkern-1.2mu}\\approx}}" + "{\\mathop{\\char\"3a\\char\"2248}}"); // \providecommand*\Colonapprox{\dblcolon\mathrel{\mkern-1.2mu}\approx} 15881 15882defineMacro("\\Colonapprox", "\\html@mathml{" + "\\mathrel{\\dblcolon\\mathrel{\\mkern-1.2mu}\\approx}}" + "{\\mathop{\\char\"2237\\char\"2248}}"); // \providecommand*\colonsim{\vcentcolon\mathrel{\mkern-1.2mu}\sim} 15883 15884defineMacro("\\colonsim", "\\html@mathml{" + "\\mathrel{\\vcentcolon\\mathrel{\\mkern-1.2mu}\\sim}}" + "{\\mathop{\\char\"3a\\char\"223c}}"); // \providecommand*\Colonsim{\dblcolon\mathrel{\mkern-1.2mu}\sim} 15885 15886defineMacro("\\Colonsim", "\\html@mathml{" + "\\mathrel{\\dblcolon\\mathrel{\\mkern-1.2mu}\\sim}}" + "{\\mathop{\\char\"2237\\char\"223c}}"); // Some Unicode characters are implemented with macros to mathtools functions. 15887 15888defineMacro("\u2237", "\\dblcolon"); // :: 15889 15890defineMacro("\u2239", "\\eqcolon"); // -: 15891 15892defineMacro("\u2254", "\\coloneqq"); // := 15893 15894defineMacro("\u2255", "\\eqqcolon"); // =: 15895 15896defineMacro("\u2A74", "\\Coloneqq"); // ::=
15897////////////////////////////////////////////////////////////////////// 15898// colonequals.sty 15899// Alternate names for mathtools's macros: 15900 15901defineMacro("\\ratio", "\\vcentcolon"); 15902defineMacro("\\coloncolon", "\\dblcolon"); 15903defineMacro("\\colonequals", "\\coloneqq"); 15904defineMacro("\\coloncolonequals", "\\Coloneqq"); 15905defineMacro("\\equalscolon", "\\eqqcolon"); 15906defineMacro("\\equalscoloncolon", "\\Eqqcolon"); 15907defineMacro("\\colonminus", "\\coloneq"); 15908defineMacro("\\coloncolonminus", "\\Coloneq"); 15909defineMacro("\\minuscolon", "\\eqcolon"); 15910defineMacro("\\minuscoloncolon", "\\Eqcolon"); // \colonapprox name is same in mathtools and colonequals. 15911 15912defineMacro("\\coloncolonapprox", "\\Colonapprox"); // \colonsim name is same in mathtools and colonequals. 15913 15914defineMacro("\\coloncolonsim", "\\Colonsim"); // Additional macros, implemented by analogy with mathtools definitions: 15915 15916defineMacro("\\simcolon", "\\mathrel{\\sim\\mathrel{\\mkern-1.2mu}\\vcentcolon}"); 15917defineMacro("\\simcoloncolon", "\\mathrel{\\sim\\mathrel{\\mkern-1.2mu}\\dblcolon}"); 15918defineMacro("\\approxcolon", "\\mathrel{\\approx\\mathrel{\\mkern-1.2mu}\\vcentcolon}"); 15919defineMacro("\\approxcoloncolon", "\\mathrel{\\approx\\mathrel{\\mkern-1.2mu}\\dblcolon}"); // Present in newtxmath, pxfonts and txfonts 15920 15921defineMacro("\\notni", "\\html@mathml{\\not\\ni}{\\mathrel{\\char`\u220C}}"); 15922defineMacro("\\limsup", "\\DOTSB\\operatorname*{lim\\,sup}"); 15923defineMacro("\\liminf", "\\DOTSB\\operatorname*{lim\\,inf}"); ////////////////////////////////////////////////////////////////////// 15924// From amsopn.sty 15925 15926defineMacro("\\injlim", "\\DOTSB\\operatorname*{inj\\,lim}"); 15927defineMacro("\\projlim", "\\DOTSB\\operatorname*{proj\\,lim}"); 15928defineMacro("\\varlimsup", "\\DOTSB\\operatorname*{\\overline{lim}}"); 15929defineMacro("\\varliminf", "\\DOTSB\\operatorname*{\\underline{lim}}"); 15930defineMacro("\\varinjlim", "\\DOTSB\\operatorname*{\\underrightarrow{lim}}"); 15931defineMacro("\\varprojlim", "\\DOTSB\\operatorname*{\\underleftarrow{lim}}"); ////////////////////////////////////////////////////////////////////// 15932// MathML alternates for KaTeX glyphs in the Unicode private area 15933 15934defineMacro("\\gvertneqq", "\\html@mathml{\\@gvertneqq}{\u2269}"); 15935defineMacro("\\lvertneqq", "\\html@mathml{\\@lvertneqq}{\u2268}"); 15936defineMacro("\\ngeqq", "\\html@mathml{\\@ngeqq}{\u2271}"); 15937defineMacro("\\ngeqslant", "\\html@mathml{\\@ngeqslant}{\u2271}"); 15938defineMacro("\\nleqq", "\\html@mathml{\\@nleqq}{\u2270}"); 15939defineMacro("\\nleqslant", "\\html@mathml{\\@nleqslant}{\u2270}"); 15940defineMacro("\\nshortmid", "\\html@mathml{\\@nshortmid}{â¤}"); 15941defineMacro("\\nshortparallel", "\\html@mathml{\\@nshortparallel}{â¦}"); 15942defineMacro("\\nsubseteqq", "\\html@mathml{\\@nsubseteqq}{\u2288}"); 15943defineMacro("\\nsupseteqq", "\\html@mathml{\\@nsupseteqq}{\u2289}"); 15944defineMacro("\\varsubsetneq", "\\html@mathml{\\@varsubsetneq}{â}"); 15945defineMacro("\\varsubsetneqq", "\\html@mathml{\\@varsubsetneqq}{â«}"); 15946defineMacro("\\varsupsetneq", "\\html@mathml{\\@varsupsetneq}{â}"); 15947defineMacro("\\varsupsetneqq", "\\html@mathml{\\@varsupsetneqq}{â«}"); 15948defineMacro("\\imath", "\\html@mathml{\\@imath}{\u0131}"); 15949defineMacro("\\jmath", "\\html@mathml{\\@jmath}{\u0237}"); ////////////////////////////////////////////////////////////////////// 15950// stmaryrd and semantic 15951// The stmaryrd and semantic packages render the next four items by calling a 15952// glyph. Those glyphs do not exist in the KaTeX fonts. Hence the macros. 15953 15954defineMacro("\\llbracket", "\\html@mathml{" + "\\mathopen{[\\mkern-3.2mu[}}" + "{\\mathopen{\\char`\u27e6}}"); 15955defineMacro("\\rrbracket", "\\html@mathml{" + "\\mathclose{]\\mkern-3.2mu]}}" + "{\\mathclose{\\char`\u27e7}}"); 15956defineMacro("\u27e6", "\\llbracket"); // blackboard bold [ 15957 15958defineMacro("\u27e7", "\\rrbracket"); // blackboard bold ] 15959 15960defineMacro("\\lBrace", "\\html@mathml{" + "\\mathopen{\\{\\mkern-3.2mu[}}" + "{\\mathopen{\\char`\u2983}}"); 15961defineMacro("\\rBrace", "\\html@mathml{" + "\\mathclose{]\\mkern-3.2mu\\}}}" + "{\\mathclose{\\char`\u2984}}"); 15962defineMacro("\u2983", "\\lBrace"); // blackboard bold { 15963 15964defineMacro("\u2984", "\\rBrace"); // blackboard bold }
15965// TODO: Create variable sized versions of the last two items. I believe that 15966// will require new font glyphs. 15967// The stmaryrd function `\minuso` provides a "Plimsoll" symbol that 15968// superimposes the characters \circ and \mathminus. Used in chemistry. 15969 15970defineMacro("\\minuso", "\\mathbin{\\html@mathml{" + "{\\mathrlap{\\mathchoice{\\kern{0.145em}}{\\kern{0.145em}}" + "{\\kern{0.1015em}}{\\kern{0.0725em}}\\circ}{-}}}" + "{\\char`⦵}}"); 15971defineMacro("⦵", "\\minuso"); ////////////////////////////////////////////////////////////////////// 15972// texvc.sty 15973// The texvc package contains macros available in mediawiki pages. 15974// We omit the functions deprecated at 15975// https://en.wikipedia.org/wiki/Help:Displaying_a_formula#Deprecated_syntax 15976// We also omit texvc's \O, which conflicts with \text{\O} 15977 15978defineMacro("\\darr", "\\downarrow"); 15979defineMacro("\\dArr", "\\Downarrow"); 15980defineMacro("\\Darr", "\\Downarrow"); 15981defineMacro("\\lang", "\\langle"); 15982defineMacro("\\rang", "\\rangle"); 15983defineMacro("\\uarr", "\\uparrow"); 15984defineMacro("\\uArr", "\\Uparrow"); 15985defineMacro("\\Uarr", "\\Uparrow"); 15986defineMacro("\\N", "\\mathbb{N}"); 15987defineMacro("\\R", "\\mathbb{R}"); 15988defineMacro("\\Z", "\\mathbb{Z}"); 15989defineMacro("\\alef", "\\aleph"); 15990defineMacro("\\alefsym", "\\aleph"); 15991defineMacro("\\Alpha", "\\mathrm{A}"); 15992defineMacro("\\Beta", "\\mathrm{B}"); 15993defineMacro("\\bull", "\\bullet"); 15994defineMacro("\\Chi", "\\mathrm{X}"); 15995defineMacro("\\clubs", "\\clubsuit"); 15996defineMacro("\\cnums", "\\mathbb{C}"); 15997defineMacro("\\Complex", "\\mathbb{C}"); 15998defineMacro("\\Dagger", "\\ddagger"); 15999defineMacro("\\diamonds", "\\diamondsuit"); 16000defineMacro("\\empty", "\\emptyset"); 16001defineMacro("\\Epsilon", "\\mathrm{E}"); 16002defineMacro("\\Eta", "\\mathrm{H}"); 16003defineMacro("\\exist", "\\exists"); 16004defineMacro("\\harr", "\\leftrightarrow"); 16005defineMacro("\\hArr", "\\Leftrightarrow"); 16006defineMacro("\\Harr", "\\Leftrightarrow"); 16007defineMacro("\\hearts", "\\heartsuit"); 16008defineMacro("\\image", "\\Im"); 16009defineMacro("\\infin", "\\infty"); 16010defineMacro("\\Iota", "\\mathrm{I}"); 16011defineMacro("\\isin", "\\in"); 16012defineMacro("\\Kappa", "\\mathrm{K}"); 16013defineMacro("\\larr", "\\leftarrow"); 16014defineMacro("\\lArr", "\\Leftarrow"); 16015defineMacro("\\Larr", "\\Leftarrow"); 16016defineMacro("\\lrarr", "\\leftrightarrow"); 16017defineMacro("\\lrArr", "\\Leftrightarrow"); 16018defineMacro("\\Lrarr", "\\Leftrightarrow"); 16019defineMacro("\\Mu", "\\mathrm{M}"); 16020defineMacro("\\natnums", "\\mathbb{N}"); 16021defineMacro("\\Nu", "\\mathrm{N}"); 16022defineMacro("\\Omicron", "\\mathrm{O}"); 16023defineMacro("\\plusmn", "\\pm"); 16024defineMacro("\\rarr", "\\rightarrow"); 16025defineMacro("\\rArr", "\\Rightarrow"); 16026defineMacro("\\Rarr", "\\Rightarrow"); 16027defineMacro("\\real", "\\Re"); 16028defineMacro("\\reals", "\\mathbb{R}"); 16029defineMacro("\\Reals", "\\mathbb{R}"); 16030defineMacro("\\Rho", "\\mathrm{P}"); 16031defineMacro("\\sdot", "\\cdot"); 16032defineMacro("\\sect", "\\S"); 16033defineMacro("\\spades", "\\spadesuit"); 16034defineMacro("\\sub", "\\subset"); 16035defineMacro("\\sube", "\\subseteq"); 16036defineMacro("\\supe", "\\supseteq"); 16037defineMacro("\\Tau", "\\mathrm{T}"); 16038defineMacro("\\thetasym", "\\vartheta"); // TODO: defineMacro("\\varcoppa", "\\\mbox{\\coppa}"); 16039 16040defineMacro("\\weierp", "\\wp"); 16041defineMacro("\\Zeta", "\\mathrm{Z}"); ////////////////////////////////////////////////////////////////////// 16042// statmath.sty 16043// https://ctan.math.illinois.edu/macros/latex/contrib/statmath/statmath.pdf 16044 16045defineMacro("\\argmin", "\\DOTSB\\operatorname*{arg\\,min}"); 16046defineMacro("\\argmax", "\\DOTSB\\operatorname*{arg\\,max}"); 16047defineMacro("\\plim", "\\DOTSB\\mathop{\\operatorname{plim}}\\limits"); ////////////////////////////////////////////////////////////////////// 16048// braket.sty 16049// http://ctan.math.washington.edu/tex-archive/macros/latex/contrib/braket/braket.pdf 16050 16051defineMacro("\\bra", "\\mathinner{\\langle{#1}|}"); 16052defineMacro("\\ket", "\\mathinner{|{#1}\\rangle}"); 16053defineMacro("\\braket", "\\mathinner{\\langle{#1}\\rangle}"); 16054defineMacro("\\Bra", "\\left\\langle#1\\right|"); 16055defineMacro("\\Ket", "\\left|#1\\right\\rangle"); 16056 16057var braketHelper = one => context => { 16058 var left = context.consumeArg().tokens; 16059 var middle = context.consumeArg().tokens; 16060 var middleDouble = context.consumeArg().tokens; 16061 var right = context.consumeArg().tokens; 16062 var oldMiddle = context.macros.get("|"); 16063 var oldMiddleDouble = context.macros.get("\\|"); 16064 context.macros.beginGroup(); 16065 16066 var midMacro = double => context => { 16067 if (one) { 16068 // Only modify the first instance of | or \| 16069 context.macros.set("|", oldMiddle); 16070 16071 if (middleDouble.length) { 16072 context.macros.set("\\|", oldMiddleDouble); 16073 } 16074 } 16075 16076 var doubled = double; 16077 16078 if (!double && middleDouble.length) {
vendor: 8,266 bytes, lines 16079-16360
16079 // Mimic \@ifnextchar 16080 var nextToken = context.future(); 16081 16082 if (nextToken.text === "|") { 16083 context.popToken(); 16084 doubled = true; 16085 } 16086 } 16087 16088 return { 16089 tokens: doubled ? middleDouble : middle, 16090 numArgs: 0 16091 }; 16092 }; 16093 16094 context.macros.set("|", midMacro(false)); 16095 16096 if (middleDouble.length) { 16097 context.macros.set("\\|", midMacro(true)); 16098 } 16099 16100 var arg = context.consumeArg().tokens; 16101 var expanded = context.expandTokens([...right, ...arg, ...left // reversed 16102 ]); 16103 context.macros.endGroup(); 16104 return { 16105 tokens: expanded.reverse(), 16106 numArgs: 0 16107 }; 16108}; 16109 16110defineMacro("\\bra@ket", braketHelper(false)); 16111defineMacro("\\bra@set", braketHelper(true)); 16112defineMacro("\\Braket", "\\bra@ket{\\left\\langle}" + "{\\,\\middle\\vert\\,}{\\,\\middle\\vert\\,}{\\right\\rangle}"); 16113defineMacro("\\Set", "\\bra@set{\\left\\{\\:}" + "{\\;\\middle\\vert\\;}{\\;\\middle\\Vert\\;}{\\:\\right\\}}"); 16114defineMacro("\\set", "\\bra@set{\\{\\,}{\\mid}{}{\\,\\}}"); // has no support for special || or \| 16115////////////////////////////////////////////////////////////////////// 16116// actuarialangle.dtx 16117 16118defineMacro("\\angln", "{\\angl n}"); // Custom Khan Academy colors, should be moved to an optional package 16119 16120defineMacro("\\blue", "\\textcolor{##6495ed}{#1}"); 16121defineMacro("\\orange", "\\textcolor{##ffa500}{#1}"); 16122defineMacro("\\pink", "\\textcolor{##ff00af}{#1}"); 16123defineMacro("\\red", "\\textcolor{##df0030}{#1}"); 16124defineMacro("\\green", "\\textcolor{##28ae7b}{#1}"); 16125defineMacro("\\gray", "\\textcolor{gray}{#1}"); 16126defineMacro("\\purple", "\\textcolor{##9d38bd}{#1}"); 16127defineMacro("\\blueA", "\\textcolor{##ccfaff}{#1}"); 16128defineMacro("\\blueB", "\\textcolor{##80f6ff}{#1}"); 16129defineMacro("\\blueC", "\\textcolor{##63d9ea}{#1}"); 16130defineMacro("\\blueD", "\\textcolor{##11accd}{#1}"); 16131defineMacro("\\blueE", "\\textcolor{##0c7f99}{#1}"); 16132defineMacro("\\tealA", "\\textcolor{##94fff5}{#1}"); 16133defineMacro("\\tealB", "\\textcolor{##26edd5}{#1}"); 16134defineMacro("\\tealC", "\\textcolor{##01d1c1}{#1}"); 16135defineMacro("\\tealD", "\\textcolor{##01a995}{#1}"); 16136defineMacro("\\tealE", "\\textcolor{##208170}{#1}"); 16137defineMacro("\\greenA", "\\textcolor{##b6ffb0}{#1}"); 16138defineMacro("\\greenB", "\\textcolor{##8af281}{#1}"); 16139defineMacro("\\greenC", "\\textcolor{##74cf70}{#1}"); 16140defineMacro("\\greenD", "\\textcolor{##1fab54}{#1}"); 16141defineMacro("\\greenE", "\\textcolor{##0d923f}{#1}"); 16142defineMacro("\\goldA", "\\textcolor{##ffd0a9}{#1}"); 16143defineMacro("\\goldB", "\\textcolor{##ffbb71}{#1}"); 16144defineMacro("\\goldC", "\\textcolor{##ff9c39}{#1}"); 16145defineMacro("\\goldD", "\\textcolor{##e07d10}{#1}"); 16146defineMacro("\\goldE", "\\textcolor{##a75a05}{#1}"); 16147defineMacro("\\redA", "\\textcolor{##fca9a9}{#1}"); 16148defineMacro("\\redB", "\\textcolor{##ff8482}{#1}"); 16149defineMacro("\\redC", "\\textcolor{##f9685d}{#1}"); 16150defineMacro("\\redD", "\\textcolor{##e84d39}{#1}"); 16151defineMacro("\\redE", "\\textcolor{##bc2612}{#1}"); 16152defineMacro("\\maroonA", "\\textcolor{##ffbde0}{#1}"); 16153defineMacro("\\maroonB", "\\textcolor{##ff92c6}{#1}"); 16154defineMacro("\\maroonC", "\\textcolor{##ed5fa6}{#1}"); 16155defineMacro("\\maroonD", "\\textcolor{##ca337c}{#1}"); 16156defineMacro("\\maroonE", "\\textcolor{##9e034e}{#1}"); 16157defineMacro("\\purpleA", "\\textcolor{##ddd7ff}{#1}"); 16158defineMacro("\\purpleB", "\\textcolor{##c6b9fc}{#1}"); 16159defineMacro("\\purpleC", "\\textcolor{##aa87ff}{#1}"); 16160defineMacro("\\purpleD", "\\textcolor{##7854ab}{#1}"); 16161defineMacro("\\purpleE", "\\textcolor{##543b78}{#1}"); 16162defineMacro("\\mintA", "\\textcolor{##f5f9e8}{#1}"); 16163defineMacro("\\mintB", "\\textcolor{##edf2df}{#1}"); 16164defineMacro("\\mintC", "\\textcolor{##e0e5cc}{#1}"); 16165defineMacro("\\grayA", "\\textcolor{##f6f7f7}{#1}"); 16166defineMacro("\\grayB", "\\textcolor{##f0f1f2}{#1}"); 16167defineMacro("\\grayC", "\\textcolor{##e3e5e6}{#1}"); 16168defineMacro("\\grayD", "\\textcolor{##d6d8da}{#1}"); 16169defineMacro("\\grayE", "\\textcolor{##babec2}{#1}"); 16170defineMacro("\\grayF", "\\textcolor{##888d93}{#1}"); 16171defineMacro("\\grayG", "\\textcolor{##626569}{#1}"); 16172defineMacro("\\grayH", "\\textcolor{##3b3e40}{#1}"); 16173defineMacro("\\grayI", "\\textcolor{##21242c}{#1}"); 16174defineMacro("\\kaBlue", "\\textcolor{##314453}{#1}"); 16175defineMacro("\\kaGreen", "\\textcolor{##71B307}{#1}"); 16176 16177/** 16178 * This file contains the âgulletâ where macros are expanded 16179 * until only non-macro tokens remain. 16180 */ 16181// List of commands that act like macros but aren't defined as a macro, 16182// function, or symbol. Used in `isDefined`. 16183var implicitCommands = { 16184 "^": true, 16185 // Parser.js 16186 "_": true, 16187 // Parser.js 16188 "\\limits": true, 16189 // Parser.js 16190 "\\nolimits": true // Parser.js 16191 16192}; 16193class MacroExpander { 16194 constructor(input, settings, mode) { 16195 this.settings = void 0; 16196 this.expansionCount = void 0; 16197 this.lexer = void 0; 16198 this.macros = void 0; 16199 this.stack = void 0; 16200 this.mode = void 0; 16201 this.settings = settings; 16202 this.expansionCount = 0; 16203 this.feed(input); // Make new global namespace 16204 16205 this.macros = new Namespace(macros, settings.macros); 16206 this.mode = mode; 16207 this.stack = []; // contains tokens in REVERSE order 16208 } 16209 /** 16210 * Feed a new input string to the same MacroExpander 16211 * (with existing macros etc.). 16212 */ 16213 16214 16215 feed(input) { 16216 this.lexer = new Lexer(input, this.settings); 16217 } 16218 /** 16219 * Switches between "text" and "math" modes. 16220 */ 16221 16222 16223 switchMode(newMode) { 16224 this.mode = newMode; 16225 } 16226 /** 16227 * Start a new group nesting within all namespaces. 16228 */ 16229 16230 16231 beginGroup() { 16232 this.macros.beginGroup(); 16233 } 16234 /** 16235 * End current group nesting within all namespaces. 16236 */ 16237 16238 16239 endGroup() { 16240 this.macros.endGroup(); 16241 } 16242 /** 16243 * Ends all currently nested groups (if any), restoring values before the 16244 * groups began. Useful in case of an error in the middle of parsing. 16245 */ 16246 16247 16248 endGroups() { 16249 this.macros.endGroups(); 16250 } 16251 /** 16252 * Returns the topmost token on the stack, without expanding it. 16253 * Similar in behavior to TeX's `\futurelet`. 16254 */ 16255 16256 16257 future() { 16258 if (this.stack.length === 0) { 16259 this.pushToken(this.lexer.lex()); 16260 } 16261 16262 return this.stack[this.stack.length - 1]; 16263 } 16264 /** 16265 * Remove and return the next unexpanded token. 16266 */ 16267 16268 16269 popToken() { 16270 this.future(); // ensure non-empty stack 16271 16272 return this.stack.pop(); 16273 } 16274 /** 16275 * Add a given token to the token stack. In particular, this get be used 16276 * to put back a token returned from one of the other methods. 16277 */ 16278 16279 16280 pushToken(token) { 16281 this.stack.push(token); 16282 } 16283 /** 16284 * Append an array of tokens to the token stack. 16285 */ 16286 16287 16288 pushTokens(tokens) { 16289 this.stack.push(...tokens); 16290 } 16291 /** 16292 * Find an macro argument without expanding tokens and append the array of 16293 * tokens to the token stack. Uses Token as a container for the result. 16294 */ 16295 16296 16297 scanArgument(isOptional) { 16298 var start; 16299 var end; 16300 var tokens; 16301 16302 if (isOptional) { 16303 this.consumeSpaces(); // \@ifnextchar gobbles any space following it 16304 16305 if (this.future().text !== "[") { 16306 return null; 16307 } 16308 16309 start = this.popToken(); // don't include [ in tokens 16310 16311 ({ 16312 tokens, 16313 end 16314 } = this.consumeArg(["]"])); 16315 } else { 16316 ({ 16317 tokens, 16318 start, 16319 end 16320 } = this.consumeArg()); 16321 } // indicate the end of an argument 16322 16323 16324 this.pushToken(new Token("EOF", end.loc)); 16325 this.pushTokens(tokens); 16326 return start.range(end, ""); 16327 } 16328 /** 16329 * Consume all following space tokens, without expansion. 16330 */ 16331 16332 16333 consumeSpaces() { 16334 for (;;) { 16335 var token = this.future(); 16336 16337 if (token.text === " ") { 16338 this.stack.pop(); 16339 } else { 16340 break; 16341 } 16342 } 16343 } 16344 /** 16345 * Consume an argument from the token stream, and return the resulting array 16346 * of tokens and start/end token. 16347 */ 16348 16349 16350 consumeArg(delims) { 16351 // The argument for a delimited parameter is the shortest (possibly 16352 // empty) sequence of tokens with properly nested {...} groups that is 16353 // followed ... by this particular list of non-parameter tokens. 16354 // The argument for an undelimited parameter is the next nonblank 16355 // token, unless that token is â{â, when the argument will be the 16356 // entire {...} group that follows. 16357 var tokens = []; 16358 var isDelimited = delims && delims.length > 0; 16359 16360 if (!isDelimited) {
vendor: 5,152 bytes, lines 16361-16534
16361 // Ignore spaces between arguments. As the TeXbook says: 16362 // "After you have said â\def\row#1#2{...}â, you are allowed to 16363 // put spaces between the arguments (e.g., â\row x nâ), because 16364 // TeX doesnât use single spaces as undelimited arguments." 16365 this.consumeSpaces(); 16366 } 16367 16368 var start = this.future(); 16369 var tok; 16370 var depth = 0; 16371 var match = 0; 16372 16373 do { 16374 tok = this.popToken(); 16375 tokens.push(tok); 16376 16377 if (tok.text === "{") { 16378 ++depth; 16379 } else if (tok.text === "}") { 16380 --depth; 16381 16382 if (depth === -1) { 16383 throw new ParseError("Extra }", tok); 16384 } 16385 } else if (tok.text === "EOF") { 16386 throw new ParseError("Unexpected end of input in a macro argument" + ", expected '" + (delims && isDelimited ? delims[match] : "}") + "'", tok); 16387 } 16388 16389 if (delims && isDelimited) { 16390 if ((depth === 0 || depth === 1 && delims[match] === "{") && tok.text === delims[match]) { 16391 ++match; 16392 16393 if (match === delims.length) { 16394 // don't include delims in tokens 16395 tokens.splice(-match, match); 16396 break; 16397 } 16398 } else { 16399 match = 0; 16400 } 16401 } 16402 } while (depth !== 0 || isDelimited); // If the argument found ... has the form â{<nested tokens>}â, 16403 // ... the outermost braces enclosing the argument are removed 16404 16405 16406 if (start.text === "{" && tokens[tokens.length - 1].text === "}") { 16407 tokens.pop(); 16408 tokens.shift(); 16409 } 16410 16411 tokens.reverse(); // to fit in with stack order 16412 16413 return { 16414 tokens, 16415 start, 16416 end: tok 16417 }; 16418 } 16419 /** 16420 * Consume the specified number of (delimited) arguments from the token 16421 * stream and return the resulting array of arguments. 16422 */ 16423 16424 16425 consumeArgs(numArgs, delimiters) { 16426 if (delimiters) { 16427 if (delimiters.length !== numArgs + 1) { 16428 throw new ParseError("The length of delimiters doesn't match the number of args!"); 16429 } 16430 16431 var delims = delimiters[0]; 16432 16433 for (var i = 0; i < delims.length; i++) { 16434 var tok = this.popToken(); 16435 16436 if (delims[i] !== tok.text) { 16437 throw new ParseError("Use of the macro doesn't match its definition", tok); 16438 } 16439 } 16440 } 16441 16442 var args = []; 16443 16444 for (var _i = 0; _i < numArgs; _i++) { 16445 args.push(this.consumeArg(delimiters && delimiters[_i + 1]).tokens); 16446 } 16447 16448 return args; 16449 } 16450 /** 16451 * Increment `expansionCount` by the specified amount. 16452 * Throw an error if it exceeds `maxExpand`. 16453 */ 16454 16455 16456 countExpansion(amount) { 16457 this.expansionCount += amount; 16458 16459 if (this.expansionCount > this.settings.maxExpand) { 16460 throw new ParseError("Too many expansions: infinite loop or " + "need to increase maxExpand setting"); 16461 } 16462 } 16463 /** 16464 * Expand the next token only once if possible. 16465 * 16466 * If the token is expanded, the resulting tokens will be pushed onto 16467 * the stack in reverse order, and the number of such tokens will be 16468 * returned. This number might be zero or positive. 16469 * 16470 * If not, the return value is `false`, and the next token remains at the 16471 * top of the stack. 16472 * 16473 * In either case, the next token will be on the top of the stack, 16474 * or the stack will be empty (in case of empty expansion 16475 * and no other tokens). 16476 * 16477 * Used to implement `expandAfterFuture` and `expandNextToken`. 16478 * 16479 * If expandableOnly, only expandable tokens are expanded and 16480 * an undefined control sequence results in an error. 16481 */ 16482 16483 16484 expandOnce(expandableOnly) { 16485 var topToken = this.popToken(); 16486 var name = topToken.text; 16487 var expansion = !topToken.noexpand ? this._getExpansion(name) : null; 16488 16489 if (expansion == null || expandableOnly && expansion.unexpandable) { 16490 if (expandableOnly && expansion == null && name[0] === "\\" && !this.isDefined(name)) { 16491 throw new ParseError("Undefined control sequence: " + name); 16492 } 16493 16494 this.pushToken(topToken); 16495 return false; 16496 } 16497 16498 this.countExpansion(1); 16499 var tokens = expansion.tokens; 16500 var args = this.consumeArgs(expansion.numArgs, expansion.delimiters); 16501 16502 if (expansion.numArgs) { 16503 // paste arguments in place of the placeholders 16504 tokens = tokens.slice(); // make a shallow copy 16505 16506 for (var i = tokens.length - 1; i >= 0; --i) { 16507 var tok = tokens[i]; 16508 16509 if (tok.text === "#") { 16510 if (i === 0) { 16511 throw new ParseError("Incomplete placeholder at end of macro body", tok); 16512 } 16513 16514 tok = tokens[--i]; // next token on stack 16515 16516 if (tok.text === "#") { 16517 // ## â # 16518 tokens.splice(i + 1, 1); // drop first # 16519 } else if (/^[1-9]$/.test(tok.text)) { 16520 // replace the placeholder with the indicated argument 16521 tokens.splice(i, 2, ...args[+tok.text - 1]); 16522 } else { 16523 throw new ParseError("Not a valid argument number", tok); 16524 } 16525 } 16526 } 16527 } // Concatenate expansion onto top of stack. 16528 16529 16530 this.pushTokens(tokens); 16531 return tokens.length; 16532 } 16533 /** 16534 * Expand the next token only once (if possible), and return the resulting
vendor: 8,681 bytes, lines 16535-16961
16535 * top token on the stack (without removing anything from the stack). 16536 * Similar in behavior to TeX's `\expandafter\futurelet`. 16537 * Equivalent to expandOnce() followed by future(). 16538 */ 16539 16540 16541 expandAfterFuture() { 16542 this.expandOnce(); 16543 return this.future(); 16544 } 16545 /** 16546 * Recursively expand first token, then return first non-expandable token. 16547 */ 16548 16549 16550 expandNextToken() { 16551 for (;;) { 16552 if (this.expandOnce() === false) { 16553 // fully expanded 16554 var token = this.stack.pop(); // the token after \noexpand is interpreted as if its meaning 16555 // were â\relaxâ 16556 16557 if (token.treatAsRelax) { 16558 token.text = "\\relax"; 16559 } 16560 16561 return token; 16562 } 16563 } // Flow unable to figure out that this pathway is impossible. 16564 // https://github.com/facebook/flow/issues/4808 16565 16566 16567 throw new Error(); // eslint-disable-line no-unreachable 16568 } 16569 /** 16570 * Fully expand the given macro name and return the resulting list of 16571 * tokens, or return `undefined` if no such macro is defined. 16572 */ 16573 16574 16575 expandMacro(name) { 16576 return this.macros.has(name) ? this.expandTokens([new Token(name)]) : undefined; 16577 } 16578 /** 16579 * Fully expand the given token stream and return the resulting list of 16580 * tokens. Note that the input tokens are in reverse order, but the 16581 * output tokens are in forward order. 16582 */ 16583 16584 16585 expandTokens(tokens) { 16586 var output = []; 16587 var oldStackLength = this.stack.length; 16588 this.pushTokens(tokens); 16589 16590 while (this.stack.length > oldStackLength) { 16591 // Expand only expandable tokens 16592 if (this.expandOnce(true) === false) { 16593 // fully expanded 16594 var token = this.stack.pop(); 16595 16596 if (token.treatAsRelax) { 16597 // the expansion of \noexpand is the token itself 16598 token.noexpand = false; 16599 token.treatAsRelax = false; 16600 } 16601 16602 output.push(token); 16603 } 16604 } // Count all of these tokens as additional expansions, to prevent 16605 // exponential blowup from linearly many \edef's. 16606 16607 16608 this.countExpansion(output.length); 16609 return output; 16610 } 16611 /** 16612 * Fully expand the given macro name and return the result as a string, 16613 * or return `undefined` if no such macro is defined. 16614 */ 16615 16616 16617 expandMacroAsText(name) { 16618 var tokens = this.expandMacro(name); 16619 16620 if (tokens) { 16621 return tokens.map(token => token.text).join(""); 16622 } else { 16623 return tokens; 16624 } 16625 } 16626 /** 16627 * Returns the expanded macro as a reversed array of tokens and a macro 16628 * argument count. Or returns `null` if no such macro. 16629 */ 16630 16631 16632 _getExpansion(name) { 16633 var definition = this.macros.get(name); 16634 16635 if (definition == null) { 16636 // mainly checking for undefined here 16637 return definition; 16638 } // If a single character has an associated catcode other than 13 16639 // (active character), then don't expand it. 16640 16641 16642 if (name.length === 1) { 16643 var catcode = this.lexer.catcodes[name]; 16644 16645 if (catcode != null && catcode !== 13) { 16646 return; 16647 } 16648 } 16649 16650 var expansion = typeof definition === "function" ? definition(this) : definition; 16651 16652 if (typeof expansion === "string") { 16653 var numArgs = 0; 16654 16655 if (expansion.indexOf("#") !== -1) { 16656 var stripped = expansion.replace(/##/g, ""); 16657 16658 while (stripped.indexOf("#" + (numArgs + 1)) !== -1) { 16659 ++numArgs; 16660 } 16661 } 16662 16663 var bodyLexer = new Lexer(expansion, this.settings); 16664 var tokens = []; 16665 var tok = bodyLexer.lex(); 16666 16667 while (tok.text !== "EOF") { 16668 tokens.push(tok); 16669 tok = bodyLexer.lex(); 16670 } 16671 16672 tokens.reverse(); // to fit in with stack using push and pop 16673 16674 var expanded = { 16675 tokens, 16676 numArgs 16677 }; 16678 return expanded; 16679 } 16680 16681 return expansion; 16682 } 16683 /** 16684 * Determine whether a command is currently "defined" (has some 16685 * functionality), meaning that it's a macro (in the current group), 16686 * a function, a symbol, or one of the special commands listed in 16687 * `implicitCommands`. 16688 */ 16689 16690 16691 isDefined(name) { 16692 return this.macros.has(name) || functions.hasOwnProperty(name) || symbols.math.hasOwnProperty(name) || symbols.text.hasOwnProperty(name) || implicitCommands.hasOwnProperty(name); 16693 } 16694 /** 16695 * Determine whether a command is expandable. 16696 */ 16697 16698 16699 isExpandable(name) { 16700 var macro = this.macros.get(name); 16701 return macro != null ? typeof macro === "string" || typeof macro === "function" || !macro.unexpandable : functions.hasOwnProperty(name) && !functions[name].primitive; 16702 } 16703 16704} 16705 16706// Helpers for Parser.js handling of Unicode (sub|super)script characters. 16707var unicodeSubRegEx = /^[âââââââââââ âââââââᵢⱼââââââáµ£ââᵤᵥâᵦᵧᵨᵩᵪ]/; 16708var uSubsAndSups = Object.freeze({ 16709 'â': '+', 16710 'â': '-', 16711 'â': '=', 16712 'â': '(', 16713 'â': ')', 16714 'â': '0', 16715 'â': '1', 16716 'â': '2', 16717 'â': '3', 16718 'â': '4', 16719 'â ': '5', 16720 'â': '6', 16721 'â': '7', 16722 'â': '8', 16723 'â': '9', 16724 '\u2090': 'a', 16725 '\u2091': 'e', 16726 '\u2095': 'h', 16727 '\u1D62': 'i', 16728 '\u2C7C': 'j', 16729 '\u2096': 'k', 16730 '\u2097': 'l', 16731 '\u2098': 'm', 16732 '\u2099': 'n', 16733 '\u2092': 'o', 16734 '\u209A': 'p', 16735 '\u1D63': 'r', 16736 '\u209B': 's', 16737 '\u209C': 't', 16738 '\u1D64': 'u', 16739 '\u1D65': 'v', 16740 '\u2093': 'x', 16741 '\u1D66': 'β', 16742 '\u1D67': 'γ', 16743 '\u1D68': 'Ï', 16744 '\u1D69': '\u03d5', 16745 '\u1D6A': 'Ï', 16746 'âº': '+', 16747 'â»': '-', 16748 'â¼': '=', 16749 'â½': '(', 16750 'â¾': ')', 16751 'â°': '0', 16752 '¹': '1', 16753 '²': '2', 16754 '³': '3', 16755 'â´': '4', 16756 'âµ': '5', 16757 'â¶': '6', 16758 'â·': '7', 16759 'â¸': '8', 16760 'â¹': '9', 16761 '\u1D2C': 'A', 16762 '\u1D2E': 'B', 16763 '\u1D30': 'D', 16764 '\u1D31': 'E', 16765 '\u1D33': 'G', 16766 '\u1D34': 'H', 16767 '\u1D35': 'I', 16768 '\u1D36': 'J', 16769 '\u1D37': 'K', 16770 '\u1D38': 'L', 16771 '\u1D39': 'M', 16772 '\u1D3A': 'N', 16773 '\u1D3C': 'O', 16774 '\u1D3E': 'P', 16775 '\u1D3F': 'R', 16776 '\u1D40': 'T', 16777 '\u1D41': 'U', 16778 '\u2C7D': 'V', 16779 '\u1D42': 'W', 16780 '\u1D43': 'a', 16781 '\u1D47': 'b', 16782 '\u1D9C': 'c', 16783 '\u1D48': 'd', 16784 '\u1D49': 'e', 16785 '\u1DA0': 'f', 16786 '\u1D4D': 'g', 16787 '\u02B0': 'h', 16788 '\u2071': 'i', 16789 '\u02B2': 'j', 16790 '\u1D4F': 'k', 16791 '\u02E1': 'l', 16792 '\u1D50': 'm', 16793 '\u207F': 'n', 16794 '\u1D52': 'o', 16795 '\u1D56': 'p', 16796 '\u02B3': 'r', 16797 '\u02E2': 's', 16798 '\u1D57': 't', 16799 '\u1D58': 'u', 16800 '\u1D5B': 'v', 16801 '\u02B7': 'w', 16802 '\u02E3': 'x', 16803 '\u02B8': 'y', 16804 '\u1DBB': 'z', 16805 '\u1D5D': 'β', 16806 '\u1D5E': 'γ', 16807 '\u1D5F': 'δ', 16808 '\u1D60': '\u03d5', 16809 '\u1D61': 'Ï', 16810 '\u1DBF': 'θ' 16811}); 16812 16813/* eslint no-constant-condition:0 */ 16814 16815var unicodeAccents = { 16816 "Ì": { 16817 "text": "\\'", 16818 "math": "\\acute" 16819 }, 16820 "Ì": { 16821 "text": "\\`", 16822 "math": "\\grave" 16823 }, 16824 "Ì": { 16825 "text": "\\\"", 16826 "math": "\\ddot" 16827 }, 16828 "Ì": { 16829 "text": "\\~", 16830 "math": "\\tilde" 16831 }, 16832 "Ì": { 16833 "text": "\\=", 16834 "math": "\\bar" 16835 }, 16836 "Ì": { 16837 "text": "\\u", 16838 "math": "\\breve" 16839 }, 16840 "Ì": { 16841 "text": "\\v", 16842 "math": "\\check" 16843 }, 16844 "Ì": { 16845 "text": "\\^", 16846 "math": "\\hat" 16847 }, 16848 "Ì": { 16849 "text": "\\.", 16850 "math": "\\dot" 16851 }, 16852 "Ì": { 16853 "text": "\\r", 16854 "math": "\\mathring" 16855 }, 16856 "Ì": { 16857 "text": "\\H" 16858 }, 16859 "̧": { 16860 "text": "\\c" 16861 } 16862}; 16863var unicodeSymbols = { 16864 "á": "aÌ", 16865 "à ": "aÌ", 16866 "ä": "aÌ", 16867 "Ç": "aÌÌ", 16868 "ã": "aÌ", 16869 "Ä": "aÌ", 16870 "Ä": "aÌ", 16871 "ắ": "aÌÌ", 16872 "ằ": "aÌÌ", 16873 "ẵ": "aÌÌ", 16874 "Ç": "aÌ", 16875 "â": "aÌ", 16876 "ấ": "aÌÌ", 16877 "ầ": "aÌÌ", 16878 "ẫ": "aÌÌ", 16879 "ȧ": "aÌ", 16880 "Ç¡": "aÌÌ", 16881 "Ã¥": "aÌ", 16882 "Ç»": "aÌÌ", 16883 "á¸": "bÌ", 16884 "Ä": "cÌ", 16885 "á¸": "çÌ", 16886 "Ä": "cÌ", 16887 "Ä": "cÌ", 16888 "Ä": "cÌ", 16889 "ç": "ç", 16890 "Ä": "dÌ", 16891 "á¸": "dÌ", 16892 "á¸": "ḑ", 16893 "é": "eÌ", 16894 "è": "eÌ", 16895 "ë": "eÌ", 16896 "ẽ": "eÌ", 16897 "Ä": "eÌ", 16898 "á¸": "eÌÌ", 16899 "á¸": "eÌÌ", 16900 "Ä": "eÌ", 16901 "á¸": "ȩÌ", 16902 "Ä": "eÌ", 16903 "ê": "eÌ", 16904 "ế": "eÌÌ", 16905 "á»": "eÌÌ", 16906 "á» ": "eÌÌ", 16907 "Ä": "eÌ", 16908 "È©": "ȩ", 16909 "á¸": "fÌ", 16910 "ǵ": "gÌ", 16911 "ḡ": "gÌ", 16912 "Ä": "gÌ", 16913 "ǧ": "gÌ", 16914 "Ä": "gÌ", 16915 "Ä¡": "gÌ", 16916 "Ä£": "ģ", 16917 "ḧ": "hÌ", 16918 "È": "hÌ", 16919 "Ä¥": "hÌ", 16920 "ḣ": "hÌ", 16921 "ḩ": "ḩ", 16922 "Ã": "iÌ", 16923 "ì": "iÌ", 16924 "ï": "iÌ", 16925 "ḯ": "iÌÌ", 16926 "Ä©": "iÌ", 16927 "Ä«": "iÌ", 16928 "Ä": "iÌ", 16929 "Ç": "iÌ", 16930 "î": "iÌ", 16931 "ǰ": "jÌ", 16932 "ĵ": "jÌ", 16933 "ḱ": "kÌ", 16934 "Ç©": "kÌ", 16935 "Ä·": "ķ", 16936 "ĺ": "lÌ", 16937 "ľ": "lÌ", 16938 "ļ": "ļ", 16939 "ḿ": "mÌ", 16940 "á¹": "mÌ", 16941 "Å": "nÌ", 16942 "ǹ": "nÌ", 16943 "ñ": "nÌ", 16944 "Å": "nÌ", 16945 "á¹ ": "nÌ", 16946 "Å": "ņ", 16947 "ó": "oÌ", 16948 "ò": "oÌ", 16949 "ö": "oÌ", 16950 "È«": "oÌÌ", 16951 "õ": "oÌ", 16952 "á¹": "oÌÌ", 16953 "á¹": "oÌÌ", 16954 "È": "oÌÌ", 16955 "Å": "oÌ", 16956 "á¹": "oÌÌ", 16957 "á¹": "oÌÌ", 16958 "Å": "oÌ", 16959 "Ç": "oÌ", 16960 "ô": "oÌ", 16961 "á»": "oÌÌ",
16962 "á»": "oÌÌ", 16963 "á»": "oÌÌ", 16964 "ȯ": "oÌ", 16965 "ȱ": "oÌÌ", 16966 "Å": "oÌ", 16967 "á¹": "pÌ", 16968 "á¹": "pÌ", 16969 "Å": "rÌ", 16970 "Å": "rÌ", 16971 "á¹": "rÌ", 16972 "Å": "ŗ", 16973 "Å": "sÌ", 16974 "á¹¥": "sÌÌ", 16975 "Å¡": "sÌ", 16976 "á¹§": "sÌÌ", 16977 "Å": "sÌ", 16978 "ṡ": "sÌ", 16979 "Å": "ş", 16980 "áº": "tÌ", 16981 "Å¥": "tÌ", 16982 "ṫ": "tÌ", 16983 "Å£": "ţ", 16984 "ú": "uÌ", 16985 "ù": "uÌ", 16986 "ü": "uÌ", 16987 "Ç": "uÌÌ", 16988 "Ç": "uÌÌ", 16989 "Ç": "uÌÌ", 16990 "Ç": "uÌÌ", 16991 "Å©": "uÌ", 16992 "á¹¹": "uÌÌ", 16993 "Å«": "uÌ", 16994 "á¹»": "uÌÌ", 16995 "Å": "uÌ", 16996 "Ç": "uÌ", 16997 "û": "uÌ", 16998 "ů": "uÌ", 16999 "ű": "uÌ", 17000 "á¹½": "vÌ", 17001 "áº": "wÌ", 17002 "áº": "wÌ", 17003 "Ạ": "wÌ", 17004 "ŵ": "wÌ", 17005 "áº": "wÌ", 17006 "áº": "wÌ", 17007 "áº": "xÌ", 17008 "áº": "xÌ", 17009 "ý": "yÌ", 17010 "ỳ": "yÌ", 17011 "ÿ": "yÌ", 17012 "ỹ": "yÌ", 17013 "ȳ": "yÌ", 17014 "Å·": "yÌ", 17015 "áº": "yÌ", 17016 "áº": "yÌ", 17017 "ź": "zÌ", 17018 "ž": "zÌ", 17019 "áº": "zÌ", 17020 "ż": "zÌ", 17021 "Ã": "AÌ", 17022 "Ã": "AÌ", 17023 "Ã": "AÌ", 17024 "Ç": "AÌÌ", 17025 "Ã": "AÌ", 17026 "Ä": "AÌ", 17027 "Ä": "AÌ", 17028 "Ắ": "AÌÌ", 17029 "Ằ": "AÌÌ", 17030 "Ẵ": "AÌÌ", 17031 "Ç": "AÌ", 17032 "Ã": "AÌ", 17033 "Ấ": "AÌÌ", 17034 "Ầ": "AÌÌ", 17035 "Ẫ": "AÌÌ", 17036 "Ȧ": "AÌ", 17037 "Ç ": "AÌÌ", 17038 "à ": "AÌ", 17039 "Ǻ": "AÌÌ", 17040 "á¸": "BÌ", 17041 "Ä": "CÌ", 17042 "á¸": "ÇÌ", 17043 "Ä": "CÌ", 17044 "Ä": "CÌ", 17045 "Ä": "CÌ", 17046 "Ã": "Ç", 17047 "Ä": "DÌ", 17048 "á¸": "DÌ", 17049 "á¸": "Ḑ", 17050 "Ã": "EÌ", 17051 "Ã": "EÌ", 17052 "Ã": "EÌ", 17053 "Ẽ": "EÌ", 17054 "Ä": "EÌ", 17055 "á¸": "EÌÌ", 17056 "á¸": "EÌÌ", 17057 "Ä": "EÌ", 17058 "á¸": "ȨÌ", 17059 "Ä": "EÌ", 17060 "Ã": "EÌ", 17061 "Ế": "EÌÌ", 17062 "á»": "EÌÌ", 17063 "á»": "EÌÌ", 17064 "Ä": "EÌ", 17065 "Ȩ": "Ȩ", 17066 "á¸": "FÌ", 17067 "Ç´": "GÌ", 17068 "Ḡ": "GÌ", 17069 "Ä": "GÌ", 17070 "Ǧ": "GÌ", 17071 "Ä": "GÌ", 17072 "Ä ": "GÌ", 17073 "Ä¢": "Ģ", 17074 "Ḧ": "HÌ", 17075 "È": "HÌ", 17076 "Ĥ": "HÌ", 17077 "Ḣ": "HÌ", 17078 "Ḩ": "Ḩ", 17079 "Ã": "IÌ", 17080 "Ã": "IÌ", 17081 "Ã": "IÌ", 17082 "Ḯ": "IÌÌ", 17083 "Ĩ": "IÌ", 17084 "Ī": "IÌ", 17085 "Ĭ": "IÌ", 17086 "Ç": "IÌ", 17087 "Ã": "IÌ", 17088 "İ": "IÌ", 17089 "Ä´": "JÌ", 17090 "Ḱ": "KÌ", 17091 "Ǩ": "KÌ", 17092 "Ķ": "Ķ", 17093 "Ĺ": "LÌ", 17094 "Ľ": "LÌ", 17095 "Ä»": "Ļ", 17096 "Ḿ": "MÌ", 17097 "á¹": "MÌ", 17098 "Å": "NÌ", 17099 "Ǹ": "NÌ", 17100 "Ã": "NÌ", 17101 "Å": "NÌ", 17102 "á¹": "NÌ", 17103 "Å ": "Ņ", 17104 "Ã": "OÌ", 17105 "Ã": "OÌ", 17106 "Ã": "OÌ", 17107 "Ȫ": "OÌÌ", 17108 "Ã": "OÌ", 17109 "á¹": "OÌÌ", 17110 "á¹": "OÌÌ", 17111 "Ȭ": "OÌÌ", 17112 "Å": "OÌ", 17113 "á¹": "OÌÌ", 17114 "á¹": "OÌÌ", 17115 "Å": "OÌ", 17116 "Ç": "OÌ", 17117 "Ã": "OÌ", 17118 "á»": "OÌÌ", 17119 "á»": "OÌÌ", 17120 "á»": "OÌÌ", 17121 "È®": "OÌ", 17122 "Ȱ": "OÌÌ", 17123 "Å": "OÌ", 17124 "á¹": "PÌ", 17125 "á¹": "PÌ", 17126 "Å": "RÌ", 17127 "Å": "RÌ", 17128 "á¹": "RÌ", 17129 "Å": "Ŗ", 17130 "Å": "SÌ", 17131 "Ṥ": "SÌÌ", 17132 "Å ": "SÌ", 17133 "Ṧ": "SÌÌ", 17134 "Å": "SÌ", 17135 "á¹ ": "SÌ", 17136 "Å": "Ş", 17137 "Ť": "TÌ", 17138 "Ṫ": "TÌ", 17139 "Å¢": "Ţ", 17140 "Ã": "UÌ", 17141 "Ã": "UÌ", 17142 "Ã": "UÌ", 17143 "Ç": "UÌÌ", 17144 "Ç": "UÌÌ", 17145 "Ç": "UÌÌ", 17146 "Ç": "UÌÌ", 17147 "Ũ": "UÌ", 17148 "Ṹ": "UÌÌ", 17149 "Ū": "UÌ", 17150 "Ṻ": "UÌÌ", 17151 "Ŭ": "UÌ", 17152 "Ç": "UÌ", 17153 "Ã": "UÌ", 17154 "Å®": "UÌ", 17155 "Ű": "UÌ", 17156 "á¹¼": "VÌ", 17157 "áº": "WÌ", 17158 "áº": "WÌ", 17159 "áº": "WÌ", 17160 "Å´": "WÌ", 17161 "áº": "WÌ", 17162 "áº": "XÌ", 17163 "áº": "XÌ", 17164 "Ã": "YÌ", 17165 "Ỳ": "YÌ", 17166 "Ÿ": "YÌ", 17167 "Ỹ": "YÌ", 17168 "Ȳ": "YÌ", 17169 "Ŷ": "YÌ", 17170 "áº": "YÌ", 17171 "Ź": "ZÌ", 17172 "Ž": "ZÌ", 17173 "áº": "ZÌ", 17174 "Å»": "ZÌ", 17175 "ά": "αÌ", 17176 "á½°": "αÌ", 17177 "á¾±": "αÌ", 17178 "á¾°": "αÌ", 17179 "Î": "εÌ", 17180 "á½²": "εÌ", 17181 "ή": "ηÌ", 17182 "á½´": "ηÌ", 17183 "ί": "ιÌ", 17184 "á½¶": "ιÌ", 17185 "Ï": "ιÌ", 17186 "Î": "ιÌÌ", 17187 "á¿": "ιÌÌ", 17188 "á¿": "ιÌ", 17189 "á¿": "ιÌ", 17190 "Ï": "οÌ", 17191 "ὸ": "οÌ", 17192 "Ï": "Ï Ì", 17193 "ὺ": "Ï Ì", 17194 "Ï": "Ï Ì", 17195 "ΰ": "Ï ÌÌ", 17196 "á¿¢": "Ï ÌÌ", 17197 "á¿¡": "Ï Ì", 17198 "á¿ ": "Ï Ì", 17199 "Ï": "ÏÌ", 17200 "á½¼": "ÏÌ", 17201 "Î": "Î¥Ì", 17202 "Ὺ": "Î¥Ì", 17203 "Ϋ": "Î¥Ì", 17204 "á¿©": "Î¥Ì", 17205 "Ῠ": "Î¥Ì", 17206 "Î": "ΩÌ", 17207 "Ὼ": "ΩÌ" 17208}; 17209 17210/** 17211 * This file contains the parser used to parse out a TeX expression from the 17212 * input. Since TeX isn't context-free, standard parsers don't work particularly 17213 * well. 17214 * 17215 * The strategy of this parser is as such: 17216 * 17217 * The main functions (the `.parse...` ones) take a position in the current 17218 * parse string to parse tokens from. The lexer (found in Lexer.js, stored at 17219 * this.gullet.lexer) also supports pulling out tokens at arbitrary places. When 17220 * individual tokens are needed at a position, the lexer is called to pull out a 17221 * token, which is then used. 17222 * 17223 * The parser has a property called "mode" indicating the mode that 17224 * the parser is currently in. Currently it has to be one of "math" or 17225 * "text", which denotes whether the current environment is a math-y 17226 * one or a text-y one (e.g. inside \text). Currently, this serves to 17227 * limit the functions which can be used in text mode. 17228 * 17229 * The main functions then return an object which contains the useful data that 17230 * was parsed at its given point, and a new position at the end of the parsed 17231 * data. The main functions can call each other and continue the parsing by 17232 * using the returned position as a new starting point. 17233 * 17234 * There are also extra `.handle...` functions, which pull out some reused 17235 * functionality into self-contained functions. 17236 * 17237 * The functions return ParseNodes. 17238 */ 17239class Parser { 17240 constructor(input, settings) { 17241 this.mode = void 0; 17242 this.gullet = void 0; 17243 this.settings = void 0; 17244 this.leftrightDepth = void 0; 17245 this.nextToken = void 0; 17246 // Start in math mode 17247 this.mode = "math"; // Create a new macro expander (gullet) and (indirectly via that) also a 17248 // new lexer (mouth) for this parser (stomach, in the language of TeX) 17249 17250 this.gullet = new MacroExpander(input, settings, this.mode); // Store the settings for use in parsing 17251 17252 this.settings = settings; // Count leftright depth (for \middle errors) 17253 17254 this.leftrightDepth = 0; 17255 } 17256 /** 17257 * Checks a result to make sure it has the right type, and throws an 17258 * appropriate error otherwise. 17259 */ 17260 17261 17262 expect(text, consume) { 17263 if (consume === void 0) { 17264 consume = true; 17265 } 17266 17267 if (this.fetch().text !== text) {
vendor: 4,486 bytes, lines 17268-17438
17268 throw new ParseError("Expected '" + text + "', got '" + this.fetch().text + "'", this.fetch()); 17269 } 17270 17271 if (consume) { 17272 this.consume(); 17273 } 17274 } 17275 /** 17276 * Discards the current lookahead token, considering it consumed. 17277 */ 17278 17279 17280 consume() { 17281 this.nextToken = null; 17282 } 17283 /** 17284 * Return the current lookahead token, or if there isn't one (at the 17285 * beginning, or if the previous lookahead token was consume()d), 17286 * fetch the next token as the new lookahead token and return it. 17287 */ 17288 17289 17290 fetch() { 17291 if (this.nextToken == null) { 17292 this.nextToken = this.gullet.expandNextToken(); 17293 } 17294 17295 return this.nextToken; 17296 } 17297 /** 17298 * Switches between "text" and "math" modes. 17299 */ 17300 17301 17302 switchMode(newMode) { 17303 this.mode = newMode; 17304 this.gullet.switchMode(newMode); 17305 } 17306 /** 17307 * Main parsing function, which parses an entire input. 17308 */ 17309 17310 17311 parse() { 17312 if (!this.settings.globalGroup) { 17313 // Create a group namespace for the math expression. 17314 // (LaTeX creates a new group for every $...$, $$...$$, \[...\].) 17315 this.gullet.beginGroup(); 17316 } // Use old \color behavior (same as LaTeX's \textcolor) if requested. 17317 // We do this within the group for the math expression, so it doesn't 17318 // pollute settings.macros. 17319 17320 17321 if (this.settings.colorIsTextColor) { 17322 this.gullet.macros.set("\\color", "\\textcolor"); 17323 } 17324 17325 try { 17326 // Try to parse the input 17327 var parse = this.parseExpression(false); // If we succeeded, make sure there's an EOF at the end 17328 17329 this.expect("EOF"); // End the group namespace for the expression 17330 17331 if (!this.settings.globalGroup) { 17332 this.gullet.endGroup(); 17333 } 17334 17335 return parse; // Close any leftover groups in case of a parse error. 17336 } finally { 17337 this.gullet.endGroups(); 17338 } 17339 } 17340 /** 17341 * Fully parse a separate sequence of tokens as a separate job. 17342 * Tokens should be specified in reverse order, as in a MacroDefinition. 17343 */ 17344 17345 17346 subparse(tokens) { 17347 // Save the next token from the current job. 17348 var oldToken = this.nextToken; 17349 this.consume(); // Run the new job, terminating it with an excess '}' 17350 17351 this.gullet.pushToken(new Token("}")); 17352 this.gullet.pushTokens(tokens); 17353 var parse = this.parseExpression(false); 17354 this.expect("}"); // Restore the next token from the current job. 17355 17356 this.nextToken = oldToken; 17357 return parse; 17358 } 17359 17360 /** 17361 * Parses an "expression", which is a list of atoms. 17362 * 17363 * `breakOnInfix`: Should the parsing stop when we hit infix nodes? This 17364 * happens when functions have higher precedence han infix 17365 * nodes in implicit parses. 17366 * 17367 * `breakOnTokenText`: The text of the token that the expression should end 17368 * with, or `null` if something else should end the 17369 * expression. 17370 */ 17371 parseExpression(breakOnInfix, breakOnTokenText) { 17372 var body = []; // Keep adding atoms to the body until we can't parse any more atoms (either 17373 // we reached the end, a }, or a \right) 17374 17375 while (true) { 17376 // Ignore spaces in math mode 17377 if (this.mode === "math") { 17378 this.consumeSpaces(); 17379 } 17380 17381 var lex = this.fetch(); 17382 17383 if (Parser.endOfExpression.indexOf(lex.text) !== -1) { 17384 break; 17385 } 17386 17387 if (breakOnTokenText && lex.text === breakOnTokenText) { 17388 break; 17389 } 17390 17391 if (breakOnInfix && functions[lex.text] && functions[lex.text].infix) { 17392 break; 17393 } 17394 17395 var atom = this.parseAtom(breakOnTokenText); 17396 17397 if (!atom) { 17398 break; 17399 } else if (atom.type === "internal") { 17400 continue; 17401 } 17402 17403 body.push(atom); 17404 } 17405 17406 if (this.mode === "text") { 17407 this.formLigatures(body); 17408 } 17409 17410 return this.handleInfixNodes(body); 17411 } 17412 /** 17413 * Rewrites infix operators such as \over with corresponding commands such 17414 * as \frac. 17415 * 17416 * There can only be one infix operator per group. If there's more than one 17417 * then the expression is ambiguous. This can be resolved by adding {}. 17418 */ 17419 17420 17421 handleInfixNodes(body) { 17422 var overIndex = -1; 17423 var funcName; 17424 17425 for (var i = 0; i < body.length; i++) { 17426 if (body[i].type === "infix") { 17427 if (overIndex !== -1) { 17428 throw new ParseError("only one infix operator per group", body[i].token); 17429 } 17430 17431 overIndex = i; 17432 funcName = body[i].replaceWith; 17433 } 17434 } 17435 17436 if (overIndex !== -1 && funcName) { 17437 var numerNode; 17438 var denomNode;
vendor: 14,111 bytes, lines 17439-17976
17439 var numerBody = body.slice(0, overIndex); 17440 var denomBody = body.slice(overIndex + 1); 17441 17442 if (numerBody.length === 1 && numerBody[0].type === "ordgroup") { 17443 numerNode = numerBody[0]; 17444 } else { 17445 numerNode = { 17446 type: "ordgroup", 17447 mode: this.mode, 17448 body: numerBody 17449 }; 17450 } 17451 17452 if (denomBody.length === 1 && denomBody[0].type === "ordgroup") { 17453 denomNode = denomBody[0]; 17454 } else { 17455 denomNode = { 17456 type: "ordgroup", 17457 mode: this.mode, 17458 body: denomBody 17459 }; 17460 } 17461 17462 var node; 17463 17464 if (funcName === "\\\\abovefrac") { 17465 node = this.callFunction(funcName, [numerNode, body[overIndex], denomNode], []); 17466 } else { 17467 node = this.callFunction(funcName, [numerNode, denomNode], []); 17468 } 17469 17470 return [node]; 17471 } else { 17472 return body; 17473 } 17474 } 17475 /** 17476 * Handle a subscript or superscript with nice errors. 17477 */ 17478 17479 17480 handleSupSubscript(name // For error reporting. 17481 ) { 17482 var symbolToken = this.fetch(); 17483 var symbol = symbolToken.text; 17484 this.consume(); 17485 this.consumeSpaces(); // ignore spaces before sup/subscript argument 17486 17487 var group = this.parseGroup(name); 17488 17489 if (!group) { 17490 throw new ParseError("Expected group after '" + symbol + "'", symbolToken); 17491 } 17492 17493 return group; 17494 } 17495 /** 17496 * Converts the textual input of an unsupported command into a text node 17497 * contained within a color node whose color is determined by errorColor 17498 */ 17499 17500 17501 formatUnsupportedCmd(text) { 17502 var textordArray = []; 17503 17504 for (var i = 0; i < text.length; i++) { 17505 textordArray.push({ 17506 type: "textord", 17507 mode: "text", 17508 text: text[i] 17509 }); 17510 } 17511 17512 var textNode = { 17513 type: "text", 17514 mode: this.mode, 17515 body: textordArray 17516 }; 17517 var colorNode = { 17518 type: "color", 17519 mode: this.mode, 17520 color: this.settings.errorColor, 17521 body: [textNode] 17522 }; 17523 return colorNode; 17524 } 17525 /** 17526 * Parses a group with optional super/subscripts. 17527 */ 17528 17529 17530 parseAtom(breakOnTokenText) { 17531 // The body of an atom is an implicit group, so that things like 17532 // \left(x\right)^2 work correctly. 17533 var base = this.parseGroup("atom", breakOnTokenText); // In text mode, we don't have superscripts or subscripts 17534 17535 if (this.mode === "text") { 17536 return base; 17537 } // Note that base may be empty (i.e. null) at this point. 17538 17539 17540 var superscript; 17541 var subscript; 17542 17543 while (true) { 17544 // Guaranteed in math mode, so eat any spaces first. 17545 this.consumeSpaces(); // Lex the first token 17546 17547 var lex = this.fetch(); 17548 17549 if (lex.text === "\\limits" || lex.text === "\\nolimits") { 17550 // We got a limit control 17551 if (base && base.type === "op") { 17552 var limits = lex.text === "\\limits"; 17553 base.limits = limits; 17554 base.alwaysHandleSupSub = true; 17555 } else if (base && base.type === "operatorname") { 17556 if (base.alwaysHandleSupSub) { 17557 base.limits = lex.text === "\\limits"; 17558 } 17559 } else { 17560 throw new ParseError("Limit controls must follow a math operator", lex); 17561 } 17562 17563 this.consume(); 17564 } else if (lex.text === "^") { 17565 // We got a superscript start 17566 if (superscript) { 17567 throw new ParseError("Double superscript", lex); 17568 } 17569 17570 superscript = this.handleSupSubscript("superscript"); 17571 } else if (lex.text === "_") { 17572 // We got a subscript start 17573 if (subscript) { 17574 throw new ParseError("Double subscript", lex); 17575 } 17576 17577 subscript = this.handleSupSubscript("subscript"); 17578 } else if (lex.text === "'") { 17579 // We got a prime 17580 if (superscript) { 17581 throw new ParseError("Double superscript", lex); 17582 } 17583 17584 var prime = { 17585 type: "textord", 17586 mode: this.mode, 17587 text: "\\prime" 17588 }; // Many primes can be grouped together, so we handle this here 17589 17590 var primes = [prime]; 17591 this.consume(); // Keep lexing tokens until we get something that's not a prime 17592 17593 while (this.fetch().text === "'") { 17594 // For each one, add another prime to the list 17595 primes.push(prime); 17596 this.consume(); 17597 } // If there's a superscript following the primes, combine that 17598 // superscript in with the primes. 17599 17600 17601 if (this.fetch().text === "^") { 17602 primes.push(this.handleSupSubscript("superscript")); 17603 } // Put everything into an ordgroup as the superscript 17604 17605 17606 superscript = { 17607 type: "ordgroup", 17608 mode: this.mode, 17609 body: primes 17610 }; 17611 } else if (uSubsAndSups[lex.text]) { 17612 // A Unicode subscript or superscript character. 17613 // We treat these similarly to the unicode-math package. 17614 // So we render a string of Unicode (sub|super)scripts the 17615 // same as a (sub|super)script of regular characters. 17616 var isSub = unicodeSubRegEx.test(lex.text); 17617 var subsupTokens = []; 17618 subsupTokens.push(new Token(uSubsAndSups[lex.text])); 17619 this.consume(); // Continue fetching tokens to fill out the string. 17620 17621 while (true) { 17622 var token = this.fetch().text; 17623 17624 if (!uSubsAndSups[token]) { 17625 break; 17626 } 17627 17628 if (unicodeSubRegEx.test(token) !== isSub) { 17629 break; 17630 } 17631 17632 subsupTokens.unshift(new Token(uSubsAndSups[token])); 17633 this.consume(); 17634 } // Now create a (sub|super)script. 17635 17636 17637 var body = this.subparse(subsupTokens); 17638 17639 if (isSub) { 17640 subscript = { 17641 type: "ordgroup", 17642 mode: "math", 17643 body 17644 }; 17645 } else { 17646 superscript = { 17647 type: "ordgroup", 17648 mode: "math", 17649 body 17650 }; 17651 } 17652 } else { 17653 // If it wasn't ^, _, or ', stop parsing super/subscripts 17654 break; 17655 } 17656 } // Base must be set if superscript or subscript are set per logic above, 17657 // but need to check here for type check to pass. 17658 17659 17660 if (superscript || subscript) { 17661 // If we got either a superscript or subscript, create a supsub 17662 return { 17663 type: "supsub", 17664 mode: this.mode, 17665 base: base, 17666 sup: superscript, 17667 sub: subscript 17668 }; 17669 } else { 17670 // Otherwise return the original body 17671 return base; 17672 } 17673 } 17674 /** 17675 * Parses an entire function, including its base and all of its arguments. 17676 */ 17677 17678 17679 parseFunction(breakOnTokenText, name // For determining its context 17680 ) { 17681 var token = this.fetch(); 17682 var func = token.text; 17683 var funcData = functions[func]; 17684 17685 if (!funcData) { 17686 return null; 17687 } 17688 17689 this.consume(); // consume command token 17690 17691 if (name && name !== "atom" && !funcData.allowedInArgument) { 17692 throw new ParseError("Got function '" + func + "' with no arguments" + (name ? " as " + name : ""), token); 17693 } else if (this.mode === "text" && !funcData.allowedInText) { 17694 throw new ParseError("Can't use function '" + func + "' in text mode", token); 17695 } else if (this.mode === "math" && funcData.allowedInMath === false) { 17696 throw new ParseError("Can't use function '" + func + "' in math mode", token); 17697 } 17698 17699 var { 17700 args, 17701 optArgs 17702 } = this.parseArguments(func, funcData); 17703 return this.callFunction(func, args, optArgs, token, breakOnTokenText); 17704 } 17705 /** 17706 * Call a function handler with a suitable context and arguments. 17707 */ 17708 17709 17710 callFunction(name, args, optArgs, token, breakOnTokenText) { 17711 var context = { 17712 funcName: name, 17713 parser: this, 17714 token, 17715 breakOnTokenText 17716 }; 17717 var func = functions[name]; 17718 17719 if (func && func.handler) { 17720 return func.handler(context, args, optArgs); 17721 } else { 17722 throw new ParseError("No function handler for " + name); 17723 } 17724 } 17725 /** 17726 * Parses the arguments of a function or environment 17727 */ 17728 17729 17730 parseArguments(func, // Should look like "\name" or "\begin{name}". 17731 funcData) { 17732 var totalArgs = funcData.numArgs + funcData.numOptionalArgs; 17733 17734 if (totalArgs === 0) { 17735 return { 17736 args: [], 17737 optArgs: [] 17738 }; 17739 } 17740 17741 var args = []; 17742 var optArgs = []; 17743 17744 for (var i = 0; i < totalArgs; i++) { 17745 var argType = funcData.argTypes && funcData.argTypes[i]; 17746 var isOptional = i < funcData.numOptionalArgs; 17747 17748 if (funcData.primitive && argType == null || // \sqrt expands into primitive if optional argument doesn't exist 17749 funcData.type === "sqrt" && i === 1 && optArgs[0] == null) { 17750 argType = "primitive"; 17751 } 17752 17753 var arg = this.parseGroupOfType("argument to '" + func + "'", argType, isOptional); 17754 17755 if (isOptional) { 17756 optArgs.push(arg); 17757 } else if (arg != null) { 17758 args.push(arg); 17759 } else { 17760 // should be unreachable 17761 throw new ParseError("Null argument, please report this as a bug"); 17762 } 17763 } 17764 17765 return { 17766 args, 17767 optArgs 17768 }; 17769 } 17770 /** 17771 * Parses a group when the mode is changing. 17772 */ 17773 17774 17775 parseGroupOfType(name, type, optional) { 17776 switch (type) { 17777 case "color": 17778 return this.parseColorGroup(optional); 17779 17780 case "size": 17781 return this.parseSizeGroup(optional); 17782 17783 case "url": 17784 return this.parseUrlGroup(optional); 17785 17786 case "math": 17787 case "text": 17788 return this.parseArgumentGroup(optional, type); 17789 17790 case "hbox": 17791 { 17792 // hbox argument type wraps the argument in the equivalent of 17793 // \hbox, which is like \text but switching to \textstyle size. 17794 var group = this.parseArgumentGroup(optional, "text"); 17795 return group != null ? { 17796 type: "styling", 17797 mode: group.mode, 17798 body: [group], 17799 style: "text" // simulate \textstyle 17800 17801 } : null; 17802 } 17803 17804 case "raw": 17805 { 17806 var token = this.parseStringGroup("raw", optional); 17807 return token != null ? { 17808 type: "raw", 17809 mode: "text", 17810 string: token.text 17811 } : null; 17812 } 17813 17814 case "primitive": 17815 { 17816 if (optional) { 17817 throw new ParseError("A primitive argument cannot be optional"); 17818 } 17819 17820 var _group = this.parseGroup(name); 17821 17822 if (_group == null) { 17823 throw new ParseError("Expected group as " + name, this.fetch()); 17824 } 17825 17826 return _group; 17827 } 17828 17829 case "original": 17830 case null: 17831 case undefined: 17832 return this.parseArgumentGroup(optional); 17833 17834 default: 17835 throw new ParseError("Unknown group type as " + name, this.fetch()); 17836 } 17837 } 17838 /** 17839 * Discard any space tokens, fetching the next non-space token. 17840 */ 17841 17842 17843 consumeSpaces() { 17844 while (this.fetch().text === " ") { 17845 this.consume(); 17846 } 17847 } 17848 /** 17849 * Parses a group, essentially returning the string formed by the 17850 * brace-enclosed tokens plus some position information. 17851 */ 17852 17853 17854 parseStringGroup(modeName, // Used to describe the mode in error messages. 17855 optional) { 17856 var argToken = this.gullet.scanArgument(optional); 17857 17858 if (argToken == null) { 17859 return null; 17860 } 17861 17862 var str = ""; 17863 var nextToken; 17864 17865 while ((nextToken = this.fetch()).text !== "EOF") { 17866 str += nextToken.text; 17867 this.consume(); 17868 } 17869 17870 this.consume(); // consume the end of the argument 17871 17872 argToken.text = str; 17873 return argToken; 17874 } 17875 /** 17876 * Parses a regex-delimited group: the largest sequence of tokens 17877 * whose concatenated strings match `regex`. Returns the string 17878 * formed by the tokens plus some position information. 17879 */ 17880 17881 17882 parseRegexGroup(regex, modeName // Used to describe the mode in error messages. 17883 ) { 17884 var firstToken = this.fetch(); 17885 var lastToken = firstToken; 17886 var str = ""; 17887 var nextToken; 17888 17889 while ((nextToken = this.fetch()).text !== "EOF" && regex.test(str + nextToken.text)) { 17890 lastToken = nextToken; 17891 str += lastToken.text; 17892 this.consume(); 17893 } 17894 17895 if (str === "") { 17896 throw new ParseError("Invalid " + modeName + ": '" + firstToken.text + "'", firstToken); 17897 } 17898 17899 return firstToken.range(lastToken, str); 17900 } 17901 /** 17902 * Parses a color description. 17903 */ 17904 17905 17906 parseColorGroup(optional) { 17907 var res = this.parseStringGroup("color", optional); 17908 17909 if (res == null) { 17910 return null; 17911 } 17912 17913 var match = /^(#[a-f0-9]{3}|#?[a-f0-9]{6}|[a-z]+)$/i.exec(res.text); 17914 17915 if (!match) { 17916 throw new ParseError("Invalid color: '" + res.text + "'", res); 17917 } 17918 17919 var color = match[0]; 17920 17921 if (/^[0-9a-f]{6}$/i.test(color)) { 17922 // We allow a 6-digit HTML color spec without a leading "#". 17923 // This follows the xcolor package's HTML color model. 17924 // Predefined color names are all missed by this RegEx pattern. 17925 color = "#" + color; 17926 } 17927 17928 return { 17929 type: "color-token", 17930 mode: this.mode, 17931 color 17932 }; 17933 } 17934 /** 17935 * Parses a size specification, consisting of magnitude and unit. 17936 */ 17937 17938 17939 parseSizeGroup(optional) { 17940 var res; 17941 var isBlank = false; // don't expand before parseStringGroup 17942 17943 this.gullet.consumeSpaces(); 17944 17945 if (!optional && this.gullet.future().text !== "{") { 17946 res = this.parseRegexGroup(/^[-+]? *(?:$|\d+|\d+\.\d*|\.\d*) *[a-z]{0,2} *$/, "size"); 17947 } else { 17948 res = this.parseStringGroup("size", optional); 17949 } 17950 17951 if (!res) { 17952 return null; 17953 } 17954 17955 if (!optional && res.text.length === 0) { 17956 // Because we've tested for what is !optional, this block won't 17957 // affect \kern, \hspace, etc. It will capture the mandatory arguments 17958 // to \genfrac and \above. 17959 res.text = "0pt"; // Enable \above{} 17960 17961 isBlank = true; // This is here specifically for \genfrac 17962 } 17963 17964 var match = /([-+]?) *(\d+(?:\.\d*)?|\.\d+) *([a-z]{2})/.exec(res.text); 17965 17966 if (!match) { 17967 throw new ParseError("Invalid size: '" + res.text + "'", res); 17968 } 17969 17970 var data = { 17971 number: +(match[1] + match[2]), 17972 // sign + magnitude, cast to number 17973 unit: match[3] 17974 }; 17975 17976 if (!validUnit(data)) {
vendor: 11,167 bytes, lines 17977-18353
17977 throw new ParseError("Invalid unit: '" + data.unit + "'", res); 17978 } 17979 17980 return { 17981 type: "size", 17982 mode: this.mode, 17983 value: data, 17984 isBlank 17985 }; 17986 } 17987 /** 17988 * Parses an URL, checking escaped letters and allowed protocols, 17989 * and setting the catcode of % as an active character (as in \hyperref). 17990 */ 17991 17992 17993 parseUrlGroup(optional) { 17994 this.gullet.lexer.setCatcode("%", 13); // active character 17995 17996 this.gullet.lexer.setCatcode("~", 12); // other character 17997 17998 var res = this.parseStringGroup("url", optional); 17999 this.gullet.lexer.setCatcode("%", 14); // comment character 18000 18001 this.gullet.lexer.setCatcode("~", 13); // active character 18002 18003 if (res == null) { 18004 return null; 18005 } // hyperref package allows backslashes alone in href, but doesn't 18006 // generate valid links in such cases; we interpret this as 18007 // "undefined" behaviour, and keep them as-is. Some browser will 18008 // replace backslashes with forward slashes. 18009 18010 18011 var url = res.text.replace(/\\([#$%&~_^{}])/g, '$1'); 18012 return { 18013 type: "url", 18014 mode: this.mode, 18015 url 18016 }; 18017 } 18018 /** 18019 * Parses an argument with the mode specified. 18020 */ 18021 18022 18023 parseArgumentGroup(optional, mode) { 18024 var argToken = this.gullet.scanArgument(optional); 18025 18026 if (argToken == null) { 18027 return null; 18028 } 18029 18030 var outerMode = this.mode; 18031 18032 if (mode) { 18033 // Switch to specified mode 18034 this.switchMode(mode); 18035 } 18036 18037 this.gullet.beginGroup(); 18038 var expression = this.parseExpression(false, "EOF"); // TODO: find an alternative way to denote the end 18039 18040 this.expect("EOF"); // expect the end of the argument 18041 18042 this.gullet.endGroup(); 18043 var result = { 18044 type: "ordgroup", 18045 mode: this.mode, 18046 loc: argToken.loc, 18047 body: expression 18048 }; 18049 18050 if (mode) { 18051 // Switch mode back 18052 this.switchMode(outerMode); 18053 } 18054 18055 return result; 18056 } 18057 /** 18058 * Parses an ordinary group, which is either a single nucleus (like "x") 18059 * or an expression in braces (like "{x+y}") or an implicit group, a group 18060 * that starts at the current position, and ends right before a higher explicit 18061 * group ends, or at EOF. 18062 */ 18063 18064 18065 parseGroup(name, // For error reporting. 18066 breakOnTokenText) { 18067 var firstToken = this.fetch(); 18068 var text = firstToken.text; 18069 var result; // Try to parse an open brace or \begingroup 18070 18071 if (text === "{" || text === "\\begingroup") { 18072 this.consume(); 18073 var groupEnd = text === "{" ? "}" : "\\endgroup"; 18074 this.gullet.beginGroup(); // If we get a brace, parse an expression 18075 18076 var expression = this.parseExpression(false, groupEnd); 18077 var lastToken = this.fetch(); 18078 this.expect(groupEnd); // Check that we got a matching closing brace 18079 18080 this.gullet.endGroup(); 18081 result = { 18082 type: "ordgroup", 18083 mode: this.mode, 18084 loc: SourceLocation.range(firstToken, lastToken), 18085 body: expression, 18086 // A group formed by \begingroup...\endgroup is a semi-simple group 18087 // which doesn't affect spacing in math mode, i.e., is transparent. 18088 // https://tex.stackexchange.com/questions/1930/when-should-one- 18089 // use-begingroup-instead-of-bgroup 18090 semisimple: text === "\\begingroup" || undefined 18091 }; 18092 } else { 18093 // If there exists a function with this name, parse the function. 18094 // Otherwise, just return a nucleus 18095 result = this.parseFunction(breakOnTokenText, name) || this.parseSymbol(); 18096 18097 if (result == null && text[0] === "\\" && !implicitCommands.hasOwnProperty(text)) { 18098 if (this.settings.throwOnError) { 18099 throw new ParseError("Undefined control sequence: " + text, firstToken); 18100 } 18101 18102 result = this.formatUnsupportedCmd(text); 18103 this.consume(); 18104 } 18105 } 18106 18107 return result; 18108 } 18109 /** 18110 * Form ligature-like combinations of characters for text mode. 18111 * This includes inputs like "--", "---", "``" and "''". 18112 * The result will simply replace multiple textord nodes with a single 18113 * character in each value by a single textord node having multiple 18114 * characters in its value. The representation is still ASCII source. 18115 * The group will be modified in place. 18116 */ 18117 18118 18119 formLigatures(group) { 18120 var n = group.length - 1; 18121 18122 for (var i = 0; i < n; ++i) { 18123 var a = group[i]; // $FlowFixMe: Not every node type has a `text` property. 18124 18125 var v = a.text; 18126 18127 if (v === "-" && group[i + 1].text === "-") { 18128 if (i + 1 < n && group[i + 2].text === "-") { 18129 group.splice(i, 3, { 18130 type: "textord", 18131 mode: "text", 18132 loc: SourceLocation.range(a, group[i + 2]), 18133 text: "---" 18134 }); 18135 n -= 2; 18136 } else { 18137 group.splice(i, 2, { 18138 type: "textord", 18139 mode: "text", 18140 loc: SourceLocation.range(a, group[i + 1]), 18141 text: "--" 18142 }); 18143 n -= 1; 18144 } 18145 } 18146 18147 if ((v === "'" || v === "`") && group[i + 1].text === v) { 18148 group.splice(i, 2, { 18149 type: "textord", 18150 mode: "text", 18151 loc: SourceLocation.range(a, group[i + 1]), 18152 text: v + v 18153 }); 18154 n -= 1; 18155 } 18156 } 18157 } 18158 /** 18159 * Parse a single symbol out of the string. Here, we handle single character 18160 * symbols and special functions like \verb. 18161 */ 18162 18163 18164 parseSymbol() { 18165 var nucleus = this.fetch(); 18166 var text = nucleus.text; 18167 18168 if (/^\\verb[^a-zA-Z]/.test(text)) { 18169 this.consume(); 18170 var arg = text.slice(5); 18171 var star = arg.charAt(0) === "*"; 18172 18173 if (star) { 18174 arg = arg.slice(1); 18175 } // Lexer's tokenRegex is constructed to always have matching 18176 // first/last characters. 18177 18178 18179 if (arg.length < 2 || arg.charAt(0) !== arg.slice(-1)) { 18180 throw new ParseError("\\verb assertion failed --\n please report what input caused this bug"); 18181 } 18182 18183 arg = arg.slice(1, -1); // remove first and last char 18184 18185 return { 18186 type: "verb", 18187 mode: "text", 18188 body: arg, 18189 star 18190 }; 18191 } // At this point, we should have a symbol, possibly with accents. 18192 // First expand any accented base symbol according to unicodeSymbols. 18193 18194 18195 if (unicodeSymbols.hasOwnProperty(text[0]) && !symbols[this.mode][text[0]]) { 18196 // This behavior is not strict (XeTeX-compatible) in math mode. 18197 if (this.settings.strict && this.mode === "math") { 18198 this.settings.reportNonstrict("unicodeTextInMathMode", "Accented Unicode text character \"" + text[0] + "\" used in " + "math mode", nucleus); 18199 } 18200 18201 text = unicodeSymbols[text[0]] + text.slice(1); 18202 } // Strip off any combining characters 18203 18204 18205 var match = combiningDiacriticalMarksEndRegex.exec(text); 18206 18207 if (match) { 18208 text = text.substring(0, match.index); 18209 18210 if (text === 'i') { 18211 text = '\u0131'; // dotless i, in math and text mode 18212 } else if (text === 'j') { 18213 text = '\u0237'; // dotless j, in math and text mode 18214 } 18215 } // Recognize base symbol 18216 18217 18218 var symbol; 18219 18220 if (symbols[this.mode][text]) { 18221 if (this.settings.strict && this.mode === 'math' && extraLatin.indexOf(text) >= 0) { 18222 this.settings.reportNonstrict("unicodeTextInMathMode", "Latin-1/Unicode text character \"" + text[0] + "\" used in " + "math mode", nucleus); 18223 } 18224 18225 var group = symbols[this.mode][text].group; 18226 var loc = SourceLocation.range(nucleus); 18227 var s; 18228 18229 if (ATOMS.hasOwnProperty(group)) { 18230 // $FlowFixMe 18231 var family = group; 18232 s = { 18233 type: "atom", 18234 mode: this.mode, 18235 family, 18236 loc, 18237 text 18238 }; 18239 } else { 18240 // $FlowFixMe 18241 s = { 18242 type: group, 18243 mode: this.mode, 18244 loc, 18245 text 18246 }; 18247 } // $FlowFixMe 18248 18249 18250 symbol = s; 18251 } else if (text.charCodeAt(0) >= 0x80) { 18252 // no symbol for e.g. ^ 18253 if (this.settings.strict) { 18254 if (!supportedCodepoint(text.charCodeAt(0))) { 18255 this.settings.reportNonstrict("unknownSymbol", "Unrecognized Unicode character \"" + text[0] + "\"" + (" (" + text.charCodeAt(0) + ")"), nucleus); 18256 } else if (this.mode === "math") { 18257 this.settings.reportNonstrict("unicodeTextInMathMode", "Unicode text character \"" + text[0] + "\" used in math mode", nucleus); 18258 } 18259 } // All nonmathematical Unicode characters are rendered as if they 18260 // are in text mode (wrapped in \text) because that's what it 18261 // takes to render them in LaTeX. Setting `mode: this.mode` is 18262 // another natural choice (the user requested math mode), but 18263 // this makes it more difficult for getCharacterMetrics() to 18264 // distinguish Unicode characters without metrics and those for 18265 // which we want to simulate the letter M. 18266 18267 18268 symbol = { 18269 type: "textord", 18270 mode: "text", 18271 loc: SourceLocation.range(nucleus), 18272 text 18273 }; 18274 } else { 18275 return null; // EOF, ^, _, {, }, etc. 18276 } 18277 18278 this.consume(); // Transform combining characters into accents 18279 18280 if (match) { 18281 for (var i = 0; i < match[0].length; i++) { 18282 var accent = match[0][i]; 18283 18284 if (!unicodeAccents[accent]) { 18285 throw new ParseError("Unknown accent ' " + accent + "'", nucleus); 18286 } 18287 18288 var command = unicodeAccents[accent][this.mode] || unicodeAccents[accent].text; 18289 18290 if (!command) { 18291 throw new ParseError("Accent " + accent + " unsupported in " + this.mode + " mode", nucleus); 18292 } 18293 18294 symbol = { 18295 type: "accent", 18296 mode: this.mode, 18297 loc: SourceLocation.range(nucleus), 18298 label: command, 18299 isStretchy: false, 18300 isShifty: true, 18301 // $FlowFixMe 18302 base: symbol 18303 }; 18304 } 18305 } // $FlowFixMe 18306 18307 18308 return symbol; 18309 } 18310 18311} 18312Parser.endOfExpression = ["}", "\\endgroup", "\\end", "\\right", "&"]; 18313 18314/** 18315 * Provides a single function for parsing an expression using a Parser 18316 * TODO(emily): Remove this 18317 */ 18318 18319/** 18320 * Parses an expression using a Parser, then returns the parsed result. 18321 */ 18322var parseTree = function parseTree(toParse, settings) { 18323 if (!(typeof toParse === 'string' || toParse instanceof String)) { 18324 throw new TypeError('KaTeX can only parse string typed expression'); 18325 } 18326 18327 var parser = new Parser(toParse, settings); // Blank out any \df@tag to avoid spurious "Duplicate \tag" errors 18328 18329 delete parser.gullet.macros.current["\\df@tag"]; 18330 var tree = parser.parse(); // Prevent a color definition from persisting between calls to katex.render(). 18331 18332 delete parser.gullet.macros.current["\\current@color"]; 18333 delete parser.gullet.macros.current["\\color"]; // If the input used \tag, it will set the \df@tag macro to the tag. 18334 // In this case, we separately parse the tag and wrap the tree. 18335 18336 if (parser.gullet.macros.get("\\df@tag")) { 18337 if (!settings.displayMode) { 18338 throw new ParseError("\\tag works only in display equations"); 18339 } 18340 18341 tree = [{ 18342 type: "tag", 18343 mode: "text", 18344 body: tree, 18345 tag: parser.subparse([new Token("\\df@tag")]) 18346 }]; 18347 } 18348 18349 return tree; 18350}; 18351 18352/* eslint no-console:0 */ 18353
vendor: 4,558 bytes, lines 18354-18519
18354/** 18355 * Parse and build an expression, and place that expression in the DOM node 18356 * given. 18357 */ 18358var render = function render(expression, baseNode, options) { 18359 baseNode.textContent = ""; 18360 var node = renderToDomTree(expression, options).toNode(); 18361 baseNode.appendChild(node); 18362}; // KaTeX's styles don't work properly in quirks mode. Print out an error, and 18363// disable rendering. 18364 18365 18366if (typeof document !== "undefined") { 18367 if (document.compatMode !== "CSS1Compat") { 18368 typeof console !== "undefined" && console.warn("Warning: KaTeX doesn't work in quirks mode. Make sure your " + "website has a suitable doctype."); 18369 18370 render = function render() { 18371 throw new ParseError("KaTeX doesn't work in quirks mode."); 18372 }; 18373 } 18374} 18375/** 18376 * Parse and build an expression, and return the markup for that. 18377 */ 18378 18379 18380var renderToString = function renderToString(expression, options) { 18381 var markup = renderToDomTree(expression, options).toMarkup(); 18382 return markup; 18383}; 18384/** 18385 * Parse an expression and return the parse tree. 18386 */ 18387 18388 18389var generateParseTree = function generateParseTree(expression, options) { 18390 var settings = new Settings(options); 18391 return parseTree(expression, settings); 18392}; 18393/** 18394 * If the given error is a KaTeX ParseError and options.throwOnError is false, 18395 * renders the invalid LaTeX as a span with hover title giving the KaTeX 18396 * error message. Otherwise, simply throws the error. 18397 */ 18398 18399 18400var renderError = function renderError(error, expression, options) { 18401 if (options.throwOnError || !(error instanceof ParseError)) { 18402 throw error; 18403 } 18404 18405 var node = buildCommon.makeSpan(["katex-error"], [new SymbolNode(expression)]); 18406 node.setAttribute("title", error.toString()); 18407 node.setAttribute("style", "color:" + options.errorColor); 18408 return node; 18409}; 18410/** 18411 * Generates and returns the katex build tree. This is used for advanced 18412 * use cases (like rendering to custom output). 18413 */ 18414 18415 18416var renderToDomTree = function renderToDomTree(expression, options) { 18417 var settings = new Settings(options); 18418 18419 try { 18420 var tree = parseTree(expression, settings); 18421 return buildTree(tree, expression, settings); 18422 } catch (error) { 18423 return renderError(error, expression, settings); 18424 } 18425}; 18426/** 18427 * Generates and returns the katex build tree, with just HTML (no MathML). 18428 * This is used for advanced use cases (like rendering to custom output). 18429 */ 18430 18431 18432var renderToHTMLTree = function renderToHTMLTree(expression, options) { 18433 var settings = new Settings(options); 18434 18435 try { 18436 var tree = parseTree(expression, settings); 18437 return buildHTMLTree(tree, expression, settings); 18438 } catch (error) { 18439 return renderError(error, expression, settings); 18440 } 18441}; 18442 18443var version = "0.16.21"; 18444var __domTree = { 18445 Span, 18446 Anchor, 18447 SymbolNode, 18448 SvgNode, 18449 PathNode, 18450 LineNode 18451}; // ESM exports 18452 18453var katex = { 18454 /** 18455 * Current KaTeX version 18456 */ 18457 version, 18458 18459 /** 18460 * Renders the given LaTeX into an HTML+MathML combination, and adds 18461 * it as a child to the specified DOM node. 18462 */ 18463 render, 18464 18465 /** 18466 * Renders the given LaTeX into an HTML+MathML combination string, 18467 * for sending to the client. 18468 */ 18469 renderToString, 18470 18471 /** 18472 * KaTeX error, usually during parsing. 18473 */ 18474 ParseError, 18475 18476 /** 18477 * The schema of Settings 18478 */ 18479 SETTINGS_SCHEMA, 18480 18481 /** 18482 * Parses the given LaTeX into KaTeX's internal parse tree structure, 18483 * without rendering to HTML or MathML. 18484 * 18485 * NOTE: This method is not currently recommended for public use. 18486 * The internal tree representation is unstable and is very likely 18487 * to change. Use at your own risk. 18488 */ 18489 __parse: generateParseTree, 18490 18491 /** 18492 * Renders the given LaTeX into an HTML+MathML internal DOM tree 18493 * representation, without flattening that representation to a string. 18494 * 18495 * NOTE: This method is not currently recommended for public use. 18496 * The internal tree representation is unstable and is very likely 18497 * to change. Use at your own risk. 18498 */ 18499 __renderToDomTree: renderToDomTree, 18500 18501 /** 18502 * Renders the given LaTeX into an HTML internal DOM tree representation, 18503 * without MathML and without flattening that representation to a string. 18504 * 18505 * NOTE: This method is not currently recommended for public use. 18506 * The internal tree representation is unstable and is very likely 18507 * to change. Use at your own risk. 18508 */ 18509 __renderToHTMLTree: renderToHTMLTree, 18510 18511 /** 18512 * extends internal font metrics object with a new object 18513 * each key in the new object represents a font name 18514 */ 18515 __setFontMetrics: setFontMetrics, 18516 18517 /** 18518 * adds a new symbol to builtin symbols table 18519 */
18520 __defineSymbol: defineSymbol, 18521 18522 /** 18523 * adds a new function to builtin function list, 18524 * which directly produce parse tree elements 18525 * and have their own html/mathml builders 18526 */ 18527 __defineFunction: defineFunction, 18528 18529 /** 18530 * adds a new macro to builtin macro list 18531 */ 18532 __defineMacro: defineMacro, 18533 18534 /** 18535 * Expose the dom tree node types, which can be useful for type checking nodes. 18536 * 18537 * NOTE: These methods are not currently recommended for public use. 18538 * The internal tree representation is unstable and is very likely 18539 * to change. Use at your own risk. 18540 */ 18541 __domTree 18542}; 18543 18544 18545 18546 18547/***/ }) 18548 18549}]);
Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.