add initial marp implementation with sample content and build configuration
This commit is contained in:
+480
@@ -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
@@ -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
@@ -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
@@ -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);
|
||||
}
|
||||
|
||||
}
|
||||
+58
@@ -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
@@ -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
|
||||
};
|
||||
+64
@@ -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));
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
+89
@@ -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]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
+208
@@ -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);
|
||||
}
|
||||
|
||||
}
|
||||
+156
@@ -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);
|
||||
}
|
||||
|
||||
}
|
||||
+489
@@ -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);
|
||||
}
|
||||
|
||||
}
|
||||
+52
@@ -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);
|
||||
}
|
||||
|
||||
}
|
||||
+275
@@ -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);
|
||||
}
|
||||
|
||||
}
|
||||
+79
@@ -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);
|
||||
}
|
||||
|
||||
}
|
||||
+45
@@ -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;
|
||||
|
||||
}
|
||||
+139
@@ -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]));
|
||||
}
|
||||
|
||||
}
|
||||
+45
@@ -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;
|
||||
|
||||
}
|
||||
+211
@@ -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);
|
||||
}
|
||||
|
||||
}
|
||||
+103
@@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
+58
@@ -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));
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
+89
@@ -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;
|
||||
|
||||
}
|
||||
+45
@@ -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;
|
||||
|
||||
}
|
||||
+67
@@ -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));
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
+125
@@ -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) {
|
||||
}
|
||||
|
||||
}
|
||||
+125
@@ -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));
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
+580
@@ -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];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
+123
@@ -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'));
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
+45
@@ -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;
|
||||
|
||||
}
|
||||
+153
@@ -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);
|
||||
}
|
||||
|
||||
}
|
||||
+236
@@ -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);
|
||||
}
|
||||
|
||||
}
|
||||
+118
@@ -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;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
+174
@@ -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() {}
|
||||
|
||||
}
|
||||
Generated
Vendored
BIN
Binary file not shown.
Generated
Vendored
BIN
Binary file not shown.
Generated
Vendored
BIN
Binary file not shown.
Generated
Vendored
BIN
Binary file not shown.
Generated
Vendored
BIN
Binary file not shown.
Generated
Vendored
BIN
Binary file not shown.
Generated
Vendored
BIN
Binary file not shown.
Generated
Vendored
BIN
Binary file not shown.
Generated
Vendored
BIN
Binary file not shown.
Generated
Vendored
BIN
Binary file not shown.
Generated
Vendored
BIN
Binary file not shown.
Generated
Vendored
BIN
Binary file not shown.
Generated
Vendored
BIN
Binary file not shown.
Generated
Vendored
BIN
Binary file not shown.
Generated
Vendored
BIN
Binary file not shown.
Generated
Vendored
BIN
Binary file not shown.
Generated
Vendored
BIN
Binary file not shown.
Generated
Vendored
BIN
Binary file not shown.
Generated
Vendored
BIN
Binary file not shown.
Generated
Vendored
BIN
Binary file not shown.
Generated
Vendored
BIN
Binary file not shown.
Generated
Vendored
BIN
Binary file not shown.
BIN
Binary file not shown.
+371
@@ -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")'
|
||||
},
|
||||
};
|
||||
|
||||
}
|
||||
+26
@@ -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: '/'},
|
||||
});
|
||||
+82
@@ -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'},
|
||||
});
|
||||
+17
@@ -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';
|
||||
+22
@@ -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: '/'},
|
||||
});
|
||||
+22
@@ -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: '/'},
|
||||
});
|
||||
+28
@@ -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'},
|
||||
});
|
||||
+36
@@ -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'},
|
||||
});
|
||||
+41
@@ -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'},
|
||||
});
|
||||
+1043
File diff suppressed because it is too large
Load Diff
+23
@@ -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'},
|
||||
});
|
||||
+25
@@ -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'},
|
||||
});
|
||||
+38
@@ -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'},
|
||||
});
|
||||
+38
@@ -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'},
|
||||
});
|
||||
+17
@@ -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';
|
||||
+17
@@ -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';
|
||||
+28
@@ -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'},
|
||||
});
|
||||
+23
@@ -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'},
|
||||
});
|
||||
+17
@@ -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';
|
||||
+17
@@ -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';
|
||||
+17
@@ -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';
|
||||
+17
@@ -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';
|
||||
+26
@@ -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'},
|
||||
});
|
||||
+28
@@ -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'},
|
||||
});
|
||||
+37
@@ -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'},
|
||||
});
|
||||
Reference in New Issue
Block a user