From 9a5928be6e4d913550aad10a64b04ac300ccda3b Mon Sep 17 00:00:00 2001 From: "Davide P. Cervone" Date: Sat, 28 Mar 2015 11:39:45 -0400 Subject: [PATCH] Add fuller support for mtables and their attributes. --- .../jax/output/CommonHTML/autoload/mtable.js | 569 ++++++++++++++++++ unpacked/jax/output/CommonHTML/jax.js | 103 +--- 2 files changed, 590 insertions(+), 82 deletions(-) create mode 100644 unpacked/jax/output/CommonHTML/autoload/mtable.js diff --git a/unpacked/jax/output/CommonHTML/autoload/mtable.js b/unpacked/jax/output/CommonHTML/autoload/mtable.js new file mode 100644 index 000000000..216fdf5b7 --- /dev/null +++ b/unpacked/jax/output/CommonHTML/autoload/mtable.js @@ -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 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"); +}); + diff --git a/unpacked/jax/output/CommonHTML/jax.js b/unpacked/jax/output/CommonHTML/jax.js index 34c990f8c..f8661510a 100644 --- a/unpacked/jax/output/CommonHTML/jax.js +++ b/unpacked/jax/output/CommonHTML/jax.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}); /********************************************************/