Add fuller support for mtables and their attributes.
This commit is contained in:
parent
9b0378af9b
commit
9a5928be6e
569
unpacked/jax/output/CommonHTML/autoload/mtable.js
Normal file
569
unpacked/jax/output/CommonHTML/autoload/mtable.js
Normal file
|
@ -0,0 +1,569 @@
|
|||
/* -*- Mode: Javascript; indent-tabs-mode:nil; js-indent-level: 2 -*- */
|
||||
/* vim: set ts=2 et sw=2 tw=80: */
|
||||
|
||||
/*************************************************************
|
||||
*
|
||||
* MathJax/jax/output/CommonHTML/autoload/mtable.js
|
||||
*
|
||||
* Implements the CommonHTML output for <mtable> elements.
|
||||
*
|
||||
* ---------------------------------------------------------------------
|
||||
*
|
||||
* Copyright (c) 2015 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("CommonHTML Jax Ready",function () {
|
||||
var VERSION = "2.5.0";
|
||||
var MML = MathJax.ElementJax.mml,
|
||||
HTML = MathJax.HTML, CONFIG = MathJax.Hub.config,
|
||||
CHTML = MathJax.OutputJax.CommonHTML,
|
||||
SPLIT = MathJax.Hub.SplitList;
|
||||
|
||||
var LABEL = -1,
|
||||
BIGDIMEN = 1000000;
|
||||
|
||||
MML.mtable.Augment({
|
||||
toCommonHTML: function (node) {
|
||||
//
|
||||
// Create the table nodes and put them in a table
|
||||
// (so that its bottom is on the baseline, rather than aligned on the top row)
|
||||
//
|
||||
var state = {rows:[], labels:[], labeled: false};
|
||||
node = this.CHTMLdefaultNode(node,{noBBox:true, childOptions:state});
|
||||
var table = HTML.Element("mjx-table");
|
||||
while (node.firstChild) table.appendChild(node.firstChild);
|
||||
node.appendChild(table);
|
||||
//
|
||||
// Get the table attributes
|
||||
//
|
||||
var values = this.getValues("columnalign","rowalign","columnspacing","rowspacing",
|
||||
"columnwidth","equalcolumns","equalrows",
|
||||
"columnlines","rowlines","frame","framespacing",
|
||||
"align","width","side","minlabelspacing","useHeight");
|
||||
//
|
||||
// Create the table
|
||||
//
|
||||
this.CHTMLgetBoxSizes(values,state);
|
||||
this.CHTMLgetAttributes(values,state);
|
||||
if (values.equalrows) {
|
||||
state.HD = true;
|
||||
state.HH = Math.max.apply(Math,state.H);
|
||||
state.DD = Math.max.apply(Math,state.D);
|
||||
}
|
||||
this.CHTMLadjustCells(values,state);
|
||||
if (values.frame) table.style.border = "1px "+values.frame;
|
||||
this.CHTMLalignV(values,state,node);
|
||||
this.CHTMLcolumnWidths(values,state,node);
|
||||
this.CHTMLstretchCells(values,state);
|
||||
if (state.labeled) this.CHTMLaddLabels(values,state,node,table);
|
||||
//
|
||||
// Set the bounding box (ignores overlapping outside of the table)
|
||||
//
|
||||
var BBOX = this.CHTML;
|
||||
BBOX.w = BBOX.r = state.R;
|
||||
BBOX.h = BBOX.t = state.T-state.B;
|
||||
BBOX.d = BBOX.b = state.B;
|
||||
if (!values.frame && !BBOX.pwidth) {
|
||||
node.style.padding = "0 "+CHTML.Em(1/6);
|
||||
BBOX.L = BBOX.R = 1/6;
|
||||
}
|
||||
//
|
||||
// Add any needed space and color
|
||||
//
|
||||
this.CHTMLhandleSpace(node);
|
||||
this.CHTMLhandleBBox(node);
|
||||
this.CHTMLhandleColor(node);
|
||||
//
|
||||
// Return the completed node
|
||||
//
|
||||
return node;
|
||||
},
|
||||
//
|
||||
// Get the natural height, depth, and widths of the rows and columns
|
||||
//
|
||||
CHTMLgetBoxSizes: function (values,state) {
|
||||
var LH = CHTML.FONTDATA.lineH * values.useHeight,
|
||||
LD = CHTML.FONTDATA.lineD * values.useHeight;
|
||||
var H = [], D = [], W = [], J = -1;
|
||||
for (var i = 0, m = this.data.length; i < m; i++) {
|
||||
var row = this.data[i], s = (row.type === "mtr" ? 0 : LABEL);
|
||||
H[i] = LH; D[i] = LD;
|
||||
for (var j = s, M = row.data.length + s; j < M; j++) {
|
||||
if (W[j] == null) {W[j] = -BIGDIMEN; if (j > J) J = j}
|
||||
var cbox = row.data[j-s].CHTML;
|
||||
if (cbox.h > H[i]) H[i] = cbox.h;
|
||||
if (cbox.d > D[i]) D[i] = cbox.d;
|
||||
if (cbox.w > W[j]) W[j] = cbox.w;
|
||||
}
|
||||
}
|
||||
state.H = H; state.D = D; state.W = W, state.J = J;
|
||||
},
|
||||
//
|
||||
// Pad the spacing and alignment attributes to match the size of the table
|
||||
//
|
||||
CHTMLgetAttributes: function (values,state) {
|
||||
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 = [], i, m, J = state.J, M = state.rows.length-1;
|
||||
for (i = 0, m = CSPACE.length; i < m; i++) CSPACE[i] = CHTML.length2em(CSPACE[i]);
|
||||
for (i = 0, m = RSPACE.length; i < m; i++) RSPACE[i] = CHTML.length2em(RSPACE[i]);
|
||||
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 < M) RSPACE.push(RSPACE[RSPACE.length-1]);
|
||||
while (RALIGN.length <= M) RALIGN.push(RALIGN[RALIGN.length-1]);
|
||||
while (RLINES.length < M) RLINES.push(RLINES[RLINES.length-1]);
|
||||
CALIGN[LABEL] = (values.side.substr(0,1) === "l" ? "left" : "right");
|
||||
//
|
||||
// Override aligment data based on row-specific attributes
|
||||
//
|
||||
for (i = 0; i <= M; i++) {
|
||||
var 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 framespacing
|
||||
//
|
||||
var FSPACE = SPLIT(values.framespacing);
|
||||
if (FSPACE.length != 2) FSPACE = SPLIT(this.defaults.framespacing);
|
||||
FSPACE[0] = Math.max(0,CHTML.length2em(FSPACE[0]));
|
||||
FSPACE[1] = Math.max(0,CHTML.length2em(FSPACE[1]));
|
||||
//
|
||||
// Pad arrays so that final column can be treated as all the others
|
||||
//
|
||||
if (values.frame === MML.LINES.NONE) {
|
||||
delete values.frame;
|
||||
CSPACE[J] = RSPACE[M] = 0;
|
||||
} else {
|
||||
CSPACE[J] = FSPACE[0]; RSPACE[M] = FSPACE[1];
|
||||
}
|
||||
CLINES[J] = RLINES[M] = MML.LINES.NONE;
|
||||
//
|
||||
// Save everything in the state
|
||||
//
|
||||
state.CSPACE = CSPACE; state.RSPACE = RSPACE;
|
||||
state.CALIGN = CALIGN; state.RALIGN = RALIGN;
|
||||
state.CLINES = CLINES; state.RLINES = RLINES;
|
||||
state.CWIDTH = CWIDTH; state.RCALIGN = RCALIGN;
|
||||
state.FSPACE = FSPACE;
|
||||
},
|
||||
//
|
||||
// Add styles to cells to handle borders, spacing, alignment, etc.
|
||||
//
|
||||
CHTMLadjustCells: function(values,state) {
|
||||
var ROWS = state.rows, H = state.H, D = state.D,
|
||||
CSPACE = state.CSPACE, CLINES = state.CLINES,
|
||||
RSPACE = state.RSPACE, RLINES = state.RLINES,
|
||||
CALIGN = state.CALIGN, RALIGN = state.RALIGN,
|
||||
RCALIGN = state.RCALIGN;
|
||||
CSPACE[state.J] *= 2; RSPACE[ROWS.length-1] *= 2; // since halved below
|
||||
var LH = CHTML.FONTDATA.lineH * values.useHeight,
|
||||
LD = CHTML.FONTDATA.lineD * values.useHeight;
|
||||
var T = "0", B, R, L, border, HD, cbox, align;
|
||||
if (values.frame) T = CHTML.Em(state.FSPACE[1]);
|
||||
for (var i = 0, m = ROWS.length; i < m; i++) {
|
||||
var row = ROWS[i], rdata = this.data[i];
|
||||
//
|
||||
// Space and borders between rows
|
||||
//
|
||||
B = RSPACE[i]/2; border = F = null; L = "0";
|
||||
if (RLINES[i] !== MML.LINES.NONE) {
|
||||
border = "1px "+RLINES[i];
|
||||
B -= 1/CHTML.em/2;
|
||||
}
|
||||
B = CHTML.Em(Math.max(0,B));
|
||||
//
|
||||
// Frame space for initial cell
|
||||
//
|
||||
if (values.frame) L = CHTML.Em(state.FSPACE[0]);
|
||||
//
|
||||
// The cells in the row
|
||||
//
|
||||
for (var j = 0, M = row.length; j < M; j++) {
|
||||
var s = (rdata.type === "mtr" ? 0 : LABEL);
|
||||
cell = row[j].style; cbox = rdata.data[j-s].CHTML;
|
||||
//
|
||||
// Space and borders between columns
|
||||
//
|
||||
R = CSPACE[j]/2;
|
||||
if (CLINES[j] !== MML.LINES.NONE) {
|
||||
cell.borderRight = "1px "+CLINES[j];
|
||||
R -= 1/CHTML.em/2;
|
||||
}
|
||||
R = CHTML.Em(Math.max(0,R));
|
||||
cell.padding = T+" "+R+" "+B+" "+L;
|
||||
if (border) cell.borderBottom = border;
|
||||
L = R;
|
||||
//
|
||||
// Handle vertical and horizontal alignment
|
||||
//
|
||||
align = (rdata.data[j-s].rowalign||this.data[i].rowalign||RALIGN[i]);
|
||||
align = ({top:"top", bottom:"bottom", center:"middle"})[align];
|
||||
if (align) cell.verticalAlign = align;
|
||||
align = (rdata.data[j-s].columnalign||RCALIGN[i][j]||CALIGN[j]);
|
||||
if (align !== MML.ALIGN.CENTER) cell.textAlign = align;
|
||||
//
|
||||
// Equal heights forced by adding an element of the proper size
|
||||
// (setting style.height seems to work very strangely)
|
||||
//
|
||||
if (state.HD && j === 0) {
|
||||
HTML.addElement(row[j].parentNode,"mjx-mtd",{},
|
||||
[["mjx-box",{style:{
|
||||
height:CHTML.Em(state.HH+state.DD),
|
||||
"vertical-align":CHTML.Em(-state.DD)
|
||||
}}]]
|
||||
);
|
||||
}
|
||||
//
|
||||
// Pad cells that are too short
|
||||
//
|
||||
cell = row[j].firstChild.style;
|
||||
if (cbox.h < LH) cell.marginTop = CHTML.Em(LH-cbox.h);
|
||||
if (cbox.d < LD) cell.marginBottom = CHTML.Em(LD-cbox.d);
|
||||
}
|
||||
T = B;
|
||||
}
|
||||
CSPACE[state.J] /= 2; RSPACE[ROWS.length-1] /= 2; // back to normal
|
||||
},
|
||||
//
|
||||
// Align the table vertically according to the align attribute
|
||||
//
|
||||
CHTMLalignV: function (values,state,node) {
|
||||
var n, M = state.rows.length, H = state.H, D = state.D, RSPACE = state.RSPACE;
|
||||
//
|
||||
// Get alignment type and row number
|
||||
//
|
||||
if (typeof(values.align) !== "string") values.align = String(values.align);
|
||||
if (values.align.match(/(top|bottom|center|baseline|axis)( +(-?\d+))?/)) {
|
||||
n = parseInt(RegExp.$3||"0");
|
||||
values.align = RegExp.$1
|
||||
if (n < 0) n += state.rows.length + 1;
|
||||
if (n > M || n <= 0) n = null;
|
||||
} else {
|
||||
values.align = this.defaults.align;
|
||||
}
|
||||
//
|
||||
// Get table height and baseline offset
|
||||
//
|
||||
var T = 0, B = 0, a = CHTML.TEX.axis_height;
|
||||
if (values.frame) {T = state.FSPACE[1] + 2/CHTML.em; B = 1/CHTML.em}
|
||||
var h = state.HH, d = state.DD;
|
||||
for (var i = 0; i < M; i++) {
|
||||
if (!state.HD) {h = H[i]; d = D[i]}
|
||||
T += h + d + RSPACE[i];
|
||||
if (n) {
|
||||
if (i === n-1) {
|
||||
B += ({top:h+d, bottom:0, center:(h+d)/2,
|
||||
baseline:d, axis:a+d})[values.align] + RSPACE[i];
|
||||
}
|
||||
if (i >= n) B += h + d + RSPACE[i];
|
||||
}
|
||||
}
|
||||
if (!n) B = ({top:T, bottom:0, center:T/2, baseline:T/2, axis:T/2-a})[values.align];
|
||||
//
|
||||
// Place the node and save the values
|
||||
//
|
||||
if (B) node.style.verticalAlign = CHTML.Em(-B);
|
||||
state.T = T; state.B = B;
|
||||
},
|
||||
//
|
||||
// Determine column widths and set the styles for the columns
|
||||
//
|
||||
CHTMLcolumnWidths: function (values,state,node) {
|
||||
var CWIDTH = state.CWIDTH, CSPACE = state.CSPACE, J = state.J, j;
|
||||
var WW = 0, setWidths = false, relWidth = values.width.match(/%$/);
|
||||
var i, m, w;
|
||||
//
|
||||
// Handle equal columns by adjusting the CWIDTH array
|
||||
//
|
||||
if (values.width !== "auto" && !relWidth) {
|
||||
WW = Math.max(0,CHTML.length2em(values.width,state.R));
|
||||
setWidths = true;
|
||||
}
|
||||
if (values.equalcolumns) {
|
||||
if (relWidth) {
|
||||
//
|
||||
// Use percent of total (not perfect, but best we can do)
|
||||
//
|
||||
var p = CHTML.Percent(1/(J+1));
|
||||
for (j = 0; j <= J; j++) CWIDTH[j] = p;
|
||||
} else {
|
||||
//
|
||||
// For width = auto, make all widths equal the widest,
|
||||
// otherwise, for specific width, remove intercolumn space
|
||||
// and divide by number of columns to get widest space.
|
||||
//
|
||||
w = Math.max.apply(Math,state.W);
|
||||
if (values.width !== "auto") {
|
||||
var S = (values.frame ? state.FSPACE[0] + 2/CHTML.em : 0);
|
||||
for (j = 0; j <= J; j++) S += CSPACE[j];
|
||||
w = Math.max((WW-S)/(J+1),w);
|
||||
}
|
||||
w = CHTML.Em(w);
|
||||
for (j = 0; j <= J; j++) CWIDTH[j] = w;
|
||||
}
|
||||
setWidths = true;
|
||||
}
|
||||
//
|
||||
// Compute natural table width
|
||||
//
|
||||
var TW = 0; if (values.frame) TW = state.FSPACE[0];
|
||||
var auto = [], fit = [], percent = [], W = [];
|
||||
var row = state.rows[0];
|
||||
for (j = 0; j <= J; j++) {
|
||||
W[j] = state.W[j];
|
||||
if (CWIDTH[j] === "auto") auto.push(j)
|
||||
else if (CWIDTH[j] === "fit") fit.push(j)
|
||||
else if (CWIDTH[j].match(/%$/)) percent.push(j)
|
||||
else W[j] = CHTML.length2em(CWIDTH[j],W[j]);
|
||||
TW += W[j] + CSPACE[j];
|
||||
row[j].style.width = CHTML.Em(W[j]);
|
||||
}
|
||||
if (values.frame) TW += 2/CHTML.em;
|
||||
var hasFit = (fit.length > 0);
|
||||
//
|
||||
// Adjust widths of columns
|
||||
//
|
||||
if (setWidths) {
|
||||
if (relWidth) {
|
||||
//
|
||||
// Set variable width on DOM nodes
|
||||
//
|
||||
this.CHTML.pwidth = values.width; this.CHTML.mwidth = CHTML.Em(TW);
|
||||
node.style.width = node.firstChild.style.width = "100%";
|
||||
//
|
||||
// Attach appropriate widths to the columns
|
||||
//
|
||||
for (j = 0; j <= J; j++) {
|
||||
cell = row[j].style;
|
||||
if (CWIDTH[j] === "auto" && !hasFit) cell.width = "";
|
||||
else if (CWIDTH[j] === "fit") cell.width = "";
|
||||
else if (CWIDTH[j].match(/%$/)) cell.width = CWIDTH[j];
|
||||
else cell.minWidth = cell.maxWidth = cell.width;
|
||||
}
|
||||
} else {
|
||||
//
|
||||
// Compute percentage widths
|
||||
//
|
||||
if (WW > TW) {
|
||||
var extra = 0;
|
||||
for (i = 0, m = percent.length; i < m; i++) {
|
||||
j = percent[i];
|
||||
w = Math.max(W[j],CHTML.length2em(CWIDTH[j],WW));
|
||||
extra += w-W[j]; W[j] = w;
|
||||
row[j].style.width = CHTML.Em(w);
|
||||
}
|
||||
TW += extra;
|
||||
}
|
||||
//
|
||||
// Compute "fit" widths
|
||||
//
|
||||
if (!hasFit) fit = auto;
|
||||
if (WW > TW && fit.length) {
|
||||
var dw = (WW - TW) / fit.length;
|
||||
for (i = 0, m = fit.length; i < m; i++) {
|
||||
j = fit[i]; W[j] += dw;
|
||||
row[j].style.width = CHTML.Em(W[j]);
|
||||
}
|
||||
TW = WW;
|
||||
}
|
||||
}
|
||||
}
|
||||
state.W = W;
|
||||
state.R = TW;
|
||||
},
|
||||
//
|
||||
// Stretch any cells that can be stretched
|
||||
//
|
||||
CHTMLstretchCells: function (values,state) {
|
||||
var ROWS = state.rows, H = state.H, D = state.D, W = state.W,
|
||||
J = state.J, M = ROWS.length-1;
|
||||
var h = state.HH, d = state.DD;
|
||||
for (var i = 0; i <= M; i++) {
|
||||
var row = ROWS[i], rdata = this.data[i];
|
||||
if (!state.HD) {h = H[i]; d = D[i]}
|
||||
for (var j = 0; j <= J; j++) {
|
||||
var cell = row[j], cdata = rdata.data[j];
|
||||
if (cdata.CHTML.stretch === "V") cdata.CHTMLstretchV(h,d);
|
||||
else if (cdata.CHTML.stretch === "H") cdata.CHTMLstretchH(cell,W[j]);
|
||||
}
|
||||
}
|
||||
},
|
||||
//
|
||||
// Add labels to a table
|
||||
//
|
||||
CHTMLaddLabels: function (values,state,node,table) {
|
||||
//
|
||||
// Get indentation and alignment
|
||||
//
|
||||
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 = CONFIG.displayAlign;
|
||||
if (indent.indentshiftfirst !== MML.INDENTSHIFT.INDENTSHIFT) indent.indentshift = indent.indentshiftfirst;
|
||||
if (indent.indentshift === "auto") indent.indentshift = "0";
|
||||
var shift = CHTML.length2em(indent.indentshift,CHTML.cwidth);
|
||||
var labelshift = CHTML.length2em(values.minlabelspacing,CHTML.cwidth);
|
||||
if (this.displayIndent !== "0") {
|
||||
var dIndent = CHTML.length2em(CONFIG.displayIndent,CHTML.cwidth);
|
||||
shift += (indent.indentAlign === MML.INDENTALIGN.RIGHT ? -dIndent: dIndent);
|
||||
}
|
||||
if (indent.indentalign === MML.INDENTALIGN.CENTER) shift *= 2;
|
||||
var margin = "margin"+(indent.indentalign === MML.INDENTALIGN.RIGHT ? "Right" : "Left");
|
||||
//
|
||||
// Create boxes for table and labels
|
||||
//
|
||||
var box = HTML.addElement(node,"mjx-box",{
|
||||
style:{width:"100%","text-align":indent.indentalign}
|
||||
}); box.appendChild(table);
|
||||
var labels = HTML.Element("mjx-stack");
|
||||
table.style.display = "inline-table"; if (!table.style.width) table.style.width = "auto";
|
||||
labels.style.verticalAlign = table.style.verticalAlign = "top";
|
||||
node.style.verticalAlign = "";
|
||||
if (shift) table.style[margin] = CHTML.Em(shift);
|
||||
//
|
||||
// Add labels on correct side
|
||||
//
|
||||
if (state.CALIGN[LABEL] === "left") {
|
||||
node.insertBefore(labels,box);
|
||||
labels.style.marginRight = CHTML.Em(-state.W[LABEL]);
|
||||
} else {
|
||||
node.appendChild(labels);
|
||||
labels.style.marginLeft = CHTML.Em(-state.W[LABEL]);
|
||||
}
|
||||
//
|
||||
// Vertically align the labels with their rows
|
||||
//
|
||||
var LABELS = state.labels, T = 0, H = state.H, D = state.D, RSPACE = state.RSPACE;
|
||||
if (values.frame) T = state.FSPACE[0] + 1/CHTML.em;
|
||||
var h = state.HH, d = state.DD;
|
||||
for (var i = 0, m = LABELS.length; i < m; i++) {
|
||||
if (!state.HD) {h = H[i]; d = D[i]}
|
||||
if (LABELS[i]) {
|
||||
labels.appendChild(LABELS[i]);
|
||||
var lbox = this.data[i].data[0].CHTML;
|
||||
T += h - lbox.h;
|
||||
if (T) LABELS[i].style.marginTop = CHTML.Em(T);
|
||||
T = d - lbox.d;
|
||||
} else {
|
||||
T += h + d;
|
||||
}
|
||||
T += RSPACE[i];
|
||||
}
|
||||
//
|
||||
// Propagage full-width equations, and reserve
|
||||
// room for equation plus label and minlabelspacing
|
||||
//
|
||||
node.style.width = this.CHTML.pwidth = "100%";
|
||||
var min = CHTML.length2em(values.minlabelspacing,this.defaults.minlabelspacing);
|
||||
var w = state.R + state.W[LABEL] + min;
|
||||
if (indent.indentalign === MML.INDENTALIGN.CENTER) w += state.W[LABEL] + min;
|
||||
this.CHTML.mwidth = CHTML.Em(w);
|
||||
}
|
||||
});
|
||||
|
||||
MML.mtr.Augment({
|
||||
toCommonHTML: function (node,options) {
|
||||
//
|
||||
// Create the row node
|
||||
//
|
||||
node = this.CHTMLcreateNode(node);
|
||||
this.CHTMLhandleStyle(node);
|
||||
this.CHTMLhandleScale(node);
|
||||
//
|
||||
// Add a new row with no label
|
||||
//
|
||||
if (!options) options = {rows:[],labels:[]};
|
||||
var row = []; options.rows.push(row);
|
||||
options.labels.push(null);
|
||||
//
|
||||
// Add the cells to the row
|
||||
//
|
||||
for (var i = 0, m = this.data.length; i < m; i++)
|
||||
row.push(this.CHTMLaddChild(node,i,options));
|
||||
//
|
||||
this.CHTMLhandleColor(node);
|
||||
return node;
|
||||
}
|
||||
});
|
||||
MML.mlabeledtr.Augment({
|
||||
toCommonHTML: function (node,options) {
|
||||
//
|
||||
// Create the row node
|
||||
//
|
||||
node = this.CHTMLcreateNode(node);
|
||||
this.CHTMLhandleStyle(node);
|
||||
this.CHTMLhandleScale(node);
|
||||
//
|
||||
// Add a new row, and get the label
|
||||
//
|
||||
if (!options) options = {rows:[],labels:[]};
|
||||
var row = []; options.rows.push(row);
|
||||
var label = HTML.Element("mjx-label"); options.labels.push(label);
|
||||
this.CHTMLaddChild(label,0,options);
|
||||
options.labeled = true;
|
||||
//
|
||||
// Add the cells to the row
|
||||
//
|
||||
for (var i = 1, m = this.data.length; i < m; i++)
|
||||
row.push(this.CHTMLaddChild(node,i,options));
|
||||
//
|
||||
this.CHTMLhandleColor(node);
|
||||
return node;
|
||||
}
|
||||
});
|
||||
MML.mtd.Augment({
|
||||
toCommonHTML: function (node,options) {
|
||||
node = this.CHTMLdefaultNode(node,options);
|
||||
//
|
||||
// Determine if this is stretchy or not
|
||||
//
|
||||
if (this.isEmbellished()) {
|
||||
var mo = this.CoreMO(), BBOX = this.CHTML;
|
||||
if (mo.CHTMLcanStretch("Vertical")) BBOX.stretch = "V";
|
||||
else if (mo.CHTMLcanStretch("Horizontal")) BBOX.stretch = "H";
|
||||
if (BBOX.stretch) {
|
||||
var min = mo.Get("minsize",true);
|
||||
if (min) {
|
||||
if (BBOX.stretch === "V") {
|
||||
var HD = BBOX.h + BBOX.d;
|
||||
if (HD) {
|
||||
var r = CHTML.length2em(min,HD)/HD;
|
||||
if (r > 1) {BBOX.h *= r; BBOX.d *= r}
|
||||
}
|
||||
} else {
|
||||
BBOX.w = Math.max(BBOX.w,CHTML.length2em(min,BBOX.w));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return node;
|
||||
}
|
||||
});
|
||||
|
||||
|
||||
MathJax.Hub.Startup.signal.Post("CommonHTML mtable Ready");
|
||||
MathJax.Ajax.loadComplete(CHTML.autoloadDir+"/mtable.js");
|
||||
});
|
||||
|
|
@ -47,7 +47,6 @@
|
|||
"font-weight": "normal",
|
||||
"font-size": "100%",
|
||||
"font-size-adjust":"none",
|
||||
"text-indent": 0,
|
||||
"text-transform": "none",
|
||||
"letter-spacing": "normal",
|
||||
"word-spacing": "normal",
|
||||
|
@ -106,6 +105,11 @@
|
|||
|
||||
"mjx-annotation-xml": {"line-height":"normal"},
|
||||
|
||||
"mjx-mtr": {display:"table-row"},
|
||||
"mjx-mlabeledtr": {display:"table-row"},
|
||||
"mjx-mtd": {display:"table-cell", "text-align":"center"},
|
||||
"mjx-label": {display:"block"},
|
||||
|
||||
"mjx-box": {display:"inline-block"},
|
||||
"mjx-block": {display:"block"},
|
||||
"mjx-char": {display:"block"},
|
||||
|
@ -152,19 +156,8 @@
|
|||
"mjx-ex-box-test": {
|
||||
position: "absolute",
|
||||
width:"1px", height:"60ex"
|
||||
},
|
||||
}
|
||||
|
||||
/*********************************/
|
||||
|
||||
"mjx-mtable": {"vertical-align":AXISHEIGHT+"em", "margin":"0 .125em"},
|
||||
"mjx-mtable > span": {"display":"inline-table!important", "vertical-align":"middle"},
|
||||
"mjx-mtr": {"display":"table-row!important"},
|
||||
"mjx-mtd": {"display":"table-cell!important", "text-align":"center", "padding":".5em 0 0 .5em"},
|
||||
"mjx-mtr > mjx-mtd:first-child": {"padding-left":0},
|
||||
"mjx-mtr:first-child > mjx-mtd": {"padding-top":0},
|
||||
"mjx-mlabeledtr": {"display":"table-row!important"},
|
||||
"mjx-mlabeledtr > mjx-mtd:first-child": {"padding-left":0},
|
||||
"mjx-mlabeledtr:first-child > mjx-mtd": {"padding-top":0}
|
||||
};
|
||||
|
||||
|
||||
|
@ -1102,7 +1095,7 @@
|
|||
},
|
||||
|
||||
Em: function (m) {
|
||||
if (Math.abs(m) < .001) return "0em";
|
||||
if (Math.abs(m) < .001) return "0";
|
||||
return (m.toFixed(3).replace(/\.?0+$/,""))+"em";
|
||||
},
|
||||
unEm: function (m) {
|
||||
|
@ -1228,14 +1221,14 @@
|
|||
return node;
|
||||
},
|
||||
CHTMLaddChild: function (node,i,options) {
|
||||
var child = this.data[i];
|
||||
var child = this.data[i], cnode;
|
||||
if (child) {
|
||||
var type = options.childNodes;
|
||||
if (type) {
|
||||
if (type instanceof Array) type = type[i];
|
||||
node = HTML.addElement(node,type);
|
||||
}
|
||||
child.toCommonHTML(node,options.childOptions);
|
||||
cnode = child.toCommonHTML(node,options.childOptions);
|
||||
if (type && child.CHTML.rscale !== 1) {
|
||||
// move scale factor to outer container (which seems to be more accurate)
|
||||
node.style.fontSize = node.firstChild.style.fontSize;
|
||||
|
@ -1247,7 +1240,8 @@
|
|||
if (cbox.ic) {bbox.ic = cbox.ic} else {delete bbox.ic}
|
||||
if (cbox.skew) bbox.skew = cbox.skew;
|
||||
}
|
||||
} else if (options.forceChild) {HTML.addElement(node,"span")}
|
||||
} else if (options.forceChild) {cnode = HTML.addElement(node,"span")}
|
||||
return cnode;
|
||||
},
|
||||
CHTMLstretchChildV: function (i,H,D) {
|
||||
var data = this.data[i];
|
||||
|
@ -1371,6 +1365,11 @@
|
|||
|
||||
CHTMLhandleBBox: function (node) {
|
||||
var BBOX = this.CHTML, style = node.style;
|
||||
if (this.data.length === 1 && this.data[0].CHTML.pwidth) {
|
||||
BBOX.pwidth = this.data[0].CHTML.pwidth;
|
||||
BBOX.mwidth = this.data[0].CHTML.mwidth;
|
||||
style.width = "100%";
|
||||
}
|
||||
if (!this.style) return;
|
||||
// ### FIXME: adjust for width, height, vertical-align?
|
||||
for (var i = 0, m = CHTML.BBOX.styleAdjust.length; i < m; i++) {
|
||||
|
@ -1540,6 +1539,10 @@
|
|||
MML.math.Augment({
|
||||
toCommonHTML: function (node) {
|
||||
node = this.CHTMLdefaultNode(node);
|
||||
if (this.CHTML.pwidth) {
|
||||
node.parentNode.style.width = this.CHTML.pwidth;
|
||||
node.parentNode.style.minWidth = this.CHTML.mwidth;
|
||||
}
|
||||
return node;
|
||||
}
|
||||
});
|
||||
|
@ -2385,71 +2388,6 @@
|
|||
|
||||
/********************************************************/
|
||||
|
||||
MML.mtable.Augment({
|
||||
toCommonHTML: function (node) {
|
||||
node = this.CHTMLdefaultNode(node,{noBBox:true});
|
||||
var values = this.getValues("columnalign","rowalign","columnspacing","rowspacing",
|
||||
"columnwidth","equalcolumns","equalrows",
|
||||
"columnlines","rowlines","frame","framespacing",
|
||||
"align","width"/*,"useHeight","side","minlabelspacing"*/);
|
||||
var SPLIT = MathJax.Hub.SplitList, i, m, j, n;
|
||||
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] = CHTML.length2em(CSPACE[i])}
|
||||
for (i = 0, m = RSPACE.length; i < m; i++) {RSPACE[i] = CHTML.length2em(RSPACE[i])}
|
||||
|
||||
var table = HTML.Element("span");
|
||||
while (node.firstChild) table.appendChild(node.firstChild);
|
||||
node.appendChild(table);
|
||||
var H = 0, W = 0;
|
||||
for (i = 0, m = this.data.length; i < m; i++) {
|
||||
var row = this.data[i];
|
||||
if (row) {
|
||||
var rspace = CHTML.arrayEntry(RSPACE,i-1), ralign = CHTML.arrayEntry(RALIGN,i);
|
||||
var rbox = row.CHTML, rnode = row.CHTMLnodeElement();
|
||||
rnode.style.verticalAlign = ralign;
|
||||
var k = (row.type === "mlabeledtr" ? 1 : 0);
|
||||
for (j = 0, n = row.data.length; j < n-k; j++) {
|
||||
var cell = row.data[j+k];
|
||||
if (cell) {
|
||||
var cspace = CHTML.arrayEntry(CSPACE,j-1), calign = CHTML.arrayEntry(CALIGN,j);
|
||||
var /*cbox = cell.CHTML,*/ cnode = cell.CHTMLnodeElement();
|
||||
if (j) {rbox.w += cspace; cnode.style.paddingLeft = CHTML.Em(cspace)}
|
||||
if (i) cnode.style.paddingTop = CHTML.Em(rspace);
|
||||
cnode.style.textAlign = calign;
|
||||
}
|
||||
}
|
||||
H += rbox.h + rbox.d; if (i) {H += rspace}
|
||||
if (rbox.w > W) W = rbox.w;
|
||||
}
|
||||
}
|
||||
var bbox = this.CHTML;
|
||||
bbox.w = W; bbox.h = H/2 + AXISHEIGHT; bbox.d = H/2 - AXISHEIGHT;
|
||||
bbox.L = bbox.R = .125;
|
||||
return node;
|
||||
}
|
||||
});
|
||||
MML.mlabeledtr.Augment({
|
||||
CHTMLdefaultNode: function (node,options) {
|
||||
if (!options) options = {};
|
||||
node = this.CHTMLcreateNode(node);
|
||||
this.CHTMLhandleStyle(node);
|
||||
// skip label for now
|
||||
for (var i = 1, m = this.data.length; i < m; i++) this.CHTMLaddChild(node,i,options);
|
||||
this.CHTMLhandleBBox(node);
|
||||
this.CHTMLhandleColor(node);
|
||||
return node;
|
||||
}
|
||||
});
|
||||
|
||||
/********************************************************/
|
||||
|
||||
MML.semantics.Augment({
|
||||
toCommonHTML: function (node) {
|
||||
node = this.CHTMLcreateNode(node);
|
||||
|
@ -2470,6 +2408,7 @@
|
|||
// MML.menclose.Augment({toCommonHTML: MML.mbase.CHTMLautoload});
|
||||
// MML.maction.Augment({toCommonHTML: MML.mbase.CHTMLautoload});
|
||||
MML.mmultiscripts.Augment({toCommonHTML: MML.mbase.CHTMLautoload});
|
||||
MML.mtable.Augment({toCommonHTML: MML.mbase.CHTMLautoload});
|
||||
|
||||
/********************************************************/
|
||||
|
||||
|
|
Loading…
Reference in New Issue
Block a user