menclose.js 11 KB

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