menclose.js (11448B)
1 /* -*- Mode: Javascript; indent-tabs-mode:nil; js-indent-level: 2 -*- */ 2 /* vim: set ts=2 et sw=2 tw=80: */ 3 4 /************************************************************* 5 * 6 * MathJax/jax/output/CommonHTML/autoload/menclose.js 7 * 8 * Implements the CommonHTML output for <menclose> elements. 9 * 10 * --------------------------------------------------------------------- 11 * 12 * Copyright (c) 2015 The MathJax Consortium 13 * 14 * Licensed under the Apache License, Version 2.0 (the "License"); 15 * you may not use this file except in compliance with the License. 16 * You may obtain a copy of the License at 17 * 18 * http://www.apache.org/licenses/LICENSE-2.0 19 * 20 * Unless required by applicable law or agreed to in writing, software 21 * distributed under the License is distributed on an "AS IS" BASIS, 22 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 23 * See the License for the specific language governing permissions and 24 * limitations under the License. 25 */ 26 27 MathJax.Hub.Register.StartupHook("CommonHTML Jax Ready",function () { 28 var VERSION = "2.6.0"; 29 var MML = MathJax.ElementJax.mml, 30 CHTML = MathJax.OutputJax.CommonHTML; 31 32 var SVGNS = "http://www.w3.org/2000/svg"; 33 var ARROWX = 4, ARROWDX = 1, ARROWY = 2; 34 35 MML.menclose.Augment({ 36 toCommonHTML: function (node) { 37 var values = this.getValues("notation","thickness","padding"); 38 if (values.thickness == null) values.thickness = ".075em"; 39 if (values.padding == null) values.padding = ".2em"; 40 // 41 // Get DOM nodes 42 // 43 node = this.CHTMLdefaultNode(node,{childNodes:"mjx-box", forceChild:true}); 44 var child = node.firstChild, cbox = this.CHTMLbboxFor(0); 45 // 46 // Get the padding and rule thickness 47 // 48 var p = this.CHTMLlength2em(values.padding,1/CHTML.em); // padding for enclosure 49 var t = this.CHTMLlength2em(values.thickness,1/CHTML.em); // thickness of lines 50 t = Math.max(1,Math.round(t*CHTML.em))/CHTML.em; 51 var SOLID = CHTML.Px(t)+" solid"; 52 var bb = {L:p, R:p, T:p, B:p, H:cbox.h+p, D:cbox.d+p, W:cbox.w+2*p}; 53 child.style.padding = CHTML.Em(p); 54 // 55 // Eliminate duplicate notations. 56 // 57 var notations = MathJax.Hub.SplitList(values.notation), notation = {}; 58 for (var i = 0, m = notations.length; i < m; i++) notation[notations[i]] = true; 59 if (notation[MML.NOTATION.UPDIAGONALARROW]) delete notation[MML.NOTATION.UPDIAGONALSTRIKE]; 60 // 61 // Add the needed notations 62 // 63 for (var n in notation) { 64 if (notation.hasOwnProperty(n)) { 65 if (this.CHTMLnotation[n] && this.CHTMLnotation.hasOwnProperty(n)) 66 this.CHTMLnotation[n].call(this,child,cbox,bb,p,t,SOLID); 67 } 68 } 69 // 70 // Adjust the bounding box 71 // 72 var BBOX = this.CHTML; 73 BBOX.w += bb.L + bb.R; BBOX.r += BBOX.L; if (BBOX.w > BBOX.r) BBOX.r = BBOX.w; 74 BBOX.h += bb.T; if (BBOX.h > BBOX.t) BBOX.t = BBOX.h; 75 BBOX.d += bb.B; if (BBOX.d > BBOX.b) BBOX.b = BBOX.d; 76 77 return node; 78 }, 79 // 80 // The various notations and their implementations 81 // 82 CHTMLnotation: { 83 84 /********************************************************/ 85 86 box: function (child,cbox,bb,p,t,SOLID) { 87 p -= t; 88 child.style.padding = CHTML.Em(p); 89 child.style.border = SOLID; 90 }, 91 92 /********************************************************/ 93 94 roundedbox: function (child,cbox,bb,p,t,SOLID) { 95 var r = Math.min(cbox.w,cbox.h+cbox.d+2*p)/4; 96 CHTML.addElement(child.parentNode,"mjx-box",{ 97 style: { 98 padding:CHTML.Em(p-t), border:SOLID, "border-radius":CHTML.Em(r), 99 height:CHTML.Em(cbox.h+cbox.d), "vertical-align":CHTML.Em(-bb.D), 100 width:CHTML.Em(cbox.w), "margin-left":CHTML.Em(-bb.W) 101 } 102 }); 103 }, 104 105 /********************************************************/ 106 107 circle: function (child,cbox,bb,p,t,SOLID) { 108 var H = bb.H, D = bb.D, W = bb.W; 109 var svg = this.CHTMLsvg(child,bb,t); 110 this.CHTMLsvgElement(svg.firstChild,"ellipse",{ 111 rx:CHTML.Px(W/2-t/2), ry:CHTML.Px((H+D)/2-t/2), 112 cx:CHTML.Px(W/2), cy:CHTML.Px((H+D)/2) 113 }); 114 }, 115 116 /********************************************************/ 117 118 left: function (child,cbox,bb,p,t,SOLID) { 119 child.style.borderLeft = SOLID; 120 child.style.paddingLeft = CHTML.Em(p-t); 121 }, 122 123 /********************************************************/ 124 125 right: function (child,cbox,bb,p,t,SOLID) { 126 child.style.borderRight = SOLID; 127 child.style.paddingRight = CHTML.Em(p-t); 128 }, 129 130 /********************************************************/ 131 132 top: function (child,cbox,bb,p,t,SOLID) { 133 child.style.borderTop = SOLID; 134 child.style.paddingTop = CHTML.Em(p-t); 135 }, 136 137 /********************************************************/ 138 139 bottom: function (child,cbox,bb,p,t,SOLID) { 140 child.style.borderBottom = SOLID; 141 child.style.paddingBottom = CHTML.Em(p-t); 142 }, 143 144 /********************************************************/ 145 146 actuarial: function (child,cbox,bb,p,t,SOLID) { 147 child.style.borderTop = child.style.borderRight = SOLID; 148 child.style.paddingTop = child.style.paddingRight = CHTML.Em(p-t); 149 }, 150 151 /********************************************************/ 152 153 madruwb: function (child,cbox,bb,p,t,SOLID) { 154 child.style.borderBottom = child.style.borderRight = SOLID; 155 child.style.paddingBottom = child.style.paddingRight = CHTML.Em(p-t); 156 }, 157 158 /********************************************************/ 159 160 verticalstrike: function (child,cbox,bb,p,t,SOLID) { 161 CHTML.addElement(child.parentNode,"mjx-box",{ 162 style: { 163 "border-left":SOLID, 164 height:CHTML.Em(bb.H+bb.D), "vertical-align":CHTML.Em(-bb.D), 165 width:CHTML.Em(cbox.w/2+p-t/2), "margin-left":CHTML.Em(-cbox.w/2-p-t/2) 166 } 167 }); 168 }, 169 170 /********************************************************/ 171 172 horizontalstrike: function (child,cbox,bb,p,t,SOLID) { 173 CHTML.addElement(child.parentNode,"mjx-box",{ 174 style: { 175 "border-top":SOLID, 176 height:CHTML.Em((bb.H+bb.D)/2-t/2), "vertical-align":CHTML.Em(-bb.D), 177 width:CHTML.Em(bb.W), "margin-left":CHTML.Em(-bb.W) 178 } 179 }); 180 }, 181 182 /********************************************************/ 183 184 updiagonalstrike: function (child,cbox,bb,p,t,SOLID) { 185 var H = bb.H, D = bb.D, W = bb.W; 186 var svg = this.CHTMLsvg(child,bb,t); 187 this.CHTMLsvgElement(svg.firstChild,"line",{ 188 x1:CHTML.Px(t/2), y1:CHTML.Px(H+D-t), x2:CHTML.Px(W-t), y2:CHTML.Px(t/2) 189 }); 190 }, 191 192 /********************************************************/ 193 194 downdiagonalstrike: function (child,cbox,bb,p,t,SOLID) { 195 var H = bb.H, D = bb.D, W = bb.W; 196 var svg = this.CHTMLsvg(child,bb,t); 197 this.CHTMLsvgElement(svg.firstChild,"line",{ 198 x1:CHTML.Px(t/2), y1:CHTML.Px(t/2), x2:CHTML.Px(W-t), y2:CHTML.Px(H+D-t) 199 }); 200 }, 201 202 /********************************************************/ 203 204 updiagonalarrow: function (child,cbox,bb,p,t,SOLID) { 205 var H = bb.H + bb.D - t, W = bb.W - t/2; 206 var a = Math.atan2(H,W)*(-180/Math.PI).toFixed(3); 207 var R = Math.sqrt(H*H + W*W); 208 var svg = this.CHTMLsvg(child,bb,t); 209 var g = this.CHTMLsvgElement(svg.firstChild,"g",{ 210 fill:"currentColor", 211 transform:"translate("+this.CHTMLpx(t/2)+" "+this.CHTMLpx(H+t/2)+") rotate("+a+")" 212 }); 213 var x = t * ARROWX, dx = t * ARROWDX, y = t * ARROWY; 214 this.CHTMLsvgElement(g,"line",{ 215 x1:CHTML.Px(t/2), y1:0, x2:CHTML.Px(R-x), y2:0 216 }); 217 this.CHTMLsvgElement(g,"path",{ 218 d: "M "+this.CHTMLpx(R-x)+",0 " + 219 "L "+this.CHTMLpx(R-x-dx)+","+this.CHTMLpx(y) + 220 "L "+this.CHTMLpx(R)+",0 " + 221 "L "+this.CHTMLpx(R-x-dx)+","+this.CHTMLpx(-y), 222 stroke:"none" 223 }); 224 }, 225 226 /********************************************************/ 227 228 phasorangle: function (child,cbox,bb,p,t,SOLID) { 229 var P = p, H = bb.H, D = bb.D; 230 p = (H+D)/2; 231 var W = bb.W + p - P; bb.W = W; bb.L = p; 232 child.style.margin = "0 0 0 "+CHTML.Em(p-P); 233 var svg = this.CHTMLsvg(child,bb,t); 234 this.CHTMLsvgElement(svg.firstChild,"path",{ 235 d: "M "+this.CHTMLpx(p)+",1 " + 236 "L 1,"+this.CHTMLpx(H+D-t)+" L "+this.CHTMLpx(W)+","+this.CHTMLpx(H+D-t) 237 }); 238 }, 239 240 /********************************************************/ 241 242 longdiv: function (child,cbox,bb,p,t,SOLID) { 243 bb.W += 1.5*p; bb.L += 1.5*p; 244 var H = bb.H, D = bb.D, W = bb.W; 245 child.style.margin = "0 0 0 "+CHTML.Em(1.5*p); 246 var svg = this.CHTMLsvg(child,bb,t); 247 this.CHTMLsvgElement(svg.firstChild,"path",{ 248 d: "M "+this.CHTMLpx(W)+",1 L 1,1 "+ 249 "a"+this.CHTMLpx(p)+","+this.CHTMLpx((H+D)/2-t/2)+" 0 0,1 1,"+this.CHTMLpx(H+D-1.5*t) 250 }); 251 }, 252 253 /********************************************************/ 254 255 radical: function (child,cbox,bb,p,t,SOLID) { 256 bb.W += 1.5*p; bb.L += 1.5*p; 257 var H = bb.H, D = bb.D, W = bb.W; 258 child.style.margin = "0 0 0 "+CHTML.Em(1.5*p); 259 var svg = this.CHTMLsvg(child,bb,t); 260 this.CHTMLsvgElement(svg.firstChild,"path",{ 261 d: "M 1,"+this.CHTMLpx(.6*(H+D)) + 262 " L "+this.CHTMLpx(p)+","+this.CHTMLpx(H+D) + 263 " L "+this.CHTMLpx(2*p)+",1 L "+this.CHTMLpx(W)+",1" 264 }); 265 } 266 267 /********************************************************/ 268 269 }, 270 271 // 272 // Pixels with no "px" 273 // 274 CHTMLpx: function (m) { 275 m *= CHTML.em; 276 if (Math.abs(m) < .1) return "0"; 277 return m.toFixed(1).replace(/\.0$/,""); 278 }, 279 280 // 281 // Create the SVG element and position it over the 282 // contents 283 // 284 CHTMLsvg: function (node,bbox,t) { 285 if (!svg) { 286 var svg = document.createElementNS(SVGNS,"svg"); 287 if (svg.style) { 288 svg.style.width = CHTML.Em(bbox.W); 289 svg.style.height = CHTML.Em(bbox.H+bbox.D); 290 svg.style.verticalAlign = CHTML.Em(-bbox.D); 291 svg.style.marginLeft = CHTML.Em(-bbox.W); 292 } 293 this.CHTMLsvgElement(svg,"g",{"stroke-width":CHTML.Px(t)}); 294 node.parentNode.appendChild(svg); 295 } 296 return svg; 297 }, 298 // 299 // Add an SVG element to the given svg node 300 // 301 CHTMLsvgElement: function (svg,type,def) { 302 var obj = document.createElementNS(SVGNS,type); obj.isMathJax = true; 303 if (def) {for (var id in def) {if (def.hasOwnProperty(id)) {obj.setAttributeNS(null,id,def[id].toString())}}} 304 svg.appendChild(obj); 305 return obj; 306 } 307 }); 308 309 // 310 // Just use default toCommonHTML for EI8 311 // 312 if (!document.createElementNS) delete MML.menclose.prototype.toCommonHTML; 313 314 MathJax.Hub.Startup.signal.Post("CommonHTML menclose Ready"); 315 MathJax.Ajax.loadComplete(CHTML.autoloadDir+"/menclose.js"); 316 }); 317