More plugins and better config

- fixed puppeteer bug where MathJax message containers appeared
- added plugins
- added `extends` to `mdconfig.json` to extend a default config
- added option to show all plugins `--plugins`
develop
Trivernis 5 years ago
parent 21fd8356c3
commit ee316c6c24

@ -15,3 +15,4 @@
- auto base64 converting for images for a standalone html when bundling flag is set - auto base64 converting for images for a standalone html when bundling flag is set
- support for `mdconf.json`config file - support for `mdconf.json`config file
- MathJax script to html - MathJax script to html
- `mdconfig.json` extensions with `extends: "name"`

@ -39,26 +39,7 @@ or
[!use]: # (plugin1, plugin2, plugin3) [!use]: # (plugin1, plugin2, plugin3)
``` ```
The plugin names are listed in the following table. Basically it is just the package name with the markdown-it removed: The plugin names are listed in the following table. Basically it is just the package name with the markdown-it removed. See [Plugins](#plugins)
| module | import name |
|----------------------|-------------|
| markdown-it-footnote | footnote
| markdown-it-anchor | anchor
| markdown-it-mark | mark
| markdown-it-sub | sub
| markdown-it-attrs | attrs
| markdown-it-abbr | abbr
| markdown-it-checkbox | checkbox
| markdown-it-imsize | imsize
| markdown-it-highlightjs | highlightjs
| markdown-it-toc-done-right | toc-done-right
| markdown-it-smartarrows | smartarrows
| markdown-it-plantuml | plantuml
| markdown-it-mathjax | mathjax
| markdown-it-math | math
| markdown-it-div | div
| markdown-it-multimd-table | multimd-table
For example you can declare the use of `markdown-it-emoji` the following: For example you can declare the use of `markdown-it-emoji` the following:
@ -97,8 +78,9 @@ You can include your own stylesheet. It is applied after the default style. The
You can also define plugins, stylesheets and other stuff by using a `mdconf.json` file in the same directory as the main markdown file. Example config: You can also define plugins, stylesheets and other stuff by using a `mdconf.json` file in the same directory as the main markdown file. Example config:
```json ```json5
{ { // everything is optional
"extends": "full", // extend from predefined configurations
"format": "A4", "format": "A4",
"plugins": [ "plugins": [
"emoji", "emoji",
@ -111,6 +93,36 @@ You can also define plugins, stylesheets and other stuff by using a `mdconf.json
} }
``` ```
## Other stuff ### Predefined configurations
Images and stylesheets are included within the html file. All image urls are converted into base64 urls. config | type
-------|-----
full | includes all plugins
## Plugins
Plugin Name | Markdown-it plugin
-----------------|---------------------
emoji | markdown-it-emoji
footnote | markdown-it-footnote
anchor | markdown-it-anchor
mark | markdown-it-mark
sub | markdown-it-sub
attrs | markdown-it-attrs
abbr | markdown-it-abbr
checkbox | markdown-it-checkbox
imsize | markdown-it-imsize
highlightjs | markdown-it-highlightjs
smartarrows | markdown-it-smartarrows
plantuml | markdown-it-plantuml
math | markdown-it-math
div | markdown-it-div
kbd | markdown-it-kbd
video | markdown-it-video
underline | markdown-it-underline
multimd-table | markdown-it-multimd-table
toc-done-right | markdown-it-toc-done-right
center-text | markdown-it-center-text
header-sections | markdown-it-header-sections
task-checkbox | markdown-it-task-checkbox
implicit-figures | markdown-it-implicit-figures

@ -22,10 +22,17 @@ function compileSass() {
.pipe(dest('dist/styles')); .pipe(dest('dist/styles'));
} }
task('cleanBuild', series(clearDist, compileTypescript, compileSass)); function moveOther() {
task('default', series(compileTypescript, compileSass)); return src(['src/**/*', '!src/**/*.ts', '!src/**/*.sass'])
.pipe(dest('dist'));
}
task('cleanBuild', series(clearDist, compileTypescript, compileSass, moveOther));
task('default', series(compileTypescript, compileSass, moveOther));
task('watch', () => { task('watch', () => {
series(compileSass, compileTypescript); series(compileSass, compileTypescript, moveOther);
watch('src/**/*.sass', series(compileSass)); watch('src/**/*.sass', series(compileSass));
watch('**/*.ts', compileTypescript); watch('**/*.ts', compileTypescript);
watch(['src/**/*', '!src/**/*.ts', '!src/**/*.sass'], moveOther);
}); });

35
package-lock.json generated

@ -3396,6 +3396,11 @@
"resolved": "https://registry.npmjs.org/markdown-it-attrs/-/markdown-it-attrs-2.4.1.tgz", "resolved": "https://registry.npmjs.org/markdown-it-attrs/-/markdown-it-attrs-2.4.1.tgz",
"integrity": "sha512-BASnIYS+JLpjlhDf7jLV8VOuccxjfDDnQcz5dLfgPsYw8OsgbASexADdIkF7tIdGn+jaQSA4qOZXM3v3W3JBCg==" "integrity": "sha512-BASnIYS+JLpjlhDf7jLV8VOuccxjfDDnQcz5dLfgPsYw8OsgbASexADdIkF7tIdGn+jaQSA4qOZXM3v3W3JBCg=="
}, },
"markdown-it-center-text": {
"version": "1.0.4",
"resolved": "https://registry.npmjs.org/markdown-it-center-text/-/markdown-it-center-text-1.0.4.tgz",
"integrity": "sha512-7AA0gek4FYJ6gWB2kdGNx06k3GrlO97nEMY7uovQ70/6MtfqPznrgnKoWO3V4p36m3RT5GeQIFXqBH9Wr4iL/g=="
},
"markdown-it-checkbox": { "markdown-it-checkbox": {
"version": "1.1.0", "version": "1.1.0",
"resolved": "https://registry.npmjs.org/markdown-it-checkbox/-/markdown-it-checkbox-1.1.0.tgz", "resolved": "https://registry.npmjs.org/markdown-it-checkbox/-/markdown-it-checkbox-1.1.0.tgz",
@ -3419,6 +3424,11 @@
"resolved": "https://registry.npmjs.org/markdown-it-footnote/-/markdown-it-footnote-3.0.2.tgz", "resolved": "https://registry.npmjs.org/markdown-it-footnote/-/markdown-it-footnote-3.0.2.tgz",
"integrity": "sha512-JVW6fCmZWjvMdDQSbOT3nnOQtd9iAXmw7hTSh26+v42BnvXeVyGMDBm5b/EZocMed2MbCAHiTX632vY0FyGB8A==" "integrity": "sha512-JVW6fCmZWjvMdDQSbOT3nnOQtd9iAXmw7hTSh26+v42BnvXeVyGMDBm5b/EZocMed2MbCAHiTX632vY0FyGB8A=="
}, },
"markdown-it-header-sections": {
"version": "1.0.0",
"resolved": "https://registry.npmjs.org/markdown-it-header-sections/-/markdown-it-header-sections-1.0.0.tgz",
"integrity": "sha512-GndZbs+iTo7NkNRf00VmT4mtFql7VoJNnSwB7hP5xkomGUTdQ78siVZIuRco4fbiWJd45JUemLxUS9vO8luPSA=="
},
"markdown-it-highlightjs": { "markdown-it-highlightjs": {
"version": "3.0.0", "version": "3.0.0",
"resolved": "https://registry.npmjs.org/markdown-it-highlightjs/-/markdown-it-highlightjs-3.0.0.tgz", "resolved": "https://registry.npmjs.org/markdown-it-highlightjs/-/markdown-it-highlightjs-3.0.0.tgz",
@ -3428,6 +3438,11 @@
"lodash.flow": "^3.1.0" "lodash.flow": "^3.1.0"
} }
}, },
"markdown-it-implicit-figures": {
"version": "0.9.0",
"resolved": "https://registry.npmjs.org/markdown-it-implicit-figures/-/markdown-it-implicit-figures-0.9.0.tgz",
"integrity": "sha512-ykLQZmhy8QnNEm6NgImIrr+/QMe7gSnHgLhNAjz9GGCNdSLR7C/SLFNwGdUZq7vK3a0myWiOYE0tpaZuB0rWWw=="
},
"markdown-it-imsize": { "markdown-it-imsize": {
"version": "2.0.1", "version": "2.0.1",
"resolved": "https://registry.npmjs.org/markdown-it-imsize/-/markdown-it-imsize-2.0.1.tgz", "resolved": "https://registry.npmjs.org/markdown-it-imsize/-/markdown-it-imsize-2.0.1.tgz",
@ -3438,6 +3453,11 @@
"resolved": "https://registry.npmjs.org/markdown-it-ins/-/markdown-it-ins-2.0.0.tgz", "resolved": "https://registry.npmjs.org/markdown-it-ins/-/markdown-it-ins-2.0.0.tgz",
"integrity": "sha1-papqMPHi9x6Ul1Z8/f9A8f3mdIM=" "integrity": "sha1-papqMPHi9x6Ul1Z8/f9A8f3mdIM="
}, },
"markdown-it-kbd": {
"version": "2.0.0",
"resolved": "https://registry.npmjs.org/markdown-it-kbd/-/markdown-it-kbd-2.0.0.tgz",
"integrity": "sha512-wMEFAF6WIcitSLt2uGuqXjOB6EfmpML7FN6KI8WdhI2A5l1SsgtmaFPR1ss7BjIqUrtjSk4tNhSl0azt3quwEA=="
},
"markdown-it-mark": { "markdown-it-mark": {
"version": "2.0.0", "version": "2.0.0",
"resolved": "https://registry.npmjs.org/markdown-it-mark/-/markdown-it-mark-2.0.0.tgz", "resolved": "https://registry.npmjs.org/markdown-it-mark/-/markdown-it-mark-2.0.0.tgz",
@ -3493,11 +3513,26 @@
"resolved": "https://registry.npmjs.org/markdown-it-sub/-/markdown-it-sub-1.0.0.tgz", "resolved": "https://registry.npmjs.org/markdown-it-sub/-/markdown-it-sub-1.0.0.tgz",
"integrity": "sha1-N1/WAm6ufdywEkl/ZBEZXqHjr+g=" "integrity": "sha1-N1/WAm6ufdywEkl/ZBEZXqHjr+g="
}, },
"markdown-it-task-checkbox": {
"version": "1.0.6",
"resolved": "https://registry.npmjs.org/markdown-it-task-checkbox/-/markdown-it-task-checkbox-1.0.6.tgz",
"integrity": "sha512-7pxkHuvqTOu3iwVGmDPeYjQg+AIS9VQxzyLP9JCg9lBjgPAJXGEkChK6A2iFuj3tS0GV3HG2u5AMNhcQqwxpJw=="
},
"markdown-it-toc-done-right": { "markdown-it-toc-done-right": {
"version": "4.0.2", "version": "4.0.2",
"resolved": "https://registry.npmjs.org/markdown-it-toc-done-right/-/markdown-it-toc-done-right-4.0.2.tgz", "resolved": "https://registry.npmjs.org/markdown-it-toc-done-right/-/markdown-it-toc-done-right-4.0.2.tgz",
"integrity": "sha512-LIdwU8coEdBa6JxhMmcst5Qc9/ptVDmUB6dJuJzlxaV75Dry+AziKpQRgZ42SMQ5m7hpb7z6b0erIRoYk+bMWA==" "integrity": "sha512-LIdwU8coEdBa6JxhMmcst5Qc9/ptVDmUB6dJuJzlxaV75Dry+AziKpQRgZ42SMQ5m7hpb7z6b0erIRoYk+bMWA=="
}, },
"markdown-it-underline": {
"version": "1.0.1",
"resolved": "https://registry.npmjs.org/markdown-it-underline/-/markdown-it-underline-1.0.1.tgz",
"integrity": "sha1-Q6VKVB2V1zm0MVdwHx2jBtfDALI="
},
"markdown-it-video": {
"version": "0.6.3",
"resolved": "https://registry.npmjs.org/markdown-it-video/-/markdown-it-video-0.6.3.tgz",
"integrity": "sha512-T4th1kwy0OcvyWSN4u3rqPGxvbDclpucnVSSaH3ZacbGsAts964dxokx9s/I3GYsrDCJs4ogtEeEeVP18DQj0Q=="
},
"matchdep": { "matchdep": {
"version": "2.0.0", "version": "2.0.0",
"resolved": "https://registry.npmjs.org/matchdep/-/matchdep-2.0.0.tgz", "resolved": "https://registry.npmjs.org/matchdep/-/matchdep-2.0.0.tgz",

@ -37,13 +37,17 @@
"markdown-it-abbr": "^1.0.4", "markdown-it-abbr": "^1.0.4",
"markdown-it-anchor": "^5.2.4", "markdown-it-anchor": "^5.2.4",
"markdown-it-attrs": "^2.4.1", "markdown-it-attrs": "^2.4.1",
"markdown-it-center-text": "^1.0.4",
"markdown-it-checkbox": "^1.1.0", "markdown-it-checkbox": "^1.1.0",
"markdown-it-div": "^1.1.0", "markdown-it-div": "^1.1.0",
"markdown-it-emoji": "^1.4.0", "markdown-it-emoji": "^1.4.0",
"markdown-it-footnote": "^3.0.2", "markdown-it-footnote": "^3.0.2",
"markdown-it-header-sections": "^1.0.0",
"markdown-it-highlightjs": "^3.0.0", "markdown-it-highlightjs": "^3.0.0",
"markdown-it-implicit-figures": "^0.9.0",
"markdown-it-imsize": "^2.0.1", "markdown-it-imsize": "^2.0.1",
"markdown-it-ins": "^2.0.0", "markdown-it-ins": "^2.0.0",
"markdown-it-kbd": "^2.0.0",
"markdown-it-mark": "^2.0.0", "markdown-it-mark": "^2.0.0",
"markdown-it-math": "^4.1.1", "markdown-it-math": "^4.1.1",
"markdown-it-mathjax": "^2.0.0", "markdown-it-mathjax": "^2.0.0",
@ -51,7 +55,10 @@
"markdown-it-plantuml": "^1.4.1", "markdown-it-plantuml": "^1.4.1",
"markdown-it-smartarrows": "^1.0.1", "markdown-it-smartarrows": "^1.0.1",
"markdown-it-sub": "^1.0.0", "markdown-it-sub": "^1.0.0",
"markdown-it-task-checkbox": "^1.0.6",
"markdown-it-toc-done-right": "^4.0.2", "markdown-it-toc-done-right": "^4.0.2",
"markdown-it-underline": "^1.0.1",
"markdown-it-video": "^0.6.3",
"node-fetch": "^2.6.0", "node-fetch": "^2.6.0",
"puppeteer": "^1.19.0", "puppeteer": "^1.19.0",
"uninstall": "0.0.0", "uninstall": "0.0.0",

@ -0,0 +1,27 @@
{
"plugins": [
"emoji",
"footnote",
"anchor",
"mark",
"sub",
"attrs",
"abbr",
"checkbox",
"imsize",
"highlightjs",
"smartarrows",
"plantuml",
"math",
"div",
"multimd-table",
"toc-done-right",
"kbd",
"center-text",
"video",
"header-sections",
"task-checkbox",
"underline",
"implicit-figures"
]
}

@ -4,6 +4,7 @@ import {extname, dirname} from 'path';
import {ArgumentParser} from "argparse"; import {ArgumentParser} from "argparse";
import {MarkdownConfig} from "./lib/MarkdownConfig"; import {MarkdownConfig} from "./lib/MarkdownConfig";
import {logger} from "./lib/logger"; import {logger} from "./lib/logger";
import {markdownPlugins} from "./lib/plugins";
/** /**
* Returns the filename without the extension. * Returns the filename without the extension.
@ -14,12 +15,13 @@ function noExt(file: string): string {
} }
async function main() { async function main() {
logger.profile('processing'); let start = process.hrtime();
const parser = new ArgumentParser({ const parser = new ArgumentParser({
addHelp: true addHelp: true
}); });
parser.addArgument('file',{ parser.addArgument('file',{
help: 'The file to render' help: 'The file to render',
required: false
}); });
parser.addArgument( parser.addArgument(
['-w', '--watch'], ['-w', '--watch'],
@ -45,7 +47,24 @@ async function main() {
action: 'storeTrue' action: 'storeTrue'
} }
); );
parser.addArgument(
['--plugins'],
{
help: 'prints out the plugins, that can be used.',
required: false,
action: 'storeTrue'
}
);
let args = parser.parseArgs(); let args = parser.parseArgs();
if (args.plugins) {
console.log('Plugin Name | Markdown-it plugin');
console.log('-----------------|---------------------');
console.log(Object.entries(markdownPlugins).map((x:any) => x[0]
.padEnd(16, ' ') + ' | ' + x[1].module).join('\n'));
process.exit(0);
}
let config = new MarkdownConfig(dirname(args.file)); let config = new MarkdownConfig(dirname(args.file));
config.bundle = args.bundle || args.pdf; config.bundle = args.bundle || args.pdf;
let renderer = new Renderer(config); let renderer = new Renderer(config);
@ -72,7 +91,8 @@ async function main() {
await writeFile(outputFile, html); await writeFile(outputFile, html);
console.log(`File stored as ${outputFile}`); console.log(`File stored as ${outputFile}`);
} }
logger.profile('processing'); let diff = process.hrtime(start);
logger.info(`Total: ${(diff[0]*1e9 + diff[1])/1e6} ms`);
} }
4 4
main(); main();

@ -1,8 +1,17 @@
import * as fsx from 'fs-extra'; import * as fsx from 'fs-extra';
import * as path from 'path'; import * as path from 'path';
import {getMarkdownPlugin} from "./utils"; import {getMarkdownPlugin} from "./utils";
import {logger} from "./logger";
const confName = 'mdconfig.json'; const confName = 'mdconfig.json';
const confDir = `${__dirname}../../configs`;
/**
* Configs that can be extended
*/
const configs: any = {
"full": `${confDir}/full-${confName}`
};
/** /**
* Markdown config class for easyer access on the configuration. * Markdown config class for easyer access on the configuration.
@ -33,6 +42,11 @@ export class MarkdownConfig {
*/ */
private loadData() { private loadData() {
let configData = fsx.readJsonSync(this.filename); let configData = fsx.readJsonSync(this.filename);
if (configData.extends && configs[configData.extends]) { // assign the base config to the config data
logger.info(`Extending config with ${configData.extends}`);
Object.assign(configData, fsx.readJsonSync(configs[configData.extends]));
}
this.format = configData.format || this.format; this.format = configData.format || this.format;
this.bundle = configData.bundle; this.bundle = configData.bundle;
if (configData.plugins) if (configData.plugins)
@ -48,5 +62,6 @@ export class MarkdownConfig {
public save(filename?: string) { public save(filename?: string) {
let confFile = filename || this.filename; let confFile = filename || this.filename;
fsx.writeJsonSync(confFile, this); fsx.writeJsonSync(confFile, this);
logger.info(`Config file saved as ${filename}.`);
} }
} }

@ -77,17 +77,26 @@ export class Renderer extends EventEmitter {
let document = await fsx.readFile(filename, 'utf-8'); let document = await fsx.readFile(filename, 'utf-8');
document = document.replace(/\r\n/g, '\n'); document = document.replace(/\r\n/g, '\n');
logger.verbose(`Applying ${this.beforeRendering.length} beforeRendering functions...`); logger.verbose(`Applying ${this.beforeRendering.length} beforeRendering functions...`);
let start: any = process.hrtime();
for (let func of this.beforeRendering) { for (let func of this.beforeRendering) {
document = await func(document, filename, this); document = await func(document, filename, this);
} }
let diff: any = process.hrtime(start);
logger.info(`Pre-Rendering: ${(diff[0]*1e9 + diff[1])/1e6} ms`);
this.addConfigPlugins(); this.addConfigPlugins();
logger.verbose(`Rendering with markdown-it and ${this.config.plugins.size} plugins`); start = process.hrtime();
let result: string = this.md.render(document); let result: string = this.md.render(document);
diff = process.hrtime(start);
logger.info(`Rendering: ${(diff[0]*1e9 + diff[1])/1e6} ms`);
start = process.hrtime();
logger.verbose(`Applying ${this.afterRendering.length} afterRendering functions...`);
for (let func of this.afterRendering) { for (let func of this.afterRendering) {
result = await func(result, filename, this); result = await func(result, filename, this);
} }
diff = process.hrtime(start);
logger.info(`Post-Rendering: ${(diff[0]*1e9 + diff[1])/1e6} ms`);
logger.verbose('HTML rendered'); logger.verbose('HTML rendered');
this.emit('rendered', result); this.emit('rendered', result);
return result; return result;
@ -108,8 +117,8 @@ export class Renderer extends EventEmitter {
const page = await browser.newPage(); const page = await browser.newPage();
logger.info('Setting and evaluating content'); logger.info('Setting and evaluating content');
await page.setContent(html); await page.setContent(html);
await page.waitForFunction('window.MathJax.isReady === true'); await page.waitForFunction('window.MathJax.isReady');
await delay(1000); await page.waitForFunction('!!document.querySelector("#MathJax_Message").style.display');
logger.info(`Starting PDF export (format: ${format}) to ${output}`); logger.info(`Starting PDF export (format: ${format}) to ${output}`);
await page.pdf({ await page.pdf({
path: output, path: output,
@ -194,7 +203,7 @@ export class Renderer extends EventEmitter {
private addConfigPlugins() { private addConfigPlugins() {
for (let plugin of this.config.plugins) { for (let plugin of this.config.plugins) {
try { try {
this.md.use(plugin); this.md.use(plugin.module, plugin.options);
} catch (err) { } catch (err) {
logger.error(err); logger.error(err);
} }

@ -1,18 +1,74 @@
export const markdownPlugins: any = { export const markdownPlugins: any = {
emoji: 'markdown-it-emoji', emoji: {
footnote: 'markdown-it-footnote', module: 'markdown-it-emoji'
anchor: 'markdown-it-anchor', },
mark: 'markdown-it-mark', footnote: {
sub: 'markdown-it-sub', module: 'markdown-it-footnote'
attrs: 'markdown-it-attrs', },
abbr: 'markdown-it-abbr', anchor: {
checkbox: 'markdown-it-checkbox', module: 'markdown-it-anchor'
imsize: 'markdown-it-imsize', },
highlightjs: 'markdown-it-highlightjs', mark: {
smartarrows: 'markdown-it-smartarrows', module: 'markdown-it-mark'
plantuml: 'markdown-it-plantuml', },
mathjax: 'markdown-it-mathjax', sub: {
math: 'markdown-it-math', module: 'markdown-it-sub'
div: 'markdown-it-div', },
'toc-done-right': 'markdown-it-toc-done-right' attrs: {
module: 'markdown-it-attrs'
},
abbr: {
module: 'markdown-it-abbr'
},
checkbox: {
module: 'markdown-it-checkbox'
},
imsize: {
module: 'markdown-it-imsize'
},
highlightjs: {
module: 'markdown-it-highlightjs'
},
smartarrows: {
module: 'markdown-it-smartarrows'
},
plantuml: {
module: 'markdown-it-plantuml'
},
math: {
module: 'markdown-it-math'
},
div: {
module: 'markdown-it-div'
},
kbd: {
module: 'markdown-it-kbd'
},
video: {
module: 'markdown-it-video'
},
underline: {
module: 'markdown-it-underline'
},
'multimd-table': {
module: 'markdown-it-multimd-table'
},
'toc-done-right': {
module: 'markdown-it-toc-done-right'
},
'center-text': {
module: 'markdown-it-center-text'
},
'header-sections': {
module: 'markdown-it-header-sections'
},
'task-checkbox': {
module: 'markdown-it-task-checkbox'
},
'implicit-figures': {
module: 'markdown-it-implicit-figures',
options: {
figcaption: true
}
}
}; };

@ -55,19 +55,32 @@ export function includeMathJax(dom: JSDOM): JSDOM {
/** /**
* Returns the markdown plugin associated with the pluginName * Returns the markdown plugin associated with the pluginName
* The plugin is first searched in the plugins definition.
* Then it is tried to require the plugin.
* @param pluginName * @param pluginName
*/ */
export function getMarkdownPlugin(pluginName: string) { export function getMarkdownPlugin(pluginName: any) {
logger.debug(`Trying to resolve plugin ${pluginName}`); logger.debug(`Trying to resolve plugin ${pluginName}`);
if (markdownPlugins[pluginName]) { if (markdownPlugins[pluginName]) {
return require(markdownPlugins[pluginName]); if (markdownPlugins[pluginName].module.constructor.name === 'String')
markdownPlugins[pluginName].module = require(markdownPlugins[pluginName].module);
return markdownPlugins[pluginName];
} else { } else {
try { try {
if (pluginName.module) {
if (pluginName.module.constructor.name === 'String')
pluginName.module = require(pluginName.module);
return pluginName
} else {
let plugin = require(pluginName); let plugin = require(pluginName);
if (plugin) if (plugin)
return plugin; return {
module: plugin
};
}
} catch (err) { } catch (err) {
console.error(`Module ${pluginName} not found.`); console.error(`Module ${JSON.stringify(pluginName)} not found.`);
console.debug(err);
} }
} }
} }

@ -1,5 +1,4 @@
@import includes/vars @import includes/vars
//@import includes/w3-math
@import includes/highlighjs @import includes/highlighjs
body body
@ -24,6 +23,19 @@ img
max-width: 100% max-width: 100%
height: auto height: auto
hr
border: 0.1em solid $inactive
kbd
border: 1px solid $inactive
padding: 0.1em
background-color: $backgroundSecondary
box-shadow: 0 0.1em 0.1em $inactive
figcaption
margin: 0.5em
font-style: italic
.page .page
page-break-before: always page-break-before: always
page-break-after: always page-break-after: always
@ -31,3 +43,6 @@ img
.newpage .newpage
page-break-after: always page-break-after: always
.text-align-center
text-align: center

@ -1 +1,2 @@
$backgroundSecondary: #eee $backgroundSecondary: #eee
$inactive: #444

@ -1,380 +0,0 @@
math
{line-height:1.3em;
text-indent:0;}
math[display="block"]
{display:block;
text-align:center;
page-break-inside:avoid;}
mfrac
{display:inline-table;
white-space:nowrap;
border-collapse:collapse;
text-align:center;
vertical-align:0.9em;
margin:0 2px;
font-size:1em;}
mfrac > *
{line-height:1.3em;
font-size:0.9em;}
mfrac > *:first-child
{display:inline-table;
vertical-align:text-bottom;}
mfrac > * + *
{border-top:solid thin;
display:table-row;}
mfrac[linethickness="0"] > * + *
{border-top:none;}
mfrac[linethickness="2"] > * + *, mfrac[linethickness="thick"] > * + *
{border-top:solid medium;}
mfrac[numalign="left"] > *:first-child, mfrac[denalign="left"] > * + *
{text-align:left;}
mfrac[numalign="right"] > *:first-child, mfrac[denalign="right"] > * + *
{text-align:right;}
msub, msup, msubsup, mmultiscripts
{display:inline-table;
line-height:0.4em;}
msubsup, msup, mmultiscripts
{margin-top:0.4ex;
table-baseline:2;}
msubsup, msub, mmultiscripts
{margin-bottom:0.4ex;}
msubsup, msup
{direction:rtl;}
msub > *
{display:table-row;}
none
{content:"\A0";}
msubsup > *, msup > *
{display:table-row;
direction:ltr;
text-align:left;}
mmultiscripts > *
{display:none;}
mmultiscripts > *:first-child, mmultiscripts > mprescripts + *
{display:table-row;}
mmultiscripts > mprescripts + * + *
{display:table-header-group;}
msub > *:first-child:after, msub > * + *:before,
msubsup > *:first-child:before, msup > *:first-child:before,
mmultiscripts > *:first-child:before
{display:table-cell;
content:"\A0";}
msubsup > * + * + *, msup > * + *
{display:table-header-group;}
msub > * + *, msup > * + *, msubsup > * + *, munder > * + *, mover > * + *, munderover > * + *,
mmultiscripts > * + *
{font-size:0.7em;}
munder, munderover, mover
{display:inline-table;
margin:1px;
text-align:center;}
munder > *, munderover > *, mover > *
{display:table-row;}
mover > * + *, munderover > * + * + *
{display:table-header-group;}
mover, munderover
{table-baseline:2;}
msqrt
{display:inline-block;
margin:1px 0 1px 22px;
border-top:solid 1px;
border-left:groove 2px;
padding:2px 5px 0 0;}
msqrt:before
{display:inline-block;
vertical-align:bottom;
content:'';
width:22px;
height:14px;
background-repeat:no-repeat;
margin:0 3px 0 -22px;}
msqrt:before, mroot > * + *:after
{background-image:url("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABYAAAAOCAYAAAArMezNAAAArklEQVR42mNgIAzkgJiRgYpAGIgnAfFvIF4JxKyUGsgOxKVA/ASI5wCxHRBvA+K9QMxHrqGRQLweiDOBmBdJnAWI5wPxeSAWJ8VAPSBOAWJTAuo6gPguEKsQY6gQEPOQ4Ih8IH4JxCYMNABhQPwOiN1pYbgzEL8C4hhaGG4AxM+BuJgWhisB8W0g7qOF4SJAfBqIl1EjI6EDbiDeAcQ7SUxlRAGQa5cA8RkGGoFeACG1GGdqegJfAAAAAElFTkSuQmCC");}
mroot
{display:inline-table;
direction:rtl;}
mroot > *
{display:table-cell;
direction:ltr;
text-align:left;}
mroot > *:first-child
{border-top:solid 1px;
border-left:groove 2px;
padding:2px 5px 0 3px;}
mroot > * + *
{vertical-align:bottom;
text-align:right;
font-size:0.7em;
line-height:1em;}
mroot > * + *:after
{display:block;
content:"";
width:22px;
height:14px;
margin-right:-1px;
margin-left:auto;}
mfenced
{display:inline-table;
border-collapse:separate;
border-spacing:0.2ex 0;
white-space:nowrap;
margin:1px;}
mfenced > *:first-child
{display:table-row;}
mfenced > * + *
{display:none;}
mfenced > *:before, mfenced > *:after
{display:table-cell;
content:"\A0";
background-repeat:no-repeat;
background-size:100% 100%;}
mfenced > *:before
{background-image:url("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAABQCAYAAAAZQFV3AAABtElEQVR42s2ZK0hEURCGr8UiPhYVRJAFoxssFtsafDXRKLogNpNNDDazTSxiMYhoMdtWsAibtKhssCj4ALWIoM4s58Awdb7gD3+45eO8z5z/FgWnfnEfAWoTz4tHCJhCdsQDBGxKXBd3EbBl8a14kIBtiF+pMdsS/4pnCNic+Ed8SMAq4g/xM7HWetIEaFdrROtOEuySgE0kmHqB2FKNBLtP3yGtmtatRWGd4scEexF3RIHrpnV7xGRcG+BsFDZuYO/i9ihw3wCPicn4NMDFKHDJwNS9UeCBgTWJ2W0a4GkUVnbd3YwCaw44TY6fOnyQ3hjYE3FUfRngVRQ45Lp7FgVWHXA3Clyhl8y2A4ZvtyMHnIwCzx1wLAq8cMDRKLDhgMNR4J0DlqPABwcsRYFvDtgdBX47YPHvgHiX8UnBlw2+sPGthx8O+PGFH7D4FVAt4EsKv0bxi16FliIqvFjCyzm84FShJbEfR6Rox58V+MNHhT7NVPjjUYU+b1X4AxyPCFRoiKHCYxYVGgRloVGVCg/TVGjcl4UGklloZJqFhrpZaOychQbjWWh0b7co9nPBqvX74w/Kju1j59IjnwAAAABJRU5ErkJggg==");}
mfenced > *:after
{background-image:url("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAABQCAYAAAAZQFV3AAABl0lEQVR42s3ZPyhFYRjH8ddiEa5cJaVbd2SwWGwM/m1yR3FKNpNNBpvZJossBonFbKMs6k4s6A4Wyp/CIoXfqXd4etbnOzj1Wz+97znv3+eklFJV6UvwM6TMK20k2q9sZxx7upRzZYpEB5RbZYl+p6/KOonOKL/KJokeKD/KHAWWY/RZ+VCGKbTIXS8/VIVCLzN6TIGNDJaZIMBySt5nsElN0VXTyhUC7FBeMviodBLormnlGgHOGvCaANuVd4OOEeiRAfcIcMGAn8TH6TVgmUWilS0D7hPgiQFbBLjhul2LgtMOLKJg1YHIe3wy4A0BXhnwKwFL2qnr9mAU3HHgOD10lqNg4cCtKDjpwMMoOOrAsyg44sCLKFh3YDMK1hx4FwV7HPgQBbsd+EbMZwt+/zsQ7zL+UfBhgw9sfOrhiwO+fOELLL4F4JsUvo3iGz16FMEPS/hxDj9w4kdi9NCOXyvwiw96NcMvj/j1Fr2A4yUCtIiBl1nwQhBaqkKLaXi5Dy1IoiVTtKiLlp3Rwjhaukd/LqC/P/4AwHbtY0GeJ20AAAAASUVORK5CYII=");}
mfenced[open="["] > *:before
{border-style:solid;
border-width:1px 0 1px 1px;
background-image:none;}
mfenced[close="]"] > *:after
{border-style:solid;
border-width:1px 1px 1px 0;
background-image:none;}
mfenced[open="\2016"] > *:before
{border-style:double;
border-width:0 0 0 3px;
background-image:none;}
mfenced[close="\2016"] > *:after
{border-style:double;
border-width:0 3px 0 0;
background-image:none;}
mfenced[open="\27e6"] > *:before
{border-style:double;
border-width:2px 0 2px 3px;
background-image:none;}
mfenced[close="\27e7"] > *:after
{border-style:double;
border-width:2px 3px 2px 0;
background-image:none;}
mfenced[open="|"] > *:before
{border-style:solid;
border-width:0 0 0 1px;
background-image:none;}
mfenced[close="|"] > *:after
{border-style:solid;
border-width:0 1px 0 0;
background-image:none;}
mfenced[open="\230a"] > *:before
{border-style:solid;
border-width:0 0 1px 1px;
background-image:none;}
mfenced[close="\230b"] > *:after
{border-style:solid;
border-width:0 1px 1px 0;
background-image:none;}
mfenced[open="\2308"] > *:before
{border-style:solid;
border-width:1px 0 0 1px;
background-image:none;}
mfenced[close="\2309"] > *:after
{border-style:solid;
border-width:1px 1px 0 0;
background-image:none;}
mfenced[open="{"] > *:before
{content:"\A0\A0";
background-image:url("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAABQCAYAAAAZQFV3AAABuklEQVR42rWZuy9EURCHj0c8Qta7pRMh0WgUqBQqG4leNGRL2VZpO6GiIYobHf+DhIiSf8AjFBIkmwiNRNZvsmdjtM53J/naL+fec+7MnLkhpMeoWBZDoi1F1C12REW0pK6qQ1yIY+AJQ5M4ES+inxCWRU2UCFmXeBWfokAIN+PqMkJmG1GNwnlCWIyyL9FJCI+i8IqQNcfNMOE2IZyNMmOJPHvGGCHMouw7NQE04iYKHwlZazwqJjwjhJPu/R0SwkUn3CKEa05YJhOCsUoI95ywSAhPnXCGEF464QQhvHbCEUJ4SwvvnXCQED47YQ8hrNLCdydEUlfNkRwFJ3sjhONOeE4IF5zwgBD61LVBCPfDb3GaSpUNiI8o3CVWV4myu1Bv45J3176QBzGdKlsRT6FeP9r/I7DPqU8MizmxLnpTVoQL8UfOfVNyOTa5HGz808slOeDpC0+weAkIAS5SFngZxQs93orgzRLezuENJ94S4007fq3ALz741Qy/POLXW/wCboGOCCzwIQY+ZsEHQfioygIdpoWQw7gPH0j6RJFRQnyo689kiRLig/HGBmGj+0agPxd8/Pn98QMoXcSZw6bNQwAAAABJRU5ErkJggg==");}
mfenced[close="}"] > *:after
{content:"\A0\A0";
background-image:url("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAABQCAYAAAAZQFV3AAABoklEQVR42sWZvUpDQRBGxx+iosS/2GoXJIKNjYVapbAyCPbBRrEMaS1NJ1ppo1gEO30HQZGU+gIxooWgQkC0ESR+iwOZBzjghdMe9t7dnZ39rplZRkyJDZE38OkTNXEgRkjxubgRg5RwQryKC9FDSXdER1QpYVZ8iTcxTEnrPspdSlh0YZuaoCHx7dISNcqGC88o4b4L0+T0EsJ1FyaWCeFsECJrMhWOHxfWqe/45MJ7SnjlwrSE+gnhafiO84RwLwjXCGE1CLcI4WYQIoWiFIRHhHApCC8J4VwQ3hLCmSC8o4VNQpgLwhYhHA3CF1rYJoSZIPygKk4ngDzvQZglhNdBWCCEJ0G4SggrBpewBeseVsfUxBy68FNMEsLU1j24tEaNclE8+o4pUNIB+ztnnkXZwGdMbIsVMS3GfZv+vxB9ZXRS8GWDLmx86+HFAS9feIHFjwD0kMKPUfygx1sRvFnC2zm84cRbYrxpx68V+MUHv5rhl0f8eotfwNGIAA8x8JgFD4LwqAoN0/C4Dw8k0cgUD3XR2BkPxrHoHvu5gP7++AUnfMSZodLInwAAAABJRU5ErkJggg==");}
mfenced[open="\27e8"] > *:before, mfenced[open="\2329"] > *:before
{background-image:url("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAABZCAYAAAA+TwS/AAAB50lEQVR42s2ZPyiFURiHj7+Lrkhks0goEqtFWSilW8oqg5GULExWk5K6g26ZrFI3i24Go8kkkWQwSPkTA673lzOcvu7kfZSnfuvTe77vnO+c834hsORgX+gjZR2WIVI4T8oaLGukcNYyTgoPLfWUbNiyR1ZXtOQpWbvl0dJECfVmDyhZneXWMkcJZywfljZKeGIpUzKt2YplkRLuRmEXIdMze7OcUdWtxurWqalyE4UDhDAfZZfUcMtRuEnIBqNMGSWEhSi7t9R4Za2W1ygsENWtJMOd9MpqLddR9mRp9Aqnk+r2ieEeJ8JZr6zf8hVl75Zmr3Anqa7klbVYXhLhgle4nMg+LZ0emVbCVSI89VY3lcgqcWK7OMoIuz2y3mSqKOfe6rYz1W14ZJq4zxnhiEe4lJHdeKfKRUa45RFOZGTKmEdYysgews+2+St6MlNFKXqq26oy3GmP8K6KsPVfVYg/Q/wt/8k8xFcKvpb/5GuDfw8F/sUW6J4i8F0P35cFenIQ+NlGoKcvgZ8PBXqCFfgZG78FhADfUwR+kwoBvusJ/DYqygG8Lwv8Ro/3HATaFRF430agnSWB974E2p0TeP8Q73AKtAcr8C6xKAawjy3wTrtA/wUI/G8F/j9FzNNC/J+U6KOFuW87Lt0vtp6NAwAAAABJRU5ErkJggg==");}
mfenced[close="\27e9"] > *:after, mfenced[close="\232A"] > *:after
{background-image:url("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAABZCAYAAAA+TwS/AAAByElEQVR42s2ZPSjFURiH/z4XkZvIZpFQJFaLslDqdkvdVQYjqZuFyWq6JXUH3TJZpW4WyWA0mSS6yWCQ8hGDr9+pdzid7vY+g1PP+vSe//89H+97sizLOjN4jNDCCdFHS5dp4aZoI4WzokgKW8UxPe0DMUkKC6JKCjvEs+glpUf2x7GxJO5FCyXsEV9ikYzyTJyTwlXxa2scGQMm3CejvBQf9k2RsWVRblDCMRPWyRS6MWmBEu6Y8IwSTpswME4Im8SjCStUlBUTvoscIZyPpl0ihO3ixYR3opmQHkZR5glhMRKeEsIu8WnCHzFKSGtRlHuEcCUSvolur7BffEfSdSLKi0h4ayvJNUqRMLDgFQ4mwhNi2leRMKTQsFe4nUS56xVOJcJXS3zXqCfSNa+wnAivvSk0kwgDcx5hOFafEmHNO+1qIgwpNOQR5htMu+wR5hoIH/5VhOg3xP8ynof4SkHXMr7b4PshumPjZwp+6qHnMn5zwO826O0Lvx/iN1j0jo1XAXidglZSeK2HV6N4vYxW9HjPAe+KoH0bvLOE975CmmDdObx/iHc40R4s3iXG+9hopx1/C8BfK/D3FPTFB3+Twl/N0He9P0bV3S+iamc2AAAAAElFTkSuQmCC");}
mfenced[open=""] > *:before, mfenced[close=""] > *:after
{content:normal;}
mover > * + mo[fence="true"], munder > * + mo[fence="true"]
{content:"\A0";
line-height:1ex;
background-size:100% 100%;
background-image:url("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAFAAAAAUCAYAAAAa2LrXAAABxElEQVR42u2YsUsCURzHnxlncmJlttYWkeDi4pBNDU6J0C4tRmPc2phb2KSL0iBt9T8EhTjWP2CFDoInCFKLINe3+gaH1ekdZ6S8L3yWd+/d7/v7+t5xpxD/WwqRcqhlIuVQa0TKoXaIlANlwCHJyDjsaQs0wRJpckxqhFZADnSBZhrXOJbjHCkoyF2VBFlQBC/AAM/AZ5rr45jBOUWuSfIewWkNYR5EwR4bOgEFcA2q4B7UwRNocRf1GMRvPIL4D7XivGa1tscaLdas00OVngr0mKXnKHv4E82BBI9TBTyA/oiG7DAA50C18KByzsDFun32UmFvCfbqihZAClwA3UXT73TALSiBYxCz4SvGNSXeo+OyN509p5iBbanc6l2L3dIAN6AMTvnrHbDoNoiAdRIGi2SSn2aKqU7YVD9CTyl61Oi5zB4aFru6yyzUcQx4eHN9aIvXwBlIg00xm9+nCntLs9fa0CNKZzYeq+N6xcmvfCbsAv8MhjWu/MygwkwMZvTtWAfAHWiDIzHFrwUTVJDZtJlVwHwxDy5BSOY0UiFmlf8a2BCfb/hS9pRjdmIfeGUetuVldmJVZuFYH9nJv8ydS3kDn8bEmYaXZFsAAAAASUVORK5CYII=");}
munder > * + mo[fence="true"]
{background-image:url("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAFAAAAAUCAYAAAAa2LrXAAABzElEQVR42u2Xv0tCURzFrxlPRbEyW2uLSHBxccimBqdEaJcWozFcG3MLm3RRGqSt/oegEEf7B6zQQVBBkFoEsfPsCA8zX+9m0Y974LNc773f7znvPrlPCCE0oSSrYXYrKgdpDbPbA3aVhWXZmZ1YB2mVh2Wlmd1QGXABfCoXU/mYVcY46AG3oAkOgVfl9EZeZtNkVp7xCU5wCQbgGRTBDnD949BczKDITAbMyPneAhtIgRYn6/RAGZyCONgQf/Pqo9FbnF7L9D7KocVsbB/ZzA2OQcewgZE+qIFrUAAn3HwfxMAWCIA14gcLRPviEEZ1/Ib6AfYUY48p9lyghxo9TfLaYRZumYacLHo+dipnQRvcgDw4AiELfYW4Js892jPurUXPsWmvq1XNgQifnv6fcDd2xD+LfgLOTJ60m3P6M6zbo5civUXo9Vs0D4JgFyR51LPgCpRABVTBA2jwdeiaGLoH4Qm1wvxt2touazRYs8oeSuwpyx6T7DlID79S+rVgE0RpKAeeGMQjcBjmOjg24Jwc10S5h7p2Ucvi9Ybf4es0Uopjac5RMpF+qupgkdQ5pmRBCXBAEioOOW0TJUmtEiVJLRElSWnih393vwCZOsSZn592GQAAAABJRU5ErkJggg==");}
menclose
{display:inline-table;
border-collapse:separate;
border-spacing:0.4ex 0;}
menclose[notation="top"]
{border-top:solid thin;}
menclose[notation="bottom"]
{border-bottom:solid thin;}
menclose[notation="right"]
{border-right:solid thin;}
menclose[notation="left"]
{border-left:solid thin;}
menclose[notation="box"]
{border:solid thin;}
menclose[notation="horizontalstrike"]
{text-decoration:line-through;}
mtable
{display:inline-table;
line-height:1.5em;
text-align:center;
vertical-align:middle;}
mtr
{display:table-row;}
mtd
{display:table-cell;
padding:0 0.5ex;}
mtable[columnalign="left"], mtr[columnalign="left"], mtd[columnalign="left"]
{text-align:left;}
mtable[columnalign="right"], mtr[columnalign="right"], mtd[columnalign="right"]
{text-align:right;}
mtable[rowalign="top"] mtd, mtable mtr[rowalign="top"] mtd,
math mtable mtr mtd[rowalign="top"]
{vertical-align:top}
mtable[rowalign="bottom"] mtd, mtable mtr[rowalign="bottom"] mtd,
math mtable mtr mtd[rowalign="bottom"]
{vertical-align:bottom}
mtable[rowalign="center"] mtd, mtable mtr[rowalign="center"] mtd,
math mtable mtr mtd[rowalign="center"]
{vertical-align:middle}
mtable[frame="solid"]
{border:solid thin;}
mtable[frame="dashed"]
{border:dashed thin;}
mtable[rowlines="solid"], mtable[rowlines="dashed"],
mtable[columnlines="solid"], mtable[columnlines="dashed"]
{border-collapse:collapse;}
mtable[rowlines="solid"] > mtr + mtr
{border-top:solid thin;}
mtable[rowlines="dashed"] > mtr + mtr
{border-top:dashed thin;}
mtable[columnlines="solid"] > mtr > mtd + mtd
{border-left:solid thin;}
mtable[columnlines="dashed"] > mtr > mtd + mtd
{border-left:dashed thin;}
mspace[linebreak="goodbreak"]:before
{content:"\200B";
white-space:normal;}
mspace[linebreak="newline"]:before, mspace[linebreak="indentingnewline"]:before
{content:"\000A";
white-space:pre;}
mspace[width]:before
{content:normal;}
mspace[width="verythinmathspace"]
{padding:0 0.05em;}
mspace[width="thinmathspace"]
{padding:0 0.08em;}
mspace[width="mediummathspace"]
{padding:0 0.11em;}
mspace[width="thickmathspace"]
{padding:0 0.14em;}
mspace[width="verythickmathspace"]
{padding:0 0.17em;}
mo[largeop="true"]
{font-size:1.3em;
vertical-align:-0.1ex;}
mo[form="infix"], * + mo
{padding:0 0.3ex;}
mo[form="prefix"]
{padding:0 0 0 0.5ex;}
mo[form="postfix"]
{padding:0 0.5ex 0 0;}
mo[fence="true"], mo[separator="true"]
{padding:0;}
mi[mathvariant="bold"], mi[mathvariant="bold-italic"], mi[mathvariant="bold-sans-serif"],
mi[mathvariant="sans-serif-bold-italic"],mn[mathvariant="bold"], mn[mathvariant="bold-italic"],
mn[mathvariant="bold-sans-serif"], mn[mathvariant="sans-serif-bold-italic"],mo[mathvariant="bold"],
mo[mathvariant="bold-italic"], mo[mathvariant="bold-sans-serif"], mo[mathvariant="sans-serif-bold-italic"],
ms[mathvariant="bold"], ms[mathvariant="bold-italic"], ms[mathvariant="bold-sans-serif"],
ms[mathvariant="sans-serif-bold-italic"],mtext[mathvariant="bold"], mtext[mathvariant="bold-italic"],
mtext[mathvariant="bold-sans-serif"], mtext[mathvariant="sans-serif-bold-italic"]
{font-weight:bold;
font-style:normal;}
mi[mathvariant="monospace"], mn[mathvariant="monospace"],mo[mathvariant="monospace"],
ms[mathvariant="monospace"],mtext[mathvariant="monospace"]
{font-family:monospace;
font-style:normal;}
mi[mathvariant="sans-serif"], mi[mathvariant="bold-sans-serif"], mi[mathvariant="bold-sans-serif"],
mi[mathvariant="sans-serif-italic"], mi[mathvariant="sans-serif-bold-italic"],mn[mathvariant="bold-sans-serif"],
mn[mathvariant="sans-serif"], mn[mathvariant="bold-sans-serif"], mn[mathvariant="sans-serif-italic"],
mn[mathvariant="sans-serif-bold-italic"], mo[mathvariant="sans-serif"], mo[mathvariant="bold-sans-serif"],
mo[mathvariant="bold-sans-serif"], mo[mathvariant="sans-serif-italic"], mo[mathvariant="sans-serif-bold-italic"],
ms[mathvariant="sans-serif"], ms[mathvariant="bold-sans-serif"], ms[mathvariant="bold-sans-serif"],
ms[mathvariant="sans-serif-italic"], ms[mathvariant="sans-serif-bold-italic"], mtext[mathvariant="sans-serif"],
mtext[mathvariant="bold-sans-serif"], mtext[mathvariant="bold-sans-serif"], mtext[mathvariant="sans-serif-italic"],
mtext[mathvariant="sans-serif-bold-italic"]
{font-family:sans-serif;
font-style:normal;}
mi, mi[mathvariant="italic"], mi[mathvariant="bold-italic"],mi[mathvariant="sans-serif-italic"],
mi[mathvariant="sans-serif-bold-italic"],mn[mathvariant="italic"], mn[mathvariant="bold-italic"],
mn[mathvariant="sans-serif-italic"], mn[mathvariant="sans-serif-bold-italic"],mo[mathvariant="italic"],
mo[mathvariant="bold-italic"],mo[mathvariant="sans-serif-italic"], mo[mathvariant="sans-serif-bold-italic"],
ms[mathvariant="italic"], ms[mathvariant="bold-italic"],ms[mathvariant="sans-serif-italic"],
ms[mathvariant="sans-serif-bold-italic"],mtext[mathvariant="italic"], mtext[mathvariant="bold-italic"],
mtext[mathvariant="sans-serif-italic"], mtext[mathvariant="sans-serif-bold-italic"]
{font-style:italic;}
mi[mathvariant="normal"], mn[mathvariant="normal"], mo[mathvariant="normal"],
ms[mathvariant="normal"], mtext[mathvariant="normal"]
{font-style:normal;}
ms:before, ms:after
{content:"\0022"}
ms[lquote]:before
{content:attr(lquote)}
ms[rquote]:after
{content:attr(rquote)}
mphantom
{visibility:hidden}
merror
{outline:solid thin red}
merror:before
{content:"Error: "}
mrow
{white-space:nowrap;}
math[display='block']
{display:block;
margin:1em 0 1em 3em;}
mstack, mlongdiv
{display:inline-table;
font-family:monospace;}
mstack
{text-align:right;
border-collapse:collapse;}
mstack[align='top'], mlongdiv[align='top']
{vertical-align:top;}
mstack[align='bottom'], mlongdiv[align='bottom']
{vertical-align:bottom;}
mstack[align='center'], mlongdiv[align='center']
{vertical-align:middle;}
msline
{display:block;
border-bottom:solid thin;}
mstack > *, mlongdiv > mn:first-child
{display:table-row;}
mlongdiv > *:first-child + *
{display:table-cell;}
mlongdiv > *:first-child + * + *
{border-top:solid thin;}
mlongdiv > *:first-child:before
{display:table-cell;
content:'\a0';}
mlongdiv > *:first-child + *:after
{content:')';}
mlongdiv > *
{display:block;}
mscarry
{display:none;}
maction > * + *
{display:none;}
maction[actiontype="tooltip"]:focus > * + *,
maction[actiontype="tooltip"]:hover > * + *
{position:fixed;
display:block;
top:0;
left:0;
background-color:InfoBackground;
color:InfoText;
padding:0.5ex;
border:solid 1px;}
annotation, annotation-xml
{display:none;}
Loading…
Cancel
Save