Spaces:
Running
on
T4
Running
on
T4
da03
commited on
Commit
·
b498cbf
1
Parent(s):
a3459d2
- app.py +9 -2
- katex/LICENSE.txt +27 -0
- katex/README.md +68 -0
- katex/cli.js +32 -0
- katex/katex.js +74 -0
- katex/package.json +108 -0
- katex/src/Lexer.js +162 -0
- katex/src/Options.js +189 -0
- katex/src/ParseError.js +40 -0
- katex/src/Parser.js +798 -0
- katex/src/Settings.js +28 -0
- katex/src/Style.js +126 -0
- katex/src/buildCommon.js +450 -0
- katex/src/buildHTML.js +1402 -0
- katex/src/buildMathML.js +533 -0
- katex/src/buildTree.js +40 -0
- katex/src/delimiter.js +542 -0
- katex/src/domTree.js +269 -0
- katex/src/environments.js +298 -0
- katex/src/fontMetrics.js +147 -0
- katex/src/fontMetricsData.js +1752 -0
- katex/src/functions.js +585 -0
- katex/src/mathMLTree.js +102 -0
- katex/src/parseData.js +13 -0
- katex/src/parseTree.js +17 -0
- katex/src/symbols.js +687 -0
- katex/src/utils.js +106 -0
- match-at/README.md +1 -0
- match-at/lib/__tests__/matchAt-test.js +90 -0
- match-at/lib/matchAt.js +42 -0
- match-at/package.json +54 -0
- preprocess_latex.js +395 -0
app.py
CHANGED
|
@@ -12,6 +12,8 @@ import diffusers
|
|
| 12 |
from diffusers import DDPMPipeline
|
| 13 |
from transformers import AutoTokenizer, AutoModel
|
| 14 |
|
|
|
|
|
|
|
| 15 |
tz = timezone('EST')
|
| 16 |
|
| 17 |
API_ENDPOINT = os.getenv('API_ENDPOINT')
|
|
@@ -83,8 +85,13 @@ with gr.Blocks() as demo:
|
|
| 83 |
current_time = datetime.now(tz)
|
| 84 |
print (current_time, formula)
|
| 85 |
data = {'formula': formula, 'api_key': API_KEY}
|
| 86 |
-
|
| 87 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 88 |
|
| 89 |
try:
|
| 90 |
i = 0
|
|
|
|
| 12 |
from diffusers import DDPMPipeline
|
| 13 |
from transformers import AutoTokenizer, AutoModel
|
| 14 |
|
| 15 |
+
from utils import normalize_formula
|
| 16 |
+
|
| 17 |
tz = timezone('EST')
|
| 18 |
|
| 19 |
API_ENDPOINT = os.getenv('API_ENDPOINT')
|
|
|
|
| 85 |
current_time = datetime.now(tz)
|
| 86 |
print (current_time, formula)
|
| 87 |
data = {'formula': formula, 'api_key': API_KEY}
|
| 88 |
+
try:
|
| 89 |
+
formula_normalized = normalize_formula(formula)
|
| 90 |
+
except Exception as e:
|
| 91 |
+
print (e)
|
| 92 |
+
formula_normalized = formula
|
| 93 |
+
print ('normalized', formula_normalized)
|
| 94 |
+
encoder_hidden_states = forward_encoder(formula_normalized)
|
| 95 |
|
| 96 |
try:
|
| 97 |
i = 0
|
katex/LICENSE.txt
ADDED
|
@@ -0,0 +1,27 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
The MIT License (MIT)
|
| 2 |
+
|
| 3 |
+
Copyright (c) 2015 Khan Academy
|
| 4 |
+
|
| 5 |
+
This software also uses portions of the underscore.js project, which is
|
| 6 |
+
MIT licensed with the following copyright:
|
| 7 |
+
|
| 8 |
+
Copyright (c) 2009-2015 Jeremy Ashkenas, DocumentCloud and Investigative
|
| 9 |
+
Reporters & Editors
|
| 10 |
+
|
| 11 |
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
| 12 |
+
of this software and associated documentation files (the "Software"), to deal
|
| 13 |
+
in the Software without restriction, including without limitation the rights
|
| 14 |
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
| 15 |
+
copies of the Software, and to permit persons to whom the Software is
|
| 16 |
+
furnished to do so, subject to the following conditions:
|
| 17 |
+
|
| 18 |
+
The above copyright notice and this permission notice shall be included in all
|
| 19 |
+
copies or substantial portions of the Software.
|
| 20 |
+
|
| 21 |
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
| 22 |
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
| 23 |
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
| 24 |
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
| 25 |
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
| 26 |
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
| 27 |
+
SOFTWARE.
|
katex/README.md
ADDED
|
@@ -0,0 +1,68 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
# [<img src="https://khan.github.io/KaTeX/katex-logo.svg" width="130" alt="KaTeX">](https://khan.github.io/KaTeX/) [](https://travis-ci.org/Khan/KaTeX)
|
| 2 |
+
|
| 3 |
+
[](https://gitter.im/Khan/KaTeX?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge)
|
| 4 |
+
|
| 5 |
+
KaTeX is a fast, easy-to-use JavaScript library for TeX math rendering on the web.
|
| 6 |
+
|
| 7 |
+
* **Fast:** KaTeX renders its math synchronously and doesn't need to reflow the page. See how it compares to a competitor in [this speed test](http://jsperf.com/katex-vs-mathjax/).
|
| 8 |
+
* **Print quality:** KaTeX’s layout is based on Donald Knuth’s TeX, the gold standard for math typesetting.
|
| 9 |
+
* **Self contained:** KaTeX has no dependencies and can easily be bundled with your website resources.
|
| 10 |
+
* **Server side rendering:** KaTeX produces the same output regardless of browser or environment, so you can pre-render expressions using Node.js and send them as plain HTML.
|
| 11 |
+
|
| 12 |
+
KaTeX supports all major browsers, including Chrome, Safari, Firefox, Opera, and IE 8 - IE 11. A list of supported commands can be on the [wiki](https://github.com/Khan/KaTeX/wiki/Function-Support-in-KaTeX).
|
| 13 |
+
|
| 14 |
+
## Usage
|
| 15 |
+
|
| 16 |
+
You can [download KaTeX](https://github.com/khan/katex/releases) and host it on your server or include the `katex.min.js` and `katex.min.css` files on your page directly from a CDN:
|
| 17 |
+
|
| 18 |
+
```html
|
| 19 |
+
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/KaTeX/0.5.1/katex.min.css">
|
| 20 |
+
<script src="https://cdnjs.cloudflare.com/ajax/libs/KaTeX/0.5.1/katex.min.js"></script>
|
| 21 |
+
```
|
| 22 |
+
|
| 23 |
+
#### In-browser rendering
|
| 24 |
+
|
| 25 |
+
Call `katex.render` with a TeX expression and a DOM element to render into:
|
| 26 |
+
|
| 27 |
+
```js
|
| 28 |
+
katex.render("c = \\pm\\sqrt{a^2 + b^2}", element);
|
| 29 |
+
```
|
| 30 |
+
|
| 31 |
+
If KaTeX can't parse the expression, it throws a `katex.ParseError` error.
|
| 32 |
+
|
| 33 |
+
#### Server side rendering or rendering to a string
|
| 34 |
+
|
| 35 |
+
To generate HTML on the server or to generate an HTML string of the rendered math, you can use `katex.renderToString`:
|
| 36 |
+
|
| 37 |
+
```js
|
| 38 |
+
var html = katex.renderToString("c = \\pm\\sqrt{a^2 + b^2}");
|
| 39 |
+
// '<span class="katex">...</span>'
|
| 40 |
+
```
|
| 41 |
+
|
| 42 |
+
Make sure to include the CSS and font files, but there is no need to include the JavaScript. Like `render`, `renderToString` throws if it can't parse the expression.
|
| 43 |
+
|
| 44 |
+
#### Rendering options
|
| 45 |
+
|
| 46 |
+
You can provide an object of options as the last argument to `katex.render` and `katex.renderToString`. Available options are:
|
| 47 |
+
|
| 48 |
+
- `displayMode`: `boolean`. If `true` the math will be rendered in display mode, which will put the math in display style (so `\int` and `\sum` are large, for example), and will center the math on the page on its own line. If `false` the math will be rendered in inline mode. (default: `false`)
|
| 49 |
+
- `throwOnError`: `boolean`. If `true`, KaTeX will throw a `ParseError` when it encounters an unsupported command. If `false`, KaTeX will render the unsupported command as text in the color given by `errorColor`. (default: `true`)
|
| 50 |
+
- `errorColor`: `string`. A color string given in the format `"#XXX"` or `"#XXXXXX"`. This option determines the color which unsupported commands are rendered in. (default: `#cc0000`)
|
| 51 |
+
|
| 52 |
+
For example:
|
| 53 |
+
|
| 54 |
+
```js
|
| 55 |
+
katex.render("c = \\pm\\sqrt{a^2 + b^2}", element, { displayMode: true });
|
| 56 |
+
```
|
| 57 |
+
|
| 58 |
+
#### Automatic rendering of math on a page
|
| 59 |
+
|
| 60 |
+
Math on the page can be automatically rendered using the auto-render extension. See [the Auto-render README](contrib/auto-render/README.md) for more information.
|
| 61 |
+
|
| 62 |
+
## Contributing
|
| 63 |
+
|
| 64 |
+
See [CONTRIBUTING.md](CONTRIBUTING.md)
|
| 65 |
+
|
| 66 |
+
## License
|
| 67 |
+
|
| 68 |
+
KaTeX is licensed under the [MIT License](http://opensource.org/licenses/MIT).
|
katex/cli.js
ADDED
|
@@ -0,0 +1,32 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
#!/usr/bin/env node
|
| 2 |
+
// Simple CLI for KaTeX.
|
| 3 |
+
// Reads TeX from stdin, outputs HTML to stdout.
|
| 4 |
+
/* eslint no-console:0 */
|
| 5 |
+
|
| 6 |
+
var katex = require("./");
|
| 7 |
+
var input = "";
|
| 8 |
+
|
| 9 |
+
// Skip the first two args, which are just "node" and "cli.js"
|
| 10 |
+
var args = process.argv.slice(2);
|
| 11 |
+
|
| 12 |
+
if (args.indexOf("--help") !== -1) {
|
| 13 |
+
console.log(process.argv[0] + " " + process.argv[1] +
|
| 14 |
+
" [ --help ]" +
|
| 15 |
+
" [ --display-mode ]");
|
| 16 |
+
|
| 17 |
+
console.log("\n" +
|
| 18 |
+
"Options:");
|
| 19 |
+
console.log(" --help Display this help message");
|
| 20 |
+
console.log(" --display-mode Render in display mode (not inline mode)");
|
| 21 |
+
process.exit();
|
| 22 |
+
}
|
| 23 |
+
|
| 24 |
+
process.stdin.on("data", function(chunk) {
|
| 25 |
+
input += chunk.toString();
|
| 26 |
+
});
|
| 27 |
+
|
| 28 |
+
process.stdin.on("end", function() {
|
| 29 |
+
var options = { displayMode: args.indexOf("--display-mode") !== -1 };
|
| 30 |
+
var output = katex.renderToString(input, options);
|
| 31 |
+
console.log(output);
|
| 32 |
+
});
|
katex/katex.js
ADDED
|
@@ -0,0 +1,74 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
/* eslint no-console:0 */
|
| 2 |
+
/**
|
| 3 |
+
* This is the main entry point for KaTeX. Here, we expose functions for
|
| 4 |
+
* rendering expressions either to DOM nodes or to markup strings.
|
| 5 |
+
*
|
| 6 |
+
* We also expose the ParseError class to check if errors thrown from KaTeX are
|
| 7 |
+
* errors in the expression, or errors in javascript handling.
|
| 8 |
+
*/
|
| 9 |
+
|
| 10 |
+
var ParseError = require("./src/ParseError");
|
| 11 |
+
var Settings = require("./src/Settings");
|
| 12 |
+
|
| 13 |
+
var buildTree = require("./src/buildTree");
|
| 14 |
+
var parseTree = require("./src/parseTree");
|
| 15 |
+
var utils = require("./src/utils");
|
| 16 |
+
|
| 17 |
+
/**
|
| 18 |
+
* Parse and build an expression, and place that expression in the DOM node
|
| 19 |
+
* given.
|
| 20 |
+
*/
|
| 21 |
+
var render = function(expression, baseNode, options) {
|
| 22 |
+
utils.clearNode(baseNode);
|
| 23 |
+
|
| 24 |
+
var settings = new Settings(options);
|
| 25 |
+
|
| 26 |
+
var tree = parseTree(expression, settings);
|
| 27 |
+
var node = buildTree(tree, expression, settings).toNode();
|
| 28 |
+
|
| 29 |
+
baseNode.appendChild(node);
|
| 30 |
+
};
|
| 31 |
+
|
| 32 |
+
// KaTeX's styles don't work properly in quirks mode. Print out an error, and
|
| 33 |
+
// disable rendering.
|
| 34 |
+
if (typeof document !== "undefined") {
|
| 35 |
+
if (document.compatMode !== "CSS1Compat") {
|
| 36 |
+
typeof console !== "undefined" && console.warn(
|
| 37 |
+
"Warning: KaTeX doesn't work in quirks mode. Make sure your " +
|
| 38 |
+
"website has a suitable doctype.");
|
| 39 |
+
|
| 40 |
+
render = function() {
|
| 41 |
+
throw new ParseError("KaTeX doesn't work in quirks mode.");
|
| 42 |
+
};
|
| 43 |
+
}
|
| 44 |
+
}
|
| 45 |
+
|
| 46 |
+
/**
|
| 47 |
+
* Parse and build an expression, and return the markup for that.
|
| 48 |
+
*/
|
| 49 |
+
var renderToString = function(expression, options) {
|
| 50 |
+
var settings = new Settings(options);
|
| 51 |
+
|
| 52 |
+
var tree = parseTree(expression, settings);
|
| 53 |
+
return buildTree(tree, expression, settings).toMarkup();
|
| 54 |
+
};
|
| 55 |
+
|
| 56 |
+
/**
|
| 57 |
+
* Parse an expression and return the parse tree.
|
| 58 |
+
*/
|
| 59 |
+
var generateParseTree = function(expression, options) {
|
| 60 |
+
var settings = new Settings(options);
|
| 61 |
+
return parseTree(expression, settings);
|
| 62 |
+
};
|
| 63 |
+
|
| 64 |
+
module.exports = {
|
| 65 |
+
render: render,
|
| 66 |
+
renderToString: renderToString,
|
| 67 |
+
/**
|
| 68 |
+
* NOTE: This method is not currently recommended for public use.
|
| 69 |
+
* The internal tree representation is unstable and is very likely
|
| 70 |
+
* to change. Use at your own risk.
|
| 71 |
+
*/
|
| 72 |
+
__parse: generateParseTree,
|
| 73 |
+
ParseError: ParseError,
|
| 74 |
+
};
|
katex/package.json
ADDED
|
@@ -0,0 +1,108 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
{
|
| 2 |
+
"_args": [
|
| 3 |
+
[
|
| 4 |
+
"katex",
|
| 5 |
+
"/home/srush/Projects/im2latex"
|
| 6 |
+
]
|
| 7 |
+
],
|
| 8 |
+
"_from": "katex@latest",
|
| 9 |
+
"_id": "[email protected]",
|
| 10 |
+
"_inCache": true,
|
| 11 |
+
"_installable": true,
|
| 12 |
+
"_location": "/katex",
|
| 13 |
+
"_nodeVersion": "4.2.1",
|
| 14 |
+
"_npmOperationalInternal": {
|
| 15 |
+
"host": "packages-12-west.internal.npmjs.com",
|
| 16 |
+
"tmp": "tmp/katex-0.6.0.tgz_1460769444991_0.38667152682319283"
|
| 17 |
+
},
|
| 18 |
+
"_npmUser": {
|
| 19 |
+
"email": "[email protected]",
|
| 20 |
+
"name": "kevinbarabash"
|
| 21 |
+
},
|
| 22 |
+
"_npmVersion": "2.15.2",
|
| 23 |
+
"_phantomChildren": {},
|
| 24 |
+
"_requested": {
|
| 25 |
+
"name": "katex",
|
| 26 |
+
"raw": "katex",
|
| 27 |
+
"rawSpec": "",
|
| 28 |
+
"scope": null,
|
| 29 |
+
"spec": "latest",
|
| 30 |
+
"type": "tag"
|
| 31 |
+
},
|
| 32 |
+
"_requiredBy": [
|
| 33 |
+
"#USER"
|
| 34 |
+
],
|
| 35 |
+
"_resolved": "https://registry.npmjs.org/katex/-/katex-0.6.0.tgz",
|
| 36 |
+
"_shasum": "12418e09121c05c92041b6b3b9fb6bab213cb6f3",
|
| 37 |
+
"_shrinkwrap": null,
|
| 38 |
+
"_spec": "katex",
|
| 39 |
+
"_where": "/home/srush/Projects/im2latex",
|
| 40 |
+
"bin": {
|
| 41 |
+
"katex": "cli.js"
|
| 42 |
+
},
|
| 43 |
+
"bugs": {
|
| 44 |
+
"url": "https://github.com/Khan/KaTeX/issues"
|
| 45 |
+
},
|
| 46 |
+
"dependencies": {
|
| 47 |
+
"match-at": "^0.1.0"
|
| 48 |
+
},
|
| 49 |
+
"description": "Fast math typesetting for the web.",
|
| 50 |
+
"devDependencies": {
|
| 51 |
+
"browserify": "^10.2.4",
|
| 52 |
+
"clean-css": "~2.2.15",
|
| 53 |
+
"eslint": "^1.10.2",
|
| 54 |
+
"express": "~3.3.3",
|
| 55 |
+
"glob": "^5.0.15",
|
| 56 |
+
"jasmine": "^2.3.2",
|
| 57 |
+
"jasmine-core": "^2.3.4",
|
| 58 |
+
"js-yaml": "^3.3.1",
|
| 59 |
+
"jspngopt": "^0.1.0",
|
| 60 |
+
"less": "~1.7.5",
|
| 61 |
+
"nomnom": "^1.8.1",
|
| 62 |
+
"pako": "0.2.7",
|
| 63 |
+
"selenium-webdriver": "^2.46.1",
|
| 64 |
+
"uglify-js": "~2.4.15"
|
| 65 |
+
},
|
| 66 |
+
"directories": {},
|
| 67 |
+
"dist": {
|
| 68 |
+
"shasum": "12418e09121c05c92041b6b3b9fb6bab213cb6f3",
|
| 69 |
+
"tarball": "https://registry.npmjs.org/katex/-/katex-0.6.0.tgz"
|
| 70 |
+
},
|
| 71 |
+
"files": [
|
| 72 |
+
"cli.js",
|
| 73 |
+
"dist/",
|
| 74 |
+
"katex.js",
|
| 75 |
+
"src/"
|
| 76 |
+
],
|
| 77 |
+
"gitHead": "b94fc6534d5c23f944906a52a592bee4e0090665",
|
| 78 |
+
"homepage": "https://github.com/Khan/KaTeX#readme",
|
| 79 |
+
"license": "MIT",
|
| 80 |
+
"main": "katex.js",
|
| 81 |
+
"maintainers": [
|
| 82 |
+
{
|
| 83 |
+
"name": "kevinbarabash",
|
| 84 |
+
"email": "[email protected]"
|
| 85 |
+
},
|
| 86 |
+
{
|
| 87 |
+
"name": "spicyj",
|
| 88 |
+
"email": "[email protected]"
|
| 89 |
+
},
|
| 90 |
+
{
|
| 91 |
+
"name": "xymostech",
|
| 92 |
+
"email": "[email protected]"
|
| 93 |
+
}
|
| 94 |
+
],
|
| 95 |
+
"name": "katex",
|
| 96 |
+
"optionalDependencies": {},
|
| 97 |
+
"readme": "ERROR: No README data found!",
|
| 98 |
+
"repository": {
|
| 99 |
+
"type": "git",
|
| 100 |
+
"url": "git://github.com/Khan/KaTeX.git"
|
| 101 |
+
},
|
| 102 |
+
"scripts": {
|
| 103 |
+
"prepublish": "make dist",
|
| 104 |
+
"start": "node server.js",
|
| 105 |
+
"test": "make lint test"
|
| 106 |
+
},
|
| 107 |
+
"version": "0.6.0"
|
| 108 |
+
}
|
katex/src/Lexer.js
ADDED
|
@@ -0,0 +1,162 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
/**
|
| 2 |
+
* The Lexer class handles tokenizing the input in various ways. Since our
|
| 3 |
+
* parser expects us to be able to backtrack, the lexer allows lexing from any
|
| 4 |
+
* given starting point.
|
| 5 |
+
*
|
| 6 |
+
* Its main exposed function is the `lex` function, which takes a position to
|
| 7 |
+
* lex from and a type of token to lex. It defers to the appropriate `_innerLex`
|
| 8 |
+
* function.
|
| 9 |
+
*
|
| 10 |
+
* The various `_innerLex` functions perform the actual lexing of different
|
| 11 |
+
* kinds.
|
| 12 |
+
*/
|
| 13 |
+
|
| 14 |
+
var matchAt = require("../../match-at");
|
| 15 |
+
|
| 16 |
+
var ParseError = require("./ParseError");
|
| 17 |
+
|
| 18 |
+
// The main lexer class
|
| 19 |
+
function Lexer(input) {
|
| 20 |
+
this._input = input;
|
| 21 |
+
}
|
| 22 |
+
|
| 23 |
+
// The resulting token returned from `lex`.
|
| 24 |
+
function Token(text, data, position) {
|
| 25 |
+
this.text = text;
|
| 26 |
+
this.data = data;
|
| 27 |
+
this.position = position;
|
| 28 |
+
}
|
| 29 |
+
|
| 30 |
+
/* The following tokenRegex
|
| 31 |
+
* - matches typical whitespace (but not NBSP etc.) using its first group
|
| 32 |
+
* - matches symbol combinations which result in a single output character
|
| 33 |
+
* - does not match any control character \x00-\x1f except whitespace
|
| 34 |
+
* - does not match a bare backslash
|
| 35 |
+
* - matches any ASCII character except those just mentioned
|
| 36 |
+
* - does not match the BMP private use area \uE000-\uF8FF
|
| 37 |
+
* - does not match bare surrogate code units
|
| 38 |
+
* - matches any BMP character except for those just described
|
| 39 |
+
* - matches any valid Unicode surrogate pair
|
| 40 |
+
* - matches a backslash followed by one or more letters
|
| 41 |
+
* - matches a backslash followed by any BMP character, including newline
|
| 42 |
+
* Just because the Lexer matches something doesn't mean it's valid input:
|
| 43 |
+
* If there is no matching function or symbol definition, the Parser will
|
| 44 |
+
* still reject the input.
|
| 45 |
+
*/
|
| 46 |
+
var tokenRegex = new RegExp(
|
| 47 |
+
"([ \r\n\t]+)|(" + // whitespace
|
| 48 |
+
"---?" + // special combinations
|
| 49 |
+
"|[!-\\[\\]-\u2027\u202A-\uD7FF\uF900-\uFFFF]" + // single codepoint
|
| 50 |
+
"|[\uD800-\uDBFF][\uDC00-\uDFFF]" + // surrogate pair
|
| 51 |
+
"|\\\\(?:[a-zA-Z]+|[^\uD800-\uDFFF])" + // function name
|
| 52 |
+
")"
|
| 53 |
+
);
|
| 54 |
+
|
| 55 |
+
var whitespaceRegex = /\s*/;
|
| 56 |
+
|
| 57 |
+
/**
|
| 58 |
+
* This function lexes a single normal token. It takes a position and
|
| 59 |
+
* whether it should completely ignore whitespace or not.
|
| 60 |
+
*/
|
| 61 |
+
Lexer.prototype._innerLex = function(pos, ignoreWhitespace) {
|
| 62 |
+
var input = this._input;
|
| 63 |
+
if (pos === input.length) {
|
| 64 |
+
return new Token("EOF", null, pos);
|
| 65 |
+
}
|
| 66 |
+
var match = matchAt(tokenRegex, input, pos);
|
| 67 |
+
if (match === null) {
|
| 68 |
+
throw new ParseError(
|
| 69 |
+
"Unexpected character: '" + input[pos] + "'",
|
| 70 |
+
this, pos);
|
| 71 |
+
} else if (match[2]) { // matched non-whitespace
|
| 72 |
+
return new Token(match[2], null, pos + match[2].length);
|
| 73 |
+
} else if (ignoreWhitespace) {
|
| 74 |
+
return this._innerLex(pos + match[1].length, true);
|
| 75 |
+
} else { // concatenate whitespace to a single space
|
| 76 |
+
return new Token(" ", null, pos + match[1].length);
|
| 77 |
+
}
|
| 78 |
+
};
|
| 79 |
+
|
| 80 |
+
// A regex to match a CSS color (like #ffffff or BlueViolet)
|
| 81 |
+
var cssColor = /#[a-z0-9]+|[a-z]+/i;
|
| 82 |
+
|
| 83 |
+
/**
|
| 84 |
+
* This function lexes a CSS color.
|
| 85 |
+
*/
|
| 86 |
+
Lexer.prototype._innerLexColor = function(pos) {
|
| 87 |
+
var input = this._input;
|
| 88 |
+
|
| 89 |
+
// Ignore whitespace
|
| 90 |
+
var whitespace = matchAt(whitespaceRegex, input, pos)[0];
|
| 91 |
+
pos += whitespace.length;
|
| 92 |
+
|
| 93 |
+
var match;
|
| 94 |
+
if ((match = matchAt(cssColor, input, pos))) {
|
| 95 |
+
// If we look like a color, return a color
|
| 96 |
+
return new Token(match[0], null, pos + match[0].length);
|
| 97 |
+
} else {
|
| 98 |
+
throw new ParseError("Invalid color", this, pos);
|
| 99 |
+
}
|
| 100 |
+
};
|
| 101 |
+
|
| 102 |
+
// A regex to match a dimension. Dimensions look like
|
| 103 |
+
// "1.2em" or ".4pt" or "1 ex"
|
| 104 |
+
var sizeRegex = /(-?)\s*(\d+(?:\.\d*)?|\.\d+)\s*([a-z]{2})/;
|
| 105 |
+
|
| 106 |
+
/**
|
| 107 |
+
* This function lexes a dimension.
|
| 108 |
+
*/
|
| 109 |
+
Lexer.prototype._innerLexSize = function(pos) {
|
| 110 |
+
var input = this._input;
|
| 111 |
+
|
| 112 |
+
// Ignore whitespace
|
| 113 |
+
var whitespace = matchAt(whitespaceRegex, input, pos)[0];
|
| 114 |
+
pos += whitespace.length;
|
| 115 |
+
|
| 116 |
+
var match;
|
| 117 |
+
if ((match = matchAt(sizeRegex, input, pos))) {
|
| 118 |
+
var unit = match[3];
|
| 119 |
+
// We only currently handle "em" and "ex" units
|
| 120 |
+
// if (unit !== "em" && unit !== "ex") {
|
| 121 |
+
// throw new ParseError("Invalid unit: '" + unit + "'", this, pos);
|
| 122 |
+
// }
|
| 123 |
+
return new Token(match[0], {
|
| 124 |
+
number: +(match[1] + match[2]),
|
| 125 |
+
unit: unit,
|
| 126 |
+
}, pos + match[0].length);
|
| 127 |
+
}
|
| 128 |
+
|
| 129 |
+
throw new ParseError("Invalid size", this, pos);
|
| 130 |
+
};
|
| 131 |
+
|
| 132 |
+
/**
|
| 133 |
+
* This function lexes a string of whitespace.
|
| 134 |
+
*/
|
| 135 |
+
Lexer.prototype._innerLexWhitespace = function(pos) {
|
| 136 |
+
var input = this._input;
|
| 137 |
+
|
| 138 |
+
var whitespace = matchAt(whitespaceRegex, input, pos)[0];
|
| 139 |
+
pos += whitespace.length;
|
| 140 |
+
|
| 141 |
+
return new Token(whitespace[0], null, pos);
|
| 142 |
+
};
|
| 143 |
+
|
| 144 |
+
/**
|
| 145 |
+
* This function lexes a single token starting at `pos` and of the given mode.
|
| 146 |
+
* Based on the mode, we defer to one of the `_innerLex` functions.
|
| 147 |
+
*/
|
| 148 |
+
Lexer.prototype.lex = function(pos, mode) {
|
| 149 |
+
if (mode === "math") {
|
| 150 |
+
return this._innerLex(pos, true);
|
| 151 |
+
} else if (mode === "text") {
|
| 152 |
+
return this._innerLex(pos, false);
|
| 153 |
+
} else if (mode === "color") {
|
| 154 |
+
return this._innerLexColor(pos);
|
| 155 |
+
} else if (mode === "size") {
|
| 156 |
+
return this._innerLexSize(pos);
|
| 157 |
+
} else if (mode === "whitespace") {
|
| 158 |
+
return this._innerLexWhitespace(pos);
|
| 159 |
+
}
|
| 160 |
+
};
|
| 161 |
+
|
| 162 |
+
module.exports = Lexer;
|
katex/src/Options.js
ADDED
|
@@ -0,0 +1,189 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
/**
|
| 2 |
+
* This file contains information about the options that the Parser carries
|
| 3 |
+
* around with it while parsing. Data is held in an `Options` object, and when
|
| 4 |
+
* recursing, a new `Options` object can be created with the `.with*` and
|
| 5 |
+
* `.reset` functions.
|
| 6 |
+
*/
|
| 7 |
+
|
| 8 |
+
/**
|
| 9 |
+
* This is the main options class. It contains the style, size, color, and font
|
| 10 |
+
* of the current parse level. It also contains the style and size of the parent
|
| 11 |
+
* parse level, so size changes can be handled efficiently.
|
| 12 |
+
*
|
| 13 |
+
* Each of the `.with*` and `.reset` functions passes its current style and size
|
| 14 |
+
* as the parentStyle and parentSize of the new options class, so parent
|
| 15 |
+
* handling is taken care of automatically.
|
| 16 |
+
*/
|
| 17 |
+
function Options(data) {
|
| 18 |
+
this.style = data.style;
|
| 19 |
+
this.color = data.color;
|
| 20 |
+
this.size = data.size;
|
| 21 |
+
this.phantom = data.phantom;
|
| 22 |
+
this.font = data.font;
|
| 23 |
+
|
| 24 |
+
if (data.parentStyle === undefined) {
|
| 25 |
+
this.parentStyle = data.style;
|
| 26 |
+
} else {
|
| 27 |
+
this.parentStyle = data.parentStyle;
|
| 28 |
+
}
|
| 29 |
+
|
| 30 |
+
if (data.parentSize === undefined) {
|
| 31 |
+
this.parentSize = data.size;
|
| 32 |
+
} else {
|
| 33 |
+
this.parentSize = data.parentSize;
|
| 34 |
+
}
|
| 35 |
+
}
|
| 36 |
+
|
| 37 |
+
/**
|
| 38 |
+
* Returns a new options object with the same properties as "this". Properties
|
| 39 |
+
* from "extension" will be copied to the new options object.
|
| 40 |
+
*/
|
| 41 |
+
Options.prototype.extend = function(extension) {
|
| 42 |
+
var data = {
|
| 43 |
+
style: this.style,
|
| 44 |
+
size: this.size,
|
| 45 |
+
color: this.color,
|
| 46 |
+
parentStyle: this.style,
|
| 47 |
+
parentSize: this.size,
|
| 48 |
+
phantom: this.phantom,
|
| 49 |
+
font: this.font,
|
| 50 |
+
};
|
| 51 |
+
|
| 52 |
+
for (var key in extension) {
|
| 53 |
+
if (extension.hasOwnProperty(key)) {
|
| 54 |
+
data[key] = extension[key];
|
| 55 |
+
}
|
| 56 |
+
}
|
| 57 |
+
|
| 58 |
+
return new Options(data);
|
| 59 |
+
};
|
| 60 |
+
|
| 61 |
+
/**
|
| 62 |
+
* Create a new options object with the given style.
|
| 63 |
+
*/
|
| 64 |
+
Options.prototype.withStyle = function(style) {
|
| 65 |
+
return this.extend({
|
| 66 |
+
style: style,
|
| 67 |
+
});
|
| 68 |
+
};
|
| 69 |
+
|
| 70 |
+
/**
|
| 71 |
+
* Create a new options object with the given size.
|
| 72 |
+
*/
|
| 73 |
+
Options.prototype.withSize = function(size) {
|
| 74 |
+
return this.extend({
|
| 75 |
+
size: size,
|
| 76 |
+
});
|
| 77 |
+
};
|
| 78 |
+
|
| 79 |
+
/**
|
| 80 |
+
* Create a new options object with the given color.
|
| 81 |
+
*/
|
| 82 |
+
Options.prototype.withColor = function(color) {
|
| 83 |
+
return this.extend({
|
| 84 |
+
color: color,
|
| 85 |
+
});
|
| 86 |
+
};
|
| 87 |
+
|
| 88 |
+
/**
|
| 89 |
+
* Create a new options object with "phantom" set to true.
|
| 90 |
+
*/
|
| 91 |
+
Options.prototype.withPhantom = function() {
|
| 92 |
+
return this.extend({
|
| 93 |
+
phantom: true,
|
| 94 |
+
});
|
| 95 |
+
};
|
| 96 |
+
|
| 97 |
+
/**
|
| 98 |
+
* Create a new options objects with the give font.
|
| 99 |
+
*/
|
| 100 |
+
Options.prototype.withFont = function(font) {
|
| 101 |
+
return this.extend({
|
| 102 |
+
font: font,
|
| 103 |
+
});
|
| 104 |
+
};
|
| 105 |
+
|
| 106 |
+
/**
|
| 107 |
+
* Create a new options object with the same style, size, and color. This is
|
| 108 |
+
* used so that parent style and size changes are handled correctly.
|
| 109 |
+
*/
|
| 110 |
+
Options.prototype.reset = function() {
|
| 111 |
+
return this.extend({});
|
| 112 |
+
};
|
| 113 |
+
|
| 114 |
+
/**
|
| 115 |
+
* A map of color names to CSS colors.
|
| 116 |
+
* TODO(emily): Remove this when we have real macros
|
| 117 |
+
*/
|
| 118 |
+
var colorMap = {
|
| 119 |
+
"katex-blue": "#6495ed",
|
| 120 |
+
"katex-orange": "#ffa500",
|
| 121 |
+
"katex-pink": "#ff00af",
|
| 122 |
+
"katex-red": "#df0030",
|
| 123 |
+
"katex-green": "#28ae7b",
|
| 124 |
+
"katex-gray": "gray",
|
| 125 |
+
"katex-purple": "#9d38bd",
|
| 126 |
+
"katex-blueA": "#c7e9f1",
|
| 127 |
+
"katex-blueB": "#9cdceb",
|
| 128 |
+
"katex-blueC": "#58c4dd",
|
| 129 |
+
"katex-blueD": "#29abca",
|
| 130 |
+
"katex-blueE": "#1c758a",
|
| 131 |
+
"katex-tealA": "#acead7",
|
| 132 |
+
"katex-tealB": "#76ddc0",
|
| 133 |
+
"katex-tealC": "#5cd0b3",
|
| 134 |
+
"katex-tealD": "#55c1a7",
|
| 135 |
+
"katex-tealE": "#49a88f",
|
| 136 |
+
"katex-greenA": "#c9e2ae",
|
| 137 |
+
"katex-greenB": "#a6cf8c",
|
| 138 |
+
"katex-greenC": "#83c167",
|
| 139 |
+
"katex-greenD": "#77b05d",
|
| 140 |
+
"katex-greenE": "#699c52",
|
| 141 |
+
"katex-goldA": "#f7c797",
|
| 142 |
+
"katex-goldB": "#f9b775",
|
| 143 |
+
"katex-goldC": "#f0ac5f",
|
| 144 |
+
"katex-goldD": "#e1a158",
|
| 145 |
+
"katex-goldE": "#c78d46",
|
| 146 |
+
"katex-redA": "#f7a1a3",
|
| 147 |
+
"katex-redB": "#ff8080",
|
| 148 |
+
"katex-redC": "#fc6255",
|
| 149 |
+
"katex-redD": "#e65a4c",
|
| 150 |
+
"katex-redE": "#cf5044",
|
| 151 |
+
"katex-maroonA": "#ecabc1",
|
| 152 |
+
"katex-maroonB": "#ec92ab",
|
| 153 |
+
"katex-maroonC": "#c55f73",
|
| 154 |
+
"katex-maroonD": "#a24d61",
|
| 155 |
+
"katex-maroonE": "#94424f",
|
| 156 |
+
"katex-purpleA": "#caa3e8",
|
| 157 |
+
"katex-purpleB": "#b189c6",
|
| 158 |
+
"katex-purpleC": "#9a72ac",
|
| 159 |
+
"katex-purpleD": "#715582",
|
| 160 |
+
"katex-purpleE": "#644172",
|
| 161 |
+
"katex-mintA": "#f5f9e8",
|
| 162 |
+
"katex-mintB": "#edf2df",
|
| 163 |
+
"katex-mintC": "#e0e5cc",
|
| 164 |
+
"katex-grayA": "#fdfdfd",
|
| 165 |
+
"katex-grayB": "#f7f7f7",
|
| 166 |
+
"katex-grayC": "#eeeeee",
|
| 167 |
+
"katex-grayD": "#dddddd",
|
| 168 |
+
"katex-grayE": "#cccccc",
|
| 169 |
+
"katex-grayF": "#aaaaaa",
|
| 170 |
+
"katex-grayG": "#999999",
|
| 171 |
+
"katex-grayH": "#555555",
|
| 172 |
+
"katex-grayI": "#333333",
|
| 173 |
+
"katex-kaBlue": "#314453",
|
| 174 |
+
"katex-kaGreen": "#639b24",
|
| 175 |
+
};
|
| 176 |
+
|
| 177 |
+
/**
|
| 178 |
+
* Gets the CSS color of the current options object, accounting for the
|
| 179 |
+
* `colorMap`.
|
| 180 |
+
*/
|
| 181 |
+
Options.prototype.getColor = function() {
|
| 182 |
+
if (this.phantom) {
|
| 183 |
+
return "transparent";
|
| 184 |
+
} else {
|
| 185 |
+
return colorMap[this.color] || this.color;
|
| 186 |
+
}
|
| 187 |
+
};
|
| 188 |
+
|
| 189 |
+
module.exports = Options;
|
katex/src/ParseError.js
ADDED
|
@@ -0,0 +1,40 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
/**
|
| 2 |
+
* This is the ParseError class, which is the main error thrown by KaTeX
|
| 3 |
+
* functions when something has gone wrong. This is used to distinguish internal
|
| 4 |
+
* errors from errors in the expression that the user provided.
|
| 5 |
+
*/
|
| 6 |
+
function ParseError(message, lexer, position) {
|
| 7 |
+
var error = "KaTeX parse error: " + message;
|
| 8 |
+
|
| 9 |
+
if (lexer !== undefined && position !== undefined) {
|
| 10 |
+
// If we have the input and a position, make the error a bit fancier
|
| 11 |
+
|
| 12 |
+
// Prepend some information
|
| 13 |
+
error += " at position " + position + ": ";
|
| 14 |
+
|
| 15 |
+
// Get the input
|
| 16 |
+
var input = lexer._input;
|
| 17 |
+
// Insert a combining underscore at the correct position
|
| 18 |
+
input = input.slice(0, position) + "\u0332" +
|
| 19 |
+
input.slice(position);
|
| 20 |
+
|
| 21 |
+
// Extract some context from the input and add it to the error
|
| 22 |
+
var begin = Math.max(0, position - 15);
|
| 23 |
+
var end = position + 15;
|
| 24 |
+
error += input.slice(begin, end);
|
| 25 |
+
}
|
| 26 |
+
|
| 27 |
+
// Some hackery to make ParseError a prototype of Error
|
| 28 |
+
// See http://stackoverflow.com/a/8460753
|
| 29 |
+
var self = new Error(error);
|
| 30 |
+
self.name = "ParseError";
|
| 31 |
+
self.__proto__ = ParseError.prototype;
|
| 32 |
+
|
| 33 |
+
self.position = position;
|
| 34 |
+
return self;
|
| 35 |
+
}
|
| 36 |
+
|
| 37 |
+
// More hackery
|
| 38 |
+
ParseError.prototype.__proto__ = Error.prototype;
|
| 39 |
+
|
| 40 |
+
module.exports = ParseError;
|
katex/src/Parser.js
ADDED
|
@@ -0,0 +1,798 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
/* eslint no-constant-condition:0 */
|
| 2 |
+
var functions = require("./functions");
|
| 3 |
+
var environments = require("./environments");
|
| 4 |
+
var Lexer = require("./Lexer");
|
| 5 |
+
var symbols = require("./symbols");
|
| 6 |
+
var utils = require("./utils");
|
| 7 |
+
|
| 8 |
+
var parseData = require("./parseData");
|
| 9 |
+
var ParseError = require("./ParseError");
|
| 10 |
+
|
| 11 |
+
global_str = ""
|
| 12 |
+
|
| 13 |
+
/**
|
| 14 |
+
* This file contains the parser used to parse out a TeX expression from the
|
| 15 |
+
* input. Since TeX isn't context-free, standard parsers don't work particularly
|
| 16 |
+
* well.
|
| 17 |
+
*
|
| 18 |
+
* The strategy of this parser is as such:
|
| 19 |
+
*
|
| 20 |
+
* The main functions (the `.parse...` ones) take a position in the current
|
| 21 |
+
* parse string to parse tokens from. The lexer (found in Lexer.js, stored at
|
| 22 |
+
* this.lexer) also supports pulling out tokens at arbitrary places. When
|
| 23 |
+
* individual tokens are needed at a position, the lexer is called to pull out a
|
| 24 |
+
* token, which is then used.
|
| 25 |
+
*
|
| 26 |
+
* The parser has a property called "mode" indicating the mode that
|
| 27 |
+
* the parser is currently in. Currently it has to be one of "math" or
|
| 28 |
+
* "text", which denotes whether the current environment is a math-y
|
| 29 |
+
* one or a text-y one (e.g. inside \text). Currently, this serves to
|
| 30 |
+
* limit the functions which can be used in text mode.
|
| 31 |
+
*
|
| 32 |
+
* The main functions then return an object which contains the useful data that
|
| 33 |
+
* was parsed at its given point, and a new position at the end of the parsed
|
| 34 |
+
* data. The main functions can call each other and continue the parsing by
|
| 35 |
+
* using the returned position as a new starting point.
|
| 36 |
+
*
|
| 37 |
+
* There are also extra `.handle...` functions, which pull out some reused
|
| 38 |
+
* functionality into self-contained functions.
|
| 39 |
+
*
|
| 40 |
+
* The earlier functions return ParseNodes.
|
| 41 |
+
* The later functions (which are called deeper in the parse) sometimes return
|
| 42 |
+
* ParseFuncOrArgument, which contain a ParseNode as well as some data about
|
| 43 |
+
* whether the parsed object is a function which is missing some arguments, or a
|
| 44 |
+
* standalone object which can be used as an argument to another function.
|
| 45 |
+
*/
|
| 46 |
+
|
| 47 |
+
/**
|
| 48 |
+
* Main Parser class
|
| 49 |
+
*/
|
| 50 |
+
function Parser(input, settings) {
|
| 51 |
+
// Make a new lexer
|
| 52 |
+
this.lexer = new Lexer(input);
|
| 53 |
+
// Store the settings for use in parsing
|
| 54 |
+
this.settings = settings;
|
| 55 |
+
}
|
| 56 |
+
|
| 57 |
+
var ParseNode = parseData.ParseNode;
|
| 58 |
+
|
| 59 |
+
/**
|
| 60 |
+
* An initial function (without its arguments), or an argument to a function.
|
| 61 |
+
* The `result` argument should be a ParseNode.
|
| 62 |
+
*/
|
| 63 |
+
function ParseFuncOrArgument(result, isFunction) {
|
| 64 |
+
this.result = result;
|
| 65 |
+
// Is this a function (i.e. is it something defined in functions.js)?
|
| 66 |
+
this.isFunction = isFunction;
|
| 67 |
+
}
|
| 68 |
+
|
| 69 |
+
/**
|
| 70 |
+
* Checks a result to make sure it has the right type, and throws an
|
| 71 |
+
* appropriate error otherwise.
|
| 72 |
+
*
|
| 73 |
+
* @param {boolean=} consume whether to consume the expected token,
|
| 74 |
+
* defaults to true
|
| 75 |
+
*/
|
| 76 |
+
Parser.prototype.expect = function(text, consume) {
|
| 77 |
+
if (this.nextToken.text !== text) {
|
| 78 |
+
throw new ParseError(
|
| 79 |
+
"Expected '" + text + "', got '" + this.nextToken.text + "'",
|
| 80 |
+
this.lexer, this.nextToken.position
|
| 81 |
+
);
|
| 82 |
+
}
|
| 83 |
+
if (consume !== false) {
|
| 84 |
+
this.consume();
|
| 85 |
+
}
|
| 86 |
+
};
|
| 87 |
+
|
| 88 |
+
/**
|
| 89 |
+
* Considers the current look ahead token as consumed,
|
| 90 |
+
* and fetches the one after that as the new look ahead.
|
| 91 |
+
*/
|
| 92 |
+
Parser.prototype.consume = function() {
|
| 93 |
+
this.pos = this.nextToken.position;
|
| 94 |
+
|
| 95 |
+
global_str = global_str + " " + this.nextToken.text
|
| 96 |
+
this.nextToken = this.lexer.lex(this.pos, this.mode);
|
| 97 |
+
};
|
| 98 |
+
|
| 99 |
+
/**
|
| 100 |
+
* Main parsing function, which parses an entire input.
|
| 101 |
+
*
|
| 102 |
+
* @return {?Array.<ParseNode>}
|
| 103 |
+
*/
|
| 104 |
+
Parser.prototype.parse = function() {
|
| 105 |
+
// Try to parse the input
|
| 106 |
+
this.mode = "math";
|
| 107 |
+
this.pos = 0;
|
| 108 |
+
this.nextToken = this.lexer.lex(this.pos, this.mode);
|
| 109 |
+
var parse = this.parseInput();
|
| 110 |
+
return parse;
|
| 111 |
+
};
|
| 112 |
+
|
| 113 |
+
/**
|
| 114 |
+
* Parses an entire input tree.
|
| 115 |
+
*/
|
| 116 |
+
Parser.prototype.parseInput = function() {
|
| 117 |
+
// Parse an expression
|
| 118 |
+
var expression = this.parseExpression(false);
|
| 119 |
+
// If we succeeded, make sure there's an EOF at the end
|
| 120 |
+
this.expect("EOF", false);
|
| 121 |
+
return expression;
|
| 122 |
+
};
|
| 123 |
+
|
| 124 |
+
var endOfExpression = ["}", "\\end", "\\right", "&", "\\\\", "\\cr"];
|
| 125 |
+
|
| 126 |
+
/**
|
| 127 |
+
* Parses an "expression", which is a list of atoms.
|
| 128 |
+
*
|
| 129 |
+
* @param {boolean} breakOnInfix Should the parsing stop when we hit infix
|
| 130 |
+
* nodes? This happens when functions have higher precendence
|
| 131 |
+
* than infix nodes in implicit parses.
|
| 132 |
+
*
|
| 133 |
+
* @param {?string} breakOnToken The token that the expression should end with,
|
| 134 |
+
* or `null` if something else should end the expression.
|
| 135 |
+
*
|
| 136 |
+
* @return {ParseNode}
|
| 137 |
+
*/
|
| 138 |
+
Parser.prototype.parseExpression = function(breakOnInfix, breakOnToken) {
|
| 139 |
+
var body = [];
|
| 140 |
+
// Keep adding atoms to the body until we can't parse any more atoms (either
|
| 141 |
+
// we reached the end, a }, or a \right)
|
| 142 |
+
while (true) {
|
| 143 |
+
var lex = this.nextToken;
|
| 144 |
+
var pos = this.pos;
|
| 145 |
+
if (endOfExpression.indexOf(lex.text) !== -1) {
|
| 146 |
+
break;
|
| 147 |
+
}
|
| 148 |
+
if (breakOnToken && lex.text === breakOnToken) {
|
| 149 |
+
break;
|
| 150 |
+
}
|
| 151 |
+
var atom = this.parseAtom();
|
| 152 |
+
if (!atom) {
|
| 153 |
+
if (!this.settings.throwOnError && lex.text[0] === "\\") {
|
| 154 |
+
var errorNode = this.handleUnsupportedCmd();
|
| 155 |
+
body.push(errorNode);
|
| 156 |
+
|
| 157 |
+
pos = lex.position;
|
| 158 |
+
continue;
|
| 159 |
+
}
|
| 160 |
+
|
| 161 |
+
break;
|
| 162 |
+
}
|
| 163 |
+
if (breakOnInfix && atom.type === "infix") {
|
| 164 |
+
// rewind so we can parse the infix atom again
|
| 165 |
+
this.pos = pos;
|
| 166 |
+
this.nextToken = lex;
|
| 167 |
+
break;
|
| 168 |
+
}
|
| 169 |
+
body.push(atom);
|
| 170 |
+
}
|
| 171 |
+
return this.handleInfixNodes(body);
|
| 172 |
+
};
|
| 173 |
+
|
| 174 |
+
/**
|
| 175 |
+
* Rewrites infix operators such as \over with corresponding commands such
|
| 176 |
+
* as \frac.
|
| 177 |
+
*
|
| 178 |
+
* There can only be one infix operator per group. If there's more than one
|
| 179 |
+
* then the expression is ambiguous. This can be resolved by adding {}.
|
| 180 |
+
*
|
| 181 |
+
* @returns {Array}
|
| 182 |
+
*/
|
| 183 |
+
Parser.prototype.handleInfixNodes = function(body) {
|
| 184 |
+
var overIndex = -1;
|
| 185 |
+
var funcName;
|
| 186 |
+
|
| 187 |
+
for (var i = 0; i < body.length; i++) {
|
| 188 |
+
var node = body[i];
|
| 189 |
+
if (node.type === "infix") {
|
| 190 |
+
if (overIndex !== -1) {
|
| 191 |
+
throw new ParseError("only one infix operator per group",
|
| 192 |
+
this.lexer, -1);
|
| 193 |
+
}
|
| 194 |
+
overIndex = i;
|
| 195 |
+
funcName = node.value.replaceWith;
|
| 196 |
+
}
|
| 197 |
+
}
|
| 198 |
+
|
| 199 |
+
if (overIndex !== -1) {
|
| 200 |
+
var numerNode;
|
| 201 |
+
var denomNode;
|
| 202 |
+
|
| 203 |
+
var numerBody = body.slice(0, overIndex);
|
| 204 |
+
var denomBody = body.slice(overIndex + 1);
|
| 205 |
+
|
| 206 |
+
if (numerBody.length === 1 && numerBody[0].type === "ordgroup") {
|
| 207 |
+
numerNode = numerBody[0];
|
| 208 |
+
} else {
|
| 209 |
+
numerNode = new ParseNode("ordgroup", numerBody, this.mode);
|
| 210 |
+
}
|
| 211 |
+
|
| 212 |
+
if (denomBody.length === 1 && denomBody[0].type === "ordgroup") {
|
| 213 |
+
denomNode = denomBody[0];
|
| 214 |
+
} else {
|
| 215 |
+
denomNode = new ParseNode("ordgroup", denomBody, this.mode);
|
| 216 |
+
}
|
| 217 |
+
|
| 218 |
+
var value = this.callFunction(
|
| 219 |
+
funcName, [numerNode, denomNode], null);
|
| 220 |
+
return [new ParseNode(value.type, value, this.mode)];
|
| 221 |
+
} else {
|
| 222 |
+
return body;
|
| 223 |
+
}
|
| 224 |
+
};
|
| 225 |
+
|
| 226 |
+
// The greediness of a superscript or subscript
|
| 227 |
+
var SUPSUB_GREEDINESS = 1;
|
| 228 |
+
|
| 229 |
+
/**
|
| 230 |
+
* Handle a subscript or superscript with nice errors.
|
| 231 |
+
*/
|
| 232 |
+
Parser.prototype.handleSupSubscript = function(name) {
|
| 233 |
+
var symbol = this.nextToken.text;
|
| 234 |
+
var symPos = this.pos;
|
| 235 |
+
this.consume();
|
| 236 |
+
var group = this.parseGroup();
|
| 237 |
+
|
| 238 |
+
if (!group) {
|
| 239 |
+
if (!this.settings.throwOnError && this.nextToken.text[0] === "\\") {
|
| 240 |
+
return this.handleUnsupportedCmd();
|
| 241 |
+
} else {
|
| 242 |
+
// throw new ParseError(
|
| 243 |
+
// "Expected group after '" + symbol + "'",
|
| 244 |
+
// this.lexer,
|
| 245 |
+
// symPos + 1
|
| 246 |
+
// );
|
| 247 |
+
}
|
| 248 |
+
} else if (group.isFunction) {
|
| 249 |
+
// ^ and _ have a greediness, so handle interactions with functions'
|
| 250 |
+
// greediness
|
| 251 |
+
var funcGreediness = functions[group.result].greediness;
|
| 252 |
+
if (funcGreediness > SUPSUB_GREEDINESS) {
|
| 253 |
+
return this.parseFunction(group);
|
| 254 |
+
} else {
|
| 255 |
+
throw new ParseError(
|
| 256 |
+
"Got function '" + group.result + "' with no arguments " +
|
| 257 |
+
"as " + name,
|
| 258 |
+
this.lexer, symPos + 1);
|
| 259 |
+
}
|
| 260 |
+
} else {
|
| 261 |
+
return group.result;
|
| 262 |
+
}
|
| 263 |
+
};
|
| 264 |
+
|
| 265 |
+
/**
|
| 266 |
+
* Converts the textual input of an unsupported command into a text node
|
| 267 |
+
* contained within a color node whose color is determined by errorColor
|
| 268 |
+
*/
|
| 269 |
+
Parser.prototype.handleUnsupportedCmd = function() {
|
| 270 |
+
var text = this.nextToken.text;
|
| 271 |
+
var textordArray = [];
|
| 272 |
+
|
| 273 |
+
for (var i = 0; i < text.length; i++) {
|
| 274 |
+
textordArray.push(new ParseNode("textord", text[i], "text"));
|
| 275 |
+
}
|
| 276 |
+
|
| 277 |
+
var textNode = new ParseNode(
|
| 278 |
+
"text",
|
| 279 |
+
{
|
| 280 |
+
body: textordArray,
|
| 281 |
+
type: "text",
|
| 282 |
+
},
|
| 283 |
+
this.mode);
|
| 284 |
+
|
| 285 |
+
var colorNode = new ParseNode(
|
| 286 |
+
"color",
|
| 287 |
+
{
|
| 288 |
+
color: this.settings.errorColor,
|
| 289 |
+
value: [textNode],
|
| 290 |
+
type: "color",
|
| 291 |
+
},
|
| 292 |
+
this.mode);
|
| 293 |
+
|
| 294 |
+
this.consume();
|
| 295 |
+
return colorNode;
|
| 296 |
+
};
|
| 297 |
+
|
| 298 |
+
/**
|
| 299 |
+
* Parses a group with optional super/subscripts.
|
| 300 |
+
*
|
| 301 |
+
* @return {?ParseNode}
|
| 302 |
+
*/
|
| 303 |
+
Parser.prototype.parseAtom = function() {
|
| 304 |
+
// The body of an atom is an implicit group, so that things like
|
| 305 |
+
// \left(x\right)^2 work correctly.
|
| 306 |
+
var base = this.parseImplicitGroup();
|
| 307 |
+
|
| 308 |
+
// In text mode, we don't have superscripts or subscripts
|
| 309 |
+
if (this.mode === "text") {
|
| 310 |
+
return base;
|
| 311 |
+
}
|
| 312 |
+
|
| 313 |
+
// Note that base may be empty (i.e. null) at this point.
|
| 314 |
+
|
| 315 |
+
var superscript;
|
| 316 |
+
var subscript;
|
| 317 |
+
while (true) {
|
| 318 |
+
// Lex the first token
|
| 319 |
+
var lex = this.nextToken;
|
| 320 |
+
|
| 321 |
+
if (lex.text === "\\limits" || lex.text === "\\nolimits") {
|
| 322 |
+
// We got a limit control
|
| 323 |
+
if (!base || base.type !== "op") {
|
| 324 |
+
throw new ParseError(
|
| 325 |
+
"Limit controls must follow a math operator",
|
| 326 |
+
this.lexer, this.pos);
|
| 327 |
+
} else {
|
| 328 |
+
var limits = lex.text === "\\limits";
|
| 329 |
+
base.value.limits = limits;
|
| 330 |
+
base.value.alwaysHandleSupSub = true;
|
| 331 |
+
}
|
| 332 |
+
this.consume();
|
| 333 |
+
} else if (lex.text === "^") {
|
| 334 |
+
// We got a superscript start
|
| 335 |
+
// if (superscript) {
|
| 336 |
+
// throw new ParseError(
|
| 337 |
+
// "Double superscript", this.lexer, this.pos);
|
| 338 |
+
// }
|
| 339 |
+
superscript = this.handleSupSubscript("superscript");
|
| 340 |
+
} else if (lex.text === "_") {
|
| 341 |
+
// We got a subscript start
|
| 342 |
+
// if (subscript) {
|
| 343 |
+
// throw new ParseError(
|
| 344 |
+
// "Double subscript", this.lexer, this.pos);
|
| 345 |
+
// }
|
| 346 |
+
subscript = this.handleSupSubscript("subscript");
|
| 347 |
+
} else if (lex.text === "'") {
|
| 348 |
+
// We got a prime
|
| 349 |
+
var prime = new ParseNode("textord", "\\prime", this.mode);
|
| 350 |
+
|
| 351 |
+
// Many primes can be grouped together, so we handle this here
|
| 352 |
+
var primes = [prime];
|
| 353 |
+
this.consume();
|
| 354 |
+
// Keep lexing tokens until we get something that's not a prime
|
| 355 |
+
while (this.nextToken.text === "'") {
|
| 356 |
+
// For each one, add another prime to the list
|
| 357 |
+
primes.push(prime);
|
| 358 |
+
this.consume();
|
| 359 |
+
}
|
| 360 |
+
// Put them into an ordgroup as the superscript
|
| 361 |
+
superscript = new ParseNode("ordgroup", primes, this.mode);
|
| 362 |
+
} else {
|
| 363 |
+
// If it wasn't ^, _, or ', stop parsing super/subscripts
|
| 364 |
+
break;
|
| 365 |
+
}
|
| 366 |
+
}
|
| 367 |
+
|
| 368 |
+
if (superscript || subscript) {
|
| 369 |
+
// If we got either a superscript or subscript, create a supsub
|
| 370 |
+
return new ParseNode("supsub", {
|
| 371 |
+
base: base,
|
| 372 |
+
sup: superscript,
|
| 373 |
+
sub: subscript,
|
| 374 |
+
}, this.mode);
|
| 375 |
+
} else {
|
| 376 |
+
// Otherwise return the original body
|
| 377 |
+
return base;
|
| 378 |
+
}
|
| 379 |
+
};
|
| 380 |
+
|
| 381 |
+
// A list of the size-changing functions, for use in parseImplicitGroup
|
| 382 |
+
var sizeFuncs = [
|
| 383 |
+
"\\tiny", "\\scriptsize", "\\footnotesize", "\\small", "\\normalsize",
|
| 384 |
+
"\\large", "\\Large", "\\LARGE", "\\huge", "\\Huge", "\\textrm", "\\rm", "\\cal",
|
| 385 |
+
"\\bf", "\\siptstyle", "\\boldmath", "\\it"
|
| 386 |
+
];
|
| 387 |
+
|
| 388 |
+
// A list of the style-changing functions, for use in parseImplicitGroup
|
| 389 |
+
var styleFuncs = [
|
| 390 |
+
"\\displaystyle", "\\textstyle", "\\scriptstyle", "\\scriptscriptstyle",
|
| 391 |
+
];
|
| 392 |
+
|
| 393 |
+
/**
|
| 394 |
+
* Parses an implicit group, which is a group that starts at the end of a
|
| 395 |
+
* specified, and ends right before a higher explicit group ends, or at EOL. It
|
| 396 |
+
* is used for functions that appear to affect the current style, like \Large or
|
| 397 |
+
* \textrm, where instead of keeping a style we just pretend that there is an
|
| 398 |
+
* implicit grouping after it until the end of the group. E.g.
|
| 399 |
+
* small text {\Large large text} small text again
|
| 400 |
+
* It is also used for \left and \right to get the correct grouping.
|
| 401 |
+
*
|
| 402 |
+
* @return {?ParseNode}
|
| 403 |
+
*/
|
| 404 |
+
Parser.prototype.parseImplicitGroup = function() {
|
| 405 |
+
var start = this.parseSymbol();
|
| 406 |
+
|
| 407 |
+
if (start == null) {
|
| 408 |
+
// If we didn't get anything we handle, fall back to parseFunction
|
| 409 |
+
return this.parseFunction();
|
| 410 |
+
}
|
| 411 |
+
|
| 412 |
+
var func = start.result;
|
| 413 |
+
var body;
|
| 414 |
+
if (func === "\\left") {
|
| 415 |
+
// If we see a left:
|
| 416 |
+
// Parse the entire left function (including the delimiter)
|
| 417 |
+
var left = this.parseFunction(start);
|
| 418 |
+
// Parse out the implicit body
|
| 419 |
+
body = this.parseExpression(false);
|
| 420 |
+
// Check the next token
|
| 421 |
+
this.expect("\\right", false);
|
| 422 |
+
var right = this.parseFunction();
|
| 423 |
+
return new ParseNode("leftright", {
|
| 424 |
+
body: body,
|
| 425 |
+
left: left.value.value,
|
| 426 |
+
right: right.value.value,
|
| 427 |
+
}, this.mode);
|
| 428 |
+
} else if (func === "\\begin") {
|
| 429 |
+
// begin...end is similar to left...right
|
| 430 |
+
var begin = this.parseFunction(start);
|
| 431 |
+
var envName = begin.value.name;
|
| 432 |
+
var name = (begin.value.name + "")
|
| 433 |
+
|
| 434 |
+
global_str = global_str.substring(0, global_str.length - (name.length * 2 + 2)) + name + "}"
|
| 435 |
+
|
| 436 |
+
if (!environments.hasOwnProperty(envName)) {
|
| 437 |
+
throw new ParseError(
|
| 438 |
+
"No such environment: " + envName,
|
| 439 |
+
this.lexer, begin.value.namepos);
|
| 440 |
+
}
|
| 441 |
+
// Build the environment object. Arguments and other information will
|
| 442 |
+
// be made available to the begin and end methods using properties.
|
| 443 |
+
var env = environments[envName];
|
| 444 |
+
var args = this.parseArguments("\\begin{" + envName + "}", env);
|
| 445 |
+
var context = {
|
| 446 |
+
mode: this.mode,
|
| 447 |
+
envName: envName,
|
| 448 |
+
parser: this,
|
| 449 |
+
lexer: this.lexer,
|
| 450 |
+
positions: args.pop(),
|
| 451 |
+
};
|
| 452 |
+
var result = env.handler(context, args);
|
| 453 |
+
this.expect("\\end", false);
|
| 454 |
+
var end = this.parseFunction();
|
| 455 |
+
|
| 456 |
+
var name = (begin.value.name + "")
|
| 457 |
+
|
| 458 |
+
global_str = global_str.substring(0, global_str.length - (name.length * 2 + 2)) + name + "}"
|
| 459 |
+
if (end.value.name !== envName) {
|
| 460 |
+
throw new ParseError(
|
| 461 |
+
"Mismatch: \\begin{" + envName + "} matched " +
|
| 462 |
+
"by \\end{" + end.value.name + "}",
|
| 463 |
+
this.lexer /* , end.value.namepos */);
|
| 464 |
+
// TODO: Add position to the above line and adjust test case,
|
| 465 |
+
// requires #385 to get merged first
|
| 466 |
+
}
|
| 467 |
+
result.position = end.position;
|
| 468 |
+
|
| 469 |
+
return result;
|
| 470 |
+
|
| 471 |
+
} else if (func.value == "\\matrix" || func.value == "\\pmatrix" || func.value == "\\cases") {
|
| 472 |
+
// if (!environments.hasOwnProperty(envName)) {
|
| 473 |
+
// throw new ParseError(
|
| 474 |
+
// "No such environment: " + envName,
|
| 475 |
+
// this.lexer, begin.value.namepos);
|
| 476 |
+
// }
|
| 477 |
+
// Build the environment object. Arguments and other information will
|
| 478 |
+
// be made available to the begin and end methods using properties.
|
| 479 |
+
|
| 480 |
+
envName = func.value.slice(1);
|
| 481 |
+
var env = environments[envName];
|
| 482 |
+
// var args = this.parseArguments("\\matrix{", env);
|
| 483 |
+
this.expect("{", true);
|
| 484 |
+
var context = {
|
| 485 |
+
mode: this.mode,
|
| 486 |
+
envName: envName,
|
| 487 |
+
parser: this,
|
| 488 |
+
lexer: this.lexer
|
| 489 |
+
};
|
| 490 |
+
|
| 491 |
+
var result = env.handler(context, {} );
|
| 492 |
+
// exit();
|
| 493 |
+
this.expect("}", true);
|
| 494 |
+
// var end = this.parseFunction();
|
| 495 |
+
var next = this.nextToken.text;
|
| 496 |
+
// exit();
|
| 497 |
+
// console.log(next);
|
| 498 |
+
// var name = ( + "")
|
| 499 |
+
|
| 500 |
+
// global_str = global_str.substring(0, global_str.length - (name.length * 2 + 2)) + name + "}"
|
| 501 |
+
// result.position = end.position;
|
| 502 |
+
|
| 503 |
+
return result;
|
| 504 |
+
|
| 505 |
+
} else if (utils.contains(sizeFuncs, func)) {
|
| 506 |
+
// If we see a sizing function, parse out the implict body
|
| 507 |
+
body = this.parseExpression(false);
|
| 508 |
+
|
| 509 |
+
return new ParseNode("sizing", {
|
| 510 |
+
// Figure out what size to use based on the list of functions above
|
| 511 |
+
original: func,
|
| 512 |
+
size: "size" + (utils.indexOf(sizeFuncs, func) + 1),
|
| 513 |
+
value: body,
|
| 514 |
+
}, this.mode);
|
| 515 |
+
} else if (utils.contains(styleFuncs, func)) {
|
| 516 |
+
// If we see a styling function, parse out the implict body
|
| 517 |
+
body = this.parseExpression(true);
|
| 518 |
+
return new ParseNode("styling", {
|
| 519 |
+
// Figure out what style to use by pulling out the style from
|
| 520 |
+
// the function name
|
| 521 |
+
original: func,
|
| 522 |
+
style: func.slice(1, func.length - 5),
|
| 523 |
+
value: body,
|
| 524 |
+
}, this.mode);
|
| 525 |
+
} else {
|
| 526 |
+
// Defer to parseFunction if it's not a function we handle
|
| 527 |
+
return this.parseFunction(start);
|
| 528 |
+
}
|
| 529 |
+
};
|
| 530 |
+
|
| 531 |
+
/**
|
| 532 |
+
* Parses an entire function, including its base and all of its arguments.
|
| 533 |
+
* The base might either have been parsed already, in which case
|
| 534 |
+
* it is provided as an argument, or it's the next group in the input.
|
| 535 |
+
*
|
| 536 |
+
* @param {ParseFuncOrArgument=} baseGroup optional as described above
|
| 537 |
+
* @return {?ParseNode}
|
| 538 |
+
*/
|
| 539 |
+
Parser.prototype.parseFunction = function(baseGroup) {
|
| 540 |
+
if (!baseGroup) {
|
| 541 |
+
baseGroup = this.parseGroup();
|
| 542 |
+
}
|
| 543 |
+
|
| 544 |
+
if (baseGroup) {
|
| 545 |
+
if (baseGroup.isFunction) {
|
| 546 |
+
var func = baseGroup.result;
|
| 547 |
+
var funcData = functions[func];
|
| 548 |
+
if (this.mode === "text" && !funcData.allowedInText) {
|
| 549 |
+
// throw new ParseError(
|
| 550 |
+
// "Can't use function '" + func + "' in text mode",
|
| 551 |
+
// this.lexer, baseGroup.position);
|
| 552 |
+
}
|
| 553 |
+
|
| 554 |
+
var args = this.parseArguments(func, funcData);
|
| 555 |
+
var result = this.callFunction(func, args, args.pop());
|
| 556 |
+
return new ParseNode(result.type, result, this.mode);
|
| 557 |
+
} else {
|
| 558 |
+
return baseGroup.result;
|
| 559 |
+
}
|
| 560 |
+
} else {
|
| 561 |
+
return null;
|
| 562 |
+
}
|
| 563 |
+
};
|
| 564 |
+
|
| 565 |
+
/**
|
| 566 |
+
* Call a function handler with a suitable context and arguments.
|
| 567 |
+
*/
|
| 568 |
+
Parser.prototype.callFunction = function(name, args, positions) {
|
| 569 |
+
var context = {
|
| 570 |
+
funcName: name,
|
| 571 |
+
parser: this,
|
| 572 |
+
lexer: this.lexer,
|
| 573 |
+
positions: positions,
|
| 574 |
+
};
|
| 575 |
+
return functions[name].handler(context, args);
|
| 576 |
+
};
|
| 577 |
+
|
| 578 |
+
/**
|
| 579 |
+
* Parses the arguments of a function or environment
|
| 580 |
+
*
|
| 581 |
+
* @param {string} func "\name" or "\begin{name}"
|
| 582 |
+
* @param {{numArgs:number,numOptionalArgs:number|undefined}} funcData
|
| 583 |
+
* @return the array of arguments, with the list of positions as last element
|
| 584 |
+
*/
|
| 585 |
+
Parser.prototype.parseArguments = function(func, funcData) {
|
| 586 |
+
var totalArgs = funcData.numArgs + funcData.numOptionalArgs;
|
| 587 |
+
if (totalArgs === 0) {
|
| 588 |
+
return [[this.pos]];
|
| 589 |
+
}
|
| 590 |
+
|
| 591 |
+
var baseGreediness = funcData.greediness;
|
| 592 |
+
var positions = [this.pos];
|
| 593 |
+
var args = [];
|
| 594 |
+
|
| 595 |
+
for (var i = 0; i < totalArgs; i++) {
|
| 596 |
+
var argType = funcData.argTypes && funcData.argTypes[i];
|
| 597 |
+
var arg;
|
| 598 |
+
if (i < funcData.numOptionalArgs) {
|
| 599 |
+
if (argType) {
|
| 600 |
+
arg = this.parseSpecialGroup(argType, true);
|
| 601 |
+
} else {
|
| 602 |
+
arg = this.parseOptionalGroup();
|
| 603 |
+
}
|
| 604 |
+
if (!arg) {
|
| 605 |
+
args.push(null);
|
| 606 |
+
positions.push(this.pos);
|
| 607 |
+
continue;
|
| 608 |
+
}
|
| 609 |
+
} else {
|
| 610 |
+
if (argType) {
|
| 611 |
+
arg = this.parseSpecialGroup(argType);
|
| 612 |
+
} else {
|
| 613 |
+
arg = this.parseGroup();
|
| 614 |
+
}
|
| 615 |
+
if (!arg) {
|
| 616 |
+
if (!this.settings.throwOnError &&
|
| 617 |
+
this.nextToken.text[0] === "\\") {
|
| 618 |
+
arg = new ParseFuncOrArgument(
|
| 619 |
+
this.handleUnsupportedCmd(this.nextToken.text),
|
| 620 |
+
false);
|
| 621 |
+
} else {
|
| 622 |
+
throw new ParseError(
|
| 623 |
+
"Expected group after '" + func + "'",
|
| 624 |
+
this.lexer, this.pos);
|
| 625 |
+
}
|
| 626 |
+
}
|
| 627 |
+
}
|
| 628 |
+
var argNode;
|
| 629 |
+
if (arg.isFunction) {
|
| 630 |
+
var argGreediness =
|
| 631 |
+
functions[arg.result].greediness;
|
| 632 |
+
if (argGreediness > baseGreediness) {
|
| 633 |
+
argNode = this.parseFunction(arg);
|
| 634 |
+
} else {
|
| 635 |
+
// throw new ParseError(
|
| 636 |
+
// "Got function '" + arg.result + "' as " +
|
| 637 |
+
// "argument to '" + func + "'",
|
| 638 |
+
// this.lexer, this.pos - 1);
|
| 639 |
+
}
|
| 640 |
+
} else {
|
| 641 |
+
argNode = arg.result;
|
| 642 |
+
}
|
| 643 |
+
args.push(argNode);
|
| 644 |
+
positions.push(this.pos);
|
| 645 |
+
}
|
| 646 |
+
|
| 647 |
+
args.push(positions);
|
| 648 |
+
|
| 649 |
+
return args;
|
| 650 |
+
};
|
| 651 |
+
|
| 652 |
+
|
| 653 |
+
/**
|
| 654 |
+
* Parses a group when the mode is changing. Takes a position, a new mode, and
|
| 655 |
+
* an outer mode that is used to parse the outside.
|
| 656 |
+
*
|
| 657 |
+
* @return {?ParseFuncOrArgument}
|
| 658 |
+
*/
|
| 659 |
+
Parser.prototype.parseSpecialGroup = function(innerMode, optional) {
|
| 660 |
+
var outerMode = this.mode;
|
| 661 |
+
// Handle `original` argTypes
|
| 662 |
+
if (innerMode === "original") {
|
| 663 |
+
innerMode = outerMode;
|
| 664 |
+
}
|
| 665 |
+
|
| 666 |
+
if (innerMode === "color" || innerMode === "size") {
|
| 667 |
+
// color and size modes are special because they should have braces and
|
| 668 |
+
// should only lex a single symbol inside
|
| 669 |
+
var openBrace = this.nextToken;
|
| 670 |
+
if (optional && openBrace.text !== "[") {
|
| 671 |
+
// optional arguments should return null if they don't exist
|
| 672 |
+
return null;
|
| 673 |
+
}
|
| 674 |
+
// The call to expect will lex the token after the '{' in inner mode
|
| 675 |
+
this.mode = innerMode;
|
| 676 |
+
this.expect(optional ? "[" : "{");
|
| 677 |
+
var inner = this.nextToken;
|
| 678 |
+
this.mode = outerMode;
|
| 679 |
+
var data;
|
| 680 |
+
if (innerMode === "color") {
|
| 681 |
+
data = inner.text;
|
| 682 |
+
} else {
|
| 683 |
+
data = inner.data;
|
| 684 |
+
}
|
| 685 |
+
this.consume(); // consume the token stored in inner
|
| 686 |
+
this.expect(optional ? "]" : "}");
|
| 687 |
+
return new ParseFuncOrArgument(
|
| 688 |
+
new ParseNode(innerMode, data, outerMode),
|
| 689 |
+
false);
|
| 690 |
+
} else if (innerMode === "text") {
|
| 691 |
+
// text mode is special because it should ignore the whitespace before
|
| 692 |
+
// it
|
| 693 |
+
var whitespace = this.lexer.lex(this.pos, "whitespace");
|
| 694 |
+
this.pos = whitespace.position;
|
| 695 |
+
}
|
| 696 |
+
|
| 697 |
+
// By the time we get here, innerMode is one of "text" or "math".
|
| 698 |
+
// We switch the mode of the parser, recurse, then restore the old mode.
|
| 699 |
+
this.mode = innerMode;
|
| 700 |
+
this.nextToken = this.lexer.lex(this.pos, innerMode);
|
| 701 |
+
var res;
|
| 702 |
+
if (optional) {
|
| 703 |
+
res = this.parseOptionalGroup();
|
| 704 |
+
} else {
|
| 705 |
+
res = this.parseGroup();
|
| 706 |
+
}
|
| 707 |
+
this.mode = outerMode;
|
| 708 |
+
this.nextToken = this.lexer.lex(this.pos, outerMode);
|
| 709 |
+
return res;
|
| 710 |
+
};
|
| 711 |
+
|
| 712 |
+
/**
|
| 713 |
+
* Parses a group, which is either a single nucleus (like "x") or an expression
|
| 714 |
+
* in braces (like "{x+y}")
|
| 715 |
+
*
|
| 716 |
+
* @return {?ParseFuncOrArgument}
|
| 717 |
+
*/
|
| 718 |
+
Parser.prototype.parseGroup = function() {
|
| 719 |
+
// Try to parse an open brace
|
| 720 |
+
if (this.nextToken.text === "{") {
|
| 721 |
+
// If we get a brace, parse an expression
|
| 722 |
+
this.consume();
|
| 723 |
+
var expression = this.parseExpression(false);
|
| 724 |
+
// Make sure we get a close brace
|
| 725 |
+
this.expect("}");
|
| 726 |
+
return new ParseFuncOrArgument(
|
| 727 |
+
new ParseNode("ordgroup", expression, this.mode),
|
| 728 |
+
false);
|
| 729 |
+
} else {
|
| 730 |
+
// Otherwise, just return a nucleus
|
| 731 |
+
return this.parseSymbol();
|
| 732 |
+
}
|
| 733 |
+
};
|
| 734 |
+
|
| 735 |
+
/**
|
| 736 |
+
* Parses a group, which is an expression in brackets (like "[x+y]")
|
| 737 |
+
*
|
| 738 |
+
* @return {?ParseFuncOrArgument}
|
| 739 |
+
*/
|
| 740 |
+
Parser.prototype.parseOptionalGroup = function() {
|
| 741 |
+
// Try to parse an open bracket
|
| 742 |
+
if (this.nextToken.text === "[") {
|
| 743 |
+
// If we get a brace, parse an expression
|
| 744 |
+
this.consume();
|
| 745 |
+
var expression = this.parseExpression(false, "]");
|
| 746 |
+
// Make sure we get a close bracket
|
| 747 |
+
this.expect("]");
|
| 748 |
+
return new ParseFuncOrArgument(
|
| 749 |
+
new ParseNode("ordgroup", expression, this.mode),
|
| 750 |
+
false);
|
| 751 |
+
} else {
|
| 752 |
+
// Otherwise, return null,
|
| 753 |
+
return null;
|
| 754 |
+
}
|
| 755 |
+
};
|
| 756 |
+
|
| 757 |
+
/**
|
| 758 |
+
* Parse a single symbol out of the string. Here, we handle both the functions
|
| 759 |
+
* we have defined, as well as the single character symbols
|
| 760 |
+
*
|
| 761 |
+
* @return {?ParseFuncOrArgument}
|
| 762 |
+
*/
|
| 763 |
+
Parser.prototype.parseSymbol = function() {
|
| 764 |
+
var nucleus = this.nextToken;
|
| 765 |
+
|
| 766 |
+
if (functions[nucleus.text]) {
|
| 767 |
+
this.consume();
|
| 768 |
+
// If there exists a function with this name, we return the function and
|
| 769 |
+
// say that it is a function.
|
| 770 |
+
return new ParseFuncOrArgument(
|
| 771 |
+
nucleus.text,
|
| 772 |
+
true);
|
| 773 |
+
} else if (symbols[this.mode][nucleus.text]) {
|
| 774 |
+
this.consume();
|
| 775 |
+
// Otherwise if this is a no-argument function, find the type it
|
| 776 |
+
// corresponds to in the symbols map
|
| 777 |
+
return new ParseFuncOrArgument(
|
| 778 |
+
new ParseNode(symbols[this.mode][nucleus.text].group,
|
| 779 |
+
nucleus.text, this.mode),
|
| 780 |
+
false);
|
| 781 |
+
} else if (nucleus.text == "EOF" || nucleus.text == "{") {
|
| 782 |
+
return null;
|
| 783 |
+
|
| 784 |
+
} else {
|
| 785 |
+
this.consume();
|
| 786 |
+
// console.error(nucleus);
|
| 787 |
+
return new ParseFuncOrArgument(
|
| 788 |
+
new ParseNode(symbols["math"]["\\sigma"].group,
|
| 789 |
+
nucleus.text, this.mode),
|
| 790 |
+
false);
|
| 791 |
+
// console.log(nucleus.text);
|
| 792 |
+
// return null;
|
| 793 |
+
}
|
| 794 |
+
};
|
| 795 |
+
|
| 796 |
+
Parser.prototype.ParseNode = ParseNode;
|
| 797 |
+
|
| 798 |
+
module.exports = Parser;
|
katex/src/Settings.js
ADDED
|
@@ -0,0 +1,28 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
/**
|
| 2 |
+
* This is a module for storing settings passed into KaTeX. It correctly handles
|
| 3 |
+
* default settings.
|
| 4 |
+
*/
|
| 5 |
+
|
| 6 |
+
/**
|
| 7 |
+
* Helper function for getting a default value if the value is undefined
|
| 8 |
+
*/
|
| 9 |
+
function get(option, defaultValue) {
|
| 10 |
+
return option === undefined ? defaultValue : option;
|
| 11 |
+
}
|
| 12 |
+
|
| 13 |
+
/**
|
| 14 |
+
* The main Settings object
|
| 15 |
+
*
|
| 16 |
+
* The current options stored are:
|
| 17 |
+
* - displayMode: Whether the expression should be typeset by default in
|
| 18 |
+
* textstyle or displaystyle (default false)
|
| 19 |
+
*/
|
| 20 |
+
function Settings(options) {
|
| 21 |
+
// allow null options
|
| 22 |
+
options = options || {};
|
| 23 |
+
this.displayMode = get(options.displayMode, false);
|
| 24 |
+
this.throwOnError = get(options.throwOnError, true);
|
| 25 |
+
this.errorColor = get(options.errorColor, "#cc0000");
|
| 26 |
+
}
|
| 27 |
+
|
| 28 |
+
module.exports = Settings;
|
katex/src/Style.js
ADDED
|
@@ -0,0 +1,126 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
/**
|
| 2 |
+
* This file contains information and classes for the various kinds of styles
|
| 3 |
+
* used in TeX. It provides a generic `Style` class, which holds information
|
| 4 |
+
* about a specific style. It then provides instances of all the different kinds
|
| 5 |
+
* of styles possible, and provides functions to move between them and get
|
| 6 |
+
* information about them.
|
| 7 |
+
*/
|
| 8 |
+
|
| 9 |
+
/**
|
| 10 |
+
* The main style class. Contains a unique id for the style, a size (which is
|
| 11 |
+
* the same for cramped and uncramped version of a style), a cramped flag, and a
|
| 12 |
+
* size multiplier, which gives the size difference between a style and
|
| 13 |
+
* textstyle.
|
| 14 |
+
*/
|
| 15 |
+
function Style(id, size, multiplier, cramped) {
|
| 16 |
+
this.id = id;
|
| 17 |
+
this.size = size;
|
| 18 |
+
this.cramped = cramped;
|
| 19 |
+
this.sizeMultiplier = multiplier;
|
| 20 |
+
}
|
| 21 |
+
|
| 22 |
+
/**
|
| 23 |
+
* Get the style of a superscript given a base in the current style.
|
| 24 |
+
*/
|
| 25 |
+
Style.prototype.sup = function() {
|
| 26 |
+
return styles[sup[this.id]];
|
| 27 |
+
};
|
| 28 |
+
|
| 29 |
+
/**
|
| 30 |
+
* Get the style of a subscript given a base in the current style.
|
| 31 |
+
*/
|
| 32 |
+
Style.prototype.sub = function() {
|
| 33 |
+
return styles[sub[this.id]];
|
| 34 |
+
};
|
| 35 |
+
|
| 36 |
+
/**
|
| 37 |
+
* Get the style of a fraction numerator given the fraction in the current
|
| 38 |
+
* style.
|
| 39 |
+
*/
|
| 40 |
+
Style.prototype.fracNum = function() {
|
| 41 |
+
return styles[fracNum[this.id]];
|
| 42 |
+
};
|
| 43 |
+
|
| 44 |
+
/**
|
| 45 |
+
* Get the style of a fraction denominator given the fraction in the current
|
| 46 |
+
* style.
|
| 47 |
+
*/
|
| 48 |
+
Style.prototype.fracDen = function() {
|
| 49 |
+
return styles[fracDen[this.id]];
|
| 50 |
+
};
|
| 51 |
+
|
| 52 |
+
/**
|
| 53 |
+
* Get the cramped version of a style (in particular, cramping a cramped style
|
| 54 |
+
* doesn't change the style).
|
| 55 |
+
*/
|
| 56 |
+
Style.prototype.cramp = function() {
|
| 57 |
+
return styles[cramp[this.id]];
|
| 58 |
+
};
|
| 59 |
+
|
| 60 |
+
/**
|
| 61 |
+
* HTML class name, like "displaystyle cramped"
|
| 62 |
+
*/
|
| 63 |
+
Style.prototype.cls = function() {
|
| 64 |
+
return sizeNames[this.size] + (this.cramped ? " cramped" : " uncramped");
|
| 65 |
+
};
|
| 66 |
+
|
| 67 |
+
/**
|
| 68 |
+
* HTML Reset class name, like "reset-textstyle"
|
| 69 |
+
*/
|
| 70 |
+
Style.prototype.reset = function() {
|
| 71 |
+
return resetNames[this.size];
|
| 72 |
+
};
|
| 73 |
+
|
| 74 |
+
// IDs of the different styles
|
| 75 |
+
var D = 0;
|
| 76 |
+
var Dc = 1;
|
| 77 |
+
var T = 2;
|
| 78 |
+
var Tc = 3;
|
| 79 |
+
var S = 4;
|
| 80 |
+
var Sc = 5;
|
| 81 |
+
var SS = 6;
|
| 82 |
+
var SSc = 7;
|
| 83 |
+
|
| 84 |
+
// String names for the different sizes
|
| 85 |
+
var sizeNames = [
|
| 86 |
+
"displaystyle textstyle",
|
| 87 |
+
"textstyle",
|
| 88 |
+
"scriptstyle",
|
| 89 |
+
"scriptscriptstyle",
|
| 90 |
+
];
|
| 91 |
+
|
| 92 |
+
// Reset names for the different sizes
|
| 93 |
+
var resetNames = [
|
| 94 |
+
"reset-textstyle",
|
| 95 |
+
"reset-textstyle",
|
| 96 |
+
"reset-scriptstyle",
|
| 97 |
+
"reset-scriptscriptstyle",
|
| 98 |
+
];
|
| 99 |
+
|
| 100 |
+
// Instances of the different styles
|
| 101 |
+
var styles = [
|
| 102 |
+
new Style(D, 0, 1.0, false),
|
| 103 |
+
new Style(Dc, 0, 1.0, true),
|
| 104 |
+
new Style(T, 1, 1.0, false),
|
| 105 |
+
new Style(Tc, 1, 1.0, true),
|
| 106 |
+
new Style(S, 2, 0.7, false),
|
| 107 |
+
new Style(Sc, 2, 0.7, true),
|
| 108 |
+
new Style(SS, 3, 0.5, false),
|
| 109 |
+
new Style(SSc, 3, 0.5, true),
|
| 110 |
+
];
|
| 111 |
+
|
| 112 |
+
// Lookup tables for switching from one style to another
|
| 113 |
+
var sup = [S, Sc, S, Sc, SS, SSc, SS, SSc];
|
| 114 |
+
var sub = [Sc, Sc, Sc, Sc, SSc, SSc, SSc, SSc];
|
| 115 |
+
var fracNum = [T, Tc, S, Sc, SS, SSc, SS, SSc];
|
| 116 |
+
var fracDen = [Tc, Tc, Sc, Sc, SSc, SSc, SSc, SSc];
|
| 117 |
+
var cramp = [Dc, Dc, Tc, Tc, Sc, Sc, SSc, SSc];
|
| 118 |
+
|
| 119 |
+
// We only export some of the styles. Also, we don't export the `Style` class so
|
| 120 |
+
// no more styles can be generated.
|
| 121 |
+
module.exports = {
|
| 122 |
+
DISPLAY: styles[D],
|
| 123 |
+
TEXT: styles[T],
|
| 124 |
+
SCRIPT: styles[S],
|
| 125 |
+
SCRIPTSCRIPT: styles[SS],
|
| 126 |
+
};
|
katex/src/buildCommon.js
ADDED
|
@@ -0,0 +1,450 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
/* eslint no-console:0 */
|
| 2 |
+
/**
|
| 3 |
+
* This module contains general functions that can be used for building
|
| 4 |
+
* different kinds of domTree nodes in a consistent manner.
|
| 5 |
+
*/
|
| 6 |
+
|
| 7 |
+
var domTree = require("./domTree");
|
| 8 |
+
var fontMetrics = require("./fontMetrics");
|
| 9 |
+
var symbols = require("./symbols");
|
| 10 |
+
var utils = require("./utils");
|
| 11 |
+
|
| 12 |
+
var greekCapitals = [
|
| 13 |
+
"\\Gamma",
|
| 14 |
+
"\\Delta",
|
| 15 |
+
"\\Theta",
|
| 16 |
+
"\\Lambda",
|
| 17 |
+
"\\Xi",
|
| 18 |
+
"\\Pi",
|
| 19 |
+
"\\Sigma",
|
| 20 |
+
"\\Upsilon",
|
| 21 |
+
"\\Phi",
|
| 22 |
+
"\\Psi",
|
| 23 |
+
"\\Omega",
|
| 24 |
+
];
|
| 25 |
+
|
| 26 |
+
var dotlessLetters = [
|
| 27 |
+
"\u0131", // dotless i, \imath
|
| 28 |
+
"\u0237", // dotless j, \jmath
|
| 29 |
+
];
|
| 30 |
+
|
| 31 |
+
/**
|
| 32 |
+
* Makes a symbolNode after translation via the list of symbols in symbols.js.
|
| 33 |
+
* Correctly pulls out metrics for the character, and optionally takes a list of
|
| 34 |
+
* classes to be attached to the node.
|
| 35 |
+
*/
|
| 36 |
+
var makeSymbol = function(value, style, mode, color, classes) {
|
| 37 |
+
// Replace the value with its replaced value from symbol.js
|
| 38 |
+
if (symbols[mode][value] && symbols[mode][value].replace) {
|
| 39 |
+
value = symbols[mode][value].replace;
|
| 40 |
+
}
|
| 41 |
+
|
| 42 |
+
var metrics = fontMetrics.getCharacterMetrics(value, style);
|
| 43 |
+
|
| 44 |
+
var symbolNode;
|
| 45 |
+
if (metrics) {
|
| 46 |
+
symbolNode = new domTree.symbolNode(
|
| 47 |
+
value, metrics.height, metrics.depth, metrics.italic, metrics.skew,
|
| 48 |
+
classes);
|
| 49 |
+
} else {
|
| 50 |
+
// TODO(emily): Figure out a good way to only print this in development
|
| 51 |
+
typeof console !== "undefined" && console.warn(
|
| 52 |
+
"No character metrics for '" + value + "' in style '" +
|
| 53 |
+
style + "'");
|
| 54 |
+
symbolNode = new domTree.symbolNode(value, 0, 0, 0, 0, classes);
|
| 55 |
+
}
|
| 56 |
+
|
| 57 |
+
if (color) {
|
| 58 |
+
symbolNode.style.color = color;
|
| 59 |
+
}
|
| 60 |
+
|
| 61 |
+
return symbolNode;
|
| 62 |
+
};
|
| 63 |
+
|
| 64 |
+
/**
|
| 65 |
+
* Makes a symbol in Main-Regular or AMS-Regular.
|
| 66 |
+
* Used for rel, bin, open, close, inner, and punct.
|
| 67 |
+
*/
|
| 68 |
+
var mathsym = function(value, mode, color, classes) {
|
| 69 |
+
// Decide what font to render the symbol in by its entry in the symbols
|
| 70 |
+
// table.
|
| 71 |
+
// Have a special case for when the value = \ because the \ is used as a
|
| 72 |
+
// textord in unsupported command errors but cannot be parsed as a regular
|
| 73 |
+
// text ordinal and is therefore not present as a symbol in the symbols
|
| 74 |
+
// table for text
|
| 75 |
+
if (value === "\\" || symbols[mode][value].font === "main") {
|
| 76 |
+
return makeSymbol(value, "Main-Regular", mode, color, classes);
|
| 77 |
+
} else {
|
| 78 |
+
return makeSymbol(
|
| 79 |
+
value, "AMS-Regular", mode, color, classes.concat(["amsrm"]));
|
| 80 |
+
}
|
| 81 |
+
};
|
| 82 |
+
|
| 83 |
+
/**
|
| 84 |
+
* Makes a symbol in the default font for mathords and textords.
|
| 85 |
+
*/
|
| 86 |
+
var mathDefault = function(value, mode, color, classes, type) {
|
| 87 |
+
if (type === "mathord") {
|
| 88 |
+
return mathit(value, mode, color, classes);
|
| 89 |
+
} else if (type === "textord") {
|
| 90 |
+
return makeSymbol(
|
| 91 |
+
value, "Main-Regular", mode, color, classes.concat(["mathrm"]));
|
| 92 |
+
} else {
|
| 93 |
+
throw new Error("unexpected type: " + type + " in mathDefault");
|
| 94 |
+
}
|
| 95 |
+
};
|
| 96 |
+
|
| 97 |
+
/**
|
| 98 |
+
* Makes a symbol in the italic math font.
|
| 99 |
+
*/
|
| 100 |
+
var mathit = function(value, mode, color, classes) {
|
| 101 |
+
if (/[0-9]/.test(value.charAt(0)) ||
|
| 102 |
+
// glyphs for \imath and \jmath do not exist in Math-Italic so we
|
| 103 |
+
// need to use Main-Italic instead
|
| 104 |
+
utils.contains(dotlessLetters, value) ||
|
| 105 |
+
utils.contains(greekCapitals, value)) {
|
| 106 |
+
return makeSymbol(
|
| 107 |
+
value, "Main-Italic", mode, color, classes.concat(["mainit"]));
|
| 108 |
+
} else {
|
| 109 |
+
return makeSymbol(
|
| 110 |
+
value, "Math-Italic", mode, color, classes.concat(["mathit"]));
|
| 111 |
+
}
|
| 112 |
+
};
|
| 113 |
+
|
| 114 |
+
/**
|
| 115 |
+
* Makes either a mathord or textord in the correct font and color.
|
| 116 |
+
*/
|
| 117 |
+
var makeOrd = function(group, options, type) {
|
| 118 |
+
var mode = group.mode;
|
| 119 |
+
var value = group.value;
|
| 120 |
+
if (symbols[mode][value] && symbols[mode][value].replace) {
|
| 121 |
+
value = symbols[mode][value].replace;
|
| 122 |
+
}
|
| 123 |
+
|
| 124 |
+
var classes = ["mord"];
|
| 125 |
+
var color = options.getColor();
|
| 126 |
+
|
| 127 |
+
var font = options.font;
|
| 128 |
+
if (font) {
|
| 129 |
+
if (font === "mathit" || utils.contains(dotlessLetters, value)) {
|
| 130 |
+
return mathit(value, mode, color, classes);
|
| 131 |
+
} else {
|
| 132 |
+
var fontName = fontMap[font].fontName;
|
| 133 |
+
if (fontMetrics.getCharacterMetrics(value, fontName)) {
|
| 134 |
+
return makeSymbol(
|
| 135 |
+
value, fontName, mode, color, classes.concat([font]));
|
| 136 |
+
} else {
|
| 137 |
+
return mathDefault(value, mode, color, classes, type);
|
| 138 |
+
}
|
| 139 |
+
}
|
| 140 |
+
} else {
|
| 141 |
+
return mathDefault(value, mode, color, classes, type);
|
| 142 |
+
}
|
| 143 |
+
};
|
| 144 |
+
|
| 145 |
+
/**
|
| 146 |
+
* Calculate the height, depth, and maxFontSize of an element based on its
|
| 147 |
+
* children.
|
| 148 |
+
*/
|
| 149 |
+
var sizeElementFromChildren = function(elem) {
|
| 150 |
+
var height = 0;
|
| 151 |
+
var depth = 0;
|
| 152 |
+
var maxFontSize = 0;
|
| 153 |
+
|
| 154 |
+
if (elem.children) {
|
| 155 |
+
for (var i = 0; i < elem.children.length; i++) {
|
| 156 |
+
if (elem.children[i].height > height) {
|
| 157 |
+
height = elem.children[i].height;
|
| 158 |
+
}
|
| 159 |
+
if (elem.children[i].depth > depth) {
|
| 160 |
+
depth = elem.children[i].depth;
|
| 161 |
+
}
|
| 162 |
+
if (elem.children[i].maxFontSize > maxFontSize) {
|
| 163 |
+
maxFontSize = elem.children[i].maxFontSize;
|
| 164 |
+
}
|
| 165 |
+
}
|
| 166 |
+
}
|
| 167 |
+
|
| 168 |
+
elem.height = height;
|
| 169 |
+
elem.depth = depth;
|
| 170 |
+
elem.maxFontSize = maxFontSize;
|
| 171 |
+
};
|
| 172 |
+
|
| 173 |
+
/**
|
| 174 |
+
* Makes a span with the given list of classes, list of children, and color.
|
| 175 |
+
*/
|
| 176 |
+
var makeSpan = function(classes, children, color) {
|
| 177 |
+
var span = new domTree.span(classes, children);
|
| 178 |
+
|
| 179 |
+
sizeElementFromChildren(span);
|
| 180 |
+
|
| 181 |
+
if (color) {
|
| 182 |
+
span.style.color = color;
|
| 183 |
+
}
|
| 184 |
+
|
| 185 |
+
return span;
|
| 186 |
+
};
|
| 187 |
+
|
| 188 |
+
/**
|
| 189 |
+
* Makes a document fragment with the given list of children.
|
| 190 |
+
*/
|
| 191 |
+
var makeFragment = function(children) {
|
| 192 |
+
var fragment = new domTree.documentFragment(children);
|
| 193 |
+
|
| 194 |
+
sizeElementFromChildren(fragment);
|
| 195 |
+
|
| 196 |
+
return fragment;
|
| 197 |
+
};
|
| 198 |
+
|
| 199 |
+
/**
|
| 200 |
+
* Makes an element placed in each of the vlist elements to ensure that each
|
| 201 |
+
* element has the same max font size. To do this, we create a zero-width space
|
| 202 |
+
* with the correct font size.
|
| 203 |
+
*/
|
| 204 |
+
var makeFontSizer = function(options, fontSize) {
|
| 205 |
+
var fontSizeInner = makeSpan([], [new domTree.symbolNode("\u200b")]);
|
| 206 |
+
fontSizeInner.style.fontSize =
|
| 207 |
+
(fontSize / options.style.sizeMultiplier) + "em";
|
| 208 |
+
|
| 209 |
+
var fontSizer = makeSpan(
|
| 210 |
+
["fontsize-ensurer", "reset-" + options.size, "size5"],
|
| 211 |
+
[fontSizeInner]);
|
| 212 |
+
|
| 213 |
+
return fontSizer;
|
| 214 |
+
};
|
| 215 |
+
|
| 216 |
+
/**
|
| 217 |
+
* Makes a vertical list by stacking elements and kerns on top of each other.
|
| 218 |
+
* Allows for many different ways of specifying the positioning method.
|
| 219 |
+
*
|
| 220 |
+
* Arguments:
|
| 221 |
+
* - children: A list of child or kern nodes to be stacked on top of each other
|
| 222 |
+
* (i.e. the first element will be at the bottom, and the last at
|
| 223 |
+
* the top). Element nodes are specified as
|
| 224 |
+
* {type: "elem", elem: node}
|
| 225 |
+
* while kern nodes are specified as
|
| 226 |
+
* {type: "kern", size: size}
|
| 227 |
+
* - positionType: The method by which the vlist should be positioned. Valid
|
| 228 |
+
* values are:
|
| 229 |
+
* - "individualShift": The children list only contains elem
|
| 230 |
+
* nodes, and each node contains an extra
|
| 231 |
+
* "shift" value of how much it should be
|
| 232 |
+
* shifted (note that shifting is always
|
| 233 |
+
* moving downwards). positionData is
|
| 234 |
+
* ignored.
|
| 235 |
+
* - "top": The positionData specifies the topmost point of
|
| 236 |
+
* the vlist (note this is expected to be a height,
|
| 237 |
+
* so positive values move up)
|
| 238 |
+
* - "bottom": The positionData specifies the bottommost point
|
| 239 |
+
* of the vlist (note this is expected to be a
|
| 240 |
+
* depth, so positive values move down
|
| 241 |
+
* - "shift": The vlist will be positioned such that its
|
| 242 |
+
* baseline is positionData away from the baseline
|
| 243 |
+
* of the first child. Positive values move
|
| 244 |
+
* downwards.
|
| 245 |
+
* - "firstBaseline": The vlist will be positioned such that
|
| 246 |
+
* its baseline is aligned with the
|
| 247 |
+
* baseline of the first child.
|
| 248 |
+
* positionData is ignored. (this is
|
| 249 |
+
* equivalent to "shift" with
|
| 250 |
+
* positionData=0)
|
| 251 |
+
* - positionData: Data used in different ways depending on positionType
|
| 252 |
+
* - options: An Options object
|
| 253 |
+
*
|
| 254 |
+
*/
|
| 255 |
+
var makeVList = function(children, positionType, positionData, options) {
|
| 256 |
+
var depth;
|
| 257 |
+
var currPos;
|
| 258 |
+
var i;
|
| 259 |
+
if (positionType === "individualShift") {
|
| 260 |
+
var oldChildren = children;
|
| 261 |
+
children = [oldChildren[0]];
|
| 262 |
+
|
| 263 |
+
// Add in kerns to the list of children to get each element to be
|
| 264 |
+
// shifted to the correct specified shift
|
| 265 |
+
depth = -oldChildren[0].shift - oldChildren[0].elem.depth;
|
| 266 |
+
currPos = depth;
|
| 267 |
+
for (i = 1; i < oldChildren.length; i++) {
|
| 268 |
+
var diff = -oldChildren[i].shift - currPos -
|
| 269 |
+
oldChildren[i].elem.depth;
|
| 270 |
+
var size = diff -
|
| 271 |
+
(oldChildren[i - 1].elem.height +
|
| 272 |
+
oldChildren[i - 1].elem.depth);
|
| 273 |
+
|
| 274 |
+
currPos = currPos + diff;
|
| 275 |
+
|
| 276 |
+
children.push({type: "kern", size: size});
|
| 277 |
+
children.push(oldChildren[i]);
|
| 278 |
+
}
|
| 279 |
+
} else if (positionType === "top") {
|
| 280 |
+
// We always start at the bottom, so calculate the bottom by adding up
|
| 281 |
+
// all the sizes
|
| 282 |
+
var bottom = positionData;
|
| 283 |
+
for (i = 0; i < children.length; i++) {
|
| 284 |
+
if (children[i].type === "kern") {
|
| 285 |
+
bottom -= children[i].size;
|
| 286 |
+
} else {
|
| 287 |
+
bottom -= children[i].elem.height + children[i].elem.depth;
|
| 288 |
+
}
|
| 289 |
+
}
|
| 290 |
+
depth = bottom;
|
| 291 |
+
} else if (positionType === "bottom") {
|
| 292 |
+
depth = -positionData;
|
| 293 |
+
} else if (positionType === "shift") {
|
| 294 |
+
depth = -children[0].elem.depth - positionData;
|
| 295 |
+
} else if (positionType === "firstBaseline") {
|
| 296 |
+
depth = -children[0].elem.depth;
|
| 297 |
+
} else {
|
| 298 |
+
depth = 0;
|
| 299 |
+
}
|
| 300 |
+
|
| 301 |
+
// Make the fontSizer
|
| 302 |
+
var maxFontSize = 0;
|
| 303 |
+
for (i = 0; i < children.length; i++) {
|
| 304 |
+
if (children[i].type === "elem") {
|
| 305 |
+
maxFontSize = Math.max(maxFontSize, children[i].elem.maxFontSize);
|
| 306 |
+
}
|
| 307 |
+
}
|
| 308 |
+
var fontSizer = makeFontSizer(options, maxFontSize);
|
| 309 |
+
|
| 310 |
+
// Create a new list of actual children at the correct offsets
|
| 311 |
+
var realChildren = [];
|
| 312 |
+
currPos = depth;
|
| 313 |
+
for (i = 0; i < children.length; i++) {
|
| 314 |
+
if (children[i].type === "kern") {
|
| 315 |
+
currPos += children[i].size;
|
| 316 |
+
} else {
|
| 317 |
+
var child = children[i].elem;
|
| 318 |
+
|
| 319 |
+
var shift = -child.depth - currPos;
|
| 320 |
+
currPos += child.height + child.depth;
|
| 321 |
+
|
| 322 |
+
var childWrap = makeSpan([], [fontSizer, child]);
|
| 323 |
+
childWrap.height -= shift;
|
| 324 |
+
childWrap.depth += shift;
|
| 325 |
+
childWrap.style.top = shift + "em";
|
| 326 |
+
|
| 327 |
+
realChildren.push(childWrap);
|
| 328 |
+
}
|
| 329 |
+
}
|
| 330 |
+
|
| 331 |
+
// Add in an element at the end with no offset to fix the calculation of
|
| 332 |
+
// baselines in some browsers (namely IE, sometimes safari)
|
| 333 |
+
var baselineFix = makeSpan(
|
| 334 |
+
["baseline-fix"], [fontSizer, new domTree.symbolNode("\u200b")]);
|
| 335 |
+
realChildren.push(baselineFix);
|
| 336 |
+
|
| 337 |
+
var vlist = makeSpan(["vlist"], realChildren);
|
| 338 |
+
// Fix the final height and depth, in case there were kerns at the ends
|
| 339 |
+
// since the makeSpan calculation won't take that in to account.
|
| 340 |
+
vlist.height = Math.max(currPos, vlist.height);
|
| 341 |
+
vlist.depth = Math.max(-depth, vlist.depth);
|
| 342 |
+
return vlist;
|
| 343 |
+
};
|
| 344 |
+
|
| 345 |
+
// A table of size -> font size for the different sizing functions
|
| 346 |
+
var sizingMultiplier = {
|
| 347 |
+
size1: 0.5,
|
| 348 |
+
size2: 0.7,
|
| 349 |
+
size3: 0.8,
|
| 350 |
+
size4: 0.9,
|
| 351 |
+
size5: 1.0,
|
| 352 |
+
size6: 1.2,
|
| 353 |
+
size7: 1.44,
|
| 354 |
+
size8: 1.73,
|
| 355 |
+
size9: 2.07,
|
| 356 |
+
size10: 2.49,
|
| 357 |
+
};
|
| 358 |
+
|
| 359 |
+
// A map of spacing functions to their attributes, like size and corresponding
|
| 360 |
+
// CSS class
|
| 361 |
+
var spacingFunctions = {
|
| 362 |
+
"\\qquad": {
|
| 363 |
+
size: "2em",
|
| 364 |
+
className: "qquad",
|
| 365 |
+
},
|
| 366 |
+
"\\quad": {
|
| 367 |
+
size: "1em",
|
| 368 |
+
className: "quad",
|
| 369 |
+
},
|
| 370 |
+
"\\enspace": {
|
| 371 |
+
size: "0.5em",
|
| 372 |
+
className: "enspace",
|
| 373 |
+
},
|
| 374 |
+
"\\;": {
|
| 375 |
+
size: "0.277778em",
|
| 376 |
+
className: "thickspace",
|
| 377 |
+
},
|
| 378 |
+
"\\:": {
|
| 379 |
+
size: "0.22222em",
|
| 380 |
+
className: "mediumspace",
|
| 381 |
+
},
|
| 382 |
+
"\\,": {
|
| 383 |
+
size: "0.16667em",
|
| 384 |
+
className: "thinspace",
|
| 385 |
+
},
|
| 386 |
+
"\\!": {
|
| 387 |
+
size: "-0.16667em",
|
| 388 |
+
className: "negativethinspace",
|
| 389 |
+
},
|
| 390 |
+
};
|
| 391 |
+
|
| 392 |
+
/**
|
| 393 |
+
* Maps TeX font commands to objects containing:
|
| 394 |
+
* - variant: string used for "mathvariant" attribute in buildMathML.js
|
| 395 |
+
* - fontName: the "style" parameter to fontMetrics.getCharacterMetrics
|
| 396 |
+
*/
|
| 397 |
+
// A map between tex font commands an MathML mathvariant attribute values
|
| 398 |
+
var fontMap = {
|
| 399 |
+
// styles
|
| 400 |
+
"mathbf": {
|
| 401 |
+
variant: "bold",
|
| 402 |
+
fontName: "Main-Bold",
|
| 403 |
+
},
|
| 404 |
+
"mathrm": {
|
| 405 |
+
variant: "normal",
|
| 406 |
+
fontName: "Main-Regular",
|
| 407 |
+
},
|
| 408 |
+
|
| 409 |
+
// "mathit" is missing because it requires the use of two fonts: Main-Italic
|
| 410 |
+
// and Math-Italic. This is handled by a special case in makeOrd which ends
|
| 411 |
+
// up calling mathit.
|
| 412 |
+
|
| 413 |
+
// families
|
| 414 |
+
"mathbb": {
|
| 415 |
+
variant: "double-struck",
|
| 416 |
+
fontName: "AMS-Regular",
|
| 417 |
+
},
|
| 418 |
+
"mathcal": {
|
| 419 |
+
variant: "script",
|
| 420 |
+
fontName: "Caligraphic-Regular",
|
| 421 |
+
},
|
| 422 |
+
"mathfrak": {
|
| 423 |
+
variant: "fraktur",
|
| 424 |
+
fontName: "Fraktur-Regular",
|
| 425 |
+
},
|
| 426 |
+
"mathscr": {
|
| 427 |
+
variant: "script",
|
| 428 |
+
fontName: "Script-Regular",
|
| 429 |
+
},
|
| 430 |
+
"mathsf": {
|
| 431 |
+
variant: "sans-serif",
|
| 432 |
+
fontName: "SansSerif-Regular",
|
| 433 |
+
},
|
| 434 |
+
"mathtt": {
|
| 435 |
+
variant: "monospace",
|
| 436 |
+
fontName: "Typewriter-Regular",
|
| 437 |
+
},
|
| 438 |
+
};
|
| 439 |
+
|
| 440 |
+
module.exports = {
|
| 441 |
+
fontMap: fontMap,
|
| 442 |
+
makeSymbol: makeSymbol,
|
| 443 |
+
mathsym: mathsym,
|
| 444 |
+
makeSpan: makeSpan,
|
| 445 |
+
makeFragment: makeFragment,
|
| 446 |
+
makeVList: makeVList,
|
| 447 |
+
makeOrd: makeOrd,
|
| 448 |
+
sizingMultiplier: sizingMultiplier,
|
| 449 |
+
spacingFunctions: spacingFunctions,
|
| 450 |
+
};
|
katex/src/buildHTML.js
ADDED
|
@@ -0,0 +1,1402 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
/* eslint no-console:0 */
|
| 2 |
+
/**
|
| 3 |
+
* This file does the main work of building a domTree structure from a parse
|
| 4 |
+
* tree. The entry point is the `buildHTML` function, which takes a parse tree.
|
| 5 |
+
* Then, the buildExpression, buildGroup, and various groupTypes functions are
|
| 6 |
+
* called, to produce a final HTML tree.
|
| 7 |
+
*/
|
| 8 |
+
|
| 9 |
+
var ParseError = require("./ParseError");
|
| 10 |
+
var Style = require("./Style");
|
| 11 |
+
|
| 12 |
+
var buildCommon = require("./buildCommon");
|
| 13 |
+
var delimiter = require("./delimiter");
|
| 14 |
+
var domTree = require("./domTree");
|
| 15 |
+
var fontMetrics = require("./fontMetrics");
|
| 16 |
+
var utils = require("./utils");
|
| 17 |
+
|
| 18 |
+
var makeSpan = buildCommon.makeSpan;
|
| 19 |
+
|
| 20 |
+
/**
|
| 21 |
+
* Take a list of nodes, build them in order, and return a list of the built
|
| 22 |
+
* nodes. This function handles the `prev` node correctly, and passes the
|
| 23 |
+
* previous element from the list as the prev of the next element.
|
| 24 |
+
*/
|
| 25 |
+
var buildExpression = function(expression, options, prev) {
|
| 26 |
+
var groups = [];
|
| 27 |
+
for (var i = 0; i < expression.length; i++) {
|
| 28 |
+
var group = expression[i];
|
| 29 |
+
groups.push(buildGroup(group, options, prev));
|
| 30 |
+
prev = group;
|
| 31 |
+
}
|
| 32 |
+
return groups;
|
| 33 |
+
};
|
| 34 |
+
|
| 35 |
+
// List of types used by getTypeOfGroup,
|
| 36 |
+
// see https://github.com/Khan/KaTeX/wiki/Examining-TeX#group-types
|
| 37 |
+
var groupToType = {
|
| 38 |
+
mathord: "mord",
|
| 39 |
+
textord: "mord",
|
| 40 |
+
bin: "mbin",
|
| 41 |
+
rel: "mrel",
|
| 42 |
+
text: "mord",
|
| 43 |
+
open: "mopen",
|
| 44 |
+
close: "mclose",
|
| 45 |
+
inner: "minner",
|
| 46 |
+
genfrac: "mord",
|
| 47 |
+
array: "mord",
|
| 48 |
+
spacing: "mord",
|
| 49 |
+
punct: "mpunct",
|
| 50 |
+
ordgroup: "mord",
|
| 51 |
+
op: "mop",
|
| 52 |
+
katex: "mord",
|
| 53 |
+
overline: "mord",
|
| 54 |
+
underline: "mord",
|
| 55 |
+
rule: "mord",
|
| 56 |
+
leftright: "minner",
|
| 57 |
+
sqrt: "mord",
|
| 58 |
+
accent: "mord",
|
| 59 |
+
};
|
| 60 |
+
|
| 61 |
+
/**
|
| 62 |
+
* Gets the final math type of an expression, given its group type. This type is
|
| 63 |
+
* used to determine spacing between elements, and affects bin elements by
|
| 64 |
+
* causing them to change depending on what types are around them. This type
|
| 65 |
+
* must be attached to the outermost node of an element as a CSS class so that
|
| 66 |
+
* spacing with its surrounding elements works correctly.
|
| 67 |
+
*
|
| 68 |
+
* Some elements can be mapped one-to-one from group type to math type, and
|
| 69 |
+
* those are listed in the `groupToType` table.
|
| 70 |
+
*
|
| 71 |
+
* Others (usually elements that wrap around other elements) often have
|
| 72 |
+
* recursive definitions, and thus call `getTypeOfGroup` on their inner
|
| 73 |
+
* elements.
|
| 74 |
+
*/
|
| 75 |
+
var getTypeOfGroup = function(group) {
|
| 76 |
+
if (group == null) {
|
| 77 |
+
// Like when typesetting $^3$
|
| 78 |
+
return groupToType.mathord;
|
| 79 |
+
} else if (group.type === "supsub") {
|
| 80 |
+
return getTypeOfGroup(group.value.base);
|
| 81 |
+
} else if (group.type === "llap" || group.type === "rlap") {
|
| 82 |
+
return getTypeOfGroup(group.value);
|
| 83 |
+
} else if (group.type === "color") {
|
| 84 |
+
return getTypeOfGroup(group.value.value);
|
| 85 |
+
} else if (group.type === "sizing") {
|
| 86 |
+
return getTypeOfGroup(group.value.value);
|
| 87 |
+
} else if (group.type === "styling") {
|
| 88 |
+
return getTypeOfGroup(group.value.value);
|
| 89 |
+
} else if (group.type === "delimsizing") {
|
| 90 |
+
return groupToType[group.value.delimType];
|
| 91 |
+
} else {
|
| 92 |
+
return groupToType[group.type];
|
| 93 |
+
}
|
| 94 |
+
};
|
| 95 |
+
|
| 96 |
+
/**
|
| 97 |
+
* Sometimes, groups perform special rules when they have superscripts or
|
| 98 |
+
* subscripts attached to them. This function lets the `supsub` group know that
|
| 99 |
+
* its inner element should handle the superscripts and subscripts instead of
|
| 100 |
+
* handling them itself.
|
| 101 |
+
*/
|
| 102 |
+
var shouldHandleSupSub = function(group, options) {
|
| 103 |
+
if (!group) {
|
| 104 |
+
return false;
|
| 105 |
+
} else if (group.type === "op") {
|
| 106 |
+
// Operators handle supsubs differently when they have limits
|
| 107 |
+
// (e.g. `\displaystyle\sum_2^3`)
|
| 108 |
+
return group.value.limits &&
|
| 109 |
+
(options.style.size === Style.DISPLAY.size ||
|
| 110 |
+
group.value.alwaysHandleSupSub);
|
| 111 |
+
} else if (group.type === "accent") {
|
| 112 |
+
return isCharacterBox(group.value.base);
|
| 113 |
+
} else {
|
| 114 |
+
return null;
|
| 115 |
+
}
|
| 116 |
+
};
|
| 117 |
+
|
| 118 |
+
/**
|
| 119 |
+
* Sometimes we want to pull out the innermost element of a group. In most
|
| 120 |
+
* cases, this will just be the group itself, but when ordgroups and colors have
|
| 121 |
+
* a single element, we want to pull that out.
|
| 122 |
+
*/
|
| 123 |
+
var getBaseElem = function(group) {
|
| 124 |
+
if (!group) {
|
| 125 |
+
return false;
|
| 126 |
+
} else if (group.type === "ordgroup") {
|
| 127 |
+
if (group.value.length === 1) {
|
| 128 |
+
return getBaseElem(group.value[0]);
|
| 129 |
+
} else {
|
| 130 |
+
return group;
|
| 131 |
+
}
|
| 132 |
+
} else if (group.type === "color") {
|
| 133 |
+
if (group.value.value.length === 1) {
|
| 134 |
+
return getBaseElem(group.value.value[0]);
|
| 135 |
+
} else {
|
| 136 |
+
return group;
|
| 137 |
+
}
|
| 138 |
+
} else {
|
| 139 |
+
return group;
|
| 140 |
+
}
|
| 141 |
+
};
|
| 142 |
+
|
| 143 |
+
/**
|
| 144 |
+
* TeXbook algorithms often reference "character boxes", which are simply groups
|
| 145 |
+
* with a single character in them. To decide if something is a character box,
|
| 146 |
+
* we find its innermost group, and see if it is a single character.
|
| 147 |
+
*/
|
| 148 |
+
var isCharacterBox = function(group) {
|
| 149 |
+
var baseElem = getBaseElem(group);
|
| 150 |
+
|
| 151 |
+
// These are all they types of groups which hold single characters
|
| 152 |
+
return baseElem.type === "mathord" ||
|
| 153 |
+
baseElem.type === "textord" ||
|
| 154 |
+
baseElem.type === "bin" ||
|
| 155 |
+
baseElem.type === "rel" ||
|
| 156 |
+
baseElem.type === "inner" ||
|
| 157 |
+
baseElem.type === "open" ||
|
| 158 |
+
baseElem.type === "close" ||
|
| 159 |
+
baseElem.type === "punct";
|
| 160 |
+
};
|
| 161 |
+
|
| 162 |
+
var makeNullDelimiter = function(options) {
|
| 163 |
+
return makeSpan([
|
| 164 |
+
"sizing", "reset-" + options.size, "size5",
|
| 165 |
+
options.style.reset(), Style.TEXT.cls(),
|
| 166 |
+
"nulldelimiter",
|
| 167 |
+
]);
|
| 168 |
+
};
|
| 169 |
+
|
| 170 |
+
/**
|
| 171 |
+
* This is a map of group types to the function used to handle that type.
|
| 172 |
+
* Simpler types come at the beginning, while complicated types come afterwards.
|
| 173 |
+
*/
|
| 174 |
+
var groupTypes = {};
|
| 175 |
+
|
| 176 |
+
groupTypes.mathord = function(group, options, prev) {
|
| 177 |
+
return buildCommon.makeOrd(group, options, "mathord");
|
| 178 |
+
};
|
| 179 |
+
|
| 180 |
+
groupTypes.textord = function(group, options, prev) {
|
| 181 |
+
return buildCommon.makeOrd(group, options, "textord");
|
| 182 |
+
};
|
| 183 |
+
|
| 184 |
+
groupTypes.bin = function(group, options, prev) {
|
| 185 |
+
var className = "mbin";
|
| 186 |
+
// Pull out the most recent element. Do some special handling to find
|
| 187 |
+
// things at the end of a \color group. Note that we don't use the same
|
| 188 |
+
// logic for ordgroups (which count as ords).
|
| 189 |
+
var prevAtom = prev;
|
| 190 |
+
while (prevAtom && prevAtom.type === "color") {
|
| 191 |
+
var atoms = prevAtom.value.value;
|
| 192 |
+
prevAtom = atoms[atoms.length - 1];
|
| 193 |
+
}
|
| 194 |
+
// See TeXbook pg. 442-446, Rules 5 and 6, and the text before Rule 19.
|
| 195 |
+
// Here, we determine whether the bin should turn into an ord. We
|
| 196 |
+
// currently only apply Rule 5.
|
| 197 |
+
if (!prev || utils.contains(["mbin", "mopen", "mrel", "mop", "mpunct"],
|
| 198 |
+
getTypeOfGroup(prevAtom))) {
|
| 199 |
+
group.type = "textord";
|
| 200 |
+
className = "mord";
|
| 201 |
+
}
|
| 202 |
+
|
| 203 |
+
return buildCommon.mathsym(
|
| 204 |
+
group.value, group.mode, options.getColor(), [className]);
|
| 205 |
+
};
|
| 206 |
+
|
| 207 |
+
groupTypes.rel = function(group, options, prev) {
|
| 208 |
+
return buildCommon.mathsym(
|
| 209 |
+
group.value, group.mode, options.getColor(), ["mrel"]);
|
| 210 |
+
};
|
| 211 |
+
|
| 212 |
+
groupTypes.open = function(group, options, prev) {
|
| 213 |
+
return buildCommon.mathsym(
|
| 214 |
+
group.value, group.mode, options.getColor(), ["mopen"]);
|
| 215 |
+
};
|
| 216 |
+
|
| 217 |
+
groupTypes.close = function(group, options, prev) {
|
| 218 |
+
return buildCommon.mathsym(
|
| 219 |
+
group.value, group.mode, options.getColor(), ["mclose"]);
|
| 220 |
+
};
|
| 221 |
+
|
| 222 |
+
groupTypes.inner = function(group, options, prev) {
|
| 223 |
+
return buildCommon.mathsym(
|
| 224 |
+
group.value, group.mode, options.getColor(), ["minner"]);
|
| 225 |
+
};
|
| 226 |
+
|
| 227 |
+
groupTypes.punct = function(group, options, prev) {
|
| 228 |
+
return buildCommon.mathsym(
|
| 229 |
+
group.value, group.mode, options.getColor(), ["mpunct"]);
|
| 230 |
+
};
|
| 231 |
+
|
| 232 |
+
groupTypes.ordgroup = function(group, options, prev) {
|
| 233 |
+
return makeSpan(
|
| 234 |
+
["mord", options.style.cls()],
|
| 235 |
+
buildExpression(group.value, options.reset())
|
| 236 |
+
);
|
| 237 |
+
};
|
| 238 |
+
|
| 239 |
+
groupTypes.text = function(group, options, prev) {
|
| 240 |
+
return makeSpan(["text", "mord", options.style.cls()],
|
| 241 |
+
buildExpression(group.value.body, options.reset()));
|
| 242 |
+
};
|
| 243 |
+
|
| 244 |
+
groupTypes.color = function(group, options, prev) {
|
| 245 |
+
var elements = buildExpression(
|
| 246 |
+
group.value.value,
|
| 247 |
+
options.withColor(group.value.color),
|
| 248 |
+
prev
|
| 249 |
+
);
|
| 250 |
+
|
| 251 |
+
// \color isn't supposed to affect the type of the elements it contains.
|
| 252 |
+
// To accomplish this, we wrap the results in a fragment, so the inner
|
| 253 |
+
// elements will be able to directly interact with their neighbors. For
|
| 254 |
+
// example, `\color{red}{2 +} 3` has the same spacing as `2 + 3`
|
| 255 |
+
return new buildCommon.makeFragment(elements);
|
| 256 |
+
};
|
| 257 |
+
|
| 258 |
+
groupTypes.supsub = function(group, options, prev) {
|
| 259 |
+
// Superscript and subscripts are handled in the TeXbook on page
|
| 260 |
+
// 445-446, rules 18(a-f).
|
| 261 |
+
|
| 262 |
+
// Here is where we defer to the inner group if it should handle
|
| 263 |
+
// superscripts and subscripts itself.
|
| 264 |
+
if (shouldHandleSupSub(group.value.base, options)) {
|
| 265 |
+
return groupTypes[group.value.base.type](group, options, prev);
|
| 266 |
+
}
|
| 267 |
+
|
| 268 |
+
var base = buildGroup(group.value.base, options.reset());
|
| 269 |
+
var supmid;
|
| 270 |
+
var submid;
|
| 271 |
+
var sup;
|
| 272 |
+
var sub;
|
| 273 |
+
|
| 274 |
+
if (group.value.sup) {
|
| 275 |
+
sup = buildGroup(group.value.sup,
|
| 276 |
+
options.withStyle(options.style.sup()));
|
| 277 |
+
supmid = makeSpan(
|
| 278 |
+
[options.style.reset(), options.style.sup().cls()], [sup]);
|
| 279 |
+
}
|
| 280 |
+
|
| 281 |
+
if (group.value.sub) {
|
| 282 |
+
sub = buildGroup(group.value.sub,
|
| 283 |
+
options.withStyle(options.style.sub()));
|
| 284 |
+
submid = makeSpan(
|
| 285 |
+
[options.style.reset(), options.style.sub().cls()], [sub]);
|
| 286 |
+
}
|
| 287 |
+
|
| 288 |
+
// Rule 18a
|
| 289 |
+
var supShift;
|
| 290 |
+
var subShift;
|
| 291 |
+
if (isCharacterBox(group.value.base)) {
|
| 292 |
+
supShift = 0;
|
| 293 |
+
subShift = 0;
|
| 294 |
+
} else {
|
| 295 |
+
supShift = base.height - fontMetrics.metrics.supDrop;
|
| 296 |
+
subShift = base.depth + fontMetrics.metrics.subDrop;
|
| 297 |
+
}
|
| 298 |
+
|
| 299 |
+
// Rule 18c
|
| 300 |
+
var minSupShift;
|
| 301 |
+
if (options.style === Style.DISPLAY) {
|
| 302 |
+
minSupShift = fontMetrics.metrics.sup1;
|
| 303 |
+
} else if (options.style.cramped) {
|
| 304 |
+
minSupShift = fontMetrics.metrics.sup3;
|
| 305 |
+
} else {
|
| 306 |
+
minSupShift = fontMetrics.metrics.sup2;
|
| 307 |
+
}
|
| 308 |
+
|
| 309 |
+
// scriptspace is a font-size-independent size, so scale it
|
| 310 |
+
// appropriately
|
| 311 |
+
var multiplier = Style.TEXT.sizeMultiplier *
|
| 312 |
+
options.style.sizeMultiplier;
|
| 313 |
+
var scriptspace =
|
| 314 |
+
(0.5 / fontMetrics.metrics.ptPerEm) / multiplier + "em";
|
| 315 |
+
|
| 316 |
+
var supsub;
|
| 317 |
+
if (!group.value.sup) {
|
| 318 |
+
// Rule 18b
|
| 319 |
+
subShift = Math.max(
|
| 320 |
+
subShift, fontMetrics.metrics.sub1,
|
| 321 |
+
sub.height - 0.8 * fontMetrics.metrics.xHeight);
|
| 322 |
+
|
| 323 |
+
supsub = buildCommon.makeVList([
|
| 324 |
+
{type: "elem", elem: submid},
|
| 325 |
+
], "shift", subShift, options);
|
| 326 |
+
|
| 327 |
+
supsub.children[0].style.marginRight = scriptspace;
|
| 328 |
+
|
| 329 |
+
// Subscripts shouldn't be shifted by the base's italic correction.
|
| 330 |
+
// Account for that by shifting the subscript back the appropriate
|
| 331 |
+
// amount. Note we only do this when the base is a single symbol.
|
| 332 |
+
if (base instanceof domTree.symbolNode) {
|
| 333 |
+
supsub.children[0].style.marginLeft = -base.italic + "em";
|
| 334 |
+
}
|
| 335 |
+
} else if (!group.value.sub) {
|
| 336 |
+
// Rule 18c, d
|
| 337 |
+
supShift = Math.max(supShift, minSupShift,
|
| 338 |
+
sup.depth + 0.25 * fontMetrics.metrics.xHeight);
|
| 339 |
+
|
| 340 |
+
supsub = buildCommon.makeVList([
|
| 341 |
+
{type: "elem", elem: supmid},
|
| 342 |
+
], "shift", -supShift, options);
|
| 343 |
+
|
| 344 |
+
supsub.children[0].style.marginRight = scriptspace;
|
| 345 |
+
} else {
|
| 346 |
+
supShift = Math.max(
|
| 347 |
+
supShift, minSupShift,
|
| 348 |
+
sup.depth + 0.25 * fontMetrics.metrics.xHeight);
|
| 349 |
+
subShift = Math.max(subShift, fontMetrics.metrics.sub2);
|
| 350 |
+
|
| 351 |
+
var ruleWidth = fontMetrics.metrics.defaultRuleThickness;
|
| 352 |
+
|
| 353 |
+
// Rule 18e
|
| 354 |
+
if ((supShift - sup.depth) - (sub.height - subShift) <
|
| 355 |
+
4 * ruleWidth) {
|
| 356 |
+
subShift = 4 * ruleWidth - (supShift - sup.depth) + sub.height;
|
| 357 |
+
var psi = 0.8 * fontMetrics.metrics.xHeight -
|
| 358 |
+
(supShift - sup.depth);
|
| 359 |
+
if (psi > 0) {
|
| 360 |
+
supShift += psi;
|
| 361 |
+
subShift -= psi;
|
| 362 |
+
}
|
| 363 |
+
}
|
| 364 |
+
|
| 365 |
+
supsub = buildCommon.makeVList([
|
| 366 |
+
{type: "elem", elem: submid, shift: subShift},
|
| 367 |
+
{type: "elem", elem: supmid, shift: -supShift},
|
| 368 |
+
], "individualShift", null, options);
|
| 369 |
+
|
| 370 |
+
// See comment above about subscripts not being shifted
|
| 371 |
+
if (base instanceof domTree.symbolNode) {
|
| 372 |
+
supsub.children[0].style.marginLeft = -base.italic + "em";
|
| 373 |
+
}
|
| 374 |
+
|
| 375 |
+
supsub.children[0].style.marginRight = scriptspace;
|
| 376 |
+
supsub.children[1].style.marginRight = scriptspace;
|
| 377 |
+
}
|
| 378 |
+
|
| 379 |
+
return makeSpan([getTypeOfGroup(group.value.base)],
|
| 380 |
+
[base, supsub]);
|
| 381 |
+
};
|
| 382 |
+
|
| 383 |
+
groupTypes.genfrac = function(group, options, prev) {
|
| 384 |
+
// Fractions are handled in the TeXbook on pages 444-445, rules 15(a-e).
|
| 385 |
+
// Figure out what style this fraction should be in based on the
|
| 386 |
+
// function used
|
| 387 |
+
var fstyle = options.style;
|
| 388 |
+
if (group.value.size === "display") {
|
| 389 |
+
fstyle = Style.DISPLAY;
|
| 390 |
+
} else if (group.value.size === "text") {
|
| 391 |
+
fstyle = Style.TEXT;
|
| 392 |
+
}
|
| 393 |
+
|
| 394 |
+
var nstyle = fstyle.fracNum();
|
| 395 |
+
var dstyle = fstyle.fracDen();
|
| 396 |
+
|
| 397 |
+
var numer = buildGroup(group.value.numer, options.withStyle(nstyle));
|
| 398 |
+
var numerreset = makeSpan([fstyle.reset(), nstyle.cls()], [numer]);
|
| 399 |
+
|
| 400 |
+
var denom = buildGroup(group.value.denom, options.withStyle(dstyle));
|
| 401 |
+
var denomreset = makeSpan([fstyle.reset(), dstyle.cls()], [denom]);
|
| 402 |
+
|
| 403 |
+
var ruleWidth;
|
| 404 |
+
if (group.value.hasBarLine) {
|
| 405 |
+
ruleWidth = fontMetrics.metrics.defaultRuleThickness /
|
| 406 |
+
options.style.sizeMultiplier;
|
| 407 |
+
} else {
|
| 408 |
+
ruleWidth = 0;
|
| 409 |
+
}
|
| 410 |
+
|
| 411 |
+
// Rule 15b
|
| 412 |
+
var numShift;
|
| 413 |
+
var clearance;
|
| 414 |
+
var denomShift;
|
| 415 |
+
if (fstyle.size === Style.DISPLAY.size) {
|
| 416 |
+
numShift = fontMetrics.metrics.num1;
|
| 417 |
+
if (ruleWidth > 0) {
|
| 418 |
+
clearance = 3 * ruleWidth;
|
| 419 |
+
} else {
|
| 420 |
+
clearance = 7 * fontMetrics.metrics.defaultRuleThickness;
|
| 421 |
+
}
|
| 422 |
+
denomShift = fontMetrics.metrics.denom1;
|
| 423 |
+
} else {
|
| 424 |
+
if (ruleWidth > 0) {
|
| 425 |
+
numShift = fontMetrics.metrics.num2;
|
| 426 |
+
clearance = ruleWidth;
|
| 427 |
+
} else {
|
| 428 |
+
numShift = fontMetrics.metrics.num3;
|
| 429 |
+
clearance = 3 * fontMetrics.metrics.defaultRuleThickness;
|
| 430 |
+
}
|
| 431 |
+
denomShift = fontMetrics.metrics.denom2;
|
| 432 |
+
}
|
| 433 |
+
|
| 434 |
+
var frac;
|
| 435 |
+
if (ruleWidth === 0) {
|
| 436 |
+
// Rule 15c
|
| 437 |
+
var candiateClearance =
|
| 438 |
+
(numShift - numer.depth) - (denom.height - denomShift);
|
| 439 |
+
if (candiateClearance < clearance) {
|
| 440 |
+
numShift += 0.5 * (clearance - candiateClearance);
|
| 441 |
+
denomShift += 0.5 * (clearance - candiateClearance);
|
| 442 |
+
}
|
| 443 |
+
|
| 444 |
+
frac = buildCommon.makeVList([
|
| 445 |
+
{type: "elem", elem: denomreset, shift: denomShift},
|
| 446 |
+
{type: "elem", elem: numerreset, shift: -numShift},
|
| 447 |
+
], "individualShift", null, options);
|
| 448 |
+
} else {
|
| 449 |
+
// Rule 15d
|
| 450 |
+
var axisHeight = fontMetrics.metrics.axisHeight;
|
| 451 |
+
|
| 452 |
+
if ((numShift - numer.depth) - (axisHeight + 0.5 * ruleWidth) <
|
| 453 |
+
clearance) {
|
| 454 |
+
numShift +=
|
| 455 |
+
clearance - ((numShift - numer.depth) -
|
| 456 |
+
(axisHeight + 0.5 * ruleWidth));
|
| 457 |
+
}
|
| 458 |
+
|
| 459 |
+
if ((axisHeight - 0.5 * ruleWidth) - (denom.height - denomShift) <
|
| 460 |
+
clearance) {
|
| 461 |
+
denomShift +=
|
| 462 |
+
clearance - ((axisHeight - 0.5 * ruleWidth) -
|
| 463 |
+
(denom.height - denomShift));
|
| 464 |
+
}
|
| 465 |
+
|
| 466 |
+
var mid = makeSpan(
|
| 467 |
+
[options.style.reset(), Style.TEXT.cls(), "frac-line"]);
|
| 468 |
+
// Manually set the height of the line because its height is
|
| 469 |
+
// created in CSS
|
| 470 |
+
mid.height = ruleWidth;
|
| 471 |
+
|
| 472 |
+
var midShift = -(axisHeight - 0.5 * ruleWidth);
|
| 473 |
+
|
| 474 |
+
frac = buildCommon.makeVList([
|
| 475 |
+
{type: "elem", elem: denomreset, shift: denomShift},
|
| 476 |
+
{type: "elem", elem: mid, shift: midShift},
|
| 477 |
+
{type: "elem", elem: numerreset, shift: -numShift},
|
| 478 |
+
], "individualShift", null, options);
|
| 479 |
+
}
|
| 480 |
+
|
| 481 |
+
// Since we manually change the style sometimes (with \dfrac or \tfrac),
|
| 482 |
+
// account for the possible size change here.
|
| 483 |
+
frac.height *= fstyle.sizeMultiplier / options.style.sizeMultiplier;
|
| 484 |
+
frac.depth *= fstyle.sizeMultiplier / options.style.sizeMultiplier;
|
| 485 |
+
|
| 486 |
+
// Rule 15e
|
| 487 |
+
var delimSize;
|
| 488 |
+
if (fstyle.size === Style.DISPLAY.size) {
|
| 489 |
+
delimSize = fontMetrics.metrics.delim1;
|
| 490 |
+
} else {
|
| 491 |
+
delimSize = fontMetrics.metrics.getDelim2(fstyle);
|
| 492 |
+
}
|
| 493 |
+
|
| 494 |
+
var leftDelim;
|
| 495 |
+
var rightDelim;
|
| 496 |
+
if (group.value.leftDelim == null) {
|
| 497 |
+
leftDelim = makeNullDelimiter(options);
|
| 498 |
+
} else {
|
| 499 |
+
leftDelim = delimiter.customSizedDelim(
|
| 500 |
+
group.value.leftDelim, delimSize, true,
|
| 501 |
+
options.withStyle(fstyle), group.mode);
|
| 502 |
+
}
|
| 503 |
+
if (group.value.rightDelim == null) {
|
| 504 |
+
rightDelim = makeNullDelimiter(options);
|
| 505 |
+
} else {
|
| 506 |
+
rightDelim = delimiter.customSizedDelim(
|
| 507 |
+
group.value.rightDelim, delimSize, true,
|
| 508 |
+
options.withStyle(fstyle), group.mode);
|
| 509 |
+
}
|
| 510 |
+
|
| 511 |
+
return makeSpan(
|
| 512 |
+
["mord", options.style.reset(), fstyle.cls()],
|
| 513 |
+
[leftDelim, makeSpan(["mfrac"], [frac]), rightDelim],
|
| 514 |
+
options.getColor());
|
| 515 |
+
};
|
| 516 |
+
|
| 517 |
+
groupTypes.array = function(group, options, prev) {
|
| 518 |
+
var r;
|
| 519 |
+
var c;
|
| 520 |
+
var nr = group.value.body.length;
|
| 521 |
+
var nc = 0;
|
| 522 |
+
var body = new Array(nr);
|
| 523 |
+
|
| 524 |
+
// Horizontal spacing
|
| 525 |
+
var pt = 1 / fontMetrics.metrics.ptPerEm;
|
| 526 |
+
var arraycolsep = 5 * pt; // \arraycolsep in article.cls
|
| 527 |
+
|
| 528 |
+
// Vertical spacing
|
| 529 |
+
var baselineskip = 12 * pt; // see size10.clo
|
| 530 |
+
// Default \arraystretch from lttab.dtx
|
| 531 |
+
// TODO(gagern): may get redefined once we have user-defined macros
|
| 532 |
+
var arraystretch = utils.deflt(group.value.arraystretch, 1);
|
| 533 |
+
var arrayskip = arraystretch * baselineskip;
|
| 534 |
+
var arstrutHeight = 0.7 * arrayskip; // \strutbox in ltfsstrc.dtx and
|
| 535 |
+
var arstrutDepth = 0.3 * arrayskip; // \@arstrutbox in lttab.dtx
|
| 536 |
+
|
| 537 |
+
var totalHeight = 0;
|
| 538 |
+
for (r = 0; r < group.value.body.length; ++r) {
|
| 539 |
+
var inrow = group.value.body[r];
|
| 540 |
+
var height = arstrutHeight; // \@array adds an \@arstrut
|
| 541 |
+
var depth = arstrutDepth; // to each tow (via the template)
|
| 542 |
+
|
| 543 |
+
if (nc < inrow.length) {
|
| 544 |
+
nc = inrow.length;
|
| 545 |
+
}
|
| 546 |
+
|
| 547 |
+
var outrow = new Array(inrow.length);
|
| 548 |
+
for (c = 0; c < inrow.length; ++c) {
|
| 549 |
+
var elt = buildGroup(inrow[c], options);
|
| 550 |
+
if (depth < elt.depth) {
|
| 551 |
+
depth = elt.depth;
|
| 552 |
+
}
|
| 553 |
+
if (height < elt.height) {
|
| 554 |
+
height = elt.height;
|
| 555 |
+
}
|
| 556 |
+
outrow[c] = elt;
|
| 557 |
+
}
|
| 558 |
+
|
| 559 |
+
var gap = 0;
|
| 560 |
+
if (group.value.rowGaps[r]) {
|
| 561 |
+
gap = group.value.rowGaps[r].value;
|
| 562 |
+
switch (gap.unit) {
|
| 563 |
+
case "em":
|
| 564 |
+
gap = gap.number;
|
| 565 |
+
break;
|
| 566 |
+
case "ex":
|
| 567 |
+
gap = gap.number * fontMetrics.metrics.emPerEx;
|
| 568 |
+
break;
|
| 569 |
+
default:
|
| 570 |
+
console.error("Can't handle unit " + gap.unit);
|
| 571 |
+
gap = 0;
|
| 572 |
+
}
|
| 573 |
+
if (gap > 0) { // \@argarraycr
|
| 574 |
+
gap += arstrutDepth;
|
| 575 |
+
if (depth < gap) {
|
| 576 |
+
depth = gap; // \@xargarraycr
|
| 577 |
+
}
|
| 578 |
+
gap = 0;
|
| 579 |
+
}
|
| 580 |
+
}
|
| 581 |
+
|
| 582 |
+
outrow.height = height;
|
| 583 |
+
outrow.depth = depth;
|
| 584 |
+
totalHeight += height;
|
| 585 |
+
outrow.pos = totalHeight;
|
| 586 |
+
totalHeight += depth + gap; // \@yargarraycr
|
| 587 |
+
body[r] = outrow;
|
| 588 |
+
}
|
| 589 |
+
|
| 590 |
+
var offset = totalHeight / 2 + fontMetrics.metrics.axisHeight;
|
| 591 |
+
var colDescriptions = group.value.cols || [];
|
| 592 |
+
var cols = [];
|
| 593 |
+
var colSep;
|
| 594 |
+
var colDescrNum;
|
| 595 |
+
for (c = 0, colDescrNum = 0;
|
| 596 |
+
// Continue while either there are more columns or more column
|
| 597 |
+
// descriptions, so trailing separators don't get lost.
|
| 598 |
+
c < nc || colDescrNum < colDescriptions.length;
|
| 599 |
+
++c, ++colDescrNum) {
|
| 600 |
+
|
| 601 |
+
var colDescr = colDescriptions[colDescrNum] || {};
|
| 602 |
+
|
| 603 |
+
var firstSeparator = true;
|
| 604 |
+
while (colDescr.type === "separator") {
|
| 605 |
+
// If there is more than one separator in a row, add a space
|
| 606 |
+
// between them.
|
| 607 |
+
if (!firstSeparator) {
|
| 608 |
+
colSep = makeSpan(["arraycolsep"], []);
|
| 609 |
+
colSep.style.width =
|
| 610 |
+
fontMetrics.metrics.doubleRuleSep + "em";
|
| 611 |
+
cols.push(colSep);
|
| 612 |
+
}
|
| 613 |
+
|
| 614 |
+
if (colDescr.separator === "|") {
|
| 615 |
+
var separator = makeSpan(
|
| 616 |
+
["vertical-separator"],
|
| 617 |
+
[]);
|
| 618 |
+
separator.style.height = totalHeight + "em";
|
| 619 |
+
separator.style.verticalAlign =
|
| 620 |
+
-(totalHeight - offset) + "em";
|
| 621 |
+
|
| 622 |
+
cols.push(separator);
|
| 623 |
+
} else {
|
| 624 |
+
throw new ParseError(
|
| 625 |
+
"Invalid separator type: " + colDescr.separator);
|
| 626 |
+
}
|
| 627 |
+
|
| 628 |
+
colDescrNum++;
|
| 629 |
+
colDescr = colDescriptions[colDescrNum] || {};
|
| 630 |
+
firstSeparator = false;
|
| 631 |
+
}
|
| 632 |
+
|
| 633 |
+
if (c >= nc) {
|
| 634 |
+
continue;
|
| 635 |
+
}
|
| 636 |
+
|
| 637 |
+
var sepwidth;
|
| 638 |
+
if (c > 0 || group.value.hskipBeforeAndAfter) {
|
| 639 |
+
sepwidth = utils.deflt(colDescr.pregap, arraycolsep);
|
| 640 |
+
if (sepwidth !== 0) {
|
| 641 |
+
colSep = makeSpan(["arraycolsep"], []);
|
| 642 |
+
colSep.style.width = sepwidth + "em";
|
| 643 |
+
cols.push(colSep);
|
| 644 |
+
}
|
| 645 |
+
}
|
| 646 |
+
|
| 647 |
+
var col = [];
|
| 648 |
+
for (r = 0; r < nr; ++r) {
|
| 649 |
+
var row = body[r];
|
| 650 |
+
var elem = row[c];
|
| 651 |
+
if (!elem) {
|
| 652 |
+
continue;
|
| 653 |
+
}
|
| 654 |
+
var shift = row.pos - offset;
|
| 655 |
+
elem.depth = row.depth;
|
| 656 |
+
elem.height = row.height;
|
| 657 |
+
col.push({type: "elem", elem: elem, shift: shift});
|
| 658 |
+
}
|
| 659 |
+
|
| 660 |
+
col = buildCommon.makeVList(col, "individualShift", null, options);
|
| 661 |
+
col = makeSpan(
|
| 662 |
+
["col-align-" + (colDescr.align || "c")],
|
| 663 |
+
[col]);
|
| 664 |
+
cols.push(col);
|
| 665 |
+
|
| 666 |
+
if (c < nc - 1 || group.value.hskipBeforeAndAfter) {
|
| 667 |
+
sepwidth = utils.deflt(colDescr.postgap, arraycolsep);
|
| 668 |
+
if (sepwidth !== 0) {
|
| 669 |
+
colSep = makeSpan(["arraycolsep"], []);
|
| 670 |
+
colSep.style.width = sepwidth + "em";
|
| 671 |
+
cols.push(colSep);
|
| 672 |
+
}
|
| 673 |
+
}
|
| 674 |
+
}
|
| 675 |
+
body = makeSpan(["mtable"], cols);
|
| 676 |
+
return makeSpan(["mord"], [body], options.getColor());
|
| 677 |
+
};
|
| 678 |
+
|
| 679 |
+
groupTypes.spacing = function(group, options, prev) {
|
| 680 |
+
if (group.value === "\\ " || group.value === "\\space" ||
|
| 681 |
+
group.value === " " || group.value === "~") {
|
| 682 |
+
// Spaces are generated by adding an actual space. Each of these
|
| 683 |
+
// things has an entry in the symbols table, so these will be turned
|
| 684 |
+
// into appropriate outputs.
|
| 685 |
+
return makeSpan(
|
| 686 |
+
["mord", "mspace"],
|
| 687 |
+
[buildCommon.mathsym(group.value, group.mode)]
|
| 688 |
+
);
|
| 689 |
+
} else {
|
| 690 |
+
// Other kinds of spaces are of arbitrary width. We use CSS to
|
| 691 |
+
// generate these.
|
| 692 |
+
return makeSpan(
|
| 693 |
+
["mord", "mspace",
|
| 694 |
+
buildCommon.spacingFunctions[group.value].className]);
|
| 695 |
+
}
|
| 696 |
+
};
|
| 697 |
+
|
| 698 |
+
groupTypes.llap = function(group, options, prev) {
|
| 699 |
+
var inner = makeSpan(
|
| 700 |
+
["inner"], [buildGroup(group.value.body, options.reset())]);
|
| 701 |
+
var fix = makeSpan(["fix"], []);
|
| 702 |
+
return makeSpan(
|
| 703 |
+
["llap", options.style.cls()], [inner, fix]);
|
| 704 |
+
};
|
| 705 |
+
|
| 706 |
+
groupTypes.rlap = function(group, options, prev) {
|
| 707 |
+
var inner = makeSpan(
|
| 708 |
+
["inner"], [buildGroup(group.value.body, options.reset())]);
|
| 709 |
+
var fix = makeSpan(["fix"], []);
|
| 710 |
+
return makeSpan(
|
| 711 |
+
["rlap", options.style.cls()], [inner, fix]);
|
| 712 |
+
};
|
| 713 |
+
|
| 714 |
+
groupTypes.op = function(group, options, prev) {
|
| 715 |
+
// Operators are handled in the TeXbook pg. 443-444, rule 13(a).
|
| 716 |
+
var supGroup;
|
| 717 |
+
var subGroup;
|
| 718 |
+
var hasLimits = false;
|
| 719 |
+
if (group.type === "supsub" ) {
|
| 720 |
+
// If we have limits, supsub will pass us its group to handle. Pull
|
| 721 |
+
// out the superscript and subscript and set the group to the op in
|
| 722 |
+
// its base.
|
| 723 |
+
supGroup = group.value.sup;
|
| 724 |
+
subGroup = group.value.sub;
|
| 725 |
+
group = group.value.base;
|
| 726 |
+
hasLimits = true;
|
| 727 |
+
}
|
| 728 |
+
|
| 729 |
+
// Most operators have a large successor symbol, but these don't.
|
| 730 |
+
var noSuccessor = [
|
| 731 |
+
"\\smallint",
|
| 732 |
+
];
|
| 733 |
+
|
| 734 |
+
var large = false;
|
| 735 |
+
if (options.style.size === Style.DISPLAY.size &&
|
| 736 |
+
group.value.symbol &&
|
| 737 |
+
!utils.contains(noSuccessor, group.value.body)) {
|
| 738 |
+
|
| 739 |
+
// Most symbol operators get larger in displaystyle (rule 13)
|
| 740 |
+
large = true;
|
| 741 |
+
}
|
| 742 |
+
|
| 743 |
+
var base;
|
| 744 |
+
var baseShift = 0;
|
| 745 |
+
var slant = 0;
|
| 746 |
+
if (group.value.symbol) {
|
| 747 |
+
// If this is a symbol, create the symbol.
|
| 748 |
+
var style = large ? "Size2-Regular" : "Size1-Regular";
|
| 749 |
+
base = buildCommon.makeSymbol(
|
| 750 |
+
group.value.body, style, "math", options.getColor(),
|
| 751 |
+
["op-symbol", large ? "large-op" : "small-op", "mop"]);
|
| 752 |
+
|
| 753 |
+
// Shift the symbol so its center lies on the axis (rule 13). It
|
| 754 |
+
// appears that our fonts have the centers of the symbols already
|
| 755 |
+
// almost on the axis, so these numbers are very small. Note we
|
| 756 |
+
// don't actually apply this here, but instead it is used either in
|
| 757 |
+
// the vlist creation or separately when there are no limits.
|
| 758 |
+
baseShift = (base.height - base.depth) / 2 -
|
| 759 |
+
fontMetrics.metrics.axisHeight *
|
| 760 |
+
options.style.sizeMultiplier;
|
| 761 |
+
|
| 762 |
+
// The slant of the symbol is just its italic correction.
|
| 763 |
+
slant = base.italic;
|
| 764 |
+
} else {
|
| 765 |
+
// Otherwise, this is a text operator. Build the text from the
|
| 766 |
+
// operator's name.
|
| 767 |
+
// TODO(emily): Add a space in the middle of some of these
|
| 768 |
+
// operators, like \limsup
|
| 769 |
+
var output = [];
|
| 770 |
+
for (var i = 1; i < group.value.body.length; i++) {
|
| 771 |
+
output.push(buildCommon.mathsym(group.value.body[i], group.mode));
|
| 772 |
+
}
|
| 773 |
+
base = makeSpan(["mop"], output, options.getColor());
|
| 774 |
+
}
|
| 775 |
+
|
| 776 |
+
if (hasLimits) {
|
| 777 |
+
// IE 8 clips \int if it is in a display: inline-block. We wrap it
|
| 778 |
+
// in a new span so it is an inline, and works.
|
| 779 |
+
base = makeSpan([], [base]);
|
| 780 |
+
|
| 781 |
+
var supmid;
|
| 782 |
+
var supKern;
|
| 783 |
+
var submid;
|
| 784 |
+
var subKern;
|
| 785 |
+
// We manually have to handle the superscripts and subscripts. This,
|
| 786 |
+
// aside from the kern calculations, is copied from supsub.
|
| 787 |
+
if (supGroup) {
|
| 788 |
+
var sup = buildGroup(
|
| 789 |
+
supGroup, options.withStyle(options.style.sup()));
|
| 790 |
+
supmid = makeSpan(
|
| 791 |
+
[options.style.reset(), options.style.sup().cls()], [sup]);
|
| 792 |
+
|
| 793 |
+
supKern = Math.max(
|
| 794 |
+
fontMetrics.metrics.bigOpSpacing1,
|
| 795 |
+
fontMetrics.metrics.bigOpSpacing3 - sup.depth);
|
| 796 |
+
}
|
| 797 |
+
|
| 798 |
+
if (subGroup) {
|
| 799 |
+
var sub = buildGroup(
|
| 800 |
+
subGroup, options.withStyle(options.style.sub()));
|
| 801 |
+
submid = makeSpan(
|
| 802 |
+
[options.style.reset(), options.style.sub().cls()],
|
| 803 |
+
[sub]);
|
| 804 |
+
|
| 805 |
+
subKern = Math.max(
|
| 806 |
+
fontMetrics.metrics.bigOpSpacing2,
|
| 807 |
+
fontMetrics.metrics.bigOpSpacing4 - sub.height);
|
| 808 |
+
}
|
| 809 |
+
|
| 810 |
+
// Build the final group as a vlist of the possible subscript, base,
|
| 811 |
+
// and possible superscript.
|
| 812 |
+
var finalGroup;
|
| 813 |
+
var top;
|
| 814 |
+
var bottom;
|
| 815 |
+
if (!supGroup) {
|
| 816 |
+
top = base.height - baseShift;
|
| 817 |
+
|
| 818 |
+
finalGroup = buildCommon.makeVList([
|
| 819 |
+
{type: "kern", size: fontMetrics.metrics.bigOpSpacing5},
|
| 820 |
+
{type: "elem", elem: submid},
|
| 821 |
+
{type: "kern", size: subKern},
|
| 822 |
+
{type: "elem", elem: base},
|
| 823 |
+
], "top", top, options);
|
| 824 |
+
|
| 825 |
+
// Here, we shift the limits by the slant of the symbol. Note
|
| 826 |
+
// that we are supposed to shift the limits by 1/2 of the slant,
|
| 827 |
+
// but since we are centering the limits adding a full slant of
|
| 828 |
+
// margin will shift by 1/2 that.
|
| 829 |
+
finalGroup.children[0].style.marginLeft = -slant + "em";
|
| 830 |
+
} else if (!subGroup) {
|
| 831 |
+
bottom = base.depth + baseShift;
|
| 832 |
+
|
| 833 |
+
finalGroup = buildCommon.makeVList([
|
| 834 |
+
{type: "elem", elem: base},
|
| 835 |
+
{type: "kern", size: supKern},
|
| 836 |
+
{type: "elem", elem: supmid},
|
| 837 |
+
{type: "kern", size: fontMetrics.metrics.bigOpSpacing5},
|
| 838 |
+
], "bottom", bottom, options);
|
| 839 |
+
|
| 840 |
+
// See comment above about slants
|
| 841 |
+
finalGroup.children[1].style.marginLeft = slant + "em";
|
| 842 |
+
} else if (!supGroup && !subGroup) {
|
| 843 |
+
// This case probably shouldn't occur (this would mean the
|
| 844 |
+
// supsub was sending us a group with no superscript or
|
| 845 |
+
// subscript) but be safe.
|
| 846 |
+
return base;
|
| 847 |
+
} else {
|
| 848 |
+
bottom = fontMetrics.metrics.bigOpSpacing5 +
|
| 849 |
+
submid.height + submid.depth +
|
| 850 |
+
subKern +
|
| 851 |
+
base.depth + baseShift;
|
| 852 |
+
|
| 853 |
+
finalGroup = buildCommon.makeVList([
|
| 854 |
+
{type: "kern", size: fontMetrics.metrics.bigOpSpacing5},
|
| 855 |
+
{type: "elem", elem: submid},
|
| 856 |
+
{type: "kern", size: subKern},
|
| 857 |
+
{type: "elem", elem: base},
|
| 858 |
+
{type: "kern", size: supKern},
|
| 859 |
+
{type: "elem", elem: supmid},
|
| 860 |
+
{type: "kern", size: fontMetrics.metrics.bigOpSpacing5},
|
| 861 |
+
], "bottom", bottom, options);
|
| 862 |
+
|
| 863 |
+
// See comment above about slants
|
| 864 |
+
finalGroup.children[0].style.marginLeft = -slant + "em";
|
| 865 |
+
finalGroup.children[2].style.marginLeft = slant + "em";
|
| 866 |
+
}
|
| 867 |
+
|
| 868 |
+
return makeSpan(["mop", "op-limits"], [finalGroup]);
|
| 869 |
+
} else {
|
| 870 |
+
if (group.value.symbol) {
|
| 871 |
+
base.style.top = baseShift + "em";
|
| 872 |
+
}
|
| 873 |
+
|
| 874 |
+
return base;
|
| 875 |
+
}
|
| 876 |
+
};
|
| 877 |
+
|
| 878 |
+
groupTypes.katex = function(group, options, prev) {
|
| 879 |
+
// The KaTeX logo. The offsets for the K and a were chosen to look
|
| 880 |
+
// good, but the offsets for the T, E, and X were taken from the
|
| 881 |
+
// definition of \TeX in TeX (see TeXbook pg. 356)
|
| 882 |
+
var k = makeSpan(
|
| 883 |
+
["k"], [buildCommon.mathsym("K", group.mode)]);
|
| 884 |
+
var a = makeSpan(
|
| 885 |
+
["a"], [buildCommon.mathsym("A", group.mode)]);
|
| 886 |
+
|
| 887 |
+
a.height = (a.height + 0.2) * 0.75;
|
| 888 |
+
a.depth = (a.height - 0.2) * 0.75;
|
| 889 |
+
|
| 890 |
+
var t = makeSpan(
|
| 891 |
+
["t"], [buildCommon.mathsym("T", group.mode)]);
|
| 892 |
+
var e = makeSpan(
|
| 893 |
+
["e"], [buildCommon.mathsym("E", group.mode)]);
|
| 894 |
+
|
| 895 |
+
e.height = (e.height - 0.2155);
|
| 896 |
+
e.depth = (e.depth + 0.2155);
|
| 897 |
+
|
| 898 |
+
var x = makeSpan(
|
| 899 |
+
["x"], [buildCommon.mathsym("X", group.mode)]);
|
| 900 |
+
|
| 901 |
+
return makeSpan(
|
| 902 |
+
["katex-logo", "mord"], [k, a, t, e, x], options.getColor());
|
| 903 |
+
};
|
| 904 |
+
|
| 905 |
+
groupTypes.overline = function(group, options, prev) {
|
| 906 |
+
// Overlines are handled in the TeXbook pg 443, Rule 9.
|
| 907 |
+
|
| 908 |
+
// Build the inner group in the cramped style.
|
| 909 |
+
var innerGroup = buildGroup(group.value.body,
|
| 910 |
+
options.withStyle(options.style.cramp()));
|
| 911 |
+
|
| 912 |
+
var ruleWidth = fontMetrics.metrics.defaultRuleThickness /
|
| 913 |
+
options.style.sizeMultiplier;
|
| 914 |
+
|
| 915 |
+
// Create the line above the body
|
| 916 |
+
var line = makeSpan(
|
| 917 |
+
[options.style.reset(), Style.TEXT.cls(), "overline-line"]);
|
| 918 |
+
line.height = ruleWidth;
|
| 919 |
+
line.maxFontSize = 1.0;
|
| 920 |
+
|
| 921 |
+
// Generate the vlist, with the appropriate kerns
|
| 922 |
+
var vlist = buildCommon.makeVList([
|
| 923 |
+
{type: "elem", elem: innerGroup},
|
| 924 |
+
{type: "kern", size: 3 * ruleWidth},
|
| 925 |
+
{type: "elem", elem: line},
|
| 926 |
+
{type: "kern", size: ruleWidth},
|
| 927 |
+
], "firstBaseline", null, options);
|
| 928 |
+
|
| 929 |
+
return makeSpan(["overline", "mord"], [vlist], options.getColor());
|
| 930 |
+
};
|
| 931 |
+
|
| 932 |
+
groupTypes.underline = function(group, options, prev) {
|
| 933 |
+
// Underlines are handled in the TeXbook pg 443, Rule 10.
|
| 934 |
+
|
| 935 |
+
// Build the inner group.
|
| 936 |
+
var innerGroup = buildGroup(group.value.body, options);
|
| 937 |
+
|
| 938 |
+
var ruleWidth = fontMetrics.metrics.defaultRuleThickness /
|
| 939 |
+
options.style.sizeMultiplier;
|
| 940 |
+
|
| 941 |
+
// Create the line above the body
|
| 942 |
+
var line = makeSpan(
|
| 943 |
+
[options.style.reset(), Style.TEXT.cls(), "underline-line"]);
|
| 944 |
+
line.height = ruleWidth;
|
| 945 |
+
line.maxFontSize = 1.0;
|
| 946 |
+
|
| 947 |
+
// Generate the vlist, with the appropriate kerns
|
| 948 |
+
var vlist = buildCommon.makeVList([
|
| 949 |
+
{type: "kern", size: ruleWidth},
|
| 950 |
+
{type: "elem", elem: line},
|
| 951 |
+
{type: "kern", size: 3 * ruleWidth},
|
| 952 |
+
{type: "elem", elem: innerGroup},
|
| 953 |
+
], "top", innerGroup.height, options);
|
| 954 |
+
|
| 955 |
+
return makeSpan(["underline", "mord"], [vlist], options.getColor());
|
| 956 |
+
};
|
| 957 |
+
|
| 958 |
+
groupTypes.sqrt = function(group, options, prev) {
|
| 959 |
+
// Square roots are handled in the TeXbook pg. 443, Rule 11.
|
| 960 |
+
|
| 961 |
+
// First, we do the same steps as in overline to build the inner group
|
| 962 |
+
// and line
|
| 963 |
+
var inner = buildGroup(group.value.body,
|
| 964 |
+
options.withStyle(options.style.cramp()));
|
| 965 |
+
|
| 966 |
+
var ruleWidth = fontMetrics.metrics.defaultRuleThickness /
|
| 967 |
+
options.style.sizeMultiplier;
|
| 968 |
+
|
| 969 |
+
var line = makeSpan(
|
| 970 |
+
[options.style.reset(), Style.TEXT.cls(), "sqrt-line"], [],
|
| 971 |
+
options.getColor());
|
| 972 |
+
line.height = ruleWidth;
|
| 973 |
+
line.maxFontSize = 1.0;
|
| 974 |
+
|
| 975 |
+
var phi = ruleWidth;
|
| 976 |
+
if (options.style.id < Style.TEXT.id) {
|
| 977 |
+
phi = fontMetrics.metrics.xHeight;
|
| 978 |
+
}
|
| 979 |
+
|
| 980 |
+
// Calculate the clearance between the body and line
|
| 981 |
+
var lineClearance = ruleWidth + phi / 4;
|
| 982 |
+
|
| 983 |
+
var innerHeight =
|
| 984 |
+
(inner.height + inner.depth) * options.style.sizeMultiplier;
|
| 985 |
+
var minDelimiterHeight = innerHeight + lineClearance + ruleWidth;
|
| 986 |
+
|
| 987 |
+
// Create a \surd delimiter of the required minimum size
|
| 988 |
+
var delim = makeSpan(["sqrt-sign"], [
|
| 989 |
+
delimiter.customSizedDelim("\\surd", minDelimiterHeight,
|
| 990 |
+
false, options, group.mode)],
|
| 991 |
+
options.getColor());
|
| 992 |
+
|
| 993 |
+
var delimDepth = (delim.height + delim.depth) - ruleWidth;
|
| 994 |
+
|
| 995 |
+
// Adjust the clearance based on the delimiter size
|
| 996 |
+
if (delimDepth > inner.height + inner.depth + lineClearance) {
|
| 997 |
+
lineClearance =
|
| 998 |
+
(lineClearance + delimDepth - inner.height - inner.depth) / 2;
|
| 999 |
+
}
|
| 1000 |
+
|
| 1001 |
+
// Shift the delimiter so that its top lines up with the top of the line
|
| 1002 |
+
var delimShift = -(inner.height + lineClearance + ruleWidth) + delim.height;
|
| 1003 |
+
delim.style.top = delimShift + "em";
|
| 1004 |
+
delim.height -= delimShift;
|
| 1005 |
+
delim.depth += delimShift;
|
| 1006 |
+
|
| 1007 |
+
// We add a special case here, because even when `inner` is empty, we
|
| 1008 |
+
// still get a line. So, we use a simple heuristic to decide if we
|
| 1009 |
+
// should omit the body entirely. (note this doesn't work for something
|
| 1010 |
+
// like `\sqrt{\rlap{x}}`, but if someone is doing that they deserve for
|
| 1011 |
+
// it not to work.
|
| 1012 |
+
var body;
|
| 1013 |
+
if (inner.height === 0 && inner.depth === 0) {
|
| 1014 |
+
body = makeSpan();
|
| 1015 |
+
} else {
|
| 1016 |
+
body = buildCommon.makeVList([
|
| 1017 |
+
{type: "elem", elem: inner},
|
| 1018 |
+
{type: "kern", size: lineClearance},
|
| 1019 |
+
{type: "elem", elem: line},
|
| 1020 |
+
{type: "kern", size: ruleWidth},
|
| 1021 |
+
], "firstBaseline", null, options);
|
| 1022 |
+
}
|
| 1023 |
+
|
| 1024 |
+
if (!group.value.index) {
|
| 1025 |
+
return makeSpan(["sqrt", "mord"], [delim, body]);
|
| 1026 |
+
} else {
|
| 1027 |
+
// Handle the optional root index
|
| 1028 |
+
|
| 1029 |
+
// The index is always in scriptscript style
|
| 1030 |
+
var root = buildGroup(
|
| 1031 |
+
group.value.index,
|
| 1032 |
+
options.withStyle(Style.SCRIPTSCRIPT));
|
| 1033 |
+
var rootWrap = makeSpan(
|
| 1034 |
+
[options.style.reset(), Style.SCRIPTSCRIPT.cls()],
|
| 1035 |
+
[root]);
|
| 1036 |
+
|
| 1037 |
+
// Figure out the height and depth of the inner part
|
| 1038 |
+
var innerRootHeight = Math.max(delim.height, body.height);
|
| 1039 |
+
var innerRootDepth = Math.max(delim.depth, body.depth);
|
| 1040 |
+
|
| 1041 |
+
// The amount the index is shifted by. This is taken from the TeX
|
| 1042 |
+
// source, in the definition of `\r@@t`.
|
| 1043 |
+
var toShift = 0.6 * (innerRootHeight - innerRootDepth);
|
| 1044 |
+
|
| 1045 |
+
// Build a VList with the superscript shifted up correctly
|
| 1046 |
+
var rootVList = buildCommon.makeVList(
|
| 1047 |
+
[{type: "elem", elem: rootWrap}],
|
| 1048 |
+
"shift", -toShift, options);
|
| 1049 |
+
// Add a class surrounding it so we can add on the appropriate
|
| 1050 |
+
// kerning
|
| 1051 |
+
var rootVListWrap = makeSpan(["root"], [rootVList]);
|
| 1052 |
+
|
| 1053 |
+
return makeSpan(["sqrt", "mord"], [rootVListWrap, delim, body]);
|
| 1054 |
+
}
|
| 1055 |
+
};
|
| 1056 |
+
|
| 1057 |
+
groupTypes.sizing = function(group, options, prev) {
|
| 1058 |
+
// Handle sizing operators like \Huge. Real TeX doesn't actually allow
|
| 1059 |
+
// these functions inside of math expressions, so we do some special
|
| 1060 |
+
// handling.
|
| 1061 |
+
var inner = buildExpression(group.value.value,
|
| 1062 |
+
options.withSize(group.value.size), prev);
|
| 1063 |
+
|
| 1064 |
+
var span = makeSpan(["mord"],
|
| 1065 |
+
[makeSpan(["sizing", "reset-" + options.size, group.value.size,
|
| 1066 |
+
options.style.cls()],
|
| 1067 |
+
inner)]);
|
| 1068 |
+
|
| 1069 |
+
// Calculate the correct maxFontSize manually
|
| 1070 |
+
var fontSize = buildCommon.sizingMultiplier[group.value.size];
|
| 1071 |
+
span.maxFontSize = fontSize * options.style.sizeMultiplier;
|
| 1072 |
+
|
| 1073 |
+
return span;
|
| 1074 |
+
};
|
| 1075 |
+
|
| 1076 |
+
groupTypes.styling = function(group, options, prev) {
|
| 1077 |
+
// Style changes are handled in the TeXbook on pg. 442, Rule 3.
|
| 1078 |
+
|
| 1079 |
+
// Figure out what style we're changing to.
|
| 1080 |
+
var style = {
|
| 1081 |
+
"display": Style.DISPLAY,
|
| 1082 |
+
"text": Style.TEXT,
|
| 1083 |
+
"script": Style.SCRIPT,
|
| 1084 |
+
"scriptscript": Style.SCRIPTSCRIPT,
|
| 1085 |
+
};
|
| 1086 |
+
|
| 1087 |
+
var newStyle = style[group.value.style];
|
| 1088 |
+
|
| 1089 |
+
// Build the inner expression in the new style.
|
| 1090 |
+
var inner = buildExpression(
|
| 1091 |
+
group.value.value, options.withStyle(newStyle), prev);
|
| 1092 |
+
|
| 1093 |
+
return makeSpan([options.style.reset(), newStyle.cls()], inner);
|
| 1094 |
+
};
|
| 1095 |
+
|
| 1096 |
+
groupTypes.font = function(group, options, prev) {
|
| 1097 |
+
var font = group.value.font;
|
| 1098 |
+
return buildGroup(group.value.body, options.withFont(font), prev);
|
| 1099 |
+
};
|
| 1100 |
+
|
| 1101 |
+
groupTypes.delimsizing = function(group, options, prev) {
|
| 1102 |
+
var delim = group.value.value;
|
| 1103 |
+
|
| 1104 |
+
if (delim === ".") {
|
| 1105 |
+
// Empty delimiters still count as elements, even though they don't
|
| 1106 |
+
// show anything.
|
| 1107 |
+
return makeSpan([groupToType[group.value.delimType]]);
|
| 1108 |
+
}
|
| 1109 |
+
|
| 1110 |
+
// Use delimiter.sizedDelim to generate the delimiter.
|
| 1111 |
+
return makeSpan(
|
| 1112 |
+
[groupToType[group.value.delimType]],
|
| 1113 |
+
[delimiter.sizedDelim(
|
| 1114 |
+
delim, group.value.size, options, group.mode)]);
|
| 1115 |
+
};
|
| 1116 |
+
|
| 1117 |
+
groupTypes.leftright = function(group, options, prev) {
|
| 1118 |
+
// Build the inner expression
|
| 1119 |
+
var inner = buildExpression(group.value.body, options.reset());
|
| 1120 |
+
|
| 1121 |
+
var innerHeight = 0;
|
| 1122 |
+
var innerDepth = 0;
|
| 1123 |
+
|
| 1124 |
+
// Calculate its height and depth
|
| 1125 |
+
for (var i = 0; i < inner.length; i++) {
|
| 1126 |
+
innerHeight = Math.max(inner[i].height, innerHeight);
|
| 1127 |
+
innerDepth = Math.max(inner[i].depth, innerDepth);
|
| 1128 |
+
}
|
| 1129 |
+
|
| 1130 |
+
// The size of delimiters is the same, regardless of what style we are
|
| 1131 |
+
// in. Thus, to correctly calculate the size of delimiter we need around
|
| 1132 |
+
// a group, we scale down the inner size based on the size.
|
| 1133 |
+
innerHeight *= options.style.sizeMultiplier;
|
| 1134 |
+
innerDepth *= options.style.sizeMultiplier;
|
| 1135 |
+
|
| 1136 |
+
var leftDelim;
|
| 1137 |
+
if (group.value.left === ".") {
|
| 1138 |
+
// Empty delimiters in \left and \right make null delimiter spaces.
|
| 1139 |
+
leftDelim = makeNullDelimiter(options);
|
| 1140 |
+
} else {
|
| 1141 |
+
// Otherwise, use leftRightDelim to generate the correct sized
|
| 1142 |
+
// delimiter.
|
| 1143 |
+
leftDelim = delimiter.leftRightDelim(
|
| 1144 |
+
group.value.left, innerHeight, innerDepth, options,
|
| 1145 |
+
group.mode);
|
| 1146 |
+
}
|
| 1147 |
+
// Add it to the beginning of the expression
|
| 1148 |
+
inner.unshift(leftDelim);
|
| 1149 |
+
|
| 1150 |
+
var rightDelim;
|
| 1151 |
+
// Same for the right delimiter
|
| 1152 |
+
if (group.value.right === ".") {
|
| 1153 |
+
rightDelim = makeNullDelimiter(options);
|
| 1154 |
+
} else {
|
| 1155 |
+
rightDelim = delimiter.leftRightDelim(
|
| 1156 |
+
group.value.right, innerHeight, innerDepth, options,
|
| 1157 |
+
group.mode);
|
| 1158 |
+
}
|
| 1159 |
+
// Add it to the end of the expression.
|
| 1160 |
+
inner.push(rightDelim);
|
| 1161 |
+
|
| 1162 |
+
return makeSpan(
|
| 1163 |
+
["minner", options.style.cls()], inner, options.getColor());
|
| 1164 |
+
};
|
| 1165 |
+
|
| 1166 |
+
groupTypes.rule = function(group, options, prev) {
|
| 1167 |
+
// Make an empty span for the rule
|
| 1168 |
+
var rule = makeSpan(["mord", "rule"], [], options.getColor());
|
| 1169 |
+
|
| 1170 |
+
// Calculate the shift, width, and height of the rule, and account for units
|
| 1171 |
+
var shift = 0;
|
| 1172 |
+
if (group.value.shift) {
|
| 1173 |
+
shift = group.value.shift.number;
|
| 1174 |
+
if (group.value.shift.unit === "ex") {
|
| 1175 |
+
shift *= fontMetrics.metrics.xHeight;
|
| 1176 |
+
}
|
| 1177 |
+
}
|
| 1178 |
+
|
| 1179 |
+
var width = group.value.width.number;
|
| 1180 |
+
if (group.value.width.unit === "ex") {
|
| 1181 |
+
width *= fontMetrics.metrics.xHeight;
|
| 1182 |
+
}
|
| 1183 |
+
|
| 1184 |
+
var height = group.value.height.number;
|
| 1185 |
+
if (group.value.height.unit === "ex") {
|
| 1186 |
+
height *= fontMetrics.metrics.xHeight;
|
| 1187 |
+
}
|
| 1188 |
+
|
| 1189 |
+
// The sizes of rules are absolute, so make it larger if we are in a
|
| 1190 |
+
// smaller style.
|
| 1191 |
+
shift /= options.style.sizeMultiplier;
|
| 1192 |
+
width /= options.style.sizeMultiplier;
|
| 1193 |
+
height /= options.style.sizeMultiplier;
|
| 1194 |
+
|
| 1195 |
+
// Style the rule to the right size
|
| 1196 |
+
rule.style.borderRightWidth = width + "em";
|
| 1197 |
+
rule.style.borderTopWidth = height + "em";
|
| 1198 |
+
rule.style.bottom = shift + "em";
|
| 1199 |
+
|
| 1200 |
+
// Record the height and width
|
| 1201 |
+
rule.width = width;
|
| 1202 |
+
rule.height = height + shift;
|
| 1203 |
+
rule.depth = -shift;
|
| 1204 |
+
|
| 1205 |
+
return rule;
|
| 1206 |
+
};
|
| 1207 |
+
|
| 1208 |
+
groupTypes.accent = function(group, options, prev) {
|
| 1209 |
+
// Accents are handled in the TeXbook pg. 443, rule 12.
|
| 1210 |
+
var base = group.value.base;
|
| 1211 |
+
|
| 1212 |
+
var supsubGroup;
|
| 1213 |
+
if (group.type === "supsub") {
|
| 1214 |
+
// If our base is a character box, and we have superscripts and
|
| 1215 |
+
// subscripts, the supsub will defer to us. In particular, we want
|
| 1216 |
+
// to attach the superscripts and subscripts to the inner body (so
|
| 1217 |
+
// that the position of the superscripts and subscripts won't be
|
| 1218 |
+
// affected by the height of the accent). We accomplish this by
|
| 1219 |
+
// sticking the base of the accent into the base of the supsub, and
|
| 1220 |
+
// rendering that, while keeping track of where the accent is.
|
| 1221 |
+
|
| 1222 |
+
// The supsub group is the group that was passed in
|
| 1223 |
+
var supsub = group;
|
| 1224 |
+
// The real accent group is the base of the supsub group
|
| 1225 |
+
group = supsub.value.base;
|
| 1226 |
+
// The character box is the base of the accent group
|
| 1227 |
+
base = group.value.base;
|
| 1228 |
+
// Stick the character box into the base of the supsub group
|
| 1229 |
+
supsub.value.base = base;
|
| 1230 |
+
|
| 1231 |
+
// Rerender the supsub group with its new base, and store that
|
| 1232 |
+
// result.
|
| 1233 |
+
supsubGroup = buildGroup(
|
| 1234 |
+
supsub, options.reset(), prev);
|
| 1235 |
+
}
|
| 1236 |
+
|
| 1237 |
+
// Build the base group
|
| 1238 |
+
var body = buildGroup(
|
| 1239 |
+
base, options.withStyle(options.style.cramp()));
|
| 1240 |
+
|
| 1241 |
+
// Calculate the skew of the accent. This is based on the line "If the
|
| 1242 |
+
// nucleus is not a single character, let s = 0; otherwise set s to the
|
| 1243 |
+
// kern amount for the nucleus followed by the \skewchar of its font."
|
| 1244 |
+
// Note that our skew metrics are just the kern between each character
|
| 1245 |
+
// and the skewchar.
|
| 1246 |
+
var skew;
|
| 1247 |
+
if (isCharacterBox(base)) {
|
| 1248 |
+
// If the base is a character box, then we want the skew of the
|
| 1249 |
+
// innermost character. To do that, we find the innermost character:
|
| 1250 |
+
var baseChar = getBaseElem(base);
|
| 1251 |
+
// Then, we render its group to get the symbol inside it
|
| 1252 |
+
var baseGroup = buildGroup(
|
| 1253 |
+
baseChar, options.withStyle(options.style.cramp()));
|
| 1254 |
+
// Finally, we pull the skew off of the symbol.
|
| 1255 |
+
skew = baseGroup.skew;
|
| 1256 |
+
// Note that we now throw away baseGroup, because the layers we
|
| 1257 |
+
// removed with getBaseElem might contain things like \color which
|
| 1258 |
+
// we can't get rid of.
|
| 1259 |
+
// TODO(emily): Find a better way to get the skew
|
| 1260 |
+
} else {
|
| 1261 |
+
skew = 0;
|
| 1262 |
+
}
|
| 1263 |
+
|
| 1264 |
+
// calculate the amount of space between the body and the accent
|
| 1265 |
+
var clearance = Math.min(body.height, fontMetrics.metrics.xHeight);
|
| 1266 |
+
|
| 1267 |
+
// Build the accent
|
| 1268 |
+
var accent = buildCommon.makeSymbol(
|
| 1269 |
+
group.value.accent, "Main-Regular", "math", options.getColor());
|
| 1270 |
+
// Remove the italic correction of the accent, because it only serves to
|
| 1271 |
+
// shift the accent over to a place we don't want.
|
| 1272 |
+
accent.italic = 0;
|
| 1273 |
+
|
| 1274 |
+
// The \vec character that the fonts use is a combining character, and
|
| 1275 |
+
// thus shows up much too far to the left. To account for this, we add a
|
| 1276 |
+
// specific class which shifts the accent over to where we want it.
|
| 1277 |
+
// TODO(emily): Fix this in a better way, like by changing the font
|
| 1278 |
+
var vecClass = group.value.accent === "\\vec" ? "accent-vec" : null;
|
| 1279 |
+
|
| 1280 |
+
var accentBody = makeSpan(["accent-body", vecClass], [
|
| 1281 |
+
makeSpan([], [accent])]);
|
| 1282 |
+
|
| 1283 |
+
accentBody = buildCommon.makeVList([
|
| 1284 |
+
{type: "elem", elem: body},
|
| 1285 |
+
{type: "kern", size: -clearance},
|
| 1286 |
+
{type: "elem", elem: accentBody},
|
| 1287 |
+
], "firstBaseline", null, options);
|
| 1288 |
+
|
| 1289 |
+
// Shift the accent over by the skew. Note we shift by twice the skew
|
| 1290 |
+
// because we are centering the accent, so by adding 2*skew to the left,
|
| 1291 |
+
// we shift it to the right by 1*skew.
|
| 1292 |
+
accentBody.children[1].style.marginLeft = 2 * skew + "em";
|
| 1293 |
+
|
| 1294 |
+
var accentWrap = makeSpan(["mord", "accent"], [accentBody]);
|
| 1295 |
+
|
| 1296 |
+
if (supsubGroup) {
|
| 1297 |
+
// Here, we replace the "base" child of the supsub with our newly
|
| 1298 |
+
// generated accent.
|
| 1299 |
+
supsubGroup.children[0] = accentWrap;
|
| 1300 |
+
|
| 1301 |
+
// Since we don't rerun the height calculation after replacing the
|
| 1302 |
+
// accent, we manually recalculate height.
|
| 1303 |
+
supsubGroup.height = Math.max(accentWrap.height, supsubGroup.height);
|
| 1304 |
+
|
| 1305 |
+
// Accents should always be ords, even when their innards are not.
|
| 1306 |
+
supsubGroup.classes[0] = "mord";
|
| 1307 |
+
|
| 1308 |
+
return supsubGroup;
|
| 1309 |
+
} else {
|
| 1310 |
+
return accentWrap;
|
| 1311 |
+
}
|
| 1312 |
+
};
|
| 1313 |
+
|
| 1314 |
+
groupTypes.phantom = function(group, options, prev) {
|
| 1315 |
+
var elements = buildExpression(
|
| 1316 |
+
group.value.value,
|
| 1317 |
+
options.withPhantom(),
|
| 1318 |
+
prev
|
| 1319 |
+
);
|
| 1320 |
+
|
| 1321 |
+
// \phantom isn't supposed to affect the elements it contains.
|
| 1322 |
+
// See "color" for more details.
|
| 1323 |
+
return new buildCommon.makeFragment(elements);
|
| 1324 |
+
};
|
| 1325 |
+
|
| 1326 |
+
/**
|
| 1327 |
+
* buildGroup is the function that takes a group and calls the correct groupType
|
| 1328 |
+
* function for it. It also handles the interaction of size and style changes
|
| 1329 |
+
* between parents and children.
|
| 1330 |
+
*/
|
| 1331 |
+
var buildGroup = function(group, options, prev) {
|
| 1332 |
+
if (!group) {
|
| 1333 |
+
return makeSpan();
|
| 1334 |
+
}
|
| 1335 |
+
|
| 1336 |
+
if (groupTypes[group.type]) {
|
| 1337 |
+
// Call the groupTypes function
|
| 1338 |
+
var groupNode = groupTypes[group.type](group, options, prev);
|
| 1339 |
+
var multiplier;
|
| 1340 |
+
|
| 1341 |
+
// If the style changed between the parent and the current group,
|
| 1342 |
+
// account for the size difference
|
| 1343 |
+
if (options.style !== options.parentStyle) {
|
| 1344 |
+
multiplier = options.style.sizeMultiplier /
|
| 1345 |
+
options.parentStyle.sizeMultiplier;
|
| 1346 |
+
|
| 1347 |
+
groupNode.height *= multiplier;
|
| 1348 |
+
groupNode.depth *= multiplier;
|
| 1349 |
+
}
|
| 1350 |
+
|
| 1351 |
+
// If the size changed between the parent and the current group, account
|
| 1352 |
+
// for that size difference.
|
| 1353 |
+
if (options.size !== options.parentSize) {
|
| 1354 |
+
multiplier = buildCommon.sizingMultiplier[options.size] /
|
| 1355 |
+
buildCommon.sizingMultiplier[options.parentSize];
|
| 1356 |
+
|
| 1357 |
+
groupNode.height *= multiplier;
|
| 1358 |
+
groupNode.depth *= multiplier;
|
| 1359 |
+
}
|
| 1360 |
+
|
| 1361 |
+
return groupNode;
|
| 1362 |
+
} else {
|
| 1363 |
+
throw new ParseError(
|
| 1364 |
+
"Got group of unknown type: '" + group.type + "'");
|
| 1365 |
+
}
|
| 1366 |
+
};
|
| 1367 |
+
|
| 1368 |
+
/**
|
| 1369 |
+
* Take an entire parse tree, and build it into an appropriate set of HTML
|
| 1370 |
+
* nodes.
|
| 1371 |
+
*/
|
| 1372 |
+
var buildHTML = function(tree, options) {
|
| 1373 |
+
// buildExpression is destructive, so we need to make a clone
|
| 1374 |
+
// of the incoming tree so that it isn't accidentally changed
|
| 1375 |
+
tree = JSON.parse(JSON.stringify(tree));
|
| 1376 |
+
|
| 1377 |
+
// Build the expression contained in the tree
|
| 1378 |
+
var expression = buildExpression(tree, options);
|
| 1379 |
+
var body = makeSpan(["base", options.style.cls()], expression);
|
| 1380 |
+
|
| 1381 |
+
// Add struts, which ensure that the top of the HTML element falls at the
|
| 1382 |
+
// height of the expression, and the bottom of the HTML element falls at the
|
| 1383 |
+
// depth of the expression.
|
| 1384 |
+
var topStrut = makeSpan(["strut"]);
|
| 1385 |
+
var bottomStrut = makeSpan(["strut", "bottom"]);
|
| 1386 |
+
|
| 1387 |
+
topStrut.style.height = body.height + "em";
|
| 1388 |
+
bottomStrut.style.height = (body.height + body.depth) + "em";
|
| 1389 |
+
// We'd like to use `vertical-align: top` but in IE 9 this lowers the
|
| 1390 |
+
// baseline of the box to the bottom of this strut (instead staying in the
|
| 1391 |
+
// normal place) so we use an absolute value for vertical-align instead
|
| 1392 |
+
bottomStrut.style.verticalAlign = -body.depth + "em";
|
| 1393 |
+
|
| 1394 |
+
// Wrap the struts and body together
|
| 1395 |
+
var htmlNode = makeSpan(["katex-html"], [topStrut, bottomStrut, body]);
|
| 1396 |
+
|
| 1397 |
+
htmlNode.setAttribute("aria-hidden", "true");
|
| 1398 |
+
|
| 1399 |
+
return htmlNode;
|
| 1400 |
+
};
|
| 1401 |
+
|
| 1402 |
+
module.exports = buildHTML;
|
katex/src/buildMathML.js
ADDED
|
@@ -0,0 +1,533 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
/**
|
| 2 |
+
* This file converts a parse tree into a cooresponding MathML tree. The main
|
| 3 |
+
* entry point is the `buildMathML` function, which takes a parse tree from the
|
| 4 |
+
* parser.
|
| 5 |
+
*/
|
| 6 |
+
|
| 7 |
+
var buildCommon = require("./buildCommon");
|
| 8 |
+
var fontMetrics = require("./fontMetrics");
|
| 9 |
+
var mathMLTree = require("./mathMLTree");
|
| 10 |
+
var ParseError = require("./ParseError");
|
| 11 |
+
var symbols = require("./symbols");
|
| 12 |
+
var utils = require("./utils");
|
| 13 |
+
|
| 14 |
+
var makeSpan = buildCommon.makeSpan;
|
| 15 |
+
var fontMap = buildCommon.fontMap;
|
| 16 |
+
|
| 17 |
+
/**
|
| 18 |
+
* Takes a symbol and converts it into a MathML text node after performing
|
| 19 |
+
* optional replacement from symbols.js.
|
| 20 |
+
*/
|
| 21 |
+
var makeText = function(text, mode) {
|
| 22 |
+
if (symbols[mode][text] && symbols[mode][text].replace) {
|
| 23 |
+
text = symbols[mode][text].replace;
|
| 24 |
+
}
|
| 25 |
+
|
| 26 |
+
return new mathMLTree.TextNode(text);
|
| 27 |
+
};
|
| 28 |
+
|
| 29 |
+
/**
|
| 30 |
+
* Returns the math variant as a string or null if none is required.
|
| 31 |
+
*/
|
| 32 |
+
var getVariant = function(group, options) {
|
| 33 |
+
var font = options.font;
|
| 34 |
+
if (!font) {
|
| 35 |
+
return null;
|
| 36 |
+
}
|
| 37 |
+
|
| 38 |
+
var mode = group.mode;
|
| 39 |
+
if (font === "mathit") {
|
| 40 |
+
return "italic";
|
| 41 |
+
}
|
| 42 |
+
|
| 43 |
+
var value = group.value;
|
| 44 |
+
if (utils.contains(["\\imath", "\\jmath"], value)) {
|
| 45 |
+
return null;
|
| 46 |
+
}
|
| 47 |
+
|
| 48 |
+
if (symbols[mode][value] && symbols[mode][value].replace) {
|
| 49 |
+
value = symbols[mode][value].replace;
|
| 50 |
+
}
|
| 51 |
+
|
| 52 |
+
var fontName = fontMap[font].fontName;
|
| 53 |
+
if (fontMetrics.getCharacterMetrics(value, fontName)) {
|
| 54 |
+
return fontMap[options.font].variant;
|
| 55 |
+
}
|
| 56 |
+
|
| 57 |
+
return null;
|
| 58 |
+
};
|
| 59 |
+
|
| 60 |
+
/**
|
| 61 |
+
* Functions for handling the different types of groups found in the parse
|
| 62 |
+
* tree. Each function should take a parse group and return a MathML node.
|
| 63 |
+
*/
|
| 64 |
+
var groupTypes = {};
|
| 65 |
+
|
| 66 |
+
groupTypes.mathord = function(group, options) {
|
| 67 |
+
var node = new mathMLTree.MathNode(
|
| 68 |
+
"mi",
|
| 69 |
+
[makeText(group.value, group.mode)]);
|
| 70 |
+
|
| 71 |
+
var variant = getVariant(group, options);
|
| 72 |
+
if (variant) {
|
| 73 |
+
node.setAttribute("mathvariant", variant);
|
| 74 |
+
}
|
| 75 |
+
return node;
|
| 76 |
+
};
|
| 77 |
+
|
| 78 |
+
groupTypes.textord = function(group, options) {
|
| 79 |
+
var text = makeText(group.value, group.mode);
|
| 80 |
+
|
| 81 |
+
var variant = getVariant(group, options) || "normal";
|
| 82 |
+
|
| 83 |
+
var node;
|
| 84 |
+
if (/[0-9]/.test(group.value)) {
|
| 85 |
+
// TODO(kevinb) merge adjacent <mn> nodes
|
| 86 |
+
// do it as a post processing step
|
| 87 |
+
node = new mathMLTree.MathNode("mn", [text]);
|
| 88 |
+
if (options.font) {
|
| 89 |
+
node.setAttribute("mathvariant", variant);
|
| 90 |
+
}
|
| 91 |
+
} else {
|
| 92 |
+
node = new mathMLTree.MathNode("mi", [text]);
|
| 93 |
+
node.setAttribute("mathvariant", variant);
|
| 94 |
+
}
|
| 95 |
+
|
| 96 |
+
return node;
|
| 97 |
+
};
|
| 98 |
+
|
| 99 |
+
groupTypes.bin = function(group) {
|
| 100 |
+
var node = new mathMLTree.MathNode(
|
| 101 |
+
"mo", [makeText(group.value, group.mode)]);
|
| 102 |
+
|
| 103 |
+
return node;
|
| 104 |
+
};
|
| 105 |
+
|
| 106 |
+
groupTypes.rel = function(group) {
|
| 107 |
+
var node = new mathMLTree.MathNode(
|
| 108 |
+
"mo", [makeText(group.value, group.mode)]);
|
| 109 |
+
|
| 110 |
+
return node;
|
| 111 |
+
};
|
| 112 |
+
|
| 113 |
+
groupTypes.open = function(group) {
|
| 114 |
+
var node = new mathMLTree.MathNode(
|
| 115 |
+
"mo", [makeText(group.value, group.mode)]);
|
| 116 |
+
|
| 117 |
+
return node;
|
| 118 |
+
};
|
| 119 |
+
|
| 120 |
+
groupTypes.close = function(group) {
|
| 121 |
+
var node = new mathMLTree.MathNode(
|
| 122 |
+
"mo", [makeText(group.value, group.mode)]);
|
| 123 |
+
|
| 124 |
+
return node;
|
| 125 |
+
};
|
| 126 |
+
|
| 127 |
+
groupTypes.inner = function(group) {
|
| 128 |
+
var node = new mathMLTree.MathNode(
|
| 129 |
+
"mo", [makeText(group.value, group.mode)]);
|
| 130 |
+
|
| 131 |
+
return node;
|
| 132 |
+
};
|
| 133 |
+
|
| 134 |
+
groupTypes.punct = function(group) {
|
| 135 |
+
var node = new mathMLTree.MathNode(
|
| 136 |
+
"mo", [makeText(group.value, group.mode)]);
|
| 137 |
+
|
| 138 |
+
node.setAttribute("separator", "true");
|
| 139 |
+
|
| 140 |
+
return node;
|
| 141 |
+
};
|
| 142 |
+
|
| 143 |
+
groupTypes.ordgroup = function(group, options) {
|
| 144 |
+
var inner = buildExpression(group.value, options);
|
| 145 |
+
|
| 146 |
+
var node = new mathMLTree.MathNode("mrow", inner);
|
| 147 |
+
|
| 148 |
+
return node;
|
| 149 |
+
};
|
| 150 |
+
|
| 151 |
+
groupTypes.text = function(group, options) {
|
| 152 |
+
var inner = buildExpression(group.value.body, options);
|
| 153 |
+
|
| 154 |
+
var node = new mathMLTree.MathNode("mtext", inner);
|
| 155 |
+
|
| 156 |
+
return node;
|
| 157 |
+
};
|
| 158 |
+
|
| 159 |
+
groupTypes.color = function(group, options) {
|
| 160 |
+
var inner = buildExpression(group.value.value, options);
|
| 161 |
+
|
| 162 |
+
var node = new mathMLTree.MathNode("mstyle", inner);
|
| 163 |
+
|
| 164 |
+
node.setAttribute("mathcolor", group.value.color);
|
| 165 |
+
|
| 166 |
+
return node;
|
| 167 |
+
};
|
| 168 |
+
|
| 169 |
+
groupTypes.supsub = function(group, options) {
|
| 170 |
+
var children = [buildGroup(group.value.base, options)];
|
| 171 |
+
|
| 172 |
+
if (group.value.sub) {
|
| 173 |
+
children.push(buildGroup(group.value.sub, options));
|
| 174 |
+
}
|
| 175 |
+
|
| 176 |
+
if (group.value.sup) {
|
| 177 |
+
children.push(buildGroup(group.value.sup, options));
|
| 178 |
+
}
|
| 179 |
+
|
| 180 |
+
var nodeType;
|
| 181 |
+
if (!group.value.sub) {
|
| 182 |
+
nodeType = "msup";
|
| 183 |
+
} else if (!group.value.sup) {
|
| 184 |
+
nodeType = "msub";
|
| 185 |
+
} else {
|
| 186 |
+
nodeType = "msubsup";
|
| 187 |
+
}
|
| 188 |
+
|
| 189 |
+
var node = new mathMLTree.MathNode(nodeType, children);
|
| 190 |
+
|
| 191 |
+
return node;
|
| 192 |
+
};
|
| 193 |
+
|
| 194 |
+
groupTypes.genfrac = function(group, options) {
|
| 195 |
+
var node = new mathMLTree.MathNode(
|
| 196 |
+
"mfrac",
|
| 197 |
+
[buildGroup(group.value.numer, options),
|
| 198 |
+
buildGroup(group.value.denom, options)]);
|
| 199 |
+
|
| 200 |
+
if (!group.value.hasBarLine) {
|
| 201 |
+
node.setAttribute("linethickness", "0px");
|
| 202 |
+
}
|
| 203 |
+
|
| 204 |
+
if (group.value.leftDelim != null || group.value.rightDelim != null) {
|
| 205 |
+
var withDelims = [];
|
| 206 |
+
|
| 207 |
+
if (group.value.leftDelim != null) {
|
| 208 |
+
var leftOp = new mathMLTree.MathNode(
|
| 209 |
+
"mo", [new mathMLTree.TextNode(group.value.leftDelim)]);
|
| 210 |
+
|
| 211 |
+
leftOp.setAttribute("fence", "true");
|
| 212 |
+
|
| 213 |
+
withDelims.push(leftOp);
|
| 214 |
+
}
|
| 215 |
+
|
| 216 |
+
withDelims.push(node);
|
| 217 |
+
|
| 218 |
+
if (group.value.rightDelim != null) {
|
| 219 |
+
var rightOp = new mathMLTree.MathNode(
|
| 220 |
+
"mo", [new mathMLTree.TextNode(group.value.rightDelim)]);
|
| 221 |
+
|
| 222 |
+
rightOp.setAttribute("fence", "true");
|
| 223 |
+
|
| 224 |
+
withDelims.push(rightOp);
|
| 225 |
+
}
|
| 226 |
+
|
| 227 |
+
var outerNode = new mathMLTree.MathNode("mrow", withDelims);
|
| 228 |
+
|
| 229 |
+
return outerNode;
|
| 230 |
+
}
|
| 231 |
+
|
| 232 |
+
return node;
|
| 233 |
+
};
|
| 234 |
+
|
| 235 |
+
groupTypes.array = function(group, options) {
|
| 236 |
+
return new mathMLTree.MathNode(
|
| 237 |
+
"mtable", group.value.body.map(function(row) {
|
| 238 |
+
return new mathMLTree.MathNode(
|
| 239 |
+
"mtr", row.map(function(cell) {
|
| 240 |
+
return new mathMLTree.MathNode(
|
| 241 |
+
"mtd", [buildGroup(cell, options)]);
|
| 242 |
+
}));
|
| 243 |
+
}));
|
| 244 |
+
};
|
| 245 |
+
|
| 246 |
+
groupTypes.sqrt = function(group, options) {
|
| 247 |
+
var node;
|
| 248 |
+
if (group.value.index) {
|
| 249 |
+
node = new mathMLTree.MathNode(
|
| 250 |
+
"mroot", [
|
| 251 |
+
buildGroup(group.value.body, options),
|
| 252 |
+
buildGroup(group.value.index, options),
|
| 253 |
+
]);
|
| 254 |
+
} else {
|
| 255 |
+
node = new mathMLTree.MathNode(
|
| 256 |
+
"msqrt", [buildGroup(group.value.body, options)]);
|
| 257 |
+
}
|
| 258 |
+
|
| 259 |
+
return node;
|
| 260 |
+
};
|
| 261 |
+
|
| 262 |
+
groupTypes.leftright = function(group, options) {
|
| 263 |
+
var inner = buildExpression(group.value.body, options);
|
| 264 |
+
|
| 265 |
+
if (group.value.left !== ".") {
|
| 266 |
+
var leftNode = new mathMLTree.MathNode(
|
| 267 |
+
"mo", [makeText(group.value.left, group.mode)]);
|
| 268 |
+
|
| 269 |
+
leftNode.setAttribute("fence", "true");
|
| 270 |
+
|
| 271 |
+
inner.unshift(leftNode);
|
| 272 |
+
}
|
| 273 |
+
|
| 274 |
+
if (group.value.right !== ".") {
|
| 275 |
+
var rightNode = new mathMLTree.MathNode(
|
| 276 |
+
"mo", [makeText(group.value.right, group.mode)]);
|
| 277 |
+
|
| 278 |
+
rightNode.setAttribute("fence", "true");
|
| 279 |
+
|
| 280 |
+
inner.push(rightNode);
|
| 281 |
+
}
|
| 282 |
+
|
| 283 |
+
var outerNode = new mathMLTree.MathNode("mrow", inner);
|
| 284 |
+
|
| 285 |
+
return outerNode;
|
| 286 |
+
};
|
| 287 |
+
|
| 288 |
+
groupTypes.accent = function(group, options) {
|
| 289 |
+
var accentNode = new mathMLTree.MathNode(
|
| 290 |
+
"mo", [makeText(group.value.accent, group.mode)]);
|
| 291 |
+
|
| 292 |
+
var node = new mathMLTree.MathNode(
|
| 293 |
+
"mover",
|
| 294 |
+
[buildGroup(group.value.base, options),
|
| 295 |
+
accentNode]);
|
| 296 |
+
|
| 297 |
+
node.setAttribute("accent", "true");
|
| 298 |
+
|
| 299 |
+
return node;
|
| 300 |
+
};
|
| 301 |
+
|
| 302 |
+
groupTypes.spacing = function(group) {
|
| 303 |
+
var node;
|
| 304 |
+
|
| 305 |
+
if (group.value === "\\ " || group.value === "\\space" ||
|
| 306 |
+
group.value === " " || group.value === "~") {
|
| 307 |
+
node = new mathMLTree.MathNode(
|
| 308 |
+
"mtext", [new mathMLTree.TextNode("\u00a0")]);
|
| 309 |
+
} else {
|
| 310 |
+
node = new mathMLTree.MathNode("mspace");
|
| 311 |
+
|
| 312 |
+
node.setAttribute(
|
| 313 |
+
"width", buildCommon.spacingFunctions[group.value].size);
|
| 314 |
+
}
|
| 315 |
+
|
| 316 |
+
return node;
|
| 317 |
+
};
|
| 318 |
+
|
| 319 |
+
groupTypes.op = function(group) {
|
| 320 |
+
var node;
|
| 321 |
+
|
| 322 |
+
// TODO(emily): handle big operators using the `largeop` attribute
|
| 323 |
+
|
| 324 |
+
if (group.value.symbol) {
|
| 325 |
+
// This is a symbol. Just add the symbol.
|
| 326 |
+
node = new mathMLTree.MathNode(
|
| 327 |
+
"mo", [makeText(group.value.body, group.mode)]);
|
| 328 |
+
} else {
|
| 329 |
+
// This is a text operator. Add all of the characters from the
|
| 330 |
+
// operator's name.
|
| 331 |
+
// TODO(emily): Add a space in the middle of some of these
|
| 332 |
+
// operators, like \limsup.
|
| 333 |
+
node = new mathMLTree.MathNode(
|
| 334 |
+
"mi", [new mathMLTree.TextNode(group.value.body.slice(1))]);
|
| 335 |
+
}
|
| 336 |
+
|
| 337 |
+
return node;
|
| 338 |
+
};
|
| 339 |
+
|
| 340 |
+
groupTypes.katex = function(group) {
|
| 341 |
+
var node = new mathMLTree.MathNode(
|
| 342 |
+
"mtext", [new mathMLTree.TextNode("KaTeX")]);
|
| 343 |
+
|
| 344 |
+
return node;
|
| 345 |
+
};
|
| 346 |
+
|
| 347 |
+
groupTypes.font = function(group, options) {
|
| 348 |
+
var font = group.value.font;
|
| 349 |
+
return buildGroup(group.value.body, options.withFont(font));
|
| 350 |
+
};
|
| 351 |
+
|
| 352 |
+
groupTypes.delimsizing = function(group) {
|
| 353 |
+
var children = [];
|
| 354 |
+
|
| 355 |
+
if (group.value.value !== ".") {
|
| 356 |
+
children.push(makeText(group.value.value, group.mode));
|
| 357 |
+
}
|
| 358 |
+
|
| 359 |
+
var node = new mathMLTree.MathNode("mo", children);
|
| 360 |
+
|
| 361 |
+
if (group.value.delimType === "open" ||
|
| 362 |
+
group.value.delimType === "close") {
|
| 363 |
+
// Only some of the delimsizing functions act as fences, and they
|
| 364 |
+
// return "open" or "close" delimTypes.
|
| 365 |
+
node.setAttribute("fence", "true");
|
| 366 |
+
} else {
|
| 367 |
+
// Explicitly disable fencing if it's not a fence, to override the
|
| 368 |
+
// defaults.
|
| 369 |
+
node.setAttribute("fence", "false");
|
| 370 |
+
}
|
| 371 |
+
|
| 372 |
+
return node;
|
| 373 |
+
};
|
| 374 |
+
|
| 375 |
+
groupTypes.styling = function(group, options) {
|
| 376 |
+
var inner = buildExpression(group.value.value, options);
|
| 377 |
+
|
| 378 |
+
var node = new mathMLTree.MathNode("mstyle", inner);
|
| 379 |
+
|
| 380 |
+
var styleAttributes = {
|
| 381 |
+
"display": ["0", "true"],
|
| 382 |
+
"text": ["0", "false"],
|
| 383 |
+
"script": ["1", "false"],
|
| 384 |
+
"scriptscript": ["2", "false"],
|
| 385 |
+
};
|
| 386 |
+
|
| 387 |
+
var attr = styleAttributes[group.value.style];
|
| 388 |
+
|
| 389 |
+
node.setAttribute("scriptlevel", attr[0]);
|
| 390 |
+
node.setAttribute("displaystyle", attr[1]);
|
| 391 |
+
|
| 392 |
+
return node;
|
| 393 |
+
};
|
| 394 |
+
|
| 395 |
+
groupTypes.sizing = function(group, options) {
|
| 396 |
+
var inner = buildExpression(group.value.value, options);
|
| 397 |
+
|
| 398 |
+
var node = new mathMLTree.MathNode("mstyle", inner);
|
| 399 |
+
|
| 400 |
+
// TODO(emily): This doesn't produce the correct size for nested size
|
| 401 |
+
// changes, because we don't keep state of what style we're currently
|
| 402 |
+
// in, so we can't reset the size to normal before changing it. Now
|
| 403 |
+
// that we're passing an options parameter we should be able to fix
|
| 404 |
+
// this.
|
| 405 |
+
node.setAttribute(
|
| 406 |
+
"mathsize", buildCommon.sizingMultiplier[group.value.size] + "em");
|
| 407 |
+
|
| 408 |
+
return node;
|
| 409 |
+
};
|
| 410 |
+
|
| 411 |
+
groupTypes.overline = function(group, options) {
|
| 412 |
+
var operator = new mathMLTree.MathNode(
|
| 413 |
+
"mo", [new mathMLTree.TextNode("\u203e")]);
|
| 414 |
+
operator.setAttribute("stretchy", "true");
|
| 415 |
+
|
| 416 |
+
var node = new mathMLTree.MathNode(
|
| 417 |
+
"mover",
|
| 418 |
+
[buildGroup(group.value.body, options),
|
| 419 |
+
operator]);
|
| 420 |
+
node.setAttribute("accent", "true");
|
| 421 |
+
|
| 422 |
+
return node;
|
| 423 |
+
};
|
| 424 |
+
|
| 425 |
+
groupTypes.underline = function(group, options) {
|
| 426 |
+
var operator = new mathMLTree.MathNode(
|
| 427 |
+
"mo", [new mathMLTree.TextNode("\u203e")]);
|
| 428 |
+
operator.setAttribute("stretchy", "true");
|
| 429 |
+
|
| 430 |
+
var node = new mathMLTree.MathNode(
|
| 431 |
+
"munder",
|
| 432 |
+
[buildGroup(group.value.body, options),
|
| 433 |
+
operator]);
|
| 434 |
+
node.setAttribute("accentunder", "true");
|
| 435 |
+
|
| 436 |
+
return node;
|
| 437 |
+
};
|
| 438 |
+
|
| 439 |
+
groupTypes.rule = function(group) {
|
| 440 |
+
// TODO(emily): Figure out if there's an actual way to draw black boxes
|
| 441 |
+
// in MathML.
|
| 442 |
+
var node = new mathMLTree.MathNode("mrow");
|
| 443 |
+
|
| 444 |
+
return node;
|
| 445 |
+
};
|
| 446 |
+
|
| 447 |
+
groupTypes.llap = function(group, options) {
|
| 448 |
+
var node = new mathMLTree.MathNode(
|
| 449 |
+
"mpadded", [buildGroup(group.value.body, options)]);
|
| 450 |
+
|
| 451 |
+
node.setAttribute("lspace", "-1width");
|
| 452 |
+
node.setAttribute("width", "0px");
|
| 453 |
+
|
| 454 |
+
return node;
|
| 455 |
+
};
|
| 456 |
+
|
| 457 |
+
groupTypes.rlap = function(group, options) {
|
| 458 |
+
var node = new mathMLTree.MathNode(
|
| 459 |
+
"mpadded", [buildGroup(group.value.body, options)]);
|
| 460 |
+
|
| 461 |
+
node.setAttribute("width", "0px");
|
| 462 |
+
|
| 463 |
+
return node;
|
| 464 |
+
};
|
| 465 |
+
|
| 466 |
+
groupTypes.phantom = function(group, options, prev) {
|
| 467 |
+
var inner = buildExpression(group.value.value, options);
|
| 468 |
+
return new mathMLTree.MathNode("mphantom", inner);
|
| 469 |
+
};
|
| 470 |
+
|
| 471 |
+
/**
|
| 472 |
+
* Takes a list of nodes, builds them, and returns a list of the generated
|
| 473 |
+
* MathML nodes. A little simpler than the HTML version because we don't do any
|
| 474 |
+
* previous-node handling.
|
| 475 |
+
*/
|
| 476 |
+
var buildExpression = function(expression, options) {
|
| 477 |
+
var groups = [];
|
| 478 |
+
for (var i = 0; i < expression.length; i++) {
|
| 479 |
+
var group = expression[i];
|
| 480 |
+
groups.push(buildGroup(group, options));
|
| 481 |
+
}
|
| 482 |
+
return groups;
|
| 483 |
+
};
|
| 484 |
+
|
| 485 |
+
/**
|
| 486 |
+
* Takes a group from the parser and calls the appropriate groupTypes function
|
| 487 |
+
* on it to produce a MathML node.
|
| 488 |
+
*/
|
| 489 |
+
var buildGroup = function(group, options) {
|
| 490 |
+
if (!group) {
|
| 491 |
+
return new mathMLTree.MathNode("mrow");
|
| 492 |
+
}
|
| 493 |
+
|
| 494 |
+
if (groupTypes[group.type]) {
|
| 495 |
+
// Call the groupTypes function
|
| 496 |
+
return groupTypes[group.type](group, options);
|
| 497 |
+
} else {
|
| 498 |
+
throw new ParseError(
|
| 499 |
+
"Got group of unknown type: '" + group.type + "'");
|
| 500 |
+
}
|
| 501 |
+
};
|
| 502 |
+
|
| 503 |
+
/**
|
| 504 |
+
* Takes a full parse tree and settings and builds a MathML representation of
|
| 505 |
+
* it. In particular, we put the elements from building the parse tree into a
|
| 506 |
+
* <semantics> tag so we can also include that TeX source as an annotation.
|
| 507 |
+
*
|
| 508 |
+
* Note that we actually return a domTree element with a `<math>` inside it so
|
| 509 |
+
* we can do appropriate styling.
|
| 510 |
+
*/
|
| 511 |
+
var buildMathML = function(tree, texExpression, options) {
|
| 512 |
+
var expression = buildExpression(tree, options);
|
| 513 |
+
|
| 514 |
+
// Wrap up the expression in an mrow so it is presented in the semantics
|
| 515 |
+
// tag correctly.
|
| 516 |
+
var wrapper = new mathMLTree.MathNode("mrow", expression);
|
| 517 |
+
|
| 518 |
+
// Build a TeX annotation of the source
|
| 519 |
+
var annotation = new mathMLTree.MathNode(
|
| 520 |
+
"annotation", [new mathMLTree.TextNode(texExpression)]);
|
| 521 |
+
|
| 522 |
+
annotation.setAttribute("encoding", "application/x-tex");
|
| 523 |
+
|
| 524 |
+
var semantics = new mathMLTree.MathNode(
|
| 525 |
+
"semantics", [wrapper, annotation]);
|
| 526 |
+
|
| 527 |
+
var math = new mathMLTree.MathNode("math", [semantics]);
|
| 528 |
+
|
| 529 |
+
// You can't style <math> nodes, so we wrap the node in a span.
|
| 530 |
+
return makeSpan(["katex-mathml"], [math]);
|
| 531 |
+
};
|
| 532 |
+
|
| 533 |
+
module.exports = buildMathML;
|
katex/src/buildTree.js
ADDED
|
@@ -0,0 +1,40 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
var buildHTML = require("./buildHTML");
|
| 2 |
+
var buildMathML = require("./buildMathML");
|
| 3 |
+
var buildCommon = require("./buildCommon");
|
| 4 |
+
var Options = require("./Options");
|
| 5 |
+
var Settings = require("./Settings");
|
| 6 |
+
var Style = require("./Style");
|
| 7 |
+
|
| 8 |
+
var makeSpan = buildCommon.makeSpan;
|
| 9 |
+
|
| 10 |
+
var buildTree = function(tree, expression, settings) {
|
| 11 |
+
settings = settings || new Settings({});
|
| 12 |
+
|
| 13 |
+
var startStyle = Style.TEXT;
|
| 14 |
+
if (settings.displayMode) {
|
| 15 |
+
startStyle = Style.DISPLAY;
|
| 16 |
+
}
|
| 17 |
+
|
| 18 |
+
// Setup the default options
|
| 19 |
+
var options = new Options({
|
| 20 |
+
style: startStyle,
|
| 21 |
+
size: "size5",
|
| 22 |
+
});
|
| 23 |
+
|
| 24 |
+
// `buildHTML` sometimes messes with the parse tree (like turning bins ->
|
| 25 |
+
// ords), so we build the MathML version first.
|
| 26 |
+
var mathMLNode = buildMathML(tree, expression, options);
|
| 27 |
+
var htmlNode = buildHTML(tree, options);
|
| 28 |
+
|
| 29 |
+
var katexNode = makeSpan(["katex"], [
|
| 30 |
+
mathMLNode, htmlNode,
|
| 31 |
+
]);
|
| 32 |
+
|
| 33 |
+
if (settings.displayMode) {
|
| 34 |
+
return makeSpan(["katex-display"], [katexNode]);
|
| 35 |
+
} else {
|
| 36 |
+
return katexNode;
|
| 37 |
+
}
|
| 38 |
+
};
|
| 39 |
+
|
| 40 |
+
module.exports = buildTree;
|
katex/src/delimiter.js
ADDED
|
@@ -0,0 +1,542 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
/**
|
| 2 |
+
* This file deals with creating delimiters of various sizes. The TeXbook
|
| 3 |
+
* discusses these routines on page 441-442, in the "Another subroutine sets box
|
| 4 |
+
* x to a specified variable delimiter" paragraph.
|
| 5 |
+
*
|
| 6 |
+
* There are three main routines here. `makeSmallDelim` makes a delimiter in the
|
| 7 |
+
* normal font, but in either text, script, or scriptscript style.
|
| 8 |
+
* `makeLargeDelim` makes a delimiter in textstyle, but in one of the Size1,
|
| 9 |
+
* Size2, Size3, or Size4 fonts. `makeStackedDelim` makes a delimiter out of
|
| 10 |
+
* smaller pieces that are stacked on top of one another.
|
| 11 |
+
*
|
| 12 |
+
* The functions take a parameter `center`, which determines if the delimiter
|
| 13 |
+
* should be centered around the axis.
|
| 14 |
+
*
|
| 15 |
+
* Then, there are three exposed functions. `sizedDelim` makes a delimiter in
|
| 16 |
+
* one of the given sizes. This is used for things like `\bigl`.
|
| 17 |
+
* `customSizedDelim` makes a delimiter with a given total height+depth. It is
|
| 18 |
+
* called in places like `\sqrt`. `leftRightDelim` makes an appropriate
|
| 19 |
+
* delimiter which surrounds an expression of a given height an depth. It is
|
| 20 |
+
* used in `\left` and `\right`.
|
| 21 |
+
*/
|
| 22 |
+
|
| 23 |
+
var ParseError = require("./ParseError");
|
| 24 |
+
var Style = require("./Style");
|
| 25 |
+
|
| 26 |
+
var buildCommon = require("./buildCommon");
|
| 27 |
+
var fontMetrics = require("./fontMetrics");
|
| 28 |
+
var symbols = require("./symbols");
|
| 29 |
+
var utils = require("./utils");
|
| 30 |
+
|
| 31 |
+
var makeSpan = buildCommon.makeSpan;
|
| 32 |
+
|
| 33 |
+
/**
|
| 34 |
+
* Get the metrics for a given symbol and font, after transformation (i.e.
|
| 35 |
+
* after following replacement from symbols.js)
|
| 36 |
+
*/
|
| 37 |
+
var getMetrics = function(symbol, font) {
|
| 38 |
+
if (symbols.math[symbol] && symbols.math[symbol].replace) {
|
| 39 |
+
return fontMetrics.getCharacterMetrics(
|
| 40 |
+
symbols.math[symbol].replace, font);
|
| 41 |
+
} else {
|
| 42 |
+
return fontMetrics.getCharacterMetrics(
|
| 43 |
+
symbol, font);
|
| 44 |
+
}
|
| 45 |
+
};
|
| 46 |
+
|
| 47 |
+
/**
|
| 48 |
+
* Builds a symbol in the given font size (note size is an integer)
|
| 49 |
+
*/
|
| 50 |
+
var mathrmSize = function(value, size, mode) {
|
| 51 |
+
return buildCommon.makeSymbol(value, "Size" + size + "-Regular", mode);
|
| 52 |
+
};
|
| 53 |
+
|
| 54 |
+
/**
|
| 55 |
+
* Puts a delimiter span in a given style, and adds appropriate height, depth,
|
| 56 |
+
* and maxFontSizes.
|
| 57 |
+
*/
|
| 58 |
+
var styleWrap = function(delim, toStyle, options) {
|
| 59 |
+
var span = makeSpan(
|
| 60 |
+
["style-wrap", options.style.reset(), toStyle.cls()], [delim]);
|
| 61 |
+
|
| 62 |
+
var multiplier = toStyle.sizeMultiplier / options.style.sizeMultiplier;
|
| 63 |
+
|
| 64 |
+
span.height *= multiplier;
|
| 65 |
+
span.depth *= multiplier;
|
| 66 |
+
span.maxFontSize = toStyle.sizeMultiplier;
|
| 67 |
+
|
| 68 |
+
return span;
|
| 69 |
+
};
|
| 70 |
+
|
| 71 |
+
/**
|
| 72 |
+
* Makes a small delimiter. This is a delimiter that comes in the Main-Regular
|
| 73 |
+
* font, but is restyled to either be in textstyle, scriptstyle, or
|
| 74 |
+
* scriptscriptstyle.
|
| 75 |
+
*/
|
| 76 |
+
var makeSmallDelim = function(delim, style, center, options, mode) {
|
| 77 |
+
var text = buildCommon.makeSymbol(delim, "Main-Regular", mode);
|
| 78 |
+
|
| 79 |
+
var span = styleWrap(text, style, options);
|
| 80 |
+
|
| 81 |
+
if (center) {
|
| 82 |
+
var shift =
|
| 83 |
+
(1 - options.style.sizeMultiplier / style.sizeMultiplier) *
|
| 84 |
+
fontMetrics.metrics.axisHeight;
|
| 85 |
+
|
| 86 |
+
span.style.top = shift + "em";
|
| 87 |
+
span.height -= shift;
|
| 88 |
+
span.depth += shift;
|
| 89 |
+
}
|
| 90 |
+
|
| 91 |
+
return span;
|
| 92 |
+
};
|
| 93 |
+
|
| 94 |
+
/**
|
| 95 |
+
* Makes a large delimiter. This is a delimiter that comes in the Size1, Size2,
|
| 96 |
+
* Size3, or Size4 fonts. It is always rendered in textstyle.
|
| 97 |
+
*/
|
| 98 |
+
var makeLargeDelim = function(delim, size, center, options, mode) {
|
| 99 |
+
var inner = mathrmSize(delim, size, mode);
|
| 100 |
+
|
| 101 |
+
var span = styleWrap(
|
| 102 |
+
makeSpan(["delimsizing", "size" + size],
|
| 103 |
+
[inner], options.getColor()),
|
| 104 |
+
Style.TEXT, options);
|
| 105 |
+
|
| 106 |
+
if (center) {
|
| 107 |
+
var shift = (1 - options.style.sizeMultiplier) *
|
| 108 |
+
fontMetrics.metrics.axisHeight;
|
| 109 |
+
|
| 110 |
+
span.style.top = shift + "em";
|
| 111 |
+
span.height -= shift;
|
| 112 |
+
span.depth += shift;
|
| 113 |
+
}
|
| 114 |
+
|
| 115 |
+
return span;
|
| 116 |
+
};
|
| 117 |
+
|
| 118 |
+
/**
|
| 119 |
+
* Make an inner span with the given offset and in the given font. This is used
|
| 120 |
+
* in `makeStackedDelim` to make the stacking pieces for the delimiter.
|
| 121 |
+
*/
|
| 122 |
+
var makeInner = function(symbol, font, mode) {
|
| 123 |
+
var sizeClass;
|
| 124 |
+
// Apply the correct CSS class to choose the right font.
|
| 125 |
+
if (font === "Size1-Regular") {
|
| 126 |
+
sizeClass = "delim-size1";
|
| 127 |
+
} else if (font === "Size4-Regular") {
|
| 128 |
+
sizeClass = "delim-size4";
|
| 129 |
+
}
|
| 130 |
+
|
| 131 |
+
var inner = makeSpan(
|
| 132 |
+
["delimsizinginner", sizeClass],
|
| 133 |
+
[makeSpan([], [buildCommon.makeSymbol(symbol, font, mode)])]);
|
| 134 |
+
|
| 135 |
+
// Since this will be passed into `makeVList` in the end, wrap the element
|
| 136 |
+
// in the appropriate tag that VList uses.
|
| 137 |
+
return {type: "elem", elem: inner};
|
| 138 |
+
};
|
| 139 |
+
|
| 140 |
+
/**
|
| 141 |
+
* Make a stacked delimiter out of a given delimiter, with the total height at
|
| 142 |
+
* least `heightTotal`. This routine is mentioned on page 442 of the TeXbook.
|
| 143 |
+
*/
|
| 144 |
+
var makeStackedDelim = function(delim, heightTotal, center, options, mode) {
|
| 145 |
+
// There are four parts, the top, an optional middle, a repeated part, and a
|
| 146 |
+
// bottom.
|
| 147 |
+
var top;
|
| 148 |
+
var middle;
|
| 149 |
+
var repeat;
|
| 150 |
+
var bottom;
|
| 151 |
+
top = repeat = bottom = delim;
|
| 152 |
+
middle = null;
|
| 153 |
+
// Also keep track of what font the delimiters are in
|
| 154 |
+
var font = "Size1-Regular";
|
| 155 |
+
|
| 156 |
+
// We set the parts and font based on the symbol. Note that we use
|
| 157 |
+
// '\u23d0' instead of '|' and '\u2016' instead of '\\|' for the
|
| 158 |
+
// repeats of the arrows
|
| 159 |
+
if (delim === "\\uparrow") {
|
| 160 |
+
repeat = bottom = "\u23d0";
|
| 161 |
+
} else if (delim === "\\Uparrow") {
|
| 162 |
+
repeat = bottom = "\u2016";
|
| 163 |
+
} else if (delim === "\\downarrow") {
|
| 164 |
+
top = repeat = "\u23d0";
|
| 165 |
+
} else if (delim === "\\Downarrow") {
|
| 166 |
+
top = repeat = "\u2016";
|
| 167 |
+
} else if (delim === "\\updownarrow") {
|
| 168 |
+
top = "\\uparrow";
|
| 169 |
+
repeat = "\u23d0";
|
| 170 |
+
bottom = "\\downarrow";
|
| 171 |
+
} else if (delim === "\\Updownarrow") {
|
| 172 |
+
top = "\\Uparrow";
|
| 173 |
+
repeat = "\u2016";
|
| 174 |
+
bottom = "\\Downarrow";
|
| 175 |
+
} else if (delim === "[" || delim === "\\lbrack") {
|
| 176 |
+
top = "\u23a1";
|
| 177 |
+
repeat = "\u23a2";
|
| 178 |
+
bottom = "\u23a3";
|
| 179 |
+
font = "Size4-Regular";
|
| 180 |
+
} else if (delim === "]" || delim === "\\rbrack") {
|
| 181 |
+
top = "\u23a4";
|
| 182 |
+
repeat = "\u23a5";
|
| 183 |
+
bottom = "\u23a6";
|
| 184 |
+
font = "Size4-Regular";
|
| 185 |
+
} else if (delim === "\\lfloor") {
|
| 186 |
+
repeat = top = "\u23a2";
|
| 187 |
+
bottom = "\u23a3";
|
| 188 |
+
font = "Size4-Regular";
|
| 189 |
+
} else if (delim === "\\lceil") {
|
| 190 |
+
top = "\u23a1";
|
| 191 |
+
repeat = bottom = "\u23a2";
|
| 192 |
+
font = "Size4-Regular";
|
| 193 |
+
} else if (delim === "\\rfloor") {
|
| 194 |
+
repeat = top = "\u23a5";
|
| 195 |
+
bottom = "\u23a6";
|
| 196 |
+
font = "Size4-Regular";
|
| 197 |
+
} else if (delim === "\\rceil") {
|
| 198 |
+
top = "\u23a4";
|
| 199 |
+
repeat = bottom = "\u23a5";
|
| 200 |
+
font = "Size4-Regular";
|
| 201 |
+
} else if (delim === "(") {
|
| 202 |
+
top = "\u239b";
|
| 203 |
+
repeat = "\u239c";
|
| 204 |
+
bottom = "\u239d";
|
| 205 |
+
font = "Size4-Regular";
|
| 206 |
+
} else if (delim === ")") {
|
| 207 |
+
top = "\u239e";
|
| 208 |
+
repeat = "\u239f";
|
| 209 |
+
bottom = "\u23a0";
|
| 210 |
+
font = "Size4-Regular";
|
| 211 |
+
} else if (delim === "\\{" || delim === "\\lbrace") {
|
| 212 |
+
top = "\u23a7";
|
| 213 |
+
middle = "\u23a8";
|
| 214 |
+
bottom = "\u23a9";
|
| 215 |
+
repeat = "\u23aa";
|
| 216 |
+
font = "Size4-Regular";
|
| 217 |
+
} else if (delim === "\\}" || delim === "\\rbrace") {
|
| 218 |
+
top = "\u23ab";
|
| 219 |
+
middle = "\u23ac";
|
| 220 |
+
bottom = "\u23ad";
|
| 221 |
+
repeat = "\u23aa";
|
| 222 |
+
font = "Size4-Regular";
|
| 223 |
+
} else if (delim === "\\lgroup") {
|
| 224 |
+
top = "\u23a7";
|
| 225 |
+
bottom = "\u23a9";
|
| 226 |
+
repeat = "\u23aa";
|
| 227 |
+
font = "Size4-Regular";
|
| 228 |
+
} else if (delim === "\\rgroup") {
|
| 229 |
+
top = "\u23ab";
|
| 230 |
+
bottom = "\u23ad";
|
| 231 |
+
repeat = "\u23aa";
|
| 232 |
+
font = "Size4-Regular";
|
| 233 |
+
} else if (delim === "\\lmoustache") {
|
| 234 |
+
top = "\u23a7";
|
| 235 |
+
bottom = "\u23ad";
|
| 236 |
+
repeat = "\u23aa";
|
| 237 |
+
font = "Size4-Regular";
|
| 238 |
+
} else if (delim === "\\rmoustache") {
|
| 239 |
+
top = "\u23ab";
|
| 240 |
+
bottom = "\u23a9";
|
| 241 |
+
repeat = "\u23aa";
|
| 242 |
+
font = "Size4-Regular";
|
| 243 |
+
} else if (delim === "\\surd") {
|
| 244 |
+
top = "\ue001";
|
| 245 |
+
bottom = "\u23b7";
|
| 246 |
+
repeat = "\ue000";
|
| 247 |
+
font = "Size4-Regular";
|
| 248 |
+
}
|
| 249 |
+
|
| 250 |
+
// Get the metrics of the four sections
|
| 251 |
+
var topMetrics = getMetrics(top, font);
|
| 252 |
+
var topHeightTotal = topMetrics.height + topMetrics.depth;
|
| 253 |
+
var repeatMetrics = getMetrics(repeat, font);
|
| 254 |
+
var repeatHeightTotal = repeatMetrics.height + repeatMetrics.depth;
|
| 255 |
+
var bottomMetrics = getMetrics(bottom, font);
|
| 256 |
+
var bottomHeightTotal = bottomMetrics.height + bottomMetrics.depth;
|
| 257 |
+
var middleHeightTotal = 0;
|
| 258 |
+
var middleFactor = 1;
|
| 259 |
+
if (middle !== null) {
|
| 260 |
+
var middleMetrics = getMetrics(middle, font);
|
| 261 |
+
middleHeightTotal = middleMetrics.height + middleMetrics.depth;
|
| 262 |
+
middleFactor = 2; // repeat symmetrically above and below middle
|
| 263 |
+
}
|
| 264 |
+
|
| 265 |
+
// Calcuate the minimal height that the delimiter can have.
|
| 266 |
+
// It is at least the size of the top, bottom, and optional middle combined.
|
| 267 |
+
var minHeight = topHeightTotal + bottomHeightTotal + middleHeightTotal;
|
| 268 |
+
|
| 269 |
+
// Compute the number of copies of the repeat symbol we will need
|
| 270 |
+
var repeatCount = Math.ceil(
|
| 271 |
+
(heightTotal - minHeight) / (middleFactor * repeatHeightTotal));
|
| 272 |
+
|
| 273 |
+
// Compute the total height of the delimiter including all the symbols
|
| 274 |
+
var realHeightTotal =
|
| 275 |
+
minHeight + repeatCount * middleFactor * repeatHeightTotal;
|
| 276 |
+
|
| 277 |
+
// The center of the delimiter is placed at the center of the axis. Note
|
| 278 |
+
// that in this context, "center" means that the delimiter should be
|
| 279 |
+
// centered around the axis in the current style, while normally it is
|
| 280 |
+
// centered around the axis in textstyle.
|
| 281 |
+
var axisHeight = fontMetrics.metrics.axisHeight;
|
| 282 |
+
if (center) {
|
| 283 |
+
axisHeight *= options.style.sizeMultiplier;
|
| 284 |
+
}
|
| 285 |
+
// Calculate the depth
|
| 286 |
+
var depth = realHeightTotal / 2 - axisHeight;
|
| 287 |
+
|
| 288 |
+
// Now, we start building the pieces that will go into the vlist
|
| 289 |
+
|
| 290 |
+
// Keep a list of the inner pieces
|
| 291 |
+
var inners = [];
|
| 292 |
+
|
| 293 |
+
// Add the bottom symbol
|
| 294 |
+
inners.push(makeInner(bottom, font, mode));
|
| 295 |
+
|
| 296 |
+
var i;
|
| 297 |
+
if (middle === null) {
|
| 298 |
+
// Add that many symbols
|
| 299 |
+
for (i = 0; i < repeatCount; i++) {
|
| 300 |
+
inners.push(makeInner(repeat, font, mode));
|
| 301 |
+
}
|
| 302 |
+
} else {
|
| 303 |
+
// When there is a middle bit, we need the middle part and two repeated
|
| 304 |
+
// sections
|
| 305 |
+
for (i = 0; i < repeatCount; i++) {
|
| 306 |
+
inners.push(makeInner(repeat, font, mode));
|
| 307 |
+
}
|
| 308 |
+
inners.push(makeInner(middle, font, mode));
|
| 309 |
+
for (i = 0; i < repeatCount; i++) {
|
| 310 |
+
inners.push(makeInner(repeat, font, mode));
|
| 311 |
+
}
|
| 312 |
+
}
|
| 313 |
+
|
| 314 |
+
// Add the top symbol
|
| 315 |
+
inners.push(makeInner(top, font, mode));
|
| 316 |
+
|
| 317 |
+
// Finally, build the vlist
|
| 318 |
+
var inner = buildCommon.makeVList(inners, "bottom", depth, options);
|
| 319 |
+
|
| 320 |
+
return styleWrap(
|
| 321 |
+
makeSpan(["delimsizing", "mult"], [inner], options.getColor()),
|
| 322 |
+
Style.TEXT, options);
|
| 323 |
+
};
|
| 324 |
+
|
| 325 |
+
// There are three kinds of delimiters, delimiters that stack when they become
|
| 326 |
+
// too large
|
| 327 |
+
var stackLargeDelimiters = [
|
| 328 |
+
"(", ")", "[", "\\lbrack", "]", "\\rbrack",
|
| 329 |
+
"\\{", "\\lbrace", "\\}", "\\rbrace",
|
| 330 |
+
"\\lfloor", "\\rfloor", "\\lceil", "\\rceil",
|
| 331 |
+
"\\surd",
|
| 332 |
+
];
|
| 333 |
+
|
| 334 |
+
// delimiters that always stack
|
| 335 |
+
var stackAlwaysDelimiters = [
|
| 336 |
+
"\\uparrow", "\\downarrow", "\\updownarrow",
|
| 337 |
+
"\\Uparrow", "\\Downarrow", "\\Updownarrow",
|
| 338 |
+
"|", "\\|", "\\vert", "\\Vert",
|
| 339 |
+
"\\lvert", "\\rvert", "\\lVert", "\\rVert",
|
| 340 |
+
"\\lgroup", "\\rgroup", "\\lmoustache", "\\rmoustache",
|
| 341 |
+
];
|
| 342 |
+
|
| 343 |
+
// and delimiters that never stack
|
| 344 |
+
var stackNeverDelimiters = [
|
| 345 |
+
"<", ">", "\\langle", "\\rangle", "/", "\\backslash", "\\lt", "\\gt",
|
| 346 |
+
];
|
| 347 |
+
|
| 348 |
+
// Metrics of the different sizes. Found by looking at TeX's output of
|
| 349 |
+
// $\bigl| // \Bigl| \biggl| \Biggl| \showlists$
|
| 350 |
+
// Used to create stacked delimiters of appropriate sizes in makeSizedDelim.
|
| 351 |
+
var sizeToMaxHeight = [0, 1.2, 1.8, 2.4, 3.0];
|
| 352 |
+
|
| 353 |
+
/**
|
| 354 |
+
* Used to create a delimiter of a specific size, where `size` is 1, 2, 3, or 4.
|
| 355 |
+
*/
|
| 356 |
+
var makeSizedDelim = function(delim, size, options, mode) {
|
| 357 |
+
// < and > turn into \langle and \rangle in delimiters
|
| 358 |
+
if (delim === "<" || delim === "\\lt") {
|
| 359 |
+
delim = "\\langle";
|
| 360 |
+
} else if (delim === ">" || delim === "\\gt") {
|
| 361 |
+
delim = "\\rangle";
|
| 362 |
+
}
|
| 363 |
+
|
| 364 |
+
// Sized delimiters are never centered.
|
| 365 |
+
if (utils.contains(stackLargeDelimiters, delim) ||
|
| 366 |
+
utils.contains(stackNeverDelimiters, delim)) {
|
| 367 |
+
return makeLargeDelim(delim, size, false, options, mode);
|
| 368 |
+
} else if (utils.contains(stackAlwaysDelimiters, delim)) {
|
| 369 |
+
return makeStackedDelim(
|
| 370 |
+
delim, sizeToMaxHeight[size], false, options, mode);
|
| 371 |
+
} else {
|
| 372 |
+
throw new ParseError("Illegal delimiter: '" + delim + "'");
|
| 373 |
+
}
|
| 374 |
+
};
|
| 375 |
+
|
| 376 |
+
/**
|
| 377 |
+
* There are three different sequences of delimiter sizes that the delimiters
|
| 378 |
+
* follow depending on the kind of delimiter. This is used when creating custom
|
| 379 |
+
* sized delimiters to decide whether to create a small, large, or stacked
|
| 380 |
+
* delimiter.
|
| 381 |
+
*
|
| 382 |
+
* In real TeX, these sequences aren't explicitly defined, but are instead
|
| 383 |
+
* defined inside the font metrics. Since there are only three sequences that
|
| 384 |
+
* are possible for the delimiters that TeX defines, it is easier to just encode
|
| 385 |
+
* them explicitly here.
|
| 386 |
+
*/
|
| 387 |
+
|
| 388 |
+
// Delimiters that never stack try small delimiters and large delimiters only
|
| 389 |
+
var stackNeverDelimiterSequence = [
|
| 390 |
+
{type: "small", style: Style.SCRIPTSCRIPT},
|
| 391 |
+
{type: "small", style: Style.SCRIPT},
|
| 392 |
+
{type: "small", style: Style.TEXT},
|
| 393 |
+
{type: "large", size: 1},
|
| 394 |
+
{type: "large", size: 2},
|
| 395 |
+
{type: "large", size: 3},
|
| 396 |
+
{type: "large", size: 4},
|
| 397 |
+
];
|
| 398 |
+
|
| 399 |
+
// Delimiters that always stack try the small delimiters first, then stack
|
| 400 |
+
var stackAlwaysDelimiterSequence = [
|
| 401 |
+
{type: "small", style: Style.SCRIPTSCRIPT},
|
| 402 |
+
{type: "small", style: Style.SCRIPT},
|
| 403 |
+
{type: "small", style: Style.TEXT},
|
| 404 |
+
{type: "stack"},
|
| 405 |
+
];
|
| 406 |
+
|
| 407 |
+
// Delimiters that stack when large try the small and then large delimiters, and
|
| 408 |
+
// stack afterwards
|
| 409 |
+
var stackLargeDelimiterSequence = [
|
| 410 |
+
{type: "small", style: Style.SCRIPTSCRIPT},
|
| 411 |
+
{type: "small", style: Style.SCRIPT},
|
| 412 |
+
{type: "small", style: Style.TEXT},
|
| 413 |
+
{type: "large", size: 1},
|
| 414 |
+
{type: "large", size: 2},
|
| 415 |
+
{type: "large", size: 3},
|
| 416 |
+
{type: "large", size: 4},
|
| 417 |
+
{type: "stack"},
|
| 418 |
+
];
|
| 419 |
+
|
| 420 |
+
/**
|
| 421 |
+
* Get the font used in a delimiter based on what kind of delimiter it is.
|
| 422 |
+
*/
|
| 423 |
+
var delimTypeToFont = function(type) {
|
| 424 |
+
if (type.type === "small") {
|
| 425 |
+
return "Main-Regular";
|
| 426 |
+
} else if (type.type === "large") {
|
| 427 |
+
return "Size" + type.size + "-Regular";
|
| 428 |
+
} else if (type.type === "stack") {
|
| 429 |
+
return "Size4-Regular";
|
| 430 |
+
}
|
| 431 |
+
};
|
| 432 |
+
|
| 433 |
+
/**
|
| 434 |
+
* Traverse a sequence of types of delimiters to decide what kind of delimiter
|
| 435 |
+
* should be used to create a delimiter of the given height+depth.
|
| 436 |
+
*/
|
| 437 |
+
var traverseSequence = function(delim, height, sequence, options) {
|
| 438 |
+
// Here, we choose the index we should start at in the sequences. In smaller
|
| 439 |
+
// sizes (which correspond to larger numbers in style.size) we start earlier
|
| 440 |
+
// in the sequence. Thus, scriptscript starts at index 3-3=0, script starts
|
| 441 |
+
// at index 3-2=1, text starts at 3-1=2, and display starts at min(2,3-0)=2
|
| 442 |
+
var start = Math.min(2, 3 - options.style.size);
|
| 443 |
+
for (var i = start; i < sequence.length; i++) {
|
| 444 |
+
if (sequence[i].type === "stack") {
|
| 445 |
+
// This is always the last delimiter, so we just break the loop now.
|
| 446 |
+
break;
|
| 447 |
+
}
|
| 448 |
+
|
| 449 |
+
var metrics = getMetrics(delim, delimTypeToFont(sequence[i]));
|
| 450 |
+
var heightDepth = metrics.height + metrics.depth;
|
| 451 |
+
|
| 452 |
+
// Small delimiters are scaled down versions of the same font, so we
|
| 453 |
+
// account for the style change size.
|
| 454 |
+
|
| 455 |
+
if (sequence[i].type === "small") {
|
| 456 |
+
heightDepth *= sequence[i].style.sizeMultiplier;
|
| 457 |
+
}
|
| 458 |
+
|
| 459 |
+
// Check if the delimiter at this size works for the given height.
|
| 460 |
+
if (heightDepth > height) {
|
| 461 |
+
return sequence[i];
|
| 462 |
+
}
|
| 463 |
+
}
|
| 464 |
+
|
| 465 |
+
// If we reached the end of the sequence, return the last sequence element.
|
| 466 |
+
return sequence[sequence.length - 1];
|
| 467 |
+
};
|
| 468 |
+
|
| 469 |
+
/**
|
| 470 |
+
* Make a delimiter of a given height+depth, with optional centering. Here, we
|
| 471 |
+
* traverse the sequences, and create a delimiter that the sequence tells us to.
|
| 472 |
+
*/
|
| 473 |
+
var makeCustomSizedDelim = function(delim, height, center, options, mode) {
|
| 474 |
+
if (delim === "<" || delim === "\\lt") {
|
| 475 |
+
delim = "\\langle";
|
| 476 |
+
} else if (delim === ">" || delim === "\\gt") {
|
| 477 |
+
delim = "\\rangle";
|
| 478 |
+
}
|
| 479 |
+
|
| 480 |
+
// Decide what sequence to use
|
| 481 |
+
var sequence;
|
| 482 |
+
if (utils.contains(stackNeverDelimiters, delim)) {
|
| 483 |
+
sequence = stackNeverDelimiterSequence;
|
| 484 |
+
} else if (utils.contains(stackLargeDelimiters, delim)) {
|
| 485 |
+
sequence = stackLargeDelimiterSequence;
|
| 486 |
+
} else {
|
| 487 |
+
sequence = stackAlwaysDelimiterSequence;
|
| 488 |
+
}
|
| 489 |
+
|
| 490 |
+
// Look through the sequence
|
| 491 |
+
var delimType = traverseSequence(delim, height, sequence, options);
|
| 492 |
+
|
| 493 |
+
// Depending on the sequence element we decided on, call the appropriate
|
| 494 |
+
// function.
|
| 495 |
+
if (delimType.type === "small") {
|
| 496 |
+
return makeSmallDelim(delim, delimType.style, center, options, mode);
|
| 497 |
+
} else if (delimType.type === "large") {
|
| 498 |
+
return makeLargeDelim(delim, delimType.size, center, options, mode);
|
| 499 |
+
} else if (delimType.type === "stack") {
|
| 500 |
+
return makeStackedDelim(delim, height, center, options, mode);
|
| 501 |
+
}
|
| 502 |
+
};
|
| 503 |
+
|
| 504 |
+
/**
|
| 505 |
+
* Make a delimiter for use with `\left` and `\right`, given a height and depth
|
| 506 |
+
* of an expression that the delimiters surround.
|
| 507 |
+
*/
|
| 508 |
+
var makeLeftRightDelim = function(delim, height, depth, options, mode) {
|
| 509 |
+
// We always center \left/\right delimiters, so the axis is always shifted
|
| 510 |
+
var axisHeight =
|
| 511 |
+
fontMetrics.metrics.axisHeight * options.style.sizeMultiplier;
|
| 512 |
+
|
| 513 |
+
// Taken from TeX source, tex.web, function make_left_right
|
| 514 |
+
var delimiterFactor = 901;
|
| 515 |
+
var delimiterExtend = 5.0 / fontMetrics.metrics.ptPerEm;
|
| 516 |
+
|
| 517 |
+
var maxDistFromAxis = Math.max(
|
| 518 |
+
height - axisHeight, depth + axisHeight);
|
| 519 |
+
|
| 520 |
+
var totalHeight = Math.max(
|
| 521 |
+
// In real TeX, calculations are done using integral values which are
|
| 522 |
+
// 65536 per pt, or 655360 per em. So, the division here truncates in
|
| 523 |
+
// TeX but doesn't here, producing different results. If we wanted to
|
| 524 |
+
// exactly match TeX's calculation, we could do
|
| 525 |
+
// Math.floor(655360 * maxDistFromAxis / 500) *
|
| 526 |
+
// delimiterFactor / 655360
|
| 527 |
+
// (To see the difference, compare
|
| 528 |
+
// x^{x^{\left(\rule{0.1em}{0.68em}\right)}}
|
| 529 |
+
// in TeX and KaTeX)
|
| 530 |
+
maxDistFromAxis / 500 * delimiterFactor,
|
| 531 |
+
2 * maxDistFromAxis - delimiterExtend);
|
| 532 |
+
|
| 533 |
+
// Finally, we defer to `makeCustomSizedDelim` with our calculated total
|
| 534 |
+
// height
|
| 535 |
+
return makeCustomSizedDelim(delim, totalHeight, true, options, mode);
|
| 536 |
+
};
|
| 537 |
+
|
| 538 |
+
module.exports = {
|
| 539 |
+
sizedDelim: makeSizedDelim,
|
| 540 |
+
customSizedDelim: makeCustomSizedDelim,
|
| 541 |
+
leftRightDelim: makeLeftRightDelim,
|
| 542 |
+
};
|
katex/src/domTree.js
ADDED
|
@@ -0,0 +1,269 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
/**
|
| 2 |
+
* These objects store the data about the DOM nodes we create, as well as some
|
| 3 |
+
* extra data. They can then be transformed into real DOM nodes with the
|
| 4 |
+
* `toNode` function or HTML markup using `toMarkup`. They are useful for both
|
| 5 |
+
* storing extra properties on the nodes, as well as providing a way to easily
|
| 6 |
+
* work with the DOM.
|
| 7 |
+
*
|
| 8 |
+
* Similar functions for working with MathML nodes exist in mathMLTree.js.
|
| 9 |
+
*/
|
| 10 |
+
|
| 11 |
+
var utils = require("./utils");
|
| 12 |
+
|
| 13 |
+
/**
|
| 14 |
+
* Create an HTML className based on a list of classes. In addition to joining
|
| 15 |
+
* with spaces, we also remove null or empty classes.
|
| 16 |
+
*/
|
| 17 |
+
var createClass = function(classes) {
|
| 18 |
+
classes = classes.slice();
|
| 19 |
+
for (var i = classes.length - 1; i >= 0; i--) {
|
| 20 |
+
if (!classes[i]) {
|
| 21 |
+
classes.splice(i, 1);
|
| 22 |
+
}
|
| 23 |
+
}
|
| 24 |
+
|
| 25 |
+
return classes.join(" ");
|
| 26 |
+
};
|
| 27 |
+
|
| 28 |
+
/**
|
| 29 |
+
* This node represents a span node, with a className, a list of children, and
|
| 30 |
+
* an inline style. It also contains information about its height, depth, and
|
| 31 |
+
* maxFontSize.
|
| 32 |
+
*/
|
| 33 |
+
function span(classes, children, height, depth, maxFontSize, style) {
|
| 34 |
+
this.classes = classes || [];
|
| 35 |
+
this.children = children || [];
|
| 36 |
+
this.height = height || 0;
|
| 37 |
+
this.depth = depth || 0;
|
| 38 |
+
this.maxFontSize = maxFontSize || 0;
|
| 39 |
+
this.style = style || {};
|
| 40 |
+
this.attributes = {};
|
| 41 |
+
}
|
| 42 |
+
|
| 43 |
+
/**
|
| 44 |
+
* Sets an arbitrary attribute on the span. Warning: use this wisely. Not all
|
| 45 |
+
* browsers support attributes the same, and having too many custom attributes
|
| 46 |
+
* is probably bad.
|
| 47 |
+
*/
|
| 48 |
+
span.prototype.setAttribute = function(attribute, value) {
|
| 49 |
+
this.attributes[attribute] = value;
|
| 50 |
+
};
|
| 51 |
+
|
| 52 |
+
/**
|
| 53 |
+
* Convert the span into an HTML node
|
| 54 |
+
*/
|
| 55 |
+
span.prototype.toNode = function() {
|
| 56 |
+
var span = document.createElement("span");
|
| 57 |
+
|
| 58 |
+
// Apply the class
|
| 59 |
+
span.className = createClass(this.classes);
|
| 60 |
+
|
| 61 |
+
// Apply inline styles
|
| 62 |
+
for (var style in this.style) {
|
| 63 |
+
if (Object.prototype.hasOwnProperty.call(this.style, style)) {
|
| 64 |
+
span.style[style] = this.style[style];
|
| 65 |
+
}
|
| 66 |
+
}
|
| 67 |
+
|
| 68 |
+
// Apply attributes
|
| 69 |
+
for (var attr in this.attributes) {
|
| 70 |
+
if (Object.prototype.hasOwnProperty.call(this.attributes, attr)) {
|
| 71 |
+
span.setAttribute(attr, this.attributes[attr]);
|
| 72 |
+
}
|
| 73 |
+
}
|
| 74 |
+
|
| 75 |
+
// Append the children, also as HTML nodes
|
| 76 |
+
for (var i = 0; i < this.children.length; i++) {
|
| 77 |
+
span.appendChild(this.children[i].toNode());
|
| 78 |
+
}
|
| 79 |
+
|
| 80 |
+
return span;
|
| 81 |
+
};
|
| 82 |
+
|
| 83 |
+
/**
|
| 84 |
+
* Convert the span into an HTML markup string
|
| 85 |
+
*/
|
| 86 |
+
span.prototype.toMarkup = function() {
|
| 87 |
+
var markup = "<span";
|
| 88 |
+
|
| 89 |
+
// Add the class
|
| 90 |
+
if (this.classes.length) {
|
| 91 |
+
markup += " class=\"";
|
| 92 |
+
markup += utils.escape(createClass(this.classes));
|
| 93 |
+
markup += "\"";
|
| 94 |
+
}
|
| 95 |
+
|
| 96 |
+
var styles = "";
|
| 97 |
+
|
| 98 |
+
// Add the styles, after hyphenation
|
| 99 |
+
for (var style in this.style) {
|
| 100 |
+
if (this.style.hasOwnProperty(style)) {
|
| 101 |
+
styles += utils.hyphenate(style) + ":" + this.style[style] + ";";
|
| 102 |
+
}
|
| 103 |
+
}
|
| 104 |
+
|
| 105 |
+
if (styles) {
|
| 106 |
+
markup += " style=\"" + utils.escape(styles) + "\"";
|
| 107 |
+
}
|
| 108 |
+
|
| 109 |
+
// Add the attributes
|
| 110 |
+
for (var attr in this.attributes) {
|
| 111 |
+
if (Object.prototype.hasOwnProperty.call(this.attributes, attr)) {
|
| 112 |
+
markup += " " + attr + "=\"";
|
| 113 |
+
markup += utils.escape(this.attributes[attr]);
|
| 114 |
+
markup += "\"";
|
| 115 |
+
}
|
| 116 |
+
}
|
| 117 |
+
|
| 118 |
+
markup += ">";
|
| 119 |
+
|
| 120 |
+
// Add the markup of the children, also as markup
|
| 121 |
+
for (var i = 0; i < this.children.length; i++) {
|
| 122 |
+
markup += this.children[i].toMarkup();
|
| 123 |
+
}
|
| 124 |
+
|
| 125 |
+
markup += "</span>";
|
| 126 |
+
|
| 127 |
+
return markup;
|
| 128 |
+
};
|
| 129 |
+
|
| 130 |
+
/**
|
| 131 |
+
* This node represents a document fragment, which contains elements, but when
|
| 132 |
+
* placed into the DOM doesn't have any representation itself. Thus, it only
|
| 133 |
+
* contains children and doesn't have any HTML properties. It also keeps track
|
| 134 |
+
* of a height, depth, and maxFontSize.
|
| 135 |
+
*/
|
| 136 |
+
function documentFragment(children, height, depth, maxFontSize) {
|
| 137 |
+
this.children = children || [];
|
| 138 |
+
this.height = height || 0;
|
| 139 |
+
this.depth = depth || 0;
|
| 140 |
+
this.maxFontSize = maxFontSize || 0;
|
| 141 |
+
}
|
| 142 |
+
|
| 143 |
+
/**
|
| 144 |
+
* Convert the fragment into a node
|
| 145 |
+
*/
|
| 146 |
+
documentFragment.prototype.toNode = function() {
|
| 147 |
+
// Create a fragment
|
| 148 |
+
var frag = document.createDocumentFragment();
|
| 149 |
+
|
| 150 |
+
// Append the children
|
| 151 |
+
for (var i = 0; i < this.children.length; i++) {
|
| 152 |
+
frag.appendChild(this.children[i].toNode());
|
| 153 |
+
}
|
| 154 |
+
|
| 155 |
+
return frag;
|
| 156 |
+
};
|
| 157 |
+
|
| 158 |
+
/**
|
| 159 |
+
* Convert the fragment into HTML markup
|
| 160 |
+
*/
|
| 161 |
+
documentFragment.prototype.toMarkup = function() {
|
| 162 |
+
var markup = "";
|
| 163 |
+
|
| 164 |
+
// Simply concatenate the markup for the children together
|
| 165 |
+
for (var i = 0; i < this.children.length; i++) {
|
| 166 |
+
markup += this.children[i].toMarkup();
|
| 167 |
+
}
|
| 168 |
+
|
| 169 |
+
return markup;
|
| 170 |
+
};
|
| 171 |
+
|
| 172 |
+
/**
|
| 173 |
+
* A symbol node contains information about a single symbol. It either renders
|
| 174 |
+
* to a single text node, or a span with a single text node in it, depending on
|
| 175 |
+
* whether it has CSS classes, styles, or needs italic correction.
|
| 176 |
+
*/
|
| 177 |
+
function symbolNode(value, height, depth, italic, skew, classes, style) {
|
| 178 |
+
this.value = value || "";
|
| 179 |
+
this.height = height || 0;
|
| 180 |
+
this.depth = depth || 0;
|
| 181 |
+
this.italic = italic || 0;
|
| 182 |
+
this.skew = skew || 0;
|
| 183 |
+
this.classes = classes || [];
|
| 184 |
+
this.style = style || {};
|
| 185 |
+
this.maxFontSize = 0;
|
| 186 |
+
}
|
| 187 |
+
|
| 188 |
+
/**
|
| 189 |
+
* Creates a text node or span from a symbol node. Note that a span is only
|
| 190 |
+
* created if it is needed.
|
| 191 |
+
*/
|
| 192 |
+
symbolNode.prototype.toNode = function() {
|
| 193 |
+
var node = document.createTextNode(this.value);
|
| 194 |
+
var span = null;
|
| 195 |
+
|
| 196 |
+
if (this.italic > 0) {
|
| 197 |
+
span = document.createElement("span");
|
| 198 |
+
span.style.marginRight = this.italic + "em";
|
| 199 |
+
}
|
| 200 |
+
|
| 201 |
+
if (this.classes.length > 0) {
|
| 202 |
+
span = span || document.createElement("span");
|
| 203 |
+
span.className = createClass(this.classes);
|
| 204 |
+
}
|
| 205 |
+
|
| 206 |
+
for (var style in this.style) {
|
| 207 |
+
if (this.style.hasOwnProperty(style)) {
|
| 208 |
+
span = span || document.createElement("span");
|
| 209 |
+
span.style[style] = this.style[style];
|
| 210 |
+
}
|
| 211 |
+
}
|
| 212 |
+
|
| 213 |
+
if (span) {
|
| 214 |
+
span.appendChild(node);
|
| 215 |
+
return span;
|
| 216 |
+
} else {
|
| 217 |
+
return node;
|
| 218 |
+
}
|
| 219 |
+
};
|
| 220 |
+
|
| 221 |
+
/**
|
| 222 |
+
* Creates markup for a symbol node.
|
| 223 |
+
*/
|
| 224 |
+
symbolNode.prototype.toMarkup = function() {
|
| 225 |
+
// TODO(alpert): More duplication than I'd like from
|
| 226 |
+
// span.prototype.toMarkup and symbolNode.prototype.toNode...
|
| 227 |
+
var needsSpan = false;
|
| 228 |
+
|
| 229 |
+
var markup = "<span";
|
| 230 |
+
|
| 231 |
+
if (this.classes.length) {
|
| 232 |
+
needsSpan = true;
|
| 233 |
+
markup += " class=\"";
|
| 234 |
+
markup += utils.escape(createClass(this.classes));
|
| 235 |
+
markup += "\"";
|
| 236 |
+
}
|
| 237 |
+
|
| 238 |
+
var styles = "";
|
| 239 |
+
|
| 240 |
+
if (this.italic > 0) {
|
| 241 |
+
styles += "margin-right:" + this.italic + "em;";
|
| 242 |
+
}
|
| 243 |
+
for (var style in this.style) {
|
| 244 |
+
if (this.style.hasOwnProperty(style)) {
|
| 245 |
+
styles += utils.hyphenate(style) + ":" + this.style[style] + ";";
|
| 246 |
+
}
|
| 247 |
+
}
|
| 248 |
+
|
| 249 |
+
if (styles) {
|
| 250 |
+
needsSpan = true;
|
| 251 |
+
markup += " style=\"" + utils.escape(styles) + "\"";
|
| 252 |
+
}
|
| 253 |
+
|
| 254 |
+
var escaped = utils.escape(this.value);
|
| 255 |
+
if (needsSpan) {
|
| 256 |
+
markup += ">";
|
| 257 |
+
markup += escaped;
|
| 258 |
+
markup += "</span>";
|
| 259 |
+
return markup;
|
| 260 |
+
} else {
|
| 261 |
+
return escaped;
|
| 262 |
+
}
|
| 263 |
+
};
|
| 264 |
+
|
| 265 |
+
module.exports = {
|
| 266 |
+
span: span,
|
| 267 |
+
documentFragment: documentFragment,
|
| 268 |
+
symbolNode: symbolNode,
|
| 269 |
+
};
|
katex/src/environments.js
ADDED
|
@@ -0,0 +1,298 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
/* eslint no-constant-condition:0 */
|
| 2 |
+
var fontMetrics = require("./fontMetrics");
|
| 3 |
+
var parseData = require("./parseData");
|
| 4 |
+
var ParseError = require("./ParseError");
|
| 5 |
+
|
| 6 |
+
var ParseNode = parseData.ParseNode;
|
| 7 |
+
|
| 8 |
+
/**
|
| 9 |
+
* Parse the body of the environment, with rows delimited by \\ and
|
| 10 |
+
* columns delimited by &, and create a nested list in row-major order
|
| 11 |
+
* with one group per cell.
|
| 12 |
+
*/
|
| 13 |
+
var q = 0 ;
|
| 14 |
+
function parseArray(parser, result) {
|
| 15 |
+
var row = [];
|
| 16 |
+
var body = [row];
|
| 17 |
+
var rowGaps = [];
|
| 18 |
+
|
| 19 |
+
while (true) {
|
| 20 |
+
|
| 21 |
+
// if (q == 1) console.error(parser.nextToken.text);
|
| 22 |
+
try {
|
| 23 |
+
var cell = parser.parseExpression(false, null);
|
| 24 |
+
} catch (e) {
|
| 25 |
+
// console.error(e);
|
| 26 |
+
exit();
|
| 27 |
+
}
|
| 28 |
+
// if (q == 1) exit();
|
| 29 |
+
row.push(new ParseNode("ordgroup", cell, parser.mode));
|
| 30 |
+
var next = parser.nextToken.text;
|
| 31 |
+
if (next === "&") {
|
| 32 |
+
parser.consume();
|
| 33 |
+
} else if (next === "\\end" || next == "}") {
|
| 34 |
+
break;
|
| 35 |
+
} else if (next === "\\\\" || next === "\\cr") {
|
| 36 |
+
var cr = parser.parseFunction();
|
| 37 |
+
rowGaps.push(cr.value.size);
|
| 38 |
+
row = [];
|
| 39 |
+
body.push(row);
|
| 40 |
+
} else {
|
| 41 |
+
// TODO: Clean up the following hack once #385 got merged
|
| 42 |
+
var pos = Math.min(parser.pos + 1, parser.lexer._input.length);
|
| 43 |
+
throw new ParseError("Expected & or \\\\ or \\end",
|
| 44 |
+
parser.lexer, pos);
|
| 45 |
+
}
|
| 46 |
+
}
|
| 47 |
+
result.body = body;
|
| 48 |
+
result.rowGaps = rowGaps;
|
| 49 |
+
// if (q == 1) exit();
|
| 50 |
+
var node = new ParseNode(result.type, result, parser.mode);
|
| 51 |
+
return node;
|
| 52 |
+
}
|
| 53 |
+
|
| 54 |
+
/*
|
| 55 |
+
* An environment definition is very similar to a function definition:
|
| 56 |
+
* it is declared with a name or a list of names, a set of properties
|
| 57 |
+
* and a handler containing the actual implementation.
|
| 58 |
+
*
|
| 59 |
+
* The properties include:
|
| 60 |
+
* - numArgs: The number of arguments after the \begin{name} function.
|
| 61 |
+
* - argTypes: (optional) Just like for a function
|
| 62 |
+
* - allowedInText: (optional) Whether or not the environment is allowed inside
|
| 63 |
+
* text mode (default false) (not enforced yet)
|
| 64 |
+
* - numOptionalArgs: (optional) Just like for a function
|
| 65 |
+
* A bare number instead of that object indicates the numArgs value.
|
| 66 |
+
*
|
| 67 |
+
* The handler function will receive two arguments
|
| 68 |
+
* - context: information and references provided by the parser
|
| 69 |
+
* - args: an array of arguments passed to \begin{name}
|
| 70 |
+
* The context contains the following properties:
|
| 71 |
+
* - envName: the name of the environment, one of the listed names.
|
| 72 |
+
* - parser: the parser object
|
| 73 |
+
* - lexer: the lexer object
|
| 74 |
+
* - positions: the positions associated with these arguments from args.
|
| 75 |
+
* The handler must return a ParseResult.
|
| 76 |
+
*/
|
| 77 |
+
|
| 78 |
+
function defineEnvironment(names, props, handler) {
|
| 79 |
+
if (typeof names === "string") {
|
| 80 |
+
names = [names];
|
| 81 |
+
}
|
| 82 |
+
if (typeof props === "number") {
|
| 83 |
+
props = { numArgs: props };
|
| 84 |
+
}
|
| 85 |
+
// Set default values of environments
|
| 86 |
+
var data = {
|
| 87 |
+
numArgs: props.numArgs || 0,
|
| 88 |
+
argTypes: props.argTypes,
|
| 89 |
+
greediness: 1,
|
| 90 |
+
allowedInText: !!props.allowedInText,
|
| 91 |
+
numOptionalArgs: props.numOptionalArgs || 0,
|
| 92 |
+
handler: handler,
|
| 93 |
+
};
|
| 94 |
+
for (var i = 0; i < names.length; ++i) {
|
| 95 |
+
module.exports[names[i]] = data;
|
| 96 |
+
}
|
| 97 |
+
}
|
| 98 |
+
|
| 99 |
+
// Arrays are part of LaTeX, defined in lttab.dtx so its documentation
|
| 100 |
+
// is part of the source2e.pdf file of LaTeX2e source documentation.
|
| 101 |
+
defineEnvironment("array", {
|
| 102 |
+
numArgs: 1,
|
| 103 |
+
}, function(context, args) {
|
| 104 |
+
var colalign = args[0];
|
| 105 |
+
colalign = colalign.value.map ? colalign.value : [colalign];
|
| 106 |
+
var cols = colalign.map(function(node) {
|
| 107 |
+
var ca = node.value;
|
| 108 |
+
if ("lcr".indexOf(ca) !== -1) {
|
| 109 |
+
return {
|
| 110 |
+
type: "align",
|
| 111 |
+
align: ca,
|
| 112 |
+
};
|
| 113 |
+
} else if (ca === "|") {
|
| 114 |
+
return {
|
| 115 |
+
type: "separator",
|
| 116 |
+
separator: "|",
|
| 117 |
+
};
|
| 118 |
+
}
|
| 119 |
+
// throw new ParseError(
|
| 120 |
+
// "Unknown column alignment: " + node.value,
|
| 121 |
+
// context.lexer, context.positions[1]);
|
| 122 |
+
});
|
| 123 |
+
var res = {
|
| 124 |
+
type: "array",
|
| 125 |
+
style: "array",
|
| 126 |
+
cols: cols,
|
| 127 |
+
hskipBeforeAndAfter: true, // \@preamble in lttab.dtx
|
| 128 |
+
};
|
| 129 |
+
res = parseArray(context.parser, res);
|
| 130 |
+
return res;
|
| 131 |
+
});
|
| 132 |
+
|
| 133 |
+
defineEnvironment("tabular", {
|
| 134 |
+
numArgs: 1,
|
| 135 |
+
}, function(context, args) {
|
| 136 |
+
var colalign = args[0];
|
| 137 |
+
colalign = colalign.value.map ? colalign.value : [colalign];
|
| 138 |
+
var cols = colalign.map(function(node) {
|
| 139 |
+
var ca = node.value;
|
| 140 |
+
if ("lcr".indexOf(ca) !== -1) {
|
| 141 |
+
return {
|
| 142 |
+
type: "align",
|
| 143 |
+
align: ca,
|
| 144 |
+
};
|
| 145 |
+
} else if (ca === "|") {
|
| 146 |
+
return {
|
| 147 |
+
type: "separator",
|
| 148 |
+
separator: "|",
|
| 149 |
+
};
|
| 150 |
+
}
|
| 151 |
+
// throw new ParseError(
|
| 152 |
+
// "Unknown column alignment: " + node.value,
|
| 153 |
+
// context.lexer, context.positions[1]);
|
| 154 |
+
});
|
| 155 |
+
var res = {
|
| 156 |
+
type: "array",
|
| 157 |
+
style: "tabular",
|
| 158 |
+
cols: cols,
|
| 159 |
+
hskipBeforeAndAfter: true, // \@preamble in lttab.dtx
|
| 160 |
+
};
|
| 161 |
+
res = parseArray(context.parser, res);
|
| 162 |
+
return res;
|
| 163 |
+
});
|
| 164 |
+
|
| 165 |
+
// The matrix environments of amsmath builds on the array environment
|
| 166 |
+
// of LaTeX, which is discussed above.
|
| 167 |
+
defineEnvironment([
|
| 168 |
+
"matrix",
|
| 169 |
+
"pmatrix",
|
| 170 |
+
"bmatrix",
|
| 171 |
+
"Bmatrix",
|
| 172 |
+
"vmatrix",
|
| 173 |
+
"Vmatrix",
|
| 174 |
+
], {
|
| 175 |
+
}, function(context) {
|
| 176 |
+
var delimiters = {
|
| 177 |
+
"matrix": null,
|
| 178 |
+
"pmatrix": ["(", ")"],
|
| 179 |
+
"bmatrix": ["[", "]"],
|
| 180 |
+
"Bmatrix": ["\\{", "\\}"],
|
| 181 |
+
"vmatrix": ["|", "|"],
|
| 182 |
+
"Vmatrix": ["\\Vert", "\\Vert"],
|
| 183 |
+
}[context.envName];
|
| 184 |
+
var res = {
|
| 185 |
+
type: "array",
|
| 186 |
+
style: "matrix",
|
| 187 |
+
hskipBeforeAndAfter: false, // \hskip -\arraycolsep in amsmath
|
| 188 |
+
};
|
| 189 |
+
q = 1;
|
| 190 |
+
res = parseArray(context.parser, res);
|
| 191 |
+
|
| 192 |
+
if (delimiters) {
|
| 193 |
+
res = new ParseNode("leftright", {
|
| 194 |
+
body: [res],
|
| 195 |
+
left: delimiters[0],
|
| 196 |
+
right: delimiters[1],
|
| 197 |
+
}, context.mode);
|
| 198 |
+
}
|
| 199 |
+
return res;
|
| 200 |
+
});
|
| 201 |
+
|
| 202 |
+
// A cases environment (in amsmath.sty) is almost equivalent to
|
| 203 |
+
// \def\arraystretch{1.2}%
|
| 204 |
+
// \left\{\begin{array}{@{}l@{\quad}l@{}} … \end{array}\right.
|
| 205 |
+
defineEnvironment("picture", {
|
| 206 |
+
}, function(context) {
|
| 207 |
+
var res = {
|
| 208 |
+
type: "array",
|
| 209 |
+
style: "picture",
|
| 210 |
+
arraystretch: 1.2,
|
| 211 |
+
cols: [{
|
| 212 |
+
type: "align",
|
| 213 |
+
align: "l",
|
| 214 |
+
pregap: 0,
|
| 215 |
+
postgap: fontMetrics.metrics.quad,
|
| 216 |
+
}, {
|
| 217 |
+
type: "align",
|
| 218 |
+
align: "l",
|
| 219 |
+
pregap: 0,
|
| 220 |
+
postgap: 0,
|
| 221 |
+
}],
|
| 222 |
+
};
|
| 223 |
+
res = parseArray(context.parser, res);
|
| 224 |
+
res = new ParseNode("leftright", {
|
| 225 |
+
body: [res],
|
| 226 |
+
left: "\\{",
|
| 227 |
+
right: ".",
|
| 228 |
+
}, context.mode);
|
| 229 |
+
return res;
|
| 230 |
+
});
|
| 231 |
+
|
| 232 |
+
defineEnvironment("cases", {
|
| 233 |
+
}, function(context) {
|
| 234 |
+
var res = {
|
| 235 |
+
type: "array",
|
| 236 |
+
style: "cases",
|
| 237 |
+
arraystretch: 1.2,
|
| 238 |
+
cols: [{
|
| 239 |
+
type: "align",
|
| 240 |
+
align: "l",
|
| 241 |
+
pregap: 0,
|
| 242 |
+
postgap: fontMetrics.metrics.quad,
|
| 243 |
+
}, {
|
| 244 |
+
type: "align",
|
| 245 |
+
align: "l",
|
| 246 |
+
pregap: 0,
|
| 247 |
+
postgap: 0,
|
| 248 |
+
}],
|
| 249 |
+
};
|
| 250 |
+
res = parseArray(context.parser, res);
|
| 251 |
+
res = new ParseNode("leftright", {
|
| 252 |
+
body: [res],
|
| 253 |
+
left: "\\{",
|
| 254 |
+
right: ".",
|
| 255 |
+
}, context.mode);
|
| 256 |
+
return res;
|
| 257 |
+
});
|
| 258 |
+
|
| 259 |
+
// An aligned environment is like the align* environment
|
| 260 |
+
// except it operates within math mode.
|
| 261 |
+
// Note that we assume \nomallineskiplimit to be zero,
|
| 262 |
+
// so that \strut@ is the same as \strut.
|
| 263 |
+
defineEnvironment("aligned", {
|
| 264 |
+
}, function(context) {
|
| 265 |
+
var res = {
|
| 266 |
+
type: "array",
|
| 267 |
+
style: "aligned",
|
| 268 |
+
cols: [],
|
| 269 |
+
};
|
| 270 |
+
res = parseArray(context.parser, res);
|
| 271 |
+
var emptyGroup = new ParseNode("ordgroup", [], context.mode);
|
| 272 |
+
var numCols = 0;
|
| 273 |
+
res.value.body.forEach(function(row) {
|
| 274 |
+
var i;
|
| 275 |
+
for (i = 1; i < row.length; i += 2) {
|
| 276 |
+
row[i].value.unshift(emptyGroup);
|
| 277 |
+
}
|
| 278 |
+
if (numCols < row.length) {
|
| 279 |
+
numCols = row.length;
|
| 280 |
+
}
|
| 281 |
+
});
|
| 282 |
+
for (var i = 0; i < numCols; ++i) {
|
| 283 |
+
var align = "r";
|
| 284 |
+
var pregap = 0;
|
| 285 |
+
if (i % 2 === 1) {
|
| 286 |
+
align = "l";
|
| 287 |
+
} else if (i > 0) {
|
| 288 |
+
pregap = 2; // one \qquad between columns
|
| 289 |
+
}
|
| 290 |
+
res.value.cols[i] = {
|
| 291 |
+
type: "align",
|
| 292 |
+
align: align,
|
| 293 |
+
pregap: pregap,
|
| 294 |
+
postgap: 0,
|
| 295 |
+
};
|
| 296 |
+
}
|
| 297 |
+
return res;
|
| 298 |
+
});
|
katex/src/fontMetrics.js
ADDED
|
@@ -0,0 +1,147 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
/* eslint no-unused-vars:0 */
|
| 2 |
+
|
| 3 |
+
var Style = require("./Style");
|
| 4 |
+
|
| 5 |
+
/**
|
| 6 |
+
* This file contains metrics regarding fonts and individual symbols. The sigma
|
| 7 |
+
* and xi variables, as well as the metricMap map contain data extracted from
|
| 8 |
+
* TeX, TeX font metrics, and the TTF files. These data are then exposed via the
|
| 9 |
+
* `metrics` variable and the getCharacterMetrics function.
|
| 10 |
+
*/
|
| 11 |
+
|
| 12 |
+
// These font metrics are extracted from TeX by using
|
| 13 |
+
// \font\a=cmmi10
|
| 14 |
+
// \showthe\fontdimenX\a
|
| 15 |
+
// where X is the corresponding variable number. These correspond to the font
|
| 16 |
+
// parameters of the symbol fonts. In TeX, there are actually three sets of
|
| 17 |
+
// dimensions, one for each of textstyle, scriptstyle, and scriptscriptstyle,
|
| 18 |
+
// but we only use the textstyle ones, and scale certain dimensions accordingly.
|
| 19 |
+
// See the TeXbook, page 441.
|
| 20 |
+
var sigma1 = 0.025;
|
| 21 |
+
var sigma2 = 0;
|
| 22 |
+
var sigma3 = 0;
|
| 23 |
+
var sigma4 = 0;
|
| 24 |
+
var sigma5 = 0.431;
|
| 25 |
+
var sigma6 = 1;
|
| 26 |
+
var sigma7 = 0;
|
| 27 |
+
var sigma8 = 0.677;
|
| 28 |
+
var sigma9 = 0.394;
|
| 29 |
+
var sigma10 = 0.444;
|
| 30 |
+
var sigma11 = 0.686;
|
| 31 |
+
var sigma12 = 0.345;
|
| 32 |
+
var sigma13 = 0.413;
|
| 33 |
+
var sigma14 = 0.363;
|
| 34 |
+
var sigma15 = 0.289;
|
| 35 |
+
var sigma16 = 0.150;
|
| 36 |
+
var sigma17 = 0.247;
|
| 37 |
+
var sigma18 = 0.386;
|
| 38 |
+
var sigma19 = 0.050;
|
| 39 |
+
var sigma20 = 2.390;
|
| 40 |
+
var sigma21 = 1.01;
|
| 41 |
+
var sigma21Script = 0.81;
|
| 42 |
+
var sigma21ScriptScript = 0.71;
|
| 43 |
+
var sigma22 = 0.250;
|
| 44 |
+
|
| 45 |
+
// These font metrics are extracted from TeX by using
|
| 46 |
+
// \font\a=cmex10
|
| 47 |
+
// \showthe\fontdimenX\a
|
| 48 |
+
// where X is the corresponding variable number. These correspond to the font
|
| 49 |
+
// parameters of the extension fonts (family 3). See the TeXbook, page 441.
|
| 50 |
+
var xi1 = 0;
|
| 51 |
+
var xi2 = 0;
|
| 52 |
+
var xi3 = 0;
|
| 53 |
+
var xi4 = 0;
|
| 54 |
+
var xi5 = 0.431;
|
| 55 |
+
var xi6 = 1;
|
| 56 |
+
var xi7 = 0;
|
| 57 |
+
var xi8 = 0.04;
|
| 58 |
+
var xi9 = 0.111;
|
| 59 |
+
var xi10 = 0.166;
|
| 60 |
+
var xi11 = 0.2;
|
| 61 |
+
var xi12 = 0.6;
|
| 62 |
+
var xi13 = 0.1;
|
| 63 |
+
|
| 64 |
+
// This value determines how large a pt is, for metrics which are defined in
|
| 65 |
+
// terms of pts.
|
| 66 |
+
// This value is also used in katex.less; if you change it make sure the values
|
| 67 |
+
// match.
|
| 68 |
+
var ptPerEm = 10.0;
|
| 69 |
+
|
| 70 |
+
// The space between adjacent `|` columns in an array definition. From
|
| 71 |
+
// `\showthe\doublerulesep` in LaTeX.
|
| 72 |
+
var doubleRuleSep = 2.0 / ptPerEm;
|
| 73 |
+
|
| 74 |
+
/**
|
| 75 |
+
* This is just a mapping from common names to real metrics
|
| 76 |
+
*/
|
| 77 |
+
var metrics = {
|
| 78 |
+
xHeight: sigma5,
|
| 79 |
+
quad: sigma6,
|
| 80 |
+
num1: sigma8,
|
| 81 |
+
num2: sigma9,
|
| 82 |
+
num3: sigma10,
|
| 83 |
+
denom1: sigma11,
|
| 84 |
+
denom2: sigma12,
|
| 85 |
+
sup1: sigma13,
|
| 86 |
+
sup2: sigma14,
|
| 87 |
+
sup3: sigma15,
|
| 88 |
+
sub1: sigma16,
|
| 89 |
+
sub2: sigma17,
|
| 90 |
+
supDrop: sigma18,
|
| 91 |
+
subDrop: sigma19,
|
| 92 |
+
axisHeight: sigma22,
|
| 93 |
+
defaultRuleThickness: xi8,
|
| 94 |
+
bigOpSpacing1: xi9,
|
| 95 |
+
bigOpSpacing2: xi10,
|
| 96 |
+
bigOpSpacing3: xi11,
|
| 97 |
+
bigOpSpacing4: xi12,
|
| 98 |
+
bigOpSpacing5: xi13,
|
| 99 |
+
ptPerEm: ptPerEm,
|
| 100 |
+
emPerEx: sigma5 / sigma6,
|
| 101 |
+
doubleRuleSep: doubleRuleSep,
|
| 102 |
+
|
| 103 |
+
// TODO(alpert): Missing parallel structure here. We should probably add
|
| 104 |
+
// style-specific metrics for all of these.
|
| 105 |
+
delim1: sigma20,
|
| 106 |
+
getDelim2: function(style) {
|
| 107 |
+
if (style.size === Style.TEXT.size) {
|
| 108 |
+
return sigma21;
|
| 109 |
+
} else if (style.size === Style.SCRIPT.size) {
|
| 110 |
+
return sigma21Script;
|
| 111 |
+
} else if (style.size === Style.SCRIPTSCRIPT.size) {
|
| 112 |
+
return sigma21ScriptScript;
|
| 113 |
+
}
|
| 114 |
+
throw new Error("Unexpected style size: " + style.size);
|
| 115 |
+
},
|
| 116 |
+
};
|
| 117 |
+
|
| 118 |
+
// This map contains a mapping from font name and character code to character
|
| 119 |
+
// metrics, including height, depth, italic correction, and skew (kern from the
|
| 120 |
+
// character to the corresponding \skewchar)
|
| 121 |
+
// This map is generated via `make metrics`. It should not be changed manually.
|
| 122 |
+
var metricMap = require("./fontMetricsData");
|
| 123 |
+
|
| 124 |
+
/**
|
| 125 |
+
* This function is a convenience function for looking up information in the
|
| 126 |
+
* metricMap table. It takes a character as a string, and a style.
|
| 127 |
+
*
|
| 128 |
+
* Note: the `width` property may be undefined if fontMetricsData.js wasn't
|
| 129 |
+
* built using `Make extended_metrics`.
|
| 130 |
+
*/
|
| 131 |
+
var getCharacterMetrics = function(character, style) {
|
| 132 |
+
var metrics = metricMap[style][character.charCodeAt(0)];
|
| 133 |
+
if (metrics) {
|
| 134 |
+
return {
|
| 135 |
+
depth: metrics[0],
|
| 136 |
+
height: metrics[1],
|
| 137 |
+
italic: metrics[2],
|
| 138 |
+
skew: metrics[3],
|
| 139 |
+
width: metrics[4],
|
| 140 |
+
};
|
| 141 |
+
}
|
| 142 |
+
};
|
| 143 |
+
|
| 144 |
+
module.exports = {
|
| 145 |
+
metrics: metrics,
|
| 146 |
+
getCharacterMetrics: getCharacterMetrics,
|
| 147 |
+
};
|
katex/src/fontMetricsData.js
ADDED
|
@@ -0,0 +1,1752 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
module.exports = {
|
| 2 |
+
"AMS-Regular": {
|
| 3 |
+
"65": [0, 0.68889, 0, 0],
|
| 4 |
+
"66": [0, 0.68889, 0, 0],
|
| 5 |
+
"67": [0, 0.68889, 0, 0],
|
| 6 |
+
"68": [0, 0.68889, 0, 0],
|
| 7 |
+
"69": [0, 0.68889, 0, 0],
|
| 8 |
+
"70": [0, 0.68889, 0, 0],
|
| 9 |
+
"71": [0, 0.68889, 0, 0],
|
| 10 |
+
"72": [0, 0.68889, 0, 0],
|
| 11 |
+
"73": [0, 0.68889, 0, 0],
|
| 12 |
+
"74": [0.16667, 0.68889, 0, 0],
|
| 13 |
+
"75": [0, 0.68889, 0, 0],
|
| 14 |
+
"76": [0, 0.68889, 0, 0],
|
| 15 |
+
"77": [0, 0.68889, 0, 0],
|
| 16 |
+
"78": [0, 0.68889, 0, 0],
|
| 17 |
+
"79": [0.16667, 0.68889, 0, 0],
|
| 18 |
+
"80": [0, 0.68889, 0, 0],
|
| 19 |
+
"81": [0.16667, 0.68889, 0, 0],
|
| 20 |
+
"82": [0, 0.68889, 0, 0],
|
| 21 |
+
"83": [0, 0.68889, 0, 0],
|
| 22 |
+
"84": [0, 0.68889, 0, 0],
|
| 23 |
+
"85": [0, 0.68889, 0, 0],
|
| 24 |
+
"86": [0, 0.68889, 0, 0],
|
| 25 |
+
"87": [0, 0.68889, 0, 0],
|
| 26 |
+
"88": [0, 0.68889, 0, 0],
|
| 27 |
+
"89": [0, 0.68889, 0, 0],
|
| 28 |
+
"90": [0, 0.68889, 0, 0],
|
| 29 |
+
"107": [0, 0.68889, 0, 0],
|
| 30 |
+
"165": [0, 0.675, 0.025, 0],
|
| 31 |
+
"174": [0.15559, 0.69224, 0, 0],
|
| 32 |
+
"240": [0, 0.68889, 0, 0],
|
| 33 |
+
"295": [0, 0.68889, 0, 0],
|
| 34 |
+
"710": [0, 0.825, 0, 0],
|
| 35 |
+
"732": [0, 0.9, 0, 0],
|
| 36 |
+
"770": [0, 0.825, 0, 0],
|
| 37 |
+
"771": [0, 0.9, 0, 0],
|
| 38 |
+
"989": [0.08167, 0.58167, 0, 0],
|
| 39 |
+
"1008": [0, 0.43056, 0.04028, 0],
|
| 40 |
+
"8245": [0, 0.54986, 0, 0],
|
| 41 |
+
"8463": [0, 0.68889, 0, 0],
|
| 42 |
+
"8487": [0, 0.68889, 0, 0],
|
| 43 |
+
"8498": [0, 0.68889, 0, 0],
|
| 44 |
+
"8502": [0, 0.68889, 0, 0],
|
| 45 |
+
"8503": [0, 0.68889, 0, 0],
|
| 46 |
+
"8504": [0, 0.68889, 0, 0],
|
| 47 |
+
"8513": [0, 0.68889, 0, 0],
|
| 48 |
+
"8592": [-0.03598, 0.46402, 0, 0],
|
| 49 |
+
"8594": [-0.03598, 0.46402, 0, 0],
|
| 50 |
+
"8602": [-0.13313, 0.36687, 0, 0],
|
| 51 |
+
"8603": [-0.13313, 0.36687, 0, 0],
|
| 52 |
+
"8606": [0.01354, 0.52239, 0, 0],
|
| 53 |
+
"8608": [0.01354, 0.52239, 0, 0],
|
| 54 |
+
"8610": [0.01354, 0.52239, 0, 0],
|
| 55 |
+
"8611": [0.01354, 0.52239, 0, 0],
|
| 56 |
+
"8619": [0, 0.54986, 0, 0],
|
| 57 |
+
"8620": [0, 0.54986, 0, 0],
|
| 58 |
+
"8621": [-0.13313, 0.37788, 0, 0],
|
| 59 |
+
"8622": [-0.13313, 0.36687, 0, 0],
|
| 60 |
+
"8624": [0, 0.69224, 0, 0],
|
| 61 |
+
"8625": [0, 0.69224, 0, 0],
|
| 62 |
+
"8630": [0, 0.43056, 0, 0],
|
| 63 |
+
"8631": [0, 0.43056, 0, 0],
|
| 64 |
+
"8634": [0.08198, 0.58198, 0, 0],
|
| 65 |
+
"8635": [0.08198, 0.58198, 0, 0],
|
| 66 |
+
"8638": [0.19444, 0.69224, 0, 0],
|
| 67 |
+
"8639": [0.19444, 0.69224, 0, 0],
|
| 68 |
+
"8642": [0.19444, 0.69224, 0, 0],
|
| 69 |
+
"8643": [0.19444, 0.69224, 0, 0],
|
| 70 |
+
"8644": [0.1808, 0.675, 0, 0],
|
| 71 |
+
"8646": [0.1808, 0.675, 0, 0],
|
| 72 |
+
"8647": [0.1808, 0.675, 0, 0],
|
| 73 |
+
"8648": [0.19444, 0.69224, 0, 0],
|
| 74 |
+
"8649": [0.1808, 0.675, 0, 0],
|
| 75 |
+
"8650": [0.19444, 0.69224, 0, 0],
|
| 76 |
+
"8651": [0.01354, 0.52239, 0, 0],
|
| 77 |
+
"8652": [0.01354, 0.52239, 0, 0],
|
| 78 |
+
"8653": [-0.13313, 0.36687, 0, 0],
|
| 79 |
+
"8654": [-0.13313, 0.36687, 0, 0],
|
| 80 |
+
"8655": [-0.13313, 0.36687, 0, 0],
|
| 81 |
+
"8666": [0.13667, 0.63667, 0, 0],
|
| 82 |
+
"8667": [0.13667, 0.63667, 0, 0],
|
| 83 |
+
"8669": [-0.13313, 0.37788, 0, 0],
|
| 84 |
+
"8672": [-0.064, 0.437, 0, 0],
|
| 85 |
+
"8674": [-0.064, 0.437, 0, 0],
|
| 86 |
+
"8705": [0, 0.825, 0, 0],
|
| 87 |
+
"8708": [0, 0.68889, 0, 0],
|
| 88 |
+
"8709": [0.08167, 0.58167, 0, 0],
|
| 89 |
+
"8717": [0, 0.43056, 0, 0],
|
| 90 |
+
"8722": [-0.03598, 0.46402, 0, 0],
|
| 91 |
+
"8724": [0.08198, 0.69224, 0, 0],
|
| 92 |
+
"8726": [0.08167, 0.58167, 0, 0],
|
| 93 |
+
"8733": [0, 0.69224, 0, 0],
|
| 94 |
+
"8736": [0, 0.69224, 0, 0],
|
| 95 |
+
"8737": [0, 0.69224, 0, 0],
|
| 96 |
+
"8738": [0.03517, 0.52239, 0, 0],
|
| 97 |
+
"8739": [0.08167, 0.58167, 0, 0],
|
| 98 |
+
"8740": [0.25142, 0.74111, 0, 0],
|
| 99 |
+
"8741": [0.08167, 0.58167, 0, 0],
|
| 100 |
+
"8742": [0.25142, 0.74111, 0, 0],
|
| 101 |
+
"8756": [0, 0.69224, 0, 0],
|
| 102 |
+
"8757": [0, 0.69224, 0, 0],
|
| 103 |
+
"8764": [-0.13313, 0.36687, 0, 0],
|
| 104 |
+
"8765": [-0.13313, 0.37788, 0, 0],
|
| 105 |
+
"8769": [-0.13313, 0.36687, 0, 0],
|
| 106 |
+
"8770": [-0.03625, 0.46375, 0, 0],
|
| 107 |
+
"8774": [0.30274, 0.79383, 0, 0],
|
| 108 |
+
"8776": [-0.01688, 0.48312, 0, 0],
|
| 109 |
+
"8778": [0.08167, 0.58167, 0, 0],
|
| 110 |
+
"8782": [0.06062, 0.54986, 0, 0],
|
| 111 |
+
"8783": [0.06062, 0.54986, 0, 0],
|
| 112 |
+
"8785": [0.08198, 0.58198, 0, 0],
|
| 113 |
+
"8786": [0.08198, 0.58198, 0, 0],
|
| 114 |
+
"8787": [0.08198, 0.58198, 0, 0],
|
| 115 |
+
"8790": [0, 0.69224, 0, 0],
|
| 116 |
+
"8791": [0.22958, 0.72958, 0, 0],
|
| 117 |
+
"8796": [0.08198, 0.91667, 0, 0],
|
| 118 |
+
"8806": [0.25583, 0.75583, 0, 0],
|
| 119 |
+
"8807": [0.25583, 0.75583, 0, 0],
|
| 120 |
+
"8808": [0.25142, 0.75726, 0, 0],
|
| 121 |
+
"8809": [0.25142, 0.75726, 0, 0],
|
| 122 |
+
"8812": [0.25583, 0.75583, 0, 0],
|
| 123 |
+
"8814": [0.20576, 0.70576, 0, 0],
|
| 124 |
+
"8815": [0.20576, 0.70576, 0, 0],
|
| 125 |
+
"8816": [0.30274, 0.79383, 0, 0],
|
| 126 |
+
"8817": [0.30274, 0.79383, 0, 0],
|
| 127 |
+
"8818": [0.22958, 0.72958, 0, 0],
|
| 128 |
+
"8819": [0.22958, 0.72958, 0, 0],
|
| 129 |
+
"8822": [0.1808, 0.675, 0, 0],
|
| 130 |
+
"8823": [0.1808, 0.675, 0, 0],
|
| 131 |
+
"8828": [0.13667, 0.63667, 0, 0],
|
| 132 |
+
"8829": [0.13667, 0.63667, 0, 0],
|
| 133 |
+
"8830": [0.22958, 0.72958, 0, 0],
|
| 134 |
+
"8831": [0.22958, 0.72958, 0, 0],
|
| 135 |
+
"8832": [0.20576, 0.70576, 0, 0],
|
| 136 |
+
"8833": [0.20576, 0.70576, 0, 0],
|
| 137 |
+
"8840": [0.30274, 0.79383, 0, 0],
|
| 138 |
+
"8841": [0.30274, 0.79383, 0, 0],
|
| 139 |
+
"8842": [0.13597, 0.63597, 0, 0],
|
| 140 |
+
"8843": [0.13597, 0.63597, 0, 0],
|
| 141 |
+
"8847": [0.03517, 0.54986, 0, 0],
|
| 142 |
+
"8848": [0.03517, 0.54986, 0, 0],
|
| 143 |
+
"8858": [0.08198, 0.58198, 0, 0],
|
| 144 |
+
"8859": [0.08198, 0.58198, 0, 0],
|
| 145 |
+
"8861": [0.08198, 0.58198, 0, 0],
|
| 146 |
+
"8862": [0, 0.675, 0, 0],
|
| 147 |
+
"8863": [0, 0.675, 0, 0],
|
| 148 |
+
"8864": [0, 0.675, 0, 0],
|
| 149 |
+
"8865": [0, 0.675, 0, 0],
|
| 150 |
+
"8872": [0, 0.69224, 0, 0],
|
| 151 |
+
"8873": [0, 0.69224, 0, 0],
|
| 152 |
+
"8874": [0, 0.69224, 0, 0],
|
| 153 |
+
"8876": [0, 0.68889, 0, 0],
|
| 154 |
+
"8877": [0, 0.68889, 0, 0],
|
| 155 |
+
"8878": [0, 0.68889, 0, 0],
|
| 156 |
+
"8879": [0, 0.68889, 0, 0],
|
| 157 |
+
"8882": [0.03517, 0.54986, 0, 0],
|
| 158 |
+
"8883": [0.03517, 0.54986, 0, 0],
|
| 159 |
+
"8884": [0.13667, 0.63667, 0, 0],
|
| 160 |
+
"8885": [0.13667, 0.63667, 0, 0],
|
| 161 |
+
"8888": [0, 0.54986, 0, 0],
|
| 162 |
+
"8890": [0.19444, 0.43056, 0, 0],
|
| 163 |
+
"8891": [0.19444, 0.69224, 0, 0],
|
| 164 |
+
"8892": [0.19444, 0.69224, 0, 0],
|
| 165 |
+
"8901": [0, 0.54986, 0, 0],
|
| 166 |
+
"8903": [0.08167, 0.58167, 0, 0],
|
| 167 |
+
"8905": [0.08167, 0.58167, 0, 0],
|
| 168 |
+
"8906": [0.08167, 0.58167, 0, 0],
|
| 169 |
+
"8907": [0, 0.69224, 0, 0],
|
| 170 |
+
"8908": [0, 0.69224, 0, 0],
|
| 171 |
+
"8909": [-0.03598, 0.46402, 0, 0],
|
| 172 |
+
"8910": [0, 0.54986, 0, 0],
|
| 173 |
+
"8911": [0, 0.54986, 0, 0],
|
| 174 |
+
"8912": [0.03517, 0.54986, 0, 0],
|
| 175 |
+
"8913": [0.03517, 0.54986, 0, 0],
|
| 176 |
+
"8914": [0, 0.54986, 0, 0],
|
| 177 |
+
"8915": [0, 0.54986, 0, 0],
|
| 178 |
+
"8916": [0, 0.69224, 0, 0],
|
| 179 |
+
"8918": [0.0391, 0.5391, 0, 0],
|
| 180 |
+
"8919": [0.0391, 0.5391, 0, 0],
|
| 181 |
+
"8920": [0.03517, 0.54986, 0, 0],
|
| 182 |
+
"8921": [0.03517, 0.54986, 0, 0],
|
| 183 |
+
"8922": [0.38569, 0.88569, 0, 0],
|
| 184 |
+
"8923": [0.38569, 0.88569, 0, 0],
|
| 185 |
+
"8926": [0.13667, 0.63667, 0, 0],
|
| 186 |
+
"8927": [0.13667, 0.63667, 0, 0],
|
| 187 |
+
"8928": [0.30274, 0.79383, 0, 0],
|
| 188 |
+
"8929": [0.30274, 0.79383, 0, 0],
|
| 189 |
+
"8934": [0.23222, 0.74111, 0, 0],
|
| 190 |
+
"8935": [0.23222, 0.74111, 0, 0],
|
| 191 |
+
"8936": [0.23222, 0.74111, 0, 0],
|
| 192 |
+
"8937": [0.23222, 0.74111, 0, 0],
|
| 193 |
+
"8938": [0.20576, 0.70576, 0, 0],
|
| 194 |
+
"8939": [0.20576, 0.70576, 0, 0],
|
| 195 |
+
"8940": [0.30274, 0.79383, 0, 0],
|
| 196 |
+
"8941": [0.30274, 0.79383, 0, 0],
|
| 197 |
+
"8994": [0.19444, 0.69224, 0, 0],
|
| 198 |
+
"8995": [0.19444, 0.69224, 0, 0],
|
| 199 |
+
"9416": [0.15559, 0.69224, 0, 0],
|
| 200 |
+
"9484": [0, 0.69224, 0, 0],
|
| 201 |
+
"9488": [0, 0.69224, 0, 0],
|
| 202 |
+
"9492": [0, 0.37788, 0, 0],
|
| 203 |
+
"9496": [0, 0.37788, 0, 0],
|
| 204 |
+
"9585": [0.19444, 0.68889, 0, 0],
|
| 205 |
+
"9586": [0.19444, 0.74111, 0, 0],
|
| 206 |
+
"9632": [0, 0.675, 0, 0],
|
| 207 |
+
"9633": [0, 0.675, 0, 0],
|
| 208 |
+
"9650": [0, 0.54986, 0, 0],
|
| 209 |
+
"9651": [0, 0.54986, 0, 0],
|
| 210 |
+
"9654": [0.03517, 0.54986, 0, 0],
|
| 211 |
+
"9660": [0, 0.54986, 0, 0],
|
| 212 |
+
"9661": [0, 0.54986, 0, 0],
|
| 213 |
+
"9664": [0.03517, 0.54986, 0, 0],
|
| 214 |
+
"9674": [0.11111, 0.69224, 0, 0],
|
| 215 |
+
"9733": [0.19444, 0.69224, 0, 0],
|
| 216 |
+
"10003": [0, 0.69224, 0, 0],
|
| 217 |
+
"10016": [0, 0.69224, 0, 0],
|
| 218 |
+
"10731": [0.11111, 0.69224, 0, 0],
|
| 219 |
+
"10846": [0.19444, 0.75583, 0, 0],
|
| 220 |
+
"10877": [0.13667, 0.63667, 0, 0],
|
| 221 |
+
"10878": [0.13667, 0.63667, 0, 0],
|
| 222 |
+
"10885": [0.25583, 0.75583, 0, 0],
|
| 223 |
+
"10886": [0.25583, 0.75583, 0, 0],
|
| 224 |
+
"10887": [0.13597, 0.63597, 0, 0],
|
| 225 |
+
"10888": [0.13597, 0.63597, 0, 0],
|
| 226 |
+
"10889": [0.26167, 0.75726, 0, 0],
|
| 227 |
+
"10890": [0.26167, 0.75726, 0, 0],
|
| 228 |
+
"10891": [0.48256, 0.98256, 0, 0],
|
| 229 |
+
"10892": [0.48256, 0.98256, 0, 0],
|
| 230 |
+
"10901": [0.13667, 0.63667, 0, 0],
|
| 231 |
+
"10902": [0.13667, 0.63667, 0, 0],
|
| 232 |
+
"10933": [0.25142, 0.75726, 0, 0],
|
| 233 |
+
"10934": [0.25142, 0.75726, 0, 0],
|
| 234 |
+
"10935": [0.26167, 0.75726, 0, 0],
|
| 235 |
+
"10936": [0.26167, 0.75726, 0, 0],
|
| 236 |
+
"10937": [0.26167, 0.75726, 0, 0],
|
| 237 |
+
"10938": [0.26167, 0.75726, 0, 0],
|
| 238 |
+
"10949": [0.25583, 0.75583, 0, 0],
|
| 239 |
+
"10950": [0.25583, 0.75583, 0, 0],
|
| 240 |
+
"10955": [0.28481, 0.79383, 0, 0],
|
| 241 |
+
"10956": [0.28481, 0.79383, 0, 0],
|
| 242 |
+
"57350": [0.08167, 0.58167, 0, 0],
|
| 243 |
+
"57351": [0.08167, 0.58167, 0, 0],
|
| 244 |
+
"57352": [0.08167, 0.58167, 0, 0],
|
| 245 |
+
"57353": [0, 0.43056, 0.04028, 0],
|
| 246 |
+
"57356": [0.25142, 0.75726, 0, 0],
|
| 247 |
+
"57357": [0.25142, 0.75726, 0, 0],
|
| 248 |
+
"57358": [0.41951, 0.91951, 0, 0],
|
| 249 |
+
"57359": [0.30274, 0.79383, 0, 0],
|
| 250 |
+
"57360": [0.30274, 0.79383, 0, 0],
|
| 251 |
+
"57361": [0.41951, 0.91951, 0, 0],
|
| 252 |
+
"57366": [0.25142, 0.75726, 0, 0],
|
| 253 |
+
"57367": [0.25142, 0.75726, 0, 0],
|
| 254 |
+
"57368": [0.25142, 0.75726, 0, 0],
|
| 255 |
+
"57369": [0.25142, 0.75726, 0, 0],
|
| 256 |
+
"57370": [0.13597, 0.63597, 0, 0],
|
| 257 |
+
"57371": [0.13597, 0.63597, 0, 0],
|
| 258 |
+
},
|
| 259 |
+
"Caligraphic-Regular": {
|
| 260 |
+
"48": [0, 0.43056, 0, 0],
|
| 261 |
+
"49": [0, 0.43056, 0, 0],
|
| 262 |
+
"50": [0, 0.43056, 0, 0],
|
| 263 |
+
"51": [0.19444, 0.43056, 0, 0],
|
| 264 |
+
"52": [0.19444, 0.43056, 0, 0],
|
| 265 |
+
"53": [0.19444, 0.43056, 0, 0],
|
| 266 |
+
"54": [0, 0.64444, 0, 0],
|
| 267 |
+
"55": [0.19444, 0.43056, 0, 0],
|
| 268 |
+
"56": [0, 0.64444, 0, 0],
|
| 269 |
+
"57": [0.19444, 0.43056, 0, 0],
|
| 270 |
+
"65": [0, 0.68333, 0, 0.19445],
|
| 271 |
+
"66": [0, 0.68333, 0.03041, 0.13889],
|
| 272 |
+
"67": [0, 0.68333, 0.05834, 0.13889],
|
| 273 |
+
"68": [0, 0.68333, 0.02778, 0.08334],
|
| 274 |
+
"69": [0, 0.68333, 0.08944, 0.11111],
|
| 275 |
+
"70": [0, 0.68333, 0.09931, 0.11111],
|
| 276 |
+
"71": [0.09722, 0.68333, 0.0593, 0.11111],
|
| 277 |
+
"72": [0, 0.68333, 0.00965, 0.11111],
|
| 278 |
+
"73": [0, 0.68333, 0.07382, 0],
|
| 279 |
+
"74": [0.09722, 0.68333, 0.18472, 0.16667],
|
| 280 |
+
"75": [0, 0.68333, 0.01445, 0.05556],
|
| 281 |
+
"76": [0, 0.68333, 0, 0.13889],
|
| 282 |
+
"77": [0, 0.68333, 0, 0.13889],
|
| 283 |
+
"78": [0, 0.68333, 0.14736, 0.08334],
|
| 284 |
+
"79": [0, 0.68333, 0.02778, 0.11111],
|
| 285 |
+
"80": [0, 0.68333, 0.08222, 0.08334],
|
| 286 |
+
"81": [0.09722, 0.68333, 0, 0.11111],
|
| 287 |
+
"82": [0, 0.68333, 0, 0.08334],
|
| 288 |
+
"83": [0, 0.68333, 0.075, 0.13889],
|
| 289 |
+
"84": [0, 0.68333, 0.25417, 0],
|
| 290 |
+
"85": [0, 0.68333, 0.09931, 0.08334],
|
| 291 |
+
"86": [0, 0.68333, 0.08222, 0],
|
| 292 |
+
"87": [0, 0.68333, 0.08222, 0.08334],
|
| 293 |
+
"88": [0, 0.68333, 0.14643, 0.13889],
|
| 294 |
+
"89": [0.09722, 0.68333, 0.08222, 0.08334],
|
| 295 |
+
"90": [0, 0.68333, 0.07944, 0.13889],
|
| 296 |
+
},
|
| 297 |
+
"Fraktur-Regular": {
|
| 298 |
+
"33": [0, 0.69141, 0, 0],
|
| 299 |
+
"34": [0, 0.69141, 0, 0],
|
| 300 |
+
"38": [0, 0.69141, 0, 0],
|
| 301 |
+
"39": [0, 0.69141, 0, 0],
|
| 302 |
+
"40": [0.24982, 0.74947, 0, 0],
|
| 303 |
+
"41": [0.24982, 0.74947, 0, 0],
|
| 304 |
+
"42": [0, 0.62119, 0, 0],
|
| 305 |
+
"43": [0.08319, 0.58283, 0, 0],
|
| 306 |
+
"44": [0, 0.10803, 0, 0],
|
| 307 |
+
"45": [0.08319, 0.58283, 0, 0],
|
| 308 |
+
"46": [0, 0.10803, 0, 0],
|
| 309 |
+
"47": [0.24982, 0.74947, 0, 0],
|
| 310 |
+
"48": [0, 0.47534, 0, 0],
|
| 311 |
+
"49": [0, 0.47534, 0, 0],
|
| 312 |
+
"50": [0, 0.47534, 0, 0],
|
| 313 |
+
"51": [0.18906, 0.47534, 0, 0],
|
| 314 |
+
"52": [0.18906, 0.47534, 0, 0],
|
| 315 |
+
"53": [0.18906, 0.47534, 0, 0],
|
| 316 |
+
"54": [0, 0.69141, 0, 0],
|
| 317 |
+
"55": [0.18906, 0.47534, 0, 0],
|
| 318 |
+
"56": [0, 0.69141, 0, 0],
|
| 319 |
+
"57": [0.18906, 0.47534, 0, 0],
|
| 320 |
+
"58": [0, 0.47534, 0, 0],
|
| 321 |
+
"59": [0.12604, 0.47534, 0, 0],
|
| 322 |
+
"61": [-0.13099, 0.36866, 0, 0],
|
| 323 |
+
"63": [0, 0.69141, 0, 0],
|
| 324 |
+
"65": [0, 0.69141, 0, 0],
|
| 325 |
+
"66": [0, 0.69141, 0, 0],
|
| 326 |
+
"67": [0, 0.69141, 0, 0],
|
| 327 |
+
"68": [0, 0.69141, 0, 0],
|
| 328 |
+
"69": [0, 0.69141, 0, 0],
|
| 329 |
+
"70": [0.12604, 0.69141, 0, 0],
|
| 330 |
+
"71": [0, 0.69141, 0, 0],
|
| 331 |
+
"72": [0.06302, 0.69141, 0, 0],
|
| 332 |
+
"73": [0, 0.69141, 0, 0],
|
| 333 |
+
"74": [0.12604, 0.69141, 0, 0],
|
| 334 |
+
"75": [0, 0.69141, 0, 0],
|
| 335 |
+
"76": [0, 0.69141, 0, 0],
|
| 336 |
+
"77": [0, 0.69141, 0, 0],
|
| 337 |
+
"78": [0, 0.69141, 0, 0],
|
| 338 |
+
"79": [0, 0.69141, 0, 0],
|
| 339 |
+
"80": [0.18906, 0.69141, 0, 0],
|
| 340 |
+
"81": [0.03781, 0.69141, 0, 0],
|
| 341 |
+
"82": [0, 0.69141, 0, 0],
|
| 342 |
+
"83": [0, 0.69141, 0, 0],
|
| 343 |
+
"84": [0, 0.69141, 0, 0],
|
| 344 |
+
"85": [0, 0.69141, 0, 0],
|
| 345 |
+
"86": [0, 0.69141, 0, 0],
|
| 346 |
+
"87": [0, 0.69141, 0, 0],
|
| 347 |
+
"88": [0, 0.69141, 0, 0],
|
| 348 |
+
"89": [0.18906, 0.69141, 0, 0],
|
| 349 |
+
"90": [0.12604, 0.69141, 0, 0],
|
| 350 |
+
"91": [0.24982, 0.74947, 0, 0],
|
| 351 |
+
"93": [0.24982, 0.74947, 0, 0],
|
| 352 |
+
"94": [0, 0.69141, 0, 0],
|
| 353 |
+
"97": [0, 0.47534, 0, 0],
|
| 354 |
+
"98": [0, 0.69141, 0, 0],
|
| 355 |
+
"99": [0, 0.47534, 0, 0],
|
| 356 |
+
"100": [0, 0.62119, 0, 0],
|
| 357 |
+
"101": [0, 0.47534, 0, 0],
|
| 358 |
+
"102": [0.18906, 0.69141, 0, 0],
|
| 359 |
+
"103": [0.18906, 0.47534, 0, 0],
|
| 360 |
+
"104": [0.18906, 0.69141, 0, 0],
|
| 361 |
+
"105": [0, 0.69141, 0, 0],
|
| 362 |
+
"106": [0, 0.69141, 0, 0],
|
| 363 |
+
"107": [0, 0.69141, 0, 0],
|
| 364 |
+
"108": [0, 0.69141, 0, 0],
|
| 365 |
+
"109": [0, 0.47534, 0, 0],
|
| 366 |
+
"110": [0, 0.47534, 0, 0],
|
| 367 |
+
"111": [0, 0.47534, 0, 0],
|
| 368 |
+
"112": [0.18906, 0.52396, 0, 0],
|
| 369 |
+
"113": [0.18906, 0.47534, 0, 0],
|
| 370 |
+
"114": [0, 0.47534, 0, 0],
|
| 371 |
+
"115": [0, 0.47534, 0, 0],
|
| 372 |
+
"116": [0, 0.62119, 0, 0],
|
| 373 |
+
"117": [0, 0.47534, 0, 0],
|
| 374 |
+
"118": [0, 0.52396, 0, 0],
|
| 375 |
+
"119": [0, 0.52396, 0, 0],
|
| 376 |
+
"120": [0.18906, 0.47534, 0, 0],
|
| 377 |
+
"121": [0.18906, 0.47534, 0, 0],
|
| 378 |
+
"122": [0.18906, 0.47534, 0, 0],
|
| 379 |
+
"8216": [0, 0.69141, 0, 0],
|
| 380 |
+
"8217": [0, 0.69141, 0, 0],
|
| 381 |
+
"58112": [0, 0.62119, 0, 0],
|
| 382 |
+
"58113": [0, 0.62119, 0, 0],
|
| 383 |
+
"58114": [0.18906, 0.69141, 0, 0],
|
| 384 |
+
"58115": [0.18906, 0.69141, 0, 0],
|
| 385 |
+
"58116": [0.18906, 0.47534, 0, 0],
|
| 386 |
+
"58117": [0, 0.69141, 0, 0],
|
| 387 |
+
"58118": [0, 0.62119, 0, 0],
|
| 388 |
+
"58119": [0, 0.47534, 0, 0],
|
| 389 |
+
},
|
| 390 |
+
"Main-Bold": {
|
| 391 |
+
"33": [0, 0.69444, 0, 0],
|
| 392 |
+
"34": [0, 0.69444, 0, 0],
|
| 393 |
+
"35": [0.19444, 0.69444, 0, 0],
|
| 394 |
+
"36": [0.05556, 0.75, 0, 0],
|
| 395 |
+
"37": [0.05556, 0.75, 0, 0],
|
| 396 |
+
"38": [0, 0.69444, 0, 0],
|
| 397 |
+
"39": [0, 0.69444, 0, 0],
|
| 398 |
+
"40": [0.25, 0.75, 0, 0],
|
| 399 |
+
"41": [0.25, 0.75, 0, 0],
|
| 400 |
+
"42": [0, 0.75, 0, 0],
|
| 401 |
+
"43": [0.13333, 0.63333, 0, 0],
|
| 402 |
+
"44": [0.19444, 0.15556, 0, 0],
|
| 403 |
+
"45": [0, 0.44444, 0, 0],
|
| 404 |
+
"46": [0, 0.15556, 0, 0],
|
| 405 |
+
"47": [0.25, 0.75, 0, 0],
|
| 406 |
+
"48": [0, 0.64444, 0, 0],
|
| 407 |
+
"49": [0, 0.64444, 0, 0],
|
| 408 |
+
"50": [0, 0.64444, 0, 0],
|
| 409 |
+
"51": [0, 0.64444, 0, 0],
|
| 410 |
+
"52": [0, 0.64444, 0, 0],
|
| 411 |
+
"53": [0, 0.64444, 0, 0],
|
| 412 |
+
"54": [0, 0.64444, 0, 0],
|
| 413 |
+
"55": [0, 0.64444, 0, 0],
|
| 414 |
+
"56": [0, 0.64444, 0, 0],
|
| 415 |
+
"57": [0, 0.64444, 0, 0],
|
| 416 |
+
"58": [0, 0.44444, 0, 0],
|
| 417 |
+
"59": [0.19444, 0.44444, 0, 0],
|
| 418 |
+
"60": [0.08556, 0.58556, 0, 0],
|
| 419 |
+
"61": [-0.10889, 0.39111, 0, 0],
|
| 420 |
+
"62": [0.08556, 0.58556, 0, 0],
|
| 421 |
+
"63": [0, 0.69444, 0, 0],
|
| 422 |
+
"64": [0, 0.69444, 0, 0],
|
| 423 |
+
"65": [0, 0.68611, 0, 0],
|
| 424 |
+
"66": [0, 0.68611, 0, 0],
|
| 425 |
+
"67": [0, 0.68611, 0, 0],
|
| 426 |
+
"68": [0, 0.68611, 0, 0],
|
| 427 |
+
"69": [0, 0.68611, 0, 0],
|
| 428 |
+
"70": [0, 0.68611, 0, 0],
|
| 429 |
+
"71": [0, 0.68611, 0, 0],
|
| 430 |
+
"72": [0, 0.68611, 0, 0],
|
| 431 |
+
"73": [0, 0.68611, 0, 0],
|
| 432 |
+
"74": [0, 0.68611, 0, 0],
|
| 433 |
+
"75": [0, 0.68611, 0, 0],
|
| 434 |
+
"76": [0, 0.68611, 0, 0],
|
| 435 |
+
"77": [0, 0.68611, 0, 0],
|
| 436 |
+
"78": [0, 0.68611, 0, 0],
|
| 437 |
+
"79": [0, 0.68611, 0, 0],
|
| 438 |
+
"80": [0, 0.68611, 0, 0],
|
| 439 |
+
"81": [0.19444, 0.68611, 0, 0],
|
| 440 |
+
"82": [0, 0.68611, 0, 0],
|
| 441 |
+
"83": [0, 0.68611, 0, 0],
|
| 442 |
+
"84": [0, 0.68611, 0, 0],
|
| 443 |
+
"85": [0, 0.68611, 0, 0],
|
| 444 |
+
"86": [0, 0.68611, 0.01597, 0],
|
| 445 |
+
"87": [0, 0.68611, 0.01597, 0],
|
| 446 |
+
"88": [0, 0.68611, 0, 0],
|
| 447 |
+
"89": [0, 0.68611, 0.02875, 0],
|
| 448 |
+
"90": [0, 0.68611, 0, 0],
|
| 449 |
+
"91": [0.25, 0.75, 0, 0],
|
| 450 |
+
"92": [0.25, 0.75, 0, 0],
|
| 451 |
+
"93": [0.25, 0.75, 0, 0],
|
| 452 |
+
"94": [0, 0.69444, 0, 0],
|
| 453 |
+
"95": [0.31, 0.13444, 0.03194, 0],
|
| 454 |
+
"96": [0, 0.69444, 0, 0],
|
| 455 |
+
"97": [0, 0.44444, 0, 0],
|
| 456 |
+
"98": [0, 0.69444, 0, 0],
|
| 457 |
+
"99": [0, 0.44444, 0, 0],
|
| 458 |
+
"100": [0, 0.69444, 0, 0],
|
| 459 |
+
"101": [0, 0.44444, 0, 0],
|
| 460 |
+
"102": [0, 0.69444, 0.10903, 0],
|
| 461 |
+
"103": [0.19444, 0.44444, 0.01597, 0],
|
| 462 |
+
"104": [0, 0.69444, 0, 0],
|
| 463 |
+
"105": [0, 0.69444, 0, 0],
|
| 464 |
+
"106": [0.19444, 0.69444, 0, 0],
|
| 465 |
+
"107": [0, 0.69444, 0, 0],
|
| 466 |
+
"108": [0, 0.69444, 0, 0],
|
| 467 |
+
"109": [0, 0.44444, 0, 0],
|
| 468 |
+
"110": [0, 0.44444, 0, 0],
|
| 469 |
+
"111": [0, 0.44444, 0, 0],
|
| 470 |
+
"112": [0.19444, 0.44444, 0, 0],
|
| 471 |
+
"113": [0.19444, 0.44444, 0, 0],
|
| 472 |
+
"114": [0, 0.44444, 0, 0],
|
| 473 |
+
"115": [0, 0.44444, 0, 0],
|
| 474 |
+
"116": [0, 0.63492, 0, 0],
|
| 475 |
+
"117": [0, 0.44444, 0, 0],
|
| 476 |
+
"118": [0, 0.44444, 0.01597, 0],
|
| 477 |
+
"119": [0, 0.44444, 0.01597, 0],
|
| 478 |
+
"120": [0, 0.44444, 0, 0],
|
| 479 |
+
"121": [0.19444, 0.44444, 0.01597, 0],
|
| 480 |
+
"122": [0, 0.44444, 0, 0],
|
| 481 |
+
"123": [0.25, 0.75, 0, 0],
|
| 482 |
+
"124": [0.25, 0.75, 0, 0],
|
| 483 |
+
"125": [0.25, 0.75, 0, 0],
|
| 484 |
+
"126": [0.35, 0.34444, 0, 0],
|
| 485 |
+
"168": [0, 0.69444, 0, 0],
|
| 486 |
+
"172": [0, 0.44444, 0, 0],
|
| 487 |
+
"175": [0, 0.59611, 0, 0],
|
| 488 |
+
"176": [0, 0.69444, 0, 0],
|
| 489 |
+
"177": [0.13333, 0.63333, 0, 0],
|
| 490 |
+
"180": [0, 0.69444, 0, 0],
|
| 491 |
+
"215": [0.13333, 0.63333, 0, 0],
|
| 492 |
+
"247": [0.13333, 0.63333, 0, 0],
|
| 493 |
+
"305": [0, 0.44444, 0, 0],
|
| 494 |
+
"567": [0.19444, 0.44444, 0, 0],
|
| 495 |
+
"710": [0, 0.69444, 0, 0],
|
| 496 |
+
"711": [0, 0.63194, 0, 0],
|
| 497 |
+
"713": [0, 0.59611, 0, 0],
|
| 498 |
+
"714": [0, 0.69444, 0, 0],
|
| 499 |
+
"715": [0, 0.69444, 0, 0],
|
| 500 |
+
"728": [0, 0.69444, 0, 0],
|
| 501 |
+
"729": [0, 0.69444, 0, 0],
|
| 502 |
+
"730": [0, 0.69444, 0, 0],
|
| 503 |
+
"732": [0, 0.69444, 0, 0],
|
| 504 |
+
"768": [0, 0.69444, 0, 0],
|
| 505 |
+
"769": [0, 0.69444, 0, 0],
|
| 506 |
+
"770": [0, 0.69444, 0, 0],
|
| 507 |
+
"771": [0, 0.69444, 0, 0],
|
| 508 |
+
"772": [0, 0.59611, 0, 0],
|
| 509 |
+
"774": [0, 0.69444, 0, 0],
|
| 510 |
+
"775": [0, 0.69444, 0, 0],
|
| 511 |
+
"776": [0, 0.69444, 0, 0],
|
| 512 |
+
"778": [0, 0.69444, 0, 0],
|
| 513 |
+
"779": [0, 0.69444, 0, 0],
|
| 514 |
+
"780": [0, 0.63194, 0, 0],
|
| 515 |
+
"824": [0.19444, 0.69444, 0, 0],
|
| 516 |
+
"915": [0, 0.68611, 0, 0],
|
| 517 |
+
"916": [0, 0.68611, 0, 0],
|
| 518 |
+
"920": [0, 0.68611, 0, 0],
|
| 519 |
+
"923": [0, 0.68611, 0, 0],
|
| 520 |
+
"926": [0, 0.68611, 0, 0],
|
| 521 |
+
"928": [0, 0.68611, 0, 0],
|
| 522 |
+
"931": [0, 0.68611, 0, 0],
|
| 523 |
+
"933": [0, 0.68611, 0, 0],
|
| 524 |
+
"934": [0, 0.68611, 0, 0],
|
| 525 |
+
"936": [0, 0.68611, 0, 0],
|
| 526 |
+
"937": [0, 0.68611, 0, 0],
|
| 527 |
+
"8211": [0, 0.44444, 0.03194, 0],
|
| 528 |
+
"8212": [0, 0.44444, 0.03194, 0],
|
| 529 |
+
"8216": [0, 0.69444, 0, 0],
|
| 530 |
+
"8217": [0, 0.69444, 0, 0],
|
| 531 |
+
"8220": [0, 0.69444, 0, 0],
|
| 532 |
+
"8221": [0, 0.69444, 0, 0],
|
| 533 |
+
"8224": [0.19444, 0.69444, 0, 0],
|
| 534 |
+
"8225": [0.19444, 0.69444, 0, 0],
|
| 535 |
+
"8242": [0, 0.55556, 0, 0],
|
| 536 |
+
"8407": [0, 0.72444, 0.15486, 0],
|
| 537 |
+
"8463": [0, 0.69444, 0, 0],
|
| 538 |
+
"8465": [0, 0.69444, 0, 0],
|
| 539 |
+
"8467": [0, 0.69444, 0, 0],
|
| 540 |
+
"8472": [0.19444, 0.44444, 0, 0],
|
| 541 |
+
"8476": [0, 0.69444, 0, 0],
|
| 542 |
+
"8501": [0, 0.69444, 0, 0],
|
| 543 |
+
"8592": [-0.10889, 0.39111, 0, 0],
|
| 544 |
+
"8593": [0.19444, 0.69444, 0, 0],
|
| 545 |
+
"8594": [-0.10889, 0.39111, 0, 0],
|
| 546 |
+
"8595": [0.19444, 0.69444, 0, 0],
|
| 547 |
+
"8596": [-0.10889, 0.39111, 0, 0],
|
| 548 |
+
"8597": [0.25, 0.75, 0, 0],
|
| 549 |
+
"8598": [0.19444, 0.69444, 0, 0],
|
| 550 |
+
"8599": [0.19444, 0.69444, 0, 0],
|
| 551 |
+
"8600": [0.19444, 0.69444, 0, 0],
|
| 552 |
+
"8601": [0.19444, 0.69444, 0, 0],
|
| 553 |
+
"8636": [-0.10889, 0.39111, 0, 0],
|
| 554 |
+
"8637": [-0.10889, 0.39111, 0, 0],
|
| 555 |
+
"8640": [-0.10889, 0.39111, 0, 0],
|
| 556 |
+
"8641": [-0.10889, 0.39111, 0, 0],
|
| 557 |
+
"8656": [-0.10889, 0.39111, 0, 0],
|
| 558 |
+
"8657": [0.19444, 0.69444, 0, 0],
|
| 559 |
+
"8658": [-0.10889, 0.39111, 0, 0],
|
| 560 |
+
"8659": [0.19444, 0.69444, 0, 0],
|
| 561 |
+
"8660": [-0.10889, 0.39111, 0, 0],
|
| 562 |
+
"8661": [0.25, 0.75, 0, 0],
|
| 563 |
+
"8704": [0, 0.69444, 0, 0],
|
| 564 |
+
"8706": [0, 0.69444, 0.06389, 0],
|
| 565 |
+
"8707": [0, 0.69444, 0, 0],
|
| 566 |
+
"8709": [0.05556, 0.75, 0, 0],
|
| 567 |
+
"8711": [0, 0.68611, 0, 0],
|
| 568 |
+
"8712": [0.08556, 0.58556, 0, 0],
|
| 569 |
+
"8715": [0.08556, 0.58556, 0, 0],
|
| 570 |
+
"8722": [0.13333, 0.63333, 0, 0],
|
| 571 |
+
"8723": [0.13333, 0.63333, 0, 0],
|
| 572 |
+
"8725": [0.25, 0.75, 0, 0],
|
| 573 |
+
"8726": [0.25, 0.75, 0, 0],
|
| 574 |
+
"8727": [-0.02778, 0.47222, 0, 0],
|
| 575 |
+
"8728": [-0.02639, 0.47361, 0, 0],
|
| 576 |
+
"8729": [-0.02639, 0.47361, 0, 0],
|
| 577 |
+
"8730": [0.18, 0.82, 0, 0],
|
| 578 |
+
"8733": [0, 0.44444, 0, 0],
|
| 579 |
+
"8734": [0, 0.44444, 0, 0],
|
| 580 |
+
"8736": [0, 0.69224, 0, 0],
|
| 581 |
+
"8739": [0.25, 0.75, 0, 0],
|
| 582 |
+
"8741": [0.25, 0.75, 0, 0],
|
| 583 |
+
"8743": [0, 0.55556, 0, 0],
|
| 584 |
+
"8744": [0, 0.55556, 0, 0],
|
| 585 |
+
"8745": [0, 0.55556, 0, 0],
|
| 586 |
+
"8746": [0, 0.55556, 0, 0],
|
| 587 |
+
"8747": [0.19444, 0.69444, 0.12778, 0],
|
| 588 |
+
"8764": [-0.10889, 0.39111, 0, 0],
|
| 589 |
+
"8768": [0.19444, 0.69444, 0, 0],
|
| 590 |
+
"8771": [0.00222, 0.50222, 0, 0],
|
| 591 |
+
"8776": [0.02444, 0.52444, 0, 0],
|
| 592 |
+
"8781": [0.00222, 0.50222, 0, 0],
|
| 593 |
+
"8801": [0.00222, 0.50222, 0, 0],
|
| 594 |
+
"8804": [0.19667, 0.69667, 0, 0],
|
| 595 |
+
"8805": [0.19667, 0.69667, 0, 0],
|
| 596 |
+
"8810": [0.08556, 0.58556, 0, 0],
|
| 597 |
+
"8811": [0.08556, 0.58556, 0, 0],
|
| 598 |
+
"8826": [0.08556, 0.58556, 0, 0],
|
| 599 |
+
"8827": [0.08556, 0.58556, 0, 0],
|
| 600 |
+
"8834": [0.08556, 0.58556, 0, 0],
|
| 601 |
+
"8835": [0.08556, 0.58556, 0, 0],
|
| 602 |
+
"8838": [0.19667, 0.69667, 0, 0],
|
| 603 |
+
"8839": [0.19667, 0.69667, 0, 0],
|
| 604 |
+
"8846": [0, 0.55556, 0, 0],
|
| 605 |
+
"8849": [0.19667, 0.69667, 0, 0],
|
| 606 |
+
"8850": [0.19667, 0.69667, 0, 0],
|
| 607 |
+
"8851": [0, 0.55556, 0, 0],
|
| 608 |
+
"8852": [0, 0.55556, 0, 0],
|
| 609 |
+
"8853": [0.13333, 0.63333, 0, 0],
|
| 610 |
+
"8854": [0.13333, 0.63333, 0, 0],
|
| 611 |
+
"8855": [0.13333, 0.63333, 0, 0],
|
| 612 |
+
"8856": [0.13333, 0.63333, 0, 0],
|
| 613 |
+
"8857": [0.13333, 0.63333, 0, 0],
|
| 614 |
+
"8866": [0, 0.69444, 0, 0],
|
| 615 |
+
"8867": [0, 0.69444, 0, 0],
|
| 616 |
+
"8868": [0, 0.69444, 0, 0],
|
| 617 |
+
"8869": [0, 0.69444, 0, 0],
|
| 618 |
+
"8900": [-0.02639, 0.47361, 0, 0],
|
| 619 |
+
"8901": [-0.02639, 0.47361, 0, 0],
|
| 620 |
+
"8902": [-0.02778, 0.47222, 0, 0],
|
| 621 |
+
"8968": [0.25, 0.75, 0, 0],
|
| 622 |
+
"8969": [0.25, 0.75, 0, 0],
|
| 623 |
+
"8970": [0.25, 0.75, 0, 0],
|
| 624 |
+
"8971": [0.25, 0.75, 0, 0],
|
| 625 |
+
"8994": [-0.13889, 0.36111, 0, 0],
|
| 626 |
+
"8995": [-0.13889, 0.36111, 0, 0],
|
| 627 |
+
"9651": [0.19444, 0.69444, 0, 0],
|
| 628 |
+
"9657": [-0.02778, 0.47222, 0, 0],
|
| 629 |
+
"9661": [0.19444, 0.69444, 0, 0],
|
| 630 |
+
"9667": [-0.02778, 0.47222, 0, 0],
|
| 631 |
+
"9711": [0.19444, 0.69444, 0, 0],
|
| 632 |
+
"9824": [0.12963, 0.69444, 0, 0],
|
| 633 |
+
"9825": [0.12963, 0.69444, 0, 0],
|
| 634 |
+
"9826": [0.12963, 0.69444, 0, 0],
|
| 635 |
+
"9827": [0.12963, 0.69444, 0, 0],
|
| 636 |
+
"9837": [0, 0.75, 0, 0],
|
| 637 |
+
"9838": [0.19444, 0.69444, 0, 0],
|
| 638 |
+
"9839": [0.19444, 0.69444, 0, 0],
|
| 639 |
+
"10216": [0.25, 0.75, 0, 0],
|
| 640 |
+
"10217": [0.25, 0.75, 0, 0],
|
| 641 |
+
"10815": [0, 0.68611, 0, 0],
|
| 642 |
+
"10927": [0.19667, 0.69667, 0, 0],
|
| 643 |
+
"10928": [0.19667, 0.69667, 0, 0],
|
| 644 |
+
},
|
| 645 |
+
"Main-Italic": {
|
| 646 |
+
"33": [0, 0.69444, 0.12417, 0],
|
| 647 |
+
"34": [0, 0.69444, 0.06961, 0],
|
| 648 |
+
"35": [0.19444, 0.69444, 0.06616, 0],
|
| 649 |
+
"37": [0.05556, 0.75, 0.13639, 0],
|
| 650 |
+
"38": [0, 0.69444, 0.09694, 0],
|
| 651 |
+
"39": [0, 0.69444, 0.12417, 0],
|
| 652 |
+
"40": [0.25, 0.75, 0.16194, 0],
|
| 653 |
+
"41": [0.25, 0.75, 0.03694, 0],
|
| 654 |
+
"42": [0, 0.75, 0.14917, 0],
|
| 655 |
+
"43": [0.05667, 0.56167, 0.03694, 0],
|
| 656 |
+
"44": [0.19444, 0.10556, 0, 0],
|
| 657 |
+
"45": [0, 0.43056, 0.02826, 0],
|
| 658 |
+
"46": [0, 0.10556, 0, 0],
|
| 659 |
+
"47": [0.25, 0.75, 0.16194, 0],
|
| 660 |
+
"48": [0, 0.64444, 0.13556, 0],
|
| 661 |
+
"49": [0, 0.64444, 0.13556, 0],
|
| 662 |
+
"50": [0, 0.64444, 0.13556, 0],
|
| 663 |
+
"51": [0, 0.64444, 0.13556, 0],
|
| 664 |
+
"52": [0.19444, 0.64444, 0.13556, 0],
|
| 665 |
+
"53": [0, 0.64444, 0.13556, 0],
|
| 666 |
+
"54": [0, 0.64444, 0.13556, 0],
|
| 667 |
+
"55": [0.19444, 0.64444, 0.13556, 0],
|
| 668 |
+
"56": [0, 0.64444, 0.13556, 0],
|
| 669 |
+
"57": [0, 0.64444, 0.13556, 0],
|
| 670 |
+
"58": [0, 0.43056, 0.0582, 0],
|
| 671 |
+
"59": [0.19444, 0.43056, 0.0582, 0],
|
| 672 |
+
"61": [-0.13313, 0.36687, 0.06616, 0],
|
| 673 |
+
"63": [0, 0.69444, 0.1225, 0],
|
| 674 |
+
"64": [0, 0.69444, 0.09597, 0],
|
| 675 |
+
"65": [0, 0.68333, 0, 0],
|
| 676 |
+
"66": [0, 0.68333, 0.10257, 0],
|
| 677 |
+
"67": [0, 0.68333, 0.14528, 0],
|
| 678 |
+
"68": [0, 0.68333, 0.09403, 0],
|
| 679 |
+
"69": [0, 0.68333, 0.12028, 0],
|
| 680 |
+
"70": [0, 0.68333, 0.13305, 0],
|
| 681 |
+
"71": [0, 0.68333, 0.08722, 0],
|
| 682 |
+
"72": [0, 0.68333, 0.16389, 0],
|
| 683 |
+
"73": [0, 0.68333, 0.15806, 0],
|
| 684 |
+
"74": [0, 0.68333, 0.14028, 0],
|
| 685 |
+
"75": [0, 0.68333, 0.14528, 0],
|
| 686 |
+
"76": [0, 0.68333, 0, 0],
|
| 687 |
+
"77": [0, 0.68333, 0.16389, 0],
|
| 688 |
+
"78": [0, 0.68333, 0.16389, 0],
|
| 689 |
+
"79": [0, 0.68333, 0.09403, 0],
|
| 690 |
+
"80": [0, 0.68333, 0.10257, 0],
|
| 691 |
+
"81": [0.19444, 0.68333, 0.09403, 0],
|
| 692 |
+
"82": [0, 0.68333, 0.03868, 0],
|
| 693 |
+
"83": [0, 0.68333, 0.11972, 0],
|
| 694 |
+
"84": [0, 0.68333, 0.13305, 0],
|
| 695 |
+
"85": [0, 0.68333, 0.16389, 0],
|
| 696 |
+
"86": [0, 0.68333, 0.18361, 0],
|
| 697 |
+
"87": [0, 0.68333, 0.18361, 0],
|
| 698 |
+
"88": [0, 0.68333, 0.15806, 0],
|
| 699 |
+
"89": [0, 0.68333, 0.19383, 0],
|
| 700 |
+
"90": [0, 0.68333, 0.14528, 0],
|
| 701 |
+
"91": [0.25, 0.75, 0.1875, 0],
|
| 702 |
+
"93": [0.25, 0.75, 0.10528, 0],
|
| 703 |
+
"94": [0, 0.69444, 0.06646, 0],
|
| 704 |
+
"95": [0.31, 0.12056, 0.09208, 0],
|
| 705 |
+
"97": [0, 0.43056, 0.07671, 0],
|
| 706 |
+
"98": [0, 0.69444, 0.06312, 0],
|
| 707 |
+
"99": [0, 0.43056, 0.05653, 0],
|
| 708 |
+
"100": [0, 0.69444, 0.10333, 0],
|
| 709 |
+
"101": [0, 0.43056, 0.07514, 0],
|
| 710 |
+
"102": [0.19444, 0.69444, 0.21194, 0],
|
| 711 |
+
"103": [0.19444, 0.43056, 0.08847, 0],
|
| 712 |
+
"104": [0, 0.69444, 0.07671, 0],
|
| 713 |
+
"105": [0, 0.65536, 0.1019, 0],
|
| 714 |
+
"106": [0.19444, 0.65536, 0.14467, 0],
|
| 715 |
+
"107": [0, 0.69444, 0.10764, 0],
|
| 716 |
+
"108": [0, 0.69444, 0.10333, 0],
|
| 717 |
+
"109": [0, 0.43056, 0.07671, 0],
|
| 718 |
+
"110": [0, 0.43056, 0.07671, 0],
|
| 719 |
+
"111": [0, 0.43056, 0.06312, 0],
|
| 720 |
+
"112": [0.19444, 0.43056, 0.06312, 0],
|
| 721 |
+
"113": [0.19444, 0.43056, 0.08847, 0],
|
| 722 |
+
"114": [0, 0.43056, 0.10764, 0],
|
| 723 |
+
"115": [0, 0.43056, 0.08208, 0],
|
| 724 |
+
"116": [0, 0.61508, 0.09486, 0],
|
| 725 |
+
"117": [0, 0.43056, 0.07671, 0],
|
| 726 |
+
"118": [0, 0.43056, 0.10764, 0],
|
| 727 |
+
"119": [0, 0.43056, 0.10764, 0],
|
| 728 |
+
"120": [0, 0.43056, 0.12042, 0],
|
| 729 |
+
"121": [0.19444, 0.43056, 0.08847, 0],
|
| 730 |
+
"122": [0, 0.43056, 0.12292, 0],
|
| 731 |
+
"126": [0.35, 0.31786, 0.11585, 0],
|
| 732 |
+
"163": [0, 0.69444, 0, 0],
|
| 733 |
+
"305": [0, 0.43056, 0, 0.02778],
|
| 734 |
+
"567": [0.19444, 0.43056, 0, 0.08334],
|
| 735 |
+
"768": [0, 0.69444, 0, 0],
|
| 736 |
+
"769": [0, 0.69444, 0.09694, 0],
|
| 737 |
+
"770": [0, 0.69444, 0.06646, 0],
|
| 738 |
+
"771": [0, 0.66786, 0.11585, 0],
|
| 739 |
+
"772": [0, 0.56167, 0.10333, 0],
|
| 740 |
+
"774": [0, 0.69444, 0.10806, 0],
|
| 741 |
+
"775": [0, 0.66786, 0.11752, 0],
|
| 742 |
+
"776": [0, 0.66786, 0.10474, 0],
|
| 743 |
+
"778": [0, 0.69444, 0, 0],
|
| 744 |
+
"779": [0, 0.69444, 0.1225, 0],
|
| 745 |
+
"780": [0, 0.62847, 0.08295, 0],
|
| 746 |
+
"915": [0, 0.68333, 0.13305, 0],
|
| 747 |
+
"916": [0, 0.68333, 0, 0],
|
| 748 |
+
"920": [0, 0.68333, 0.09403, 0],
|
| 749 |
+
"923": [0, 0.68333, 0, 0],
|
| 750 |
+
"926": [0, 0.68333, 0.15294, 0],
|
| 751 |
+
"928": [0, 0.68333, 0.16389, 0],
|
| 752 |
+
"931": [0, 0.68333, 0.12028, 0],
|
| 753 |
+
"933": [0, 0.68333, 0.11111, 0],
|
| 754 |
+
"934": [0, 0.68333, 0.05986, 0],
|
| 755 |
+
"936": [0, 0.68333, 0.11111, 0],
|
| 756 |
+
"937": [0, 0.68333, 0.10257, 0],
|
| 757 |
+
"8211": [0, 0.43056, 0.09208, 0],
|
| 758 |
+
"8212": [0, 0.43056, 0.09208, 0],
|
| 759 |
+
"8216": [0, 0.69444, 0.12417, 0],
|
| 760 |
+
"8217": [0, 0.69444, 0.12417, 0],
|
| 761 |
+
"8220": [0, 0.69444, 0.1685, 0],
|
| 762 |
+
"8221": [0, 0.69444, 0.06961, 0],
|
| 763 |
+
"8463": [0, 0.68889, 0, 0],
|
| 764 |
+
},
|
| 765 |
+
"Main-Regular": {
|
| 766 |
+
"32": [0, 0, 0, 0],
|
| 767 |
+
"33": [0, 0.69444, 0, 0],
|
| 768 |
+
"34": [0, 0.69444, 0, 0],
|
| 769 |
+
"35": [0.19444, 0.69444, 0, 0],
|
| 770 |
+
"36": [0.05556, 0.75, 0, 0],
|
| 771 |
+
"37": [0.05556, 0.75, 0, 0],
|
| 772 |
+
"38": [0, 0.69444, 0, 0],
|
| 773 |
+
"39": [0, 0.69444, 0, 0],
|
| 774 |
+
"40": [0.25, 0.75, 0, 0],
|
| 775 |
+
"41": [0.25, 0.75, 0, 0],
|
| 776 |
+
"42": [0, 0.75, 0, 0],
|
| 777 |
+
"43": [0.08333, 0.58333, 0, 0],
|
| 778 |
+
"44": [0.19444, 0.10556, 0, 0],
|
| 779 |
+
"45": [0, 0.43056, 0, 0],
|
| 780 |
+
"46": [0, 0.10556, 0, 0],
|
| 781 |
+
"47": [0.25, 0.75, 0, 0],
|
| 782 |
+
"48": [0, 0.64444, 0, 0],
|
| 783 |
+
"49": [0, 0.64444, 0, 0],
|
| 784 |
+
"50": [0, 0.64444, 0, 0],
|
| 785 |
+
"51": [0, 0.64444, 0, 0],
|
| 786 |
+
"52": [0, 0.64444, 0, 0],
|
| 787 |
+
"53": [0, 0.64444, 0, 0],
|
| 788 |
+
"54": [0, 0.64444, 0, 0],
|
| 789 |
+
"55": [0, 0.64444, 0, 0],
|
| 790 |
+
"56": [0, 0.64444, 0, 0],
|
| 791 |
+
"57": [0, 0.64444, 0, 0],
|
| 792 |
+
"58": [0, 0.43056, 0, 0],
|
| 793 |
+
"59": [0.19444, 0.43056, 0, 0],
|
| 794 |
+
"60": [0.0391, 0.5391, 0, 0],
|
| 795 |
+
"61": [-0.13313, 0.36687, 0, 0],
|
| 796 |
+
"62": [0.0391, 0.5391, 0, 0],
|
| 797 |
+
"63": [0, 0.69444, 0, 0],
|
| 798 |
+
"64": [0, 0.69444, 0, 0],
|
| 799 |
+
"65": [0, 0.68333, 0, 0],
|
| 800 |
+
"66": [0, 0.68333, 0, 0],
|
| 801 |
+
"67": [0, 0.68333, 0, 0],
|
| 802 |
+
"68": [0, 0.68333, 0, 0],
|
| 803 |
+
"69": [0, 0.68333, 0, 0],
|
| 804 |
+
"70": [0, 0.68333, 0, 0],
|
| 805 |
+
"71": [0, 0.68333, 0, 0],
|
| 806 |
+
"72": [0, 0.68333, 0, 0],
|
| 807 |
+
"73": [0, 0.68333, 0, 0],
|
| 808 |
+
"74": [0, 0.68333, 0, 0],
|
| 809 |
+
"75": [0, 0.68333, 0, 0],
|
| 810 |
+
"76": [0, 0.68333, 0, 0],
|
| 811 |
+
"77": [0, 0.68333, 0, 0],
|
| 812 |
+
"78": [0, 0.68333, 0, 0],
|
| 813 |
+
"79": [0, 0.68333, 0, 0],
|
| 814 |
+
"80": [0, 0.68333, 0, 0],
|
| 815 |
+
"81": [0.19444, 0.68333, 0, 0],
|
| 816 |
+
"82": [0, 0.68333, 0, 0],
|
| 817 |
+
"83": [0, 0.68333, 0, 0],
|
| 818 |
+
"84": [0, 0.68333, 0, 0],
|
| 819 |
+
"85": [0, 0.68333, 0, 0],
|
| 820 |
+
"86": [0, 0.68333, 0.01389, 0],
|
| 821 |
+
"87": [0, 0.68333, 0.01389, 0],
|
| 822 |
+
"88": [0, 0.68333, 0, 0],
|
| 823 |
+
"89": [0, 0.68333, 0.025, 0],
|
| 824 |
+
"90": [0, 0.68333, 0, 0],
|
| 825 |
+
"91": [0.25, 0.75, 0, 0],
|
| 826 |
+
"92": [0.25, 0.75, 0, 0],
|
| 827 |
+
"93": [0.25, 0.75, 0, 0],
|
| 828 |
+
"94": [0, 0.69444, 0, 0],
|
| 829 |
+
"95": [0.31, 0.12056, 0.02778, 0],
|
| 830 |
+
"96": [0, 0.69444, 0, 0],
|
| 831 |
+
"97": [0, 0.43056, 0, 0],
|
| 832 |
+
"98": [0, 0.69444, 0, 0],
|
| 833 |
+
"99": [0, 0.43056, 0, 0],
|
| 834 |
+
"100": [0, 0.69444, 0, 0],
|
| 835 |
+
"101": [0, 0.43056, 0, 0],
|
| 836 |
+
"102": [0, 0.69444, 0.07778, 0],
|
| 837 |
+
"103": [0.19444, 0.43056, 0.01389, 0],
|
| 838 |
+
"104": [0, 0.69444, 0, 0],
|
| 839 |
+
"105": [0, 0.66786, 0, 0],
|
| 840 |
+
"106": [0.19444, 0.66786, 0, 0],
|
| 841 |
+
"107": [0, 0.69444, 0, 0],
|
| 842 |
+
"108": [0, 0.69444, 0, 0],
|
| 843 |
+
"109": [0, 0.43056, 0, 0],
|
| 844 |
+
"110": [0, 0.43056, 0, 0],
|
| 845 |
+
"111": [0, 0.43056, 0, 0],
|
| 846 |
+
"112": [0.19444, 0.43056, 0, 0],
|
| 847 |
+
"113": [0.19444, 0.43056, 0, 0],
|
| 848 |
+
"114": [0, 0.43056, 0, 0],
|
| 849 |
+
"115": [0, 0.43056, 0, 0],
|
| 850 |
+
"116": [0, 0.61508, 0, 0],
|
| 851 |
+
"117": [0, 0.43056, 0, 0],
|
| 852 |
+
"118": [0, 0.43056, 0.01389, 0],
|
| 853 |
+
"119": [0, 0.43056, 0.01389, 0],
|
| 854 |
+
"120": [0, 0.43056, 0, 0],
|
| 855 |
+
"121": [0.19444, 0.43056, 0.01389, 0],
|
| 856 |
+
"122": [0, 0.43056, 0, 0],
|
| 857 |
+
"123": [0.25, 0.75, 0, 0],
|
| 858 |
+
"124": [0.25, 0.75, 0, 0],
|
| 859 |
+
"125": [0.25, 0.75, 0, 0],
|
| 860 |
+
"126": [0.35, 0.31786, 0, 0],
|
| 861 |
+
"160": [0, 0, 0, 0],
|
| 862 |
+
"168": [0, 0.66786, 0, 0],
|
| 863 |
+
"172": [0, 0.43056, 0, 0],
|
| 864 |
+
"175": [0, 0.56778, 0, 0],
|
| 865 |
+
"176": [0, 0.69444, 0, 0],
|
| 866 |
+
"177": [0.08333, 0.58333, 0, 0],
|
| 867 |
+
"180": [0, 0.69444, 0, 0],
|
| 868 |
+
"215": [0.08333, 0.58333, 0, 0],
|
| 869 |
+
"247": [0.08333, 0.58333, 0, 0],
|
| 870 |
+
"305": [0, 0.43056, 0, 0],
|
| 871 |
+
"567": [0.19444, 0.43056, 0, 0],
|
| 872 |
+
"710": [0, 0.69444, 0, 0],
|
| 873 |
+
"711": [0, 0.62847, 0, 0],
|
| 874 |
+
"713": [0, 0.56778, 0, 0],
|
| 875 |
+
"714": [0, 0.69444, 0, 0],
|
| 876 |
+
"715": [0, 0.69444, 0, 0],
|
| 877 |
+
"728": [0, 0.69444, 0, 0],
|
| 878 |
+
"729": [0, 0.66786, 0, 0],
|
| 879 |
+
"730": [0, 0.69444, 0, 0],
|
| 880 |
+
"732": [0, 0.66786, 0, 0],
|
| 881 |
+
"768": [0, 0.69444, 0, 0],
|
| 882 |
+
"769": [0, 0.69444, 0, 0],
|
| 883 |
+
"770": [0, 0.69444, 0, 0],
|
| 884 |
+
"771": [0, 0.66786, 0, 0],
|
| 885 |
+
"772": [0, 0.56778, 0, 0],
|
| 886 |
+
"774": [0, 0.69444, 0, 0],
|
| 887 |
+
"775": [0, 0.66786, 0, 0],
|
| 888 |
+
"776": [0, 0.66786, 0, 0],
|
| 889 |
+
"778": [0, 0.69444, 0, 0],
|
| 890 |
+
"779": [0, 0.69444, 0, 0],
|
| 891 |
+
"780": [0, 0.62847, 0, 0],
|
| 892 |
+
"824": [0.19444, 0.69444, 0, 0],
|
| 893 |
+
"915": [0, 0.68333, 0, 0],
|
| 894 |
+
"916": [0, 0.68333, 0, 0],
|
| 895 |
+
"920": [0, 0.68333, 0, 0],
|
| 896 |
+
"923": [0, 0.68333, 0, 0],
|
| 897 |
+
"926": [0, 0.68333, 0, 0],
|
| 898 |
+
"928": [0, 0.68333, 0, 0],
|
| 899 |
+
"931": [0, 0.68333, 0, 0],
|
| 900 |
+
"933": [0, 0.68333, 0, 0],
|
| 901 |
+
"934": [0, 0.68333, 0, 0],
|
| 902 |
+
"936": [0, 0.68333, 0, 0],
|
| 903 |
+
"937": [0, 0.68333, 0, 0],
|
| 904 |
+
"8211": [0, 0.43056, 0.02778, 0],
|
| 905 |
+
"8212": [0, 0.43056, 0.02778, 0],
|
| 906 |
+
"8216": [0, 0.69444, 0, 0],
|
| 907 |
+
"8217": [0, 0.69444, 0, 0],
|
| 908 |
+
"8220": [0, 0.69444, 0, 0],
|
| 909 |
+
"8221": [0, 0.69444, 0, 0],
|
| 910 |
+
"8224": [0.19444, 0.69444, 0, 0],
|
| 911 |
+
"8225": [0.19444, 0.69444, 0, 0],
|
| 912 |
+
"8230": [0, 0.12, 0, 0],
|
| 913 |
+
"8242": [0, 0.55556, 0, 0],
|
| 914 |
+
"8407": [0, 0.71444, 0.15382, 0],
|
| 915 |
+
"8463": [0, 0.68889, 0, 0],
|
| 916 |
+
"8465": [0, 0.69444, 0, 0],
|
| 917 |
+
"8467": [0, 0.69444, 0, 0.11111],
|
| 918 |
+
"8472": [0.19444, 0.43056, 0, 0.11111],
|
| 919 |
+
"8476": [0, 0.69444, 0, 0],
|
| 920 |
+
"8501": [0, 0.69444, 0, 0],
|
| 921 |
+
"8592": [-0.13313, 0.36687, 0, 0],
|
| 922 |
+
"8593": [0.19444, 0.69444, 0, 0],
|
| 923 |
+
"8594": [-0.13313, 0.36687, 0, 0],
|
| 924 |
+
"8595": [0.19444, 0.69444, 0, 0],
|
| 925 |
+
"8596": [-0.13313, 0.36687, 0, 0],
|
| 926 |
+
"8597": [0.25, 0.75, 0, 0],
|
| 927 |
+
"8598": [0.19444, 0.69444, 0, 0],
|
| 928 |
+
"8599": [0.19444, 0.69444, 0, 0],
|
| 929 |
+
"8600": [0.19444, 0.69444, 0, 0],
|
| 930 |
+
"8601": [0.19444, 0.69444, 0, 0],
|
| 931 |
+
"8614": [0.011, 0.511, 0, 0],
|
| 932 |
+
"8617": [0.011, 0.511, 0, 0],
|
| 933 |
+
"8618": [0.011, 0.511, 0, 0],
|
| 934 |
+
"8636": [-0.13313, 0.36687, 0, 0],
|
| 935 |
+
"8637": [-0.13313, 0.36687, 0, 0],
|
| 936 |
+
"8640": [-0.13313, 0.36687, 0, 0],
|
| 937 |
+
"8641": [-0.13313, 0.36687, 0, 0],
|
| 938 |
+
"8652": [0.011, 0.671, 0, 0],
|
| 939 |
+
"8656": [-0.13313, 0.36687, 0, 0],
|
| 940 |
+
"8657": [0.19444, 0.69444, 0, 0],
|
| 941 |
+
"8658": [-0.13313, 0.36687, 0, 0],
|
| 942 |
+
"8659": [0.19444, 0.69444, 0, 0],
|
| 943 |
+
"8660": [-0.13313, 0.36687, 0, 0],
|
| 944 |
+
"8661": [0.25, 0.75, 0, 0],
|
| 945 |
+
"8704": [0, 0.69444, 0, 0],
|
| 946 |
+
"8706": [0, 0.69444, 0.05556, 0.08334],
|
| 947 |
+
"8707": [0, 0.69444, 0, 0],
|
| 948 |
+
"8709": [0.05556, 0.75, 0, 0],
|
| 949 |
+
"8711": [0, 0.68333, 0, 0],
|
| 950 |
+
"8712": [0.0391, 0.5391, 0, 0],
|
| 951 |
+
"8715": [0.0391, 0.5391, 0, 0],
|
| 952 |
+
"8722": [0.08333, 0.58333, 0, 0],
|
| 953 |
+
"8723": [0.08333, 0.58333, 0, 0],
|
| 954 |
+
"8725": [0.25, 0.75, 0, 0],
|
| 955 |
+
"8726": [0.25, 0.75, 0, 0],
|
| 956 |
+
"8727": [-0.03472, 0.46528, 0, 0],
|
| 957 |
+
"8728": [-0.05555, 0.44445, 0, 0],
|
| 958 |
+
"8729": [-0.05555, 0.44445, 0, 0],
|
| 959 |
+
"8730": [0.2, 0.8, 0, 0],
|
| 960 |
+
"8733": [0, 0.43056, 0, 0],
|
| 961 |
+
"8734": [0, 0.43056, 0, 0],
|
| 962 |
+
"8736": [0, 0.69224, 0, 0],
|
| 963 |
+
"8739": [0.25, 0.75, 0, 0],
|
| 964 |
+
"8741": [0.25, 0.75, 0, 0],
|
| 965 |
+
"8743": [0, 0.55556, 0, 0],
|
| 966 |
+
"8744": [0, 0.55556, 0, 0],
|
| 967 |
+
"8745": [0, 0.55556, 0, 0],
|
| 968 |
+
"8746": [0, 0.55556, 0, 0],
|
| 969 |
+
"8747": [0.19444, 0.69444, 0.11111, 0],
|
| 970 |
+
"8764": [-0.13313, 0.36687, 0, 0],
|
| 971 |
+
"8768": [0.19444, 0.69444, 0, 0],
|
| 972 |
+
"8771": [-0.03625, 0.46375, 0, 0],
|
| 973 |
+
"8773": [-0.022, 0.589, 0, 0],
|
| 974 |
+
"8776": [-0.01688, 0.48312, 0, 0],
|
| 975 |
+
"8781": [-0.03625, 0.46375, 0, 0],
|
| 976 |
+
"8784": [-0.133, 0.67, 0, 0],
|
| 977 |
+
"8800": [0.215, 0.716, 0, 0],
|
| 978 |
+
"8801": [-0.03625, 0.46375, 0, 0],
|
| 979 |
+
"8804": [0.13597, 0.63597, 0, 0],
|
| 980 |
+
"8805": [0.13597, 0.63597, 0, 0],
|
| 981 |
+
"8810": [0.0391, 0.5391, 0, 0],
|
| 982 |
+
"8811": [0.0391, 0.5391, 0, 0],
|
| 983 |
+
"8826": [0.0391, 0.5391, 0, 0],
|
| 984 |
+
"8827": [0.0391, 0.5391, 0, 0],
|
| 985 |
+
"8834": [0.0391, 0.5391, 0, 0],
|
| 986 |
+
"8835": [0.0391, 0.5391, 0, 0],
|
| 987 |
+
"8838": [0.13597, 0.63597, 0, 0],
|
| 988 |
+
"8839": [0.13597, 0.63597, 0, 0],
|
| 989 |
+
"8846": [0, 0.55556, 0, 0],
|
| 990 |
+
"8849": [0.13597, 0.63597, 0, 0],
|
| 991 |
+
"8850": [0.13597, 0.63597, 0, 0],
|
| 992 |
+
"8851": [0, 0.55556, 0, 0],
|
| 993 |
+
"8852": [0, 0.55556, 0, 0],
|
| 994 |
+
"8853": [0.08333, 0.58333, 0, 0],
|
| 995 |
+
"8854": [0.08333, 0.58333, 0, 0],
|
| 996 |
+
"8855": [0.08333, 0.58333, 0, 0],
|
| 997 |
+
"8856": [0.08333, 0.58333, 0, 0],
|
| 998 |
+
"8857": [0.08333, 0.58333, 0, 0],
|
| 999 |
+
"8866": [0, 0.69444, 0, 0],
|
| 1000 |
+
"8867": [0, 0.69444, 0, 0],
|
| 1001 |
+
"8868": [0, 0.69444, 0, 0],
|
| 1002 |
+
"8869": [0, 0.69444, 0, 0],
|
| 1003 |
+
"8872": [0.249, 0.75, 0, 0],
|
| 1004 |
+
"8900": [-0.05555, 0.44445, 0, 0],
|
| 1005 |
+
"8901": [-0.05555, 0.44445, 0, 0],
|
| 1006 |
+
"8902": [-0.03472, 0.46528, 0, 0],
|
| 1007 |
+
"8904": [0.005, 0.505, 0, 0],
|
| 1008 |
+
"8942": [0.03, 0.9, 0, 0],
|
| 1009 |
+
"8943": [-0.19, 0.31, 0, 0],
|
| 1010 |
+
"8945": [-0.1, 0.82, 0, 0],
|
| 1011 |
+
"8968": [0.25, 0.75, 0, 0],
|
| 1012 |
+
"8969": [0.25, 0.75, 0, 0],
|
| 1013 |
+
"8970": [0.25, 0.75, 0, 0],
|
| 1014 |
+
"8971": [0.25, 0.75, 0, 0],
|
| 1015 |
+
"8994": [-0.14236, 0.35764, 0, 0],
|
| 1016 |
+
"8995": [-0.14236, 0.35764, 0, 0],
|
| 1017 |
+
"9136": [0.244, 0.744, 0, 0],
|
| 1018 |
+
"9137": [0.244, 0.744, 0, 0],
|
| 1019 |
+
"9651": [0.19444, 0.69444, 0, 0],
|
| 1020 |
+
"9657": [-0.03472, 0.46528, 0, 0],
|
| 1021 |
+
"9661": [0.19444, 0.69444, 0, 0],
|
| 1022 |
+
"9667": [-0.03472, 0.46528, 0, 0],
|
| 1023 |
+
"9711": [0.19444, 0.69444, 0, 0],
|
| 1024 |
+
"9824": [0.12963, 0.69444, 0, 0],
|
| 1025 |
+
"9825": [0.12963, 0.69444, 0, 0],
|
| 1026 |
+
"9826": [0.12963, 0.69444, 0, 0],
|
| 1027 |
+
"9827": [0.12963, 0.69444, 0, 0],
|
| 1028 |
+
"9837": [0, 0.75, 0, 0],
|
| 1029 |
+
"9838": [0.19444, 0.69444, 0, 0],
|
| 1030 |
+
"9839": [0.19444, 0.69444, 0, 0],
|
| 1031 |
+
"10216": [0.25, 0.75, 0, 0],
|
| 1032 |
+
"10217": [0.25, 0.75, 0, 0],
|
| 1033 |
+
"10222": [0.244, 0.744, 0, 0],
|
| 1034 |
+
"10223": [0.244, 0.744, 0, 0],
|
| 1035 |
+
"10229": [0.011, 0.511, 0, 0],
|
| 1036 |
+
"10230": [0.011, 0.511, 0, 0],
|
| 1037 |
+
"10231": [0.011, 0.511, 0, 0],
|
| 1038 |
+
"10232": [0.024, 0.525, 0, 0],
|
| 1039 |
+
"10233": [0.024, 0.525, 0, 0],
|
| 1040 |
+
"10234": [0.024, 0.525, 0, 0],
|
| 1041 |
+
"10236": [0.011, 0.511, 0, 0],
|
| 1042 |
+
"10815": [0, 0.68333, 0, 0],
|
| 1043 |
+
"10927": [0.13597, 0.63597, 0, 0],
|
| 1044 |
+
"10928": [0.13597, 0.63597, 0, 0],
|
| 1045 |
+
},
|
| 1046 |
+
"Math-BoldItalic": {
|
| 1047 |
+
"47": [0.19444, 0.69444, 0, 0],
|
| 1048 |
+
"65": [0, 0.68611, 0, 0],
|
| 1049 |
+
"66": [0, 0.68611, 0.04835, 0],
|
| 1050 |
+
"67": [0, 0.68611, 0.06979, 0],
|
| 1051 |
+
"68": [0, 0.68611, 0.03194, 0],
|
| 1052 |
+
"69": [0, 0.68611, 0.05451, 0],
|
| 1053 |
+
"70": [0, 0.68611, 0.15972, 0],
|
| 1054 |
+
"71": [0, 0.68611, 0, 0],
|
| 1055 |
+
"72": [0, 0.68611, 0.08229, 0],
|
| 1056 |
+
"73": [0, 0.68611, 0.07778, 0],
|
| 1057 |
+
"74": [0, 0.68611, 0.10069, 0],
|
| 1058 |
+
"75": [0, 0.68611, 0.06979, 0],
|
| 1059 |
+
"76": [0, 0.68611, 0, 0],
|
| 1060 |
+
"77": [0, 0.68611, 0.11424, 0],
|
| 1061 |
+
"78": [0, 0.68611, 0.11424, 0],
|
| 1062 |
+
"79": [0, 0.68611, 0.03194, 0],
|
| 1063 |
+
"80": [0, 0.68611, 0.15972, 0],
|
| 1064 |
+
"81": [0.19444, 0.68611, 0, 0],
|
| 1065 |
+
"82": [0, 0.68611, 0.00421, 0],
|
| 1066 |
+
"83": [0, 0.68611, 0.05382, 0],
|
| 1067 |
+
"84": [0, 0.68611, 0.15972, 0],
|
| 1068 |
+
"85": [0, 0.68611, 0.11424, 0],
|
| 1069 |
+
"86": [0, 0.68611, 0.25555, 0],
|
| 1070 |
+
"87": [0, 0.68611, 0.15972, 0],
|
| 1071 |
+
"88": [0, 0.68611, 0.07778, 0],
|
| 1072 |
+
"89": [0, 0.68611, 0.25555, 0],
|
| 1073 |
+
"90": [0, 0.68611, 0.06979, 0],
|
| 1074 |
+
"97": [0, 0.44444, 0, 0],
|
| 1075 |
+
"98": [0, 0.69444, 0, 0],
|
| 1076 |
+
"99": [0, 0.44444, 0, 0],
|
| 1077 |
+
"100": [0, 0.69444, 0, 0],
|
| 1078 |
+
"101": [0, 0.44444, 0, 0],
|
| 1079 |
+
"102": [0.19444, 0.69444, 0.11042, 0],
|
| 1080 |
+
"103": [0.19444, 0.44444, 0.03704, 0],
|
| 1081 |
+
"104": [0, 0.69444, 0, 0],
|
| 1082 |
+
"105": [0, 0.69326, 0, 0],
|
| 1083 |
+
"106": [0.19444, 0.69326, 0.0622, 0],
|
| 1084 |
+
"107": [0, 0.69444, 0.01852, 0],
|
| 1085 |
+
"108": [0, 0.69444, 0.0088, 0],
|
| 1086 |
+
"109": [0, 0.44444, 0, 0],
|
| 1087 |
+
"110": [0, 0.44444, 0, 0],
|
| 1088 |
+
"111": [0, 0.44444, 0, 0],
|
| 1089 |
+
"112": [0.19444, 0.44444, 0, 0],
|
| 1090 |
+
"113": [0.19444, 0.44444, 0.03704, 0],
|
| 1091 |
+
"114": [0, 0.44444, 0.03194, 0],
|
| 1092 |
+
"115": [0, 0.44444, 0, 0],
|
| 1093 |
+
"116": [0, 0.63492, 0, 0],
|
| 1094 |
+
"117": [0, 0.44444, 0, 0],
|
| 1095 |
+
"118": [0, 0.44444, 0.03704, 0],
|
| 1096 |
+
"119": [0, 0.44444, 0.02778, 0],
|
| 1097 |
+
"120": [0, 0.44444, 0, 0],
|
| 1098 |
+
"121": [0.19444, 0.44444, 0.03704, 0],
|
| 1099 |
+
"122": [0, 0.44444, 0.04213, 0],
|
| 1100 |
+
"915": [0, 0.68611, 0.15972, 0],
|
| 1101 |
+
"916": [0, 0.68611, 0, 0],
|
| 1102 |
+
"920": [0, 0.68611, 0.03194, 0],
|
| 1103 |
+
"923": [0, 0.68611, 0, 0],
|
| 1104 |
+
"926": [0, 0.68611, 0.07458, 0],
|
| 1105 |
+
"928": [0, 0.68611, 0.08229, 0],
|
| 1106 |
+
"931": [0, 0.68611, 0.05451, 0],
|
| 1107 |
+
"933": [0, 0.68611, 0.15972, 0],
|
| 1108 |
+
"934": [0, 0.68611, 0, 0],
|
| 1109 |
+
"936": [0, 0.68611, 0.11653, 0],
|
| 1110 |
+
"937": [0, 0.68611, 0.04835, 0],
|
| 1111 |
+
"945": [0, 0.44444, 0, 0],
|
| 1112 |
+
"946": [0.19444, 0.69444, 0.03403, 0],
|
| 1113 |
+
"947": [0.19444, 0.44444, 0.06389, 0],
|
| 1114 |
+
"948": [0, 0.69444, 0.03819, 0],
|
| 1115 |
+
"949": [0, 0.44444, 0, 0],
|
| 1116 |
+
"950": [0.19444, 0.69444, 0.06215, 0],
|
| 1117 |
+
"951": [0.19444, 0.44444, 0.03704, 0],
|
| 1118 |
+
"952": [0, 0.69444, 0.03194, 0],
|
| 1119 |
+
"953": [0, 0.44444, 0, 0],
|
| 1120 |
+
"954": [0, 0.44444, 0, 0],
|
| 1121 |
+
"955": [0, 0.69444, 0, 0],
|
| 1122 |
+
"956": [0.19444, 0.44444, 0, 0],
|
| 1123 |
+
"957": [0, 0.44444, 0.06898, 0],
|
| 1124 |
+
"958": [0.19444, 0.69444, 0.03021, 0],
|
| 1125 |
+
"959": [0, 0.44444, 0, 0],
|
| 1126 |
+
"960": [0, 0.44444, 0.03704, 0],
|
| 1127 |
+
"961": [0.19444, 0.44444, 0, 0],
|
| 1128 |
+
"962": [0.09722, 0.44444, 0.07917, 0],
|
| 1129 |
+
"963": [0, 0.44444, 0.03704, 0],
|
| 1130 |
+
"964": [0, 0.44444, 0.13472, 0],
|
| 1131 |
+
"965": [0, 0.44444, 0.03704, 0],
|
| 1132 |
+
"966": [0.19444, 0.44444, 0, 0],
|
| 1133 |
+
"967": [0.19444, 0.44444, 0, 0],
|
| 1134 |
+
"968": [0.19444, 0.69444, 0.03704, 0],
|
| 1135 |
+
"969": [0, 0.44444, 0.03704, 0],
|
| 1136 |
+
"977": [0, 0.69444, 0, 0],
|
| 1137 |
+
"981": [0.19444, 0.69444, 0, 0],
|
| 1138 |
+
"982": [0, 0.44444, 0.03194, 0],
|
| 1139 |
+
"1009": [0.19444, 0.44444, 0, 0],
|
| 1140 |
+
"1013": [0, 0.44444, 0, 0],
|
| 1141 |
+
},
|
| 1142 |
+
"Math-Italic": {
|
| 1143 |
+
"47": [0.19444, 0.69444, 0, 0],
|
| 1144 |
+
"65": [0, 0.68333, 0, 0.13889],
|
| 1145 |
+
"66": [0, 0.68333, 0.05017, 0.08334],
|
| 1146 |
+
"67": [0, 0.68333, 0.07153, 0.08334],
|
| 1147 |
+
"68": [0, 0.68333, 0.02778, 0.05556],
|
| 1148 |
+
"69": [0, 0.68333, 0.05764, 0.08334],
|
| 1149 |
+
"70": [0, 0.68333, 0.13889, 0.08334],
|
| 1150 |
+
"71": [0, 0.68333, 0, 0.08334],
|
| 1151 |
+
"72": [0, 0.68333, 0.08125, 0.05556],
|
| 1152 |
+
"73": [0, 0.68333, 0.07847, 0.11111],
|
| 1153 |
+
"74": [0, 0.68333, 0.09618, 0.16667],
|
| 1154 |
+
"75": [0, 0.68333, 0.07153, 0.05556],
|
| 1155 |
+
"76": [0, 0.68333, 0, 0.02778],
|
| 1156 |
+
"77": [0, 0.68333, 0.10903, 0.08334],
|
| 1157 |
+
"78": [0, 0.68333, 0.10903, 0.08334],
|
| 1158 |
+
"79": [0, 0.68333, 0.02778, 0.08334],
|
| 1159 |
+
"80": [0, 0.68333, 0.13889, 0.08334],
|
| 1160 |
+
"81": [0.19444, 0.68333, 0, 0.08334],
|
| 1161 |
+
"82": [0, 0.68333, 0.00773, 0.08334],
|
| 1162 |
+
"83": [0, 0.68333, 0.05764, 0.08334],
|
| 1163 |
+
"84": [0, 0.68333, 0.13889, 0.08334],
|
| 1164 |
+
"85": [0, 0.68333, 0.10903, 0.02778],
|
| 1165 |
+
"86": [0, 0.68333, 0.22222, 0],
|
| 1166 |
+
"87": [0, 0.68333, 0.13889, 0],
|
| 1167 |
+
"88": [0, 0.68333, 0.07847, 0.08334],
|
| 1168 |
+
"89": [0, 0.68333, 0.22222, 0],
|
| 1169 |
+
"90": [0, 0.68333, 0.07153, 0.08334],
|
| 1170 |
+
"97": [0, 0.43056, 0, 0],
|
| 1171 |
+
"98": [0, 0.69444, 0, 0],
|
| 1172 |
+
"99": [0, 0.43056, 0, 0.05556],
|
| 1173 |
+
"100": [0, 0.69444, 0, 0.16667],
|
| 1174 |
+
"101": [0, 0.43056, 0, 0.05556],
|
| 1175 |
+
"102": [0.19444, 0.69444, 0.10764, 0.16667],
|
| 1176 |
+
"103": [0.19444, 0.43056, 0.03588, 0.02778],
|
| 1177 |
+
"104": [0, 0.69444, 0, 0],
|
| 1178 |
+
"105": [0, 0.65952, 0, 0],
|
| 1179 |
+
"106": [0.19444, 0.65952, 0.05724, 0],
|
| 1180 |
+
"107": [0, 0.69444, 0.03148, 0],
|
| 1181 |
+
"108": [0, 0.69444, 0.01968, 0.08334],
|
| 1182 |
+
"109": [0, 0.43056, 0, 0],
|
| 1183 |
+
"110": [0, 0.43056, 0, 0],
|
| 1184 |
+
"111": [0, 0.43056, 0, 0.05556],
|
| 1185 |
+
"112": [0.19444, 0.43056, 0, 0.08334],
|
| 1186 |
+
"113": [0.19444, 0.43056, 0.03588, 0.08334],
|
| 1187 |
+
"114": [0, 0.43056, 0.02778, 0.05556],
|
| 1188 |
+
"115": [0, 0.43056, 0, 0.05556],
|
| 1189 |
+
"116": [0, 0.61508, 0, 0.08334],
|
| 1190 |
+
"117": [0, 0.43056, 0, 0.02778],
|
| 1191 |
+
"118": [0, 0.43056, 0.03588, 0.02778],
|
| 1192 |
+
"119": [0, 0.43056, 0.02691, 0.08334],
|
| 1193 |
+
"120": [0, 0.43056, 0, 0.02778],
|
| 1194 |
+
"121": [0.19444, 0.43056, 0.03588, 0.05556],
|
| 1195 |
+
"122": [0, 0.43056, 0.04398, 0.05556],
|
| 1196 |
+
"915": [0, 0.68333, 0.13889, 0.08334],
|
| 1197 |
+
"916": [0, 0.68333, 0, 0.16667],
|
| 1198 |
+
"920": [0, 0.68333, 0.02778, 0.08334],
|
| 1199 |
+
"923": [0, 0.68333, 0, 0.16667],
|
| 1200 |
+
"926": [0, 0.68333, 0.07569, 0.08334],
|
| 1201 |
+
"928": [0, 0.68333, 0.08125, 0.05556],
|
| 1202 |
+
"931": [0, 0.68333, 0.05764, 0.08334],
|
| 1203 |
+
"933": [0, 0.68333, 0.13889, 0.05556],
|
| 1204 |
+
"934": [0, 0.68333, 0, 0.08334],
|
| 1205 |
+
"936": [0, 0.68333, 0.11, 0.05556],
|
| 1206 |
+
"937": [0, 0.68333, 0.05017, 0.08334],
|
| 1207 |
+
"945": [0, 0.43056, 0.0037, 0.02778],
|
| 1208 |
+
"946": [0.19444, 0.69444, 0.05278, 0.08334],
|
| 1209 |
+
"947": [0.19444, 0.43056, 0.05556, 0],
|
| 1210 |
+
"948": [0, 0.69444, 0.03785, 0.05556],
|
| 1211 |
+
"949": [0, 0.43056, 0, 0.08334],
|
| 1212 |
+
"950": [0.19444, 0.69444, 0.07378, 0.08334],
|
| 1213 |
+
"951": [0.19444, 0.43056, 0.03588, 0.05556],
|
| 1214 |
+
"952": [0, 0.69444, 0.02778, 0.08334],
|
| 1215 |
+
"953": [0, 0.43056, 0, 0.05556],
|
| 1216 |
+
"954": [0, 0.43056, 0, 0],
|
| 1217 |
+
"955": [0, 0.69444, 0, 0],
|
| 1218 |
+
"956": [0.19444, 0.43056, 0, 0.02778],
|
| 1219 |
+
"957": [0, 0.43056, 0.06366, 0.02778],
|
| 1220 |
+
"958": [0.19444, 0.69444, 0.04601, 0.11111],
|
| 1221 |
+
"959": [0, 0.43056, 0, 0.05556],
|
| 1222 |
+
"960": [0, 0.43056, 0.03588, 0],
|
| 1223 |
+
"961": [0.19444, 0.43056, 0, 0.08334],
|
| 1224 |
+
"962": [0.09722, 0.43056, 0.07986, 0.08334],
|
| 1225 |
+
"963": [0, 0.43056, 0.03588, 0],
|
| 1226 |
+
"964": [0, 0.43056, 0.1132, 0.02778],
|
| 1227 |
+
"965": [0, 0.43056, 0.03588, 0.02778],
|
| 1228 |
+
"966": [0.19444, 0.43056, 0, 0.08334],
|
| 1229 |
+
"967": [0.19444, 0.43056, 0, 0.05556],
|
| 1230 |
+
"968": [0.19444, 0.69444, 0.03588, 0.11111],
|
| 1231 |
+
"969": [0, 0.43056, 0.03588, 0],
|
| 1232 |
+
"977": [0, 0.69444, 0, 0.08334],
|
| 1233 |
+
"981": [0.19444, 0.69444, 0, 0.08334],
|
| 1234 |
+
"982": [0, 0.43056, 0.02778, 0],
|
| 1235 |
+
"1009": [0.19444, 0.43056, 0, 0.08334],
|
| 1236 |
+
"1013": [0, 0.43056, 0, 0.05556],
|
| 1237 |
+
},
|
| 1238 |
+
"Math-Regular": {
|
| 1239 |
+
"65": [0, 0.68333, 0, 0.13889],
|
| 1240 |
+
"66": [0, 0.68333, 0.05017, 0.08334],
|
| 1241 |
+
"67": [0, 0.68333, 0.07153, 0.08334],
|
| 1242 |
+
"68": [0, 0.68333, 0.02778, 0.05556],
|
| 1243 |
+
"69": [0, 0.68333, 0.05764, 0.08334],
|
| 1244 |
+
"70": [0, 0.68333, 0.13889, 0.08334],
|
| 1245 |
+
"71": [0, 0.68333, 0, 0.08334],
|
| 1246 |
+
"72": [0, 0.68333, 0.08125, 0.05556],
|
| 1247 |
+
"73": [0, 0.68333, 0.07847, 0.11111],
|
| 1248 |
+
"74": [0, 0.68333, 0.09618, 0.16667],
|
| 1249 |
+
"75": [0, 0.68333, 0.07153, 0.05556],
|
| 1250 |
+
"76": [0, 0.68333, 0, 0.02778],
|
| 1251 |
+
"77": [0, 0.68333, 0.10903, 0.08334],
|
| 1252 |
+
"78": [0, 0.68333, 0.10903, 0.08334],
|
| 1253 |
+
"79": [0, 0.68333, 0.02778, 0.08334],
|
| 1254 |
+
"80": [0, 0.68333, 0.13889, 0.08334],
|
| 1255 |
+
"81": [0.19444, 0.68333, 0, 0.08334],
|
| 1256 |
+
"82": [0, 0.68333, 0.00773, 0.08334],
|
| 1257 |
+
"83": [0, 0.68333, 0.05764, 0.08334],
|
| 1258 |
+
"84": [0, 0.68333, 0.13889, 0.08334],
|
| 1259 |
+
"85": [0, 0.68333, 0.10903, 0.02778],
|
| 1260 |
+
"86": [0, 0.68333, 0.22222, 0],
|
| 1261 |
+
"87": [0, 0.68333, 0.13889, 0],
|
| 1262 |
+
"88": [0, 0.68333, 0.07847, 0.08334],
|
| 1263 |
+
"89": [0, 0.68333, 0.22222, 0],
|
| 1264 |
+
"90": [0, 0.68333, 0.07153, 0.08334],
|
| 1265 |
+
"97": [0, 0.43056, 0, 0],
|
| 1266 |
+
"98": [0, 0.69444, 0, 0],
|
| 1267 |
+
"99": [0, 0.43056, 0, 0.05556],
|
| 1268 |
+
"100": [0, 0.69444, 0, 0.16667],
|
| 1269 |
+
"101": [0, 0.43056, 0, 0.05556],
|
| 1270 |
+
"102": [0.19444, 0.69444, 0.10764, 0.16667],
|
| 1271 |
+
"103": [0.19444, 0.43056, 0.03588, 0.02778],
|
| 1272 |
+
"104": [0, 0.69444, 0, 0],
|
| 1273 |
+
"105": [0, 0.65952, 0, 0],
|
| 1274 |
+
"106": [0.19444, 0.65952, 0.05724, 0],
|
| 1275 |
+
"107": [0, 0.69444, 0.03148, 0],
|
| 1276 |
+
"108": [0, 0.69444, 0.01968, 0.08334],
|
| 1277 |
+
"109": [0, 0.43056, 0, 0],
|
| 1278 |
+
"110": [0, 0.43056, 0, 0],
|
| 1279 |
+
"111": [0, 0.43056, 0, 0.05556],
|
| 1280 |
+
"112": [0.19444, 0.43056, 0, 0.08334],
|
| 1281 |
+
"113": [0.19444, 0.43056, 0.03588, 0.08334],
|
| 1282 |
+
"114": [0, 0.43056, 0.02778, 0.05556],
|
| 1283 |
+
"115": [0, 0.43056, 0, 0.05556],
|
| 1284 |
+
"116": [0, 0.61508, 0, 0.08334],
|
| 1285 |
+
"117": [0, 0.43056, 0, 0.02778],
|
| 1286 |
+
"118": [0, 0.43056, 0.03588, 0.02778],
|
| 1287 |
+
"119": [0, 0.43056, 0.02691, 0.08334],
|
| 1288 |
+
"120": [0, 0.43056, 0, 0.02778],
|
| 1289 |
+
"121": [0.19444, 0.43056, 0.03588, 0.05556],
|
| 1290 |
+
"122": [0, 0.43056, 0.04398, 0.05556],
|
| 1291 |
+
"915": [0, 0.68333, 0.13889, 0.08334],
|
| 1292 |
+
"916": [0, 0.68333, 0, 0.16667],
|
| 1293 |
+
"920": [0, 0.68333, 0.02778, 0.08334],
|
| 1294 |
+
"923": [0, 0.68333, 0, 0.16667],
|
| 1295 |
+
"926": [0, 0.68333, 0.07569, 0.08334],
|
| 1296 |
+
"928": [0, 0.68333, 0.08125, 0.05556],
|
| 1297 |
+
"931": [0, 0.68333, 0.05764, 0.08334],
|
| 1298 |
+
"933": [0, 0.68333, 0.13889, 0.05556],
|
| 1299 |
+
"934": [0, 0.68333, 0, 0.08334],
|
| 1300 |
+
"936": [0, 0.68333, 0.11, 0.05556],
|
| 1301 |
+
"937": [0, 0.68333, 0.05017, 0.08334],
|
| 1302 |
+
"945": [0, 0.43056, 0.0037, 0.02778],
|
| 1303 |
+
"946": [0.19444, 0.69444, 0.05278, 0.08334],
|
| 1304 |
+
"947": [0.19444, 0.43056, 0.05556, 0],
|
| 1305 |
+
"948": [0, 0.69444, 0.03785, 0.05556],
|
| 1306 |
+
"949": [0, 0.43056, 0, 0.08334],
|
| 1307 |
+
"950": [0.19444, 0.69444, 0.07378, 0.08334],
|
| 1308 |
+
"951": [0.19444, 0.43056, 0.03588, 0.05556],
|
| 1309 |
+
"952": [0, 0.69444, 0.02778, 0.08334],
|
| 1310 |
+
"953": [0, 0.43056, 0, 0.05556],
|
| 1311 |
+
"954": [0, 0.43056, 0, 0],
|
| 1312 |
+
"955": [0, 0.69444, 0, 0],
|
| 1313 |
+
"956": [0.19444, 0.43056, 0, 0.02778],
|
| 1314 |
+
"957": [0, 0.43056, 0.06366, 0.02778],
|
| 1315 |
+
"958": [0.19444, 0.69444, 0.04601, 0.11111],
|
| 1316 |
+
"959": [0, 0.43056, 0, 0.05556],
|
| 1317 |
+
"960": [0, 0.43056, 0.03588, 0],
|
| 1318 |
+
"961": [0.19444, 0.43056, 0, 0.08334],
|
| 1319 |
+
"962": [0.09722, 0.43056, 0.07986, 0.08334],
|
| 1320 |
+
"963": [0, 0.43056, 0.03588, 0],
|
| 1321 |
+
"964": [0, 0.43056, 0.1132, 0.02778],
|
| 1322 |
+
"965": [0, 0.43056, 0.03588, 0.02778],
|
| 1323 |
+
"966": [0.19444, 0.43056, 0, 0.08334],
|
| 1324 |
+
"967": [0.19444, 0.43056, 0, 0.05556],
|
| 1325 |
+
"968": [0.19444, 0.69444, 0.03588, 0.11111],
|
| 1326 |
+
"969": [0, 0.43056, 0.03588, 0],
|
| 1327 |
+
"977": [0, 0.69444, 0, 0.08334],
|
| 1328 |
+
"981": [0.19444, 0.69444, 0, 0.08334],
|
| 1329 |
+
"982": [0, 0.43056, 0.02778, 0],
|
| 1330 |
+
"1009": [0.19444, 0.43056, 0, 0.08334],
|
| 1331 |
+
"1013": [0, 0.43056, 0, 0.05556],
|
| 1332 |
+
},
|
| 1333 |
+
"SansSerif-Regular": {
|
| 1334 |
+
"33": [0, 0.69444, 0, 0],
|
| 1335 |
+
"34": [0, 0.69444, 0, 0],
|
| 1336 |
+
"35": [0.19444, 0.69444, 0, 0],
|
| 1337 |
+
"36": [0.05556, 0.75, 0, 0],
|
| 1338 |
+
"37": [0.05556, 0.75, 0, 0],
|
| 1339 |
+
"38": [0, 0.69444, 0, 0],
|
| 1340 |
+
"39": [0, 0.69444, 0, 0],
|
| 1341 |
+
"40": [0.25, 0.75, 0, 0],
|
| 1342 |
+
"41": [0.25, 0.75, 0, 0],
|
| 1343 |
+
"42": [0, 0.75, 0, 0],
|
| 1344 |
+
"43": [0.08333, 0.58333, 0, 0],
|
| 1345 |
+
"44": [0.125, 0.08333, 0, 0],
|
| 1346 |
+
"45": [0, 0.44444, 0, 0],
|
| 1347 |
+
"46": [0, 0.08333, 0, 0],
|
| 1348 |
+
"47": [0.25, 0.75, 0, 0],
|
| 1349 |
+
"48": [0, 0.65556, 0, 0],
|
| 1350 |
+
"49": [0, 0.65556, 0, 0],
|
| 1351 |
+
"50": [0, 0.65556, 0, 0],
|
| 1352 |
+
"51": [0, 0.65556, 0, 0],
|
| 1353 |
+
"52": [0, 0.65556, 0, 0],
|
| 1354 |
+
"53": [0, 0.65556, 0, 0],
|
| 1355 |
+
"54": [0, 0.65556, 0, 0],
|
| 1356 |
+
"55": [0, 0.65556, 0, 0],
|
| 1357 |
+
"56": [0, 0.65556, 0, 0],
|
| 1358 |
+
"57": [0, 0.65556, 0, 0],
|
| 1359 |
+
"58": [0, 0.44444, 0, 0],
|
| 1360 |
+
"59": [0.125, 0.44444, 0, 0],
|
| 1361 |
+
"61": [-0.13, 0.37, 0, 0],
|
| 1362 |
+
"63": [0, 0.69444, 0, 0],
|
| 1363 |
+
"64": [0, 0.69444, 0, 0],
|
| 1364 |
+
"65": [0, 0.69444, 0, 0],
|
| 1365 |
+
"66": [0, 0.69444, 0, 0],
|
| 1366 |
+
"67": [0, 0.69444, 0, 0],
|
| 1367 |
+
"68": [0, 0.69444, 0, 0],
|
| 1368 |
+
"69": [0, 0.69444, 0, 0],
|
| 1369 |
+
"70": [0, 0.69444, 0, 0],
|
| 1370 |
+
"71": [0, 0.69444, 0, 0],
|
| 1371 |
+
"72": [0, 0.69444, 0, 0],
|
| 1372 |
+
"73": [0, 0.69444, 0, 0],
|
| 1373 |
+
"74": [0, 0.69444, 0, 0],
|
| 1374 |
+
"75": [0, 0.69444, 0, 0],
|
| 1375 |
+
"76": [0, 0.69444, 0, 0],
|
| 1376 |
+
"77": [0, 0.69444, 0, 0],
|
| 1377 |
+
"78": [0, 0.69444, 0, 0],
|
| 1378 |
+
"79": [0, 0.69444, 0, 0],
|
| 1379 |
+
"80": [0, 0.69444, 0, 0],
|
| 1380 |
+
"81": [0.125, 0.69444, 0, 0],
|
| 1381 |
+
"82": [0, 0.69444, 0, 0],
|
| 1382 |
+
"83": [0, 0.69444, 0, 0],
|
| 1383 |
+
"84": [0, 0.69444, 0, 0],
|
| 1384 |
+
"85": [0, 0.69444, 0, 0],
|
| 1385 |
+
"86": [0, 0.69444, 0.01389, 0],
|
| 1386 |
+
"87": [0, 0.69444, 0.01389, 0],
|
| 1387 |
+
"88": [0, 0.69444, 0, 0],
|
| 1388 |
+
"89": [0, 0.69444, 0.025, 0],
|
| 1389 |
+
"90": [0, 0.69444, 0, 0],
|
| 1390 |
+
"91": [0.25, 0.75, 0, 0],
|
| 1391 |
+
"93": [0.25, 0.75, 0, 0],
|
| 1392 |
+
"94": [0, 0.69444, 0, 0],
|
| 1393 |
+
"95": [0.35, 0.09444, 0.02778, 0],
|
| 1394 |
+
"97": [0, 0.44444, 0, 0],
|
| 1395 |
+
"98": [0, 0.69444, 0, 0],
|
| 1396 |
+
"99": [0, 0.44444, 0, 0],
|
| 1397 |
+
"100": [0, 0.69444, 0, 0],
|
| 1398 |
+
"101": [0, 0.44444, 0, 0],
|
| 1399 |
+
"102": [0, 0.69444, 0.06944, 0],
|
| 1400 |
+
"103": [0.19444, 0.44444, 0.01389, 0],
|
| 1401 |
+
"104": [0, 0.69444, 0, 0],
|
| 1402 |
+
"105": [0, 0.67937, 0, 0],
|
| 1403 |
+
"106": [0.19444, 0.67937, 0, 0],
|
| 1404 |
+
"107": [0, 0.69444, 0, 0],
|
| 1405 |
+
"108": [0, 0.69444, 0, 0],
|
| 1406 |
+
"109": [0, 0.44444, 0, 0],
|
| 1407 |
+
"110": [0, 0.44444, 0, 0],
|
| 1408 |
+
"111": [0, 0.44444, 0, 0],
|
| 1409 |
+
"112": [0.19444, 0.44444, 0, 0],
|
| 1410 |
+
"113": [0.19444, 0.44444, 0, 0],
|
| 1411 |
+
"114": [0, 0.44444, 0.01389, 0],
|
| 1412 |
+
"115": [0, 0.44444, 0, 0],
|
| 1413 |
+
"116": [0, 0.57143, 0, 0],
|
| 1414 |
+
"117": [0, 0.44444, 0, 0],
|
| 1415 |
+
"118": [0, 0.44444, 0.01389, 0],
|
| 1416 |
+
"119": [0, 0.44444, 0.01389, 0],
|
| 1417 |
+
"120": [0, 0.44444, 0, 0],
|
| 1418 |
+
"121": [0.19444, 0.44444, 0.01389, 0],
|
| 1419 |
+
"122": [0, 0.44444, 0, 0],
|
| 1420 |
+
"126": [0.35, 0.32659, 0, 0],
|
| 1421 |
+
"305": [0, 0.44444, 0, 0],
|
| 1422 |
+
"567": [0.19444, 0.44444, 0, 0],
|
| 1423 |
+
"768": [0, 0.69444, 0, 0],
|
| 1424 |
+
"769": [0, 0.69444, 0, 0],
|
| 1425 |
+
"770": [0, 0.69444, 0, 0],
|
| 1426 |
+
"771": [0, 0.67659, 0, 0],
|
| 1427 |
+
"772": [0, 0.60889, 0, 0],
|
| 1428 |
+
"774": [0, 0.69444, 0, 0],
|
| 1429 |
+
"775": [0, 0.67937, 0, 0],
|
| 1430 |
+
"776": [0, 0.67937, 0, 0],
|
| 1431 |
+
"778": [0, 0.69444, 0, 0],
|
| 1432 |
+
"779": [0, 0.69444, 0, 0],
|
| 1433 |
+
"780": [0, 0.63194, 0, 0],
|
| 1434 |
+
"915": [0, 0.69444, 0, 0],
|
| 1435 |
+
"916": [0, 0.69444, 0, 0],
|
| 1436 |
+
"920": [0, 0.69444, 0, 0],
|
| 1437 |
+
"923": [0, 0.69444, 0, 0],
|
| 1438 |
+
"926": [0, 0.69444, 0, 0],
|
| 1439 |
+
"928": [0, 0.69444, 0, 0],
|
| 1440 |
+
"931": [0, 0.69444, 0, 0],
|
| 1441 |
+
"933": [0, 0.69444, 0, 0],
|
| 1442 |
+
"934": [0, 0.69444, 0, 0],
|
| 1443 |
+
"936": [0, 0.69444, 0, 0],
|
| 1444 |
+
"937": [0, 0.69444, 0, 0],
|
| 1445 |
+
"8211": [0, 0.44444, 0.02778, 0],
|
| 1446 |
+
"8212": [0, 0.44444, 0.02778, 0],
|
| 1447 |
+
"8216": [0, 0.69444, 0, 0],
|
| 1448 |
+
"8217": [0, 0.69444, 0, 0],
|
| 1449 |
+
"8220": [0, 0.69444, 0, 0],
|
| 1450 |
+
"8221": [0, 0.69444, 0, 0],
|
| 1451 |
+
},
|
| 1452 |
+
"Script-Regular": {
|
| 1453 |
+
"65": [0, 0.7, 0.22925, 0],
|
| 1454 |
+
"66": [0, 0.7, 0.04087, 0],
|
| 1455 |
+
"67": [0, 0.7, 0.1689, 0],
|
| 1456 |
+
"68": [0, 0.7, 0.09371, 0],
|
| 1457 |
+
"69": [0, 0.7, 0.18583, 0],
|
| 1458 |
+
"70": [0, 0.7, 0.13634, 0],
|
| 1459 |
+
"71": [0, 0.7, 0.17322, 0],
|
| 1460 |
+
"72": [0, 0.7, 0.29694, 0],
|
| 1461 |
+
"73": [0, 0.7, 0.19189, 0],
|
| 1462 |
+
"74": [0.27778, 0.7, 0.19189, 0],
|
| 1463 |
+
"75": [0, 0.7, 0.31259, 0],
|
| 1464 |
+
"76": [0, 0.7, 0.19189, 0],
|
| 1465 |
+
"77": [0, 0.7, 0.15981, 0],
|
| 1466 |
+
"78": [0, 0.7, 0.3525, 0],
|
| 1467 |
+
"79": [0, 0.7, 0.08078, 0],
|
| 1468 |
+
"80": [0, 0.7, 0.08078, 0],
|
| 1469 |
+
"81": [0, 0.7, 0.03305, 0],
|
| 1470 |
+
"82": [0, 0.7, 0.06259, 0],
|
| 1471 |
+
"83": [0, 0.7, 0.19189, 0],
|
| 1472 |
+
"84": [0, 0.7, 0.29087, 0],
|
| 1473 |
+
"85": [0, 0.7, 0.25815, 0],
|
| 1474 |
+
"86": [0, 0.7, 0.27523, 0],
|
| 1475 |
+
"87": [0, 0.7, 0.27523, 0],
|
| 1476 |
+
"88": [0, 0.7, 0.26006, 0],
|
| 1477 |
+
"89": [0, 0.7, 0.2939, 0],
|
| 1478 |
+
"90": [0, 0.7, 0.24037, 0],
|
| 1479 |
+
},
|
| 1480 |
+
"Size1-Regular": {
|
| 1481 |
+
"40": [0.35001, 0.85, 0, 0],
|
| 1482 |
+
"41": [0.35001, 0.85, 0, 0],
|
| 1483 |
+
"47": [0.35001, 0.85, 0, 0],
|
| 1484 |
+
"91": [0.35001, 0.85, 0, 0],
|
| 1485 |
+
"92": [0.35001, 0.85, 0, 0],
|
| 1486 |
+
"93": [0.35001, 0.85, 0, 0],
|
| 1487 |
+
"123": [0.35001, 0.85, 0, 0],
|
| 1488 |
+
"125": [0.35001, 0.85, 0, 0],
|
| 1489 |
+
"710": [0, 0.72222, 0, 0],
|
| 1490 |
+
"732": [0, 0.72222, 0, 0],
|
| 1491 |
+
"770": [0, 0.72222, 0, 0],
|
| 1492 |
+
"771": [0, 0.72222, 0, 0],
|
| 1493 |
+
"8214": [-0.00099, 0.601, 0, 0],
|
| 1494 |
+
"8593": [1e-05, 0.6, 0, 0],
|
| 1495 |
+
"8595": [1e-05, 0.6, 0, 0],
|
| 1496 |
+
"8657": [1e-05, 0.6, 0, 0],
|
| 1497 |
+
"8659": [1e-05, 0.6, 0, 0],
|
| 1498 |
+
"8719": [0.25001, 0.75, 0, 0],
|
| 1499 |
+
"8720": [0.25001, 0.75, 0, 0],
|
| 1500 |
+
"8721": [0.25001, 0.75, 0, 0],
|
| 1501 |
+
"8730": [0.35001, 0.85, 0, 0],
|
| 1502 |
+
"8739": [-0.00599, 0.606, 0, 0],
|
| 1503 |
+
"8741": [-0.00599, 0.606, 0, 0],
|
| 1504 |
+
"8747": [0.30612, 0.805, 0.19445, 0],
|
| 1505 |
+
"8748": [0.306, 0.805, 0.19445, 0],
|
| 1506 |
+
"8749": [0.306, 0.805, 0.19445, 0],
|
| 1507 |
+
"8750": [0.30612, 0.805, 0.19445, 0],
|
| 1508 |
+
"8896": [0.25001, 0.75, 0, 0],
|
| 1509 |
+
"8897": [0.25001, 0.75, 0, 0],
|
| 1510 |
+
"8898": [0.25001, 0.75, 0, 0],
|
| 1511 |
+
"8899": [0.25001, 0.75, 0, 0],
|
| 1512 |
+
"8968": [0.35001, 0.85, 0, 0],
|
| 1513 |
+
"8969": [0.35001, 0.85, 0, 0],
|
| 1514 |
+
"8970": [0.35001, 0.85, 0, 0],
|
| 1515 |
+
"8971": [0.35001, 0.85, 0, 0],
|
| 1516 |
+
"9168": [-0.00099, 0.601, 0, 0],
|
| 1517 |
+
"10216": [0.35001, 0.85, 0, 0],
|
| 1518 |
+
"10217": [0.35001, 0.85, 0, 0],
|
| 1519 |
+
"10752": [0.25001, 0.75, 0, 0],
|
| 1520 |
+
"10753": [0.25001, 0.75, 0, 0],
|
| 1521 |
+
"10754": [0.25001, 0.75, 0, 0],
|
| 1522 |
+
"10756": [0.25001, 0.75, 0, 0],
|
| 1523 |
+
"10758": [0.25001, 0.75, 0, 0],
|
| 1524 |
+
},
|
| 1525 |
+
"Size2-Regular": {
|
| 1526 |
+
"40": [0.65002, 1.15, 0, 0],
|
| 1527 |
+
"41": [0.65002, 1.15, 0, 0],
|
| 1528 |
+
"47": [0.65002, 1.15, 0, 0],
|
| 1529 |
+
"91": [0.65002, 1.15, 0, 0],
|
| 1530 |
+
"92": [0.65002, 1.15, 0, 0],
|
| 1531 |
+
"93": [0.65002, 1.15, 0, 0],
|
| 1532 |
+
"123": [0.65002, 1.15, 0, 0],
|
| 1533 |
+
"125": [0.65002, 1.15, 0, 0],
|
| 1534 |
+
"710": [0, 0.75, 0, 0],
|
| 1535 |
+
"732": [0, 0.75, 0, 0],
|
| 1536 |
+
"770": [0, 0.75, 0, 0],
|
| 1537 |
+
"771": [0, 0.75, 0, 0],
|
| 1538 |
+
"8719": [0.55001, 1.05, 0, 0],
|
| 1539 |
+
"8720": [0.55001, 1.05, 0, 0],
|
| 1540 |
+
"8721": [0.55001, 1.05, 0, 0],
|
| 1541 |
+
"8730": [0.65002, 1.15, 0, 0],
|
| 1542 |
+
"8747": [0.86225, 1.36, 0.44445, 0],
|
| 1543 |
+
"8748": [0.862, 1.36, 0.44445, 0],
|
| 1544 |
+
"8749": [0.862, 1.36, 0.44445, 0],
|
| 1545 |
+
"8750": [0.86225, 1.36, 0.44445, 0],
|
| 1546 |
+
"8896": [0.55001, 1.05, 0, 0],
|
| 1547 |
+
"8897": [0.55001, 1.05, 0, 0],
|
| 1548 |
+
"8898": [0.55001, 1.05, 0, 0],
|
| 1549 |
+
"8899": [0.55001, 1.05, 0, 0],
|
| 1550 |
+
"8968": [0.65002, 1.15, 0, 0],
|
| 1551 |
+
"8969": [0.65002, 1.15, 0, 0],
|
| 1552 |
+
"8970": [0.65002, 1.15, 0, 0],
|
| 1553 |
+
"8971": [0.65002, 1.15, 0, 0],
|
| 1554 |
+
"10216": [0.65002, 1.15, 0, 0],
|
| 1555 |
+
"10217": [0.65002, 1.15, 0, 0],
|
| 1556 |
+
"10752": [0.55001, 1.05, 0, 0],
|
| 1557 |
+
"10753": [0.55001, 1.05, 0, 0],
|
| 1558 |
+
"10754": [0.55001, 1.05, 0, 0],
|
| 1559 |
+
"10756": [0.55001, 1.05, 0, 0],
|
| 1560 |
+
"10758": [0.55001, 1.05, 0, 0],
|
| 1561 |
+
},
|
| 1562 |
+
"Size3-Regular": {
|
| 1563 |
+
"40": [0.95003, 1.45, 0, 0],
|
| 1564 |
+
"41": [0.95003, 1.45, 0, 0],
|
| 1565 |
+
"47": [0.95003, 1.45, 0, 0],
|
| 1566 |
+
"91": [0.95003, 1.45, 0, 0],
|
| 1567 |
+
"92": [0.95003, 1.45, 0, 0],
|
| 1568 |
+
"93": [0.95003, 1.45, 0, 0],
|
| 1569 |
+
"123": [0.95003, 1.45, 0, 0],
|
| 1570 |
+
"125": [0.95003, 1.45, 0, 0],
|
| 1571 |
+
"710": [0, 0.75, 0, 0],
|
| 1572 |
+
"732": [0, 0.75, 0, 0],
|
| 1573 |
+
"770": [0, 0.75, 0, 0],
|
| 1574 |
+
"771": [0, 0.75, 0, 0],
|
| 1575 |
+
"8730": [0.95003, 1.45, 0, 0],
|
| 1576 |
+
"8968": [0.95003, 1.45, 0, 0],
|
| 1577 |
+
"8969": [0.95003, 1.45, 0, 0],
|
| 1578 |
+
"8970": [0.95003, 1.45, 0, 0],
|
| 1579 |
+
"8971": [0.95003, 1.45, 0, 0],
|
| 1580 |
+
"10216": [0.95003, 1.45, 0, 0],
|
| 1581 |
+
"10217": [0.95003, 1.45, 0, 0],
|
| 1582 |
+
},
|
| 1583 |
+
"Size4-Regular": {
|
| 1584 |
+
"40": [1.25003, 1.75, 0, 0],
|
| 1585 |
+
"41": [1.25003, 1.75, 0, 0],
|
| 1586 |
+
"47": [1.25003, 1.75, 0, 0],
|
| 1587 |
+
"91": [1.25003, 1.75, 0, 0],
|
| 1588 |
+
"92": [1.25003, 1.75, 0, 0],
|
| 1589 |
+
"93": [1.25003, 1.75, 0, 0],
|
| 1590 |
+
"123": [1.25003, 1.75, 0, 0],
|
| 1591 |
+
"125": [1.25003, 1.75, 0, 0],
|
| 1592 |
+
"710": [0, 0.825, 0, 0],
|
| 1593 |
+
"732": [0, 0.825, 0, 0],
|
| 1594 |
+
"770": [0, 0.825, 0, 0],
|
| 1595 |
+
"771": [0, 0.825, 0, 0],
|
| 1596 |
+
"8730": [1.25003, 1.75, 0, 0],
|
| 1597 |
+
"8968": [1.25003, 1.75, 0, 0],
|
| 1598 |
+
"8969": [1.25003, 1.75, 0, 0],
|
| 1599 |
+
"8970": [1.25003, 1.75, 0, 0],
|
| 1600 |
+
"8971": [1.25003, 1.75, 0, 0],
|
| 1601 |
+
"9115": [0.64502, 1.155, 0, 0],
|
| 1602 |
+
"9116": [1e-05, 0.6, 0, 0],
|
| 1603 |
+
"9117": [0.64502, 1.155, 0, 0],
|
| 1604 |
+
"9118": [0.64502, 1.155, 0, 0],
|
| 1605 |
+
"9119": [1e-05, 0.6, 0, 0],
|
| 1606 |
+
"9120": [0.64502, 1.155, 0, 0],
|
| 1607 |
+
"9121": [0.64502, 1.155, 0, 0],
|
| 1608 |
+
"9122": [-0.00099, 0.601, 0, 0],
|
| 1609 |
+
"9123": [0.64502, 1.155, 0, 0],
|
| 1610 |
+
"9124": [0.64502, 1.155, 0, 0],
|
| 1611 |
+
"9125": [-0.00099, 0.601, 0, 0],
|
| 1612 |
+
"9126": [0.64502, 1.155, 0, 0],
|
| 1613 |
+
"9127": [1e-05, 0.9, 0, 0],
|
| 1614 |
+
"9128": [0.65002, 1.15, 0, 0],
|
| 1615 |
+
"9129": [0.90001, 0, 0, 0],
|
| 1616 |
+
"9130": [0, 0.3, 0, 0],
|
| 1617 |
+
"9131": [1e-05, 0.9, 0, 0],
|
| 1618 |
+
"9132": [0.65002, 1.15, 0, 0],
|
| 1619 |
+
"9133": [0.90001, 0, 0, 0],
|
| 1620 |
+
"9143": [0.88502, 0.915, 0, 0],
|
| 1621 |
+
"10216": [1.25003, 1.75, 0, 0],
|
| 1622 |
+
"10217": [1.25003, 1.75, 0, 0],
|
| 1623 |
+
"57344": [-0.00499, 0.605, 0, 0],
|
| 1624 |
+
"57345": [-0.00499, 0.605, 0, 0],
|
| 1625 |
+
"57680": [0, 0.12, 0, 0],
|
| 1626 |
+
"57681": [0, 0.12, 0, 0],
|
| 1627 |
+
"57682": [0, 0.12, 0, 0],
|
| 1628 |
+
"57683": [0, 0.12, 0, 0],
|
| 1629 |
+
},
|
| 1630 |
+
"Typewriter-Regular": {
|
| 1631 |
+
"33": [0, 0.61111, 0, 0],
|
| 1632 |
+
"34": [0, 0.61111, 0, 0],
|
| 1633 |
+
"35": [0, 0.61111, 0, 0],
|
| 1634 |
+
"36": [0.08333, 0.69444, 0, 0],
|
| 1635 |
+
"37": [0.08333, 0.69444, 0, 0],
|
| 1636 |
+
"38": [0, 0.61111, 0, 0],
|
| 1637 |
+
"39": [0, 0.61111, 0, 0],
|
| 1638 |
+
"40": [0.08333, 0.69444, 0, 0],
|
| 1639 |
+
"41": [0.08333, 0.69444, 0, 0],
|
| 1640 |
+
"42": [0, 0.52083, 0, 0],
|
| 1641 |
+
"43": [-0.08056, 0.53055, 0, 0],
|
| 1642 |
+
"44": [0.13889, 0.125, 0, 0],
|
| 1643 |
+
"45": [-0.08056, 0.53055, 0, 0],
|
| 1644 |
+
"46": [0, 0.125, 0, 0],
|
| 1645 |
+
"47": [0.08333, 0.69444, 0, 0],
|
| 1646 |
+
"48": [0, 0.61111, 0, 0],
|
| 1647 |
+
"49": [0, 0.61111, 0, 0],
|
| 1648 |
+
"50": [0, 0.61111, 0, 0],
|
| 1649 |
+
"51": [0, 0.61111, 0, 0],
|
| 1650 |
+
"52": [0, 0.61111, 0, 0],
|
| 1651 |
+
"53": [0, 0.61111, 0, 0],
|
| 1652 |
+
"54": [0, 0.61111, 0, 0],
|
| 1653 |
+
"55": [0, 0.61111, 0, 0],
|
| 1654 |
+
"56": [0, 0.61111, 0, 0],
|
| 1655 |
+
"57": [0, 0.61111, 0, 0],
|
| 1656 |
+
"58": [0, 0.43056, 0, 0],
|
| 1657 |
+
"59": [0.13889, 0.43056, 0, 0],
|
| 1658 |
+
"60": [-0.05556, 0.55556, 0, 0],
|
| 1659 |
+
"61": [-0.19549, 0.41562, 0, 0],
|
| 1660 |
+
"62": [-0.05556, 0.55556, 0, 0],
|
| 1661 |
+
"63": [0, 0.61111, 0, 0],
|
| 1662 |
+
"64": [0, 0.61111, 0, 0],
|
| 1663 |
+
"65": [0, 0.61111, 0, 0],
|
| 1664 |
+
"66": [0, 0.61111, 0, 0],
|
| 1665 |
+
"67": [0, 0.61111, 0, 0],
|
| 1666 |
+
"68": [0, 0.61111, 0, 0],
|
| 1667 |
+
"69": [0, 0.61111, 0, 0],
|
| 1668 |
+
"70": [0, 0.61111, 0, 0],
|
| 1669 |
+
"71": [0, 0.61111, 0, 0],
|
| 1670 |
+
"72": [0, 0.61111, 0, 0],
|
| 1671 |
+
"73": [0, 0.61111, 0, 0],
|
| 1672 |
+
"74": [0, 0.61111, 0, 0],
|
| 1673 |
+
"75": [0, 0.61111, 0, 0],
|
| 1674 |
+
"76": [0, 0.61111, 0, 0],
|
| 1675 |
+
"77": [0, 0.61111, 0, 0],
|
| 1676 |
+
"78": [0, 0.61111, 0, 0],
|
| 1677 |
+
"79": [0, 0.61111, 0, 0],
|
| 1678 |
+
"80": [0, 0.61111, 0, 0],
|
| 1679 |
+
"81": [0.13889, 0.61111, 0, 0],
|
| 1680 |
+
"82": [0, 0.61111, 0, 0],
|
| 1681 |
+
"83": [0, 0.61111, 0, 0],
|
| 1682 |
+
"84": [0, 0.61111, 0, 0],
|
| 1683 |
+
"85": [0, 0.61111, 0, 0],
|
| 1684 |
+
"86": [0, 0.61111, 0, 0],
|
| 1685 |
+
"87": [0, 0.61111, 0, 0],
|
| 1686 |
+
"88": [0, 0.61111, 0, 0],
|
| 1687 |
+
"89": [0, 0.61111, 0, 0],
|
| 1688 |
+
"90": [0, 0.61111, 0, 0],
|
| 1689 |
+
"91": [0.08333, 0.69444, 0, 0],
|
| 1690 |
+
"92": [0.08333, 0.69444, 0, 0],
|
| 1691 |
+
"93": [0.08333, 0.69444, 0, 0],
|
| 1692 |
+
"94": [0, 0.61111, 0, 0],
|
| 1693 |
+
"95": [0.09514, 0, 0, 0],
|
| 1694 |
+
"96": [0, 0.61111, 0, 0],
|
| 1695 |
+
"97": [0, 0.43056, 0, 0],
|
| 1696 |
+
"98": [0, 0.61111, 0, 0],
|
| 1697 |
+
"99": [0, 0.43056, 0, 0],
|
| 1698 |
+
"100": [0, 0.61111, 0, 0],
|
| 1699 |
+
"101": [0, 0.43056, 0, 0],
|
| 1700 |
+
"102": [0, 0.61111, 0, 0],
|
| 1701 |
+
"103": [0.22222, 0.43056, 0, 0],
|
| 1702 |
+
"104": [0, 0.61111, 0, 0],
|
| 1703 |
+
"105": [0, 0.61111, 0, 0],
|
| 1704 |
+
"106": [0.22222, 0.61111, 0, 0],
|
| 1705 |
+
"107": [0, 0.61111, 0, 0],
|
| 1706 |
+
"108": [0, 0.61111, 0, 0],
|
| 1707 |
+
"109": [0, 0.43056, 0, 0],
|
| 1708 |
+
"110": [0, 0.43056, 0, 0],
|
| 1709 |
+
"111": [0, 0.43056, 0, 0],
|
| 1710 |
+
"112": [0.22222, 0.43056, 0, 0],
|
| 1711 |
+
"113": [0.22222, 0.43056, 0, 0],
|
| 1712 |
+
"114": [0, 0.43056, 0, 0],
|
| 1713 |
+
"115": [0, 0.43056, 0, 0],
|
| 1714 |
+
"116": [0, 0.55358, 0, 0],
|
| 1715 |
+
"117": [0, 0.43056, 0, 0],
|
| 1716 |
+
"118": [0, 0.43056, 0, 0],
|
| 1717 |
+
"119": [0, 0.43056, 0, 0],
|
| 1718 |
+
"120": [0, 0.43056, 0, 0],
|
| 1719 |
+
"121": [0.22222, 0.43056, 0, 0],
|
| 1720 |
+
"122": [0, 0.43056, 0, 0],
|
| 1721 |
+
"123": [0.08333, 0.69444, 0, 0],
|
| 1722 |
+
"124": [0.08333, 0.69444, 0, 0],
|
| 1723 |
+
"125": [0.08333, 0.69444, 0, 0],
|
| 1724 |
+
"126": [0, 0.61111, 0, 0],
|
| 1725 |
+
"127": [0, 0.61111, 0, 0],
|
| 1726 |
+
"305": [0, 0.43056, 0, 0],
|
| 1727 |
+
"567": [0.22222, 0.43056, 0, 0],
|
| 1728 |
+
"768": [0, 0.61111, 0, 0],
|
| 1729 |
+
"769": [0, 0.61111, 0, 0],
|
| 1730 |
+
"770": [0, 0.61111, 0, 0],
|
| 1731 |
+
"771": [0, 0.61111, 0, 0],
|
| 1732 |
+
"772": [0, 0.56555, 0, 0],
|
| 1733 |
+
"774": [0, 0.61111, 0, 0],
|
| 1734 |
+
"776": [0, 0.61111, 0, 0],
|
| 1735 |
+
"778": [0, 0.61111, 0, 0],
|
| 1736 |
+
"780": [0, 0.56597, 0, 0],
|
| 1737 |
+
"915": [0, 0.61111, 0, 0],
|
| 1738 |
+
"916": [0, 0.61111, 0, 0],
|
| 1739 |
+
"920": [0, 0.61111, 0, 0],
|
| 1740 |
+
"923": [0, 0.61111, 0, 0],
|
| 1741 |
+
"926": [0, 0.61111, 0, 0],
|
| 1742 |
+
"928": [0, 0.61111, 0, 0],
|
| 1743 |
+
"931": [0, 0.61111, 0, 0],
|
| 1744 |
+
"933": [0, 0.61111, 0, 0],
|
| 1745 |
+
"934": [0, 0.61111, 0, 0],
|
| 1746 |
+
"936": [0, 0.61111, 0, 0],
|
| 1747 |
+
"937": [0, 0.61111, 0, 0],
|
| 1748 |
+
"2018": [0, 0.61111, 0, 0],
|
| 1749 |
+
"2019": [0, 0.61111, 0, 0],
|
| 1750 |
+
"8242": [0, 0.61111, 0, 0],
|
| 1751 |
+
},
|
| 1752 |
+
};
|
katex/src/functions.js
ADDED
|
@@ -0,0 +1,585 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
var utils = require("./utils");
|
| 2 |
+
var ParseError = require("./ParseError");
|
| 3 |
+
|
| 4 |
+
/* This file contains a list of functions that we parse, identified by
|
| 5 |
+
* the calls to defineFunction.
|
| 6 |
+
*
|
| 7 |
+
* The first argument to defineFunction is a single name or a list of names.
|
| 8 |
+
* All functions named in such a list will share a single implementation.
|
| 9 |
+
*
|
| 10 |
+
* Each declared function can have associated properties, which
|
| 11 |
+
* include the following:
|
| 12 |
+
*
|
| 13 |
+
* - numArgs: The number of arguments the function takes.
|
| 14 |
+
* If this is the only property, it can be passed as a number
|
| 15 |
+
* instead of an element of a properties object.
|
| 16 |
+
* - argTypes: (optional) An array corresponding to each argument of the
|
| 17 |
+
* function, giving the type of argument that should be parsed. Its
|
| 18 |
+
* length should be equal to `numArgs + numOptionalArgs`. Valid
|
| 19 |
+
* types:
|
| 20 |
+
* - "size": A size-like thing, such as "1em" or "5ex"
|
| 21 |
+
* - "color": An html color, like "#abc" or "blue"
|
| 22 |
+
* - "original": The same type as the environment that the
|
| 23 |
+
* function being parsed is in (e.g. used for the
|
| 24 |
+
* bodies of functions like \color where the first
|
| 25 |
+
* argument is special and the second argument is
|
| 26 |
+
* parsed normally)
|
| 27 |
+
* Other possible types (probably shouldn't be used)
|
| 28 |
+
* - "text": Text-like (e.g. \text)
|
| 29 |
+
* - "math": Normal math
|
| 30 |
+
* If undefined, this will be treated as an appropriate length
|
| 31 |
+
* array of "original" strings
|
| 32 |
+
* - greediness: (optional) The greediness of the function to use ungrouped
|
| 33 |
+
* arguments.
|
| 34 |
+
*
|
| 35 |
+
* E.g. if you have an expression
|
| 36 |
+
* \sqrt \frac 1 2
|
| 37 |
+
* since \frac has greediness=2 vs \sqrt's greediness=1, \frac
|
| 38 |
+
* will use the two arguments '1' and '2' as its two arguments,
|
| 39 |
+
* then that whole function will be used as the argument to
|
| 40 |
+
* \sqrt. On the other hand, the expressions
|
| 41 |
+
* \frac \frac 1 2 3
|
| 42 |
+
* and
|
| 43 |
+
* \frac \sqrt 1 2
|
| 44 |
+
* will fail because \frac and \frac have equal greediness
|
| 45 |
+
* and \sqrt has a lower greediness than \frac respectively. To
|
| 46 |
+
* make these parse, we would have to change them to:
|
| 47 |
+
* \frac {\frac 1 2} 3
|
| 48 |
+
* and
|
| 49 |
+
* \frac {\sqrt 1} 2
|
| 50 |
+
*
|
| 51 |
+
* The default value is `1`
|
| 52 |
+
* - allowedInText: (optional) Whether or not the function is allowed inside
|
| 53 |
+
* text mode (default false)
|
| 54 |
+
* - numOptionalArgs: (optional) The number of optional arguments the function
|
| 55 |
+
* should parse. If the optional arguments aren't found,
|
| 56 |
+
* `null` will be passed to the handler in their place.
|
| 57 |
+
* (default 0)
|
| 58 |
+
*
|
| 59 |
+
* The last argument is that implementation, the handler for the function(s).
|
| 60 |
+
* It is called to handle these functions and their arguments.
|
| 61 |
+
* It receives two arguments:
|
| 62 |
+
* - context contains information and references provided by the parser
|
| 63 |
+
* - args is an array of arguments obtained from TeX input
|
| 64 |
+
* The context contains the following properties:
|
| 65 |
+
* - funcName: the text (i.e. name) of the function, including \
|
| 66 |
+
* - parser: the parser object
|
| 67 |
+
* - lexer: the lexer object
|
| 68 |
+
* - positions: the positions in the overall string of the function
|
| 69 |
+
* and the arguments.
|
| 70 |
+
* The latter three should only be used to produce error messages.
|
| 71 |
+
*
|
| 72 |
+
* The function should return an object with the following keys:
|
| 73 |
+
* - type: The type of element that this is. This is then used in
|
| 74 |
+
* buildHTML/buildMathML to determine which function
|
| 75 |
+
* should be called to build this node into a DOM node
|
| 76 |
+
* Any other data can be added to the object, which will be passed
|
| 77 |
+
* in to the function in buildHTML/buildMathML as `group.value`.
|
| 78 |
+
*/
|
| 79 |
+
|
| 80 |
+
function defineFunction(names, props, handler) {
|
| 81 |
+
if (typeof names === "string") {
|
| 82 |
+
names = [names];
|
| 83 |
+
}
|
| 84 |
+
if (typeof props === "number") {
|
| 85 |
+
props = { numArgs: props };
|
| 86 |
+
}
|
| 87 |
+
// Set default values of functions
|
| 88 |
+
var data = {
|
| 89 |
+
numArgs: props.numArgs,
|
| 90 |
+
argTypes: props.argTypes,
|
| 91 |
+
greediness: (props.greediness === undefined) ? 1 : props.greediness,
|
| 92 |
+
allowedInText: !!props.allowedInText,
|
| 93 |
+
numOptionalArgs: props.numOptionalArgs || 0,
|
| 94 |
+
handler: handler,
|
| 95 |
+
};
|
| 96 |
+
for (var i = 0; i < names.length; ++i) {
|
| 97 |
+
module.exports[names[i]] = data;
|
| 98 |
+
}
|
| 99 |
+
}
|
| 100 |
+
|
| 101 |
+
// A normal square root
|
| 102 |
+
defineFunction("\\sqrt", {
|
| 103 |
+
numArgs: 1,
|
| 104 |
+
numOptionalArgs: 1,
|
| 105 |
+
}, function(context, args) {
|
| 106 |
+
var index = args[0];
|
| 107 |
+
var body = args[1];
|
| 108 |
+
return {
|
| 109 |
+
type: "sqrt",
|
| 110 |
+
body: body,
|
| 111 |
+
index: index,
|
| 112 |
+
};
|
| 113 |
+
});
|
| 114 |
+
|
| 115 |
+
// Some non-mathy text
|
| 116 |
+
defineFunction(["\\text", "\\mbox", "\\hbox", "\\vbox"], {
|
| 117 |
+
numArgs: 1,
|
| 118 |
+
argTypes: ["text"],
|
| 119 |
+
greediness: 2,
|
| 120 |
+
}, function(context, args) {
|
| 121 |
+
var body = args[0];
|
| 122 |
+
// Since the corresponding buildHTML/buildMathML function expects a
|
| 123 |
+
// list of elements, we normalize for different kinds of arguments
|
| 124 |
+
// TODO(emily): maybe this should be done somewhere else
|
| 125 |
+
var inner;
|
| 126 |
+
if (body.type === "ordgroup") {
|
| 127 |
+
inner = body.value;
|
| 128 |
+
} else {
|
| 129 |
+
inner = [body];
|
| 130 |
+
}
|
| 131 |
+
|
| 132 |
+
return {
|
| 133 |
+
type: "text",
|
| 134 |
+
body: inner,
|
| 135 |
+
};
|
| 136 |
+
});
|
| 137 |
+
|
| 138 |
+
// A two-argument custom color
|
| 139 |
+
defineFunction("\\color", {
|
| 140 |
+
numArgs: 2,
|
| 141 |
+
allowedInText: true,
|
| 142 |
+
greediness: 3,
|
| 143 |
+
argTypes: ["color", "original"],
|
| 144 |
+
}, function(context, args) {
|
| 145 |
+
var color = args[0];
|
| 146 |
+
var body = args[1];
|
| 147 |
+
// Normalize the different kinds of bodies (see \text above)
|
| 148 |
+
var inner;
|
| 149 |
+
if (body.type === "ordgroup") {
|
| 150 |
+
inner = body.value;
|
| 151 |
+
} else {
|
| 152 |
+
inner = [body];
|
| 153 |
+
}
|
| 154 |
+
|
| 155 |
+
return {
|
| 156 |
+
type: "color",
|
| 157 |
+
color: color.value,
|
| 158 |
+
value: inner,
|
| 159 |
+
};
|
| 160 |
+
});
|
| 161 |
+
|
| 162 |
+
// An overline
|
| 163 |
+
defineFunction("\\overline", {
|
| 164 |
+
numArgs: 1,
|
| 165 |
+
}, function(context, args) {
|
| 166 |
+
var body = args[0];
|
| 167 |
+
return {
|
| 168 |
+
type: "overline",
|
| 169 |
+
body: body,
|
| 170 |
+
};
|
| 171 |
+
});
|
| 172 |
+
|
| 173 |
+
// An underline
|
| 174 |
+
defineFunction("\\underline", {
|
| 175 |
+
numArgs: 1,
|
| 176 |
+
}, function(context, args) {
|
| 177 |
+
var body = args[0];
|
| 178 |
+
return {
|
| 179 |
+
type: "underline",
|
| 180 |
+
body: body,
|
| 181 |
+
};
|
| 182 |
+
});
|
| 183 |
+
|
| 184 |
+
// A box of the width and height
|
| 185 |
+
defineFunction("\\rule", {
|
| 186 |
+
numArgs: 2,
|
| 187 |
+
numOptionalArgs: 1,
|
| 188 |
+
argTypes: ["size", "size", "size"],
|
| 189 |
+
}, function(context, args) {
|
| 190 |
+
var shift = args[0];
|
| 191 |
+
var width = args[1];
|
| 192 |
+
var height = args[2];
|
| 193 |
+
return {
|
| 194 |
+
type: "rule",
|
| 195 |
+
shift: shift && shift.value,
|
| 196 |
+
width: width.value,
|
| 197 |
+
height: height.value,
|
| 198 |
+
};
|
| 199 |
+
});
|
| 200 |
+
|
| 201 |
+
// A KaTeX logo
|
| 202 |
+
defineFunction("\\KaTeX", {
|
| 203 |
+
numArgs: 0,
|
| 204 |
+
}, function(context) {
|
| 205 |
+
return {
|
| 206 |
+
type: "katex",
|
| 207 |
+
};
|
| 208 |
+
});
|
| 209 |
+
|
| 210 |
+
defineFunction("\\phantom", {
|
| 211 |
+
numArgs: 1,
|
| 212 |
+
}, function(context, args) {
|
| 213 |
+
var body = args[0];
|
| 214 |
+
var inner;
|
| 215 |
+
if (body.type === "ordgroup") {
|
| 216 |
+
inner = body.value;
|
| 217 |
+
} else {
|
| 218 |
+
inner = [body];
|
| 219 |
+
}
|
| 220 |
+
|
| 221 |
+
return {
|
| 222 |
+
type: "phantom",
|
| 223 |
+
value: inner,
|
| 224 |
+
};
|
| 225 |
+
});
|
| 226 |
+
|
| 227 |
+
// Extra data needed for the delimiter handler down below
|
| 228 |
+
var delimiterSizes = {
|
| 229 |
+
"\\bigl" : {type: "open", size: 1},
|
| 230 |
+
"\\Bigl" : {type: "open", size: 2},
|
| 231 |
+
"\\biggl": {type: "open", size: 3},
|
| 232 |
+
"\\Biggl": {type: "open", size: 4},
|
| 233 |
+
"\\bigr" : {type: "close", size: 1},
|
| 234 |
+
"\\Bigr" : {type: "close", size: 2},
|
| 235 |
+
"\\biggr": {type: "close", size: 3},
|
| 236 |
+
"\\Biggr": {type: "close", size: 4},
|
| 237 |
+
"\\bigm" : {type: "rel", size: 1},
|
| 238 |
+
"\\Bigm" : {type: "rel", size: 2},
|
| 239 |
+
"\\biggm": {type: "rel", size: 3},
|
| 240 |
+
"\\Biggm": {type: "rel", size: 4},
|
| 241 |
+
"\\big" : {type: "textord", size: 1},
|
| 242 |
+
"\\Big" : {type: "textord", size: 2},
|
| 243 |
+
"\\bigg" : {type: "textord", size: 3},
|
| 244 |
+
"\\Bigg" : {type: "textord", size: 4},
|
| 245 |
+
};
|
| 246 |
+
|
| 247 |
+
var delimiters = [
|
| 248 |
+
"(", ")", "[", "\\lbrack", "]", "\\rbrack",
|
| 249 |
+
"\\{", "\\lbrace", "\\}", "\\rbrace",
|
| 250 |
+
"\\lfloor", "\\rfloor", "\\lceil", "\\rceil",
|
| 251 |
+
"<", ">", "\\langle", "\\rangle", "\\lt", "\\gt",
|
| 252 |
+
"\\lvert", "\\rvert", "\\lVert", "\\rVert",
|
| 253 |
+
"\\lgroup", "\\rgroup", "\\lmoustache", "\\rmoustache",
|
| 254 |
+
"/", "\\backslash",
|
| 255 |
+
"|", "\\vert", "\\|", "\\Vert",
|
| 256 |
+
"\\uparrow", "\\Uparrow",
|
| 257 |
+
"\\downarrow", "\\Downarrow",
|
| 258 |
+
"\\updownarrow", "\\Updownarrow",
|
| 259 |
+
".",
|
| 260 |
+
];
|
| 261 |
+
|
| 262 |
+
var fontAliases = {
|
| 263 |
+
"\\Bbb": "\\mathbb",
|
| 264 |
+
"\\bold": "\\mathbf",
|
| 265 |
+
"\\frak": "\\mathfrak",
|
| 266 |
+
};
|
| 267 |
+
|
| 268 |
+
// Single-argument color functions
|
| 269 |
+
defineFunction([
|
| 270 |
+
"\\blue", "\\orange", "\\pink", "\\red",
|
| 271 |
+
"\\green", "\\gray", "\\purple",
|
| 272 |
+
"\\blueA", "\\blueB", "\\blueC", "\\blueD", "\\blueE",
|
| 273 |
+
"\\tealA", "\\tealB", "\\tealC", "\\tealD", "\\tealE",
|
| 274 |
+
"\\greenA", "\\greenB", "\\greenC", "\\greenD", "\\greenE",
|
| 275 |
+
"\\goldA", "\\goldB", "\\goldC", "\\goldD", "\\goldE",
|
| 276 |
+
"\\redA", "\\redB", "\\redC", "\\redD", "\\redE",
|
| 277 |
+
"\\maroonA", "\\maroonB", "\\maroonC", "\\maroonD", "\\maroonE",
|
| 278 |
+
"\\purpleA", "\\purpleB", "\\purpleC", "\\purpleD", "\\purpleE",
|
| 279 |
+
"\\mintA", "\\mintB", "\\mintC",
|
| 280 |
+
"\\grayA", "\\grayB", "\\grayC", "\\grayD", "\\grayE",
|
| 281 |
+
"\\grayF", "\\grayG", "\\grayH", "\\grayI",
|
| 282 |
+
"\\kaBlue", "\\kaGreen",
|
| 283 |
+
], {
|
| 284 |
+
numArgs: 1,
|
| 285 |
+
allowedInText: true,
|
| 286 |
+
greediness: 3,
|
| 287 |
+
}, function(context, args) {
|
| 288 |
+
var body = args[0];
|
| 289 |
+
var atoms;
|
| 290 |
+
if (body.type === "ordgroup") {
|
| 291 |
+
atoms = body.value;
|
| 292 |
+
} else {
|
| 293 |
+
atoms = [body];
|
| 294 |
+
}
|
| 295 |
+
|
| 296 |
+
return {
|
| 297 |
+
type: "color",
|
| 298 |
+
color: "katex-" + context.funcName.slice(1),
|
| 299 |
+
value: atoms,
|
| 300 |
+
};
|
| 301 |
+
});
|
| 302 |
+
|
| 303 |
+
// There are 2 flags for operators; whether they produce limits in
|
| 304 |
+
// displaystyle, and whether they are symbols and should grow in
|
| 305 |
+
// displaystyle. These four groups cover the four possible choices.
|
| 306 |
+
|
| 307 |
+
// No limits, not symbols
|
| 308 |
+
defineFunction([
|
| 309 |
+
"\\arcsin", "\\arccos", "\\arctan", "\\arg", "\\cos", "\\cosh",
|
| 310 |
+
"\\cot", "\\coth", "\\csc", "\\deg", "\\dim", "\\exp", "\\hom",
|
| 311 |
+
"\\ker", "\\lg", "\\ln", "\\log", "\\sec", "\\sin", "\\sinh",
|
| 312 |
+
"\\tan", "\\tanh",
|
| 313 |
+
], {
|
| 314 |
+
numArgs: 0,
|
| 315 |
+
}, function(context) {
|
| 316 |
+
return {
|
| 317 |
+
type: "op",
|
| 318 |
+
limits: false,
|
| 319 |
+
symbol: false,
|
| 320 |
+
body: context.funcName,
|
| 321 |
+
};
|
| 322 |
+
});
|
| 323 |
+
|
| 324 |
+
// Limits, not symbols
|
| 325 |
+
defineFunction([
|
| 326 |
+
"\\det", "\\gcd", "\\inf", "\\lim", "\\liminf", "\\limsup", "\\max",
|
| 327 |
+
"\\min", "\\Pr", "\\sup",
|
| 328 |
+
], {
|
| 329 |
+
numArgs: 0,
|
| 330 |
+
}, function(context) {
|
| 331 |
+
return {
|
| 332 |
+
type: "op",
|
| 333 |
+
limits: true,
|
| 334 |
+
symbol: false,
|
| 335 |
+
body: context.funcName,
|
| 336 |
+
};
|
| 337 |
+
});
|
| 338 |
+
|
| 339 |
+
// No limits, symbols
|
| 340 |
+
defineFunction([
|
| 341 |
+
"\\int", "\\iint", "\\iiint", "\\oint",
|
| 342 |
+
], {
|
| 343 |
+
numArgs: 0,
|
| 344 |
+
}, function(context) {
|
| 345 |
+
return {
|
| 346 |
+
type: "op",
|
| 347 |
+
limits: false,
|
| 348 |
+
symbol: true,
|
| 349 |
+
body: context.funcName,
|
| 350 |
+
};
|
| 351 |
+
});
|
| 352 |
+
|
| 353 |
+
// Limits, symbols
|
| 354 |
+
defineFunction([
|
| 355 |
+
"\\coprod", "\\bigvee", "\\bigwedge", "\\biguplus", "\\bigcap",
|
| 356 |
+
"\\bigcup", "\\intop", "\\prod", "\\sum", "\\bigotimes",
|
| 357 |
+
"\\bigoplus", "\\bigodot", "\\bigsqcup", "\\smallint",
|
| 358 |
+
], {
|
| 359 |
+
numArgs: 0,
|
| 360 |
+
}, function(context) {
|
| 361 |
+
return {
|
| 362 |
+
type: "op",
|
| 363 |
+
limits: true,
|
| 364 |
+
symbol: true,
|
| 365 |
+
body: context.funcName,
|
| 366 |
+
};
|
| 367 |
+
});
|
| 368 |
+
|
| 369 |
+
// Fractions
|
| 370 |
+
defineFunction([
|
| 371 |
+
"\\dfrac", "\\frac", "\\tfrac",
|
| 372 |
+
"\\dbinom", "\\binom", "\\tbinom",
|
| 373 |
+
], {
|
| 374 |
+
numArgs: 2,
|
| 375 |
+
greediness: 2,
|
| 376 |
+
}, function(context, args) {
|
| 377 |
+
var numer = args[0];
|
| 378 |
+
var denom = args[1];
|
| 379 |
+
var hasBarLine;
|
| 380 |
+
var leftDelim = null;
|
| 381 |
+
var rightDelim = null;
|
| 382 |
+
var size = "auto";
|
| 383 |
+
|
| 384 |
+
switch (context.funcName) {
|
| 385 |
+
case "\\dfrac":
|
| 386 |
+
case "\\frac":
|
| 387 |
+
case "\\tfrac":
|
| 388 |
+
hasBarLine = true;
|
| 389 |
+
break;
|
| 390 |
+
case "\\dbinom":
|
| 391 |
+
case "\\binom":
|
| 392 |
+
case "\\tbinom":
|
| 393 |
+
hasBarLine = false;
|
| 394 |
+
leftDelim = "(";
|
| 395 |
+
rightDelim = ")";
|
| 396 |
+
break;
|
| 397 |
+
default:
|
| 398 |
+
throw new Error("Unrecognized genfrac command");
|
| 399 |
+
}
|
| 400 |
+
|
| 401 |
+
switch (context.funcName) {
|
| 402 |
+
case "\\dfrac":
|
| 403 |
+
case "\\dbinom":
|
| 404 |
+
size = "display";
|
| 405 |
+
break;
|
| 406 |
+
case "\\tfrac":
|
| 407 |
+
case "\\tbinom":
|
| 408 |
+
size = "text";
|
| 409 |
+
break;
|
| 410 |
+
}
|
| 411 |
+
|
| 412 |
+
return {
|
| 413 |
+
type: "genfrac",
|
| 414 |
+
numer: numer,
|
| 415 |
+
denom: denom,
|
| 416 |
+
hasBarLine: hasBarLine,
|
| 417 |
+
leftDelim: leftDelim,
|
| 418 |
+
rightDelim: rightDelim,
|
| 419 |
+
size: size,
|
| 420 |
+
};
|
| 421 |
+
});
|
| 422 |
+
|
| 423 |
+
// Left and right overlap functions
|
| 424 |
+
defineFunction(["\\llap", "\\rlap"], {
|
| 425 |
+
numArgs: 1,
|
| 426 |
+
allowedInText: true,
|
| 427 |
+
}, function(context, args) {
|
| 428 |
+
var body = args[0];
|
| 429 |
+
return {
|
| 430 |
+
type: context.funcName.slice(1),
|
| 431 |
+
body: body,
|
| 432 |
+
};
|
| 433 |
+
});
|
| 434 |
+
|
| 435 |
+
// Delimiter functions
|
| 436 |
+
defineFunction([
|
| 437 |
+
"\\bigl", "\\Bigl", "\\biggl", "\\Biggl",
|
| 438 |
+
"\\bigr", "\\Bigr", "\\biggr", "\\Biggr",
|
| 439 |
+
"\\bigm", "\\Bigm", "\\biggm", "\\Biggm",
|
| 440 |
+
"\\big", "\\Big", "\\bigg", "\\Bigg",
|
| 441 |
+
"\\left", "\\right"
|
| 442 |
+
], {
|
| 443 |
+
numArgs: 1,
|
| 444 |
+
}, function(context, args) {
|
| 445 |
+
var delim = args[0];
|
| 446 |
+
if (!utils.contains(delimiters, delim.value)) {
|
| 447 |
+
throw new ParseError(
|
| 448 |
+
"Invalid delimiter: '" + delim.value + "' after '" +
|
| 449 |
+
context.funcName + "'",
|
| 450 |
+
context.lexer, context.positions[1]);
|
| 451 |
+
}
|
| 452 |
+
|
| 453 |
+
// \left and \right are caught somewhere in Parser.js, which is
|
| 454 |
+
// why this data doesn't match what is in buildHTML.
|
| 455 |
+
if (context.funcName === "\\left" || context.funcName === "\\right") {
|
| 456 |
+
return {
|
| 457 |
+
type: "leftright",
|
| 458 |
+
value: delim.value,
|
| 459 |
+
funcName: context.funcName
|
| 460 |
+
};
|
| 461 |
+
} else {
|
| 462 |
+
return {
|
| 463 |
+
type: "delimsizing",
|
| 464 |
+
size: delimiterSizes[context.funcName].size,
|
| 465 |
+
delimType: delimiterSizes[context.funcName].type,
|
| 466 |
+
value: delim.value,
|
| 467 |
+
funcName: context.funcName
|
| 468 |
+
};
|
| 469 |
+
}
|
| 470 |
+
});
|
| 471 |
+
|
| 472 |
+
// Sizing functions (handled in Parser.js explicitly, hence no handler)
|
| 473 |
+
defineFunction([
|
| 474 |
+
"\\tiny", "\\scriptsize", "\\footnotesize", "\\small",
|
| 475 |
+
"\\normalsize", "\\large", "\\Large", "\\LARGE", "\\huge", "\\Huge", "\\textrm", "\\rm", "\\cal", "\\bf", "\\siptstyle", "\\boldmath", "\\it"
|
| 476 |
+
], 0, null);
|
| 477 |
+
|
| 478 |
+
// Style changing functions (handled in Parser.js explicitly, hence no
|
| 479 |
+
// handler)
|
| 480 |
+
defineFunction([
|
| 481 |
+
"\\displaystyle", "\\textstyle", "\\scriptstyle",
|
| 482 |
+
"\\scriptscriptstyle",
|
| 483 |
+
], 0, null);
|
| 484 |
+
|
| 485 |
+
defineFunction([
|
| 486 |
+
// styles
|
| 487 |
+
"\\mathrm", "\\mathit", "\\mathbf","\\mathop","\\stackrel",
|
| 488 |
+
|
| 489 |
+
// families
|
| 490 |
+
"\\mathbb", "\\mathcal", "\\mathfrak", "\\mathscr", "\\mathsf",
|
| 491 |
+
"\\mathtt",
|
| 492 |
+
|
| 493 |
+
"\\label", "\\comment", "\\hspace", "\\vspace", "\\atop", "\\fbox", "\\tag", "\\makebox",
|
| 494 |
+
"\\raisebox", "\\framebox", "\\circle", "\\line", "\\put", "\\vphantom", "\\textup", "\\noalign",
|
| 495 |
+
|
| 496 |
+
// aliases
|
| 497 |
+
"\\Bbb", "\\bold", "\\frak",
|
| 498 |
+
], {
|
| 499 |
+
numArgs: 1,
|
| 500 |
+
greediness: 2,
|
| 501 |
+
}, function(context, args) {
|
| 502 |
+
var body = args[0];
|
| 503 |
+
var func = context.funcName;
|
| 504 |
+
if (func in fontAliases) {
|
| 505 |
+
func = fontAliases[func];
|
| 506 |
+
}
|
| 507 |
+
return {
|
| 508 |
+
type: "font",
|
| 509 |
+
font: func.slice(1),
|
| 510 |
+
body: body,
|
| 511 |
+
};
|
| 512 |
+
});
|
| 513 |
+
|
| 514 |
+
// Accents
|
| 515 |
+
defineFunction([
|
| 516 |
+
"\\acute", "\\grave", "\\ddot", "\\tilde", "\\bar", "\\breve",
|
| 517 |
+
"\\check", "\\hat", "\\vec", "\\dot",
|
| 518 |
+
// We don't support expanding accents yet
|
| 519 |
+
// "\\widetilde", "\\widehat"
|
| 520 |
+
], {
|
| 521 |
+
numArgs: 1,
|
| 522 |
+
}, function(context, args) {
|
| 523 |
+
var base = args[0];
|
| 524 |
+
return {
|
| 525 |
+
type: "accent",
|
| 526 |
+
accent: context.funcName,
|
| 527 |
+
base: base,
|
| 528 |
+
};
|
| 529 |
+
});
|
| 530 |
+
|
| 531 |
+
// Infix generalized fractions
|
| 532 |
+
defineFunction(["\\over", "\\choose"], {
|
| 533 |
+
numArgs: 0,
|
| 534 |
+
}, function(context) {
|
| 535 |
+
var replaceWith;
|
| 536 |
+
switch (context.funcName) {
|
| 537 |
+
case "\\over":
|
| 538 |
+
replaceWith = "\\frac";
|
| 539 |
+
break;
|
| 540 |
+
case "\\choose":
|
| 541 |
+
replaceWith = "\\binom";
|
| 542 |
+
break;
|
| 543 |
+
default:
|
| 544 |
+
throw new Error("Unrecognized infix genfrac command");
|
| 545 |
+
}
|
| 546 |
+
return {
|
| 547 |
+
type: "infix",
|
| 548 |
+
replaceWith: replaceWith,
|
| 549 |
+
};
|
| 550 |
+
});
|
| 551 |
+
|
| 552 |
+
// Row breaks for aligned data
|
| 553 |
+
defineFunction(["\\\\", "\\cr"], {
|
| 554 |
+
numArgs: 0,
|
| 555 |
+
numOptionalArgs: 1,
|
| 556 |
+
argTypes: ["size"],
|
| 557 |
+
}, function(context, args) {
|
| 558 |
+
var size = args[0];
|
| 559 |
+
return {
|
| 560 |
+
type: "cr",
|
| 561 |
+
size: size,
|
| 562 |
+
};
|
| 563 |
+
});
|
| 564 |
+
|
| 565 |
+
// Environment delimiters
|
| 566 |
+
defineFunction(["\\begin", "\\end"], {
|
| 567 |
+
numArgs: 1,
|
| 568 |
+
argTypes: ["text"],
|
| 569 |
+
}, function(context, args) {
|
| 570 |
+
var nameGroup = args[0];
|
| 571 |
+
if (nameGroup.type !== "ordgroup") {
|
| 572 |
+
throw new ParseError(
|
| 573 |
+
"Invalid environment name",
|
| 574 |
+
context.lexer, context.positions[1]);
|
| 575 |
+
}
|
| 576 |
+
var name = "";
|
| 577 |
+
for (var i = 0; i < nameGroup.value.length; ++i) {
|
| 578 |
+
name += nameGroup.value[i].value;
|
| 579 |
+
}
|
| 580 |
+
return {
|
| 581 |
+
type: "environment",
|
| 582 |
+
name: name,
|
| 583 |
+
namepos: context.positions[1],
|
| 584 |
+
};
|
| 585 |
+
});
|
katex/src/mathMLTree.js
ADDED
|
@@ -0,0 +1,102 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
/**
|
| 2 |
+
* These objects store data about MathML nodes. This is the MathML equivalent
|
| 3 |
+
* of the types in domTree.js. Since MathML handles its own rendering, and
|
| 4 |
+
* since we're mainly using MathML to improve accessibility, we don't manage
|
| 5 |
+
* any of the styling state that the plain DOM nodes do.
|
| 6 |
+
*
|
| 7 |
+
* The `toNode` and `toMarkup` functions work simlarly to how they do in
|
| 8 |
+
* domTree.js, creating namespaced DOM nodes and HTML text markup respectively.
|
| 9 |
+
*/
|
| 10 |
+
|
| 11 |
+
var utils = require("./utils");
|
| 12 |
+
|
| 13 |
+
/**
|
| 14 |
+
* This node represents a general purpose MathML node of any type. The
|
| 15 |
+
* constructor requires the type of node to create (for example, `"mo"` or
|
| 16 |
+
* `"mspace"`, corresponding to `<mo>` and `<mspace>` tags).
|
| 17 |
+
*/
|
| 18 |
+
function MathNode(type, children) {
|
| 19 |
+
this.type = type;
|
| 20 |
+
this.attributes = {};
|
| 21 |
+
this.children = children || [];
|
| 22 |
+
}
|
| 23 |
+
|
| 24 |
+
/**
|
| 25 |
+
* Sets an attribute on a MathML node. MathML depends on attributes to convey a
|
| 26 |
+
* semantic content, so this is used heavily.
|
| 27 |
+
*/
|
| 28 |
+
MathNode.prototype.setAttribute = function(name, value) {
|
| 29 |
+
this.attributes[name] = value;
|
| 30 |
+
};
|
| 31 |
+
|
| 32 |
+
/**
|
| 33 |
+
* Converts the math node into a MathML-namespaced DOM element.
|
| 34 |
+
*/
|
| 35 |
+
MathNode.prototype.toNode = function() {
|
| 36 |
+
var node = document.createElementNS(
|
| 37 |
+
"http://www.w3.org/1998/Math/MathML", this.type);
|
| 38 |
+
|
| 39 |
+
for (var attr in this.attributes) {
|
| 40 |
+
if (Object.prototype.hasOwnProperty.call(this.attributes, attr)) {
|
| 41 |
+
node.setAttribute(attr, this.attributes[attr]);
|
| 42 |
+
}
|
| 43 |
+
}
|
| 44 |
+
|
| 45 |
+
for (var i = 0; i < this.children.length; i++) {
|
| 46 |
+
node.appendChild(this.children[i].toNode());
|
| 47 |
+
}
|
| 48 |
+
|
| 49 |
+
return node;
|
| 50 |
+
};
|
| 51 |
+
|
| 52 |
+
/**
|
| 53 |
+
* Converts the math node into an HTML markup string.
|
| 54 |
+
*/
|
| 55 |
+
MathNode.prototype.toMarkup = function() {
|
| 56 |
+
var markup = "<" + this.type;
|
| 57 |
+
|
| 58 |
+
// Add the attributes
|
| 59 |
+
for (var attr in this.attributes) {
|
| 60 |
+
if (Object.prototype.hasOwnProperty.call(this.attributes, attr)) {
|
| 61 |
+
markup += " " + attr + "=\"";
|
| 62 |
+
markup += utils.escape(this.attributes[attr]);
|
| 63 |
+
markup += "\"";
|
| 64 |
+
}
|
| 65 |
+
}
|
| 66 |
+
|
| 67 |
+
markup += ">";
|
| 68 |
+
|
| 69 |
+
for (var i = 0; i < this.children.length; i++) {
|
| 70 |
+
markup += this.children[i].toMarkup();
|
| 71 |
+
}
|
| 72 |
+
|
| 73 |
+
markup += "</" + this.type + ">";
|
| 74 |
+
|
| 75 |
+
return markup;
|
| 76 |
+
};
|
| 77 |
+
|
| 78 |
+
/**
|
| 79 |
+
* This node represents a piece of text.
|
| 80 |
+
*/
|
| 81 |
+
function TextNode(text) {
|
| 82 |
+
this.text = text;
|
| 83 |
+
}
|
| 84 |
+
|
| 85 |
+
/**
|
| 86 |
+
* Converts the text node into a DOM text node.
|
| 87 |
+
*/
|
| 88 |
+
TextNode.prototype.toNode = function() {
|
| 89 |
+
return document.createTextNode(this.text);
|
| 90 |
+
};
|
| 91 |
+
|
| 92 |
+
/**
|
| 93 |
+
* Converts the text node into HTML markup (which is just the text itself).
|
| 94 |
+
*/
|
| 95 |
+
TextNode.prototype.toMarkup = function() {
|
| 96 |
+
return utils.escape(this.text);
|
| 97 |
+
};
|
| 98 |
+
|
| 99 |
+
module.exports = {
|
| 100 |
+
MathNode: MathNode,
|
| 101 |
+
TextNode: TextNode,
|
| 102 |
+
};
|
katex/src/parseData.js
ADDED
|
@@ -0,0 +1,13 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
/**
|
| 2 |
+
* The resulting parse tree nodes of the parse tree.
|
| 3 |
+
*/
|
| 4 |
+
function ParseNode(type, value, mode) {
|
| 5 |
+
this.type = type;
|
| 6 |
+
this.value = value;
|
| 7 |
+
this.mode = mode;
|
| 8 |
+
}
|
| 9 |
+
|
| 10 |
+
module.exports = {
|
| 11 |
+
ParseNode: ParseNode,
|
| 12 |
+
};
|
| 13 |
+
|
katex/src/parseTree.js
ADDED
|
@@ -0,0 +1,17 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
/**
|
| 2 |
+
* Provides a single function for parsing an expression using a Parser
|
| 3 |
+
* TODO(emily): Remove this
|
| 4 |
+
*/
|
| 5 |
+
|
| 6 |
+
var Parser = require("./Parser");
|
| 7 |
+
|
| 8 |
+
/**
|
| 9 |
+
* Parses an expression using a Parser, then returns the parsed result.
|
| 10 |
+
*/
|
| 11 |
+
var parseTree = function(toParse, settings) {
|
| 12 |
+
var parser = new Parser(toParse, settings);
|
| 13 |
+
|
| 14 |
+
return parser.parse();
|
| 15 |
+
};
|
| 16 |
+
|
| 17 |
+
module.exports = parseTree;
|
katex/src/symbols.js
ADDED
|
@@ -0,0 +1,687 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
/**
|
| 2 |
+
* This file holds a list of all no-argument functions and single-character
|
| 3 |
+
* symbols (like 'a' or ';').
|
| 4 |
+
*
|
| 5 |
+
* For each of the symbols, there are three properties they can have:
|
| 6 |
+
* - font (required): the font to be used for this symbol. Either "main" (the
|
| 7 |
+
normal font), or "ams" (the ams fonts).
|
| 8 |
+
* - group (required): the ParseNode group type the symbol should have (i.e.
|
| 9 |
+
"textord", "mathord", etc).
|
| 10 |
+
See https://github.com/Khan/KaTeX/wiki/Examining-TeX#group-types
|
| 11 |
+
* - replace: the character that this symbol or function should be
|
| 12 |
+
* replaced with (i.e. "\phi" has a replace value of "\u03d5", the phi
|
| 13 |
+
* character in the main font).
|
| 14 |
+
*
|
| 15 |
+
* The outermost map in the table indicates what mode the symbols should be
|
| 16 |
+
* accepted in (e.g. "math" or "text").
|
| 17 |
+
*/
|
| 18 |
+
|
| 19 |
+
module.exports = {
|
| 20 |
+
math: {},
|
| 21 |
+
text: {},
|
| 22 |
+
};
|
| 23 |
+
|
| 24 |
+
function defineSymbol(mode, font, group, replace, name) {
|
| 25 |
+
module.exports[mode][name] = {
|
| 26 |
+
font: font,
|
| 27 |
+
group: group,
|
| 28 |
+
replace: replace,
|
| 29 |
+
};
|
| 30 |
+
}
|
| 31 |
+
|
| 32 |
+
// Some abbreviations for commonly used strings.
|
| 33 |
+
// This helps minify the code, and also spotting typos using jshint.
|
| 34 |
+
|
| 35 |
+
// modes:
|
| 36 |
+
var math = "math";
|
| 37 |
+
var text = "text";
|
| 38 |
+
|
| 39 |
+
// fonts:
|
| 40 |
+
var main = "main";
|
| 41 |
+
var ams = "ams";
|
| 42 |
+
|
| 43 |
+
// groups:
|
| 44 |
+
var accent = "accent";
|
| 45 |
+
var bin = "bin";
|
| 46 |
+
var close = "close";
|
| 47 |
+
var inner = "inner";
|
| 48 |
+
var mathord = "mathord";
|
| 49 |
+
var op = "op";
|
| 50 |
+
var open = "open";
|
| 51 |
+
var punct = "punct";
|
| 52 |
+
var rel = "rel";
|
| 53 |
+
var spacing = "spacing";
|
| 54 |
+
var textord = "textord";
|
| 55 |
+
|
| 56 |
+
// Now comes the symbol table
|
| 57 |
+
|
| 58 |
+
// Relation Symbols
|
| 59 |
+
defineSymbol(math, main, rel, "\u2261", "\\equiv");
|
| 60 |
+
defineSymbol(math, main, rel, "\u227a", "\\prec");
|
| 61 |
+
defineSymbol(math, main, rel, "\u227b", "\\succ");
|
| 62 |
+
defineSymbol(math, main, rel, "\u223c", "\\sim");
|
| 63 |
+
defineSymbol(math, main, rel, "\u22a5", "\\perp");
|
| 64 |
+
defineSymbol(math, main, rel, "\u2aaf", "\\preceq");
|
| 65 |
+
defineSymbol(math, main, rel, "\u2ab0", "\\succeq");
|
| 66 |
+
defineSymbol(math, main, rel, "\u2243", "\\simeq");
|
| 67 |
+
defineSymbol(math, main, rel, "\u2223", "\\mid");
|
| 68 |
+
defineSymbol(math, main, rel, "\u226a", "\\ll");
|
| 69 |
+
defineSymbol(math, main, rel, "\u226b", "\\gg");
|
| 70 |
+
defineSymbol(math, main, rel, "\u224d", "\\asymp");
|
| 71 |
+
defineSymbol(math, main, rel, "\u2225", "\\parallel");
|
| 72 |
+
defineSymbol(math, main, rel, "\u22c8", "\\bowtie");
|
| 73 |
+
defineSymbol(math, main, rel, "\u2323", "\\smile");
|
| 74 |
+
defineSymbol(math, main, rel, "\u2291", "\\sqsubseteq");
|
| 75 |
+
defineSymbol(math, main, rel, "\u2292", "\\sqsupseteq");
|
| 76 |
+
defineSymbol(math, main, rel, "\u2250", "\\doteq");
|
| 77 |
+
defineSymbol(math, main, rel, "\u2322", "\\frown");
|
| 78 |
+
defineSymbol(math, main, rel, "\u220b", "\\ni");
|
| 79 |
+
defineSymbol(math, main, rel, "\u221d", "\\propto");
|
| 80 |
+
defineSymbol(math, main, rel, "\u22a2", "\\vdash");
|
| 81 |
+
defineSymbol(math, main, rel, "\u22a3", "\\dashv");
|
| 82 |
+
defineSymbol(math, main, rel, "\u220b", "\\owns");
|
| 83 |
+
|
| 84 |
+
defineSymbol(math, main, rel, "\u220b", "\\widehat");
|
| 85 |
+
defineSymbol(math, main, rel, "\u220b", "\\widetilde");
|
| 86 |
+
defineSymbol(math, main, rel, "\u220b", "\\sp");
|
| 87 |
+
defineSymbol(math, main, rel, "\u220b", "\\quad");
|
| 88 |
+
// defineSymbol(math, main, rel, "\u220b", "\\cr");
|
| 89 |
+
defineSymbol(math, main, rel, "\u220b", "\\\\sim");
|
| 90 |
+
defineSymbol(math, main, rel, "\u220b", "\\nonumber");
|
| 91 |
+
defineSymbol(math, main, rel, "\u220b", "\\dots");
|
| 92 |
+
defineSymbol(math, main, rel, "\u220b", "\\cases");
|
| 93 |
+
defineSymbol(math, main, rel, "\u220b", "\\mit");
|
| 94 |
+
defineSymbol(math, main, rel, "\u220b", "\\smallskip");
|
| 95 |
+
defineSymbol(math, main, rel, "\u220b", "\\slash");
|
| 96 |
+
defineSymbol(math, main, rel, "\u220b", "\\d");
|
| 97 |
+
defineSymbol(math, main, rel, "\u220b", "\\c");
|
| 98 |
+
defineSymbol(math, main, rel, "\u220b", "\\b");
|
| 99 |
+
defineSymbol(math, main, rel, "\u220b", "\\M");
|
| 100 |
+
defineSymbol(math, main, rel, "\u220b", "\\S");
|
| 101 |
+
defineSymbol(math, main, rel, "\u220b", "\\(");
|
| 102 |
+
defineSymbol(math, main, rel, "\u220b", "\\)");
|
| 103 |
+
// defineSymbol(math, main, rel, "\u220b", "\\Comp");
|
| 104 |
+
defineSymbol(math, main, rel, "\u220b", "\\thinspace");
|
| 105 |
+
defineSymbol(math, main, rel, "\u220b", "\\hskip");
|
| 106 |
+
defineSymbol(math, main, rel, "\u220b", "\\tt");
|
| 107 |
+
defineSymbol(math, main, rel, "\u220b", "\\not");
|
| 108 |
+
defineSymbol(math, main, rel, "\u220b", "\\boldmathr");
|
| 109 |
+
defineSymbol(math, main, rel, "\u220b", "\\overleftarrow");
|
| 110 |
+
defineSymbol(math, main, rel, "\u220b", "\\overrightarrow");
|
| 111 |
+
defineSymbol(math, main, rel, "\u220b", "\\intf");
|
| 112 |
+
defineSymbol(math, main, rel, "\u220b", "\\sf");
|
| 113 |
+
defineSymbol(math, main, rel, "\u220b", "\\textbf");
|
| 114 |
+
defineSymbol(math, main, rel, "\u220b", "\\L");
|
| 115 |
+
defineSymbol(math, main, rel, "\u220b", "\\pii");
|
| 116 |
+
defineSymbol(math, main, rel, "\u220b", "\\unitlength");
|
| 117 |
+
defineSymbol(math, main, rel, "\u220b", "\\arowtor5linv");
|
| 118 |
+
defineSymbol(math, main, rel, "\u220b", "\\hline");
|
| 119 |
+
defineSymbol(math, main, rel, "\u220b", "\\mathbin");
|
| 120 |
+
defineSymbol(math, main, rel, "\u220b", "\\nc");
|
| 121 |
+
defineSymbol(math, main, rel, "\u220b", "\\underbrace");
|
| 122 |
+
defineSymbol(math, main, rel, "\u220b", "\\o");
|
| 123 |
+
defineSymbol(math, main, rel, "\u220b", "\\a");
|
| 124 |
+
defineSymbol(math, main, rel, "\u220b", "\\b");
|
| 125 |
+
defineSymbol(math, main, rel, "\u220b", "\\c");
|
| 126 |
+
defineSymbol(math, main, rel, "\u220b", "\\d");
|
| 127 |
+
defineSymbol(math, main, rel, "\u220b", "\\e");
|
| 128 |
+
defineSymbol(math, main, rel, "\u220b", "\\f");
|
| 129 |
+
defineSymbol(math, main, rel, "\u220b", "\\g");
|
| 130 |
+
defineSymbol(math, main, rel, "\u220b", "\\h");
|
| 131 |
+
defineSymbol(math, main, rel, "\u220b", "\\i");
|
| 132 |
+
defineSymbol(math, main, rel, "\u220b", "\\j");
|
| 133 |
+
defineSymbol(math, main, rel, "\u220b", "\\k");
|
| 134 |
+
defineSymbol(math, main, rel, "\u220b", "\\l");
|
| 135 |
+
defineSymbol(math, main, rel, "\u220b", "\\m");
|
| 136 |
+
defineSymbol(math, main, rel, "\u220b", "\\n");
|
| 137 |
+
defineSymbol(math, main, rel, "\u220b", "\\o");
|
| 138 |
+
// defineSymbol(math, main, rel, "\u220b", "\\wedgee");
|
| 139 |
+
defineSymbol(math, main, rel, "\u220b", "\\sb");
|
| 140 |
+
defineSymbol(math, main, rel, "\u220b", "\\do");
|
| 141 |
+
defineSymbol(math, main, rel, "\u220b", "\\em");
|
| 142 |
+
// defineSymbol(math, main, rel, "\u220b", "\\diamonda");
|
| 143 |
+
|
| 144 |
+
|
| 145 |
+
defineSymbol(math, main, rel, "\u220b", "\\dint");
|
| 146 |
+
defineSymbol(math, main, rel, "\u220b", "\\intd");
|
| 147 |
+
|
| 148 |
+
|
| 149 |
+
// Punctuation
|
| 150 |
+
defineSymbol(math, main, punct, "\u002e", "\\ldotp");
|
| 151 |
+
defineSymbol(math, main, punct, "\u22c5", "\\cdotp");
|
| 152 |
+
|
| 153 |
+
// Misc Symbols
|
| 154 |
+
defineSymbol(math, main, textord, "\u0023", "\\#");
|
| 155 |
+
defineSymbol(math, main, textord, "\u0026", "\\&");
|
| 156 |
+
defineSymbol(math, main, textord, "\u2135", "\\aleph");
|
| 157 |
+
defineSymbol(math, main, textord, "\u2200", "\\forall");
|
| 158 |
+
defineSymbol(math, main, textord, "\u210f", "\\hbar");
|
| 159 |
+
defineSymbol(math, main, textord, "\u2203", "\\eixsts");
|
| 160 |
+
defineSymbol(math, main, textord, "\u2207", "\\nabla");
|
| 161 |
+
defineSymbol(math, main, textord, "\u266d", "\\flat");
|
| 162 |
+
defineSymbol(math, main, textord, "\u2113", "\\ell");
|
| 163 |
+
defineSymbol(math, main, textord, "\u266e", "\\natural");
|
| 164 |
+
defineSymbol(math, main, textord, "\u2663", "\\clubsuit");
|
| 165 |
+
defineSymbol(math, main, textord, "\u2118", "\\wp");
|
| 166 |
+
defineSymbol(math, main, textord, "\u266f", "\\sharp");
|
| 167 |
+
defineSymbol(math, main, textord, "\u2662", "\\diamondsuit");
|
| 168 |
+
defineSymbol(math, main, textord, "\u211c", "\\Re");
|
| 169 |
+
defineSymbol(math, main, textord, "\u2661", "\\heartsuit");
|
| 170 |
+
defineSymbol(math, main, textord, "\u2111", "\\Im");
|
| 171 |
+
defineSymbol(math, main, textord, "\u2660", "\\spadesuit");
|
| 172 |
+
|
| 173 |
+
// Math and Text
|
| 174 |
+
defineSymbol(math, main, textord, "\u2020", "\\dag");
|
| 175 |
+
defineSymbol(math, main, textord, "\u2021", "\\ddag");
|
| 176 |
+
|
| 177 |
+
// Large Delimiters
|
| 178 |
+
defineSymbol(math, main, close, "\u23b1", "\\rmoustache");
|
| 179 |
+
defineSymbol(math, main, open, "\u23b0", "\\lmoustache");
|
| 180 |
+
defineSymbol(math, main, close, "\u27ef", "\\rgroup");
|
| 181 |
+
defineSymbol(math, main, open, "\u27ee", "\\lgroup");
|
| 182 |
+
|
| 183 |
+
// Binary Operators
|
| 184 |
+
defineSymbol(math, main, bin, "\u2213", "\\mp");
|
| 185 |
+
defineSymbol(math, main, bin, "\u2296", "\\ominus");
|
| 186 |
+
defineSymbol(math, main, bin, "\u228e", "\\uplus");
|
| 187 |
+
defineSymbol(math, main, bin, "\u2293", "\\sqcap");
|
| 188 |
+
defineSymbol(math, main, bin, "\u2217", "\\ast");
|
| 189 |
+
defineSymbol(math, main, bin, "\u2294", "\\sqcup");
|
| 190 |
+
defineSymbol(math, main, bin, "\u25ef", "\\bigcirc");
|
| 191 |
+
defineSymbol(math, main, bin, "\u2219", "\\bullet");
|
| 192 |
+
defineSymbol(math, main, bin, "\u2021", "\\ddagger");
|
| 193 |
+
defineSymbol(math, main, bin, "\u2240", "\\wr");
|
| 194 |
+
defineSymbol(math, main, bin, "\u2a3f", "\\amalg");
|
| 195 |
+
|
| 196 |
+
// Arrow Symbols
|
| 197 |
+
defineSymbol(math, main, rel, "\u27f5", "\\longleftarrow");
|
| 198 |
+
defineSymbol(math, main, rel, "\u21d0", "\\Leftarrow");
|
| 199 |
+
defineSymbol(math, main, rel, "\u27f8", "\\Longleftarrow");
|
| 200 |
+
defineSymbol(math, main, rel, "\u27f6", "\\longrightarrow");
|
| 201 |
+
defineSymbol(math, main, rel, "\u21d2", "\\Rightarrow");
|
| 202 |
+
defineSymbol(math, main, rel, "\u27f9", "\\Longrightarrow");
|
| 203 |
+
defineSymbol(math, main, rel, "\u2194", "\\leftrightarrow");
|
| 204 |
+
defineSymbol(math, main, rel, "\u27f7", "\\longleftrightarrow");
|
| 205 |
+
defineSymbol(math, main, rel, "\u21d4", "\\Leftrightarrow");
|
| 206 |
+
defineSymbol(math, main, rel, "\u27fa", "\\Longleftrightarrow");
|
| 207 |
+
defineSymbol(math, main, rel, "\u21a6", "\\mapsto");
|
| 208 |
+
defineSymbol(math, main, rel, "\u27fc", "\\longmapsto");
|
| 209 |
+
defineSymbol(math, main, rel, "\u2197", "\\nearrow");
|
| 210 |
+
defineSymbol(math, main, rel, "\u21a9", "\\hookleftarrow");
|
| 211 |
+
defineSymbol(math, main, rel, "\u21aa", "\\hookrightarrow");
|
| 212 |
+
defineSymbol(math, main, rel, "\u2198", "\\searrow");
|
| 213 |
+
defineSymbol(math, main, rel, "\u21bc", "\\leftharpoonup");
|
| 214 |
+
defineSymbol(math, main, rel, "\u21c0", "\\rightharpoonup");
|
| 215 |
+
defineSymbol(math, main, rel, "\u2199", "\\swarrow");
|
| 216 |
+
defineSymbol(math, main, rel, "\u21bd", "\\leftharpoondown");
|
| 217 |
+
defineSymbol(math, main, rel, "\u21c1", "\\rightharpoondown");
|
| 218 |
+
defineSymbol(math, main, rel, "\u2196", "\\nwarrow");
|
| 219 |
+
defineSymbol(math, main, rel, "\u21cc", "\\rightleftharpoons");
|
| 220 |
+
|
| 221 |
+
// AMS Negated Binary Relations
|
| 222 |
+
defineSymbol(math, ams, rel, "\u226e", "\\nless");
|
| 223 |
+
defineSymbol(math, ams, rel, "\ue010", "\\nleqslant");
|
| 224 |
+
defineSymbol(math, ams, rel, "\ue011", "\\nleqq");
|
| 225 |
+
defineSymbol(math, ams, rel, "\u2a87", "\\lneq");
|
| 226 |
+
defineSymbol(math, ams, rel, "\u2268", "\\lneqq");
|
| 227 |
+
defineSymbol(math, ams, rel, "\ue00c", "\\lvertneqq");
|
| 228 |
+
defineSymbol(math, ams, rel, "\u22e6", "\\lnsim");
|
| 229 |
+
defineSymbol(math, ams, rel, "\u2a89", "\\lnapprox");
|
| 230 |
+
defineSymbol(math, ams, rel, "\u2280", "\\nprec");
|
| 231 |
+
defineSymbol(math, ams, rel, "\u22e0", "\\npreceq");
|
| 232 |
+
defineSymbol(math, ams, rel, "\u22e8", "\\precnsim");
|
| 233 |
+
defineSymbol(math, ams, rel, "\u2ab9", "\\precnapprox");
|
| 234 |
+
defineSymbol(math, ams, rel, "\u2241", "\\nsim");
|
| 235 |
+
defineSymbol(math, ams, rel, "\ue006", "\\nshortmid");
|
| 236 |
+
defineSymbol(math, ams, rel, "\u2224", "\\nmid");
|
| 237 |
+
defineSymbol(math, ams, rel, "\u22ac", "\\nvdash");
|
| 238 |
+
defineSymbol(math, ams, rel, "\u22ad", "\\nvDash");
|
| 239 |
+
defineSymbol(math, ams, rel, "\u22ea", "\\ntriangleleft");
|
| 240 |
+
defineSymbol(math, ams, rel, "\u22ec", "\\ntrianglelefteq");
|
| 241 |
+
defineSymbol(math, ams, rel, "\u228a", "\\subsetneq");
|
| 242 |
+
defineSymbol(math, ams, rel, "\ue01a", "\\varsubsetneq");
|
| 243 |
+
defineSymbol(math, ams, rel, "\u2acb", "\\subsetneqq");
|
| 244 |
+
defineSymbol(math, ams, rel, "\ue017", "\\varsubsetneqq");
|
| 245 |
+
defineSymbol(math, ams, rel, "\u226f", "\\ngtr");
|
| 246 |
+
defineSymbol(math, ams, rel, "\ue00f", "\\ngeqslant");
|
| 247 |
+
defineSymbol(math, ams, rel, "\ue00e", "\\ngeqq");
|
| 248 |
+
defineSymbol(math, ams, rel, "\u2a88", "\\gneq");
|
| 249 |
+
defineSymbol(math, ams, rel, "\u2269", "\\gneqq");
|
| 250 |
+
defineSymbol(math, ams, rel, "\ue00d", "\\gvertneqq");
|
| 251 |
+
defineSymbol(math, ams, rel, "\u22e7", "\\gnsim");
|
| 252 |
+
defineSymbol(math, ams, rel, "\u2a8a", "\\gnapprox");
|
| 253 |
+
defineSymbol(math, ams, rel, "\u2281", "\\nsucc");
|
| 254 |
+
defineSymbol(math, ams, rel, "\u22e1", "\\nsucceq");
|
| 255 |
+
defineSymbol(math, ams, rel, "\u22e9", "\\succnsim");
|
| 256 |
+
defineSymbol(math, ams, rel, "\u2aba", "\\succnapprox");
|
| 257 |
+
defineSymbol(math, ams, rel, "\u2246", "\\ncong");
|
| 258 |
+
defineSymbol(math, ams, rel, "\ue007", "\\nshortparallel");
|
| 259 |
+
defineSymbol(math, ams, rel, "\u2226", "\\nparallel");
|
| 260 |
+
defineSymbol(math, ams, rel, "\u22af", "\\nVDash");
|
| 261 |
+
defineSymbol(math, ams, rel, "\u22eb", "\\ntriangleright");
|
| 262 |
+
defineSymbol(math, ams, rel, "\u22ed", "\\ntrianglerighteq");
|
| 263 |
+
defineSymbol(math, ams, rel, "\ue018", "\\nsupseteqq");
|
| 264 |
+
defineSymbol(math, ams, rel, "\u228b", "\\supsetneq");
|
| 265 |
+
defineSymbol(math, ams, rel, "\ue01b", "\\varsupsetneq");
|
| 266 |
+
defineSymbol(math, ams, rel, "\u2acc", "\\supsetneqq");
|
| 267 |
+
defineSymbol(math, ams, rel, "\ue019", "\\varsupsetneqq");
|
| 268 |
+
defineSymbol(math, ams, rel, "\u22ae", "\\nVdash");
|
| 269 |
+
defineSymbol(math, ams, rel, "\u2ab5", "\\precneqq");
|
| 270 |
+
defineSymbol(math, ams, rel, "\u2ab6", "\\succneqq");
|
| 271 |
+
defineSymbol(math, ams, rel, "\ue016", "\\nsubseteqq");
|
| 272 |
+
defineSymbol(math, ams, bin, "\u22b4", "\\unlhd");
|
| 273 |
+
defineSymbol(math, ams, bin, "\u22b5", "\\unrhd");
|
| 274 |
+
|
| 275 |
+
// AMS Negated Arrows
|
| 276 |
+
defineSymbol(math, ams, rel, "\u219a", "\\nleftarrow");
|
| 277 |
+
defineSymbol(math, ams, rel, "\u219b", "\\nrightarrow");
|
| 278 |
+
defineSymbol(math, ams, rel, "\u21cd", "\\nLeftarrow");
|
| 279 |
+
defineSymbol(math, ams, rel, "\u21cf", "\\nRightarrow");
|
| 280 |
+
defineSymbol(math, ams, rel, "\u21ae", "\\nleftrightarrow");
|
| 281 |
+
defineSymbol(math, ams, rel, "\u21ce", "\\nLeftrightarrow");
|
| 282 |
+
|
| 283 |
+
// AMS Misc
|
| 284 |
+
defineSymbol(math, ams, rel, "\u25b3", "\\vartriangle");
|
| 285 |
+
defineSymbol(math, ams, textord, "\u210f", "\\hslash");
|
| 286 |
+
defineSymbol(math, ams, textord, "\u25bd", "\\triangledown");
|
| 287 |
+
defineSymbol(math, ams, textord, "\u25ca", "\\lozenge");
|
| 288 |
+
defineSymbol(math, ams, textord, "\u24c8", "\\circledS");
|
| 289 |
+
defineSymbol(math, ams, textord, "\u00ae", "\\circledR");
|
| 290 |
+
defineSymbol(math, ams, textord, "\u2221", "\\measuredangle");
|
| 291 |
+
defineSymbol(math, ams, textord, "\u2204", "\\nexists");
|
| 292 |
+
defineSymbol(math, ams, textord, "\u2127", "\\mho");
|
| 293 |
+
defineSymbol(math, ams, textord, "\u2132", "\\Finv");
|
| 294 |
+
defineSymbol(math, ams, textord, "\u2141", "\\Game");
|
| 295 |
+
defineSymbol(math, ams, textord, "\u006b", "\\Bbbk");
|
| 296 |
+
defineSymbol(math, ams, textord, "\u2035", "\\backprime");
|
| 297 |
+
defineSymbol(math, ams, textord, "\u25b2", "\\blacktriangle");
|
| 298 |
+
defineSymbol(math, ams, textord, "\u25bc", "\\blacktriangledown");
|
| 299 |
+
defineSymbol(math, ams, textord, "\u25a0", "\\blacksquare");
|
| 300 |
+
defineSymbol(math, ams, textord, "\u29eb", "\\blacklozenge");
|
| 301 |
+
defineSymbol(math, ams, textord, "\u2605", "\\bigstar");
|
| 302 |
+
defineSymbol(math, ams, textord, "\u2222", "\\sphericalangle");
|
| 303 |
+
defineSymbol(math, ams, textord, "\u2201", "\\complement");
|
| 304 |
+
defineSymbol(math, ams, textord, "\u00f0", "\\eth");
|
| 305 |
+
defineSymbol(math, ams, textord, "\u2571", "\\diagup");
|
| 306 |
+
defineSymbol(math, ams, textord, "\u2572", "\\diagdown");
|
| 307 |
+
defineSymbol(math, ams, textord, "\u25a1", "\\square");
|
| 308 |
+
defineSymbol(math, ams, textord, "\u25a1", "\\Box");
|
| 309 |
+
defineSymbol(math, ams, textord, "\u25ca", "\\Diamond");
|
| 310 |
+
defineSymbol(math, ams, textord, "\u00a5", "\\yen");
|
| 311 |
+
defineSymbol(math, ams, textord, "\u2713", "\\checkmark");
|
| 312 |
+
|
| 313 |
+
// AMS Hebrew
|
| 314 |
+
defineSymbol(math, ams, textord, "\u2136", "\\beth");
|
| 315 |
+
defineSymbol(math, ams, textord, "\u2138", "\\daleth");
|
| 316 |
+
defineSymbol(math, ams, textord, "\u2137", "\\gimel");
|
| 317 |
+
|
| 318 |
+
// AMS Greek
|
| 319 |
+
defineSymbol(math, ams, textord, "\u03dd", "\\digamma");
|
| 320 |
+
defineSymbol(math, ams, textord, "\u03f0", "\\varkappa");
|
| 321 |
+
|
| 322 |
+
// AMS Delimiters
|
| 323 |
+
defineSymbol(math, ams, open, "\u250c", "\\ulcorner");
|
| 324 |
+
defineSymbol(math, ams, close, "\u2510", "\\urcorner");
|
| 325 |
+
defineSymbol(math, ams, open, "\u2514", "\\llcorner");
|
| 326 |
+
defineSymbol(math, ams, close, "\u2518", "\\lrcorner");
|
| 327 |
+
|
| 328 |
+
// AMS Binary Relations
|
| 329 |
+
defineSymbol(math, ams, rel, "\u2266", "\\leqq");
|
| 330 |
+
defineSymbol(math, ams, rel, "\u2a7d", "\\leqslant");
|
| 331 |
+
defineSymbol(math, ams, rel, "\u2a95", "\\eqslantless");
|
| 332 |
+
defineSymbol(math, ams, rel, "\u2272", "\\lesssim");
|
| 333 |
+
defineSymbol(math, ams, rel, "\u2a85", "\\lessapprox");
|
| 334 |
+
defineSymbol(math, ams, rel, "\u224a", "\\approxeq");
|
| 335 |
+
defineSymbol(math, ams, bin, "\u22d6", "\\lessdot");
|
| 336 |
+
defineSymbol(math, ams, rel, "\u22d8", "\\lll");
|
| 337 |
+
defineSymbol(math, ams, rel, "\u2276", "\\lessgtr");
|
| 338 |
+
defineSymbol(math, ams, rel, "\u22da", "\\lesseqgtr");
|
| 339 |
+
defineSymbol(math, ams, rel, "\u2a8b", "\\lesseqqgtr");
|
| 340 |
+
defineSymbol(math, ams, rel, "\u2251", "\\doteqdot");
|
| 341 |
+
defineSymbol(math, ams, rel, "\u2253", "\\risingdotseq");
|
| 342 |
+
defineSymbol(math, ams, rel, "\u2252", "\\fallingdotseq");
|
| 343 |
+
defineSymbol(math, ams, rel, "\u223d", "\\backsim");
|
| 344 |
+
defineSymbol(math, ams, rel, "\u22cd", "\\backsimeq");
|
| 345 |
+
defineSymbol(math, ams, rel, "\u2ac5", "\\subseteqq");
|
| 346 |
+
defineSymbol(math, ams, rel, "\u22d0", "\\Subset");
|
| 347 |
+
defineSymbol(math, ams, rel, "\u228f", "\\sqsubset");
|
| 348 |
+
defineSymbol(math, ams, rel, "\u227c", "\\preccurlyeq");
|
| 349 |
+
defineSymbol(math, ams, rel, "\u22de", "\\curlyeqprec");
|
| 350 |
+
defineSymbol(math, ams, rel, "\u227e", "\\precsim");
|
| 351 |
+
defineSymbol(math, ams, rel, "\u2ab7", "\\precapprox");
|
| 352 |
+
defineSymbol(math, ams, rel, "\u22b2", "\\vartriangleleft");
|
| 353 |
+
defineSymbol(math, ams, rel, "\u22b4", "\\trianglelefteq");
|
| 354 |
+
defineSymbol(math, ams, rel, "\u22a8", "\\vDash");
|
| 355 |
+
defineSymbol(math, ams, rel, "\u22aa", "\\Vvdash");
|
| 356 |
+
defineSymbol(math, ams, rel, "\u2323", "\\smallsmile");
|
| 357 |
+
defineSymbol(math, ams, rel, "\u2322", "\\smallfrown");
|
| 358 |
+
defineSymbol(math, ams, rel, "\u224f", "\\bumpeq");
|
| 359 |
+
defineSymbol(math, ams, rel, "\u224e", "\\Bumpeq");
|
| 360 |
+
defineSymbol(math, ams, rel, "\u2267", "\\geqq");
|
| 361 |
+
defineSymbol(math, ams, rel, "\u2a7e", "\\geqslant");
|
| 362 |
+
defineSymbol(math, ams, rel, "\u2a96", "\\eqslantgtr");
|
| 363 |
+
defineSymbol(math, ams, rel, "\u2273", "\\gtrsim");
|
| 364 |
+
defineSymbol(math, ams, rel, "\u2a86", "\\gtrapprox");
|
| 365 |
+
defineSymbol(math, ams, bin, "\u22d7", "\\gtrdot");
|
| 366 |
+
defineSymbol(math, ams, rel, "\u22d9", "\\ggg");
|
| 367 |
+
defineSymbol(math, ams, rel, "\u2277", "\\gtrless");
|
| 368 |
+
defineSymbol(math, ams, rel, "\u22db", "\\gtreqless");
|
| 369 |
+
defineSymbol(math, ams, rel, "\u2a8c", "\\gtreqqless");
|
| 370 |
+
defineSymbol(math, ams, rel, "\u2256", "\\eqcirc");
|
| 371 |
+
defineSymbol(math, ams, rel, "\u2257", "\\circeq");
|
| 372 |
+
defineSymbol(math, ams, rel, "\u225c", "\\triangleq");
|
| 373 |
+
defineSymbol(math, ams, rel, "\u223c", "\\thicksim");
|
| 374 |
+
defineSymbol(math, ams, rel, "\u2248", "\\thickapprox");
|
| 375 |
+
defineSymbol(math, ams, rel, "\u2ac6", "\\supseteqq");
|
| 376 |
+
defineSymbol(math, ams, rel, "\u22d1", "\\Supset");
|
| 377 |
+
defineSymbol(math, ams, rel, "\u2290", "\\sqsupset");
|
| 378 |
+
defineSymbol(math, ams, rel, "\u227d", "\\succcurlyeq");
|
| 379 |
+
defineSymbol(math, ams, rel, "\u22df", "\\curlyeqsucc");
|
| 380 |
+
defineSymbol(math, ams, rel, "\u227f", "\\succsim");
|
| 381 |
+
defineSymbol(math, ams, rel, "\u2ab8", "\\succapprox");
|
| 382 |
+
defineSymbol(math, ams, rel, "\u22b3", "\\vartriangleright");
|
| 383 |
+
defineSymbol(math, ams, rel, "\u22b5", "\\trianglerighteq");
|
| 384 |
+
defineSymbol(math, ams, rel, "\u22a9", "\\Vdash");
|
| 385 |
+
defineSymbol(math, ams, rel, "\u2223", "\\shortmid");
|
| 386 |
+
defineSymbol(math, ams, rel, "\u2225", "\\shortparallel");
|
| 387 |
+
defineSymbol(math, ams, rel, "\u226c", "\\between");
|
| 388 |
+
defineSymbol(math, ams, rel, "\u22d4", "\\pitchfork");
|
| 389 |
+
defineSymbol(math, ams, rel, "\u221d", "\\varpropto");
|
| 390 |
+
defineSymbol(math, ams, rel, "\u25c0", "\\blacktriangleleft");
|
| 391 |
+
defineSymbol(math, ams, rel, "\u2234", "\\therefore");
|
| 392 |
+
defineSymbol(math, ams, rel, "\u220d", "\\backepsilon");
|
| 393 |
+
defineSymbol(math, ams, rel, "\u25b6", "\\blacktriangleright");
|
| 394 |
+
defineSymbol(math, ams, rel, "\u2235", "\\because");
|
| 395 |
+
defineSymbol(math, ams, rel, "\u22d8", "\\llless");
|
| 396 |
+
defineSymbol(math, ams, rel, "\u22d9", "\\gggtr");
|
| 397 |
+
defineSymbol(math, ams, bin, "\u22b2", "\\lhd");
|
| 398 |
+
defineSymbol(math, ams, bin, "\u22b3", "\\rhd");
|
| 399 |
+
defineSymbol(math, ams, rel, "\u2242", "\\eqsim");
|
| 400 |
+
defineSymbol(math, main, rel, "\u22c8", "\\Join");
|
| 401 |
+
defineSymbol(math, ams, rel, "\u2251", "\\Doteq");
|
| 402 |
+
|
| 403 |
+
// AMS Binary Operators
|
| 404 |
+
defineSymbol(math, ams, bin, "\u2214", "\\dotplus");
|
| 405 |
+
defineSymbol(math, ams, bin, "\u2216", "\\smallsetminus");
|
| 406 |
+
defineSymbol(math, ams, bin, "\u22d2", "\\Cap");
|
| 407 |
+
defineSymbol(math, ams, bin, "\u22d3", "\\Cup");
|
| 408 |
+
defineSymbol(math, ams, bin, "\u2a5e", "\\doublebarwedge");
|
| 409 |
+
defineSymbol(math, ams, bin, "\u229f", "\\boxminus");
|
| 410 |
+
defineSymbol(math, ams, bin, "\u229e", "\\boxplus");
|
| 411 |
+
defineSymbol(math, ams, bin, "\u22c7", "\\divideontimes");
|
| 412 |
+
defineSymbol(math, ams, bin, "\u22c9", "\\ltimes");
|
| 413 |
+
defineSymbol(math, ams, bin, "\u22ca", "\\rtimes");
|
| 414 |
+
defineSymbol(math, ams, bin, "\u22cb", "\\leftthreetimes");
|
| 415 |
+
defineSymbol(math, ams, bin, "\u22cc", "\\rightthreetimes");
|
| 416 |
+
defineSymbol(math, ams, bin, "\u22cf", "\\curlywedge");
|
| 417 |
+
defineSymbol(math, ams, bin, "\u22ce", "\\curlyvee");
|
| 418 |
+
defineSymbol(math, ams, bin, "\u229d", "\\circleddash");
|
| 419 |
+
defineSymbol(math, ams, bin, "\u229b", "\\circledast");
|
| 420 |
+
defineSymbol(math, ams, bin, "\u22c5", "\\centerdot");
|
| 421 |
+
defineSymbol(math, ams, bin, "\u22ba", "\\intercal");
|
| 422 |
+
defineSymbol(math, ams, bin, "\u22d2", "\\doublecap");
|
| 423 |
+
defineSymbol(math, ams, bin, "\u22d3", "\\doublecup");
|
| 424 |
+
defineSymbol(math, ams, bin, "\u22a0", "\\boxtimes");
|
| 425 |
+
|
| 426 |
+
// AMS Arrows
|
| 427 |
+
defineSymbol(math, ams, rel, "\u21e2", "\\dashrightarrow");
|
| 428 |
+
defineSymbol(math, ams, rel, "\u21e0", "\\dashleftarrow");
|
| 429 |
+
defineSymbol(math, ams, rel, "\u21c7", "\\leftleftarrows");
|
| 430 |
+
defineSymbol(math, ams, rel, "\u21c6", "\\leftrightarrows");
|
| 431 |
+
defineSymbol(math, ams, rel, "\u21da", "\\Lleftarrow");
|
| 432 |
+
defineSymbol(math, ams, rel, "\u219e", "\\twoheadleftarrow");
|
| 433 |
+
defineSymbol(math, ams, rel, "\u21a2", "\\leftarrowtail");
|
| 434 |
+
defineSymbol(math, ams, rel, "\u21ab", "\\looparrowleft");
|
| 435 |
+
defineSymbol(math, ams, rel, "\u21cb", "\\leftrightharpoons");
|
| 436 |
+
defineSymbol(math, ams, rel, "\u21b6", "\\curvearrowleft");
|
| 437 |
+
defineSymbol(math, ams, rel, "\u21ba", "\\circlearrowleft");
|
| 438 |
+
defineSymbol(math, ams, rel, "\u21b0", "\\Lsh");
|
| 439 |
+
defineSymbol(math, ams, rel, "\u21c8", "\\upuparrows");
|
| 440 |
+
defineSymbol(math, ams, rel, "\u21bf", "\\upharpoonleft");
|
| 441 |
+
defineSymbol(math, ams, rel, "\u21c3", "\\downharpoonleft");
|
| 442 |
+
defineSymbol(math, ams, rel, "\u22b8", "\\multimap");
|
| 443 |
+
defineSymbol(math, ams, rel, "\u21ad", "\\leftrightsquigarrow");
|
| 444 |
+
defineSymbol(math, ams, rel, "\u21c9", "\\rightrightarrows");
|
| 445 |
+
defineSymbol(math, ams, rel, "\u21c4", "\\rightleftarrows");
|
| 446 |
+
defineSymbol(math, ams, rel, "\u21a0", "\\twoheadrightarrow");
|
| 447 |
+
defineSymbol(math, ams, rel, "\u21a3", "\\rightarrowtail");
|
| 448 |
+
defineSymbol(math, ams, rel, "\u21ac", "\\looparrowright");
|
| 449 |
+
defineSymbol(math, ams, rel, "\u21b7", "\\curvearrowright");
|
| 450 |
+
defineSymbol(math, ams, rel, "\u21bb", "\\circlearrowright");
|
| 451 |
+
defineSymbol(math, ams, rel, "\u21b1", "\\Rsh");
|
| 452 |
+
defineSymbol(math, ams, rel, "\u21ca", "\\downdownarrows");
|
| 453 |
+
defineSymbol(math, ams, rel, "\u21be", "\\upharpoonright");
|
| 454 |
+
defineSymbol(math, ams, rel, "\u21c2", "\\downharpoonright");
|
| 455 |
+
defineSymbol(math, ams, rel, "\u21dd", "\\rightsquigarrow");
|
| 456 |
+
defineSymbol(math, ams, rel, "\u21dd", "\\leadsto");
|
| 457 |
+
defineSymbol(math, ams, rel, "\u21db", "\\Rrightarrow");
|
| 458 |
+
defineSymbol(math, ams, rel, "\u21be", "\\restriction");
|
| 459 |
+
|
| 460 |
+
defineSymbol(math, main, textord, "\u2018", "`");
|
| 461 |
+
defineSymbol(math, main, textord, "$", "\\$");
|
| 462 |
+
defineSymbol(math, main, textord, "%", "\\%");
|
| 463 |
+
defineSymbol(math, main, textord, "_", "\\_");
|
| 464 |
+
defineSymbol(math, main, textord, "\u2220", "\\angle");
|
| 465 |
+
defineSymbol(math, main, textord, "\u221e", "\\infty");
|
| 466 |
+
defineSymbol(math, main, textord, "\u2032", "\\prime");
|
| 467 |
+
defineSymbol(math, main, textord, "\u25b3", "\\triangle");
|
| 468 |
+
defineSymbol(math, main, textord, "\u0393", "\\Gamma");
|
| 469 |
+
defineSymbol(math, main, textord, "\u0394", "\\Delta");
|
| 470 |
+
defineSymbol(math, main, textord, "\u0398", "\\Theta");
|
| 471 |
+
defineSymbol(math, main, textord, "\u039b", "\\Lambda");
|
| 472 |
+
defineSymbol(math, main, textord, "\u039e", "\\Xi");
|
| 473 |
+
defineSymbol(math, main, textord, "\u03a0", "\\Pi");
|
| 474 |
+
defineSymbol(math, main, textord, "\u03a3", "\\Sigma");
|
| 475 |
+
defineSymbol(math, main, textord, "\u03a5", "\\Upsilon");
|
| 476 |
+
defineSymbol(math, main, textord, "\u03a6", "\\Phi");
|
| 477 |
+
defineSymbol(math, main, textord, "\u03a8", "\\Psi");
|
| 478 |
+
defineSymbol(math, main, textord, "\u03a9", "\\Omega");
|
| 479 |
+
defineSymbol(math, main, textord, "\u00ac", "\\neg");
|
| 480 |
+
defineSymbol(math, main, textord, "\u00ac", "\\lnot");
|
| 481 |
+
defineSymbol(math, main, textord, "\u22a4", "\\top");
|
| 482 |
+
defineSymbol(math, main, textord, "\u22a5", "\\bot");
|
| 483 |
+
defineSymbol(math, main, textord, "\u2205", "\\emptyset");
|
| 484 |
+
defineSymbol(math, ams, textord, "\u2205", "\\varnothing");
|
| 485 |
+
defineSymbol(math, main, mathord, "\u03b1", "\\alpha");
|
| 486 |
+
defineSymbol(math, main, mathord, "\u03b2", "\\beta");
|
| 487 |
+
defineSymbol(math, main, mathord, "\u03b3", "\\gamma");
|
| 488 |
+
defineSymbol(math, main, mathord, "\u03b4", "\\delta");
|
| 489 |
+
defineSymbol(math, main, mathord, "\u03f5", "\\epsilon");
|
| 490 |
+
defineSymbol(math, main, mathord, "\u03b6", "\\zeta");
|
| 491 |
+
defineSymbol(math, main, mathord, "\u03b7", "\\eta");
|
| 492 |
+
defineSymbol(math, main, mathord, "\u03b8", "\\theta");
|
| 493 |
+
defineSymbol(math, main, mathord, "\u03b9", "\\iota");
|
| 494 |
+
defineSymbol(math, main, mathord, "\u03ba", "\\kappa");
|
| 495 |
+
defineSymbol(math, main, mathord, "\u03bb", "\\lambda");
|
| 496 |
+
defineSymbol(math, main, mathord, "\u03bc", "\\mu");
|
| 497 |
+
defineSymbol(math, main, mathord, "\u03bd", "\\nu");
|
| 498 |
+
defineSymbol(math, main, mathord, "\u03be", "\\xi");
|
| 499 |
+
defineSymbol(math, main, mathord, "o", "\\omicron");
|
| 500 |
+
defineSymbol(math, main, mathord, "\u03c0", "\\pi");
|
| 501 |
+
defineSymbol(math, main, mathord, "\u03c1", "\\rho");
|
| 502 |
+
defineSymbol(math, main, mathord, "\u03c3", "\\sigma");
|
| 503 |
+
defineSymbol(math, main, mathord, "\u03c4", "\\tau");
|
| 504 |
+
defineSymbol(math, main, mathord, "\u03c5", "\\upsilon");
|
| 505 |
+
defineSymbol(math, main, mathord, "\u03d5", "\\phi");
|
| 506 |
+
defineSymbol(math, main, mathord, "\u03c7", "\\chi");
|
| 507 |
+
defineSymbol(math, main, mathord, "\u03c8", "\\psi");
|
| 508 |
+
defineSymbol(math, main, mathord, "\u03c9", "\\omega");
|
| 509 |
+
defineSymbol(math, main, mathord, "\u03b5", "\\varepsilon");
|
| 510 |
+
defineSymbol(math, main, mathord, "\u03d1", "\\vartheta");
|
| 511 |
+
defineSymbol(math, main, mathord, "\u03d6", "\\varpi");
|
| 512 |
+
defineSymbol(math, main, mathord, "\u03f1", "\\varrho");
|
| 513 |
+
defineSymbol(math, main, mathord, "\u03c2", "\\varsigma");
|
| 514 |
+
defineSymbol(math, main, mathord, "\u03c6", "\\varphi");
|
| 515 |
+
defineSymbol(math, main, bin, "\u2217", "*");
|
| 516 |
+
defineSymbol(math, main, bin, "+", "+");
|
| 517 |
+
defineSymbol(math, main, bin, "\u2212", "-");
|
| 518 |
+
defineSymbol(math, main, bin, "\u22c5", "\\cdot");
|
| 519 |
+
defineSymbol(math, main, bin, "\u2218", "\\circ");
|
| 520 |
+
defineSymbol(math, main, bin, "\u00f7", "\\div");
|
| 521 |
+
defineSymbol(math, main, bin, "\u00b1", "\\pm");
|
| 522 |
+
defineSymbol(math, main, bin, "\u00d7", "\\times");
|
| 523 |
+
defineSymbol(math, main, bin, "\u2229", "\\cap");
|
| 524 |
+
defineSymbol(math, main, bin, "\u222a", "\\cup");
|
| 525 |
+
defineSymbol(math, main, bin, "\u2216", "\\setminus");
|
| 526 |
+
defineSymbol(math, main, bin, "\u2227", "\\land");
|
| 527 |
+
defineSymbol(math, main, bin, "\u2228", "\\lor");
|
| 528 |
+
defineSymbol(math, main, bin, "\u2227", "\\wedge");
|
| 529 |
+
defineSymbol(math, main, bin, "\u2228", "\\vee");
|
| 530 |
+
defineSymbol(math, main, textord, "\u221a", "\\surd");
|
| 531 |
+
defineSymbol(math, main, open, "(", "(");
|
| 532 |
+
defineSymbol(math, main, open, "[", "[");
|
| 533 |
+
defineSymbol(math, main, open, "\u27e8", "\\langle");
|
| 534 |
+
defineSymbol(math, main, open, "\u2223", "\\lvert");
|
| 535 |
+
defineSymbol(math, main, open, "\u2225", "\\lVert");
|
| 536 |
+
defineSymbol(math, main, close, ")", ")");
|
| 537 |
+
defineSymbol(math, main, close, "]", "]");
|
| 538 |
+
defineSymbol(math, main, close, "?", "?");
|
| 539 |
+
defineSymbol(math, main, close, "!", "!");
|
| 540 |
+
defineSymbol(math, main, close, "\u27e9", "\\rangle");
|
| 541 |
+
defineSymbol(math, main, close, "\u2223", "\\rvert");
|
| 542 |
+
defineSymbol(math, main, close, "\u2225", "\\rVert");
|
| 543 |
+
defineSymbol(math, main, rel, "=", "=");
|
| 544 |
+
defineSymbol(math, main, rel, "<", "<");
|
| 545 |
+
defineSymbol(math, main, rel, ">", ">");
|
| 546 |
+
defineSymbol(math, main, rel, ":", ":");
|
| 547 |
+
defineSymbol(math, main, rel, "\u2248", "\\approx");
|
| 548 |
+
defineSymbol(math, main, rel, "\u2245", "\\cong");
|
| 549 |
+
defineSymbol(math, main, rel, "\u2265", "\\ge");
|
| 550 |
+
defineSymbol(math, main, rel, "\u2265", "\\geq");
|
| 551 |
+
defineSymbol(math, main, rel, "\u2190", "\\gets");
|
| 552 |
+
defineSymbol(math, main, rel, ">", "\\gt");
|
| 553 |
+
defineSymbol(math, main, rel, "\u2208", "\\in");
|
| 554 |
+
defineSymbol(math, main, rel, "\u2209", "\\notin");
|
| 555 |
+
defineSymbol(math, main, rel, "\u2282", "\\subset");
|
| 556 |
+
defineSymbol(math, main, rel, "\u2283", "\\supset");
|
| 557 |
+
defineSymbol(math, main, rel, "\u2286", "\\subseteq");
|
| 558 |
+
defineSymbol(math, main, rel, "\u2287", "\\supseteq");
|
| 559 |
+
defineSymbol(math, ams, rel, "\u2288", "\\nsubseteq");
|
| 560 |
+
defineSymbol(math, ams, rel, "\u2289", "\\nsupseteq");
|
| 561 |
+
defineSymbol(math, main, rel, "\u22a8", "\\models");
|
| 562 |
+
defineSymbol(math, main, rel, "\u2190", "\\leftarrow");
|
| 563 |
+
defineSymbol(math, main, rel, "\u2264", "\\le");
|
| 564 |
+
defineSymbol(math, main, rel, "\u2264", "\\leq");
|
| 565 |
+
defineSymbol(math, main, rel, "<", "\\lt");
|
| 566 |
+
defineSymbol(math, main, rel, "\u2260", "\\ne");
|
| 567 |
+
defineSymbol(math, main, rel, "\u2260", "\\neq");
|
| 568 |
+
defineSymbol(math, main, rel, "\u2192", "\\rightarrow");
|
| 569 |
+
defineSymbol(math, main, rel, "\u2192", "\\to");
|
| 570 |
+
defineSymbol(math, ams, rel, "\u2271", "\\ngeq");
|
| 571 |
+
defineSymbol(math, ams, rel, "\u2270", "\\nleq");
|
| 572 |
+
defineSymbol(math, main, spacing, null, "\\!");
|
| 573 |
+
defineSymbol(math, main, spacing, "\u00a0", "\\ ");
|
| 574 |
+
defineSymbol(math, main, spacing, "\u00a0", "~");
|
| 575 |
+
defineSymbol(math, main, spacing, null, "\\,");
|
| 576 |
+
defineSymbol(math, main, spacing, null, "\\:");
|
| 577 |
+
defineSymbol(math, main, spacing, null, "\\;");
|
| 578 |
+
defineSymbol(math, main, spacing, null, "\\enspace");
|
| 579 |
+
defineSymbol(math, main, spacing, null, "\\qquad");
|
| 580 |
+
defineSymbol(math, main, spacing, null, "\\quad");
|
| 581 |
+
defineSymbol(math, main, spacing, "\u00a0", "\\space");
|
| 582 |
+
defineSymbol(math, main, punct, ",", ",");
|
| 583 |
+
defineSymbol(math, main, punct, ";", ";");
|
| 584 |
+
defineSymbol(math, main, punct, ":", "\\colon");
|
| 585 |
+
defineSymbol(math, ams, bin, "\u22bc", "\\barwedge");
|
| 586 |
+
defineSymbol(math, ams, bin, "\u22bb", "\\veebar");
|
| 587 |
+
defineSymbol(math, main, bin, "\u2299", "\\odot");
|
| 588 |
+
defineSymbol(math, main, bin, "\u2295", "\\oplus");
|
| 589 |
+
defineSymbol(math, main, bin, "\u2297", "\\otimes");
|
| 590 |
+
defineSymbol(math, main, textord, "\u2202", "\\partial");
|
| 591 |
+
defineSymbol(math, main, bin, "\u2298", "\\oslash");
|
| 592 |
+
defineSymbol(math, ams, bin, "\u229a", "\\circledcirc");
|
| 593 |
+
defineSymbol(math, ams, bin, "\u22a1", "\\boxdot");
|
| 594 |
+
defineSymbol(math, main, bin, "\u25b3", "\\bigtriangleup");
|
| 595 |
+
defineSymbol(math, main, bin, "\u25bd", "\\bigtriangledown");
|
| 596 |
+
defineSymbol(math, main, bin, "\u2020", "\\dagger");
|
| 597 |
+
defineSymbol(math, main, bin, "\u22c4", "\\diamond");
|
| 598 |
+
defineSymbol(math, main, bin, "\u22c6", "\\star");
|
| 599 |
+
defineSymbol(math, main, bin, "\u25c3", "\\triangleleft");
|
| 600 |
+
defineSymbol(math, main, bin, "\u25b9", "\\triangleright");
|
| 601 |
+
defineSymbol(math, main, open, "{", "\\{");
|
| 602 |
+
defineSymbol(math, main, close, "}", "\\}");
|
| 603 |
+
defineSymbol(math, main, open, "{", "\\lbrace");
|
| 604 |
+
defineSymbol(math, main, close, "}", "\\rbrace");
|
| 605 |
+
defineSymbol(math, main, open, "[", "\\lbrack");
|
| 606 |
+
defineSymbol(math, main, close, "]", "\\rbrack");
|
| 607 |
+
defineSymbol(math, main, open, "\u230a", "\\lfloor");
|
| 608 |
+
defineSymbol(math, main, close, "\u230b", "\\rfloor");
|
| 609 |
+
defineSymbol(math, main, open, "\u2308", "\\lceil");
|
| 610 |
+
defineSymbol(math, main, close, "\u2309", "\\rceil");
|
| 611 |
+
defineSymbol(math, main, textord, "\\", "\\backslash");
|
| 612 |
+
defineSymbol(math, main, textord, "\u2223", "|");
|
| 613 |
+
defineSymbol(math, main, textord, "\u2223", "\\vert");
|
| 614 |
+
defineSymbol(math, main, textord, "\u2225", "\\|");
|
| 615 |
+
defineSymbol(math, main, textord, "\u2225", "\\Vert");
|
| 616 |
+
defineSymbol(math, main, rel, "\u2191", "\\uparrow");
|
| 617 |
+
defineSymbol(math, main, rel, "\u21d1", "\\Uparrow");
|
| 618 |
+
defineSymbol(math, main, rel, "\u2193", "\\downarrow");
|
| 619 |
+
defineSymbol(math, main, rel, "\u21d3", "\\Downarrow");
|
| 620 |
+
defineSymbol(math, main, rel, "\u2195", "\\updownarrow");
|
| 621 |
+
defineSymbol(math, main, rel, "\u21d5", "\\Updownarrow");
|
| 622 |
+
defineSymbol(math, math, op, "\u2210", "\\coprod");
|
| 623 |
+
defineSymbol(math, math, op, "\u22c1", "\\bigvee");
|
| 624 |
+
defineSymbol(math, math, op, "\u22c0", "\\bigwedge");
|
| 625 |
+
defineSymbol(math, math, op, "\u2a04", "\\biguplus");
|
| 626 |
+
defineSymbol(math, math, op, "\u22c2", "\\bigcap");
|
| 627 |
+
defineSymbol(math, math, op, "\u22c3", "\\bigcup");
|
| 628 |
+
defineSymbol(math, math, op, "\u222b", "\\int");
|
| 629 |
+
defineSymbol(math, math, op, "\u222b", "\\intop");
|
| 630 |
+
defineSymbol(math, math, op, "\u222c", "\\iint");
|
| 631 |
+
defineSymbol(math, math, op, "\u222d", "\\iiint");
|
| 632 |
+
defineSymbol(math, math, op, "\u220f", "\\prod");
|
| 633 |
+
defineSymbol(math, math, op, "\u2211", "\\sum");
|
| 634 |
+
|
| 635 |
+
defineSymbol(math, math, op, "\u2a02", "\\bigotimes");
|
| 636 |
+
defineSymbol(math, math, op, "\u2a01", "\\bigoplus");
|
| 637 |
+
defineSymbol(math, math, op, "\u2a00", "\\bigodot");
|
| 638 |
+
defineSymbol(math, math, op, "\u222e", "\\oint");
|
| 639 |
+
defineSymbol(math, math, op, "\u2a06", "\\bigsqcup");
|
| 640 |
+
defineSymbol(math, math, op, "\u222b", "\\smallint");
|
| 641 |
+
defineSymbol(math, main, inner, "\u2026", "\\ldots");
|
| 642 |
+
defineSymbol(math, main, inner, "\u22ef", "\\cdots");
|
| 643 |
+
defineSymbol(math, main, inner, "\u22f1", "\\ddots");
|
| 644 |
+
defineSymbol(math, main, textord, "\u22ee", "\\vdots");
|
| 645 |
+
defineSymbol(math, main, accent, "\u00b4", "\\acute");
|
| 646 |
+
defineSymbol(math, main, accent, "\u0060", "\\grave");
|
| 647 |
+
defineSymbol(math, main, accent, "\u00a8", "\\ddot");
|
| 648 |
+
defineSymbol(math, main, accent, "\u007e", "\\tilde");
|
| 649 |
+
defineSymbol(math, main, accent, "\u00af", "\\bar");
|
| 650 |
+
defineSymbol(math, main, accent, "\u02d8", "\\breve");
|
| 651 |
+
defineSymbol(math, main, accent, "\u02c7", "\\check");
|
| 652 |
+
defineSymbol(math, main, accent, "\u005e", "\\hat");
|
| 653 |
+
defineSymbol(math, main, accent, "\u20d7", "\\vec");
|
| 654 |
+
defineSymbol(math, main, accent, "\u02d9", "\\dot");
|
| 655 |
+
defineSymbol(math, main, mathord, "\u0131", "\\imath");
|
| 656 |
+
defineSymbol(math, main, mathord, "\u0237", "\\jmath");
|
| 657 |
+
|
| 658 |
+
|
| 659 |
+
defineSymbol(text, main, spacing, "\u00a0", "\\ ");
|
| 660 |
+
defineSymbol(text, main, spacing, "\u00a0", " ");
|
| 661 |
+
defineSymbol(text, main, spacing, "\u00a0", "~");
|
| 662 |
+
|
| 663 |
+
// There are lots of symbols which are the same, so we add them in afterwards.
|
| 664 |
+
var i;
|
| 665 |
+
var ch;
|
| 666 |
+
|
| 667 |
+
// All of these are textords in math mode
|
| 668 |
+
var mathTextSymbols = "0123456789/@.\"";
|
| 669 |
+
for (i = 0; i < mathTextSymbols.length; i++) {
|
| 670 |
+
ch = mathTextSymbols.charAt(i);
|
| 671 |
+
defineSymbol(math, main, textord, ch, ch);
|
| 672 |
+
}
|
| 673 |
+
|
| 674 |
+
// All of these are textords in text mode
|
| 675 |
+
var textSymbols = "0123456789`!@*()-=+[]'\";:?/.,";
|
| 676 |
+
for (i = 0; i < textSymbols.length; i++) {
|
| 677 |
+
ch = textSymbols.charAt(i);
|
| 678 |
+
defineSymbol(text, main, textord, ch, ch);
|
| 679 |
+
}
|
| 680 |
+
|
| 681 |
+
// All of these are textords in text mode, and mathords in math mode
|
| 682 |
+
var letters = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ";
|
| 683 |
+
for (i = 0; i < letters.length; i++) {
|
| 684 |
+
ch = letters.charAt(i);
|
| 685 |
+
defineSymbol(math, main, mathord, ch, ch);
|
| 686 |
+
defineSymbol(text, main, textord, ch, ch);
|
| 687 |
+
}
|
katex/src/utils.js
ADDED
|
@@ -0,0 +1,106 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
/**
|
| 2 |
+
* This file contains a list of utility functions which are useful in other
|
| 3 |
+
* files.
|
| 4 |
+
*/
|
| 5 |
+
|
| 6 |
+
/**
|
| 7 |
+
* Provide an `indexOf` function which works in IE8, but defers to native if
|
| 8 |
+
* possible.
|
| 9 |
+
*/
|
| 10 |
+
var nativeIndexOf = Array.prototype.indexOf;
|
| 11 |
+
var indexOf = function(list, elem) {
|
| 12 |
+
if (list == null) {
|
| 13 |
+
return -1;
|
| 14 |
+
}
|
| 15 |
+
if (nativeIndexOf && list.indexOf === nativeIndexOf) {
|
| 16 |
+
return list.indexOf(elem);
|
| 17 |
+
}
|
| 18 |
+
var i = 0;
|
| 19 |
+
var l = list.length;
|
| 20 |
+
for (; i < l; i++) {
|
| 21 |
+
if (list[i] === elem) {
|
| 22 |
+
return i;
|
| 23 |
+
}
|
| 24 |
+
}
|
| 25 |
+
return -1;
|
| 26 |
+
};
|
| 27 |
+
|
| 28 |
+
/**
|
| 29 |
+
* Return whether an element is contained in a list
|
| 30 |
+
*/
|
| 31 |
+
var contains = function(list, elem) {
|
| 32 |
+
return indexOf(list, elem) !== -1;
|
| 33 |
+
};
|
| 34 |
+
|
| 35 |
+
/**
|
| 36 |
+
* Provide a default value if a setting is undefined
|
| 37 |
+
*/
|
| 38 |
+
var deflt = function(setting, defaultIfUndefined) {
|
| 39 |
+
return setting === undefined ? defaultIfUndefined : setting;
|
| 40 |
+
};
|
| 41 |
+
|
| 42 |
+
// hyphenate and escape adapted from Facebook's React under Apache 2 license
|
| 43 |
+
|
| 44 |
+
var uppercase = /([A-Z])/g;
|
| 45 |
+
var hyphenate = function(str) {
|
| 46 |
+
return str.replace(uppercase, "-$1").toLowerCase();
|
| 47 |
+
};
|
| 48 |
+
|
| 49 |
+
var ESCAPE_LOOKUP = {
|
| 50 |
+
"&": "&",
|
| 51 |
+
">": ">",
|
| 52 |
+
"<": "<",
|
| 53 |
+
"\"": """,
|
| 54 |
+
"'": "'",
|
| 55 |
+
};
|
| 56 |
+
|
| 57 |
+
var ESCAPE_REGEX = /[&><"']/g;
|
| 58 |
+
|
| 59 |
+
function escaper(match) {
|
| 60 |
+
return ESCAPE_LOOKUP[match];
|
| 61 |
+
}
|
| 62 |
+
|
| 63 |
+
/**
|
| 64 |
+
* Escapes text to prevent scripting attacks.
|
| 65 |
+
*
|
| 66 |
+
* @param {*} text Text value to escape.
|
| 67 |
+
* @return {string} An escaped string.
|
| 68 |
+
*/
|
| 69 |
+
function escape(text) {
|
| 70 |
+
return ("" + text).replace(ESCAPE_REGEX, escaper);
|
| 71 |
+
}
|
| 72 |
+
|
| 73 |
+
/**
|
| 74 |
+
* A function to set the text content of a DOM element in all supported
|
| 75 |
+
* browsers. Note that we don't define this if there is no document.
|
| 76 |
+
*/
|
| 77 |
+
var setTextContent;
|
| 78 |
+
if (typeof document !== "undefined") {
|
| 79 |
+
var testNode = document.createElement("span");
|
| 80 |
+
if ("textContent" in testNode) {
|
| 81 |
+
setTextContent = function(node, text) {
|
| 82 |
+
node.textContent = text;
|
| 83 |
+
};
|
| 84 |
+
} else {
|
| 85 |
+
setTextContent = function(node, text) {
|
| 86 |
+
node.innerText = text;
|
| 87 |
+
};
|
| 88 |
+
}
|
| 89 |
+
}
|
| 90 |
+
|
| 91 |
+
/**
|
| 92 |
+
* A function to clear a node.
|
| 93 |
+
*/
|
| 94 |
+
function clearNode(node) {
|
| 95 |
+
setTextContent(node, "");
|
| 96 |
+
}
|
| 97 |
+
|
| 98 |
+
module.exports = {
|
| 99 |
+
contains: contains,
|
| 100 |
+
deflt: deflt,
|
| 101 |
+
escape: escape,
|
| 102 |
+
hyphenate: hyphenate,
|
| 103 |
+
indexOf: indexOf,
|
| 104 |
+
setTextContent: setTextContent,
|
| 105 |
+
clearNode: clearNode,
|
| 106 |
+
};
|
match-at/README.md
ADDED
|
@@ -0,0 +1 @@
|
|
|
|
|
|
|
| 1 |
+
# match-at [](https://travis-ci.org/spicyj/match-at)
|
match-at/lib/__tests__/matchAt-test.js
ADDED
|
@@ -0,0 +1,90 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
"use strict";
|
| 2 |
+
|
| 3 |
+
describe("matchAt", function () {
|
| 4 |
+
|
| 5 |
+
var matchAt;
|
| 6 |
+
|
| 7 |
+
beforeEach(function () {
|
| 8 |
+
matchAt = require("../matchAt.js");
|
| 9 |
+
});
|
| 10 |
+
|
| 11 |
+
it("matches a simple regex", function () {
|
| 12 |
+
expect(matchAt(/l/, "hello", 0)).toBe(null);
|
| 13 |
+
expect(matchAt(/l/, "hello", 1)).toBe(null);
|
| 14 |
+
expect(matchAt(/l/, "hello", 4)).toBe(null);
|
| 15 |
+
expect(matchAt(/l/, "hello", 5)).toBe(null);
|
| 16 |
+
|
| 17 |
+
var match = matchAt(/l/, "hello", 2);
|
| 18 |
+
expect(Array.isArray(match)).toBe(true);
|
| 19 |
+
expect(match.index).toBe(2);
|
| 20 |
+
expect(match.input).toBe("hello");
|
| 21 |
+
expect(match[0]).toBe("l");
|
| 22 |
+
expect(match[1]).toBe(undefined);
|
| 23 |
+
expect(match.length).toBe(1);
|
| 24 |
+
|
| 25 |
+
var match = matchAt(/l/, "hello", 3);
|
| 26 |
+
expect(Array.isArray(match)).toBe(true);
|
| 27 |
+
expect(match.index).toBe(3);
|
| 28 |
+
expect(match.input).toBe("hello");
|
| 29 |
+
expect(match[0]).toBe("l");
|
| 30 |
+
expect(match[1]).toBe(undefined);
|
| 31 |
+
expect(match.length).toBe(1);
|
| 32 |
+
});
|
| 33 |
+
|
| 34 |
+
it("matches a zero-length regex", function () {
|
| 35 |
+
expect(matchAt(/(?=l)/, "hello", 0)).toBe(null);
|
| 36 |
+
expect(matchAt(/(?=l)/, "hello", 1)).toBe(null);
|
| 37 |
+
expect(matchAt(/(?=l)/, "hello", 4)).toBe(null);
|
| 38 |
+
expect(matchAt(/(?=l)/, "hello", 5)).toBe(null);
|
| 39 |
+
|
| 40 |
+
var match = matchAt(/(?=l)/, "hello", 2);
|
| 41 |
+
expect(Array.isArray(match)).toBe(true);
|
| 42 |
+
expect(match.index).toBe(2);
|
| 43 |
+
expect(match.input).toBe("hello");
|
| 44 |
+
expect(match[0]).toBe("");
|
| 45 |
+
expect(match[1]).toBe(undefined);
|
| 46 |
+
expect(match.length).toBe(1);
|
| 47 |
+
|
| 48 |
+
var match = matchAt(/(?=l)/, "hello", 3);
|
| 49 |
+
expect(Array.isArray(match)).toBe(true);
|
| 50 |
+
expect(match.index).toBe(3);
|
| 51 |
+
expect(match.input).toBe("hello");
|
| 52 |
+
expect(match[0]).toBe("");
|
| 53 |
+
expect(match[1]).toBe(undefined);
|
| 54 |
+
expect(match.length).toBe(1);
|
| 55 |
+
});
|
| 56 |
+
|
| 57 |
+
it("matches a regex with capturing groups", function () {
|
| 58 |
+
expect(matchAt(/(l)(l)?/, "hello", 0)).toBe(null);
|
| 59 |
+
expect(matchAt(/(l)(l)?/, "hello", 1)).toBe(null);
|
| 60 |
+
expect(matchAt(/(l)(l)?/, "hello", 4)).toBe(null);
|
| 61 |
+
expect(matchAt(/(l)(l)?/, "hello", 5)).toBe(null);
|
| 62 |
+
|
| 63 |
+
var match = matchAt(/(l)(l)?/, "hello", 2);
|
| 64 |
+
expect(Array.isArray(match)).toBe(true);
|
| 65 |
+
expect(match.index).toBe(2);
|
| 66 |
+
expect(match.input).toBe("hello");
|
| 67 |
+
expect(match[0]).toBe("ll");
|
| 68 |
+
expect(match[1]).toBe("l");
|
| 69 |
+
expect(match[2]).toBe("l");
|
| 70 |
+
expect(match.length).toBe(3);
|
| 71 |
+
|
| 72 |
+
var match = matchAt(/(l)(l)?/, "hello", 3);
|
| 73 |
+
expect(Array.isArray(match)).toBe(true);
|
| 74 |
+
expect(match.index).toBe(3);
|
| 75 |
+
expect(match.input).toBe("hello");
|
| 76 |
+
expect(match[0]).toBe("l");
|
| 77 |
+
expect(match[1]).toBe("l");
|
| 78 |
+
expect(match[2]).toBe(undefined);
|
| 79 |
+
expect(match.length).toBe(3);
|
| 80 |
+
});
|
| 81 |
+
|
| 82 |
+
it("copies flags over", function () {
|
| 83 |
+
expect(matchAt(/L/i, "hello", 0)).toBe(null);
|
| 84 |
+
expect(matchAt(/L/i, "hello", 1)).toBe(null);
|
| 85 |
+
expect(matchAt(/L/i, "hello", 2)).not.toBe(null);
|
| 86 |
+
expect(matchAt(/L/i, "hello", 3)).not.toBe(null);
|
| 87 |
+
expect(matchAt(/L/i, "hello", 4)).toBe(null);
|
| 88 |
+
expect(matchAt(/L/i, "hello", 5)).toBe(null);
|
| 89 |
+
});
|
| 90 |
+
});
|
match-at/lib/matchAt.js
ADDED
|
@@ -0,0 +1,42 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
/** @flow */
|
| 2 |
+
|
| 3 |
+
"use strict";
|
| 4 |
+
|
| 5 |
+
function getRelocatable(re) {
|
| 6 |
+
// In the future, this could use a WeakMap instead of an expando.
|
| 7 |
+
if (!re.__matchAtRelocatable) {
|
| 8 |
+
// Disjunctions are the lowest-precedence operator, so we can make any
|
| 9 |
+
// pattern match the empty string by appending `|()` to it:
|
| 10 |
+
// https://people.mozilla.org/~jorendorff/es6-draft.html#sec-patterns
|
| 11 |
+
var source = re.source + "|()";
|
| 12 |
+
|
| 13 |
+
// We always make the new regex global.
|
| 14 |
+
var flags = "g" + (re.ignoreCase ? "i" : "") + (re.multiline ? "m" : "") + (re.unicode ? "u" : "")
|
| 15 |
+
// sticky (/.../y) doesn't make sense in conjunction with our relocation
|
| 16 |
+
// logic, so we ignore it here.
|
| 17 |
+
;
|
| 18 |
+
|
| 19 |
+
re.__matchAtRelocatable = new RegExp(source, flags);
|
| 20 |
+
}
|
| 21 |
+
return re.__matchAtRelocatable;
|
| 22 |
+
}
|
| 23 |
+
|
| 24 |
+
function matchAt(re, str, pos) {
|
| 25 |
+
if (re.global || re.sticky) {
|
| 26 |
+
throw new Error("matchAt(...): Only non-global regexes are supported");
|
| 27 |
+
}
|
| 28 |
+
var reloc = getRelocatable(re);
|
| 29 |
+
reloc.lastIndex = pos;
|
| 30 |
+
var match = reloc.exec(str);
|
| 31 |
+
// Last capturing group is our sentinel that indicates whether the regex
|
| 32 |
+
// matched at the given location.
|
| 33 |
+
if (match[match.length - 1] == null) {
|
| 34 |
+
// Original regex matched.
|
| 35 |
+
match.length = match.length - 1;
|
| 36 |
+
return match;
|
| 37 |
+
} else {
|
| 38 |
+
return null;
|
| 39 |
+
}
|
| 40 |
+
}
|
| 41 |
+
|
| 42 |
+
module.exports = matchAt;
|
match-at/package.json
ADDED
|
@@ -0,0 +1,54 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
{
|
| 2 |
+
"name": "match-at",
|
| 3 |
+
"version": "0.1.0",
|
| 4 |
+
"description": "Relocatable regular expressions.",
|
| 5 |
+
"repository": {
|
| 6 |
+
"type": "git",
|
| 7 |
+
"url": "https://github.com/spicyj/match-at"
|
| 8 |
+
},
|
| 9 |
+
"main": "lib/matchAt.js",
|
| 10 |
+
"files": [
|
| 11 |
+
"lib/"
|
| 12 |
+
],
|
| 13 |
+
"devDependencies": {
|
| 14 |
+
"babel": "^4.7.16",
|
| 15 |
+
"jest-cli": "^0.4.0",
|
| 16 |
+
"react-tools": "^0.13.1"
|
| 17 |
+
},
|
| 18 |
+
"jest": {
|
| 19 |
+
"scriptPreprocessor": "<rootDir>/jestSupport/preprocessor.js",
|
| 20 |
+
"unmockedModulePathPatterns": [
|
| 21 |
+
""
|
| 22 |
+
]
|
| 23 |
+
},
|
| 24 |
+
"scripts": {
|
| 25 |
+
"prepublish": "babel -d lib/ src/",
|
| 26 |
+
"test": "jest"
|
| 27 |
+
},
|
| 28 |
+
"gitHead": "4197daff69720734c72ba3321ed68a41c0527fb2",
|
| 29 |
+
"bugs": {
|
| 30 |
+
"url": "https://github.com/spicyj/match-at/issues"
|
| 31 |
+
},
|
| 32 |
+
"homepage": "https://github.com/spicyj/match-at",
|
| 33 |
+
"_id": "[email protected]",
|
| 34 |
+
"_shasum": "f561e7709ff9a105b85cc62c6b8ee7c15bf24f31",
|
| 35 |
+
"_from": "match-at@",
|
| 36 |
+
"_npmVersion": "2.2.0",
|
| 37 |
+
"_nodeVersion": "0.10.35",
|
| 38 |
+
"_npmUser": {
|
| 39 |
+
"name": "spicyj",
|
| 40 |
+
"email": "[email protected]"
|
| 41 |
+
},
|
| 42 |
+
"maintainers": [
|
| 43 |
+
{
|
| 44 |
+
"name": "spicyj",
|
| 45 |
+
"email": "[email protected]"
|
| 46 |
+
}
|
| 47 |
+
],
|
| 48 |
+
"dist": {
|
| 49 |
+
"shasum": "f561e7709ff9a105b85cc62c6b8ee7c15bf24f31",
|
| 50 |
+
"tarball": "https://registry.npmjs.org/match-at/-/match-at-0.1.0.tgz"
|
| 51 |
+
},
|
| 52 |
+
"directories": {},
|
| 53 |
+
"_resolved": "https://registry.npmjs.org/match-at/-/match-at-0.1.0.tgz"
|
| 54 |
+
}
|
preprocess_latex.js
ADDED
|
@@ -0,0 +1,395 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
var katex = require("./katex/katex.js")
|
| 2 |
+
options = require("./katex/src/Options.js")
|
| 3 |
+
var readline = require('readline');
|
| 4 |
+
var rl = readline.createInterface({
|
| 5 |
+
input: process.stdin,
|
| 6 |
+
output: process.stdout,
|
| 7 |
+
terminal: false
|
| 8 |
+
});
|
| 9 |
+
|
| 10 |
+
|
| 11 |
+
rl.on('line', function(line){
|
| 12 |
+
a = line
|
| 13 |
+
if (line[0] == "%") {
|
| 14 |
+
line = line.substr(1, line.length - 1);
|
| 15 |
+
}
|
| 16 |
+
line = line.split('%')[0];
|
| 17 |
+
|
| 18 |
+
line = line.split('\\~').join(' ');
|
| 19 |
+
|
| 20 |
+
for (var i = 0; i < 300; i++) {
|
| 21 |
+
line = line.replace(/\\>/, " ");
|
| 22 |
+
line = line.replace('$', ' ');
|
| 23 |
+
line = line.replace(/\\label{.*?}/, "");
|
| 24 |
+
}
|
| 25 |
+
|
| 26 |
+
if (line.indexOf("matrix") == -1 && line.indexOf("cases")==-1 &&
|
| 27 |
+
line.indexOf("array")==-1 && line.indexOf("begin")==-1) {
|
| 28 |
+
for (var i = 0; i < 300; i++) {
|
| 29 |
+
line = line.replace(/\\\\/, "\\,");
|
| 30 |
+
}
|
| 31 |
+
}
|
| 32 |
+
|
| 33 |
+
|
| 34 |
+
line = line + " "
|
| 35 |
+
// global_str is tokenized version (build in parser.js)
|
| 36 |
+
// norm_str is normalized version build by renderer below.
|
| 37 |
+
//Yuntiantry {
|
| 38 |
+
|
| 39 |
+
|
| 40 |
+
if (process.argv[2] == "tokenize") {
|
| 41 |
+
var tree = katex.__parse(line, {});
|
| 42 |
+
console.log(global_str.replace(/\\label { .*? }/, ""));
|
| 43 |
+
} else {
|
| 44 |
+
for (var i = 0; i < 300; ++i) {
|
| 45 |
+
line = line.replace(/{\\rm/, "\\mathrm{");
|
| 46 |
+
line = line.replace(/{ \\rm/, "\\mathrm{");
|
| 47 |
+
line = line.replace(/\\rm{/, "\\mathrm{");
|
| 48 |
+
}
|
| 49 |
+
|
| 50 |
+
var tree = katex.__parse(line, {});
|
| 51 |
+
buildExpression(tree, new options({}));
|
| 52 |
+
for (var i = 0; i < 300; ++i) {
|
| 53 |
+
norm_str = norm_str.replace('SSSSSS', '$');
|
| 54 |
+
norm_str = norm_str.replace(' S S S S S S', '$');
|
| 55 |
+
}
|
| 56 |
+
console.log(norm_str.replace(/\\label { .*? }/, ""));
|
| 57 |
+
}
|
| 58 |
+
//} catch (e) {
|
| 59 |
+
// console.error(line);
|
| 60 |
+
// console.error(norm_str);
|
| 61 |
+
// console.error(e);
|
| 62 |
+
// console.log("");
|
| 63 |
+
//}
|
| 64 |
+
global_str = ""
|
| 65 |
+
norm_str = ""
|
| 66 |
+
})
|
| 67 |
+
|
| 68 |
+
|
| 69 |
+
|
| 70 |
+
// This is a LaTeX AST to LaTeX Renderer (modified version of KaTeX AST-> MathML).
|
| 71 |
+
norm_str = ""
|
| 72 |
+
|
| 73 |
+
var groupTypes = {};
|
| 74 |
+
|
| 75 |
+
groupTypes.mathord = function(group, options) {
|
| 76 |
+
if (options.font == "mathrm"){
|
| 77 |
+
for (i = 0; i < group.value.length; ++i ) {
|
| 78 |
+
if (group.value[i] == " ") {
|
| 79 |
+
norm_str = norm_str + group.value[i] + "\; ";
|
| 80 |
+
} else {
|
| 81 |
+
norm_str = norm_str + group.value[i] + " ";
|
| 82 |
+
}
|
| 83 |
+
}
|
| 84 |
+
} else {
|
| 85 |
+
norm_str = norm_str + group.value + " ";
|
| 86 |
+
}
|
| 87 |
+
};
|
| 88 |
+
|
| 89 |
+
groupTypes.textord = function(group, options) {
|
| 90 |
+
norm_str = norm_str + group.value + " ";
|
| 91 |
+
};
|
| 92 |
+
|
| 93 |
+
groupTypes.bin = function(group) {
|
| 94 |
+
norm_str = norm_str + group.value + " ";
|
| 95 |
+
};
|
| 96 |
+
|
| 97 |
+
groupTypes.rel = function(group) {
|
| 98 |
+
norm_str = norm_str + group.value + " ";
|
| 99 |
+
};
|
| 100 |
+
|
| 101 |
+
groupTypes.open = function(group) {
|
| 102 |
+
norm_str = norm_str + group.value + " ";
|
| 103 |
+
};
|
| 104 |
+
|
| 105 |
+
groupTypes.close = function(group) {
|
| 106 |
+
norm_str = norm_str + group.value + " ";
|
| 107 |
+
};
|
| 108 |
+
|
| 109 |
+
groupTypes.inner = function(group) {
|
| 110 |
+
norm_str = norm_str + group.value + " ";
|
| 111 |
+
};
|
| 112 |
+
|
| 113 |
+
groupTypes.punct = function(group) {
|
| 114 |
+
norm_str = norm_str + group.value + " ";
|
| 115 |
+
};
|
| 116 |
+
|
| 117 |
+
groupTypes.ordgroup = function(group, options) {
|
| 118 |
+
norm_str = norm_str + "{ ";
|
| 119 |
+
|
| 120 |
+
buildExpression(group.value, options);
|
| 121 |
+
|
| 122 |
+
norm_str = norm_str + "} ";
|
| 123 |
+
};
|
| 124 |
+
|
| 125 |
+
groupTypes.text = function(group, options) {
|
| 126 |
+
|
| 127 |
+
norm_str = norm_str + "\\mathrm { ";
|
| 128 |
+
|
| 129 |
+
buildExpression(group.value.body, options);
|
| 130 |
+
norm_str = norm_str + "} ";
|
| 131 |
+
};
|
| 132 |
+
|
| 133 |
+
groupTypes.color = function(group, options) {
|
| 134 |
+
var inner = buildExpression(group.value.value, options);
|
| 135 |
+
|
| 136 |
+
var node = new mathMLTree.MathNode("mstyle", inner);
|
| 137 |
+
|
| 138 |
+
node.setAttribute("mathcolor", group.value.color);
|
| 139 |
+
|
| 140 |
+
return node;
|
| 141 |
+
};
|
| 142 |
+
|
| 143 |
+
groupTypes.supsub = function(group, options) {
|
| 144 |
+
buildGroup(group.value.base, options);
|
| 145 |
+
|
| 146 |
+
if (group.value.sub) {
|
| 147 |
+
norm_str = norm_str + "_ ";
|
| 148 |
+
if (group.value.sub.type != 'ordgroup') {
|
| 149 |
+
norm_str = norm_str + " { ";
|
| 150 |
+
buildGroup(group.value.sub, options);
|
| 151 |
+
norm_str = norm_str + "} ";
|
| 152 |
+
} else {
|
| 153 |
+
buildGroup(group.value.sub, options);
|
| 154 |
+
}
|
| 155 |
+
|
| 156 |
+
}
|
| 157 |
+
|
| 158 |
+
if (group.value.sup) {
|
| 159 |
+
norm_str = norm_str + "^ ";
|
| 160 |
+
if (group.value.sup.type != 'ordgroup') {
|
| 161 |
+
norm_str = norm_str + " { ";
|
| 162 |
+
buildGroup(group.value.sup, options);
|
| 163 |
+
norm_str = norm_str + "} ";
|
| 164 |
+
} else {
|
| 165 |
+
buildGroup(group.value.sup, options);
|
| 166 |
+
}
|
| 167 |
+
}
|
| 168 |
+
|
| 169 |
+
};
|
| 170 |
+
|
| 171 |
+
groupTypes.genfrac = function(group, options) {
|
| 172 |
+
if (!group.value.hasBarLine) {
|
| 173 |
+
norm_str = norm_str + "\\binom ";
|
| 174 |
+
} else {
|
| 175 |
+
norm_str = norm_str + "\\frac ";
|
| 176 |
+
}
|
| 177 |
+
buildGroup(group.value.numer, options);
|
| 178 |
+
buildGroup(group.value.denom, options);
|
| 179 |
+
|
| 180 |
+
};
|
| 181 |
+
|
| 182 |
+
groupTypes.array = function(group, options) {
|
| 183 |
+
norm_str = norm_str + "\\begin{" + group.value.style + "} ";
|
| 184 |
+
|
| 185 |
+
if (group.value.style == "array" || group.value.style == "tabular") {
|
| 186 |
+
norm_str = norm_str + "{ ";
|
| 187 |
+
if (group.value.cols) {
|
| 188 |
+
group.value.cols.map(function(start) {
|
| 189 |
+
if (start) {
|
| 190 |
+
if (start.type == "align") {
|
| 191 |
+
norm_str = norm_str + start.align + " ";
|
| 192 |
+
} else if (start.type == "separator") {
|
| 193 |
+
norm_str = norm_str + start.separator + " ";
|
| 194 |
+
}
|
| 195 |
+
}
|
| 196 |
+
});
|
| 197 |
+
} else {
|
| 198 |
+
group.value.body[0].map(function(start) {
|
| 199 |
+
norm_str = norm_str + "c ";
|
| 200 |
+
} );
|
| 201 |
+
}
|
| 202 |
+
norm_str = norm_str + "} ";
|
| 203 |
+
}
|
| 204 |
+
group.value.body.map(function(row) {
|
| 205 |
+
if (row.length > 1 || row[0].value.length > 0) {
|
| 206 |
+
if (row[0].value[0] && row[0].value[0].value == "\\hline") {
|
| 207 |
+
norm_str = norm_str + "\\hline ";
|
| 208 |
+
row[0].value = row[0].value.slice(1);
|
| 209 |
+
}
|
| 210 |
+
out = row.map(function(cell) {
|
| 211 |
+
buildGroup(cell, options);
|
| 212 |
+
norm_str = norm_str + "& ";
|
| 213 |
+
});
|
| 214 |
+
norm_str = norm_str.substring(0, norm_str.length-2) + "\\\\ ";
|
| 215 |
+
}
|
| 216 |
+
});
|
| 217 |
+
norm_str = norm_str + "\\end{" + group.value.style + "} ";
|
| 218 |
+
};
|
| 219 |
+
|
| 220 |
+
groupTypes.sqrt = function(group, options) {
|
| 221 |
+
var node;
|
| 222 |
+
if (group.value.index) {
|
| 223 |
+
norm_str = norm_str + "\\sqrt [ " + group.value.index + " ] ";
|
| 224 |
+
buildGroup(group.value.body, options);
|
| 225 |
+
} else {
|
| 226 |
+
norm_str = norm_str + "\\sqrt ";
|
| 227 |
+
buildGroup(group.value.body, options);
|
| 228 |
+
}
|
| 229 |
+
};
|
| 230 |
+
|
| 231 |
+
groupTypes.leftright = function(group, options) {
|
| 232 |
+
|
| 233 |
+
|
| 234 |
+
|
| 235 |
+
norm_str = norm_str + "\\left" + group.value.left + " ";
|
| 236 |
+
buildExpression(group.value.body, options);
|
| 237 |
+
norm_str = norm_str + "\\right" + group.value.right + " ";
|
| 238 |
+
};
|
| 239 |
+
|
| 240 |
+
groupTypes.accent = function(group, options) {
|
| 241 |
+
if (group.value.base.type != 'ordgroup') {
|
| 242 |
+
norm_str = norm_str + group.value.accent + " { ";
|
| 243 |
+
buildGroup(group.value.base, options);
|
| 244 |
+
norm_str = norm_str + "} ";
|
| 245 |
+
} else {
|
| 246 |
+
norm_str = norm_str + group.value.accent + " ";
|
| 247 |
+
buildGroup(group.value.base, options);
|
| 248 |
+
}
|
| 249 |
+
};
|
| 250 |
+
|
| 251 |
+
groupTypes.spacing = function(group) {
|
| 252 |
+
var node;
|
| 253 |
+
if (group.value == " ") {
|
| 254 |
+
norm_str = norm_str + "~ ";
|
| 255 |
+
} else {
|
| 256 |
+
norm_str = norm_str + group.value + " ";
|
| 257 |
+
}
|
| 258 |
+
return node;
|
| 259 |
+
};
|
| 260 |
+
|
| 261 |
+
groupTypes.op = function(group) {
|
| 262 |
+
var node;
|
| 263 |
+
|
| 264 |
+
// TODO(emily): handle big operators using the `largeop` attribute
|
| 265 |
+
|
| 266 |
+
|
| 267 |
+
if (group.value.symbol) {
|
| 268 |
+
// This is a symbol. Just add the symbol.
|
| 269 |
+
norm_str = norm_str + group.value.body + " ";
|
| 270 |
+
|
| 271 |
+
} else {
|
| 272 |
+
if (group.value.limits == false) {
|
| 273 |
+
norm_str = norm_str + "\\\operatorname { ";
|
| 274 |
+
} else {
|
| 275 |
+
norm_str = norm_str + "\\\operatorname* { ";
|
| 276 |
+
}
|
| 277 |
+
for (i = 1; i < group.value.body.length; ++i ) {
|
| 278 |
+
norm_str = norm_str + group.value.body[i] + " ";
|
| 279 |
+
}
|
| 280 |
+
norm_str = norm_str + "} ";
|
| 281 |
+
}
|
| 282 |
+
};
|
| 283 |
+
|
| 284 |
+
groupTypes.katex = function(group) {
|
| 285 |
+
var node = new mathMLTree.MathNode(
|
| 286 |
+
"mtext", [new mathMLTree.TextNode("KaTeX")]);
|
| 287 |
+
|
| 288 |
+
return node;
|
| 289 |
+
};
|
| 290 |
+
|
| 291 |
+
|
| 292 |
+
|
| 293 |
+
groupTypes.font = function(group, options) {
|
| 294 |
+
var font = group.value.font;
|
| 295 |
+
if (font == "mbox" || font == "hbox") {
|
| 296 |
+
font = "mathrm";
|
| 297 |
+
}
|
| 298 |
+
norm_str = norm_str + "\\" + font + " ";
|
| 299 |
+
buildGroup(group.value.body, options.withFont(font));
|
| 300 |
+
};
|
| 301 |
+
|
| 302 |
+
groupTypes.delimsizing = function(group) {
|
| 303 |
+
var children = [];
|
| 304 |
+
norm_str = norm_str + group.value.funcName + " " + group.value.value + " ";
|
| 305 |
+
};
|
| 306 |
+
|
| 307 |
+
groupTypes.styling = function(group, options) {
|
| 308 |
+
norm_str = norm_str + " " + group.value.original + " ";
|
| 309 |
+
buildExpression(group.value.value, options);
|
| 310 |
+
|
| 311 |
+
};
|
| 312 |
+
|
| 313 |
+
groupTypes.sizing = function(group, options) {
|
| 314 |
+
|
| 315 |
+
if (group.value.original == "\\rm") {
|
| 316 |
+
norm_str = norm_str + "\\mathrm { ";
|
| 317 |
+
buildExpression(group.value.value, options.withFont("mathrm"));
|
| 318 |
+
norm_str = norm_str + "} ";
|
| 319 |
+
} else {
|
| 320 |
+
norm_str = norm_str + " " + group.value.original + " ";
|
| 321 |
+
buildExpression(group.value.value, options);
|
| 322 |
+
}
|
| 323 |
+
};
|
| 324 |
+
|
| 325 |
+
groupTypes.overline = function(group, options) {
|
| 326 |
+
norm_str = norm_str + "\\overline { ";
|
| 327 |
+
|
| 328 |
+
buildGroup(group.value.body, options);
|
| 329 |
+
norm_str = norm_str + "} ";
|
| 330 |
+
norm_str = norm_str;
|
| 331 |
+
|
| 332 |
+
};
|
| 333 |
+
|
| 334 |
+
groupTypes.underline = function(group, options) {
|
| 335 |
+
norm_str = norm_str + "\\underline { ";
|
| 336 |
+
buildGroup(group.value.body, options);
|
| 337 |
+
norm_str = norm_str + "} ";
|
| 338 |
+
|
| 339 |
+
norm_str = norm_str;
|
| 340 |
+
|
| 341 |
+
};
|
| 342 |
+
|
| 343 |
+
groupTypes.rule = function(group) {
|
| 344 |
+
norm_str = norm_str + "\\rule { "+group.value.width.number+" "+group.value.width.unit+" } { "+group.value.height.number+" "+group.value.height.unit+ " } ";
|
| 345 |
+
|
| 346 |
+
};
|
| 347 |
+
|
| 348 |
+
groupTypes.llap = function(group, options) {
|
| 349 |
+
norm_str = norm_str + "\\llap ";
|
| 350 |
+
buildGroup(group.value.body, options);
|
| 351 |
+
};
|
| 352 |
+
|
| 353 |
+
groupTypes.rlap = function(group, options) {
|
| 354 |
+
norm_str = norm_str + "\\rlap ";
|
| 355 |
+
buildGroup(group.value.body, options);
|
| 356 |
+
|
| 357 |
+
};
|
| 358 |
+
|
| 359 |
+
groupTypes.phantom = function(group, options, prev) {
|
| 360 |
+
norm_str = norm_str + "\\phantom { ";
|
| 361 |
+
buildExpression(group.value.value, options);
|
| 362 |
+
norm_str = norm_str + "} ";
|
| 363 |
+
|
| 364 |
+
};
|
| 365 |
+
|
| 366 |
+
/**
|
| 367 |
+
* Takes a list of nodes, builds them, and returns a list of the generated
|
| 368 |
+
* MathML nodes. A little simpler than the HTML version because we don't do any
|
| 369 |
+
* previous-node handling.
|
| 370 |
+
*/
|
| 371 |
+
var buildExpression = function(expression, options) {
|
| 372 |
+
var groups = [];
|
| 373 |
+
for (var i = 0; i < expression.length; i++) {
|
| 374 |
+
var group = expression[i];
|
| 375 |
+
buildGroup(group, options);
|
| 376 |
+
}
|
| 377 |
+
// console.log(norm_str);
|
| 378 |
+
// return groups;
|
| 379 |
+
};
|
| 380 |
+
|
| 381 |
+
/**
|
| 382 |
+
* Takes a group from the parser and calls the appropriate groupTypes function
|
| 383 |
+
* on it to produce a MathML node.
|
| 384 |
+
*/
|
| 385 |
+
var buildGroup = function(group, options) {
|
| 386 |
+
if (groupTypes[group.type]) {
|
| 387 |
+
groupTypes[group.type](group, options);
|
| 388 |
+
} else {
|
| 389 |
+
throw new ParseError(
|
| 390 |
+
"Got group of unknown type: '" + group.type + "'");
|
| 391 |
+
}
|
| 392 |
+
};
|
| 393 |
+
|
| 394 |
+
|
| 395 |
+
|