1
0

add initial marp implementation with sample content and build configuration

This commit is contained in:
2025-09-13 18:13:22 +02:00
parent dcacc9b409
commit e5f219507f
10319 changed files with 1402023 additions and 0 deletions

480
node_modules/mathjax-full/ts/output/chtml/FontData.ts generated vendored Normal file
View File

@@ -0,0 +1,480 @@
/*************************************************************
*
* Copyright (c) 2017-2022 The MathJax Consortium
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
/**
* @fileoverview Implements the CHTMLFontData class and AddCSS() function.
*
* @author dpvc@mathjax.org (Davide Cervone)
*/
import {CharMap, CharOptions, CharData, VariantData, DelimiterData, FontData, DIRECTION} from '../common/FontData.js';
import {Usage} from './Usage.js';
import {StringMap} from './Wrapper.js';
import {StyleList, StyleData} from '../../util/StyleList.js';
import {em} from '../../util/lengths.js';
export * from '../common/FontData.js';
/****************************************************************************/
/**
* Add the extra data needed for CharOptions in CHTML
*/
export interface CHTMLCharOptions extends CharOptions {
c?: string; // the content value (for css)
f?: string; // the font postfix (for css)
}
/**
* Shorthands for CHTML char maps and char data
*/
export type CHTMLCharMap = CharMap<CHTMLCharOptions>;
export type CHTMLCharData = CharData<CHTMLCharOptions>;
/**
* The extra data needed for a Variant in CHTML output
*/
export interface CHTMLVariantData extends VariantData<CHTMLCharOptions> {
classes?: string; // the classes to use for this variant
letter: string; // the font letter(s) for the default font for this variant
}
/**
* The extra data needed for a Delimiter in CHTML output
*/
export interface CHTMLDelimiterData extends DelimiterData {
}
/****************************************************************************/
/**
* The CHTML FontData class
*/
export class CHTMLFontData extends FontData<CHTMLCharOptions, CHTMLVariantData, CHTMLDelimiterData> {
/**
* Default options
*/
public static OPTIONS = {
...FontData.OPTIONS,
fontURL: 'js/output/chtml/fonts/tex-woff-v2'
};
/**
* @override
*/
public static JAX = 'CHTML';
/**
* The default class names to use for each variant
*/
protected static defaultVariantClasses: StringMap = {};
/**
* The default font letter to use for each variant
*/
protected static defaultVariantLetters: StringMap = {};
/**
* The CSS styles needed for this font.
*/
protected static defaultStyles = {
'mjx-c::before': {
display: 'block',
width: 0
}
};
/**
* The default @font-face declarations with %%URL%% where the font path should go
*/
protected static defaultFonts = {
'@font-face /* 0 */': {
'font-family': 'MJXZERO',
src: 'url("%%URL%%/MathJax_Zero.woff") format("woff")'
}
};
/***********************************************************************/
/**
* Data about the characters used (for adaptive CSS)
*/
public charUsage: Usage<[string, number]> = new Usage<[string, number]>();
/**
* Data about the delimiters used (for adpative CSS)
*/
public delimUsage: Usage<number> = new Usage<number>();
/***********************************************************************/
/**
* @override
*/
public static charOptions(font: CHTMLCharMap, n: number) {
return super.charOptions(font, n) as CHTMLCharOptions;
}
/***********************************************************************/
/**
* @param {boolean} adapt Whether to use adaptive CSS or not
*/
public adaptiveCSS(adapt: boolean) {
this.options.adaptiveCSS = adapt;
}
/**
* Clear the cache of which characters have been used
*/
public clearCache() {
if (this.options.adaptiveCSS) {
this.charUsage.clear();
this.delimUsage.clear();
}
}
/**
* @override
*/
public createVariant(name: string, inherit: string = null, link: string = null) {
super.createVariant(name, inherit, link);
let CLASS = (this.constructor as CHTMLFontDataClass);
this.variant[name].classes = CLASS.defaultVariantClasses[name];
this.variant[name].letter = CLASS.defaultVariantLetters[name];
}
/**
* @override
*/
public defineChars(name: string, chars: CHTMLCharMap) {
super.defineChars(name, chars);
const letter = this.variant[name].letter;
for (const n of Object.keys(chars)) {
const options = CHTMLFontData.charOptions(chars, parseInt(n));
if (options.f === undefined) {
options.f = letter;
}
}
}
/***********************************************************************/
/**
* @return {StyleList} The (computed) styles for this font
*/
get styles(): StyleList {
const CLASS = this.constructor as typeof CHTMLFontData;
//
// Include the default styles
//
const styles: StyleList = {...CLASS.defaultStyles};
//
// Add fonts with proper URL
//
this.addFontURLs(styles, CLASS.defaultFonts, this.options.fontURL);
//
// Add the styles for delimiters and characters
//
if (this.options.adaptiveCSS) {
this.updateStyles(styles);
} else {
this.allStyles(styles);
}
//
// Return the final style sheet
//
return styles;
}
/**
* Get the styles for any newly used characters and delimiters
*
* @param {StyleList} styles The style list to add delimiter styles to.
* @return {StyleList} The modified style list.
*/
public updateStyles(styles: StyleList): StyleList {
for (const N of this.delimUsage.update()) {
this.addDelimiterStyles(styles, N, this.delimiters[N]);
}
for (const [name, N] of this.charUsage.update()) {
const variant = this.variant[name];
this.addCharStyles(styles, variant.letter, N, variant.chars[N]);
}
return styles;
}
/**
* @param {StyleList} styles The style list to add characters to
*/
protected allStyles(styles: StyleList) {
//
// Create styles needed for the delimiters
//
for (const n of Object.keys(this.delimiters)) {
const N = parseInt(n);
this.addDelimiterStyles(styles, N, this.delimiters[N]);
}
//
// Add style for all character data
//
for (const name of Object.keys(this.variant)) {
const variant = this.variant[name];
const vletter = variant.letter;
for (const n of Object.keys(variant.chars)) {
const N = parseInt(n);
const char = variant.chars[N];
if ((char[3] || {}).smp) continue;
if (char.length < 4) {
(char as CHTMLCharData)[3] = {};
}
this.addCharStyles(styles, vletter, N, char);
}
}
}
/**
* @param {StyleList} styles The style object to add styles to
* @param {StyleList} fonts The default font-face directives with %%URL%% where the url should go
* @param {string} url The actual URL to insert into the src strings
*/
protected addFontURLs(styles: StyleList, fonts: StyleList, url: string) {
for (const name of Object.keys(fonts)) {
const font = {...fonts[name]};
font.src = (font.src as string).replace(/%%URL%%/, url);
styles[name] = font;
}
}
/*******************************************************/
/**
* @param {StyleList} styles The style object to add styles to
* @param {number} n The unicode character number of the delimiter
* @param {CHTMLDelimiterData} data The data for the delimiter whose CSS is to be added
*/
protected addDelimiterStyles(styles: StyleList, n: number, data: CHTMLDelimiterData) {
let c = this.charSelector(n);
if (data.c && data.c !== n) {
c = this.charSelector(data.c);
styles['.mjx-stretched mjx-c' + c + '::before'] = {
content: this.charContent(data.c)
};
}
if (!data.stretch) return;
if (data.dir === DIRECTION.Vertical) {
this.addDelimiterVStyles(styles, c, data);
} else {
this.addDelimiterHStyles(styles, c, data);
}
}
/*******************************************************/
/**
* @param {StyleList} styles The style object to add styles to
* @param {string} c The delimiter character string
* @param {CHTMLDelimiterData} data The data for the delimiter whose CSS is to be added
*/
protected addDelimiterVStyles(styles: StyleList, c: string, data: CHTMLDelimiterData) {
const HDW = data.HDW as CHTMLCharData;
const [beg, ext, end, mid] = data.stretch;
const Hb = this.addDelimiterVPart(styles, c, 'beg', beg, HDW);
this.addDelimiterVPart(styles, c, 'ext', ext, HDW);
const He = this.addDelimiterVPart(styles, c, 'end', end, HDW);
const css: StyleData = {};
if (mid) {
const Hm = this.addDelimiterVPart(styles, c, 'mid', mid, HDW);
css.height = '50%';
styles['mjx-stretchy-v' + c + ' > mjx-mid'] = {
'margin-top': this.em(-Hm / 2),
'margin-bottom': this.em(-Hm / 2)
};
}
if (Hb) {
css['border-top-width'] = this.em0(Hb - .03);
}
if (He) {
css['border-bottom-width'] = this.em0(He - .03);
styles['mjx-stretchy-v' + c + ' > mjx-end'] = {'margin-top': this.em(-He)};
}
if (Object.keys(css).length) {
styles['mjx-stretchy-v' + c + ' > mjx-ext'] = css;
}
}
/**
* @param {StyleList} styles The style object to add styles to
* @param {string} c The vertical character whose part is being added
* @param {string} part The name of the part (beg, ext, end, mid) that is being added
* @param {number} n The unicode character to use for the part
* @param {number} HDW The height-depth-width data for the stretchy delimiter
* @return {number} The total height of the character
*/
protected addDelimiterVPart(styles: StyleList, c: string, part: string, n: number, HDW: CHTMLCharData): number {
if (!n) return 0;
const data = this.getDelimiterData(n);
const dw = (HDW[2] - data[2]) / 2;
const css: StyleData = {content: this.charContent(n)};
if (part !== 'ext') {
css.padding = this.padding(data, dw);
} else {
css.width = this.em0(HDW[2]);
if (dw) {
css['padding-left'] = this.em0(dw);
}
}
styles['mjx-stretchy-v' + c + ' mjx-' + part + ' mjx-c::before'] = css;
return data[0] + data[1];
}
/*******************************************************/
/**
* @param {StyleList} styles The style object to add styles to
* @param {string} c The delimiter character string
* @param {CHTMLDelimiterData} data The data for the delimiter whose CSS is to be added
*/
protected addDelimiterHStyles(styles: StyleList, c: string, data: CHTMLDelimiterData) {
const [beg, ext, end, mid] = data.stretch;
const HDW = data.HDW as CHTMLCharData;
this.addDelimiterHPart(styles, c, 'beg', beg, HDW);
this.addDelimiterHPart(styles, c, 'ext', ext, HDW);
this.addDelimiterHPart(styles, c, 'end', end, HDW);
if (mid) {
this.addDelimiterHPart(styles, c, 'mid', mid, HDW);
styles['mjx-stretchy-h' + c + ' > mjx-ext'] = {width: '50%'};
}
}
/**
* @param {StyleList} styles The style object to add styles to
* @param {string} c The vertical character whose part is being added
* @param {string} part The name of the part (beg, ext, end, mid) that is being added
* @param {number} n The unicode character to use for the part
* @param {CHTMLCharData} HDW The height-depth-width data for the stretchy character
*/
protected addDelimiterHPart(styles: StyleList, c: string, part: string, n: number, HDW: CHTMLCharData) {
if (!n) return;
const data = this.getDelimiterData(n);
const options = data[3] as CHTMLCharOptions;
const css: StyleData = {content: (options && options.c ? '"' + options.c + '"' : this.charContent(n))};
css.padding = this.padding(HDW as CHTMLCharData, 0, -HDW[2]);
styles['mjx-stretchy-h' + c + ' mjx-' + part + ' mjx-c::before'] = css;
}
/*******************************************************/
/**
* @param {StyleList} styles The style object to add styles to
* @param {string} vletter The variant class letter (e.g., `B`, `SS`) where this character is being defined
* @param {number} n The unicode character being defined
* @param {CHTMLCharData} data The bounding box data and options for the character
*/
protected addCharStyles(styles: StyleList, vletter: string, n: number, data: CHTMLCharData) {
const options = data[3] as CHTMLCharOptions;
const letter = (options.f !== undefined ? options.f : vletter);
const selector = 'mjx-c' + this.charSelector(n) + (letter ? '.TEX-' + letter : '');
styles[selector + '::before'] = {
padding: this.padding(data, 0, options.ic || 0),
content: (options.c != null ? '"' + options.c + '"' : this.charContent(n))
};
}
/***********************************************************************/
/**
* @param {number} n The character number to find
* @return {CHTMLCharData} The data for that character to be used for stretchy delimiters
*/
protected getDelimiterData(n: number): CHTMLCharData {
return this.getChar('-smallop', n);
}
/**
* @param {number} n The number of ems
* @return {string} The string representing the number with units of "em"
*/
public em(n: number): string {
return em(n);
}
/**
* @param {number} n The number of ems (will be restricted to non-negative values)
* @return {string} The string representing the number with units of "em"
*/
public em0(n: number): string {
return em(Math.max(0, n));
}
/**
* @param {CHTMLCharData} data The [h, d, w] data for the character
* @param {number} dw The (optional) left offset of the glyph
* @param {number} ic The (optional) italic correction value
* @return {string} The padding string for the h, d, w.
*/
public padding([h, d, w]: CHTMLCharData, dw: number = 0, ic: number = 0): string {
return [h, w + ic, d, dw].map(this.em0).join(' ');
}
/**
* @param {number} n A unicode code point to be converted to character content for use with the
* CSS rules for fonts (either a literal character for most ASCII values, or \nnnn
* for higher values, or for the double quote and backslash characters).
* @return {string} The character as a properly encoded string in quotes.
*/
public charContent(n: number): string {
return '"' + (n >= 0x20 && n <= 0x7E && n !== 0x22 && n !== 0x27 && n !== 0x5C ?
String.fromCharCode(n) : '\\' + n.toString(16).toUpperCase()) + '"';
}
/**
* @param {number} n A unicode code point to be converted to a selector for use with the
* CSS rules for fonts
* @return {string} The character as a selector value.
*/
public charSelector(n: number): string {
return '.mjx-c' + n.toString(16).toUpperCase();
}
}
/**
* The CHTMLFontData constructor class
*/
export type CHTMLFontDataClass = typeof CHTMLFontData;
/****************************************************************************/
/**
* Data needed for AddCSS()
*/
export type CharOptionsMap = {[name: number]: CHTMLCharOptions};
export type CssMap = {[name: number]: number};
/**
* @param {CHTMLCharMap} font The font to augment
* @param {CharOptionsMap} options Any additional options for characters in the font
* @return {CHTMLCharMap} The augmented font
*/
export function AddCSS(font: CHTMLCharMap, options: CharOptionsMap): CHTMLCharMap {
for (const c of Object.keys(options)) {
const n = parseInt(c);
Object.assign(FontData.charOptions(font, n), options[n]);
}
return font;
}

116
node_modules/mathjax-full/ts/output/chtml/Notation.ts generated vendored Normal file
View File

@@ -0,0 +1,116 @@
/*************************************************************
*
* Copyright (c) 2018-2022 The MathJax Consortium
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
/**
* @fileoverview Implements utilities for notations for menclose elements
*
* @author dpvc@mathjax.org (Davide Cervone)
*/
import {CHTMLmenclose} from './Wrappers/menclose.js';
import * as Notation from '../common/Notation.js';
export * from '../common/Notation.js';
/*
* Shorthands for common types
*/
export type RENDERER<N, T, D> = Notation.Renderer<CHTMLmenclose<N, T, D>, N>;
export type DEFPAIR<N, T, D> = Notation.DefPair<CHTMLmenclose<N, T, D>, N>;
/**
* Create a named element (handled by CSS), and adjust it if thickness is non-standard
*
* @param {string} name The name of the element to create
* @param {string} offset The offset direction to adjust if thickness is non-standard
* @return {RENDERER} The renderer function for the given element name
*/
export const RenderElement = function<N, T, D>(name: string, offset: string = ''): RENDERER<N, T, D> {
return ((node, _child) => {
const shape = node.adjustBorder(node.html('mjx-' + name));
if (offset) {
const d = node.getOffset(offset);
if (node.thickness !== Notation.THICKNESS || d) {
const transform = `translate${offset}(${node.em(node.thickness / 2 - d)})`;
node.adaptor.setStyle(shape, 'transform', transform);
}
}
node.adaptor.append(node.chtml, shape);
}) as Notation.Renderer<CHTMLmenclose<N, T, D>, N>;
};
/**
* @param {Notation.Side} side The side on which a border should appear
* @return {DEFPAIR} The notation definition for the notation having a line on the given side
*/
export const Border = function<N, T, D>(side: Notation.Side): DEFPAIR<N, T, D> {
return Notation.CommonBorder<CHTMLmenclose<N, T, D>, N>((node, child) => {
node.adaptor.setStyle(child, 'border-' + side, node.em(node.thickness) + ' solid');
})(side);
};
/**
* @param {string} name The name of the notation to define
* @param {Notation.Side} side1 The first side to get a border
* @param {Notation.Side} side2 The second side to get a border
* @return {DEFPAIR} The notation definition for the notation having lines on two sides
*/
export const Border2 = function<N, T, D>(name: string, side1: Notation.Side, side2: Notation.Side): DEFPAIR<N, T, D> {
return Notation.CommonBorder2<CHTMLmenclose<N, T, D>, N>((node, child) => {
const border = node.em(node.thickness) + ' solid';
node.adaptor.setStyle(child, 'border-' + side1, border);
node.adaptor.setStyle(child, 'border-' + side2, border);
})(name, side1, side2);
};
/**
* @param {string} name The name of the diagonal strike to define
* @param {number} neg 1 or -1 to use with the angle
* @return {DEFPAIR} The notation definition for the diagonal strike
*/
export const DiagonalStrike = function<N, T, D>(name: string, neg: number): DEFPAIR<N, T, D> {
return Notation.CommonDiagonalStrike<CHTMLmenclose<N, T, D>, N>((cname: string) => (node, _child) => {
const {w, h, d} = node.getBBox();
const [a, W] = node.getArgMod(w, h + d);
const t = neg * node.thickness / 2;
const strike = node.adjustBorder(node.html(cname, {style: {
width: node.em(W),
transform: 'rotate(' + node.fixed(-neg * a) + 'rad) translateY(' + t + 'em)',
}}));
node.adaptor.append(node.chtml, strike);
})(name);
};
/**
* @param {string} name The name of the diagonal arrow to define
* @return {DEFPAIR} The notation definition for the diagonal arrow
*/
export const DiagonalArrow = function<N, T, D>(name: string): DEFPAIR<N, T, D> {
return Notation.CommonDiagonalArrow<CHTMLmenclose<N, T, D>, N>((node, arrow) => {
node.adaptor.append(node.chtml, arrow);
})(name);
};
/**
* @param {string} name The name of the horizontal or vertical arrow to define
* @return {DEFPAIR} The notation definition for the arrow
*/
export const Arrow = function<N, T, D>(name: string): DEFPAIR<N, T, D> {
return Notation.CommonArrow<CHTMLmenclose<N, T, D>, N>((node, arrow) => {
node.adaptor.append(node.chtml, arrow);
})(name);
};

76
node_modules/mathjax-full/ts/output/chtml/Usage.ts generated vendored Normal file
View File

@@ -0,0 +1,76 @@
/*************************************************************
*
* Copyright (c) 2021-2022 The MathJax Consortium
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
/**
* @fileoverview Keeps track of usage of font characters and wrappers
*
* @author dpvc@mathjax.org (Davide Cervone)
*/
/**
* Class used for tracking usage of font characters or wrappers
*/
export class Usage<T> {
/**
* The used items.
*/
protected used: Set<string> = new Set<string>();
/**
* The items marked as used since last update.
*/
protected needsUpdate: T[] = [];
/**
* @param {T} item The item that has been used
*/
public add(item: T) {
const name = JSON.stringify(item);
if (!this.used.has(name)) {
this.needsUpdate.push(item);
}
this.used.add(name);
}
/**
* @param {T} item The item to check for being used
* @return {boolean} True if the item has been used
*/
public has(item: T): boolean {
return this.used.has(JSON.stringify(item));
}
/**
* Clear the usage information
*/
public clear() {
this.used.clear();
this.needsUpdate = [];
}
/**
* Get the items marked as used since the last update.
*/
public update() {
const update = this.needsUpdate;
this.needsUpdate = [];
return update;
}
}

399
node_modules/mathjax-full/ts/output/chtml/Wrapper.ts generated vendored Normal file
View File

@@ -0,0 +1,399 @@
/*************************************************************
*
* Copyright (c) 2017-2022 The MathJax Consortium
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
/**
* @fileoverview Implements the CHTMLWrapper class
*
* @author dpvc@mathjax.org (Davide Cervone)
*/
import {OptionList} from '../../util/Options.js';
import * as LENGTHS from '../../util/lengths.js';
import {CommonWrapper, AnyWrapperClass, Constructor, StringMap} from '../common/Wrapper.js';
import {CHTML} from '../chtml.js';
import {CHTMLWrapperFactory} from './WrapperFactory.js';
import {BBox} from '../../util/BBox.js';
import {CHTMLFontData, CHTMLCharOptions, CHTMLDelimiterData} from './FontData.js';
export {Constructor, StringMap} from '../common/Wrapper.js';
/*****************************************************************/
/**
* Some standard sizes to use in predefind CSS properties
*/
export const FONTSIZE: StringMap = {
'70.7%': 's',
'70%': 's',
'50%': 'ss',
'60%': 'Tn',
'85%': 'sm',
'120%': 'lg',
'144%': 'Lg',
'173%': 'LG',
'207%': 'hg',
'249%': 'HG'
};
export const SPACE: StringMap = {
/* tslint:disable:whitespace */
[LENGTHS.em(2/18)]: '1',
[LENGTHS.em(3/18)]: '2',
[LENGTHS.em(4/18)]: '3',
[LENGTHS.em(5/18)]: '4',
[LENGTHS.em(6/18)]: '5'
/* tslint:enable */
};
/**
* Shorthand for making a CHTMLWrapper constructor
*/
export type CHTMLConstructor<N, T, D> = Constructor<CHTMLWrapper<N, T, D>>;
/*****************************************************************/
/**
* The type of the CHTMLWrapper class (used when creating the wrapper factory for this class)
*/
export interface CHTMLWrapperClass extends AnyWrapperClass {
kind: string;
/**
* If true, this causes a style for the node type to be generated automatically
* that sets display:inline-block (as needed for the output for MmlNodes).
*/
autoStyle: boolean;
}
/*****************************************************************/
/**
* The base CHTMLWrapper class
*
* @template N The HTMLElement node class
* @template T The Text node class
* @template D The Document class
*/
export class CHTMLWrapper<N, T, D> extends
CommonWrapper<
CHTML<N, T, D>,
CHTMLWrapper<N, T, D>,
CHTMLWrapperClass,
CHTMLCharOptions,
CHTMLDelimiterData,
CHTMLFontData
> {
/**
* The wrapper type
*/
public static kind: string = 'unknown';
/**
* If true, this causes a style for the node type to be generated automatically
* that sets display:inline-block (as needed for the output for MmlNodes).
*/
public static autoStyle = true;
/**
* @override
*/
protected factory: CHTMLWrapperFactory<N, T, D>;
/**
* @override
*/
public parent: CHTMLWrapper<N, T, D>;
/**
* @override
*/
public childNodes: CHTMLWrapper<N, T, D>[];
/**
* The HTML element generated for this wrapped node
*/
public chtml: N = null;
/*******************************************************************/
/**
* Create the HTML for the wrapped node.
*
* @param {N} parent The HTML node where the output is added
*/
public toCHTML(parent: N) {
const chtml = this.standardCHTMLnode(parent);
for (const child of this.childNodes) {
child.toCHTML(chtml);
}
}
/*******************************************************************/
/**
* Create the standard CHTML element for the given wrapped node.
*
* @param {N} parent The HTML element in which the node is to be created
* @returns {N} The root of the HTML tree for the wrapped node's output
*/
protected standardCHTMLnode(parent: N): N {
this.markUsed();
const chtml = this.createCHTMLnode(parent);
this.handleStyles();
this.handleVariant();
this.handleScale();
this.handleColor();
this.handleSpace();
this.handleAttributes();
this.handlePWidth();
return chtml;
}
/**
* Mark this class as having been typeset (so its styles will be output)
*/
public markUsed() {
this.jax.wrapperUsage.add(this.kind);
}
/**
* @param {N} parent The HTML element in which the node is to be created
* @returns {N} The root of the HTML tree for the wrapped node's output
*/
protected createCHTMLnode(parent: N): N {
const href = this.node.attributes.get('href');
if (href) {
parent = this.adaptor.append(parent, this.html('a', {href: href})) as N;
}
this.chtml = this.adaptor.append(parent, this.html('mjx-' + this.node.kind)) as N;
return this.chtml;
}
/**
* Set the CSS styles for the chtml element
*/
protected handleStyles() {
if (!this.styles) return;
const styles = this.styles.cssText;
if (styles) {
this.adaptor.setAttribute(this.chtml, 'style', styles);
const family = this.styles.get('font-family');
if (family) {
this.adaptor.setStyle(this.chtml, 'font-family', 'MJXZERO, ' + family);
}
}
}
/**
* Set the CSS for the math variant
*/
protected handleVariant() {
if (this.node.isToken && this.variant !== '-explicitFont') {
this.adaptor.setAttribute(this.chtml, 'class',
(this.font.getVariant(this.variant) || this.font.getVariant('normal')).classes);
}
}
/**
* Set the (relative) scaling factor for the node
*/
protected handleScale() {
this.setScale(this.chtml, this.bbox.rscale);
}
/**
* @param {N} chtml The HTML node to scale
* @param {number} rscale The relatie scale to apply
* @return {N} The HTML node (for chaining)
*/
protected setScale(chtml: N, rscale: number): N {
const scale = (Math.abs(rscale - 1) < .001 ? 1 : rscale);
if (chtml && scale !== 1) {
const size = this.percent(scale);
if (FONTSIZE[size]) {
this.adaptor.setAttribute(chtml, 'size', FONTSIZE[size]);
} else {
this.adaptor.setStyle(chtml, 'fontSize', size);
}
}
return chtml;
}
/**
* Add the proper spacing
*/
protected handleSpace() {
for (const data of [[this.bbox.L, 'space', 'marginLeft'],
[this.bbox.R, 'rspace', 'marginRight']]) {
const [dimen, name, margin] = data as [number, string, string];
if (dimen) {
const space = this.em(dimen);
if (SPACE[space]) {
this.adaptor.setAttribute(this.chtml, name, SPACE[space]);
} else {
this.adaptor.setStyle(this.chtml, margin, space);
}
}
}
}
/**
* Add the foreground and background colors
* (Only look at explicit attributes, since inherited ones will
* be applied to a parent element, and we will inherit from that)
*/
protected handleColor() {
const attributes = this.node.attributes;
const mathcolor = attributes.getExplicit('mathcolor') as string;
const color = attributes.getExplicit('color') as string;
const mathbackground = attributes.getExplicit('mathbackground') as string;
const background = attributes.getExplicit('background') as string;
if (mathcolor || color) {
this.adaptor.setStyle(this.chtml, 'color', mathcolor || color);
}
if (mathbackground || background) {
this.adaptor.setStyle(this.chtml, 'backgroundColor', mathbackground || background);
}
}
/**
* Copy RDFa, aria, and other tags from the MathML to the CHTML output nodes.
* Don't copy those in the skipAttributes list, or anything that already exists
* as a property of the node (e.g., no "onlick", etc.). If a name in the
* skipAttributes object is set to false, then the attribute WILL be copied.
* Add the class to any other classes already in use.
*/
protected handleAttributes() {
const attributes = this.node.attributes;
const defaults = attributes.getAllDefaults();
const skip = CHTMLWrapper.skipAttributes;
for (const name of attributes.getExplicitNames()) {
if (skip[name] === false || (!(name in defaults) && !skip[name] &&
!this.adaptor.hasAttribute(this.chtml, name))) {
this.adaptor.setAttribute(this.chtml, name, attributes.getExplicit(name) as string);
}
}
if (attributes.get('class')) {
const names = (attributes.get('class') as string).trim().split(/ +/);
for (const name of names) {
this.adaptor.addClass(this.chtml, name);
}
}
}
/**
* Handle the attributes needed for percentage widths
*/
protected handlePWidth() {
if (this.bbox.pwidth) {
if (this.bbox.pwidth === BBox.fullWidth) {
this.adaptor.setAttribute(this.chtml, 'width', 'full');
} else {
this.adaptor.setStyle(this.chtml, 'width', this.bbox.pwidth);
}
}
}
/*******************************************************************/
/**
* @param {N} chtml The HTML node whose indentation is to be adjusted
* @param {string} align The alignment for the node
* @param {number} shift The indent (positive or negative) for the node
*/
protected setIndent(chtml: N, align: string, shift: number) {
const adaptor = this.adaptor;
if (align === 'center' || align === 'left') {
const L = this.getBBox().L;
adaptor.setStyle(chtml, 'margin-left', this.em(shift + L));
}
if (align === 'center' || align === 'right') {
const R = this.getBBox().R;
adaptor.setStyle(chtml, 'margin-right', this.em(-shift + R));
}
}
/*******************************************************************/
/**
* For debugging
*/
public drawBBox() {
let {w, h, d, R} = this.getBBox();
const box = this.html('mjx-box', {style: {
opacity: .25, 'margin-left': this.em(-w - R)
}}, [
this.html('mjx-box', {style: {
height: this.em(h),
width: this.em(w),
'background-color': 'red'
}}),
this.html('mjx-box', {style: {
height: this.em(d),
width: this.em(w),
'margin-left': this.em(-w),
'vertical-align': this.em(-d),
'background-color': 'green'
}})
] as N[]);
const node = this.chtml || this.parent.chtml;
const size = this.adaptor.getAttribute(node, 'size');
if (size) {
this.adaptor.setAttribute(box, 'size', size);
}
const fontsize = this.adaptor.getStyle(node, 'fontSize');
if (fontsize) {
this.adaptor.setStyle(box, 'fontSize', fontsize);
}
this.adaptor.append(this.adaptor.parent(node), box);
this.adaptor.setStyle(node, 'backgroundColor', '#FFEE00');
}
/*******************************************************************/
/*
* Easy access to some utility routines
*/
/**
* @param {string} type The tag name of the HTML node to be created
* @param {OptionList} def The properties to set for the created node
* @param {(N|T)[]} content The child nodes for the created HTML node
* @return {N} The generated HTML tree
*/
public html(type: string, def: OptionList = {}, content: (N | T)[] = []): N {
return this.jax.html(type, def, content);
}
/**
* @param {string} text The text from which to create an HTML text node
* @return {T} The generated text node with the given text
*/
public text(text: string): T {
return this.jax.text(text);
}
/**
* @param {number} n A unicode code point to be converted to a character className reference.
* @return {string} The className for the character
*/
protected char(n: number): string {
return this.font.charSelector(n).substr(1);
}
}

View File

@@ -0,0 +1,58 @@
/*************************************************************
*
* Copyright (c) 2017-2022 The MathJax Consortium
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
/**
* @fileoverview Implements the CHTMLWrapperFactory class
*
* @author dpvc@mathjax.org (Davide Cervone)
*/
import {CHTML} from '../chtml.js';
import {CommonWrapperFactory} from '../common/WrapperFactory.js';
import {CHTMLWrapper, CHTMLWrapperClass} from './Wrapper.js';
import {CHTMLWrappers} from './Wrappers.js';
import {CHTMLCharOptions, CHTMLDelimiterData, CHTMLFontData} from './FontData.js';
/*****************************************************************/
/**
* The CHTMLWrapperFactory class for creating CHTMLWrapper nodes
*
* @template N The HTMLElement node class
* @template T The Text node class
* @template D The Document class
*/
export class CHTMLWrapperFactory<N, T, D> extends
CommonWrapperFactory<
CHTML<N, T, D>,
CHTMLWrapper<N, T, D>,
CHTMLWrapperClass,
CHTMLCharOptions,
CHTMLDelimiterData,
CHTMLFontData
> {
/**
* The default list of wrapper nodes this factory can create
*/
public static defaultNodes = CHTMLWrappers;
/**
* The CHTML output jax associated with this factory
*/
public jax: CHTML<N, T, D>;
}

88
node_modules/mathjax-full/ts/output/chtml/Wrappers.ts generated vendored Normal file
View File

@@ -0,0 +1,88 @@
/*************************************************************
*
* Copyright (c) 2017-2022 The MathJax Consortium
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
/**
* @fileoverview An object listing all the CHTMLWrapper classes
*
* @author dpvc@mathjax.org (Davide Cervone)
*/
import {WrapperConstructor} from '../common/Wrapper.js';
import {CHTMLWrapper} from './Wrapper.js';
import {CHTMLmath} from './Wrappers/math.js';
import {CHTMLmi} from './Wrappers/mi.js';
import {CHTMLmo} from './Wrappers/mo.js';
import {CHTMLmn} from './Wrappers/mn.js';
import {CHTMLms} from './Wrappers/ms.js';
import {CHTMLmtext} from './Wrappers/mtext.js';
import {CHTMLmspace} from './Wrappers/mspace.js';
import {CHTMLmpadded} from './Wrappers/mpadded.js';
import {CHTMLmenclose} from './Wrappers/menclose.js';
import {CHTMLmrow, CHTMLinferredMrow} from './Wrappers/mrow.js';
import {CHTMLmfenced} from './Wrappers/mfenced.js';
import {CHTMLmfrac} from './Wrappers/mfrac.js';
import {CHTMLmsqrt} from './Wrappers/msqrt.js';
import {CHTMLmroot} from './Wrappers/mroot.js';
import {CHTMLmsub, CHTMLmsup, CHTMLmsubsup} from './Wrappers/msubsup.js';
import {CHTMLmover, CHTMLmunder, CHTMLmunderover} from './Wrappers/munderover.js';
import {CHTMLmmultiscripts} from './Wrappers/mmultiscripts.js';
import {CHTMLmtable} from './Wrappers/mtable.js';
import {CHTMLmtr, CHTMLmlabeledtr} from './Wrappers/mtr.js';
import {CHTMLmtd} from './Wrappers/mtd.js';
import {CHTMLmaction} from './Wrappers/maction.js';
import {CHTMLmglyph} from './Wrappers/mglyph.js';
import {CHTMLsemantics, CHTMLannotation, CHTMLannotationXML, CHTMLxml} from './Wrappers/semantics.js';
import {CHTMLTeXAtom} from './Wrappers/TeXAtom.js';
import {CHTMLTextNode} from './Wrappers/TextNode.js';
export const CHTMLWrappers: {[kind: string]: WrapperConstructor} = {
[CHTMLmath.kind]: CHTMLmath,
[CHTMLmrow.kind]: CHTMLmrow,
[CHTMLinferredMrow.kind]: CHTMLinferredMrow,
[CHTMLmi.kind]: CHTMLmi,
[CHTMLmo.kind]: CHTMLmo,
[CHTMLmn.kind]: CHTMLmn,
[CHTMLms.kind]: CHTMLms,
[CHTMLmtext.kind]: CHTMLmtext,
[CHTMLmspace.kind]: CHTMLmspace,
[CHTMLmpadded.kind]: CHTMLmpadded,
[CHTMLmenclose.kind]: CHTMLmenclose,
[CHTMLmfrac.kind]: CHTMLmfrac,
[CHTMLmsqrt.kind]: CHTMLmsqrt,
[CHTMLmroot.kind]: CHTMLmroot,
[CHTMLmsub.kind]: CHTMLmsub,
[CHTMLmsup.kind]: CHTMLmsup,
[CHTMLmsubsup.kind]: CHTMLmsubsup,
[CHTMLmunder.kind]: CHTMLmunder,
[CHTMLmover.kind]: CHTMLmover,
[CHTMLmunderover.kind]: CHTMLmunderover,
[CHTMLmmultiscripts.kind]: CHTMLmmultiscripts,
[CHTMLmfenced.kind]: CHTMLmfenced,
[CHTMLmtable.kind]: CHTMLmtable,
[CHTMLmtr.kind]: CHTMLmtr,
[CHTMLmlabeledtr.kind]: CHTMLmlabeledtr,
[CHTMLmtd.kind]: CHTMLmtd,
[CHTMLmaction.kind]: CHTMLmaction,
[CHTMLmglyph.kind]: CHTMLmglyph,
[CHTMLsemantics.kind]: CHTMLsemantics,
[CHTMLannotation.kind]: CHTMLannotation,
[CHTMLannotationXML.kind]: CHTMLannotationXML,
[CHTMLxml.kind]: CHTMLxml,
[CHTMLTeXAtom.kind]: CHTMLTeXAtom,
[CHTMLTextNode.kind]: CHTMLTextNode,
[CHTMLWrapper.kind]: CHTMLWrapper
};

View File

@@ -0,0 +1,64 @@
/*************************************************************
*
* Copyright (c) 2017-2022 The MathJax Consortium
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
/**
* @fileoverview Implements the CHTMLTeXAtom wrapper for the MmlTeXAtom object
*
* @author dpvc@mathjax.org (Davide Cervone)
*/
import {CHTMLWrapper, CHTMLConstructor} from '../Wrapper.js';
import {CommonTeXAtomMixin} from '../../common/Wrappers/TeXAtom.js';
import {TeXAtom} from '../../../core/MmlTree/MmlNodes/TeXAtom.js';
import {TEXCLASS, TEXCLASSNAMES} from '../../../core/MmlTree/MmlNode.js';
/*****************************************************************/
/**
* The CHTMLTeXAtom wrapper for the TeXAtom object
*
* @template N The HTMLElement node class
* @template T The Text node class
* @template D The Document class
*/
// @ts-ignore
export class CHTMLTeXAtom<N, T, D> extends
CommonTeXAtomMixin<CHTMLConstructor<any, any, any>>(CHTMLWrapper) {
/**
* The TeXAtom wrapper
*/
public static kind = TeXAtom.prototype.kind;
/**
* @override
*/
public toCHTML(parent: N) {
super.toCHTML(parent);
this.adaptor.setAttribute(this.chtml, 'texclass', TEXCLASSNAMES[this.node.texClass]);
//
// Center VCENTER atoms vertically
//
if (this.node.texClass === TEXCLASS.VCENTER) {
const bbox = this.childNodes[0].getBBox(); // get unmodified bbox of children
const {h, d} = bbox;
const a = this.font.params.axis_height;
const dh = ((h + d) / 2 + a) - h; // new height minus old height
this.adaptor.setStyle(this.chtml, 'verticalAlign', this.em(dh));
}
}
}

View File

@@ -0,0 +1,89 @@
/*************************************************************
*
* Copyright (c) 2017-2022 The MathJax Consortium
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
/**
* @fileoverview Implements the CHTMLTextNode wrapper for the TextNode object
*
* @author dpvc@mathjax.org (Davide Cervone)
*/
import {TextNode} from '../../../core/MmlTree/MmlNode.js';
import {CHTMLWrapper, CHTMLConstructor} from '../Wrapper.js';
import {CommonTextNodeMixin} from '../../common/Wrappers/TextNode.js';
import {StyleList} from '../../../util/StyleList.js';
/*****************************************************************/
/**
* The CHTMLTextNode wrapper for the TextNode object
*
* @template N The HTMLElement node class
* @template T The Text node class
* @template D The Document class
*/
// @ts-ignore
export class CHTMLTextNode<N, T, D> extends
CommonTextNodeMixin<CHTMLConstructor<any, any, any>>(CHTMLWrapper) {
/**
* The TextNode wrapper
*/
public static kind = TextNode.prototype.kind;
/**
* @override
*/
public static autoStyle = false;
/**
* @override
*/
public static styles: StyleList = {
'mjx-c': {
display: 'inline-block'
},
'mjx-utext': {
display: 'inline-block',
padding: '.75em 0 .2em 0'
}
};
/**
* @override
*/
public toCHTML(parent: N) {
this.markUsed();
const adaptor = this.adaptor;
const variant = this.parent.variant;
const text = (this.node as TextNode).getText();
if (text.length === 0) return;
if (variant === '-explicitFont') {
adaptor.append(parent, this.jax.unknownText(text, variant, this.getBBox().w));
} else {
const chars = this.remappedText(text, variant);
for (const n of chars) {
const data = this.getVariantChar(variant, n)[3];
const font = (data.f ? ' TEX-' + data.f : '');
const node = (data.unknown ?
this.jax.unknownText(String.fromCodePoint(n), variant) :
this.html('mjx-c', {class: this.char(n) + font}));
adaptor.append(parent, node);
!data.unknown && this.font.charUsage.add([variant, n]);
}
}
}
}

View File

@@ -0,0 +1,208 @@
/*************************************************************
*
* Copyright (c) 2018-2022 The MathJax Consortium
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
/**
* @fileoverview Implements the CHTMLmaction wrapper for the MmlMaction object
*
* @author dpvc@mathjax.org (Davide Cervone)
*/
import {CHTMLWrapper, CHTMLConstructor} from '../Wrapper.js';
import {CommonMactionMixin} from '../../common/Wrappers/maction.js';
import {ActionDef} from '../../common/Wrappers/maction.js';
import {EventHandler, TooltipData} from '../../common/Wrappers/maction.js';
import {MmlMaction} from '../../../core/MmlTree/MmlNodes/maction.js';
import {TextNode} from '../../../core/MmlTree/MmlNode.js';
import {StyleList} from '../../../util/StyleList.js';
/*****************************************************************/
/**
* The CHTMLmaction wrapper for the MmlMaction object
*
* @template N The HTMLElement node class
* @template T The Text node class
* @template D The Document class
*/
// @ts-ignore
export class CHTMLmaction<N, T, D> extends
CommonMactionMixin<CHTMLWrapper<any, any, any>, CHTMLConstructor<any, any, any>>(CHTMLWrapper) {
/**
* The maction wrapper
*/
public static kind = MmlMaction.prototype.kind;
/**
* @override
*/
public static styles: StyleList = {
'mjx-maction': {
position: 'relative'
},
'mjx-maction > mjx-tool': {
display: 'none',
position: 'absolute',
bottom: 0, right: 0,
width: 0, height: 0,
'z-index': 500
},
'mjx-tool > mjx-tip': {
display: 'inline-block',
padding: '.2em',
border: '1px solid #888',
'font-size': '70%',
'background-color': '#F8F8F8',
color: 'black',
'box-shadow': '2px 2px 5px #AAAAAA'
},
'mjx-maction[toggle]': {
cursor: 'pointer'
},
'mjx-status': {
display: 'block',
position: 'fixed',
left: '1em',
bottom: '1em',
'min-width': '25%',
padding: '.2em .4em',
border: '1px solid #888',
'font-size': '90%',
'background-color': '#F8F8F8',
color: 'black'
}
};
/**
* The valid action types and their handlers
*/
public static actions = new Map([
['toggle', [(node, _data) => {
//
// Mark which child is selected
//
node.adaptor.setAttribute(node.chtml, 'toggle', node.node.attributes.get('selection') as string);
//
// Cache the data needed to select another node
//
const math = node.factory.jax.math;
const document = node.factory.jax.document;
const mml = node.node as MmlMaction;
//
// Add a click handler that changes the selection and rerenders the expression
//
node.setEventHandler('click', (event: Event) => {
if (!math.end.node) {
//
// If the MathItem was created by hand, it might not have a node
// telling it where to replace the existing math, so set it.
//
math.start.node = math.end.node = math.typesetRoot;
math.start.n = math.end.n = 0;
}
mml.nextToggleSelection();
math.rerender(document);
event.stopPropagation();
});
}, {}]],
['tooltip', [(node, data) => {
const tip = node.childNodes[1];
if (!tip) return;
if (tip.node.isKind('mtext')) {
//
// Text tooltips are handled through title attributes
//
const text = (tip.node as TextNode).getText();
node.adaptor.setAttribute(node.chtml, 'title', text);
} else {
//
// Math tooltips are handled through hidden nodes and event handlers
//
const adaptor = node.adaptor;
const tool = adaptor.append(node.chtml, node.html('mjx-tool', {
style: {bottom: node.em(-node.dy), right: node.em(-node.dx)}
}, [node.html('mjx-tip')]));
tip.toCHTML(adaptor.firstChild(tool));
//
// Set up the event handlers to display and remove the tooltip
//
node.setEventHandler('mouseover', (event: Event) => {
data.stopTimers(node, data);
const timeout = setTimeout(() => adaptor.setStyle(tool, 'display', 'block'), data.postDelay);
data.hoverTimer.set(node, timeout);
event.stopPropagation();
});
node.setEventHandler('mouseout', (event: Event) => {
data.stopTimers(node, data);
const timeout = setTimeout(() => adaptor.setStyle(tool, 'display', ''), data.clearDelay);
data.clearTimer.set(node, timeout);
event.stopPropagation();
});
}
}, TooltipData]],
['statusline', [(node, data) => {
const tip = node.childNodes[1];
if (!tip) return;
if (tip.node.isKind('mtext')) {
const adaptor = node.adaptor;
const text = (tip.node as TextNode).getText();
adaptor.setAttribute(node.chtml, 'statusline', text);
//
// Set up event handlers to change the status window
//
node.setEventHandler('mouseover', (event: Event) => {
if (data.status === null) {
const body = adaptor.body(adaptor.document);
data.status = adaptor.append(body, node.html('mjx-status', {}, [node.text(text)]));
}
event.stopPropagation();
});
node.setEventHandler('mouseout', (event: Event) => {
if (data.status) {
adaptor.remove(data.status);
data.status = null;
}
event.stopPropagation();
});
}
}, {
status: null // cached status line
}]]
] as ActionDef<CHTMLmaction<any, any, any>>[]);
/*************************************************************/
/**
* @override
*/
public toCHTML(parent: N) {
const chtml = this.standardCHTMLnode(parent);
const child = this.selected;
child.toCHTML(chtml);
this.action(this, this.data);
}
/**
* Add an event handler to the output for this maction
*/
public setEventHandler(type: string, handler: EventHandler) {
(this.chtml as any).addEventListener(type, handler);
}
}

View File

@@ -0,0 +1,156 @@
/*************************************************************
*
* Copyright (c) 2017-2022 The MathJax Consortium
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
/**
* @fileoverview Implements the CHTMLmath wrapper for the MmlMath object
*
* @author dpvc@mathjax.org (Davide Cervone)
*/
import {CHTMLWrapper, CHTMLConstructor} from '../Wrapper.js';
import {CommonMathMixin} from '../../common/Wrappers/math.js';
import {MmlMath} from '../../../core/MmlTree/MmlNodes/math.js';
import {StyleList} from '../../../util/StyleList.js';
import {BBox} from '../../../util/BBox.js';
/*****************************************************************/
/**
* The CHTMLmath wrapper for the MmlMath object
*
* @template N The HTMLElement node class
* @template T The Text node class
* @template D The Document class
*/
// @ts-ignore
export class CHTMLmath<N, T, D> extends
CommonMathMixin<CHTMLConstructor<any, any, any>>(CHTMLWrapper) {
/**
* The math wrapper
*/
public static kind = MmlMath.prototype.kind;
/**
* @override
*/
public static styles: StyleList = {
'mjx-math': {
'line-height': 0,
'text-align': 'left',
'text-indent': 0,
'font-style': 'normal',
'font-weight': 'normal',
'font-size': '100%',
'font-size-adjust': 'none',
'letter-spacing': 'normal',
'border-collapse': 'collapse',
'word-wrap': 'normal',
'word-spacing': 'normal',
'white-space': 'nowrap',
'direction': 'ltr',
'padding': '1px 0'
},
'mjx-container[jax="CHTML"][display="true"]': {
display: 'block',
'text-align': 'center',
margin: '1em 0'
},
'mjx-container[jax="CHTML"][display="true"][width="full"]': {
display: 'flex'
},
'mjx-container[jax="CHTML"][display="true"] mjx-math': {
padding: 0
},
'mjx-container[jax="CHTML"][justify="left"]': {
'text-align': 'left'
},
'mjx-container[jax="CHTML"][justify="right"]': {
'text-align': 'right'
}
};
/**
* @override
*/
public toCHTML(parent: N) {
super.toCHTML(parent);
const chtml = this.chtml;
const adaptor = this.adaptor;
const display = (this.node.attributes.get('display') === 'block');
if (display) {
adaptor.setAttribute(chtml, 'display', 'true');
adaptor.setAttribute(parent, 'display', 'true');
this.handleDisplay(parent);
} else {
this.handleInline(parent);
}
adaptor.addClass(chtml, 'MJX-TEX');
}
/**
* Handle displayed equations (set min-width, and so on).
*/
protected handleDisplay(parent: N) {
const adaptor = this.adaptor;
const [align, shift] = this.getAlignShift();
if (align !== 'center') {
adaptor.setAttribute(parent, 'justify', align);
}
if (this.bbox.pwidth === BBox.fullWidth) {
adaptor.setAttribute(parent, 'width', 'full');
if (this.jax.table) {
let {L, w, R} = this.jax.table.getOuterBBox();
if (align === 'right') {
R = Math.max(R || -shift, -shift);
} else if (align === 'left') {
L = Math.max(L || shift, shift);
} else if (align === 'center') {
w += 2 * Math.abs(shift);
}
const W = this.em(Math.max(0, L + w + R));
adaptor.setStyle(parent, 'min-width', W);
adaptor.setStyle(this.jax.table.chtml, 'min-width', W);
}
} else {
this.setIndent(this.chtml, align, shift);
}
}
/**
* Handle in-line expressions
*/
protected handleInline(parent: N) {
//
// Transfer right margin to container (for things like $x\hskip -2em y$)
//
const adaptor = this.adaptor;
const margin = adaptor.getStyle(this.chtml, 'margin-right');
if (margin) {
adaptor.setStyle(this.chtml, 'margin-right', '');
adaptor.setStyle(parent, 'margin-right', margin);
adaptor.setStyle(parent, 'width', '0');
}
}
/**
* @override
*/
public setChildPWidths(recompute: boolean, w: number = null, clear: boolean = true) {
return (this.parent ? super.setChildPWidths(recompute, w, clear) : false);
}
}

View File

@@ -0,0 +1,489 @@
/*************************************************************
*
* Copyright (c) 2018-2022 The MathJax Consortium
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
/**
* @fileoverview Implements the CHTMLmenclose wrapper for the MmlMenclose object
*
* @author dpvc@mathjax.org (Davide Cervone)
*/
import {CHTMLWrapper, CHTMLConstructor} from '../Wrapper.js';
import {CommonMencloseMixin} from '../../common/Wrappers/menclose.js';
import {CHTMLmsqrt} from './msqrt.js';
import * as Notation from '../Notation.js';
import {MmlMenclose} from '../../../core/MmlTree/MmlNodes/menclose.js';
import {OptionList} from '../../../util/Options.js';
import {StyleList} from '../../../util/StyleList.js';
import {em} from '../../../util/lengths.js';
/*****************************************************************/
/**
* The skew angle needed for the arrow head pieces
*/
function Angle(x: number, y: number) {
return Math.atan2(x, y).toFixed(3).replace(/\.?0+$/, '');
}
const ANGLE = Angle(Notation.ARROWDX, Notation.ARROWY);
/*****************************************************************/
/**
* The CHTMLmenclose wrapper for the MmlMenclose object
*
* @template N The HTMLElement node class
* @template T The Text node class
* @template D The Document class
*/
// @ts-ignore
export class CHTMLmenclose<N, T, D> extends
CommonMencloseMixin<
CHTMLWrapper<any, any, any>,
CHTMLmsqrt<any, any, any>,
any,
CHTMLConstructor<any, any, any>
>(CHTMLWrapper) {
/**
* The menclose wrapper
*/
public static kind = MmlMenclose.prototype.kind;
/**
* Styles needed for the various notations
*/
public static styles: StyleList = {
'mjx-menclose': {
position: 'relative'
},
'mjx-menclose > mjx-dstrike': {
display: 'inline-block',
left: 0, top: 0,
position: 'absolute',
'border-top': Notation.SOLID,
'transform-origin': 'top left'
},
'mjx-menclose > mjx-ustrike': {
display: 'inline-block',
left: 0, bottom: 0,
position: 'absolute',
'border-top': Notation.SOLID,
'transform-origin': 'bottom left'
},
'mjx-menclose > mjx-hstrike': {
'border-top': Notation.SOLID,
position: 'absolute',
left: 0, right: 0, bottom: '50%',
transform: 'translateY(' + em(Notation.THICKNESS / 2) + ')'
},
'mjx-menclose > mjx-vstrike': {
'border-left': Notation.SOLID,
position: 'absolute',
top: 0, bottom: 0, right: '50%',
transform: 'translateX(' + em(Notation.THICKNESS / 2) + ')'
},
'mjx-menclose > mjx-rbox': {
position: 'absolute',
top: 0, bottom: 0, right: 0, left: 0,
'border': Notation.SOLID,
'border-radius': em(Notation.THICKNESS + Notation.PADDING)
},
'mjx-menclose > mjx-cbox': {
position: 'absolute',
top: 0, bottom: 0, right: 0, left: 0,
'border': Notation.SOLID,
'border-radius': '50%'
},
'mjx-menclose > mjx-arrow': {
position: 'absolute',
left: 0, bottom: '50%', height: 0, width: 0
},
'mjx-menclose > mjx-arrow > *': {
display: 'block',
position: 'absolute',
'transform-origin': 'bottom',
'border-left': em(Notation.THICKNESS * Notation.ARROWX) + ' solid',
'border-right': 0,
'box-sizing': 'border-box'
},
'mjx-menclose > mjx-arrow > mjx-aline': {
left: 0, top: em(-Notation.THICKNESS / 2),
right: em(Notation.THICKNESS * (Notation.ARROWX - 1)), height: 0,
'border-top': em(Notation.THICKNESS) + ' solid',
'border-left': 0
},
'mjx-menclose > mjx-arrow[double] > mjx-aline': {
left: em(Notation.THICKNESS * (Notation.ARROWX - 1)), height: 0,
},
'mjx-menclose > mjx-arrow > mjx-rthead': {
transform: 'skewX(' + ANGLE + 'rad)',
right: 0, bottom: '-1px',
'border-bottom': '1px solid transparent',
'border-top': em(Notation.THICKNESS * Notation.ARROWY) + ' solid transparent'
},
'mjx-menclose > mjx-arrow > mjx-rbhead': {
transform: 'skewX(-' + ANGLE + 'rad)',
'transform-origin': 'top',
right: 0, top: '-1px',
'border-top': '1px solid transparent',
'border-bottom': em(Notation.THICKNESS * Notation.ARROWY) + ' solid transparent'
},
'mjx-menclose > mjx-arrow > mjx-lthead': {
transform: 'skewX(-' + ANGLE + 'rad)',
left: 0, bottom: '-1px',
'border-left': 0,
'border-right': em(Notation.THICKNESS * Notation.ARROWX) + ' solid',
'border-bottom': '1px solid transparent',
'border-top': em(Notation.THICKNESS * Notation.ARROWY) + ' solid transparent'
},
'mjx-menclose > mjx-arrow > mjx-lbhead': {
transform: 'skewX(' + ANGLE + 'rad)',
'transform-origin': 'top',
left: 0, top: '-1px',
'border-left': 0,
'border-right': em(Notation.THICKNESS * Notation.ARROWX) + ' solid',
'border-top': '1px solid transparent',
'border-bottom': em(Notation.THICKNESS * Notation.ARROWY) + ' solid transparent'
},
'mjx-menclose > dbox': {
position: 'absolute',
top: 0, bottom: 0, left: em(-1.5 * Notation.PADDING),
width: em(3 * Notation.PADDING),
border: em(Notation.THICKNESS) + ' solid',
'border-radius': '50%',
'clip-path': 'inset(0 0 0 ' + em(1.5 * Notation.PADDING) + ')',
'box-sizing': 'border-box'
}
};
/**
* The definitions of the various notations
*/
public static notations: Notation.DefList<CHTMLmenclose<any, any, any>, any> = new Map([
Notation.Border('top'),
Notation.Border('right'),
Notation.Border('bottom'),
Notation.Border('left'),
Notation.Border2('actuarial', 'top', 'right'),
Notation.Border2('madruwb', 'bottom', 'right'),
Notation.DiagonalStrike('up', 1),
Notation.DiagonalStrike('down', -1),
['horizontalstrike', {
renderer: Notation.RenderElement('hstrike', 'Y'),
bbox: (node) => [0, node.padding, 0, node.padding]
}],
['verticalstrike', {
renderer: Notation.RenderElement('vstrike', 'X'),
bbox: (node) => [node.padding, 0, node.padding, 0]
}],
['box', {
renderer: (node, child) => {
node.adaptor.setStyle(child, 'border', node.em(node.thickness) + ' solid');
},
bbox: Notation.fullBBox,
border: Notation.fullBorder,
remove: 'left right top bottom'
}],
['roundedbox', {
renderer: Notation.RenderElement('rbox'),
bbox: Notation.fullBBox
}],
['circle', {
renderer: Notation.RenderElement('cbox'),
bbox: Notation.fullBBox
}],
['phasorangle', {
//
// Use a bottom border and an upward strike properly angled
//
renderer: (node, child) => {
const {h, d} = node.getBBox();
const [a, W] = node.getArgMod(1.75 * node.padding, h + d);
const t = node.thickness * Math.sin(a) * .9;
node.adaptor.setStyle(child, 'border-bottom', node.em(node.thickness) + ' solid');
const strike = node.adjustBorder(node.html('mjx-ustrike', {style: {
width: node.em(W),
transform: 'translateX(' + node.em(t) + ') rotate(' + node.fixed(-a) + 'rad)',
}}));
node.adaptor.append(node.chtml, strike);
},
bbox: (node) => {
const p = node.padding / 2;
const t = node.thickness;
return [2 * p, p, p + t, 3 * p + t];
},
border: (node) => [0, 0, node.thickness, 0],
remove: 'bottom'
}],
Notation.Arrow('up'),
Notation.Arrow('down'),
Notation.Arrow('left'),
Notation.Arrow('right'),
Notation.Arrow('updown'),
Notation.Arrow('leftright'),
Notation.DiagonalArrow('updiagonal'), // backward compatibility
Notation.DiagonalArrow('northeast'),
Notation.DiagonalArrow('southeast'),
Notation.DiagonalArrow('northwest'),
Notation.DiagonalArrow('southwest'),
Notation.DiagonalArrow('northeastsouthwest'),
Notation.DiagonalArrow('northwestsoutheast'),
['longdiv', {
//
// Use a line along the top followed by a half ellipse at the left
//
renderer: (node, child) => {
const adaptor = node.adaptor;
adaptor.setStyle(child, 'border-top', node.em(node.thickness) + ' solid');
const arc = adaptor.append(node.chtml, node.html('dbox'));
const t = node.thickness;
const p = node.padding;
if (t !== Notation.THICKNESS) {
adaptor.setStyle(arc, 'border-width', node.em(t));
}
if (p !== Notation.PADDING) {
adaptor.setStyle(arc, 'left', node.em(-1.5 * p));
adaptor.setStyle(arc, 'width', node.em(3 * p));
adaptor.setStyle(arc, 'clip-path', 'inset(0 0 0 ' + node.em(1.5 * p) + ')');
}
},
bbox: (node) => {
const p = node.padding;
const t = node.thickness;
return [p + t, p, p, 2 * p + t / 2];
}
}],
['radical', {
//
// Use the msqrt rendering, but remove the extra space due to the radical
// (it is added in at the end, so other notations overlap the root)
//
renderer: (node, child) => {
node.msqrt.toCHTML(child);
const TRBL = node.sqrtTRBL();
node.adaptor.setStyle(node.msqrt.chtml, 'margin', TRBL.map(x => node.em(-x)).join(' '));
},
//
// Create the needed msqrt wrapper
//
init: (node) => {
node.msqrt = node.createMsqrt(node.childNodes[0]);
},
//
// Add back in the padding for the square root
//
bbox: (node) => node.sqrtTRBL(),
//
// This notation replaces the child
//
renderChild: true
}]
] as Notation.DefPair<CHTMLmenclose<any, any, any>, any>[]);
/********************************************************/
/**
* @override
*/
public toCHTML(parent: N) {
const adaptor = this.adaptor;
const chtml = this.standardCHTMLnode(parent);
//
// Create a box for the child (that can have padding and borders added by the notations)
// and add the child HTML into it
//
const block = adaptor.append(chtml, this.html('mjx-box')) as N;
if (this.renderChild) {
this.renderChild(this, block);
} else {
this.childNodes[0].toCHTML(block);
}
//
// Render all the notations for this menclose element
//
for (const name of Object.keys(this.notations)) {
const notation = this.notations[name];
!notation.renderChild && notation.renderer(this, block);
}
//
// Add the needed padding, if any
//
const pbox = this.getPadding();
for (const name of Notation.sideNames) {
const i = Notation.sideIndex[name];
pbox[i] > 0 && adaptor.setStyle(block, 'padding-' + name, this.em(pbox[i]));
}
}
/********************************************************/
/**
* Create an arrow using HTML elements
*
* @param {number} w The length of the arrow
* @param {number} a The angle for the arrow
* @param {boolean} double True if this is a double-headed arrow
* @param {string} offset 'X' for vertical arrow, 'Y' for horizontal
* @param {number} dist Distance to translate in the offset direction
* @return {N} The newly created arrow
*/
public arrow(w: number, a: number, double: boolean, offset: string = '', dist: number = 0): N {
const W = this.getBBox().w;
const style = {width: this.em(w)} as OptionList;
if (W !== w) {
style.left = this.em((W - w) / 2);
}
if (a) {
style.transform = 'rotate(' + this.fixed(a) + 'rad)';
}
const arrow = this.html('mjx-arrow', {style: style}, [
this.html('mjx-aline'), this.html('mjx-rthead'), this.html('mjx-rbhead')
]);
if (double) {
this.adaptor.append(arrow, this.html('mjx-lthead'));
this.adaptor.append(arrow, this.html('mjx-lbhead'));
this.adaptor.setAttribute(arrow, 'double', 'true');
}
this.adjustArrow(arrow, double);
this.moveArrow(arrow, offset, dist);
return arrow;
}
/**
* @param {N} arrow The arrow whose thickness and arrow head is to be adjusted
* @param {boolean} double True if the arrow is double-headed
*/
protected adjustArrow(arrow: N, double: boolean) {
const t = this.thickness;
const head = this.arrowhead;
if (head.x === Notation.ARROWX && head.y === Notation.ARROWY &&
head.dx === Notation.ARROWDX && t === Notation.THICKNESS) return;
const [x, y] = [t * head.x, t * head.y].map(x => this.em(x));
const a = Angle(head.dx, head.y);
const [line, rthead, rbhead, lthead, lbhead] = this.adaptor.childNodes(arrow);
this.adjustHead(rthead, [y, '0', '1px', x], a);
this.adjustHead(rbhead, ['1px', '0', y, x], '-' + a);
this.adjustHead(lthead, [y, x, '1px', '0'], '-' + a);
this.adjustHead(lbhead, ['1px', x, y, '0'], a);
this.adjustLine(line, t, head.x, double);
}
/**
* @param {N} head The piece of arrow head to be adjusted
* @param {string[]} border The border sizes [T, R, B, L]
* @param {string} a The skew angle for the piece
*/
protected adjustHead(head: N, border: string[], a: string) {
if (head) {
this.adaptor.setStyle(head, 'border-width', border.join(' '));
this.adaptor.setStyle(head, 'transform', 'skewX(' + a + 'rad)');
}
}
/**
* @param {N} line The arrow shaft to be adjusted
* @param {number} t The arrow shaft thickness
* @param {number} x The arrow head x size
* @param {boolean} double True if the arrow is double-headed
*/
protected adjustLine(line: N, t: number, x: number, double: boolean) {
this.adaptor.setStyle(line, 'borderTop', this.em(t) + ' solid');
this.adaptor.setStyle(line, 'top', this.em(-t / 2));
this.adaptor.setStyle(line, 'right', this.em(t * (x - 1)));
if (double) {
this.adaptor.setStyle(line, 'left', this.em(t * (x - 1)));
}
}
/**
* @param {N} arrow The arrow whose position is to be adjusted
* @param {string} offset The direction to move the arrow
* @param {number} d The distance to translate in that direction
*/
protected moveArrow(arrow: N, offset: string, d: number) {
if (!d) return;
const transform = this.adaptor.getStyle(arrow, 'transform');
this.adaptor.setStyle(
arrow, 'transform', `translate${offset}(${this.em(-d)})${(transform ? ' ' + transform : '')}`
);
}
/********************************************************/
/**
* @param {N} node The HTML element whose border width must be
* adjusted if the thickness isn't the default
* @return {N} The adjusted element
*/
public adjustBorder(node: N): N {
if (this.thickness !== Notation.THICKNESS) {
this.adaptor.setStyle(node, 'borderWidth', this.em(this.thickness));
}
return node;
}
/**
* @param {N} shape The svg element whose stroke-thickness must be
* adjusted if the thickness isn't the default
* @return {N} The adjusted element
*/
public adjustThickness(shape: N): N {
if (this.thickness !== Notation.THICKNESS) {
this.adaptor.setStyle(shape, 'strokeWidth', this.fixed(this.thickness));
}
return shape;
}
/********************************************************/
/**
* @param {number} m A number to be shown with a fixed number of digits
* @param {number=} n The number of digits to use
* @return {string} The formatted number
*/
public fixed(m: number, n: number = 3): string {
if (Math.abs(m) < .0006) {
return '0';
}
return m.toFixed(n).replace(/\.?0+$/, '');
}
/**
* @override
* (make it public so it can be called by the notation functions)
*/
public em(m: number) {
return super.em(m);
}
}

View File

@@ -0,0 +1,52 @@
/*************************************************************
*
* Copyright (c) 2018-2022 The MathJax Consortium
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
/**
* @fileoverview Implements the CHTMLmfenced wrapper for the MmlMfenced object
*
* @author dpvc@mathjax.org (Davide Cervone)
*/
import {CHTMLWrapper, CHTMLConstructor} from '../Wrapper.js';
import {CommonMfencedMixin} from '../../common/Wrappers/mfenced.js';
import {MmlMfenced} from '../../../core/MmlTree/MmlNodes/mfenced.js';
import {CHTMLinferredMrow} from './mrow.js';
/*****************************************************************/
/**
* The CHTMLmfenced wrapper for the MmlMfenced object
*
* @template N The HTMLElement node class
* @template T The Text node class
* @template D The Document class
*/
export class CHTMLmfenced<N, T, D> extends CommonMfencedMixin<CHTMLConstructor<any, any, any>>(CHTMLWrapper) {
/**
* The mfenced wrapper
*/
public static kind = MmlMfenced.prototype.kind;
/**
* @override
*/
public toCHTML(parent: N) {
const chtml = this.standardCHTMLnode(parent);
(this.mrow as CHTMLinferredMrow<N, T, D>).toCHTML(chtml);
}
}

View File

@@ -0,0 +1,275 @@
/*************************************************************
*
* Copyright (c) 2017-2022 The MathJax Consortium
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
/**
* @fileoverview Implements the CHTMLmfrac wrapper for the MmlMfrac object
*
* @author dpvc@mathjax.org (Davide Cervone)
*/
import {CHTMLWrapper, CHTMLConstructor} from '../Wrapper.js';
import {CommonMfracMixin} from '../../common/Wrappers/mfrac.js';
import {MmlMfrac} from '../../../core/MmlTree/MmlNodes/mfrac.js';
import {CHTMLmo} from './mo.js';
import {StyleList} from '../../../util/StyleList.js';
import {OptionList} from '../../../util/Options.js';
/*****************************************************************/
/**
* The CHTMLmfrac wrapper for the MmlMfrac object
*
* @template N The HTMLElement node class
* @template T The Text node class
* @template D The Document class
*/
export class CHTMLmfrac<N, T, D> extends CommonMfracMixin<CHTMLConstructor<any, any, any>>(CHTMLWrapper) {
/**
* The mfrac wrapper
*/
public static kind = MmlMfrac.prototype.kind;
/**
* @override
*/
public static styles: StyleList = {
'mjx-frac': {
display: 'inline-block',
'vertical-align': '0.17em', // axis_height - 1.5 * rule_thickness
padding: '0 .22em' // nulldelimiterspace + .1 (for line's -.1em margin)
},
'mjx-frac[type="d"]': {
'vertical-align': '.04em' // axis_height - 3.5 * rule_thickness
},
'mjx-frac[delims]': {
padding: '0 .1em' // .1 (for line's -.1em margin)
},
'mjx-frac[atop]': {
padding: '0 .12em' // nulldelimiterspace
},
'mjx-frac[atop][delims]': {
padding: '0'
},
'mjx-dtable': {
display: 'inline-table',
width: '100%'
},
'mjx-dtable > *': {
'font-size': '2000%'
},
'mjx-dbox': {
display: 'block',
'font-size': '5%'
},
'mjx-num': {
display: 'block',
'text-align': 'center'
},
'mjx-den': {
display: 'block',
'text-align': 'center'
},
'mjx-mfrac[bevelled] > mjx-num': {
display: 'inline-block'
},
'mjx-mfrac[bevelled] > mjx-den': {
display: 'inline-block'
},
'mjx-den[align="right"], mjx-num[align="right"]': {
'text-align': 'right'
},
'mjx-den[align="left"], mjx-num[align="left"]': {
'text-align': 'left'
},
'mjx-nstrut': {
display: 'inline-block',
height: '.054em', // num2 - a - 1.5t
width: 0,
'vertical-align': '-.054em' // ditto
},
'mjx-nstrut[type="d"]': {
height: '.217em', // num1 - a - 3.5t
'vertical-align': '-.217em', // ditto
},
'mjx-dstrut': {
display: 'inline-block',
height: '.505em', // denom2 + a - 1.5t
width: 0
},
'mjx-dstrut[type="d"]': {
height: '.726em', // denom1 + a - 3.5t
},
'mjx-line': {
display: 'block',
'box-sizing': 'border-box',
'min-height': '1px',
height: '.06em', // t = rule_thickness
'border-top': '.06em solid', // t
margin: '.06em -.1em', // t
overflow: 'hidden'
},
'mjx-line[type="d"]': {
margin: '.18em -.1em' // 3t
}
};
/**
* An mop element to use for bevelled fractions
*/
public bevel: CHTMLmo<N, T, D>;
/************************************************/
/**
* @override
*/
public toCHTML(parent: N) {
this.standardCHTMLnode(parent);
const {linethickness, bevelled} = this.node.attributes.getList('linethickness', 'bevelled');
const display = this.isDisplay();
if (bevelled) {
this.makeBevelled(display);
} else {
const thickness = this.length2em(String(linethickness), .06);
if (thickness === 0) {
this.makeAtop(display);
} else {
this.makeFraction(display, thickness);
}
}
}
/************************************************/
/**
* @param {boolean} display True when fraction is in display mode
* @param {number} t The rule line thickness
*/
protected makeFraction(display: boolean, t: number) {
const {numalign, denomalign} = this.node.attributes.getList('numalign', 'denomalign');
const withDelims = this.node.getProperty('withDelims');
//
// Attributes to set for the different elements making up the fraction
//
const attr = (display ? {type: 'd'} : {}) as OptionList;
const fattr = (withDelims ? {...attr, delims: 'true'} : {...attr}) as OptionList;
const nattr = (numalign !== 'center' ? {align: numalign} : {}) as OptionList;
const dattr = (denomalign !== 'center' ? {align: denomalign} : {}) as OptionList;
const dsattr = {...attr}, nsattr = {...attr};
//
// Set the styles to handle the linethickness, if needed
//
const tex = this.font.params;
if (t !== .06) {
const a = tex.axis_height;
const tEm = this.em(t);
const {T, u, v} = this.getTUV(display, t);
const m = (display ? this.em(3 * t) : tEm) + ' -.1em';
attr.style = {height: tEm, 'border-top': tEm + ' solid', margin: m};
const nh = this.em(Math.max(0, u));
nsattr.style = {height: nh, 'vertical-align': '-' + nh};
dsattr.style = {height: this.em(Math.max(0, v))};
fattr.style = {'vertical-align': this.em(a - T)};
}
//
// Create the DOM tree
//
let num, den;
this.adaptor.append(this.chtml, this.html('mjx-frac', fattr, [
num = this.html('mjx-num', nattr, [this.html('mjx-nstrut', nsattr)]),
this.html('mjx-dbox', {}, [
this.html('mjx-dtable', {}, [
this.html('mjx-line', attr),
this.html('mjx-row', {}, [
den = this.html('mjx-den', dattr, [this.html('mjx-dstrut', dsattr)])
])
])
])
]));
this.childNodes[0].toCHTML(num);
this.childNodes[1].toCHTML(den);
}
/************************************************/
/**
* @param {boolean} display True when fraction is in display mode
*/
protected makeAtop(display: boolean) {
const {numalign, denomalign} = this.node.attributes.getList('numalign', 'denomalign');
const withDelims = this.node.getProperty('withDelims');
//
// Attributes to set for the different elements making up the fraction
//
const attr = (display ? {type: 'd', atop: true} : {atop: true}) as OptionList;
const fattr = (withDelims ? {...attr, delims: true} : {...attr}) as OptionList;
const nattr = (numalign !== 'center' ? {align: numalign} : {}) as OptionList;
const dattr = (denomalign !== 'center' ? {align: denomalign} : {}) as OptionList;
//
// Determine sparation and positioning
//
const {v, q} = this.getUVQ(display);
nattr.style = {'padding-bottom': this.em(q)};
fattr.style = {'vertical-align': this.em(-v)};
//
// Create the DOM tree
//
let num, den;
this.adaptor.append(this.chtml, this.html('mjx-frac', fattr, [
num = this.html('mjx-num', nattr),
den = this.html('mjx-den', dattr)
]));
this.childNodes[0].toCHTML(num);
this.childNodes[1].toCHTML(den);
}
/************************************************/
/**
* @param {boolean} display True when fraction is in display mode
*/
protected makeBevelled(display: boolean) {
const adaptor = this.adaptor;
//
// Create HTML tree
//
adaptor.setAttribute(this.chtml, 'bevelled', 'ture');
const num = adaptor.append(this.chtml, this.html('mjx-num'));
this.childNodes[0].toCHTML(num);
this.bevel.toCHTML(this.chtml);
const den = adaptor.append(this.chtml, this.html('mjx-den'));
this.childNodes[1].toCHTML(den);
//
// Place the parts
//
const {u, v, delta, nbox, dbox} = this.getBevelData(display);
if (u) {
adaptor.setStyle(num, 'verticalAlign', this.em(u / nbox.scale));
}
if (v) {
adaptor.setStyle(den, 'verticalAlign', this.em(v / dbox.scale));
}
const dx = this.em(-delta / 2);
adaptor.setStyle(this.bevel.chtml, 'marginLeft', dx);
adaptor.setStyle(this.bevel.chtml, 'marginRight', dx);
}
}

View File

@@ -0,0 +1,79 @@
/*************************************************************
*
* Copyright (c) 2018-2022 The MathJax Consortium
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
/**
* @fileoverview Implements the CHTMLmglyph wrapper for the MmlMglyph object
*
* @author dpvc@mathjax.org (Davide Cervone)
*/
import {CHTMLWrapper, CHTMLConstructor} from '../Wrapper.js';
import {CommonMglyphMixin} from '../../common/Wrappers/mglyph.js';
import {MmlMglyph} from '../../../core/MmlTree/MmlNodes/mglyph.js';
import {CHTMLTextNode} from './TextNode.js';
import {StyleList, StyleData} from '../../../util/StyleList.js';
/*****************************************************************/
/**
* The CHTMLmglyph wrapper for the MmlMglyph object
*
* @template N The HTMLElement node class
* @template T The Text node class
* @template D The Document class
*/
// @ts-ignore
export class CHTMLmglyph<N, T, D> extends
CommonMglyphMixin<CHTMLConstructor<any, any, any>>(CHTMLWrapper) {
/**
* The mglyph wrapper
*/
public static kind = MmlMglyph.prototype.kind;
/**
* @override
*/
public static styles: StyleList = {
'mjx-mglyph > img': {
display: 'inline-block',
border: 0,
padding: 0
}
};
/**
* @override
*/
public toCHTML(parent: N) {
const chtml = this.standardCHTMLnode(parent);
if (this.charWrapper) {
(this.charWrapper as CHTMLTextNode<N, T, D>).toCHTML(chtml);
return;
}
const {src, alt} = this.node.attributes.getList('src', 'alt');
const styles: StyleData = {
width: this.em(this.width),
height: this.em(this.height)
};
if (this.valign) {
styles.verticalAlign = this.em(this.valign);
}
const img = this.html('img', {src: src, style: styles, alt: alt, title: alt});
this.adaptor.append(chtml, img);
}
}

View File

@@ -0,0 +1,45 @@
/*************************************************************
*
* Copyright (c) 2017-2022 The MathJax Consortium
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
/**
* @fileoverview Implements the CHTMLmi wrapper for the MmlMi object
*
* @author dpvc@mathjax.org (Davide Cervone)
*/
import {CHTMLWrapper, CHTMLConstructor} from '../Wrapper.js';
import {CommonMiMixin} from '../../common/Wrappers/mi.js';
import {MmlMi} from '../../../core/MmlTree/MmlNodes/mi.js';
/*****************************************************************/
/**
* The CHTMLmi wrapper for the MmlMi object
*
* @template N The HTMLElement node class
* @template T The Text node class
* @template D The Document class
*/
// @ts-ignore
export class CHTMLmi<N, T, D> extends
CommonMiMixin<CHTMLConstructor<any, any, any>>(CHTMLWrapper) {
/**
* The mi wrapper
*/
public static kind = MmlMi.prototype.kind;
}

View File

@@ -0,0 +1,139 @@
/*************************************************************
*
* Copyright (c) 2018-2022 The MathJax Consortium
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
/**
* @fileoverview Implements the CHTMLmmultiscripts wrapper for the MmlMmultiscripts object
*
* @author dpvc@mathjax.org (Davide Cervone)
*/
import {CHTMLWrapper, Constructor} from '../Wrapper.js';
import {CHTMLmsubsup} from './msubsup.js';
import {CommonMmultiscriptsMixin} from '../../common/Wrappers/mmultiscripts.js';
import {MmlMmultiscripts} from '../../../core/MmlTree/MmlNodes/mmultiscripts.js';
import {BBox} from '../../../util/BBox.js';
import {StyleList} from '../../../util/StyleList.js';
import {split} from '../../../util/string.js';
/*****************************************************************/
/**
* The CHTMLmmultiscripts wrapper for the MmlMmultiscripts object
*
* @template N The HTMLElement node class
* @template T The Text node class
* @template D The Document class
*/
// @ts-ignore
export class CHTMLmmultiscripts<N, T, D> extends
CommonMmultiscriptsMixin<CHTMLWrapper<any, any, any>, Constructor<CHTMLmsubsup<any, any, any>>>(CHTMLmsubsup) {
/**
* The mmultiscripts wrapper
*/
public static kind = MmlMmultiscripts.prototype.kind;
/**
* @override
*/
public static styles: StyleList = {
'mjx-prescripts': {
display: 'inline-table',
'padding-left': '.05em' // scriptspace
},
'mjx-scripts': {
display: 'inline-table',
'padding-right': '.05em' // scriptspace
},
'mjx-prescripts > mjx-row > mjx-cell': {
'text-align': 'right'
},
'[script-align="left"] > mjx-row > mjx-cell': {
'text-align': 'left'
},
'[script-align="center"] > mjx-row > mjx-cell': {
'text-align': 'center'
},
'[script-align="right"] > mjx-row > mjx-cell': {
'text-align': 'right'
}
};
/*************************************************************/
/**
* @override
*/
public toCHTML(parent: N) {
const chtml = this.standardCHTMLnode(parent);
const data = this.scriptData;
//
// Get the alignment for the scripts
//
const scriptalign = this.node.getProperty('scriptalign') || 'right left';
const [preAlign, postAlign] = split(scriptalign + ' ' + scriptalign);
//
// Combine the bounding boxes of the pre- and post-scripts,
// and get the resulting baseline offsets
//
const sub = this.combinePrePost(data.sub, data.psub);
const sup = this.combinePrePost(data.sup, data.psup);
const [u, v] = this.getUVQ(sub, sup);
//
// Place the pre-scripts, then the base, then the post-scripts
//
if (data.numPrescripts) {
const scripts = this.addScripts(u, -v, true, data.psub, data.psup, this.firstPrescript, data.numPrescripts);
preAlign !== 'right' && this.adaptor.setAttribute(scripts, 'script-align', preAlign);
}
this.childNodes[0].toCHTML(chtml);
if (data.numScripts) {
const scripts = this.addScripts(u, -v, false, data.sub, data.sup, 1, data.numScripts);
postAlign !== 'left' && this.adaptor.setAttribute(scripts, 'script-align', postAlign);
}
}
/**
* Create a table with the super and subscripts properly separated and aligned.
*
* @param {number} u The baseline offset for the superscripts
* @param {number} v The baseline offset for the subscripts
* @param {boolean} isPre True for prescripts, false for scripts
* @param {BBox} sub The subscript bounding box
* @param {BBox} sup The superscript bounding box
* @param {number} i The starting index for the scripts
* @param {number} n The number of sub/super-scripts
* @return {N} The script table for these scripts
*/
protected addScripts(u: number, v: number, isPre: boolean, sub: BBox, sup: BBox, i: number, n: number): N {
const adaptor = this.adaptor;
const q = (u - sup.d) + (v - sub.h); // separation of scripts
const U = (u < 0 && v === 0 ? sub.h + u : u); // vertical offset of table
const rowdef = (q > 0 ? {style: {height: this.em(q)}} : {});
const tabledef = (U ? {style: {'vertical-align': this.em(U)}} : {});
const supRow = this.html('mjx-row');
const sepRow = this.html('mjx-row', rowdef);
const subRow = this.html('mjx-row');
const name = 'mjx-' + (isPre ? 'pre' : '') + 'scripts';
let m = i + 2 * n;
while (i < m) {
this.childNodes[i++].toCHTML(adaptor.append(subRow, this.html('mjx-cell')) as N);
this.childNodes[i++].toCHTML(adaptor.append(supRow, this.html('mjx-cell')) as N);
}
return adaptor.append(this.chtml, this.html(name, tabledef, [supRow, sepRow, subRow]));
}
}

View File

@@ -0,0 +1,45 @@
/*************************************************************
*
* Copyright (c) 2018-2022 The MathJax Consortium
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
/**
* @fileoverview Implements the CHTMLmn wrapper for the MmlMn object
*
* @author dpvc@mathjax.org (Davide Cervone)
*/
import {CHTMLWrapper, CHTMLConstructor} from '../Wrapper.js';
import {CommonMnMixin} from '../../common/Wrappers/mn.js';
import {MmlMn} from '../../../core/MmlTree/MmlNodes/mn.js';
/*****************************************************************/
/**
* The CHTMLmn wrapper for the MmlMn object
*
* @template N The HTMLElement node class
* @template T The Text node class
* @template D The Document class
*/
// @ts-ignore
export class CHTMLmn<N, T, D> extends
CommonMnMixin<CHTMLConstructor<any, any, any>>(CHTMLWrapper) {
/**
* The mn wrapper
*/
public static kind = MmlMn.prototype.kind;
}

View File

@@ -0,0 +1,211 @@
/*************************************************************
*
* Copyright (c) 2017-2022 The MathJax Consortium
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
/**
* @fileoverview Implements the CHTMLmo wrapper for the MmlMo object
*
* @author dpvc@mathjax.org (Davide Cervone)
*/
import {CHTMLWrapper, CHTMLConstructor, StringMap} from '../Wrapper.js';
import {CommonMoMixin, DirectionVH} from '../../common/Wrappers/mo.js';
import {MmlMo} from '../../../core/MmlTree/MmlNodes/mo.js';
import {StyleList} from '../../../util/StyleList.js';
import {DIRECTION} from '../FontData.js';
/*****************************************************************/
/**
* The CHTMLmo wrapper for the MmlMo object
*
* @template N The HTMLElement node class
* @template T The Text node class
* @template D The Document class
*/
// @ts-ignore
export class CHTMLmo<N, T, D> extends
CommonMoMixin<CHTMLConstructor<any, any, any>>(CHTMLWrapper) {
/**
* The mo wrapper
*/
public static kind = MmlMo.prototype.kind;
/**
* @override
*/
public static styles: StyleList = {
'mjx-stretchy-h': {
display: 'inline-table',
width: '100%'
},
'mjx-stretchy-h > *': {
display: 'table-cell',
width: 0
},
'mjx-stretchy-h > * > mjx-c': {
display: 'inline-block',
transform: 'scalex(1.0000001)' // improves blink positioning
},
'mjx-stretchy-h > * > mjx-c::before': {
display: 'inline-block',
width: 'initial'
},
'mjx-stretchy-h > mjx-ext': {
'/* IE */ overflow': 'hidden',
'/* others */ overflow': 'clip visible',
width: '100%'
},
'mjx-stretchy-h > mjx-ext > mjx-c::before': {
transform: 'scalex(500)'
},
'mjx-stretchy-h > mjx-ext > mjx-c': {
width: 0
},
'mjx-stretchy-h > mjx-beg > mjx-c': {
'margin-right': '-.1em'
},
'mjx-stretchy-h > mjx-end > mjx-c': {
'margin-left': '-.1em'
},
'mjx-stretchy-v': {
display: 'inline-block'
},
'mjx-stretchy-v > *': {
display: 'block'
},
'mjx-stretchy-v > mjx-beg': {
height: 0
},
'mjx-stretchy-v > mjx-end > mjx-c': {
display: 'block'
},
'mjx-stretchy-v > * > mjx-c': {
transform: 'scaley(1.0000001)', // improves Firefox and blink positioning
'transform-origin': 'left center',
overflow: 'hidden'
},
'mjx-stretchy-v > mjx-ext': {
display: 'block',
height: '100%',
'box-sizing': 'border-box',
border: '0px solid transparent',
'/* IE */ overflow': 'hidden',
'/* others */ overflow': 'visible clip',
},
'mjx-stretchy-v > mjx-ext > mjx-c::before': {
width: 'initial',
'box-sizing': 'border-box'
},
'mjx-stretchy-v > mjx-ext > mjx-c': {
transform: 'scaleY(500) translateY(.075em)',
overflow: 'visible'
},
'mjx-mark': {
display: 'inline-block',
height: '0px'
}
};
/**
* @override
*/
public toCHTML(parent: N) {
const attributes = this.node.attributes;
const symmetric = (attributes.get('symmetric') as boolean) && this.stretch.dir !== DIRECTION.Horizontal;
const stretchy = this.stretch.dir !== DIRECTION.None;
if (stretchy && this.size === null) {
this.getStretchedVariant([]);
}
let chtml = this.standardCHTMLnode(parent);
if (stretchy && this.size < 0) {
this.stretchHTML(chtml);
} else {
if (symmetric || attributes.get('largeop')) {
const u = this.em(this.getCenterOffset());
if (u !== '0') {
this.adaptor.setStyle(chtml, 'verticalAlign', u);
}
}
if (this.node.getProperty('mathaccent')) {
this.adaptor.setStyle(chtml, 'width', '0');
this.adaptor.setStyle(chtml, 'margin-left', this.em(this.getAccentOffset()));
}
for (const child of this.childNodes) {
child.toCHTML(chtml);
}
}
}
/**
* Create the HTML for a multi-character stretchy delimiter
*
* @param {N} chtml The parent element in which to put the delimiter
*/
protected stretchHTML(chtml: N) {
const c = this.getText().codePointAt(0);
this.font.delimUsage.add(c);
this.childNodes[0].markUsed();
const delim = this.stretch;
const stretch = delim.stretch;
const content: N[] = [];
//
// Set up the beginning, extension, and end pieces
//
if (stretch[0]) {
content.push(this.html('mjx-beg', {}, [this.html('mjx-c')]));
}
content.push(this.html('mjx-ext', {}, [this.html('mjx-c')]));
if (stretch.length === 4) {
//
// Braces have a middle and second extensible piece
//
content.push(
this.html('mjx-mid', {}, [this.html('mjx-c')]),
this.html('mjx-ext', {}, [this.html('mjx-c')])
);
}
if (stretch[2]) {
content.push(this.html('mjx-end', {}, [this.html('mjx-c')]));
}
//
// Set the styles needed
//
const styles: StringMap = {};
const {h, d, w} = this.bbox;
if (delim.dir === DIRECTION.Vertical) {
//
// Vertical needs an extra (empty) element to get vertical position right
// in some browsers (e.g., Safari)
//
content.push(this.html('mjx-mark'));
styles.height = this.em(h + d);
styles.verticalAlign = this.em(-d);
} else {
styles.width = this.em(w);
}
//
// Make the main element and add it to the parent
//
const dir = DirectionVH[delim.dir];
const properties = {class: this.char(delim.c || c), style: styles};
const html = this.html('mjx-stretchy-' + dir, properties, content);
this.adaptor.append(chtml, html);
}
}

View File

@@ -0,0 +1,103 @@
/*************************************************************
*
* Copyright (c) 2017-2022 The MathJax Consortium
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
/**
* @fileoverview Implements the CHTMLmpadded wrapper for the MmlMpadded object
*
* @author dpvc@mathjax.org (Davide Cervone)
*/
import {CHTMLWrapper, CHTMLConstructor, StringMap} from '../Wrapper.js';
import {CommonMpaddedMixin} from '../../common/Wrappers/mpadded.js';
import {MmlMpadded} from '../../../core/MmlTree/MmlNodes/mpadded.js';
import {StyleList} from '../../../util/StyleList.js';
/*****************************************************************/
/**
* The CHTMLmpadded wrapper for the MmlMpadded object
*
* @template N The HTMLElement node class
* @template T The Text node class
* @template D The Document class
*/
// @ts-ignore
export class CHTMLmpadded<N, T, D> extends
CommonMpaddedMixin<CHTMLConstructor<any, any, any>>(CHTMLWrapper) {
/**
* The mpadded wrapper
*/
public static kind = MmlMpadded.prototype.kind;
/**
* @override
*/
public static styles: StyleList = {
'mjx-mpadded': {
display: 'inline-block'
},
'mjx-rbox': {
display: 'inline-block',
position: 'relative'
}
};
/**
* @override
*/
public toCHTML(parent: N) {
let chtml = this.standardCHTMLnode(parent);
const content: N[] = [];
const style: StringMap = {};
const [ , , W, dh, dd, dw, x, y, dx] = this.getDimens();
//
// If the width changed, set the width explicitly
//
if (dw) {
style.width = this.em(W + dw);
}
//
// If the height or depth changed, use margin to make the change
//
if (dh || dd) {
style.margin = this.em(dh) + ' 0 ' + this.em(dd);
}
//
// If there is a horizontal or vertical shift,
// use relative positioning to move the contents
//
if (x + dx || y) {
style.position = 'relative';
const rbox = this.html('mjx-rbox', {
style: {left: this.em(x + dx), top: this.em(-y), 'max-width': style.width}
});
if (x + dx && this.childNodes[0].getBBox().pwidth) {
this.adaptor.setAttribute(rbox, 'width', 'full');
this.adaptor.setStyle(rbox, 'left', this.em(x));
}
content.push(rbox);
}
//
// Create the HTML with the proper styles and content
//
chtml = this.adaptor.append(chtml, this.html('mjx-block', {style: style}, content)) as N;
for (const child of this.childNodes) {
child.toCHTML(content[0] || chtml);
}
}
}

View File

@@ -0,0 +1,58 @@
/*************************************************************
*
* Copyright (c) 2017-2022 The MathJax Consortium
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
/**
* @fileoverview Implements the CHTMLMroot wrapper for the MmlMroot object
*
* @author dpvc@mathjax.org (Davide Cervone)
*/
import {CHTMLWrapper} from '../Wrapper.js';
import {CHTMLmsqrt} from './msqrt.js';
import {CommonMrootMixin, MrootConstructor} from '../../common/Wrappers/mroot.js';
import {BBox} from '../../../util/BBox.js';
import {MmlMroot} from '../../../core/MmlTree/MmlNodes/mroot.js';
/*****************************************************************/
/**
* The CHTMLmroot wrapper for the MmlMroot object (extends CHTMLmsqrt)
*
* @template N The HTMLElement node class
* @template T The Text node class
* @template D The Document class
*/
export class CHTMLmroot<N, T, D> extends CommonMrootMixin<MrootConstructor>(CHTMLmsqrt) {
/**
* The mroot wrapper
*/
public static kind = MmlMroot.prototype.kind;
/**
* @override
*/
protected addRoot(ROOT: N, root: CHTMLWrapper<N, T, D>, sbox: BBox, H: number) {
root.toCHTML(ROOT);
const [x, h, dx] = this.getRootDimens(sbox, H);
this.adaptor.setStyle(ROOT, 'verticalAlign', this.em(h));
this.adaptor.setStyle(ROOT, 'width', this.em(x));
if (dx) {
this.adaptor.setStyle(this.adaptor.firstChild(ROOT) as N, 'paddingLeft', this.em(dx));
}
}
}

View File

@@ -0,0 +1,89 @@
/*************************************************************
*
* Copyright (c) 2017-2022 The MathJax Consortium
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
/**
* @fileoverview Implements the CHTMLmrow wrapper for the MmlMrow object
*
* @author dpvc@mathjax.org (Davide Cervone)
*/
import {CHTMLWrapper, CHTMLConstructor, Constructor} from '../Wrapper.js';
import {CommonMrowMixin} from '../../common/Wrappers/mrow.js';
import {CommonInferredMrowMixin} from '../../common/Wrappers/mrow.js';
import {MmlMrow, MmlInferredMrow} from '../../../core/MmlTree/MmlNodes/mrow.js';
/*****************************************************************/
/**
* The CHTMLmrow wrapper for the MmlMrow object
*
* @template N The HTMLElement node class
* @template T The Text node class
* @template D The Document class
*/
// @ts-ignore
export class CHTMLmrow<N, T, D> extends
CommonMrowMixin<CHTMLConstructor<any, any, any>>(CHTMLWrapper) {
/**
* The mrow wrapper
*/
public static kind = MmlMrow.prototype.kind;
/**
* @override
*/
public toCHTML(parent: N) {
const chtml = (this.node.isInferred ? (this.chtml = parent) : this.standardCHTMLnode(parent));
let hasNegative = false;
for (const child of this.childNodes) {
child.toCHTML(chtml);
if (child.bbox.w < 0) {
hasNegative = true;
}
}
// FIXME: handle line breaks
if (hasNegative) {
const {w} = this.getBBox();
if (w) {
this.adaptor.setStyle(chtml, 'width', this.em(Math.max(0, w)));
if (w < 0) {
this.adaptor.setStyle(chtml, 'marginRight', this.em(w));
}
}
}
}
}
/*****************************************************************/
/**
* The CHTMLinferredMrow wrapper for the MmlInferredMrow object
*
* @template N The HTMLElement node class
* @template T The Text node class
* @template D The Document class
*/
// @ts-ignore
export class CHTMLinferredMrow<N, T, D> extends
CommonInferredMrowMixin<Constructor<CHTMLmrow<any, any, any>>>(CHTMLmrow) {
/**
* The inferred-mrow wrapper
*/
public static kind = MmlInferredMrow.prototype.kind;
}

View File

@@ -0,0 +1,45 @@
/*************************************************************
*
* Copyright (c) 2017-2022 The MathJax Consortium
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
/**
* @fileoverview Implements the CHTMLms wrapper for the MmlMs object
*
* @author dpvc@mathjax.org (Davide Cervone)
*/
import {CHTMLWrapper, CHTMLConstructor} from '../Wrapper.js';
import {CommonMsMixin} from '../../common/Wrappers/ms.js';
import {MmlMs} from '../../../core/MmlTree/MmlNodes/ms.js';
/*****************************************************************/
/**
* The CHTMLms wrapper for the MmlMs object
*
* @template N The HTMLElement node class
* @template T The Text node class
* @template D The Document class
*/
// @ts-ignore
export class CHTMLms<N, T, D> extends
CommonMsMixin<CHTMLConstructor<any, any, any>>(CHTMLWrapper) {
/**
* The ms wrapper
*/
public static kind = MmlMs.prototype.kind;
}

View File

@@ -0,0 +1,67 @@
/*************************************************************
*
* Copyright (c) 2017-2022 The MathJax Consortium
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
/**
* @fileoverview Implements the CHTMLmspace wrapper for the MmlMspace object
*
* @author dpvc@mathjax.org (Davide Cervone)
*/
import {CHTMLWrapper, CHTMLConstructor} from '../Wrapper.js';
import {CommonMspaceMixin} from '../../common/Wrappers/mspace.js';
import {MmlMspace} from '../../../core/MmlTree/MmlNodes/mspace.js';
/*****************************************************************/
/**
* The CHTMLmspace wrapper for the MmlMspace object
*
* @template N The HTMLElement node class
* @template T The Text node class
* @template D The Document class
*/
// @ts-ignore
export class CHTMLmspace<N, T, D> extends
CommonMspaceMixin<CHTMLConstructor<any, any, any>>(CHTMLWrapper) {
/**
* The mspace wrapper
*/
public static kind = MmlMspace.prototype.kind;
/**
* @override
*/
public toCHTML(parent: N) {
let chtml = this.standardCHTMLnode(parent);
let {w, h, d} = this.getBBox();
if (w < 0) {
this.adaptor.setStyle(chtml, 'marginRight', this.em(w));
w = 0;
}
if (w) {
this.adaptor.setStyle(chtml, 'width', this.em(w));
}
h = Math.max(0, h + d);
if (h) {
this.adaptor.setStyle(chtml, 'height', this.em(Math.max(0, h)));
}
if (d) {
this.adaptor.setStyle(chtml, 'verticalAlign', this.em(-d));
}
}
}

View File

@@ -0,0 +1,125 @@
/*************************************************************
*
* Copyright (c) 2017-2022 The MathJax Consortium
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
/**
* @fileoverview Implements the CHTMLmsqrt wrapper for the MmlMsqrt object
*
* @author dpvc@mathjax.org (Davide Cervone)
*/
import {CHTMLWrapper, CHTMLConstructor} from '../Wrapper.js';
import {CommonMsqrtMixin} from '../../common/Wrappers/msqrt.js';
import {CHTMLmo} from './mo.js';
import {BBox} from '../../../util/BBox.js';
import {MmlMsqrt} from '../../../core/MmlTree/MmlNodes/msqrt.js';
import {StyleList} from '../../../util/StyleList.js';
/*****************************************************************/
/**
* The CHTMLmsqrt wrapper for the MmlMsqrt object
*
* @template N The HTMLElement node class
* @template T The Text node class
* @template D The Document class
*/
export class CHTMLmsqrt<N, T, D> extends CommonMsqrtMixin<CHTMLConstructor<any, any, any>>(CHTMLWrapper) {
/**
* The msqrt wrapper
*/
public static kind = MmlMsqrt.prototype.kind;
/**
* @override
*/
public static styles: StyleList = {
'mjx-root': {
display: 'inline-block',
'white-space': 'nowrap'
},
'mjx-surd': {
display: 'inline-block',
'vertical-align': 'top'
},
'mjx-sqrt': {
display: 'inline-block',
'padding-top': '.07em'
},
'mjx-sqrt > mjx-box': {
'border-top': '.07em solid'
},
'mjx-sqrt.mjx-tall > mjx-box': {
'padding-left': '.3em',
'margin-left': '-.3em'
}
};
/**
* @override
*/
public toCHTML(parent: N) {
const surd = this.childNodes[this.surd] as CHTMLmo<N, T, D>;
const base = this.childNodes[this.base];
//
// Get the parameters for the spacing of the parts
//
const sbox = surd.getBBox();
const bbox = base.getOuterBBox();
const [ , q] = this.getPQ(sbox);
const t = this.font.params.rule_thickness;
const H = bbox.h + q + t;
//
// Create the HTML structure for the root
//
const CHTML = this.standardCHTMLnode(parent);
let SURD, BASE, ROOT, root;
if (this.root != null) {
ROOT = this.adaptor.append(CHTML, this.html('mjx-root')) as N;
root = this.childNodes[this.root];
}
const SQRT = this.adaptor.append(CHTML, this.html('mjx-sqrt', {}, [
SURD = this.html('mjx-surd'),
BASE = this.html('mjx-box', {style: {paddingTop: this.em(q)}})
])) as N;
//
// Add the child content
//
this.addRoot(ROOT, root, sbox, H);
surd.toCHTML(SURD);
base.toCHTML(BASE);
if (surd.size < 0) {
//
// size < 0 means surd is multi-character. The angle glyph at the
// top is hard to align with the horizontal line, so overlap them
// using CSS.
//
this.adaptor.addClass(SQRT, 'mjx-tall');
}
}
/**
* Add root HTML (overridden in mroot)
*
* @param {N} ROOT The container for the root
* @param {CHTMLWrapper} root The wrapped MML root content
* @param {BBox} sbox The bounding box of the surd
* @param {number} H The height of the root as a whole
*/
protected addRoot(_ROOT: N, _root: CHTMLWrapper<N, T, D>, _sbox: BBox, _H: number) {
}
}

View File

@@ -0,0 +1,125 @@
/*************************************************************
*
* Copyright (c) 2017-2022 The MathJax Consortium
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
/**
* @fileoverview Implements the CHTMLmsubsup wrapper for the MmlMsubsup object
* and the special cases CHTMLmsub and CHTMLmsup
*
* @author dpvc@mathjax.org (Davide Cervone)
*/
import {CHTMLWrapper, Constructor} from '../Wrapper.js';
import {CHTMLscriptbase} from './scriptbase.js';
import {CommonMsubMixin} from '../../common/Wrappers/msubsup.js';
import {CommonMsupMixin} from '../../common/Wrappers/msubsup.js';
import {CommonMsubsupMixin} from '../../common/Wrappers/msubsup.js';
import {MmlMsubsup, MmlMsub, MmlMsup} from '../../../core/MmlTree/MmlNodes/msubsup.js';
import {StyleList} from '../../../util/StyleList.js';
/*****************************************************************/
/**
* The CHTMLmsub wrapper for the MmlMsub object
*
* @template N The HTMLElement node class
* @template T The Text node class
* @template D The Document class
*/
// @ts-ignore
export class CHTMLmsub<N, T, D> extends
CommonMsubMixin<CHTMLWrapper<any, any, any>, Constructor<CHTMLscriptbase<any, any, any>>>(CHTMLscriptbase) {
/**
* The msub wrapper
*/
public static kind = MmlMsub.prototype.kind;
}
/*****************************************************************/
/**
* The CHTMLmsup wrapper for the MmlMsup object
*
* @template N The HTMLElement node class
* @template T The Text node class
* @template D The Document class
*/
// @ts-ignore
export class CHTMLmsup<N, T, D> extends
CommonMsupMixin<CHTMLWrapper<any, any, any>, Constructor<CHTMLscriptbase<any, any, any>>>(CHTMLscriptbase) {
/**
* The msup wrapper
*/
public static kind = MmlMsup.prototype.kind;
}
/*****************************************************************/
/**
* The CHTMLmsubsup wrapper for the MmlMsubsup object
*
* @template N The HTMLElement node class
* @template T The Text node class
* @template D The Document class
*/
// @ts-ignore
export class CHTMLmsubsup<N, T, D> extends
CommonMsubsupMixin<CHTMLWrapper<any, any, any>, Constructor<CHTMLscriptbase<any, any, any>>>(CHTMLscriptbase) {
/**
* The msubsup wrapper
*/
public static kind = MmlMsubsup.prototype.kind;
/**
* @override
*/
public static styles: StyleList = {
'mjx-script': {
display: 'inline-block',
'padding-right': '.05em', // scriptspace
'padding-left': '.033em' // extra_ic
},
'mjx-script > mjx-spacer': {
display: 'block'
}
};
/**
* @override
*/
public toCHTML(parent: N) {
const adaptor = this.adaptor;
const chtml = this.standardCHTMLnode(parent);
const [base, sup, sub] = [this.baseChild, this.supChild, this.subChild];
const [ , v, q] = this.getUVQ();
const style = {'vertical-align': this.em(v)};
base.toCHTML(chtml);
const stack = adaptor.append(chtml, this.html('mjx-script', {style})) as N;
sup.toCHTML(stack);
adaptor.append(stack, this.html('mjx-spacer', {style: {'margin-top': this.em(q)}}));
sub.toCHTML(stack);
const ic = this.getAdjustedIc();
if (ic) {
adaptor.setStyle(sup.chtml, 'marginLeft', this.em(ic / sup.bbox.rscale));
}
if (this.baseRemoveIc) {
adaptor.setStyle(stack, 'marginLeft', this.em(-this.baseIc));
}
}
}

View File

@@ -0,0 +1,580 @@
/*************************************************************
*
* Copyright (c) 2017-2022 The MathJax Consortium
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
/**
* @fileoverview Implements the CHTMLmtable wrapper for the MmlMtable object
*
* @author dpvc@mathjax.org (Davide Cervone)
*/
import {CHTMLWrapper, CHTMLConstructor} from '../Wrapper.js';
import {CHTMLWrapperFactory} from '../WrapperFactory.js';
import {CommonMtableMixin} from '../../common/Wrappers/mtable.js';
import {CHTMLmtr} from './mtr.js';
import {CHTMLmtd} from './mtd.js';
import {MmlMtable} from '../../../core/MmlTree/MmlNodes/mtable.js';
import {MmlNode} from '../../../core/MmlTree/MmlNode.js';
import {StyleList} from '../../../util/StyleList.js';
import {isPercent} from '../../../util/string.js';
import {OptionList} from '../../../util/Options.js';
/*****************************************************************/
/**
* The CHTMLmtable wrapper for the MmlMtable object
*
* @template N The HTMLElement node class
* @template T The Text node class
* @template D The Document class
*/
export class CHTMLmtable<N, T, D> extends
CommonMtableMixin<CHTMLmtd<any, any, any>, CHTMLmtr<any, any, any>, CHTMLConstructor<any, any, any>>(CHTMLWrapper) {
/**
* The mtable wrapper
*/
public static kind = MmlMtable.prototype.kind;
/**
* @override
*/
public static styles: StyleList = {
'mjx-mtable': {
'vertical-align': '.25em',
'text-align': 'center',
'position': 'relative',
'box-sizing': 'border-box',
'border-spacing': 0, // prevent this from being inherited from an outer table
'border-collapse': 'collapse' // similarly here
},
'mjx-mstyle[size="s"] mjx-mtable': {
'vertical-align': '.354em'
},
'mjx-labels': {
position: 'absolute',
left: 0,
top: 0
},
'mjx-table': {
'display': 'inline-block',
'vertical-align': '-.5ex',
'box-sizing': 'border-box'
},
'mjx-table > mjx-itable': {
'vertical-align': 'middle',
'text-align': 'left',
'box-sizing': 'border-box'
},
'mjx-labels > mjx-itable': {
position: 'absolute',
top: 0
},
'mjx-mtable[justify="left"]': {
'text-align': 'left'
},
'mjx-mtable[justify="right"]': {
'text-align': 'right'
},
'mjx-mtable[justify="left"][side="left"]': {
'padding-right': '0 ! important'
},
'mjx-mtable[justify="left"][side="right"]': {
'padding-left': '0 ! important'
},
'mjx-mtable[justify="right"][side="left"]': {
'padding-right': '0 ! important'
},
'mjx-mtable[justify="right"][side="right"]': {
'padding-left': '0 ! important'
},
'mjx-mtable[align]': {
'vertical-align': 'baseline'
},
'mjx-mtable[align="top"] > mjx-table': {
'vertical-align': 'top'
},
'mjx-mtable[align="bottom"] > mjx-table': {
'vertical-align': 'bottom'
},
'mjx-mtable[side="right"] mjx-labels': {
'min-width': '100%'
}
};
/**
* The column for labels
*/
public labels: N;
/**
* The inner table DOM node
*/
public itable: N;
/******************************************************************/
/**
* @override
*/
constructor(factory: CHTMLWrapperFactory<N, T, D>, node: MmlNode, parent: CHTMLWrapper<N, T, D> = null) {
super(factory, node, parent);
this.itable = this.html('mjx-itable');
this.labels = this.html('mjx-itable');
}
/**
* @override
*/
public getAlignShift() {
const data = super.getAlignShift();
if (!this.isTop) {
data[1] = 0;
}
return data;
}
/**
* @override
*/
public toCHTML(parent: N) {
//
// Create the rows inside an mjx-itable (which will be used to center the table on the math axis)
//
const chtml = this.standardCHTMLnode(parent);
this.adaptor.append(chtml, this.html('mjx-table', {}, [this.itable]));
for (const child of this.childNodes) {
child.toCHTML(this.itable);
}
//
// Pad the rows of the table, if needed
// Then set the column and row attributes for alignment, spacing, and lines
// Finally, add the frame, if needed
//
this.padRows();
this.handleColumnSpacing();
this.handleColumnLines();
this.handleColumnWidths();
this.handleRowSpacing();
this.handleRowLines();
this.handleRowHeights();
this.handleFrame();
this.handleWidth();
this.handleLabels();
this.handleAlign();
this.handleJustify();
this.shiftColor();
}
/**
* Move background color (if any) to inner itable node so that labeled tables are
* only colored on the main part of the table.
*/
protected shiftColor() {
const adaptor = this.adaptor;
const color = adaptor.getStyle(this.chtml, 'backgroundColor');
if (color) {
adaptor.setStyle(this.chtml, 'backgroundColor', '');
adaptor.setStyle(this.itable, 'backgroundColor', color);
}
}
/******************************************************************/
/**
* Pad any short rows with extra cells
*/
protected padRows() {
const adaptor = this.adaptor;
for (const row of adaptor.childNodes(this.itable) as N[]) {
while (adaptor.childNodes(row).length < this.numCols) {
adaptor.append(row, this.html('mjx-mtd', {'extra': true}));
}
}
}
/**
* Set the inter-column spacing for all columns
* (Use frame spacing on the outsides, if needed, and use half the column spacing on each
* neighboring column, so that if column lines are needed, they fall in the middle
* of the column space.)
*/
protected handleColumnSpacing() {
const scale = (this.childNodes[0] ? 1 / this.childNodes[0].getBBox().rscale : 1);
const spacing = this.getEmHalfSpacing(this.fSpace[0], this.cSpace, scale);
const frame = this.frame;
//
// For each row...
//
for (const row of this.tableRows) {
let i = 0;
//
// For each cell in the row...
//
for (const cell of row.tableCells) {
//
// Get the left and right-hand spacing
//
const lspace = spacing[i++];
const rspace = spacing[i];
//
// Set the style for the spacing, if it is needed, and isn't the
// default already set in the mtd styles
//
const styleNode = (cell ? cell.chtml : this.adaptor.childNodes(row.chtml)[i] as N);
if ((i > 1 && lspace !== '0.4em') || (frame && i === 1)) {
this.adaptor.setStyle(styleNode, 'paddingLeft', lspace);
}
if ((i < this.numCols && rspace !== '0.4em') || (frame && i === this.numCols)) {
this.adaptor.setStyle(styleNode, 'paddingRight', rspace);
}
}
}
}
/**
* Add borders to the left of cells to make the column lines
*/
protected handleColumnLines() {
if (this.node.attributes.get('columnlines') === 'none') return;
const lines = this.getColumnAttributes('columnlines');
for (const row of this.childNodes) {
let i = 0;
for (const cell of this.adaptor.childNodes(row.chtml).slice(1) as N[]) {
const line = lines[i++];
if (line === 'none') continue;
this.adaptor.setStyle(cell, 'borderLeft', '.07em ' + line);
}
}
}
/**
* Add widths to the cells for the column widths
*/
protected handleColumnWidths() {
for (const row of this.childNodes) {
let i = 0;
for (const cell of this.adaptor.childNodes(row.chtml) as N[]) {
const w = this.cWidths[i++];
if (w !== null) {
const width = (typeof w === 'number' ? this.em(w) : w);
this.adaptor.setStyle(cell, 'width', width);
this.adaptor.setStyle(cell, 'maxWidth', width);
this.adaptor.setStyle(cell, 'minWidth', width);
}
}
}
}
/**
* Set the inter-row spacing for all rows
* (Use frame spacing on the outsides, if needed, and use half the row spacing on each
* neighboring row, so that if row lines are needed, they fall in the middle
* of the row space.)
*/
protected handleRowSpacing() {
const scale = (this.childNodes[0] ? 1 / this.childNodes[0].getBBox().rscale : 1);
const spacing = this.getEmHalfSpacing(this.fSpace[1], this.rSpace, scale);
const frame = this.frame;
//
// For each row...
//
let i = 0;
for (const row of this.childNodes) {
//
// Get the top and bottom spacing
//
const tspace = spacing[i++];
const bspace = spacing[i];
//
// For each cell in the row...
//
for (const cell of row.childNodes) {
//
// Set the style for the spacing, if it is needed, and isn't the
// default already set in the mtd styles
//
if ((i > 1 && tspace !== '0.215em') || (frame && i === 1)) {
this.adaptor.setStyle(cell.chtml, 'paddingTop', tspace);
}
if ((i < this.numRows && bspace !== '0.215em') || (frame && i === this.numRows)) {
this.adaptor.setStyle(cell.chtml, 'paddingBottom', bspace);
}
}
}
}
/**
* Add borders to the tops of cells to make the row lines
*/
protected handleRowLines() {
if (this.node.attributes.get('rowlines') === 'none') return;
const lines = this.getRowAttributes('rowlines');
let i = 0;
for (const row of this.childNodes.slice(1)) {
const line = lines[i++];
if (line === 'none') continue;
for (const cell of this.adaptor.childNodes(row.chtml) as N[]) {
this.adaptor.setStyle(cell, 'borderTop', '.07em ' + line);
}
}
}
/**
* Adjust row heights for equal-sized rows
*/
protected handleRowHeights() {
if (this.node.attributes.get('equalrows')) {
this.handleEqualRows();
}
}
/**
* Set the heights of all rows to be the same, and properly center
* baseline or axis rows within the newly sized
*/
protected handleEqualRows() {
const space = this.getRowHalfSpacing();
const {H, D, NH, ND} = this.getTableData();
const HD = this.getEqualRowHeight();
//
// Loop through the rows and set their heights
//
for (let i = 0; i < this.numRows; i++) {
const row = this.childNodes[i];
this.setRowHeight(row, HD + space[i] + space[i + 1] + this.rLines[i]);
if (HD !== NH[i] + ND[i]) {
this.setRowBaseline(row, HD, (HD - H[i] + D[i]) / 2);
}
}
}
/**
* @param {CHTMLWrapper} row The row whose height is to be set
* @param {number} HD The height to be set for the row
*/
protected setRowHeight(row: CHTMLWrapper<N, T, D>, HD: number) {
this.adaptor.setStyle(row.chtml, 'height', this.em(HD));
}
/**
* Make sure the baseline is in the right position for cells
* that are row aligned to baseline ot axis
*
* @param {CHTMLWrapper} row The row to be set
* @param {number} HD The total height+depth for the row
* @param {number] D The new depth for the row
*/
protected setRowBaseline(row: CHTMLWrapper<N, T, D>, HD: number, D: number) {
const ralign = row.node.attributes.get('rowalign') as string;
//
// Loop through the cells and set the strut height and depth.
// The strut is the last element in the cell.
//
for (const cell of row.childNodes) {
if (this.setCellBaseline(cell, ralign, HD, D)) break;
}
}
/**
* Make sure the baseline is in the correct place for cells aligned on baseline or axis
*
* @param {CHTMLWrapper} cell The cell to modify
* @param {string} ralign The alignment of the row
* @param {number} HD The total height+depth for the row
* @param {number] D The new depth for the row
* @return {boolean} True if no other cells in this row need to be processed
*/
protected setCellBaseline(cell: CHTMLWrapper<N, T, D>, ralign: string, HD: number, D: number): boolean {
const calign = cell.node.attributes.get('rowalign');
if (calign === 'baseline' || calign === 'axis') {
const adaptor = this.adaptor;
const child = adaptor.lastChild(cell.chtml) as N;
adaptor.setStyle(child, 'height', this.em(HD));
adaptor.setStyle(child, 'verticalAlign', this.em(-D));
const row = cell.parent;
if ((!row.node.isKind('mlabeledtr') || cell !== row.childNodes[0]) &&
(ralign === 'baseline' || ralign === 'axis')) {
return true;
}
}
return false;
}
/**
* Add a frame to the mtable, if needed
*/
protected handleFrame() {
if (this.frame && this.fLine) {
this.adaptor.setStyle(this.itable, 'border', '.07em ' + this.node.attributes.get('frame'));
}
}
/**
* Handle percentage widths and fixed widths
*/
protected handleWidth() {
const adaptor = this.adaptor;
const {w, L, R} = this.getBBox();
adaptor.setStyle(this.chtml, 'minWidth', this.em(L + w + R));
let W = this.node.attributes.get('width') as string;
if (isPercent(W)) {
adaptor.setStyle(this.chtml, 'width', '');
adaptor.setAttribute(this.chtml, 'width', 'full');
} else if (!this.hasLabels) {
if (W === 'auto') return;
W = this.em(this.length2em(W) + 2 * this.fLine);
}
const table = adaptor.firstChild(this.chtml) as N;
adaptor.setStyle(table, 'width', W);
adaptor.setStyle(table, 'minWidth', this.em(w));
if (L || R) {
adaptor.setStyle(this.chtml, 'margin', '');
const style = (this.node.attributes.get('data-width-includes-label') ? 'padding' : 'margin');
if (L === R) {
adaptor.setStyle(table, style, '0 ' + this.em(R));
} else {
adaptor.setStyle(table, style, '0 ' + this.em(R) + ' 0 ' + this.em(L));
}
}
adaptor.setAttribute(this.itable, 'width', 'full');
}
/**
* Handle alignment of table to surrounding baseline
*/
protected handleAlign() {
const [align, row] = this.getAlignmentRow();
if (row === null) {
if (align !== 'axis') {
this.adaptor.setAttribute(this.chtml, 'align', align);
}
} else {
const y = this.getVerticalPosition(row, align);
this.adaptor.setAttribute(this.chtml, 'align', 'top');
this.adaptor.setStyle(this.chtml, 'verticalAlign', this.em(y));
}
}
/**
* Mark the alignment of the table
*/
protected handleJustify() {
const align = this.getAlignShift()[0];
if (align !== 'center') {
this.adaptor.setAttribute(this.chtml, 'justify', align);
}
}
/******************************************************************/
/**
* Handle addition of labels to the table
*/
protected handleLabels() {
if (!this.hasLabels) return;
const labels = this.labels;
const attributes = this.node.attributes;
const adaptor = this.adaptor;
//
// Set the side for the labels
//
const side = attributes.get('side') as string;
adaptor.setAttribute(this.chtml, 'side', side);
adaptor.setAttribute(labels, 'align', side);
adaptor.setStyle(labels, side, '0');
//
// Make sure labels don't overlap table
//
const [align, shift] = this.addLabelPadding(side);
//
// Handle indentation
//
if (shift) {
const table = adaptor.firstChild(this.chtml) as N;
this.setIndent(table, align, shift);
}
//
// Add the labels to the table
//
this.updateRowHeights();
this.addLabelSpacing();
}
/**
* @param {string} side The side for the labels
* @return {[string, number]} The alignment and shift values
*/
protected addLabelPadding(side: string): [string, number] {
const [ , align, shift] = this.getPadAlignShift(side);
const styles: OptionList = {};
if (side === 'right' && !this.node.attributes.get('data-width-includes-label')) {
const W = this.node.attributes.get('width') as string;
const {w, L, R} = this.getBBox();
styles.style = {
width: (isPercent(W) ? 'calc(' + W + ' + ' + this.em(L + R) + ')' : this.em(L + w + R))
};
}
this.adaptor.append(this.chtml, this.html('mjx-labels', styles, [this.labels]));
return [align, shift] as [string, number];
}
/**
* Update any rows that are not naturally tall enough for the labels,
* and set the baseline for labels that are baseline aligned.
*/
protected updateRowHeights() {
let {H, D, NH, ND} = this.getTableData();
const space = this.getRowHalfSpacing();
for (let i = 0; i < this.numRows; i++) {
const row = this.childNodes[i];
this.setRowHeight(row, H[i] + D[i] + space[i] + space[i + 1] + this.rLines[i]);
if (H[i] !== NH[i] || D[i] !== ND[i]) {
this.setRowBaseline(row, H[i] + D[i], D[i]);
} else if (row.node.isKind('mlabeledtr')) {
this.setCellBaseline(row.childNodes[0], '', H[i] + D[i], D[i]);
}
}
}
/**
* Add spacing elements between the label rows to align them with the rest of the table
*/
protected addLabelSpacing() {
const adaptor = this.adaptor;
const equal = this.node.attributes.get('equalrows') as boolean;
const {H, D} = this.getTableData();
const HD = (equal ? this.getEqualRowHeight() : 0);
const space = this.getRowHalfSpacing();
//
// Start with frame size and add in spacing, height and depth,
// and line thickness for each non-labeled row.
//
let h = this.fLine;
let current = adaptor.firstChild(this.labels) as N;
for (let i = 0; i < this.numRows; i++) {
const row = this.childNodes[i];
if (row.node.isKind('mlabeledtr')) {
h && adaptor.insert(this.html('mjx-mtr', {style: {height: this.em(h)}}), current);
adaptor.setStyle(current, 'height', this.em((equal ? HD : H[i] + D[i]) + space[i] + space[i + 1]));
current = adaptor.next(current) as N;
h = this.rLines[i];
} else {
h += space[i] + (equal ? HD : H[i] + D[i]) + space[i + 1] + this.rLines[i];
}
}
}
}

View File

@@ -0,0 +1,123 @@
/*************************************************************
*
* Copyright (c) 2017-2022 The MathJax Consortium
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
/**
* @fileoverview Implements the CHTMLmtd wrapper for the MmlMtd object
*
* @author dpvc@mathjax.org (Davide Cervone)
*/
import {CHTMLWrapper, CHTMLConstructor} from '../Wrapper.js';
import {CommonMtdMixin} from '../../common/Wrappers/mtd.js';
import {MmlMtd} from '../../../core/MmlTree/MmlNodes/mtd.js';
import {StyleList} from '../../../util/StyleList.js';
/*****************************************************************/
/**
* The CHTMLmtd wrapper for the MmlMtd object
*
* @template N The HTMLElement node class
* @template T The Text node class
* @template D The Document class
*/
// @ts-ignore
export class CHTMLmtd<N, T, D> extends
CommonMtdMixin<CHTMLConstructor<any, any, any>>(CHTMLWrapper) {
/**
* The mtd wrapper
*/
public static kind = MmlMtd.prototype.kind;
/**
* @override
*/
public static styles: StyleList = {
'mjx-mtd': {
display: 'table-cell',
'text-align': 'center',
'padding': '.215em .4em'
},
'mjx-mtd:first-child': {
'padding-left': 0
},
'mjx-mtd:last-child': {
'padding-right': 0
},
'mjx-mtable > * > mjx-itable > *:first-child > mjx-mtd': {
'padding-top': 0
},
'mjx-mtable > * > mjx-itable > *:last-child > mjx-mtd': {
'padding-bottom': 0
},
'mjx-tstrut': {
display: 'inline-block',
height: '1em',
'vertical-align': '-.25em'
},
'mjx-labels[align="left"] > mjx-mtr > mjx-mtd': {
'text-align': 'left'
},
'mjx-labels[align="right"] > mjx-mtr > mjx-mtd': {
'text-align': 'right'
},
'mjx-mtd[extra]': {
padding: 0
},
'mjx-mtd[rowalign="top"]': {
'vertical-align': 'top'
},
'mjx-mtd[rowalign="center"]': {
'vertical-align': 'middle'
},
'mjx-mtd[rowalign="bottom"]': {
'vertical-align': 'bottom'
},
'mjx-mtd[rowalign="baseline"]': {
'vertical-align': 'baseline'
},
'mjx-mtd[rowalign="axis"]': {
'vertical-align': '.25em'
}
};
/**
* @override
*/
public toCHTML(parent: N) {
super.toCHTML(parent);
const ralign = this.node.attributes.get('rowalign') as string;
const calign = this.node.attributes.get('columnalign') as string;
const palign = this.parent.node.attributes.get('rowalign') as string;
if (ralign !== palign) {
this.adaptor.setAttribute(this.chtml, 'rowalign', ralign);
}
if (calign !== 'center' &&
(this.parent.kind !== 'mlabeledtr' || this !== this.parent.childNodes[0] ||
calign !== this.parent.parent.node.attributes.get('side'))) {
this.adaptor.setStyle(this.chtml, 'textAlign', calign);
}
//
// If we are using minimum row heights,
// Include a strut to force minimum height and depth
//
if (this.parent.parent.node.getProperty('useHeight')) {
this.adaptor.append(this.chtml, this.html('mjx-tstrut'));
}
}
}

View File

@@ -0,0 +1,45 @@
/*************************************************************
*
* Copyright (c) 2019-2022 The MathJax Consortium
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
/**
* @fileoverview Implements the CHTMLmtext wrapper for the MmlMtext object
*
* @author dpvc@mathjax.org (Davide Cervone)
*/
import {CHTMLWrapper, CHTMLConstructor} from '../Wrapper.js';
import {CommonMtextMixin} from '../../common/Wrappers/mtext.js';
import {MmlMtext} from '../../../core/MmlTree/MmlNodes/mtext.js';
/*****************************************************************/
/**
* The CHTMLmtext wrapper for the MmlMtext object
*
* @template N The HTMLElement node class
* @template T The Text node class
* @template D The Document class
*/
// @ts-ignore
export class CHTMLmtext<N, T, D> extends
CommonMtextMixin<CHTMLConstructor<any, any, any>>(CHTMLWrapper) {
/**
* The mtext wrapper
*/
public static kind = MmlMtext.prototype.kind;
}

View File

@@ -0,0 +1,153 @@
/*************************************************************
*
* Copyright (c) 2017-2022 The MathJax Consortium
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
/**
* @fileoverview Implements the CHTMLmtr wrapper for the MmlMtr object
* and CHTMLmlabeledtr for MmlMlabeledtr
*
* @author dpvc@mathjax.org (Davide Cervone)
*/
import {CHTMLWrapper, CHTMLConstructor, Constructor} from '../Wrapper.js';
import {CommonMtrMixin} from '../../common/Wrappers/mtr.js';
import {CommonMlabeledtrMixin} from '../../common/Wrappers/mtr.js';
import {CHTMLmtable} from './mtable.js';
import {CHTMLmtd} from './mtd.js';
import {MmlMtr, MmlMlabeledtr} from '../../../core/MmlTree/MmlNodes/mtr.js';
import {StyleList} from '../../../util/StyleList.js';
/*****************************************************************/
/**
* The CHTMLmtr wrapper for the MmlMtr object
*
* @template N The HTMLElement node class
* @template T The Text node class
* @template D The Document class
*/
// @ts-ignore
export class CHTMLmtr<N, T, D> extends
CommonMtrMixin<CHTMLmtd<any, any, any>, CHTMLConstructor<any, any, any>>(CHTMLWrapper) {
/**
* The mtr wrapper
*/
public static kind = MmlMtr.prototype.kind;
/**
* @override
*/
public static styles: StyleList = {
'mjx-mtr': {
display: 'table-row',
},
'mjx-mtr[rowalign="top"] > mjx-mtd': {
'vertical-align': 'top'
},
'mjx-mtr[rowalign="center"] > mjx-mtd': {
'vertical-align': 'middle'
},
'mjx-mtr[rowalign="bottom"] > mjx-mtd': {
'vertical-align': 'bottom'
},
'mjx-mtr[rowalign="baseline"] > mjx-mtd': {
'vertical-align': 'baseline'
},
'mjx-mtr[rowalign="axis"] > mjx-mtd': {
'vertical-align': '.25em'
}
};
/**
* @override
*/
public toCHTML(parent: N) {
super.toCHTML(parent);
const align = this.node.attributes.get('rowalign') as string;
if (align !== 'baseline') {
this.adaptor.setAttribute(this.chtml, 'rowalign', align);
}
}
}
/*****************************************************************/
/**
* The CHTMLlabeledmtr wrapper for the MmlMlabeledtr object
*
* @template N The HTMLElement node class
* @template T The Text node class
* @template D The Document class
*/
export class CHTMLmlabeledtr<N, T, D> extends
CommonMlabeledtrMixin<CHTMLmtd<any, any, any>, Constructor<CHTMLmtr<any, any, any>>>(CHTMLmtr) {
/**
* The mlabeledtr wrapper
*/
public static kind = MmlMlabeledtr.prototype.kind;
/**
* @override
*/
public static styles: StyleList = {
'mjx-mlabeledtr': {
display: 'table-row'
},
'mjx-mlabeledtr[rowalign="top"] > mjx-mtd': {
'vertical-align': 'top'
},
'mjx-mlabeledtr[rowalign="center"] > mjx-mtd': {
'vertical-align': 'middle'
},
'mjx-mlabeledtr[rowalign="bottom"] > mjx-mtd': {
'vertical-align': 'bottom'
},
'mjx-mlabeledtr[rowalign="baseline"] > mjx-mtd': {
'vertical-align': 'baseline'
},
'mjx-mlabeledtr[rowalign="axis"] > mjx-mtd': {
'vertical-align': '.25em'
}
};
/**
* @override
*/
public toCHTML(parent: N) {
super.toCHTML(parent);
const child = this.adaptor.firstChild(this.chtml) as N;
if (child) {
//
// Remove label and put it into the labels box inside a row
//
this.adaptor.remove(child);
const align = this.node.attributes.get('rowalign') as string;
const attr = (align !== 'baseline' && align !== 'axis' ? {rowalign: align} : {});
const row = this.html('mjx-mtr', attr, [child]);
this.adaptor.append((this.parent as CHTMLmtable<N, T, D>).labels, row);
}
}
/**
* @override
*/
public markUsed() {
super.markUsed();
this.jax.wrapperUsage.add(CHTMLmtr.kind);
}
}

View File

@@ -0,0 +1,236 @@
/*************************************************************
*
* Copyright (c) 2017-2022 The MathJax Consortium
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
/**
* @fileoverview Implements the CHTMLmunderover wrapper for the MmlMunderover object
* and the special cases CHTMLmunder and CHTMLmsup
*
* @author dpvc@mathjax.org (Davide Cervone)
*/
import {CHTMLWrapper, Constructor} from '../Wrapper.js';
import {CHTMLmsubsup, CHTMLmsub, CHTMLmsup} from './msubsup.js';
import {CommonMunderMixin} from '../../common/Wrappers/munderover.js';
import {CommonMoverMixin} from '../../common/Wrappers/munderover.js';
import {CommonMunderoverMixin} from '../../common/Wrappers/munderover.js';
import {MmlMunderover, MmlMunder, MmlMover} from '../../../core/MmlTree/MmlNodes/munderover.js';
import {StyleList} from '../../../util/StyleList.js';
/*****************************************************************/
/**
* The CHTMLmunder wrapper for the MmlMunder object
*
* @template N The HTMLElement node class
* @template T The Text node class
* @template D The Document class
*/
// @ts-ignore
export class CHTMLmunder<N, T, D> extends
CommonMunderMixin<CHTMLWrapper<any, any, any>, Constructor<CHTMLmsub<any, any, any>>>(CHTMLmsub) {
/**
* The munder wrapper
*/
public static kind = MmlMunder.prototype.kind;
/**
* @override
*/
public static styles: StyleList = {
'mjx-over': {
'text-align': 'left'
},
'mjx-munder:not([limits="false"])': {
display: 'inline-table',
},
'mjx-munder > mjx-row': {
'text-align': 'left'
},
'mjx-under': {
'padding-bottom': '.1em' // big_op_spacing5
}
};
/**
* @override
*/
public toCHTML(parent: N) {
if (this.hasMovableLimits()) {
super.toCHTML(parent);
this.adaptor.setAttribute(this.chtml, 'limits', 'false');
return;
}
this.chtml = this.standardCHTMLnode(parent);
const base = this.adaptor.append(
this.adaptor.append(this.chtml, this.html('mjx-row')) as N,
this.html('mjx-base')
) as N;
const under = this.adaptor.append(
this.adaptor.append(this.chtml, this.html('mjx-row')) as N,
this.html('mjx-under')
) as N;
this.baseChild.toCHTML(base);
this.scriptChild.toCHTML(under);
const basebox = this.baseChild.getOuterBBox();
const underbox = this.scriptChild.getOuterBBox();
const k = this.getUnderKV(basebox, underbox)[0];
const delta = (this.isLineBelow ? 0 : this.getDelta(true));
this.adaptor.setStyle(under, 'paddingTop', this.em(k));
this.setDeltaW([base, under], this.getDeltaW([basebox, underbox], [0, -delta]));
this.adjustUnderDepth(under, underbox);
}
}
/*****************************************************************/
/**
* The CHTMLmover wrapper for the MmlMover object
*
* @template N The HTMLElement node class
* @template T The Text node class
* @template D The Document class
*/
// @ts-ignore
export class CHTMLmover<N, T, D> extends
CommonMoverMixin<CHTMLWrapper<any, any, any>, Constructor<CHTMLmsup<any, any, any>>>(CHTMLmsup) {
/**
* The mover wrapper
*/
public static kind = MmlMover.prototype.kind;
/**
* @override
*/
public static styles: StyleList = {
'mjx-mover:not([limits="false"])': {
'padding-top': '.1em' // big_op_spacing5
},
'mjx-mover:not([limits="false"]) > *': {
display: 'block',
'text-align': 'left'
}
};
/**
* @override
*/
public toCHTML(parent: N) {
if (this.hasMovableLimits()) {
super.toCHTML(parent);
this.adaptor.setAttribute(this.chtml, 'limits', 'false');
return;
}
this.chtml = this.standardCHTMLnode(parent);
const over = this.adaptor.append(this.chtml, this.html('mjx-over')) as N;
const base = this.adaptor.append(this.chtml, this.html('mjx-base')) as N;
this.scriptChild.toCHTML(over);
this.baseChild.toCHTML(base);
const overbox = this.scriptChild.getOuterBBox();
const basebox = this.baseChild.getOuterBBox();
this.adjustBaseHeight(base, basebox);
const k = this.getOverKU(basebox, overbox)[0];
const delta = (this.isLineAbove ? 0 : this.getDelta());
this.adaptor.setStyle(over, 'paddingBottom', this.em(k));
this.setDeltaW([base, over], this.getDeltaW([basebox, overbox], [0, delta]));
this.adjustOverDepth(over, overbox);
}
}
/*****************************************************************/
/*
* The CHTMLmunderover wrapper for the MmlMunderover object
*
* @template N The HTMLElement node class
* @template T The Text node class
* @template D The Document class
*/
// @ts-ignore
export class CHTMLmunderover<N, T, D> extends
CommonMunderoverMixin<CHTMLWrapper<any, any, any>, Constructor<CHTMLmsubsup<any, any, any>>>(CHTMLmsubsup) {
/**
* The munderover wrapper
*/
public static kind = MmlMunderover.prototype.kind;
/**
* @override
*/
public static styles: StyleList = {
'mjx-munderover:not([limits="false"])': {
'padding-top': '.1em' // big_op_spacing5
},
'mjx-munderover:not([limits="false"]) > *': {
display: 'block'
},
};
/**
* @override
*/
public toCHTML(parent: N) {
if (this.hasMovableLimits()) {
super.toCHTML(parent);
this.adaptor.setAttribute(this.chtml, 'limits', 'false');
return;
}
this.chtml = this.standardCHTMLnode(parent);
const over = this.adaptor.append(this.chtml, this.html('mjx-over')) as N;
const table = this.adaptor.append(
this.adaptor.append(this.chtml, this.html('mjx-box')) as N,
this.html('mjx-munder')
) as N;
const base = this.adaptor.append(
this.adaptor.append(table, this.html('mjx-row')) as N,
this.html('mjx-base')
) as N;
const under = this.adaptor.append(
this.adaptor.append(table, this.html('mjx-row')) as N,
this.html('mjx-under')
) as N;
this.overChild.toCHTML(over);
this.baseChild.toCHTML(base);
this.underChild.toCHTML(under);
const overbox = this.overChild.getOuterBBox();
const basebox = this.baseChild.getOuterBBox();
const underbox = this.underChild.getOuterBBox();
this.adjustBaseHeight(base, basebox);
const ok = this.getOverKU(basebox, overbox)[0];
const uk = this.getUnderKV(basebox, underbox)[0];
const delta = this.getDelta();
this.adaptor.setStyle(over, 'paddingBottom', this.em(ok));
this.adaptor.setStyle(under, 'paddingTop', this.em(uk));
this.setDeltaW([base, under, over],
this.getDeltaW([basebox, underbox, overbox],
[0, this.isLineBelow ? 0 : -delta, this.isLineAbove ? 0 : delta]));
this.adjustOverDepth(over, overbox);
this.adjustUnderDepth(under, underbox);
}
/**
* Make sure styles get output when called from munderover with movable limits
*
* @override
*/
public markUsed() {
super.markUsed();
this.jax.wrapperUsage.add(CHTMLmsubsup.kind);
}
}

View File

@@ -0,0 +1,118 @@
/*************************************************************
*
* Copyright (c) 2017-2022 The MathJax Consortium
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
/**
* @fileoverview Implements the a base class for CHTMLmsubsup, CHTMLmunderover
* and their relatives. (Since munderover can become msubsup
* when movablelimits is set, munderover needs to be able to
* do the same thing as msubsup in some cases.)
*
* @author dpvc@mathjax.org (Davide Cervone)
*/
import {CHTMLWrapper, CHTMLConstructor} from '../Wrapper.js';
import {CommonScriptbaseMixin} from '../../common/Wrappers/scriptbase.js';
import {BBox} from '../../../util/BBox.js';
import {StyleData} from '../../../util/StyleList.js';
/*****************************************************************/
/**
* A base class for msup/msub/msubsup and munder/mover/munderover
* wrapper implementations
*
* @template N The HTMLElement node class
* @template T The Text node class
* @template D The Document class
*/
// @ts-ignore
export class CHTMLscriptbase<N, T, D> extends
CommonScriptbaseMixin<CHTMLWrapper<any, any, any>, CHTMLConstructor<any, any, any>>(CHTMLWrapper) {
/**
* The scriptbase wrapper
*/
public static kind = 'scriptbase';
/**
* This gives the common output for msub and msup. It is overridden
* for all the others (msubsup, munder, mover, munderover).
*
* @override
*/
public toCHTML(parent: N) {
this.chtml = this.standardCHTMLnode(parent);
const [x, v] = this.getOffset();
const dx = x - (this.baseRemoveIc ? this.baseIc : 0);
const style: StyleData = {'vertical-align': this.em(v)};
if (dx) {
style['margin-left'] = this.em(dx);
}
this.baseChild.toCHTML(this.chtml);
this.scriptChild.toCHTML(this.adaptor.append(this.chtml, this.html('mjx-script', {style})) as N);
}
/**
* @param {N[]} nodes The HTML elements to be centered in a stack
* @param {number[]} dx The x offsets needed to center the elements
*/
protected setDeltaW(nodes: N[], dx: number[]) {
for (let i = 0; i < dx.length; i++) {
if (dx[i]) {
this.adaptor.setStyle(nodes[i], 'paddingLeft', this.em(dx[i]));
}
}
}
/**
* @param {N} over The HTML element for the overscript
* @param {BBox} overbox The bbox for the overscript
*/
protected adjustOverDepth(over: N, overbox: BBox) {
if (overbox.d >= 0) return;
this.adaptor.setStyle(over, 'marginBottom', this.em(overbox.d * overbox.rscale));
}
/**
* @param {N} under The HTML element for the underscript
* @param {BBox} underbox The bbox for the underscript
*/
protected adjustUnderDepth(under: N, underbox: BBox) {
if (underbox.d >= 0) return;
const adaptor = this.adaptor;
const v = this.em(underbox.d);
const box = this.html('mjx-box', {style: {'margin-bottom': v, 'vertical-align': v}});
for (const child of adaptor.childNodes(adaptor.firstChild(under) as N) as N[]) {
adaptor.append(box, child);
}
adaptor.append(adaptor.firstChild(under) as N, box);
}
/**
* @param {N} base The HTML element for the base
* @param {BBox} basebox The bbox for the base
*/
protected adjustBaseHeight(base: N, basebox: BBox) {
if (this.node.attributes.get('accent')) {
const minH = this.font.params.x_height * basebox.scale;
if (basebox.h < minH) {
this.adaptor.setStyle(base, 'paddingTop', this.em(minH - basebox.h));
basebox.h = minH;
}
}
}
}

View File

@@ -0,0 +1,174 @@
/*************************************************************
*
* Copyright (c) 2017-2022 The MathJax Consortium
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
/**
* @fileoverview Implements the CHTMLsemantics wrapper for the MmlSemantics object
* and the associated wrappers for annotations
*
* @author dpvc@mathjax.org (Davide Cervone)
*/
import {CHTMLWrapper, CHTMLConstructor} from '../Wrapper.js';
import {CommonSemanticsMixin} from '../../common/Wrappers/semantics.js';
import {BBox} from '../../../util/BBox.js';
import {MmlSemantics, MmlAnnotation, MmlAnnotationXML} from '../../../core/MmlTree/MmlNodes/semantics.js';
import {XMLNode} from '../../../core/MmlTree/MmlNode.js';
import {StyleList} from '../../../util/StyleList.js';
/*****************************************************************/
/**
* The CHTMLsemantics wrapper for the MmlSemantics object
*
* @template N The HTMLElement node class
* @template T The Text node class
* @template D The Document class
*/
// @ts-ignore
export class CHTMLsemantics<N, T, D> extends
CommonSemanticsMixin<CHTMLConstructor<any, any, any>>(CHTMLWrapper) {
/**
* The semantics wrapper
*/
public static kind = MmlSemantics.prototype.kind;
/**
* @override
*/
public toCHTML(parent: N) {
const chtml = this.standardCHTMLnode(parent);
if (this.childNodes.length) {
this.childNodes[0].toCHTML(chtml);
}
}
}
/*****************************************************************/
/**
* The CHTMLannotation wrapper for the MmlAnnotation object
*
* @template N The HTMLElement node class
* @template T The Text node class
* @template D The Document class
*/
export class CHTMLannotation<N, T, D> extends CHTMLWrapper<N, T, D> {
/**
* The annotation wrapper
*/
public static kind = MmlAnnotation.prototype.kind;
/**
* @override
*/
public toCHTML(parent: N) {
// FIXME: output as plain text
super.toCHTML(parent);
}
/**
* @override
*/
public computeBBox() {
// FIXME: compute using the DOM, if possible
return this.bbox;
}
}
/*****************************************************************/
/**
* The CHTMLannotationXML wrapper for the MmlAnnotationXML object
*
* @template N The HTMLElement node class
* @template T The Text node class
* @template D The Document class
*/
export class CHTMLannotationXML<N, T, D> extends CHTMLWrapper<N, T, D> {
/**
* The annotation-xml wrapper
*/
public static kind = MmlAnnotationXML.prototype.kind;
/**
* @override
*/
public static styles: StyleList = {
'mjx-annotation-xml': {
'font-family': 'initial',
'line-height': 'normal'
}
};
}
/*****************************************************************/
/**
* The CHTMLxml wrapper for the XMLNode object
*
* @template N The HTMLElement node class
* @template T The Text node class
* @template D The Document class
*/
export class CHTMLxml<N, T, D> extends CHTMLWrapper<N, T, D> {
/**
* The xml wrapper
*/
public static kind = XMLNode.prototype.kind;
/**
* Don't set up inline-block styles for this
*/
public static autoStyle = false;
/**
* @override
*/
public toCHTML(parent: N) {
this.chtml = this.adaptor.append(parent, this.adaptor.clone((this.node as XMLNode).getXML() as N));
}
/**
* @override
*/
public computeBBox(bbox: BBox, _recompute: boolean = false) {
const {w, h, d} = this.jax.measureXMLnode((this.node as XMLNode).getXML() as N);
bbox.w = w;
bbox.h = h;
bbox.d = d;
}
/**
* @override
*/
protected getStyles() {}
/**
* @override
*/
protected getScale() {}
/**
* @override
*/
protected getVariant() {}
}

Binary file not shown.

Binary file not shown.

371
node_modules/mathjax-full/ts/output/chtml/fonts/tex.ts generated vendored Normal file
View File

@@ -0,0 +1,371 @@
/*************************************************************
*
* Copyright (c) 2017-2022 The MathJax Consortium
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
/**
* @fileoverview The MathJax TeXFont object
*
* @author dpvc@mathjax.org (Davide Cervone)
*/
import {CHTMLFontData, CHTMLCharOptions, CHTMLVariantData, CHTMLDelimiterData, CHTMLFontDataClass,
DelimiterMap, CharMapMap} from '../FontData.js';
import {CommonTeXFontMixin} from '../../common/fonts/tex.js';
import {StringMap} from '../Wrapper.js';
import {boldItalic} from './tex/bold-italic.js';
import {bold} from './tex/bold.js';
import {doubleStruck} from './tex/double-struck.js';
import {frakturBold} from './tex/fraktur-bold.js';
import {fraktur} from './tex/fraktur.js';
import {italic} from './tex/italic.js';
import {largeop} from './tex/largeop.js';
import {monospace} from './tex/monospace.js';
import {normal} from './tex/normal.js';
import {sansSerifBoldItalic} from './tex/sans-serif-bold-italic.js';
import {sansSerifBold} from './tex/sans-serif-bold.js';
import {sansSerifItalic} from './tex/sans-serif-italic.js';
import {sansSerif} from './tex/sans-serif.js';
import {scriptBold} from './tex/script-bold.js';
import {script} from './tex/script.js';
import {smallop} from './tex/smallop.js';
import {texCalligraphicBold} from './tex/tex-calligraphic-bold.js';
import {texCalligraphic} from './tex/tex-calligraphic.js';
import {texMathit} from './tex/tex-mathit.js';
import {texOldstyleBold} from './tex/tex-oldstyle-bold.js';
import {texOldstyle} from './tex/tex-oldstyle.js';
import {texSize3} from './tex/tex-size3.js';
import {texSize4} from './tex/tex-size4.js';
import {texVariant} from './tex/tex-variant.js';
import {delimiters} from '../../common/fonts/tex/delimiters.js';
/*=================================================================================*/
/**
* The TeXFont class
*/
export class TeXFont extends
CommonTeXFontMixin<CHTMLCharOptions, CHTMLVariantData, CHTMLDelimiterData, CHTMLFontDataClass>(CHTMLFontData) {
/**
* Fonts to prefix any explicit ones
*/
protected static defaultCssFamilyPrefix = 'MJXZERO';
/**
* The classes to use for each variant
*/
protected static defaultVariantClasses: StringMap = {
'normal': 'mjx-n',
'bold': 'mjx-b',
'italic': 'mjx-i',
'bold-italic': 'mjx-b mjx-i',
'double-struck': 'mjx-ds mjx-b',
'fraktur': 'mjx-fr',
'bold-fraktur': 'mjx-fr mjx-b',
'script': 'mjx-sc mjx-i',
'bold-script': 'mjx-sc mjx-b mjx-i',
'sans-serif': 'mjx-ss',
'bold-sans-serif': 'mjx-ss mjx-b',
'sans-serif-italic': 'mjx-ss mjx-i',
'sans-serif-bold-italic': 'mjx-ss mjx-b mjx-i',
'monospace': 'mjx-ty',
'-smallop': 'mjx-sop',
'-largeop': 'mjx-lop',
'-size3': 'mjx-s3',
'-size4': 'mjx-s4',
'-tex-calligraphic': 'mjx-cal mjx-i',
'-tex-bold-calligraphic': 'mjx-cal mjx-b',
'-tex-mathit': 'mjx-mit mjx-i',
'-tex-oldstyle': 'mjx-os',
'-tex-bold-oldstyle': 'mjx-os mjx-b',
'-tex-variant': 'mjx-var'
};
/**
* The letters that identify the default font for each varaint
*/
protected static defaultVariantLetters: StringMap = {
'normal': '',
'bold': 'B',
'italic': 'MI',
'bold-italic': 'BI',
'double-struck': 'A',
'fraktur': 'FR',
'bold-fraktur': 'FRB',
'script': 'SC',
'bold-script': 'SCB',
'sans-serif': 'SS',
'bold-sans-serif': 'SSB',
'sans-serif-italic': 'SSI',
'sans-serif-bold-italic': 'SSBI',
'monospace': 'T',
'-smallop': 'S1',
'-largeop': 'S2',
'-size3': 'S3',
'-size4': 'S4',
'-tex-calligraphic': 'C',
'-tex-bold-calligraphic': 'CB',
'-tex-mathit': 'MI',
'-tex-oldstyle': 'C',
'-tex-bold-oldstyle': 'CB',
'-tex-variant': 'A'
};
/**
* The stretchy delimiter data
*/
protected static defaultDelimiters: DelimiterMap<CHTMLDelimiterData> = delimiters;
/**
* The character data by variant
*/
protected static defaultChars: CharMapMap<CHTMLCharOptions> = {
'normal': normal,
'bold': bold,
'italic': italic,
'bold-italic': boldItalic,
'double-struck': doubleStruck,
'fraktur': fraktur,
'bold-fraktur': frakturBold,
'script': script,
'bold-script': scriptBold,
'sans-serif': sansSerif,
'bold-sans-serif': sansSerifBold,
'sans-serif-italic': sansSerifItalic,
'sans-serif-bold-italic': sansSerifBoldItalic,
'monospace': monospace,
'-smallop': smallop,
'-largeop': largeop,
'-size3': texSize3,
'-size4': texSize4,
'-tex-calligraphic': texCalligraphic,
'-tex-bold-calligraphic': texCalligraphicBold,
'-tex-mathit': texMathit,
'-tex-oldstyle': texOldstyle,
'-tex-bold-oldstyle': texOldstyleBold,
'-tex-variant': texVariant
};
/*=====================================================*/
/**
* The CSS styles needed for this font.
*/
protected static defaultStyles = {
...CHTMLFontData.defaultStyles,
'.MJX-TEX': {
'font-family': 'MJXZERO, MJXTEX'
},
'.TEX-B': {
'font-family': 'MJXZERO, MJXTEX-B'
},
'.TEX-I': {
'font-family': 'MJXZERO, MJXTEX-I'
},
'.TEX-MI': {
'font-family': 'MJXZERO, MJXTEX-MI'
},
'.TEX-BI': {
'font-family': 'MJXZERO, MJXTEX-BI'
},
'.TEX-S1': {
'font-family': 'MJXZERO, MJXTEX-S1'
},
'.TEX-S2': {
'font-family': 'MJXZERO, MJXTEX-S2'
},
'.TEX-S3': {
'font-family': 'MJXZERO, MJXTEX-S3'
},
'.TEX-S4': {
'font-family': 'MJXZERO, MJXTEX-S4'
},
'.TEX-A': {
'font-family': 'MJXZERO, MJXTEX-A'
},
'.TEX-C': {
'font-family': 'MJXZERO, MJXTEX-C'
},
'.TEX-CB': {
'font-family': 'MJXZERO, MJXTEX-CB'
},
'.TEX-FR': {
'font-family': 'MJXZERO, MJXTEX-FR'
},
'.TEX-FRB': {
'font-family': 'MJXZERO, MJXTEX-FRB'
},
'.TEX-SS': {
'font-family': 'MJXZERO, MJXTEX-SS'
},
'.TEX-SSB': {
'font-family': 'MJXZERO, MJXTEX-SSB'
},
'.TEX-SSI': {
'font-family': 'MJXZERO, MJXTEX-SSI'
},
'.TEX-SC': {
'font-family': 'MJXZERO, MJXTEX-SC'
},
'.TEX-T': {
'font-family': 'MJXZERO, MJXTEX-T'
},
'.TEX-V': {
'font-family': 'MJXZERO, MJXTEX-V'
},
'.TEX-VB': {
'font-family': 'MJXZERO, MJXTEX-VB'
},
'mjx-stretchy-v mjx-c, mjx-stretchy-h mjx-c': {
'font-family': 'MJXZERO, MJXTEX-S1, MJXTEX-S4, MJXTEX, MJXTEX-A ! important'
}
};
/**
* The default @font-face declarations with %%URL%% where the font path should go
*/
protected static defaultFonts = {
...CHTMLFontData.defaultFonts,
'@font-face /* 1 */': {
'font-family': 'MJXTEX',
src: 'url("%%URL%%/MathJax_Main-Regular.woff") format("woff")'
},
'@font-face /* 2 */': {
'font-family': 'MJXTEX-B',
src: 'url("%%URL%%/MathJax_Main-Bold.woff") format("woff")'
},
'@font-face /* 3 */': {
'font-family': 'MJXTEX-I',
src: 'url("%%URL%%/MathJax_Math-Italic.woff") format("woff")'
},
'@font-face /* 4 */': {
'font-family': 'MJXTEX-MI',
src: 'url("%%URL%%/MathJax_Main-Italic.woff") format("woff")'
},
'@font-face /* 5 */': {
'font-family': 'MJXTEX-BI',
src: 'url("%%URL%%/MathJax_Math-BoldItalic.woff") format("woff")'
},
'@font-face /* 6 */': {
'font-family': 'MJXTEX-S1',
src: 'url("%%URL%%/MathJax_Size1-Regular.woff") format("woff")'
},
'@font-face /* 7 */': {
'font-family': 'MJXTEX-S2',
src: 'url("%%URL%%/MathJax_Size2-Regular.woff") format("woff")'
},
'@font-face /* 8 */': {
'font-family': 'MJXTEX-S3',
src: 'url("%%URL%%/MathJax_Size3-Regular.woff") format("woff")'
},
'@font-face /* 9 */': {
'font-family': 'MJXTEX-S4',
src: 'url("%%URL%%/MathJax_Size4-Regular.woff") format("woff")'
},
'@font-face /* 10 */': {
'font-family': 'MJXTEX-A',
src: 'url("%%URL%%/MathJax_AMS-Regular.woff") format("woff")'
},
'@font-face /* 11 */': {
'font-family': 'MJXTEX-C',
src: 'url("%%URL%%/MathJax_Calligraphic-Regular.woff") format("woff")'
},
'@font-face /* 12 */': {
'font-family': 'MJXTEX-CB',
src: 'url("%%URL%%/MathJax_Calligraphic-Bold.woff") format("woff")'
},
'@font-face /* 13 */': {
'font-family': 'MJXTEX-FR',
src: 'url("%%URL%%/MathJax_Fraktur-Regular.woff") format("woff")'
},
'@font-face /* 14 */': {
'font-family': 'MJXTEX-FRB',
src: 'url("%%URL%%/MathJax_Fraktur-Bold.woff") format("woff")'
},
'@font-face /* 15 */': {
'font-family': 'MJXTEX-SS',
src: 'url("%%URL%%/MathJax_SansSerif-Regular.woff") format("woff")'
},
'@font-face /* 16 */': {
'font-family': 'MJXTEX-SSB',
src: 'url("%%URL%%/MathJax_SansSerif-Bold.woff") format("woff")'
},
'@font-face /* 17 */': {
'font-family': 'MJXTEX-SSI',
src: 'url("%%URL%%/MathJax_SansSerif-Italic.woff") format("woff")'
},
'@font-face /* 18 */': {
'font-family': 'MJXTEX-SC',
src: 'url("%%URL%%/MathJax_Script-Regular.woff") format("woff")'
},
'@font-face /* 19 */': {
'font-family': 'MJXTEX-T',
src: 'url("%%URL%%/MathJax_Typewriter-Regular.woff") format("woff")'
},
'@font-face /* 20 */': {
'font-family': 'MJXTEX-V',
src: 'url("%%URL%%/MathJax_Vector-Regular.woff") format("woff")'
},
'@font-face /* 21 */': {
'font-family': 'MJXTEX-VB',
src: 'url("%%URL%%/MathJax_Vector-Bold.woff") format("woff")'
},
};
}

View File

@@ -0,0 +1,26 @@
/*************************************************************
*
* Copyright (c) 2018-2022 The MathJax Consortium
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
import {CHTMLCharMap, AddCSS} from '../../FontData.js';
import {boldItalic as font} from '../../../common/fonts/tex/bold-italic.js';
export const boldItalic: CHTMLCharMap = AddCSS(font, {
0x131: {f: 'B'},
0x237: {f: 'B'},
0x2044: {c: '/'},
0x2206: {c: '\\394'},
0x29F8: {c: '/'},
});

View File

@@ -0,0 +1,82 @@
/*************************************************************
*
* Copyright (c) 2018-2022 The MathJax Consortium
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
import {CHTMLCharMap, AddCSS} from '../../FontData.js';
import {bold as font} from '../../../common/fonts/tex/bold.js';
export const bold: CHTMLCharMap = AddCSS(font, {
0xB7: {c: '\\22C5'},
0x131: {f: ''},
0x237: {f: ''},
0x2B9: {c: '\\2032'},
0x2002: {c: ''},
0x2003: {c: ''},
0x2004: {c: ''},
0x2005: {c: ''},
0x2006: {c: ''},
0x2009: {c: ''},
0x200A: {c: ''},
0x2015: {c: '\\2014'},
0x2016: {c: '\\2225'},
0x2017: {c: '_'},
0x2022: {c: '\\2219'},
0x2033: {c: '\\2032\\2032'},
0x2034: {c: '\\2032\\2032\\2032'},
0x203E: {c: '\\2C9'},
0x2044: {c: '/'},
0x2057: {c: '\\2032\\2032\\2032\\2032'},
0x20D7: {c: '\\2192', f: 'VB'},
0x219A: {c: '\\2190\\338'},
0x219B: {c: '\\2192\\338'},
0x21AE: {c: '\\2194\\338'},
0x21CD: {c: '\\21D0\\338'},
0x21CE: {c: '\\21D4\\338'},
0x21CF: {c: '\\21D2\\338'},
0x2204: {c: '\\2203\\338'},
0x2206: {c: '\\394'},
0x220C: {c: '\\220B\\338'},
0x2224: {c: '\\2223\\338'},
0x2226: {c: '\\2225\\338'},
0x2241: {c: '\\223C\\338'},
0x2244: {c: '\\2243\\338'},
0x2247: {c: '\\2245\\338'},
0x2249: {c: '\\2248\\338'},
0x2262: {c: '\\2261\\338'},
0x226D: {c: '\\224D\\338'},
0x226E: {c: '<\\338'},
0x226F: {c: '>\\338'},
0x2270: {c: '\\2264\\338'},
0x2271: {c: '\\2265\\338'},
0x2280: {c: '\\227A\\338'},
0x2281: {c: '\\227B\\338'},
0x2284: {c: '\\2282\\338'},
0x2285: {c: '\\2283\\338'},
0x2288: {c: '\\2286\\338'},
0x2289: {c: '\\2287\\338'},
0x22AC: {c: '\\22A2\\338'},
0x22AD: {c: '\\22A8\\338'},
0x22E2: {c: '\\2291\\338'},
0x22E3: {c: '\\2292\\338'},
0x2329: {c: '\\27E8'},
0x232A: {c: '\\27E9'},
0x25B5: {c: '\\25B3'},
0x25BF: {c: '\\25BD'},
0x2758: {c: '\\2223'},
0x29F8: {c: '/', f: 'BI'},
0x2A2F: {c: '\\D7'},
0x3008: {c: '\\27E8'},
0x3009: {c: '\\27E9'},
});

View File

@@ -0,0 +1,17 @@
/*************************************************************
*
* Copyright (c) 2018-2022 The MathJax Consortium
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
export {doubleStruck} from '../../../common/fonts/tex/double-struck.js';

View File

@@ -0,0 +1,22 @@
/*************************************************************
*
* Copyright (c) 2018-2022 The MathJax Consortium
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
import {CHTMLCharMap, AddCSS} from '../../FontData.js';
import {frakturBold as font} from '../../../common/fonts/tex/fraktur-bold.js';
export const frakturBold: CHTMLCharMap = AddCSS(font, {
0x2044: {c: '/'},
});

View File

@@ -0,0 +1,22 @@
/*************************************************************
*
* Copyright (c) 2018-2022 The MathJax Consortium
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
import {CHTMLCharMap, AddCSS} from '../../FontData.js';
import {fraktur as font} from '../../../common/fonts/tex/fraktur.js';
export const fraktur: CHTMLCharMap = AddCSS(font, {
0x2044: {c: '/'},
});

View File

@@ -0,0 +1,28 @@
/*************************************************************
*
* Copyright (c) 2018-2022 The MathJax Consortium
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
import {CHTMLCharMap, AddCSS} from '../../FontData.js';
import {italic as font} from '../../../common/fonts/tex/italic.js';
export const italic: CHTMLCharMap = AddCSS(font, {
0x2F: {f: 'I'},
0x3DD: {c: '\\E008', f: 'A'},
0x2015: {c: '\\2014'},
0x2017: {c: '_'},
0x2044: {c: '/', f: 'I'},
0x2206: {c: '\\394', f: 'I'},
0x29F8: {c: '/', f: 'I'},
});

View File

@@ -0,0 +1,36 @@
/*************************************************************
*
* Copyright (c) 2018-2022 The MathJax Consortium
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
import {CHTMLCharMap, AddCSS} from '../../FontData.js';
import {largeop as font} from '../../../common/fonts/tex/largeop.js';
export const largeop: CHTMLCharMap = AddCSS(font, {
0x2016: {f: 'S1'},
0x2044: {c: '/'},
0x2191: {f: 'S1'},
0x2193: {f: 'S1'},
0x21D1: {f: 'S1'},
0x21D3: {f: 'S1'},
0x2223: {f: 'S1'},
0x2225: {f: 'S1'},
0x2329: {c: '\\27E8'},
0x232A: {c: '\\27E9'},
0x23D0: {f: 'S1'},
0x2758: {c: '\\2223', f: 'S1'},
0x2A0C: {c: '\\222C\\222C'},
0x3008: {c: '\\27E8'},
0x3009: {c: '\\27E9'},
});

View File

@@ -0,0 +1,41 @@
/*************************************************************
*
* Copyright (c) 2018-2022 The MathJax Consortium
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
import {CHTMLCharMap, AddCSS} from '../../FontData.js';
import {monospace as font} from '../../../common/fonts/tex/monospace.js';
export const monospace: CHTMLCharMap = AddCSS(font, {
0x2B9: {c: '\\2032'},
0x391: {c: 'A'},
0x392: {c: 'B'},
0x395: {c: 'E'},
0x396: {c: 'Z'},
0x397: {c: 'H'},
0x399: {c: 'I'},
0x39A: {c: 'K'},
0x39C: {c: 'M'},
0x39D: {c: 'N'},
0x39F: {c: 'O'},
0x3A1: {c: 'P'},
0x3A4: {c: 'T'},
0x3A7: {c: 'X'},
0x2017: {c: '_'},
0x2033: {c: '\\2032\\2032'},
0x2034: {c: '\\2032\\2032\\2032'},
0x2044: {c: '/'},
0x2057: {c: '\\2032\\2032\\2032\\2032'},
0x2206: {c: '\\394'},
});

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,23 @@
/*************************************************************
*
* Copyright (c) 2018-2022 The MathJax Consortium
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
import {CHTMLCharMap, AddCSS} from '../../FontData.js';
import {sansSerifBoldItalic as font} from '../../../common/fonts/tex/sans-serif-bold-italic.js';
export const sansSerifBoldItalic: CHTMLCharMap = AddCSS(font, {
0x131: {f: 'SSB'},
0x237: {f: 'SSB'},
});

View File

@@ -0,0 +1,25 @@
/*************************************************************
*
* Copyright (c) 2018-2022 The MathJax Consortium
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
import {CHTMLCharMap, AddCSS} from '../../FontData.js';
import {sansSerifBold as font} from '../../../common/fonts/tex/sans-serif-bold.js';
export const sansSerifBold: CHTMLCharMap = AddCSS(font, {
0x2015: {c: '\\2014'},
0x2017: {c: '_'},
0x2044: {c: '/'},
0x2206: {c: '\\394'},
});

View File

@@ -0,0 +1,38 @@
/*************************************************************
*
* Copyright (c) 2018-2022 The MathJax Consortium
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
import {CHTMLCharMap, AddCSS} from '../../FontData.js';
import {sansSerifItalic as font} from '../../../common/fonts/tex/sans-serif-italic.js';
export const sansSerifItalic: CHTMLCharMap = AddCSS(font, {
0x391: {c: 'A'},
0x392: {c: 'B'},
0x395: {c: 'E'},
0x396: {c: 'Z'},
0x397: {c: 'H'},
0x399: {c: 'I'},
0x39A: {c: 'K'},
0x39C: {c: 'M'},
0x39D: {c: 'N'},
0x39F: {c: 'O'},
0x3A1: {c: 'P'},
0x3A4: {c: 'T'},
0x3A7: {c: 'X'},
0x2015: {c: '\\2014'},
0x2017: {c: '_'},
0x2044: {c: '/'},
0x2206: {c: '\\394'},
});

View File

@@ -0,0 +1,38 @@
/*************************************************************
*
* Copyright (c) 2018-2022 The MathJax Consortium
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
import {CHTMLCharMap, AddCSS} from '../../FontData.js';
import {sansSerif as font} from '../../../common/fonts/tex/sans-serif.js';
export const sansSerif: CHTMLCharMap = AddCSS(font, {
0x391: {c: 'A'},
0x392: {c: 'B'},
0x395: {c: 'E'},
0x396: {c: 'Z'},
0x397: {c: 'H'},
0x399: {c: 'I'},
0x39A: {c: 'K'},
0x39C: {c: 'M'},
0x39D: {c: 'N'},
0x39F: {c: 'O'},
0x3A1: {c: 'P'},
0x3A4: {c: 'T'},
0x3A7: {c: 'X'},
0x2015: {c: '\\2014'},
0x2017: {c: '_'},
0x2044: {c: '/'},
0x2206: {c: '\\394'},
});

View File

@@ -0,0 +1,17 @@
/*************************************************************
*
* Copyright (c) 2018-2022 The MathJax Consortium
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
export {scriptBold} from '../../../common/fonts/tex/script-bold.js';

View File

@@ -0,0 +1,17 @@
/*************************************************************
*
* Copyright (c) 2018-2022 The MathJax Consortium
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
export {script} from '../../../common/fonts/tex/script.js';

View File

@@ -0,0 +1,28 @@
/*************************************************************
*
* Copyright (c) 2018-2022 The MathJax Consortium
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
import {CHTMLCharMap, AddCSS} from '../../FontData.js';
import {smallop as font} from '../../../common/fonts/tex/smallop.js';
export const smallop: CHTMLCharMap = AddCSS(font, {
0x2044: {c: '/'},
0x2329: {c: '\\27E8'},
0x232A: {c: '\\27E9'},
0x2758: {c: '\\2223'},
0x2A0C: {c: '\\222C\\222C'},
0x3008: {c: '\\27E8'},
0x3009: {c: '\\27E9'},
});

View File

@@ -0,0 +1,23 @@
/*************************************************************
*
* Copyright (c) 2018-2022 The MathJax Consortium
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
import {CHTMLCharMap, AddCSS} from '../../FontData.js';
import {texCalligraphicBold as font} from '../../../common/fonts/tex/tex-calligraphic-bold.js';
export const texCalligraphicBold: CHTMLCharMap = AddCSS(font, {
0x131: {f: 'B'},
0x237: {f: 'B'},
});

View File

@@ -0,0 +1,17 @@
/*************************************************************
*
* Copyright (c) 2018-2022 The MathJax Consortium
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
export {texCalligraphic} from '../../../common/fonts/tex/tex-calligraphic.js';

View File

@@ -0,0 +1,17 @@
/*************************************************************
*
* Copyright (c) 2018-2022 The MathJax Consortium
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
export {texMathit} from '../../../common/fonts/tex/tex-mathit.js';

View File

@@ -0,0 +1,17 @@
/*************************************************************
*
* Copyright (c) 2018-2022 The MathJax Consortium
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
export {texOldstyleBold} from '../../../common/fonts/tex/tex-oldstyle-bold.js';

View File

@@ -0,0 +1,17 @@
/*************************************************************
*
* Copyright (c) 2018-2022 The MathJax Consortium
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
export {texOldstyle} from '../../../common/fonts/tex/tex-oldstyle.js';

View File

@@ -0,0 +1,26 @@
/*************************************************************
*
* Copyright (c) 2018-2022 The MathJax Consortium
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
import {CHTMLCharMap, AddCSS} from '../../FontData.js';
import {texSize3 as font} from '../../../common/fonts/tex/tex-size3.js';
export const texSize3: CHTMLCharMap = AddCSS(font, {
0x2044: {c: '/'},
0x2329: {c: '\\27E8'},
0x232A: {c: '\\27E9'},
0x3008: {c: '\\27E8'},
0x3009: {c: '\\27E9'},
});

View File

@@ -0,0 +1,28 @@
/*************************************************************
*
* Copyright (c) 2018-2022 The MathJax Consortium
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
import {CHTMLCharMap, AddCSS} from '../../FontData.js';
import {texSize4 as font} from '../../../common/fonts/tex/tex-size4.js';
export const texSize4: CHTMLCharMap = AddCSS(font, {
0x2044: {c: '/'},
0x2329: {c: '\\27E8'},
0x232A: {c: '\\27E9'},
0x3008: {c: '\\27E8'},
0x3009: {c: '\\27E9'},
0xE155: {c: '\\E153\\E152'},
0xE156: {c: '\\E151\\E150'},
});

View File

@@ -0,0 +1,37 @@
/*************************************************************
*
* Copyright (c) 2018-2022 The MathJax Consortium
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
import {CHTMLCharMap, AddCSS} from '../../FontData.js';
import {texVariant as font} from '../../../common/fonts/tex/tex-variant.js';
export const texVariant: CHTMLCharMap = AddCSS(font, {
0x3F0: {c: '\\E009'},
0x210F: {f: ''},
0x2224: {c: '\\E006'},
0x2226: {c: '\\E007'},
0x2268: {c: '\\E00C'},
0x2269: {c: '\\E00D'},
0x2270: {c: '\\E011'},
0x2271: {c: '\\E00E'},
0x2288: {c: '\\E016'},
0x2289: {c: '\\E018'},
0x228A: {c: '\\E01A'},
0x228B: {c: '\\E01B'},
0x2A87: {c: '\\E010'},
0x2A88: {c: '\\E00F'},
0x2ACB: {c: '\\E017'},
0x2ACC: {c: '\\E019'},
});