mirror of
https://github.com/Smaug123/KaTeX
synced 2025-10-06 19:58:40 +00:00
leqno and fleqn support (#1814)
* leqno support * Add fleqn support * Add tests * Lint fix * Add leqno and fleqn to website demo
This commit is contained in:
4
cli.js
4
cli.js
@@ -26,6 +26,10 @@ const program = require("commander")
|
|||||||
"Render math in display mode, which puts the math in display style " +
|
"Render math in display mode, which puts the math in display style " +
|
||||||
"(so \\int and \\sum are large, for example), and centers the math " +
|
"(so \\int and \\sum are large, for example), and centers the math " +
|
||||||
"on the page on its own line.")
|
"on the page on its own line.")
|
||||||
|
.option("--leqno",
|
||||||
|
"Render display math in leqno style (left-justified tags).")
|
||||||
|
.option("--fleqn",
|
||||||
|
"Render display math flush left.")
|
||||||
.option("-t, --no-throw-on-error",
|
.option("-t, --no-throw-on-error",
|
||||||
"Render errors (in the color given by --error-color) instead of " +
|
"Render errors (in the color given by --error-color) instead of " +
|
||||||
"throwing a ParseError exception when encountering an error.")
|
"throwing a ParseError exception when encountering an error.")
|
||||||
|
@@ -5,6 +5,8 @@ title: Options
|
|||||||
You can provide an object of options as the last argument to [`katex.render` and `katex.renderToString`](api.md). Available options are:
|
You can provide an object of options as the last argument to [`katex.render` and `katex.renderToString`](api.md). Available options are:
|
||||||
|
|
||||||
- `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`)
|
- `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`)
|
||||||
|
- `leqno`: `boolean`. If `true`, display math has `\tag`s rendered on the left instead of the right, like `\usepackage[leqno]{amsmath}` in LaTeX.
|
||||||
|
- `fleqn`: `boolean`. If `true`, display math renders flush left, like `\documentclass[fleqn]` in LaTeX.
|
||||||
- `throwOnError`: `boolean`. If `true` (the default), KaTeX will throw a `ParseError` when it encounters an unsupported command or invalid LaTeX. If `false`, KaTeX will render unsupported commands as text, and render invalid LaTeX as its source code with hover text giving the error, in the color given by `errorColor`.
|
- `throwOnError`: `boolean`. If `true` (the default), KaTeX will throw a `ParseError` when it encounters an unsupported command or invalid LaTeX. If `false`, KaTeX will render unsupported commands as text, and render invalid LaTeX as its source code with hover text giving the error, in the color given by `errorColor`.
|
||||||
- `errorColor`: `string`. A color string given in the format `"#XXX"` or `"#XXXXXX"`. This option determines the color that unsupported commands and invalid LaTeX are rendered in when `throwOnError` is set to `false`. (default: `#cc0000`)
|
- `errorColor`: `string`. A color string given in the format `"#XXX"` or `"#XXXXXX"`. This option determines the color that unsupported commands and invalid LaTeX are rendered in when `throwOnError` is set to `false`. (default: `#cc0000`)
|
||||||
- `macros`: `object`. A collection of custom macros. Each macro is a property with a name like `\name` (written `"\\name"` in JavaScript) which maps to a string that describes the expansion of the macro, or a function that accepts an instance of `MacroExpander` as first argument and returns the expansion as a string. `MacroExpander` is an internal API and subject to non-backwards compatible changes. See [`src/macros.js`](https://github.com/KaTeX/KaTeX/blob/master/src/macros.js) for its usage. Single-character keys can also be included in which case the character will be redefined as the given macro (similar to TeX active characters). *This object will be modified* if the LaTeX code defines its own macros via `\gdef`, which enables consecutive calls to KaTeX to share state.
|
- `macros`: `object`. A collection of custom macros. Each macro is a property with a name like `\name` (written `"\\name"` in JavaScript) which maps to a string that describes the expansion of the macro, or a function that accepts an instance of `MacroExpander` as first argument and returns the expansion as a string. `MacroExpander` is an internal API and subject to non-backwards compatible changes. See [`src/macros.js`](https://github.com/KaTeX/KaTeX/blob/master/src/macros.js) for its usage. Single-character keys can also be included in which case the character will be redefined as the given macro (similar to TeX active characters). *This object will be modified* if the LaTeX code defines its own macros via `\gdef`, which enables consecutive calls to KaTeX to share state.
|
||||||
|
@@ -18,6 +18,8 @@ export type StrictFunction =
|
|||||||
|
|
||||||
export type SettingsOptions = {
|
export type SettingsOptions = {
|
||||||
displayMode?: boolean;
|
displayMode?: boolean;
|
||||||
|
leqno?: boolean;
|
||||||
|
fleqn?: boolean;
|
||||||
throwOnError?: boolean;
|
throwOnError?: boolean;
|
||||||
errorColor?: string;
|
errorColor?: string;
|
||||||
macros?: MacroMap;
|
macros?: MacroMap;
|
||||||
@@ -40,6 +42,8 @@ export type SettingsOptions = {
|
|||||||
*/
|
*/
|
||||||
class Settings {
|
class Settings {
|
||||||
displayMode: boolean;
|
displayMode: boolean;
|
||||||
|
leqno: boolean;
|
||||||
|
fleqn: boolean;
|
||||||
throwOnError: boolean;
|
throwOnError: boolean;
|
||||||
errorColor: string;
|
errorColor: string;
|
||||||
macros: MacroMap;
|
macros: MacroMap;
|
||||||
@@ -53,6 +57,8 @@ class Settings {
|
|||||||
// allow null options
|
// allow null options
|
||||||
options = options || {};
|
options = options || {};
|
||||||
this.displayMode = utils.deflt(options.displayMode, false);
|
this.displayMode = utils.deflt(options.displayMode, false);
|
||||||
|
this.leqno = utils.deflt(options.leqno, false);
|
||||||
|
this.fleqn = utils.deflt(options.fleqn, false);
|
||||||
this.throwOnError = utils.deflt(options.throwOnError, true);
|
this.throwOnError = utils.deflt(options.throwOnError, true);
|
||||||
this.errorColor = utils.deflt(options.errorColor, "#cc0000");
|
this.errorColor = utils.deflt(options.errorColor, "#cc0000");
|
||||||
this.macros = options.macros || {};
|
this.macros = options.macros || {};
|
||||||
|
@@ -16,6 +16,20 @@ const optionsFromSettings = function(settings: Settings) {
|
|||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
|
const displayWrap = function(node: DomSpan, settings: Settings): DomSpan {
|
||||||
|
if (settings.displayMode) {
|
||||||
|
const classes = ["katex-display"];
|
||||||
|
if (settings.leqno) {
|
||||||
|
classes.push("leqno");
|
||||||
|
}
|
||||||
|
if (settings.fleqn) {
|
||||||
|
classes.push("fleqn");
|
||||||
|
}
|
||||||
|
node = buildCommon.makeSpan(classes, [node]);
|
||||||
|
}
|
||||||
|
return node;
|
||||||
|
};
|
||||||
|
|
||||||
export const buildTree = function(
|
export const buildTree = function(
|
||||||
tree: AnyParseNode[],
|
tree: AnyParseNode[],
|
||||||
expression: string,
|
expression: string,
|
||||||
@@ -29,11 +43,7 @@ export const buildTree = function(
|
|||||||
mathMLNode, htmlNode,
|
mathMLNode, htmlNode,
|
||||||
]);
|
]);
|
||||||
|
|
||||||
if (settings.displayMode) {
|
return displayWrap(katexNode, settings);
|
||||||
return buildCommon.makeSpan(["katex-display"], [katexNode]);
|
|
||||||
} else {
|
|
||||||
return katexNode;
|
|
||||||
}
|
|
||||||
};
|
};
|
||||||
|
|
||||||
export const buildHTMLTree = function(
|
export const buildHTMLTree = function(
|
||||||
@@ -44,11 +54,7 @@ export const buildHTMLTree = function(
|
|||||||
const options = optionsFromSettings(settings);
|
const options = optionsFromSettings(settings);
|
||||||
const htmlNode = buildHTML(tree, options);
|
const htmlNode = buildHTML(tree, options);
|
||||||
const katexNode = buildCommon.makeSpan(["katex"], [htmlNode]);
|
const katexNode = buildCommon.makeSpan(["katex"], [htmlNode]);
|
||||||
if (settings.displayMode) {
|
return displayWrap(katexNode, settings);
|
||||||
return buildCommon.makeSpan(["katex-display"], [katexNode]);
|
|
||||||
} else {
|
|
||||||
return katexNode;
|
|
||||||
}
|
|
||||||
};
|
};
|
||||||
|
|
||||||
export default buildTree;
|
export default buildTree;
|
||||||
|
@@ -588,3 +588,14 @@
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Left-justified tags (default is right-justified)
|
||||||
|
.katex-display.leqno > .katex > .katex-html > .tag {
|
||||||
|
left: 0;
|
||||||
|
right: auto;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Flush-left display math
|
||||||
|
.katex-display.fleqn > .katex {
|
||||||
|
text-align: left;
|
||||||
|
}
|
||||||
|
@@ -29,6 +29,16 @@ function init() {
|
|||||||
options.displayMode = false;
|
options.displayMode = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Use `leqno=1` (or `=t`/`=true`/`=y`/`=yes`) to put tags on left side.
|
||||||
|
if (query.leqno && query.leqno.match(/^(1|t|y)/)) {
|
||||||
|
options.leqno = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Use `fleqn=1` (or `=t`/`=true`/`=y`/`=yes`) to put tags on left side.
|
||||||
|
if (query.fleqn && query.fleqn.match(/^(1|t|y)/)) {
|
||||||
|
options.fleqn = true;
|
||||||
|
}
|
||||||
|
|
||||||
// Use `strict=warn` for warning strict mode or `strict=error`
|
// Use `strict=warn` for warning strict mode or `strict=error`
|
||||||
// (or `=1`/`=t`/`=true`/`=y`/`=yes`)
|
// (or `=1`/`=t`/`=true`/`=y`/`=yes`)
|
||||||
// to turn off displayMode (which is on by default).
|
// to turn off displayMode (which is on by default).
|
||||||
|
@@ -3174,6 +3174,29 @@ describe("\\tag support", function() {
|
|||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
|
describe("leqno and fleqn rendering options", () => {
|
||||||
|
const expr = r`\tag{hi}x+y`;
|
||||||
|
for (const opt of ["leqno", "fleqn"]) {
|
||||||
|
it(`should not add ${opt} class by default`, () => {
|
||||||
|
const settings = new Settings({displayMode: true});
|
||||||
|
const built = katex.__renderToDomTree(expr, settings);
|
||||||
|
expect(built.classes).not.toContain(opt);
|
||||||
|
});
|
||||||
|
it(`should not add ${opt} class when false`, () => {
|
||||||
|
const settings = new Settings({displayMode: true});
|
||||||
|
settings[opt] = false;
|
||||||
|
const built = katex.__renderToDomTree(expr, settings);
|
||||||
|
expect(built.classes).not.toContain(opt);
|
||||||
|
});
|
||||||
|
it(`should add ${opt} class when true`, () => {
|
||||||
|
const settings = new Settings({displayMode: true});
|
||||||
|
settings[opt] = true;
|
||||||
|
const built = katex.__renderToDomTree(expr, settings);
|
||||||
|
expect(built.classes).toContain(opt);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
describe("\\@binrel automatic bin/rel/ord", () => {
|
describe("\\@binrel automatic bin/rel/ord", () => {
|
||||||
it("should generate proper class", () => {
|
it("should generate proper class", () => {
|
||||||
expect("L\\@binrel+xR").toParseLike("L\\mathbin xR");
|
expect("L\\@binrel+xR").toParseLike("L\\mathbin xR");
|
||||||
|
@@ -131,6 +131,14 @@
|
|||||||
<td><label for="displayMode">displayMode</label></td>
|
<td><label for="displayMode">displayMode</label></td>
|
||||||
<td><input type="checkbox" id="displayMode" checked/></td>
|
<td><input type="checkbox" id="displayMode" checked/></td>
|
||||||
</tr>
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td><label for="leqno">leqno</label></td>
|
||||||
|
<td><input type="checkbox" id="leqno"/></td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td><label for="fleqn">fleqn</label></td>
|
||||||
|
<td><input type="checkbox" id="fleqn"/></td>
|
||||||
|
</tr>
|
||||||
<tr>
|
<tr>
|
||||||
<td><label for="throwOnError">throwOnError</label></td>
|
<td><label for="throwOnError">throwOnError</label></td>
|
||||||
<td><input type="checkbox" id="throwOnError" checked/></td>
|
<td><input type="checkbox" id="throwOnError" checked/></td>
|
||||||
|
@@ -36,8 +36,8 @@
|
|||||||
demoInput.value = data.code;
|
demoInput.value = data.code;
|
||||||
}
|
}
|
||||||
|
|
||||||
var katexOptions = ["displayMode", "throwOnError", "errorColor", "strict",
|
var katexOptions = ["displayMode", "leqno", "fleqn", "throwOnError",
|
||||||
"macros"].map(function(id) {
|
"errorColor", "strict", "macros"].map(function(id) {
|
||||||
var el = document.getElementById(id);
|
var el = document.getElementById(id);
|
||||||
if (el.type === "checkbox") {
|
if (el.type === "checkbox") {
|
||||||
if (typeof data[id] === "boolean") {
|
if (typeof data[id] === "boolean") {
|
||||||
|
Reference in New Issue
Block a user