Actualización

This commit is contained in:
Xes
2025-04-10 11:37:29 +02:00
parent 4bfeadb360
commit 8969cc929d
39112 changed files with 975884 additions and 0 deletions

View File

@@ -0,0 +1,63 @@
/* -*- Mode: Javascript; indent-tabs-mode:nil; js-indent-level: 2 -*- */
/* vim: set ts=2 et sw=2 tw=80: */
/*************************************************************
*
* MathJax/jax/output/HTML-CSS/autoload/annotation-xm;l.js
*
* Implements the HTML-CSS output for <annotation-xml> elements.
*
* ---------------------------------------------------------------------
*
* Copyright (c) 2011-2020 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.
*/
MathJax.Hub.Register.StartupHook("HTML-CSS Jax Ready",function () {
var VERSION = "2.7.8";
var MML = MathJax.ElementJax.mml,
HTMLCSS = MathJax.OutputJax["HTML-CSS"];
MML["annotation-xml"].Augment({
toHTML: function (span) {
span = this.HTMLhandleSize(this.HTMLcreateSpan(span));
var encoding = this.Get("encoding");
for (var i = 0, m = this.data.length; i < m; i++)
{this.data[i].toHTML(span,encoding)}
this.HTMLhandleSpace(span);
this.HTMLhandleColor(span);
return span;
},
HTMLgetScale: function () {
return this.SUPER(arguments).HTMLgetScale.call(this) / HTMLCSS.scale;
}
});
MML.xml.Augment({
toHTML: function (span,encoding) {
for (var i = 0, m = this.data.length; i < m; i++)
{span.appendChild(this.data[i].cloneNode(true))}
var bbox = span.bbox; span.bbox = null;
bbox.rw = bbox.w = HTMLCSS.getW(span);
var HD = HTMLCSS.getHD(span);
bbox.h = HD.h; bbox.d = HD.d;
span.bbox = bbox;
}
});
MathJax.Hub.Startup.signal.Post("HTML-CSS annotation-xml Ready");
MathJax.Ajax.loadComplete(HTMLCSS.autoloadDir+"/annotation-xml.js");
});

View File

@@ -0,0 +1,229 @@
/* -*- Mode: Javascript; indent-tabs-mode:nil; js-indent-level: 2 -*- */
/* vim: set ts=2 et sw=2 tw=80: */
/*************************************************************
*
* MathJax/jax/output/HTML-CSS/autoload/maction.js
*
* Implements the HTML-CSS output for <maction> elements.
*
* ---------------------------------------------------------------------
*
* Copyright (c) 2010-2020 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.
*/
MathJax.Hub.Register.StartupHook("HTML-CSS Jax Ready",function () {
var VERSION = "2.7.8";
var MML = MathJax.ElementJax.mml,
HTMLCSS = MathJax.OutputJax["HTML-CSS"];
var currentTip, hover, clear;
//
// Add configuration for tooltips
//
var CONFIG = HTMLCSS.config.tooltip = MathJax.Hub.Insert({
delayPost: 600, delayClear: 600,
offsetX: 10, offsetY: 5
},HTMLCSS.config.tooltip||{});
MML.maction.Augment({
HTMLtooltip: HTMLCSS.addElement(document.body,"div",{id:"MathJax_Tooltip"}),
toHTML: function (span,HW,D) {
var selected = this.selected();
if (selected.type == "null") {
span = this.HTMLcreateSpan(span);
span.bbox = this.HTMLzeroBBox();
return span;
}
span = this.HTMLcreateSpan(span); span.bbox = null;
span.scale = this.HTMLgetScale();
var box = selected.toHTML(span);
if (D != null) {HTMLCSS.Remeasured(selected.HTMLstretchV(span,HW,D),span)}
else if (HW != null) {
HTMLCSS.Remeasured(selected.HTMLstretchH(span,HW),span)
} else {HTMLCSS.Measured(box,span)}
this.HTMLhandleHitBox(span);
this.HTMLhandleSpace(span);
this.HTMLhandleColor(span);
return span;
},
HTMLhandleHitBox: function (span,postfix) {
var frame;
if (HTMLCSS.msieHitBoxBug) {
// margin-left doesn't work on inline-block elements in IE, so put it in a SPAN
var box = HTMLCSS.addElement(span,"span",{isMathJax:true});
frame = HTMLCSS.createFrame(box,span.bbox.h,span.bbox.d,span.bbox.w,0,"none");
span.insertBefore(box,span.firstChild); // move below the content
box.style.marginRight = HTMLCSS.Em(-span.bbox.w);
if (HTMLCSS.msieInlineBlockAlignBug)
{frame.style.verticalAlign = HTMLCSS.Em(HTMLCSS.getHD(span).d-span.bbox.d)}
} else {
frame = HTMLCSS.createFrame(span,span.bbox.h,span.bbox.d,span.bbox.w,0,"none");
span.insertBefore(frame,span.firstChild); // move below the content
frame.style.marginRight = HTMLCSS.Em(-span.bbox.w);
}
frame.className = "MathJax_HitBox";
frame.id = "MathJax-HitBox-" + this.spanID + (postfix||"") + HTMLCSS.idPostfix;
var type = this.Get("actiontype");
if (this.HTMLaction[type]) {this.HTMLaction[type].call(this,span,frame,this.Get("selection"))}
},
HTMLstretchH: MML.mbase.HTMLstretchH,
HTMLstretchV: MML.mbase.HTMLstretchV,
//
// Implementations for the various actions
//
HTMLaction: {
toggle: function (span,frame,selection) {
this.selection = selection;
span.onclick = MathJax.Callback(["HTMLclick",this]);
frame.style.cursor = span.childNodes[1].style.cursor = "pointer";
},
statusline: function (span,frame,selection) {
span.onmouseover = MathJax.Callback(["HTMLsetStatus",this]);
span.onmouseout = MathJax.Callback(["HTMLclearStatus",this]);
span.onmouseover.autoReset = span.onmouseout.autoReset = true;
frame.style.cursor = span.childNodes[1].style.cursor = "default";
},
tooltip: function(span,frame,selection) {
if (this.data[1] && this.data[1].isToken) {
span.title = span.alt = this.data[1].data.join("");
} else {
span.onmouseover = MathJax.Callback(["HTMLtooltipOver",this]);
span.onmouseout = MathJax.Callback(["HTMLtooltipOut",this]);
span.onmouseover.autoReset = span.onmouseout.autoReset = true;
}
frame.style.cursor = span.childNodes[1].style.cursor = "default";
}
},
//
// Handle a click on the maction element
// (remove the original rendering and rerender)
//
HTMLclick: function (event) {
this.selection++;
if (this.selection > this.data.length) {this.selection = 1}
var math = this; while (math.type !== "math") {math = math.inherit}
var jax = MathJax.Hub.getJaxFor(math.inputID), hover = !!jax.hover;
jax.Update();
if (hover) {
var span = document.getElementById(jax.inputID+"-Span");
MathJax.Extension.MathEvents.Hover.Hover(jax,span);
}
return MathJax.Extension.MathEvents.Event.False(event);
},
//
// Set/Clear the window status message
//
HTMLsetStatus: function (event) {
// FIXME: Do something better with non-token elements
this.messageID = MathJax.Message.Set
((this.data[1] && this.data[1].isToken) ?
this.data[1].data.join("") : this.data[1].toString());
},
HTMLclearStatus: function (event) {
if (this.messageID) {MathJax.Message.Clear(this.messageID,0)}
delete this.messageID;
},
//
// Handle tooltips
//
HTMLtooltipOver: function (event) {
if (!event) {event = window.event}
if (clear) {clearTimeout(clear); clear = null}
if (hover) {clearTimeout(hover)}
var x = event.pageX; var y = event.pageY;
if (x == null) {
x = event.clientX + document.body.scrollLeft + document.documentElement.scrollLeft;
y = event.clientY + document.body.scrollTop + document.documentElement.scrollTop;
}
var callback = MathJax.Callback(["HTMLtooltipPost",this,x+CONFIG.offsetX,y+CONFIG.offsetY])
hover = setTimeout(callback,CONFIG.delayPost);
},
HTMLtooltipOut: function (event) {
if (hover) {clearTimeout(hover); hover = null}
if (clear) {clearTimeout(clear)}
var callback = MathJax.Callback(["HTMLtooltipClear",this,80]);
clear = setTimeout(callback,CONFIG.delayClear);
},
HTMLtooltipPost: function (x,y) {
hover = null; if (clear) {clearTimeout(clear); clear = null}
var tip = this.HTMLtooltip;
tip.style.display = "block"; tip.style.opacity = "";
tip.style.filter = HTMLCSS.config.styles["#MathJax_Tooltip"].filter;
if (this === currentTip) return;
tip.style.left = x+"px"; tip.style.top = y+"px";
tip.innerHTML = '<span class="MathJax"><nobr></nobr></span>';
//
// get em sizes (taken from HTMLCSS.preTranslate)
//
var emex = tip.insertBefore(HTMLCSS.TestSpan.cloneNode(true),tip.firstChild);
var ex = emex.childNodes[1].offsetHeight/60,
em = emex.childNodes[2].offsetHeight/60;
emex.parentNode.removeChild(emex);
HTMLCSS.em = HTMLCSS.outerEm = MML.mbase.prototype.em = em;
var scale = Math.floor(Math.max(HTMLCSS.config.minScaleAdjust/100,(ex/HTMLCSS.TeX.x_height)/em) * HTMLCSS.config.scale);
tip.firstChild.style.fontSize = scale+"%";
var stack = HTMLCSS.createStack(tip.firstChild.firstChild);
var box = HTMLCSS.createBox(stack);
try {HTMLCSS.Measured(this.data[1].toHTML(box),box)} catch(err) {
if (!err.restart) {throw err}
tip.style.display = "none";
MathJax.Callback.After(["HTMLtooltipPost",this,x,y],err.restart);
return;
}
HTMLCSS.placeBox(box,0,0);
HTMLCSS.createRule(tip.firstChild.firstChild,box.bbox.h,box.bbox.d,0);
currentTip = this;
},
HTMLtooltipClear: function (n) {
var tip = this.HTMLtooltip;
if (n <= 0) {
tip.style.display = "none";
tip.style.opacity = tip.style.filter = "";
clear = null;
} else {
tip.style.opacity = n/100;
tip.style.filter = "alpha(opacity="+n+")";
clear = setTimeout(MathJax.Callback(["HTMLtooltipClear",this,n-20]),50);
}
}
});
//
// Do browser-specific setup
//
MathJax.Hub.Browser.Select({
MSIE: function (browser) {
HTMLCSS.msieHitBoxBug = true;
}
});
MathJax.Hub.Startup.signal.Post("HTML-CSS maction Ready");
MathJax.Ajax.loadComplete(HTMLCSS.autoloadDir+"/maction.js");
});

View File

@@ -0,0 +1,339 @@
/* -*- Mode: Javascript; indent-tabs-mode:nil; js-indent-level: 2 -*- */
/* vim: set ts=2 et sw=2 tw=80: */
/*************************************************************
*
* MathJax/jax/output/HTML-CSS/autoload/menclose.js
*
* Implements the HTML-CSS output for <menclose> elements.
*
* ---------------------------------------------------------------------
*
* Copyright (c) 2010-2020 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.
*/
MathJax.Hub.Register.StartupHook("HTML-CSS Jax Ready",function () {
var VERSION = "2.7.8";
var MML = MathJax.ElementJax.mml,
HTMLCSS = MathJax.OutputJax["HTML-CSS"];
var SVGNS = "http://www.w3.org/2000/svg";
var VMLNS = "urn:schemas-microsoft-com:vml";
var vmlns = "mjxvml";
MML.menclose.Augment({
toHTML: function (span) {
var values = this.getValues("notation","thickness","padding","mathcolor","color");
if (values.color && !this.mathcolor) {values.mathcolor = values.color}
if (values.thickness == null) {values.thickness = ".075em"}
if (values.padding == null) {values.padding = ".2em"}
span = this.HTMLcreateSpan(span);
var mu = this.HTMLgetMu(span), scale = this.HTMLgetScale();
var p = HTMLCSS.length2em(values.padding,mu,1/HTMLCSS.em) * scale; // padding for enclosure
var t = HTMLCSS.length2em(values.thickness,mu,1/HTMLCSS.em) * scale; // thickness of lines
t = Math.max(1/HTMLCSS.em,t); // see issue #414
var SOLID = HTMLCSS.Em(t)+" solid";
var stack = HTMLCSS.createStack(span);
var base = HTMLCSS.createBox(stack);
this.HTMLmeasureChild(0,base);
var H = base.bbox.h+p+t, D = base.bbox.d+p+t, W = base.bbox.w+2*(p+t);
var frame = HTMLCSS.createFrame(stack,H+D,0,W,t,"none");
frame.id = "MathJax-frame-"+this.spanID;
HTMLCSS.addBox(stack,frame); stack.insertBefore(frame,base); // move base to above background
var T = 0, B = 0, R = 0, L = 0, dx = 0, dy = 0; var svg, vml;
var w, h, r;
if (!values.mathcolor) {values.mathcolor = "currentColor"} else {span.style.color = values.mathcolor}
// perform some reduction e.g. eliminate duplicate notations.
var nl = MathJax.Hub.SplitList(values.notation), notation = {};
for (var i = 0, m = nl.length; i < m; i++) notation[nl[i]] = true;
if (notation[MML.NOTATION.UPDIAGONALARROW]) notation[MML.NOTATION.UPDIAGONALSTRIKE] = false;
var line;
for (var n in notation) {
if (!notation.hasOwnProperty(n) || !notation[n]) continue;
switch (n) {
case MML.NOTATION.BOX:
frame.style.border = SOLID; if (!HTMLCSS.msieBorderWidthBug) {T = B = L = R = t}
break;
case MML.NOTATION.ROUNDEDBOX:
if (HTMLCSS.useVML) {
if (!vml) {vml = this.HTMLvml(stack,H,D,W,t,values.mathcolor)}
// roundrect.arcsize can't be set in IE8 standards mode, so use a path
r = Math.floor(1000*Math.min(W,H+D)-2*t);
w = Math.floor(4000*(W-2*t)), h = Math.floor(4000*(H+D-2*t));
this.HTMLvmlElement(vml,"shape",{
style: {width:this.HTMLpx(W-2*t),height:this.HTMLpx(H+D-2*t),
left:this.HTMLpx(t,.5),top:this.HTMLpx(t,.5)},
path: "m "+r+",0 qx 0,"+r+" l 0,"+(h-r)+" qy "+r+","+h+" "+
"l "+(w-r)+","+h+" qx "+w+","+(h-r)+" l "+w+","+r+" qy "+(w-r)+",0 x e",
coordsize: w+","+h
});
} else {
if (!svg) {svg = this.HTMLsvg(stack,H,D,W,t,values.mathcolor)}
this.HTMLsvgElement(svg.firstChild,"rect",{
x:1, y:1, width:this.HTMLpx(W-t)-1,
height:this.HTMLpx(H+D-t)-1, rx:this.HTMLpx(Math.min(H+D,W)/4)
});
}
break;
case MML.NOTATION.CIRCLE:
if (HTMLCSS.useVML) {
if (!vml) {vml = this.HTMLvml(stack,H,D,W,t,values.mathcolor)}
this.HTMLvmlElement(vml,"oval",{
style: {width:this.HTMLpx(W-2*t),height:this.HTMLpx(H+D-2*t),
left:this.HTMLpx(t,.5),top:this.HTMLpx(t,.5)}
});
} else {
if (!svg) {svg = this.HTMLsvg(stack,H,D,W,t,values.mathcolor)}
this.HTMLsvgElement(svg.firstChild,"ellipse",{
rx:this.HTMLpx(W/2-t), ry:this.HTMLpx((H+D)/2-t),
cx:this.HTMLpx(W/2), cy:this.HTMLpx((H+D)/2)
});
}
break;
case MML.NOTATION.LEFT:
frame.style.borderLeft = SOLID; if (!HTMLCSS.msieBorderWidthBug) {L = t}
break;
case MML.NOTATION.ACTUARIAL:
frame.style.borderTop = SOLID; if (!HTMLCSS.msieBorderWidthBug) {T = t; frame.bbox.w += p-t}
case MML.NOTATION.RIGHT:
frame.style.borderRight = SOLID; if (!HTMLCSS.msieBorderWidthBug) {R = t}
break;
case MML.NOTATION.VERTICALSTRIKE:
line = HTMLCSS.createRule(stack,H+D-t/2,0,t);
HTMLCSS.addBox(stack,line); HTMLCSS.placeBox(line,p+t+base.bbox.w/2,-D,true);
break;
case MML.NOTATION.TOP:
frame.style.borderTop = SOLID; if (!HTMLCSS.msieBorderWidthBug) {T = t}
break;
case MML.NOTATION.BOTTOM:
frame.style.borderBottom = SOLID; if (!HTMLCSS.msieBorderWidthBug) {B = t}
break;
case MML.NOTATION.HORIZONTALSTRIKE:
line = HTMLCSS.createRule(stack,t,0,W-t/2);
HTMLCSS.addBox(stack,line); HTMLCSS.placeBox(line,0,(H+D)/2-D,true);
break;
case MML.NOTATION.UPDIAGONALSTRIKE:
if (HTMLCSS.useVML) {
if (!vml) {vml = this.HTMLvml(stack,H,D,W,t,values.mathcolor)}
line = this.HTMLvmlElement(vml,"line",{from: "0,"+this.HTMLpx(H+D-t), to: this.HTMLpx(W)+",0"});
} else {
if (!svg) {svg = this.HTMLsvg(stack,H,D,W,t,values.mathcolor)}
this.HTMLsvgElement(svg.firstChild,"line",{
x1:1, y1:this.HTMLpx(H+D-t), x2:this.HTMLpx(W-t), y2:this.HTMLpx(t)
});
}
break;
case MML.NOTATION.UPDIAGONALARROW:
if (HTMLCSS.useVML) {
if (!vml) {vml = this.HTMLvml(stack,H,D,W,t,values.mathcolor)}
line = this.HTMLvmlElement(vml,"line",{from: "0,"+this.HTMLpx(H+D-t), to: this.HTMLpx(W)+","+this.HTMLpx(t)});
this.HTMLvmlElement(line,"stroke",{endarrow:"classic"});
} else {
if (!svg) {svg = this.HTMLsvg(stack,H,D,W,t,values.mathcolor)}
var l = Math.sqrt(W*W + (H+D)*(H+D)), f = 1/l * 10*this.scale/HTMLCSS.em * t/.075;
w = W * f; h = (H+D) * f; var x = W - t/2, y = t/2;
if (y+h-.4*w < 0) {y = .4*w-h}
this.HTMLsvgElement(svg.firstChild,"line",{
x1:1, y1:this.HTMLpx(H+D-t), x2:this.HTMLpx(x-.7*w), y2:this.HTMLpx(y+.7*h)
});
this.HTMLsvgElement(svg.firstChild,"polygon",{
points: this.HTMLpx(x)+","+this.HTMLpx(y)+" "
+this.HTMLpx(x-w-.4*h)+","+this.HTMLpx(y+h-.4*w)+" "
+this.HTMLpx(x-.7*w)+","+this.HTMLpx(y+.7*h)+" "
+this.HTMLpx(x-w+.4*h)+","+this.HTMLpx(y+h+.4*w)+" "
+this.HTMLpx(x)+","+this.HTMLpx(y),
fill:values.mathcolor, stroke:"none"
});
}
break;
case MML.NOTATION.DOWNDIAGONALSTRIKE:
if (HTMLCSS.useVML) {
if (!vml) {vml = this.HTMLvml(stack,H,D,W,t,values.mathcolor)}
this.HTMLvmlElement(vml,"line",{from: "0,0", to: this.HTMLpx(W)+","+this.HTMLpx(H+D-t)});
} else {
if (!svg) {svg = this.HTMLsvg(stack,H,D,W,t,values.mathcolor)}
this.HTMLsvgElement(svg.firstChild,"line",{
x1:1, y1:this.HTMLpx(t), x2:this.HTMLpx(W-t), y2:this.HTMLpx(H+D-t)
});
}
break;
case MML.NOTATION.PHASORANGLE:
W -= 2*p; p = (H+D)/2; W += p;
if (HTMLCSS.useVML) {
if (!vml) {vml = this.HTMLvml(stack,H,D,W,t,values.mathcolor)}
this.HTMLvmlElement(vml,"shape",{
style: {width:this.HTMLpx(W), height:this.HTMLpx(H+D)},
path: "m "+this.HTMLpt(p+t/2,t/2)+
" l "+this.HTMLpt(t/2,H+D-t)+" "+this.HTMLpt(W-t/2,H+D-t)+" e",
coordsize: this.HTMLpt(W,H+D)
});
} else {
if (!svg) {svg = this.HTMLsvg(stack,H,D,W,t,values.mathcolor)}
this.HTMLsvgElement(svg.firstChild,"path",{
d: "M "+this.HTMLpx(p)+",1" +
"L 1,"+this.HTMLpx(H+D-t)+" L "+this.HTMLpx(W)+","+this.HTMLpx(H+D-t)
});
HTMLCSS.placeBox(svg.parentNode,0,-D,true);
}
break;
case MML.NOTATION.MADRUWB:
frame.style.borderBottom = SOLID;
frame.style.borderRight = SOLID; if (!HTMLCSS.msieBorderWidthBug) {B = R = t}
break;
case MML.NOTATION.RADICAL:
if (HTMLCSS.useVML) {
if (!vml) {vml = this.HTMLvml(stack,H,D,W,t,values.mathcolor)}
this.HTMLvmlElement(vml,"shape",{
style: {width:this.HTMLpx(W), height:this.HTMLpx(H+D)},
path: "m "+this.HTMLpt(t/2,.6*(H+D))+" l "+this.HTMLpt(p,H+D-t)+" "+
this.HTMLpt(2*p,t/2)+" "+this.HTMLpt(W,t/2)+" e",
coordsize: this.HTMLpt(W,H+D)
});
dx = p;
} else {
if (!svg) {svg = this.HTMLsvg(stack,H,D,W,t,values.mathcolor)}
this.HTMLsvgElement(svg.firstChild,"path",{
d: "M 1,"+this.HTMLpx(.6*(H+D)) +
" L "+this.HTMLpx(p)+","+this.HTMLpx(H+D) +
" L "+this.HTMLpx(2*p)+",1 L "+this.HTMLpx(W)+",1"
});
HTMLCSS.placeBox(svg.parentNode,0,p/2-D,true);
dx = p; dy = t;
}
break;
case MML.NOTATION.LONGDIV:
if (HTMLCSS.useVML) {
if (!vml) {vml = this.HTMLvml(stack,H,D,W,t,values.mathcolor)}
this.HTMLvmlElement(vml,"line",{from: "0,"+this.HTMLpx(t/2), to: this.HTMLpx(W-t)+","+this.HTMLpx(t/2)});
this.HTMLvmlElement(vml,"arc",{
style: {width:this.HTMLpx(2*p),height:this.HTMLpx(H+D-2*t),
left:this.HTMLpx(-p),top:this.HTMLpx(t)},
startangle:"10", endangle:"170"
});
dx = p;
} else {
if (!svg) {svg = this.HTMLsvg(stack,H,D,W,t,values.mathcolor)}
this.HTMLsvgElement(svg.firstChild,"path",{
d: "M "+this.HTMLpx(W)+",1 L 1,1 "+
"a"+this.HTMLpx(p)+","+this.HTMLpx((H+D)/2-t)+" 0 0,1 1,"+this.HTMLpx(H+D-2*t)
});
HTMLCSS.placeBox(svg.parentNode,0,t-D,true);
dx = p; dy = t;
}
break;
}
}
frame.style.width = HTMLCSS.Em(W-L-R); frame.style.height = HTMLCSS.Em(H+D-T-B);
HTMLCSS.placeBox(frame,0,dy-D,true);
HTMLCSS.placeBox(base,dx+p+t,0);
this.HTMLhandleSpace(span);
this.HTMLhandleColor(span);
return span;
},
HTMLpx: function (n) {return (n*HTMLCSS.em)},
HTMLpt: function (x,y) {return Math.floor(1000*x)+','+Math.floor(1000*y)},
HTMLhandleColor: function (span) {
var frame = document.getElementById("MathJax-frame-"+this.spanID);
if (frame) {
// mathcolor is handled in toHTML above
var values = this.getValues("mathbackground","background");
if (this.style && span.style.backgroundColor) {
values.mathbackground = span.style.backgroundColor;
span.style.backgroundColor = "";
}
if (values.background && !this.mathbackground) {values.mathbackground = values.background}
if (values.mathbackground && values.mathbackground !== MML.COLOR.TRANSPARENT)
{frame.style.backgroundColor = values.mathbackground}
} else {this.SUPER(arguments).HTMLhandleColor.call(this,span)}
},
HTMLsvg: function (stack,H,D,W,t,color) {
var svg = document.createElementNS(SVGNS,"svg");
if (svg.style) {svg.style.width = HTMLCSS.Em(W); svg.style.height = HTMLCSS.Em(H+D)}
var scale = HTMLCSS.createBox(stack); scale.appendChild(svg);
HTMLCSS.placeBox(scale,0,-D,true);
this.HTMLsvgElement(svg,"g",{fill:"none", stroke:color, "stroke-width":t*HTMLCSS.em});
return svg;
},
HTMLsvgElement: function (svg,type,def) {
var obj = document.createElementNS(SVGNS,type); obj.isMathJax = true;
if (def) {for (var id in def) {if (def.hasOwnProperty(id)) {obj.setAttributeNS(null,id,def[id].toString())}}}
svg.appendChild(obj);
return obj;
},
HTMLvml: function (stack,H,D,W,t,color) {
var vml = HTMLCSS.createFrame(stack,H+D,0,W,0,"none");
HTMLCSS.addBox(stack,vml); HTMLCSS.placeBox(vml,0,-D,true);
this.constructor.VMLcolor = color; this.constructor.VMLthickness = this.HTMLpx(t);
return vml;
},
HTMLvmlElement: function (vml,type,def) {
var obj = HTMLCSS.addElement(vml,vmlns+":"+type,{isMathJax:true});
obj.style.position = "absolute"; obj.style.left = obj.style.top = 0;
MathJax.Hub.Insert(obj,def); // IE8 needs to do this after obj is added to the page
if (!def.fillcolor) {obj.fillcolor = "none"}
if (!def.strokecolor) {obj.strokecolor = this.constructor.VMLcolor}
if (!def.strokeweight) {obj.strokeweight =this.constructor.VMLthickness}
return obj;
}
});
MathJax.Hub.Browser.Select({
MSIE: function (browser) {
//
// IE8 and below doesn't have SVG, so use VML
//
if ((document.documentMode||0) < 9) {
MML.menclose.Augment({HTMLpx: function (n,d) {return (n*HTMLCSS.em+(d||0))+"px"}});
HTMLCSS.useVML = true;
if (!document.namespaces[vmlns]) {
if (document.documentMode && document.documentMode === 8) {
document.namespaces.add(vmlns,VMLNS,"#default#VML");
} else {
document.namespaces.add(vmlns,VMLNS);
document.createStyleSheet().addRule(vmlns+"\\: *","{behavior: url(#default#VML)}");
}
}
}
}
});
MathJax.Hub.Startup.signal.Post("HTML-CSS menclose Ready");
MathJax.Ajax.loadComplete(HTMLCSS.autoloadDir+"/menclose.js");
});

View File

@@ -0,0 +1,115 @@
/* -*- Mode: Javascript; indent-tabs-mode:nil; js-indent-level: 2 -*- */
/* vim: set ts=2 et sw=2 tw=80: */
/*************************************************************
*
* MathJax/jax/output/HTML-CSS/autoload/mglyph.js
*
* Implements the HTML-CSS output for <mglyph> elements.
*
* ---------------------------------------------------------------------
*
* Copyright (c) 2010-2020 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.
*/
MathJax.Hub.Register.StartupHook("HTML-CSS Jax Ready",function () {
var VERSION = "2.7.8";
var MML = MathJax.ElementJax.mml,
HTMLCSS = MathJax.OutputJax["HTML-CSS"],
LOCALE = MathJax.Localization;
MML.mglyph.Augment({
toHTML: function (span,variant) {
var SPAN = span, values = this.getValues("src","width","height","valign","alt"), err;
span = this.HTMLcreateSpan(span);
if (values.src === "") {
var index = this.Get("index");
if (index) {
variant = this.HTMLgetVariant(); var font = variant.defaultFont;
if (font) {
font.noStyleChar = true; font.testString = String.fromCharCode(index) + 'ABCabc';
if (HTMLCSS.Font.testFont(font)) {
this.HTMLhandleVariant(span,variant,String.fromCharCode(index));
} else {
if (values.alt === "")
{values.alt = LOCALE._(["MathML","BadMglyphFont"],"Bad font: %1",font.family)}
err = MML.Error(values.alt,{mathsize:"75%"});
this.Append(err); err.toHTML(span); this.data.pop();
span.bbox = err.HTMLspanElement().bbox;
}
}
}
} else {
if (!this.img) {this.img = MML.mglyph.GLYPH[values.src]}
if (!this.img) {
this.img = MML.mglyph.GLYPH[values.src] = {img: new Image(), status: "pending"};
var img = this.img.img;
img.onload = MathJax.Callback(["HTMLimgLoaded",this]);
img.onerror = MathJax.Callback(["HTMLimgError",this]);
img.src = values.src;
MathJax.Hub.RestartAfter(img.onload);
}
if (this.img.status !== "OK") {
err = MML.Error(
LOCALE._(["MathML","BadMglyph"],"Bad mglyph: %1",values.src),
{mathsize:"75%"});
this.Append(err); err.toHTML(span); this.data.pop();
span.bbox = err.HTMLspanElement().bbox;
} else {
var mu = this.HTMLgetMu(span);
var scale = this.HTMLgetScale();
img = HTMLCSS.addElement(span,"img",{isMathJax:true, src:values.src, alt:values.alt, title:values.alt});
if (values.width) {
img.style.width = HTMLCSS.Em(HTMLCSS.length2em(values.width,mu,this.img.img.width/HTMLCSS.em) * scale);
}
if (values.height) {
img.style.height = HTMLCSS.Em(HTMLCSS.length2em(values.height,mu,this.img.img.height/HTMLCSS.em) * scale);
}
span.bbox.w = span.bbox.rw = img.offsetWidth/HTMLCSS.em;
span.bbox.h = img.offsetHeight/HTMLCSS.em;
if (values.valign) {
span.bbox.d = -HTMLCSS.length2em(values.valign,mu,this.img.img.height/HTMLCSS.em) * scale;
img.style.verticalAlign = HTMLCSS.Em(-span.bbox.d);
span.bbox.h -= span.bbox.d;
}
}
}
if (!SPAN.bbox) {
SPAN.bbox = {w: span.bbox.w, h: span.bbox.h, d: span.bbox.d,
rw: span.bbox.rw, lw: span.bbox.lw};
} else if (span.bbox) {
SPAN.bbox.w += span.bbox.w;
if (SPAN.bbox.w > SPAN.bbox.rw) {SPAN.bbox.rw = SPAN.bbox.w}
if (span.bbox.h > SPAN.bbox.h) {SPAN.bbox.h = span.bbox.h}
if (span.bbox.d > SPAN.bbox.d) {SPAN.bbox.d = span.bbox.d}
}
this.HTMLhandleSpace(span);
this.HTMLhandleColor(span);
return span;
},
HTMLimgLoaded: function (event,status) {
if (typeof(event) === "string") {status = event}
this.img.status = (status || "OK")
},
HTMLimgError: function () {this.img.img.onload("error")}
},{
GLYPH: {} // global list of all loaded glyphs
});
MathJax.Hub.Startup.signal.Post("HTML-CSS mglyph Ready");
MathJax.Ajax.loadComplete(HTMLCSS.autoloadDir+"/mglyph.js");
});

View File

@@ -0,0 +1,200 @@
/* -*- Mode: Javascript; indent-tabs-mode:nil; js-indent-level: 2 -*- */
/* vim: set ts=2 et sw=2 tw=80: */
/*************************************************************
*
* MathJax/jax/output/HTML-CSS/autoload/mmultiscripts.js
*
* Implements the HTML-CSS output for <mmultiscripts> elements.
*
* ---------------------------------------------------------------------
*
* Copyright (c) 2010-2020 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.
*/
MathJax.Hub.Register.StartupHook("HTML-CSS Jax Ready",function () {
var VERSION = "2.7.8";
var MML = MathJax.ElementJax.mml,
HTMLCSS = MathJax.OutputJax["HTML-CSS"];
MML.mmultiscripts.Augment({
toHTML: function (span,HW,D) {
span = this.HTMLcreateSpan(span); var scale = this.HTMLgetScale();
var stack = HTMLCSS.createStack(span), values;
var base = HTMLCSS.createBox(stack);
if (this.data[this.base]) {
var child = this.data[this.base].toHTML(base);
if (D != null) {this.data[this.base].HTMLstretchV(base,HW,D)}
else if (HW != null) {this.data[this.base].HTMLstretchH(base,HW)}
HTMLCSS.Measured(child,base);
} else {base.bbox = this.HTMLzeroBBox()}
var x_height = HTMLCSS.TeX.x_height * scale,
s = HTMLCSS.TeX.scriptspace * scale * .75; // FIXME: .75 can be removed when IC is right?
var BOX = this.HTMLgetScripts(stack,s);
var sub = BOX[0], sup = BOX[1], presub = BOX[2], presup = BOX[3];
//
// <mmultiscripts> children other than the base can be <none/>,
// <mprescripts/>, <mrow></mrow> etc so try to get HTMLgetScale from the
// first element with a spanID. See issue 362.
//
var sscale = scale;
for (var i = 1; i < this.data.length; i++) {
if (this.data[i] && this.data[i].spanID) {
sscale = this.data[i].HTMLgetScale();
break;
}
}
var q = HTMLCSS.TeX.sup_drop * sscale, r = HTMLCSS.TeX.sub_drop * sscale;
var u = base.bbox.h - q, v = base.bbox.d + r, delta = 0, p;
if (base.bbox.ic) {delta = base.bbox.ic}
if (this.data[this.base] &&
(this.data[this.base].type === "mi" || this.data[this.base].type === "mo")) {
if (HTMLCSS.isChar(this.data[this.base].data.join("")) && base.bbox.scale === 1 &&
!this.data[this.base].Get("largeop")) {u = v = 0}
}
var min = this.getValues("subscriptshift","superscriptshift"), mu = this.HTMLgetMu(span);
min.subscriptshift = (min.subscriptshift === "" ? 0 : HTMLCSS.length2em(min.subscriptshift,mu));
min.superscriptshift = (min.superscriptshift === "" ? 0 : HTMLCSS.length2em(min.superscriptshift,mu));
var dx = 0;
if (presub) {dx = presub.bbox.w+delta} else if (presup) {dx = presup.bbox.w-delta}
if (dx < 0) {dx = 0};
HTMLCSS.placeBox(base,dx,0);
if (!sup && !presup) {
v = Math.max(v,HTMLCSS.TeX.sub1*scale,min.subscriptshift);
if (sub) {v = Math.max(v,sub.bbox.h-(4/5)*x_height)}
if (presub) {v = Math.max(v,presub.bbox.h-(4/5)*x_height)}
if (sub) {HTMLCSS.placeBox(sub,dx+base.bbox.w+s-delta,-v)}
if (presub) {HTMLCSS.placeBox(presub,0,-v)}
} else {
if (!sub && !presub) {
values = this.getValues("displaystyle","texprimestyle");
p = HTMLCSS.TeX[(values.displaystyle ? "sup1" : (values.texprimestyle ? "sup3" : "sup2"))];
u = Math.max(u,p*scale,min.superscriptshift);
if (sup) {u = Math.max(u,sup.bbox.d+(1/4)*x_height)}
if (presup) {u = Math.max(u,presup.bbox.d+(1/4)*x_height)}
if (sup) {HTMLCSS.placeBox(sup,dx+base.bbox.w+s,u)}
if (presup) {HTMLCSS.placeBox(presup,0,u)}
} else {
v = Math.max(v,HTMLCSS.TeX.sub2*scale);
var t = HTMLCSS.TeX.rule_thickness * scale;
var h = (sub||presub).bbox.h, d = (sup||presup).bbox.d;
if (presub) {h = Math.max(h,presub.bbox.h)}
if (presup) {d = Math.max(d,presup.bbox.d)}
if ((u - d) - (h - v) < 3*t) {
v = 3*t - u + d + h; q = (4/5)*x_height - (u - d);
if (q > 0) {u += q; v -= q}
}
u = Math.max(u,min.superscriptshift); v = Math.max(v,min.subscriptshift);
if (sup) {HTMLCSS.placeBox(sup,dx+base.bbox.w+s,u)}
if (presup) {HTMLCSS.placeBox(presup,dx+delta-presup.bbox.w,u)}
if (sub) {HTMLCSS.placeBox(sub,dx+base.bbox.w+s-delta,-v)}
if (presub) {HTMLCSS.placeBox(presub,dx-presub.bbox.w,-v)}
}
}
this.HTMLhandleSpace(span);
this.HTMLhandleColor(span);
var bbox = span.bbox;
bbox.dx = dx; bbox.s = s; bbox.u = u; bbox.v = v; bbox.delta = delta;
bbox.px = dx+base.bbox.w;
return span;
},
HTMLgetScripts: function (stack,s) {
var sup, sub, BOX = [];
var i = 1, m = this.data.length, W = 0;
for (var k = 0; k < 4; k += 2) {
while (i < m && (this.data[i]||{}).type !== "mprescripts") {
var box = [null,null,null,null];
for (var j = k; j < k+2; j++) {
if (this.data[i] && this.data[i].type !== "none" && this.data[i].type !== "mprescripts") {
if (!BOX[j]) {
BOX[j] = HTMLCSS.createBox(stack); BOX[j].bbox = this.HTMLemptyBBox({});
if (W) {HTMLCSS.createBlank(BOX[j],W); BOX[j].bbox.w = BOX[j].bbox.rw = W}
}
box[j] = this.data[i].toHTML(BOX[j]);
} else {
box[j] = MathJax.HTML.Element("span",{bbox:this.HTMLemptyBBox({})});
}
if ((this.data[i]||{}).type !== "mprescripts") i++;
}
var isPre = (k === 2);
sub = BOX[k]; sup = BOX[k+1];
if (sub && sup) {
var w = box[k+1].bbox.w - box[k].bbox.w;
if (w > 0) {
if (isPre) {
this.HTMLmoveColor(box[k],w,1);
BOX[k].w += w;
} else {
HTMLCSS.createBlank(sub,w);
}
} else if (w < 0) {
if (isPre) {
this.HTMLmoveColor(box[k+1],-w,-1);
BOX[k+1].w += -w;
} else {
HTMLCSS.createBlank(sup,-w);
}
}
this.HTMLcombineBBoxes(box[k],sub.bbox);
this.HTMLcombineBBoxes(box[k+1],sup.bbox);
if (w > 0) {
sub.bbox.w = sup.bbox.w;
sub.bbox.rw = Math.max(sub.bbox.w,sub.bbox.rw);
} else if (w < 0) {
sup.bbox.w = sub.bbox.w;
sup.bbox.rw = Math.max(sup.bbox.w,sup.bbox.rw);
}
} else {
if (sub) this.HTMLcombineBBoxes(box[k],sub.bbox);
if (sup) this.HTMLcombineBBoxes(box[k+1],sup.bbox);
}
if (sub) {W = sub.bbox.w} else if (sup) {W = sup.bbox.w}
}
i++; W = 0;
}
for (j = 0; j < 4; j++) {
if (BOX[j]) {
BOX[j].bbox.w += s;
BOX[j].bbox.rw = Math.max(BOX[j].bbox.w,BOX[j].bbox.rw);
BOX[j].bbox.name = (["sub","sup","presub","presup"])[j];
this.HTMLcleanBBox(BOX[j].bbox);
}
}
return BOX;
},
HTMLmoveColor: function (box,w,sign) {
var W = w/(box.scale||1);
box.style.paddingLeft = HTMLCSS.Em(W);
var color = box.previousSibling;
if (color && (color.id||"").match(/^MathJax-Color-/)) {
color.style.marginLeft = HTMLCSS.Em(W+parseFloat(color.style.marginLeft));
color.style.marginRight = HTMLCSS.Em(sign*(W-parseFloat(color.style.marginRight)));
}
},
HTMLstretchH: MML.mbase.HTMLstretchH,
HTMLstretchV: MML.mbase.HTMLstretchV
});
MathJax.Hub.Startup.signal.Post("HTML-CSS mmultiscripts Ready");
MathJax.Ajax.loadComplete(HTMLCSS.autoloadDir+"/mmultiscripts.js");
});

View File

@@ -0,0 +1,53 @@
/* -*- Mode: Javascript; indent-tabs-mode:nil; js-indent-level: 2 -*- */
/* vim: set ts=2 et sw=2 tw=80: */
/*************************************************************
*
* MathJax/jax/output/HTML-CSS/autoload/ms.js
*
* Implements the HTML-CSS output for <ms> elements.
*
* ---------------------------------------------------------------------
*
* Copyright (c) 2010-2020 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.
*/
MathJax.Hub.Register.StartupHook("HTML-CSS Jax Ready",function () {
var VERSION = "2.7.8";
var MML = MathJax.ElementJax.mml,
HTMLCSS = MathJax.OutputJax["HTML-CSS"];
MML.ms.Augment({
toHTML: function (span) {
span = this.HTMLhandleSize(this.HTMLcreateSpan(span));
var values = this.getValues("lquote","rquote","mathvariant");
if (!this.hasValue("lquote") || values.lquote === '"') values.lquote = "\u201C";
if (!this.hasValue("rquote") || values.rquote === '"') values.rquote = "\u201D";
if (values.lquote === "\u201C" && values.mathvariant === "monospace") values.lquote = '"';
if (values.rquote === "\u201D" && values.mathvariant === "monospace") values.rquote = '"';
var text = values.lquote+this.data.join("")+values.rquote; // FIXME: handle mglyph?
this.HTMLhandleVariant(span,this.HTMLgetVariant(),text);
this.HTMLhandleSpace(span);
this.HTMLhandleColor(span);
this.HTMLhandleDir(span);
return span;
}
});
MathJax.Hub.Startup.signal.Post("HTML-CSS ms Ready");
MathJax.Ajax.loadComplete(HTMLCSS.autoloadDir+"/ms.js");
});

View File

@@ -0,0 +1,505 @@
/* -*- Mode: Javascript; indent-tabs-mode:nil; js-indent-level: 2 -*- */
/* vim: set ts=2 et sw=2 tw=80: */
/*************************************************************
*
* MathJax/jax/output/HTML-CSS/autoload/mtable.js
*
* Implements the HTML-CSS output for <mtable> elements.
*
* ---------------------------------------------------------------------
*
* Copyright (c) 2010-2020 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.
*/
MathJax.Hub.Register.StartupHook("HTML-CSS Jax Ready",function () {
var VERSION = "2.7.8";
var MML = MathJax.ElementJax.mml,
HTMLCSS = MathJax.OutputJax["HTML-CSS"];
MML.mtable.Augment({
toHTML: function (span) {
span = this.HTMLcreateSpan(span);
if (this.data.length === 0) {return span}
var values = this.getValues("columnalign","rowalign","columnspacing","rowspacing",
"columnwidth","equalcolumns","equalrows",
"columnlines","rowlines","frame","framespacing",
"align","useHeight","width","side","minlabelspacing");
var hasRelativeWidth = values.width.match(/%$/);
var stack = HTMLCSS.createStack(span);
var scale = this.HTMLgetScale(), mu = this.HTMLgetMu(span), LABEL = -1;
var H = [], D = [], W = [], A = [], C = [], i, j, J = -1,
m, M, s, row, cell, mo, entries = [], HD;
var LH = HTMLCSS.FONTDATA.lineH * scale * values.useHeight,
LD = HTMLCSS.FONTDATA.lineD * scale * values.useHeight;
//
// Create cells and measure columns and rows
//
for (i = 0, m = this.data.length; i < m; i++) {
row = this.data[i]; s = (row.type === "mlabeledtr" ? LABEL : 0);
A[i] = []; H[i] = LH; D[i] = LD;
for (j = s, M = row.data.length + s; j < M; j++) {
if (W[j] == null) {
if (j > J) {J = j}
C[j] = HTMLCSS.createStack(HTMLCSS.createBox(stack));
W[j] = -HTMLCSS.BIGDIMEN;
}
A[i][j] = HTMLCSS.createBox(C[j]);
entries.push(row.data[j-s].toHTML(A[i][j]));
}
}
HTMLCSS.MeasureSpans(entries);
for (i = 0, m = this.data.length; i < m; i++) {
row = this.data[i]; s = (row.type === "mlabeledtr" ? LABEL : 0);
for (j = s, M = row.data.length + s; j < M; j++) {
cell = row.data[j-s];
if (cell.isMultiline) {A[i][j].style.width = "100%"}
if (cell.isEmbellished()) {
mo = cell.CoreMO();
var min = mo.Get("minsize",true);
if (min) {
var bbox = mo.HTMLspanElement().bbox;
if (mo.HTMLcanStretch("Vertical")) {
HD = bbox.h + bbox.d;
if (HD) {
min = HTMLCSS.length2em(min,mu,HD);
if (min*bbox.h/HD > H[i]) {H[i] = min*bbox.h/HD}
if (min*bbox.d/HD > D[i]) {D[i] = min*bbox.d/HD}
}
} else if (mo.HTMLcanStretch("Horizontal")) {
min = HTMLCSS.length2em(min,mu,bbox.w);
if (min > W[j]) {W[j] = min}
}
}
}
if (A[i][j].bbox.h > H[i]) {H[i] = A[i][j].bbox.h}
if (A[i][j].bbox.d > D[i]) {D[i] = A[i][j].bbox.d}
if (A[i][j].bbox.w > W[j]) {W[j] = A[i][j].bbox.w}
}
}
//
// Determine spacing and alignment
//
var SPLIT = MathJax.Hub.SplitList;
var CSPACE = SPLIT(values.columnspacing),
RSPACE = SPLIT(values.rowspacing),
CALIGN = SPLIT(values.columnalign),
RALIGN = SPLIT(values.rowalign),
CLINES = SPLIT(values.columnlines),
RLINES = SPLIT(values.rowlines),
CWIDTH = SPLIT(values.columnwidth),
RCALIGN = [];
for (i = 0, m = CSPACE.length; i < m; i++) {CSPACE[i] = HTMLCSS.length2em(CSPACE[i],mu)}
for (i = 0, m = RSPACE.length; i < m; i++) {RSPACE[i] = HTMLCSS.length2em(RSPACE[i],mu)}
while (CSPACE.length < J) {CSPACE.push(CSPACE[CSPACE.length-1])}
while (CALIGN.length <= J) {CALIGN.push(CALIGN[CALIGN.length-1])}
while (CLINES.length < J) {CLINES.push(CLINES[CLINES.length-1])}
while (CWIDTH.length <= J) {CWIDTH.push(CWIDTH[CWIDTH.length-1])}
while (RSPACE.length < A.length) {RSPACE.push(RSPACE[RSPACE.length-1])}
while (RALIGN.length <= A.length) {RALIGN.push(RALIGN[RALIGN.length-1])}
while (RLINES.length < A.length) {RLINES.push(RLINES[RLINES.length-1])}
if (C[LABEL]) {
CALIGN[LABEL] = (values.side.substr(0,1) === "l" ? "left" : "right");
CSPACE[LABEL] = -W[LABEL];
}
//
// Override row data
//
for (i = 0, m = A.length; i < m; i++) {
row = this.data[i]; RCALIGN[i] = [];
if (row.rowalign) {RALIGN[i] = row.rowalign}
if (row.columnalign) {
RCALIGN[i] = SPLIT(row.columnalign);
while (RCALIGN[i].length <= J) {RCALIGN[i].push(RCALIGN[i][RCALIGN[i].length-1])}
}
}
//
// Handle equal heights
//
if (values.equalrows) {
// FIXME: should really be based on row align (below is for baseline)
var Hm = Math.max.apply(Math,H), Dm = Math.max.apply(Math,D);
for (i = 0, m = A.length; i < m; i++)
{s = ((Hm + Dm) - (H[i] + D[i])) / 2; H[i] += s; D[i] += s}
}
// FIXME: do background colors for entire cell (include half the intercolumn space?)
//
// Determine array total height
//
HD = H[0] + D[A.length-1];
for (i = 0, m = A.length-1; i < m; i++) {HD += Math.max(0,D[i]+H[i+1]+RSPACE[i])}
//
// Determine frame and line sizes
//
var fx = 0, fy = 0, fW, fH = HD;
if (values.frame !== "none" ||
(values.columnlines+values.rowlines).match(/solid|dashed/)) {
var frameSpacing = SPLIT(values.framespacing);
if (frameSpacing.length != 2) {
// invalid attribute value: use the default.
frameSpacing = SPLIT(this.defaults.framespacing);
}
fx = HTMLCSS.length2em(frameSpacing[0],mu);
fy = HTMLCSS.length2em(frameSpacing[1],mu);
fH = HD + 2*fy; // fW waits until stack.bbox.w is determined
}
//
// Compute alignment
//
var Y, fY, n = "";
if (typeof(values.align) !== "string") {values.align = String(values.align)}
if (values.align.match(/(top|bottom|center|baseline|axis)( +(-?\d+))?/))
{n = RegExp.$3||""; values.align = RegExp.$1} else {values.align = this.defaults.align}
if (n !== "") {
//
// Find the height of the given row
//
n = parseInt(n);
if (n < 0) {n = A.length + 1 + n}
if (n < 1) {n = 1} else if (n > A.length) {n = A.length}
Y = 0; fY = -(HD + fy) + H[0];
for (i = 0, m = n-1; i < m; i++) {
// FIXME: Should handle values.align for final row
var dY = Math.max(0,D[i]+H[i+1]+RSPACE[i]);
Y += dY; fY += dY;
}
} else {
Y = ({
top: -(H[0] + fy),
bottom: HD + fy - H[0],
center: HD/2 - H[0],
baseline: HD/2 - H[0],
axis: HD/2 + HTMLCSS.TeX.axis_height*scale - H[0]
})[values.align];
fY = ({
top: -(HD + 2*fy),
bottom: 0,
center: -(HD/2 + fy),
baseline: -(HD/2 + fy),
axis: HTMLCSS.TeX.axis_height*scale - HD/2 - fy
})[values.align];
}
var WW, WP = 0, Wt = 0, Wp = 0, p = 0, f = 0, P = [], F = [], Wf = 1;
//
if (values.equalcolumns && values.width !== "auto") {
//
// Handle equalcolumns for percent-width and fixed-width tables
//
if (hasRelativeWidth) {
// Set widths to percentages
WW = (100/(J+1)).toFixed(2).replace(/\.?0+$/,"")+"%";
for (i = 0, m = Math.min(J+1,CWIDTH.length); i < m; i++) {CWIDTH[i] = WW}
// Get total column spacing
WW = 0; WP = 1; f = J+1;
for (i = 0, m = Math.min(J+1,CSPACE.length); i < m; i++) {WW += CSPACE[i]}
} else {
// Get total width minus column spacing
WW = HTMLCSS.length2em(values.width,mu);
for (i = 0, m = Math.min(J,CSPACE.length); i < m; i++) {WW -= CSPACE[i]}
// Determine individual column widths
WW /= J;
for (i = 0, m = Math.min(J+1,CWIDTH.length); i < m; i++) {W[i] = WW}
}
} else {
//
// Get column widths for fit and percentage columns
//
// Calculate the natural widths and percentage widths,
// while keeping track of the fit and percentage columns
for(i = 0, m = Math.min(J+1,CWIDTH.length); i < m; i++) {
if (CWIDTH[i] === "auto") {Wt += W[i]}
else if (CWIDTH[i] === "fit") {F[f] = i; f++; Wt += W[i]}
else if (CWIDTH[i].match(/%$/))
{P[p] = i; p++; Wp += W[i]; WP += HTMLCSS.length2em(CWIDTH[i],mu,1)}
else {W[i] = HTMLCSS.length2em(CWIDTH[i],mu); Wt += W[i]}
}
if (hasRelativeWidth) {
// Get separation width and check percentages
WW = 0; for (i = 0, m = Math.min(J,CSPACE.length); i < m; i++) {WW += CSPACE[i]}
if (WP > .98) {Wf = .98/WP; WP = .98}
} else {
// Get the full width (excluding inter-column spacing)
if (values.width === "auto") {
if (WP > .98) {Wf = Wp/(Wt+Wp); WW = Wt + Wp} else {WW = Wt / (1-WP)}
} else {
WW = HTMLCSS.length2em(values.width,mu);
for (i = 0, m = Math.min(J,CSPACE.length); i < m; i++) {WW -= CSPACE[i]}
}
// Determine the relative column widths
for (i = 0, m = P.length; i < m; i++) {
W[P[i]] = HTMLCSS.length2em(CWIDTH[P[i]],mu,WW*Wf); Wt += W[P[i]];
}
// Stretch fit columns, if any, otherwise stretch (or shrink) everything
if (Math.abs(WW - Wt) > .01) {
if (f && WW > Wt) {
WW = (WW - Wt) / f; for (i = 0, m = F.length; i < m; i++) {W[F[i]] += WW}
} else {WW = WW/Wt; for (j = 0; j <= J; j++) {W[j] *= WW}}
}
//
// Handle equal columns
//
if (values.equalcolumns) {
var Wm = Math.max.apply(Math,W);
for (j = 0; j <= J; j++) {W[j] = Wm}
}
}
}
//
// Lay out array columns
//
var y = Y, dy, line, align; s = (C[LABEL] ? LABEL : 0);
for (j = s; j <= J; j++) {
for (i = 0, m = A.length; i < m; i++) {
if (A[i][j]) {
s = (this.data[i].type === "mlabeledtr" ? LABEL : 0);
cell = this.data[i].data[j-s];
if (cell.HTMLcanStretch("Horizontal")) {
A[i][j].bbox = cell.HTMLstretchH(C[j],W[j]).bbox;
} else if (cell.HTMLcanStretch("Vertical")) {
mo = cell.CoreMO();
var symmetric = mo.symmetric; mo.symmetric = false;
A[i][j].bbox = cell.HTMLstretchV(C[j],H[i],D[i]).bbox; A[i][j].HH = null;
if (A[i][j].bbox.h > H[i]) {A[i][j].bbox.H = A[i][j].bbox.h; A[i][j].bbox.h = H[i]}
if (A[i][j].bbox.d > D[i]) {A[i][j].bbox.D = A[i][j].bbox.d; A[i][j].bbox.d = D[i]}
mo.symmetric = symmetric;
}
align = cell.rowalign||this.data[i].rowalign||RALIGN[i];
dy = ({top: H[i] - A[i][j].bbox.h,
bottom: A[i][j].bbox.d - D[i],
center: ((H[i]-D[i]) - (A[i][j].bbox.h-A[i][j].bbox.d))/2,
baseline: 0, axis: 0})[align] || 0; // FIXME: handle axis better?
align = (cell.columnalign||RCALIGN[i][j]||CALIGN[j]);
HTMLCSS.alignBox(A[i][j],align,y+dy);
}
if (i < A.length-1) {y -= Math.max(0,D[i]+H[i+1]+RSPACE[i])}
}
y = Y;
}
//
// Set column widths and placement
//
if (hasRelativeWidth) {
//
// Remove column spacing to get width available for columns
//
var box = HTMLCSS.createBox(stack); box.style.left = box.style.top = 0;
box.style.right = HTMLCSS.Em(WW+2*fx); box.style.display = "inline-block";
box.style.height = "0px";
if (HTMLCSS.msieRelativeWidthBug) {
box = HTMLCSS.createBox(box); box.style.position = "relative";
box.style.height = "1em"; box.style.width = "100%"; box.bbox = stack.bbox;
}
//
// wp = remaining width (%) divided by the number of columns it is split over
// wm = remaining width (fixed) divided by the number of columns it is split over
//
var xp = 0, xf = fx, wp, wm;
if (f) {wp = 100*(1-WP)/f, wm = Wt/f} else {wp = 100*(1-WP)/(J+1); wm = Wt/(J+1)}
for (j = 0; j <= J; j++) {
HTMLCSS.placeBox(C[j].parentNode,0,0); // sets the bbox
//
// Convert original column to the innermost span in the mobile column
//
C[j].style.position = "relative";
C[j].style.left = HTMLCSS.Em(xf);
C[j].style.width = "100%";
C[j].parentNode.parentNode.removeChild(C[j].parentNode);
var Cj = HTMLCSS.createBox(box); HTMLCSS.addBox(Cj,C[j]); C[j] = Cj;
var CjStyle = Cj.style; CjStyle.display = "inline-block"; CjStyle.left = xp + "%";
//
// Set width/position based on the type of column
//
if (CWIDTH[j].match(/%$/)) {
var pp = parseFloat(CWIDTH[j]) * Wf;
if (f === 0) {
CjStyle.width = (wp + pp) + "%"; xp += wp + pp;
Cj = HTMLCSS.createBox(Cj); HTMLCSS.addBox(Cj,C[j].firstChild);
Cj.style.left = 0; Cj.style.right = HTMLCSS.Em(wm); xf -= wm;
} else {
CjStyle.width = pp + "%"; xp += pp;
}
} else if (CWIDTH[j] === "fit" || f === 0) {
CjStyle.width = wp + "%";
Cj = HTMLCSS.createBox(Cj); HTMLCSS.addBox(Cj,C[j].firstChild);
Cj.style.left = 0; Cj.style.right = HTMLCSS.Em(wm-W[j]);
xf += W[j] - wm; xp += wp;
} else {
CjStyle.width = HTMLCSS.Em(W[j]); xf += W[j];
}
if (HTMLCSS.msieRelativeWidthBug) {
HTMLCSS.addText(Cj.firstChild,HTMLCSS.NBSP); // gets correct baseline
Cj.firstChild.style.position = "relative";
}
xf += CSPACE[j];
//
// Add column lines
//
if (CLINES[j] !== "none" && j < J && j !== LABEL) {
line = HTMLCSS.createBox(box); line.style.left = xp+"%";
line = HTMLCSS.createRule(line,fH,0,1.25/HTMLCSS.em); line.style.position = "absolute";
line.bbox = {h:fH, d:0, w:0, rw:1.25/HTMLCSS.em, lw:0};
line.parentNode.bbox = stack.bbox; // make sure stack size is updated
HTMLCSS.placeBox(line,xf-CSPACE[j]/2,fY,true); line.style.borderStyle = CLINES[j];
}
}
} else {
//
// Set the column box widths and place them
//
var x = fx;
for (j = 0; j <= J; j++) {
if (!C[j].bbox.width) {HTMLCSS.setStackWidth(C[j],W[j])}
if (CWIDTH[j] !== "auto" && CWIDTH[j] !== "fit")
{C[j].bbox.width = W[j]; C[j].bbox.isFixed = true}
HTMLCSS.placeBox(C[j].parentNode,x,0); x += W[j] + CSPACE[j];
//
// Add column lines
//
if (CLINES[j] !== "none" && j < J && j !== LABEL) {
line = HTMLCSS.createRule(stack,fH,0,1.25/HTMLCSS.em); HTMLCSS.addBox(stack,line);
line.bbox = {h:fH, d:0, w:0, rw:1.25/HTMLCSS.em, lw:0};
HTMLCSS.placeBox(line,x-CSPACE[j]/2,fY,true); line.style.borderStyle = CLINES[j];
}
}
}
stack.bbox.d = -fY; stack.bbox.h = fH+fY;
HTMLCSS.setStackWidth(stack,stack.bbox.w + fx);
//
// Add frame
//
fW = stack.bbox.w; var frame;
if (values.frame !== "none") {
frame = HTMLCSS.createFrame(stack,fH,0,fW,1.25/HTMLCSS.em,values.frame);
HTMLCSS.addBox(stack,frame); HTMLCSS.placeBox(frame,0,fY,true);
if (hasRelativeWidth) {frame.style.width = "100%"}
}
//
// Add row lines
//
y = Y;
for (i = 0, m = A.length-1; i < m; i++) {
dy = Math.max(0,D[i]+H[i+1]+RSPACE[i]);
if (RLINES[i] !== MML.LINES.NONE && RLINES[i] !== "") {
line = HTMLCSS.createRule(stack,1.25/HTMLCSS.em,0,fW); HTMLCSS.addBox(stack,line);
line.bbox = {h:1.25/HTMLCSS.em, d:0, w:fW, rw:fW, lw:0};
HTMLCSS.placeBox(line,0,y - D[i] - (dy-D[i]-H[i+1])/2,true);
if (RLINES[i] === MML.LINES.DASHED) line.style.borderTopStyle = "dashed";
if (hasRelativeWidth) line.style.width = "100%"
}
y -= dy;
}
//
// Set relative width
//
if (hasRelativeWidth) {span.bbox.width = values.width; stack.style.width = "100%"}
//
// Place the labels, if any
//
if (C[LABEL]) {
var mw = stack.bbox.w;
var indent = this.getValues("indentalignfirst","indentshiftfirst","indentalign","indentshift");
if (indent.indentalignfirst !== MML.INDENTALIGN.INDENTALIGN) {indent.indentalign = indent.indentalignfirst}
if (indent.indentalign === MML.INDENTALIGN.AUTO) {indent.indentalign = this.displayAlign}
if (indent.indentshiftfirst !== MML.INDENTSHIFT.INDENTSHIFT) {indent.indentshift = indent.indentshiftfirst}
if (indent.indentshift === "auto") {indent.indentshift = "0"}
var shift = HTMLCSS.length2em(indent.indentshift,mu,HTMLCSS.cwidth);
var labelspace = HTMLCSS.length2em(values.minlabelspacing,mu,HTMLCSS.cwidth);
var labelW = labelspace + C[LABEL].bbox.w, labelshift = 0, tw = mw;
var dIndent = HTMLCSS.length2em(this.displayIndent,mu,HTMLCSS.cwidth);
s = (CALIGN[LABEL] === MML.INDENTALIGN.RIGHT ? -1 : 1);
if (indent.indentalign === MML.INDENTALIGN.CENTER) {
tw += 2 * (labelW - s*(shift + dIndent));
shift += dIndent;
} else if (CALIGN[LABEL] === indent.indentalign) {
if (dIndent < 0) {labelshift = s*dIndent; dIndent = 0}
shift += s*dIndent; if (labelW > s*shift) shift = s*labelW; shift += labelshift;
tw += s*shift;
} else {
tw += labelW - s*shift + dIndent;
shift -= s*dIndent;
}
var eqn = HTMLCSS.createStack(span,false,"100%");
HTMLCSS.addBox(eqn,stack); HTMLCSS.alignBox(stack,indent.indentalign,0,shift);
C[LABEL].parentNode.parentNode.removeChild(C[LABEL].parentNode);
HTMLCSS.addBox(eqn,C[LABEL]); HTMLCSS.alignBox(C[LABEL],CALIGN[LABEL],0);
if (HTMLCSS.msieRelativeWidthBug) {stack.style.top = C[LABEL].style.top = ""}
if (hasRelativeWidth) {stack.style.width = values.width; span.bbox.width = "100%"}
C[LABEL].style[s === 1 ? "marginLeft" : "marginRight"] = HTMLCSS.Em(s*labelshift);
span.bbox.tw = tw;
span.style.minWidth = span.bbox.minWidth = HTMLCSS.Em(tw);
eqn.style.minWidth = eqn.bbox.minWidth = HTMLCSS.Em(tw/scale);
}
//
// Finish the table
//
if (!hasRelativeWidth) {this.HTMLhandleSpace(span)}
var color = this.HTMLhandleColor(span);
//
// Handle relative-sized background color
//
if (color && hasRelativeWidth) {
if (!frame) {
frame = HTMLCSS.createFrame(stack,fH,0,fW,0,"none");
HTMLCSS.addBox(stack,frame); HTMLCSS.placeBox(frame,0,fY,true);
frame.style.width = "100%";
}
frame.style.backgroundColor = color.style.backgroundColor;
frame.parentNode.insertBefore(frame,frame.parentNode.firstChild);
color.parentNode.removeChild(color);
}
return span;
},
HTMLhandleSpace: function (span) {
span.bbox.keepPadding = true; span.bbox.exact = true;
if (!this.hasFrame && span.bbox.width == null) {
span.firstChild.style.marginLeft = span.firstChild.style.marginRight = HTMLCSS.Em(1/6);
span.bbox.w += 1/3; span.bbox.rw += 1/3; span.bbox.lw += 1/6;
}
this.SUPER(arguments).HTMLhandleSpace.call(this,span);
}
});
MML.mtd.Augment({
toHTML: function (span,HW,D) {
span = this.HTMLcreateSpan(span);
if (this.data[0]) {
var box = this.data[0].toHTML(span);
if (D != null) {box = this.data[0].HTMLstretchV(span,HW,D)}
else if (HW != null) {box = this.data[0].HTMLstretchH(span,HW)}
span.bbox = box.bbox;
}
this.HTMLhandleSpace(span);
this.HTMLhandleColor(span);
return span;
},
HTMLstretchH: MML.mbase.HTMLstretchH,
HTMLstretchV: MML.mbase.HTMLstretchV
});
MathJax.Hub.Startup.signal.Post("HTML-CSS mtable Ready");
MathJax.Ajax.loadComplete(HTMLCSS.autoloadDir+"/mtable.js");
});

View File

@@ -0,0 +1,829 @@
/* -*- Mode: Javascript; indent-tabs-mode:nil; js-indent-level: 2 -*- */
/* vim: set ts=2 et sw=2 tw=80: */
/*************************************************************
*
* MathJax/jax/output/HTML-CSS/autoload/multiline.js
*
* Implements the HTML-CSS output for <mrow>'s that contain line breaks.
*
* ---------------------------------------------------------------------
*
* Copyright (c) 2010-2020 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.
*/
MathJax.Hub.Register.StartupHook("HTML-CSS Jax Ready",function () {
var VERSION = "2.7.8";
var MML = MathJax.ElementJax.mml,
HTMLCSS = MathJax.OutputJax["HTML-CSS"];
//
// Fake node used for testing end-of-line potential breakpoint
//
var MO = MML.mo().With({HTMLspanElement: function () {return {bbox: {w:0}, style: {}}}});
//
// Penalties for the various line breaks
//
var PENALTY = {
newline: 0,
nobreak: 1000000,
goodbreak: [-200],
badbreak: [+200],
auto: [0],
maxwidth: 1.33, // stop looking for breaks after this time the line-break width
toobig: 800,
nestfactor: 400,
spacefactor: -100,
spaceoffset: 2,
spacelimit: 1, // spaces larger than this get a penalty boost
fence: 500,
close: 500
};
var ENDVALUES = {linebreakstyle: "after"};
/**************************************************************************/
MML.mbase.Augment({
HTMLlinebreakPenalty: PENALTY,
/****************************************************************/
//
// Handle breaking an mrow into separate lines
//
HTMLmultiline: function (span) {
//
// Find the parent element and mark it as multiline
//
var parent = this;
while (parent.inferred || (parent.parent && parent.parent.type === "mrow" &&
parent.isEmbellished())) {parent = parent.parent}
var isTop = ((parent.type === "math" && parent.Get("display") === "block") ||
parent.type === "mtd");
parent.isMultiline = true;
//
// Default values for the line-breaking parameters
//
var VALUES = this.getValues(
"linebreak","linebreakstyle","lineleading","linebreakmultchar",
"indentalign","indentshift",
"indentalignfirst","indentshiftfirst",
"indentalignlast","indentshiftlast"
);
if (VALUES.linebreakstyle === MML.LINEBREAKSTYLE.INFIXLINEBREAKSTYLE)
{VALUES.linebreakstyle = this.Get("infixlinebreakstyle")}
VALUES.lineleading = HTMLCSS.length2em(VALUES.lineleading,1,0.5);
//
// Remove old color and break the span at its best line breaks
//
this.HTMLremoveColor(span);
var stack = HTMLCSS.createStack(span);
this.HTMLgetScale();
var state = {
n: 0, Y: 0,
scale: this.scale || 1,
isTop: isTop,
values: {},
VALUES: VALUES
},
align = this.HTMLgetAlign(state,{}),
shift = this.HTMLgetShift(state,{},align),
start = [],
end = {
index:[], penalty:PENALTY.nobreak,
w:0, W:shift, shift:shift, scanW:shift,
nest: 0
},
broken = false;
while (this.HTMLbetterBreak(end,state,true) &&
(end.scanW >= HTMLCSS.linebreakWidth || end.penalty === PENALTY.newline)) {
this.HTMLaddLine(stack,start,end.index,state,end.values,broken);
start = end.index.slice(0); broken = true;
align = this.HTMLgetAlign(state,end.values);
shift = this.HTMLgetShift(state,end.values,align);
if (align === MML.INDENTALIGN.CENTER) {shift = 0}
end.W = end.shift = end.scanW = shift; end.penalty = PENALTY.nobreak;
}
state.isLast = true;
this.HTMLaddLine(stack,start,[],state,ENDVALUES,broken);
//
// Make top-level spans 100% wide.
// Finish up the space and add the color again
//
if (parent.type === "math") {stack.style.width = span.bbox.width = "100%"}
this.HTMLhandleSpace(span);
this.HTMLhandleColor(span);
span.bbox.isMultiline = true;
return span;
},
/****************************************************************/
//
// Locate the next linebreak that is better than the current one
//
HTMLbetterBreak: function (info,state,toplevel) {
if (this.isToken) {return false} // FIXME: handle breaking of token elements
if (this.isEmbellished()) {
info.embellished = this;
return this.CoreMO().HTMLbetterBreak(info,state);
}
if (this.linebreakContainer) {return false}
//
// Get the current breakpoint position and other data
//
var index = info.index.slice(0), i = info.index.shift(),
m = this.data.length, W, w, scanW, broken = (info.index.length > 0), better = false;
if (i == null) {i = -1}; if (!broken) {i++; info.W += info.w; info.w = 0}
scanW = info.scanW = info.W; info.nest++;
//
// Look through the line for breakpoints,
// (as long as we are not too far past the breaking width)
//
while (i < m && (info.scanW < PENALTY.maxwidth*HTMLCSS.linebreakWidth || info.w === 0)) {
if (this.data[i]) {
if (this.data[i].HTMLbetterBreak(info,state)) {
better = true; index = [i].concat(info.index); W = info.W; w = info.w;
if (info.penalty === PENALTY.newline) {
info.index = index;
if (info.nest) {info.nest--}
return true;
}
}
scanW = (broken ? info.scanW : this.HTMLaddWidth(i,info,scanW));
}
info.index = []; i++; broken = false;
}
//
// Check if end-of-line is a better breakpoint
//
if (toplevel && better) {
MO.parent = this.parent; MO.inherit = this.inherit;
if (MO.HTMLbetterBreak(info,state)) {better = false; index = info.index}
}
if (info.nest) {info.nest--}
info.index = index;
if (better) {info.W = W; info.w = w}
return better;
},
HTMLaddWidth: function (i,info,scanW) {
if (this.data[i]) {
var span = this.data[i].HTMLspanElement();
scanW += span.bbox.w;
if (span.style.paddingLeft) {scanW += HTMLCSS.unEm(span.style.paddingLeft)}
if (span.style.paddingRight) {scanW += HTMLCSS.unEm(span.style.paddingRight)}
info.W = info.scanW = scanW; info.w = 0;
}
return scanW;
},
/****************************************************************/
//
// Create a new line and move the required elements into it
// Position it using proper alignment and indenting
//
HTMLaddLine: function (stack,start,end,state,values,broken) {
//
// Create a box for the line, with empty BBox
// fill it with the proper elements,
// and clean up the bbox
//
line = HTMLCSS.createBox(stack);
line.bbox = this.HTMLemptyBBox({});
state.first = broken; state.last = true;
this.HTMLmoveLine(start,end,line,state,values);
this.HTMLcleanBBox(line.bbox);
//
// Get the alignment and shift values
//
var align = this.HTMLgetAlign(state,values),
shift = this.HTMLgetShift(state,values,align);
//
// Set the Y offset based on previous depth, leading, and current height
//
if (state.n > 0) {
var LHD = HTMLCSS.FONTDATA.baselineskip * state.scale;
var leading = (state.values.lineleading == null ? state.VALUES : state.values).lineleading * state.scale;
state.Y -= Math.max(LHD,state.d + line.bbox.h + leading);
}
//
// Place the new line
//
HTMLCSS.alignBox(line,align,state.Y,shift);
//
// Save the values needed for the future
//
state.d = line.bbox.d; state.values = values; state.n++;
},
/****************************************************************/
//
// Get alignment and shift values from the given data
//
HTMLgetAlign: function (state,values) {
var cur = values, prev = state.values, def = state.VALUES, align;
if (state.n === 0) {align = cur.indentalignfirst || prev.indentalignfirst || def.indentalignfirst}
else if (state.isLast) {align = prev.indentalignlast || def.indentalignlast}
else {align = prev.indentalign || def.indentalign}
if (align === MML.INDENTALIGN.INDENTALIGN) {align = prev.indentalign || def.indentalign}
if (align === MML.INDENTALIGN.AUTO) {align = (state.isTop ? this.displayAlign : MML.INDENTALIGN.LEFT)}
return align;
},
HTMLgetShift: function (state,values,align) {
var cur = values, prev = state.values, def = state.VALUES, shift;
if (state.n === 0) {shift = cur.indentshiftfirst || prev.indentshiftfirst || def.indentshiftfirst}
else if (state.isLast) {shift = prev.indentshiftlast || def.indentshiftlast}
else {shift = prev.indentshift || def.indentshift}
if (shift === MML.INDENTSHIFT.INDENTSHIFT) {shift = prev.indentshift || def.indentshift}
if (shift === "auto" || shift === "") {shift = "0"}
shift = HTMLCSS.length2em(shift,1,HTMLCSS.cwidth);
if (state.isTop && this.displayIndent !== "0") {
var indent = HTMLCSS.length2em(this.displayIndent,1,HTMLCSS.cwidth);
shift += (align === MML.INDENTALIGN.RIGHT ? -indent : indent);
}
return shift;
},
/****************************************************************/
//
// Move the selected elements into the new line's span,
// moving whole items when possible, and parts of ones
// that are split by a line break.
//
HTMLmoveLine: function (start,end,span,state,values) {
var i = start[0], j = end[0];
if (i == null) {i = -1}; if (j == null) {j = this.data.length-1}
if (i === j && start.length > 1) {
//
// If starting and ending in the same element move the subpiece to the new line
//
this.data[i].HTMLmoveSlice(start.slice(1),end.slice(1),span,state,values,"paddingLeft");
} else {
//
// Otherwise, move the remainder of the initial item
// and any others up to the last one
//
var last = state.last; state.last = false;
while (i < j) {
if (this.data[i]) {
if (start.length <= 1) {this.data[i].HTMLmoveSpan(span,state,values)}
else {this.data[i].HTMLmoveSlice(start.slice(1),[],span,state,values,"paddingLeft")}
}
i++; state.first = false; start = [];
}
//
// If the last item is complete, move it,
// otherwise move the first part of it up to the split
//
state.last = last;
if (this.data[i]) {
if (end.length <= 1) {this.data[i].HTMLmoveSpan(span,state,values)}
else {this.data[i].HTMLmoveSlice([],end.slice(1),span,state,values,"paddingRight")}
}
}
},
/****************************************************************/
//
// Split an element and copy the selected items into the new part
//
HTMLmoveSlice: function (start,end,span,state,values,padding) {
//
// Get rid of color, if any (added back in later)
// Create a new span for the slice of the element
// Move the selected portion into the slice
// If it is the last slice
// Remove the original (now empty) span
// Rename the Continue-0 span with the original name (for HTMLspanElement)
// Add back the color
//
this.HTMLremoveColor();
var slice = this.HTMLcreateSliceSpan(span);
this.HTMLmoveLine(start,end,slice,state,values);
slice.style[padding] = "";
this.HTMLcombineBBoxes(slice,span.bbox);
this.HTMLcleanBBox(slice.bbox);
if (end.length === 0) {
span = this.HTMLspanElement();
var SPAN = span;
if (this.href) span = span.parentNode;
span.parentNode.removeChild(span);
span.nextMathJaxSpan.id = SPAN.id; var n = 0;
while ((SPAN = SPAN.nextMathJaxSpan)) {
if (SPAN.nodeName.toLowerCase() === "a") SPAN = SPAN.firstChild;
var color = this.HTMLhandleColor(SPAN);
if (color) {color.id += "-MathJax-Continue-"+n; n++}
}
}
return slice;
},
/****************************************************************/
//
// Create a new span for an element that is split in two
// Clone the original and update its ID.
// Link the old span to the new one so we can find it later
//
HTMLcreateSliceSpan: function (span) {
var SPAN = this.HTMLspanElement(), n = 0;
if (this.href) SPAN = SPAN.parentNode;
var LAST = SPAN; while (LAST.nextMathJaxSpan) {LAST = LAST.nextMathJaxSpan; n++}
var SLICE = SPAN.cloneNode(false); LAST.nextMathJaxSpan = SLICE; SLICE.nextMathJaxSpan = null;
SLICE.id += "-MathJax-Continue-"+n;
SLICE.bbox = this.HTMLemptyBBox({});
return span.appendChild(SLICE);
},
/****************************************************************/
//
// Move an element from its original span to its new location in
// a split element or the new line's span
//
HTMLmoveSpan: function (line,state,values) {
// FIXME: handle linebreakstyle === "duplicate"
// FIXME: handle linebreakmultchar
if (!(state.first || state.last) ||
(state.first && state.values.linebreakstyle === MML.LINEBREAKSTYLE.BEFORE) ||
(state.last && values.linebreakstyle === MML.LINEBREAKSTYLE.AFTER)) {
//
// Move color and span
//
var color = document.getElementById("MathJax-Color-"+this.spanID+HTMLCSS.idPostfix);
if (color) {line.appendChild(color)}
var span = this.HTMLspanElement();
if (this.href) span = span.parentNode;
line.appendChild(span);
//
// If it is last, remove right padding
// If it is first, remove left padding and recolor
//
if (state.last) {span.style.paddingRight = ""}
if (state.first || state.nextIsFirst) {
span.style.paddingLeft = "";
if (color) {this.HTMLremoveColor(span); this.HTMLhandleColor(span)}
}
if (state.first && span.bbox.w === 0) {state.nextIsFirst = true}
else {delete state.nextIsFirst}
//
// Update bounding box
//
this.HTMLcombineBBoxes(this,line.bbox);
}
}
});
/**************************************************************************/
MML.mfenced.Augment({
HTMLbetterBreak: function (info,state) {
//
// Get the current breakpoint position and other data
//
var index = info.index.slice(0), i = info.index.shift(),
m = this.data.length, W, w, scanW, broken = (info.index.length > 0), better = false;
if (i == null) {i = -1}; if (!broken) {i++; info.W += info.w; info.w = 0}
scanW = info.scanW = info.W; info.nest++;
//
// Create indices that include the delimiters and separators
//
if (!this.dataI) {
this.dataI = [];
if (this.data.open) {this.dataI.push("open")}
if (m) {this.dataI.push(0)}
for (var j = 1; j < m; j++) {
if (this.data["sep"+j]) {this.dataI.push("sep"+j)}
this.dataI.push(j);
}
if (this.data.close) {this.dataI.push("close")}
}
m = this.dataI.length;
//
// Look through the line for breakpoints, including the open, close, and separators
// (as long as we are not too far past the breaking width)
//
while (i < m && (info.scanW < PENALTY.maxwidth*HTMLCSS.linebreakWidth || info.w === 0)) {
var k = this.dataI[i];
if (this.data[k]) {
if (this.data[k].HTMLbetterBreak(info,state)) {
better = true; index = [i].concat(info.index); W = info.W; w = info.w;
if (info.penalty === PENALTY.newline) {
info.index = index;
if (info.nest) {info.nest--}
return true}
}
scanW = (broken ? info.scanW : this.HTMLaddWidth(i,info,scanW));
}
info.index = []; i++; broken = false;
}
if (info.nest) {info.nest--}
info.index = index;
if (better) {info.W = W; info.w = w}
return better;
},
HTMLmoveLine: function (start,end,span,state,values) {
var i = start[0], j = end[0];
if (i == null) {i = -1}; if (j == null) {j = this.dataI.length-1}
if (i === j && start.length > 1) {
//
// If starting and ending in the same element move the subpiece to the new line
//
this.data[this.dataI[i]].HTMLmoveSlice(start.slice(1),end.slice(1),span,state,values,"paddingLeft");
} else {
//
// Otherwise, move the remainder of the initial item
// and any others (including open and separators) up to the last one
//
var last = state.last; state.last = false; var k = this.dataI[i];
while (i < j) {
if (this.data[k]) {
if (start.length <= 1) {this.data[k].HTMLmoveSpan(span,state,values)}
else {this.data[k].HTMLmoveSlice(start.slice(1),[],span,state,values,"paddingLeft")}
}
i++; k = this.dataI[i]; state.first = false; start = [];
}
//
// If the last item is complete, move it
//
state.last = last;
if (this.data[k]) {
if (end.length <= 1) {this.data[k].HTMLmoveSpan(span,state,values)}
else {this.data[k].HTMLmoveSlice([],end.slice(1),span,state,values,"paddingRight")}
}
}
}
});
/**************************************************************************/
MML.msubsup.Augment({
HTMLbetterBreak: function (info,state) {
if (!this.data[this.base]) {return false}
//
// Get the current breakpoint position and other data
//
var index = info.index.slice(0), i = info.index.shift(),
W, w, scanW, broken = (info.index.length > 0), better = false;
if (!broken) {info.W += info.w; info.w = 0}
scanW = info.scanW = info.W;
//
// Record the width of the base and the super- and subscripts
//
if (i == null) {
this.HTMLbaseW = this.data[this.base].HTMLspanElement().bbox.w;
this.HTMLdw = this.HTMLspanElement().bbox.w - this.HTMLbaseW;
}
//
// Check if the base can be broken
//
if (this.data[this.base].HTMLbetterBreak(info,state)) {
better = true; index = [this.base].concat(info.index); W = info.W; w = info.w;
if (info.penalty === PENALTY.newline) {better = broken = true}
}
//
// Add in the base if it is unbroken, and add the scripts
//
if (!broken) {this.HTMLaddWidth(this.base,info,scanW)}
info.scanW += this.HTMLdw; info.W = info.scanW;
info.index = []; if (better) {info.W = W; info.w = w; info.index = index}
return better;
},
HTMLmoveLine: function (start,end,span,state,values) {
//
// Move the proper part of the base
//
if (this.data[this.base]) {
if (start.length > 1) {
this.data[this.base].HTMLmoveSlice(start.slice(1),end.slice(1),span,state,values,"paddingLeft");
} else {
if (end.length <= 1) {this.data[this.base].HTMLmoveSpan(span,state,values)}
else {this.data[this.base].HTMLmoveSlice([],end.slice(1),span,state,values,"paddingRight")}
}
}
//
// If this is the end, check for super and subscripts, and move those
// by moving the stack that contains them, and shifting by the amount of the
// base that has been removed. Remove the empty base box from the stack.
//
if (end.length === 0) {
var s = this.data[this.sup] || this.data[this.sub];
if (s && this.HTMLnotEmpty(s)) {
var box = s.HTMLspanElement().parentNode;
if (s.href) box = box.parentNode;
var stack = box.parentNode;
if (this.data[this.base]) {
var ic = this.data[this.base].HTMLspanElement().bbox.ic;
if (ic) stack.style.marginLeft = HTMLCSS.Em(-ic);
stack.removeChild(stack.firstChild);
}
for (box = stack.firstChild; box; box = box.nextSibling)
{box.style.left = HTMLCSS.Em(HTMLCSS.unEm(box.style.left)-this.HTMLbaseW)}
stack.bbox.w -= this.HTMLbaseW; stack.style.width = HTMLCSS.Em(stack.bbox.w);
this.HTMLcombineBBoxes(stack,span.bbox);
span.appendChild(stack);
}
}
}
});
/**************************************************************************/
MML.mmultiscripts.Augment({
HTMLbetterBreak: function (info,state) {
if (!this.data[this.base]) {return false}
//
// Get the current breakpoint position and other data
//
var index = info.index.slice(0); info.index.shift();
var W, w, scanW, broken = (info.index.length > 0), better = false;
if (!broken) {info.W += info.w; info.w = 0}
info.scanW = info.W;
//
// Get the bounding boxes and the width of the scripts
//
var bbox = this.HTMLspanElement().bbox,
base = this.data[this.base].HTMLspanElement().bbox;
var dw = bbox.w - base.w;
//
// Add in the prescripts
//
info.scanW += bbox.dx; scanW = info.scanW;
//
// Check if the base can be broken
//
if (this.data[this.base].HTMLbetterBreak(info,state)) {
better = true; index = [this.base].concat(info.index); W = info.W; w = info.w;
if (info.penalty === PENALTY.newline) {better = broken = true}
}
//
// Add in the base if it is unbroken, and add the scripts
//
if (!broken) {this.HTMLaddWidth(this.base,info,scanW)}
info.scanW += dw; info.W = info.scanW;
info.index = []; if (better) {info.W = W; info.w = w; info.index = index}
return better;
},
HTMLmoveLine: function (start,end,span,state,values) {
var SPAN = this.HTMLspanElement(), data = SPAN.bbox,
stack = SPAN.firstChild, BOX = {};
if (HTMLCSS.msiePaddingWidthBug) {stack = stack.nextSibling}
var box = stack.firstChild;
//
// Get the boxes for the scripts (if any)
//
while (box) {
if (box.bbox && box.bbox.name) {BOX[box.bbox.name] = box}
box = box.nextSibling;
}
//
// If this is the start, move the prescripts, if any.
//
if (start.length < 1) {
if (BOX.presub || BOX.presup) {
var STACK = HTMLCSS.createStack(span);
if (BOX.presup) {
HTMLCSS.addBox(STACK,BOX.presup);
HTMLCSS.placeBox(BOX.presup,data.dx-BOX.presup.bbox.w,data.u);
}
if (BOX.presub) {
HTMLCSS.addBox(STACK,BOX.presub);
HTMLCSS.placeBox(BOX.presub,data.dx+data.delta-BOX.presub.bbox.w,-data.v);
}
this.HTMLcombineBBoxes(STACK,span.bbox);
span.appendChild(STACK);
STACK.style.width = HTMLCSS.Em(data.dx);
}
}
//
// Move the proper part of the base
//
if (this.data[this.base]) {
if (start.length > 1) {
this.data[this.base].HTMLmoveSlice(start.slice(1),end.slice(1),span,state,values,"paddingLeft");
} else {
if (end.length <= 1) {this.data[this.base].HTMLmoveSpan(span,state,values)}
else {this.data[this.base].HTMLmoveSlice([],end.slice(1),span,state,values,"paddingRight")}
}
}
//
// If this is the end, check for super and subscripts, and move those
// by moving the stack that contains them, and shifting by the amount of the
// base that has been removed. Remove the empty base box from the stack.
//
if (end.length === 0) {
if (this.data[this.base]) {stack.removeChild(stack.firstChild)}
for (box = stack.firstChild; box; box = box.nextSibling)
{box.style.left = HTMLCSS.Em(HTMLCSS.unEm(box.style.left)-data.px)}
stack.bbox.w -= data.px; stack.style.width = HTMLCSS.Em(stack.bbox.w);
this.HTMLcombineBBoxes(stack,span.bbox);
span.appendChild(stack);
}
}
});
/**************************************************************************/
MML.mo.Augment({
//
// Override the method for checking line breaks to properly handle <mo>
//
HTMLbetterBreak: function (info,state) {
if (info.values && info.values.id === this.spanID) {return false}
var values = this.getValues(
"linebreak","linebreakstyle","lineleading","linebreakmultchar",
"indentalign","indentshift",
"indentalignfirst","indentshiftfirst",
"indentalignlast","indentshiftlast",
"texClass", "fence"
);
if (values.linebreakstyle === MML.LINEBREAKSTYLE.INFIXLINEBREAKSTYLE)
{values.linebreakstyle = this.Get("infixlinebreakstyle")}
//
// Adjust nesting by TeX class (helps output that does not include
// mrows for nesting, but can leave these unbalanced.
//
if (values.texClass === MML.TEXCLASS.OPEN) {info.nest++}
if (values.texClass === MML.TEXCLASS.CLOSE && info.nest) {info.nest--}
//
// Get the default penalty for this location
//
var W = info.scanW, mo = (info.embellished||this); delete info.embellished;
var span = mo.HTMLspanElement(), w = span.bbox.w;
if (span.style.paddingLeft) {w += HTMLCSS.unEm(span.style.paddingLeft)}
if (values.linebreakstyle === MML.LINEBREAKSTYLE.AFTER) {W += w; w = 0}
if (W - info.shift === 0 && values.linebreak !== MML.LINEBREAK.NEWLINE)
{return false} // don't break at zero width (FIXME?)
var offset = HTMLCSS.linebreakWidth - W;
// Adjust offest for explicit first-line indent and align
if (state.n === 0 && (values.indentshiftfirst !== state.VALUES.indentshiftfirst ||
values.indentalignfirst !== state.VALUES.indentalignfirst)) {
var align = this.HTMLgetAlign(state,values),
shift = this.HTMLgetShift(state,values,align);
offset += (info.shift - shift);
}
//
var penalty = Math.floor(offset / HTMLCSS.linebreakWidth * 1000);
if (penalty < 0) {penalty = PENALTY.toobig - 3*penalty}
if (values.fence) {penalty += PENALTY.fence}
if ((values.linebreakstyle === MML.LINEBREAKSTYLE.AFTER &&
values.texClass === MML.TEXCLASS.OPEN) ||
values.texClass === MML.TEXCLASS.CLOSE) {penalty += PENALTY.close}
penalty += info.nest * PENALTY.nestfactor;
//
// Get the penalty for this type of break and
// use it to modify the default penalty
//
var linebreak = PENALTY[values.linebreak||MML.LINEBREAK.AUTO]||0;
if (!MathJax.Object.isArray(linebreak)) {
// for breaks past the width, keep original penalty for newline
if (linebreak || offset >= 0) {penalty = linebreak * info.nest}
} else {penalty = Math.max(1,penalty + linebreak[0] * info.nest)}
//
// If the penalty is no better than the current one, return false
// Otherwise save the data for this breakpoint and return true
//
if (penalty >= info.penalty) {return false}
info.penalty = penalty; info.values = values; info.W = W; info.w = w;
values.lineleading = HTMLCSS.length2em(values.lineleading,1,state.VALUES.lineleading);
values.id = this.spanID;
return true;
}
});
/**************************************************************************/
MML.mspace.Augment({
//
// Override the method for checking line breaks to properly handle <mspace>
//
HTMLbetterBreak: function (info,state) {
if (info.values && info.values.id === this.spanID) {return false}
var values = this.getValues("linebreak");
var linebreakValue = values.linebreak;
if (!linebreakValue || this.hasDimAttr()) {
// The MathML spec says that the linebreak attribute should be ignored
// if any dimensional attribute is set.
linebreakValue = MML.LINEBREAK.AUTO;
}
//
// Get the default penalty for this location
//
var W = info.scanW, span = this.HTMLspanElement(), w = span.bbox.w;
if (span.style.paddingLeft) {w += HTMLCSS.unEm(span.style.paddingLeft)}
if (W - info.shift === 0) {return false} // don't break at zero width (FIXME?)
var offset = HTMLCSS.linebreakWidth - W;
//
var penalty = Math.floor(offset / HTMLCSS.linebreakWidth * 1000);
if (penalty < 0) {penalty = PENALTY.toobig - 3*penalty}
penalty += info.nest * PENALTY.nestfactor;
//
// Get the penalty for this type of break and
// use it to modify the default penalty
//
var linebreak = PENALTY[linebreakValue]||0;
if (linebreakValue === MML.LINEBREAK.AUTO && w >= PENALTY.spacelimit &&
!this.mathbackground && !this.background)
{linebreak = [(w+PENALTY.spaceoffset)*PENALTY.spacefactor]}
if (!MathJax.Object.isArray(linebreak)) {
// for breaks past the width, keep original penalty for newline
if (linebreak || offset >= 0) {penalty = linebreak * info.nest}
} else {penalty = Math.max(1,penalty + linebreak[0] * info.nest)}
//
// If the penalty is no better than the current one, return false
// Otherwise save the data for this breakpoint and return true
//
if (penalty >= info.penalty) {return false}
info.penalty = penalty; info.values = values; info.W = W; info.w = w;
values.lineleading = state.VALUES.lineleading;
values.linebreakstyle = "before"; values.id = this.spanID;
return true;
}
});
//
// Hook into the mathchoice extension
//
MathJax.Hub.Register.StartupHook("TeX mathchoice Ready",function () {
MML.TeXmathchoice.Augment({
HTMLbetterBreak: function (info,state) {
return this.Core().HTMLbetterBreak(info,state);
},
HTMLmoveLine: function (start,end,span,state,values) {
return this.Core().HTMLmoveSlice(start,end,span,state,values);
}
});
});
//
// Have maction process only the selected item
//
MML.maction.Augment({
HTMLbetterBreak: function (info,state) {
return this.Core().HTMLbetterBreak(info,state);
},
HTMLmoveLine: function (start,end,span,state,values) {
return this.Core().HTMLmoveSlice(start,end,span,state,values);
},
//
// Split and move the hit boxes as well
//
HTMLmoveSlice: function (start,end,span,state,values,padding) {
var hitbox = document.getElementById("MathJax-HitBox-"+this.spanID+HTMLCSS.idPostfix);
if (hitbox) {hitbox.parentNode.removeChild(hitbox)}
var slice = this.SUPER(arguments).HTMLmoveSlice.apply(this,arguments);
if (end.length === 0) {
span = this.HTMLspanElement(); var n = 0;
while (span) {
hitbox = this.HTMLhandleHitBox(span,"-Continue-"+n);
span = span.nextMathJaxSpan; n++;
}
}
return slice;
}
});
//
// Have semantics only do the first element
// (FIXME: do we need to do anything special about annotation-xml?)
//
MML.semantics.Augment({
HTMLbetterBreak: function (info,state) {
return (this.data[0] ? this.data[0].HTMLbetterBreak(info,state) : false);
},
HTMLmoveLine: function (start,end,span,state,values) {
return (this.data[0] ? this.data[0].HTMLmoveSlice(start,end,span,state,values) : null);
}
});
/**************************************************************************/
MathJax.Hub.Startup.signal.Post("HTML-CSS multiline Ready");
MathJax.Ajax.loadComplete(HTMLCSS.autoloadDir+"/multiline.js");
});