multiline.js 10 KB

12345678910111213141516171819202122232425
  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/SVG/autoload/multiline.js
  6. *
  7. * Implements the SVG output for <mrow>'s that contain line breaks.
  8. *
  9. * ---------------------------------------------------------------------
  10. *
  11. * Copyright (c) 2011-2013 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. */MathJax.Hub.Register.StartupHook("SVG Jax Ready",function(){var h=MathJax.ElementJax.mml,l=MathJax.OutputJax.SVG,r=l.BBOX,m={newline:0,nobreak:1E6,goodbreak:[-200],badbreak:[200],auto:[0],toobig:800,nestfactor:400,spacefactor:-100,spaceoffset:2,spacelimit:1,fence:500,close:500},t={linebreakstyle:"after"};h.mrow.Augment({SVGmultiline:function(a){for(a=this;a.inferred||a.parent&&"mrow"===a.parent.type&&1===a.parent.data.length;)a=a.parent;var d="math"===a.type&&"block"===a.Get("display")||"mtd"===a.type;a.isMultiline=!0;var b=this.getValues("linebreak","linebreakstyle","lineleading","linebreakmultchar","indentalign","indentshift","indentalignfirst","indentshiftfirst","indentalignlast","indentshiftlast");b.linebreakstyle===h.LINEBREAKSTYLE.INFIXLINEBREAKSTYLE&&(b.linebreakstyle=this.Get("infixlinebreakstyle"));b.lineleading=l.length2em(b.lineleading,1,.5);a=this.SVG();a.w=l.linebreakWidth<l.BIGDIMEN?l.linebreakWidth:l.cwidth/l.em*1E3;for(var d={n:0,Y:0,scale:this.SVGgetScale(),isTop:d,values:{},VALUES:b},b=this.SVGgetAlign(d,{}),c=this.SVGgetShift(d,{},b),e=[],f={index:[],penalty:m.nobreak,w:0,W:c,shift:c,scanW:c,nest:0},g=!1;this.SVGbetterBreak(f,d)&&(f.scanW>=l.linebreakWidth||f.penalty==m.newline);)this.SVGaddLine(a,e,f.index,d,f.values,g),e=f.index.slice(0),g=!0,b=this.SVGgetAlign(d,f.values),c=this.SVGgetShift(d,f.values,b),b===h.INDENTALIGN.CENTER&&(c=0),f.W=f.shift=f.scanW=c,f.penalty=m.nobreak;d.isLast=!0;this.SVGaddLine(a,e,[],d,t,g);this.SVGhandleSpace(a);this.SVGhandleColor(a);a.isMultiline=!0;this.SVGsaveData(a);return a}});h.mbase.Augment({SVGlinebreakPenalty:m,SVGbetterBreak:function(a,d){if(this.isToken)return!1;if(this.isEmbellished())return a.embellished=this,this.CoreMO().SVGbetterBreak(a,d);if(this.linebreakContainer)return!1;var b=a.index.slice(0),c=a.index.shift(),e=this.data.length,f,g,h=0<a.index.length,k=!1;null==c&&(c=-1);h||(c++,a.W+=a.w,a.w=0);g=a.scanW=a.W;for(a.nest++;c<e&&a.scanW<1.33*l.linebreakWidth;){if(this.data[c]){if(this.data[c].SVGbetterBreak(a,d)&&(k=!0,b=[c].concat(a.index),f=a.W,a.penalty===m.newline))return a.index=b,a.nest--,!0;g=h?a.scanW:this.SVGaddWidth(c,a,g)}a.index=[];c++;h=!1}a.nest--;a.index=b;k&&(a.W=f);return k},SVGaddWidth:function(a,d,b){this.data[a]&&(a=this.data[a].SVGdata,b+=a.w+a.x,a.X&&(b+=a.X),d.W=d.scanW=b,d.w=0);return b},SVGaddLine:function(a,d,b,c,e,f){var g=r();c.first=f;c.last=!0;this.SVGmoveLine(d,b,g,c,e);g.Clean();d=this.SVGgetAlign(c,e);if(b=this.SVGgetShift(c,e,d))d===h.INDENTALIGN.LEFT?g.x=b:d===h.INDENTALIGN.RIGHT&&(g.w+=b,g.r=g.w);0<c.n&&(c.Y-=Math.max(l.FONTDATA.baselineskip*c.scale,c.d+g.h+(null==c.values.lineleading?c.VALUES:c.values).lineleading));a.Align(g,d,0,c.Y);c.d=g.d;c.values=e;c.n++},SVGgetAlign:function(a,d){var b=a.values,c=a.VALUES,e;e=0===a.n?d.indentalignfirst||b.indentalignfirst||c.indentalignfirst:a.isLast?b.indentalignlast||c.indentalignlast:b.indentalign||c.indentalign;e===h.INDENTALIGN.INDENTALIGN&&(e=b.indentalign||c.indentalign);e===h.INDENTALIGN.AUTO&&(e=a.isTop?this.displayAlign:h.INDENTALIGN.LEFT);return e},SVGgetShift:function(a,d,b){if(b===h.INDENTALIGN.CENTER)return 0;b=a.values;var c=a.VALUES;d=0===a.n?d.indentshiftfirst||b.indentshiftfirst||c.indentshiftfirst:a.isLast?b.indentshiftlast||c.indentshiftlast:b.indentshift||c.indentshift;d===h.INDENTSHIFT.INDENTSHIFT&&(d=b.indentshift||c.indentshift);if("auto"===d||""===d)d=a.isTSop?this.displayIndent:"0";return l.length2em(d,0)},SVGmoveLine:function(a,d,b,c,e){var f=a[0],g=d[0];null==f&&(f=-1);null==g&&(g=this.data.length-1);if(f===g&&1<a.length)this.data[f].SVGmoveSlice(a.slice(1),d.slice(1),b,c,e,"paddingLeft");else{var h=c.last;for(c.last=!1;f<g;)this.data[f]&&(1>=a.length?this.data[f].SVGmove(b,c,e):this.data[f].SVGmoveSlice(a.slice(1),[],b,c,e,"paddingLeft")),f++,c.first=!1,a=[];c.last=h;this.data[f]&&(1>=d.length?this.data[f].SVGmove(b,c,e):this.data[f].SVGmoveSlice([],d.slice(1),b,c,e,"paddingRight"))}},SVGmoveSlice:function(a,d,b,c,e,f){f=r();this.SVGmoveLine(a,d,f,c,e);f.Clean();this.SVGhandleColor(f);b.Add(f,b.w,0,!0);return f},SVGmove:function(a,d,b){if(!d.first&&!d.last||d.first&&d.values.linebreakstyle===h.LINEBREAKSTYLE.BEFORE||d.last&&b.linebreakstyle===h.LINEBREAKSTYLE.AFTER){b=this.toSVG(this.SVGdata.HW,this.SVGdata.D);d.last&&(b.x=0);if(d.first||d.nextIsFirst)delete d.nextIsFirst,b.X&&(b.X=0);a.Add(b,a.w,0,!0)}else d.first?d.nextIsFirst=!0:delete d.nextIsFirst}});h.mfenced.Augment({SVGbetterBreak:function(a,d){var b=a.index.slice(0),c=a.index.shift(),e=this.data.length,f,g,h,k=0<a.index.length,q=!1;null==c&&(c=-1);k||(c++,a.W+=a.w,a.w=0);h=a.scanW=a.W;a.nest++;if(!this.dataI){this.dataI=[];this.data.open&&this.dataI.push("open");e&&this.dataI.push(0);for(var p=1;p<e;p++)this.data["sep"+p]&&this.dataI.push("sep"+p),this.dataI.push(p);this.data.close&&this.dataI.push("close")}for(e=this.dataI.length;c<e&&a.scanW<1.33*l.linebreakWidth;){p=this.dataI[c];if(this.data[p]){if(this.data[p].SVGbetterBreak(a,d)&&(q=!0,b=[c].concat(a.index),f=a.W,g=a.w,a.penalty===m.newline))return a.index=b,a.nest--,!0;h=k?a.scanW:this.SVGaddWidth(c,a,h)}a.index=[];c++;k=!1}a.nest--;a.index=b;q&&(a.W=f,a.w=g);return q},SVGmoveLine:function(a,d,b,c,e){var f=a[0],g=d[0];null==f&&(f=-1);null==g&&(g=this.dataI.length-1);if(f===g&&1<a.length)this.data[this.dataI[f]].SVGmoveSlice(a.slice(1),d.slice(1),b,c,e,"paddingLeft");else{var h=c.last;c.last=!1;for(var k=this.dataI[f];f<g;)this.data[k]&&(1>=a.length?this.data[k].SVGmove(b,c,e):this.data[k].SVGmoveSlice(a.slice(1),[],b,c,e,"paddingLeft")),f++,k=this.dataI[f],c.first=!1,a=[];c.last=h;this.data[k]&&(1>=d.length?this.data[k].SVGmove(b,c,e):this.data[k].SVGmoveSlice([],d.slice(1),b,c,e,"paddingRight"))}}});h.msubsup.Augment({SVGbetterBreak:function(a,d){if(!this.data[this.base])return!1;var b=a.index.slice(0),c=a.index.shift(),e,f,g,h=0<a.index.length,k=!1;h||(a.W+=a.w,a.w=0);g=a.scanW=a.W;null==c&&(this.SVGdata.dw=this.SVGdata.w-this.data[this.base].SVGdata.w);this.data[this.base].SVGbetterBreak(a,d)&&(k=!0,b=[this.base].concat(a.index),e=a.W,f=a.w,a.penalty===m.newline&&(k=h=!0));h||this.SVGaddWidth(this.base,a,g);a.scanW+=this.SVGdata.dw;a.W=a.scanW;a.index=[];k&&(a.W=e,a.w=f,a.index=b);return k},SVGmoveLine:function(a,d,b,c,e){this.data[this.base]&&(1<a.length?this.data[this.base].SVGmoveSlice(a.slice(1),d.slice(1),b,c,e,"paddingLeft"):1>=d.length?this.data[this.base].SVGmove(b,c,e):this.data[this.base].SVGmoveSlice([],d.slice(1),b,c,e,"paddingRight"));0===d.length&&(a=this.data[this.sup],d=this.data[this.sub],c=b.w,a&&(e=a.SVGdata,b.Add(a.toSVG(),c+(e.dx||0),e.dy)),d&&(e=d.SVGdata,b.Add(d.toSVG(),c+(e.dx||0),e.dy)))}});h.mo.Augment({SVGbetterBreak:function(a,d){if(a.values&&a.values.last===this)return!1;var b=this.getValues("linebreak","linebreakstyle","lineleading","linebreakmultchar","indentalign","indentshift","indentalignfirst","indentshiftfirst","indentalignlast","indentshiftlast","texClass","fence");b.linebreakstyle===h.LINEBREAKSTYLE.INFIXLINEBREAKSTYLE&&(b.linebreakstyle=this.Get("infixlinebreakstyle"));b.texClass===h.TEXCLASS.OPEN&&a.nest++;b.texClass===h.TEXCLASS.CLOSE&&a.nest--;var c=a.scanW,e=a.embellished||this;delete a.embellished;e=e.SVGdata;e=e.w+e.x;b.linebreakstyle===h.LINEBREAKSTYLE.AFTER&&(c+=e,e=0);if(0===c-a.shift)return!1;var f=l.linebreakWidth-c;if(0===d.n&&(b.indentshiftfirst!==d.VALUES.indentshiftfirst||b.indentalignfirst!==d.VALUES.indentalignfirst))var g=this.SVGgetAlign(d,b),g=this.SVGgetShift(d,b,g),f=f+(a.shift-g);g=Math.floor(f/l.linebreakWidth*1E3);0>g&&(g=m.toobig-3*g);b.fence&&(g+=m.fence);if(b.linebreakstyle===h.LINEBREAKSTYLE.AFTER&&b.texClass===h.TEXCLASS.OPEN||b.texClass===h.TEXCLASS.CLOSE)g+=m.close;var g=g+a.nest*m.nestfactor,n=m[b.linebreak||h.LINEBREAK.AUTO];n instanceof Array?g=Math.max(1,g+n[0]*a.nest):0<=f&&(g=n*a.nest);if(g>=a.penalty)return!1;a.penalty=g;a.values=b;a.W=c;a.w=e;b.lineleading=l.length2em(b.lineleading,d.VALUES.lineleading);b.last=this;return!0}});h.mspace.Augment({SVGbetterBreak:function(a,d){if(a.values&&a.values.last===this)return!1;var b=this.getValues("linebreak"),c=b.linebreak;if(!c||this.hasDimAttr())c=h.LINEBREAK.AUTO;var e=a.scanW,f=this.SVGdata,f=f.w+f.x;if(0===e-a.shift)return!1;var g=l.linebreakWidth-e,n=Math.floor(g/l.linebreakWidth*1E3);0>n&&(n=m.toobig-3*n);var n=n+a.nest*m.nestfactor,k=m[c];c===h.LINEBREAK.AUTO&&f>=1E3*m.spacelimit&&(k=[(f+m.spaceoffset)*m.spacefactor]);k instanceof Array?n=Math.max(1,n+k[0]*a.nest):0<=g&&(n=k*a.nest);if(n>=a.penalty)return!1;a.penalty=n;a.values=b;a.W=e;a.w=f;b.lineleading=d.VALUES.lineleading;b.linebreakstyle="before";b.last=this;return!0}});MathJax.Hub.Register.StartupHook("TeX mathchoice Ready",function(){h.TeXmathchoice.Augment({SVGbetterBreak:function(a,d){return this.Core().SVGbetterBreak(a,d)},SVGmoveLine:function(a,d,b,c,e){return this.Core().SVGmoveSlice(a,d,b,c,e)}})});h.maction.Augment({SVGbetterBreak:function(a,d){return this.Core().SVGbetterBreak(a,d)},SVGmoveLine:function(a,d,b,c,e){return this.Core().SVGmoveSlice(a,d,b,c,e)}});h.semantics.Augment({SVGbetterBreak:function(a,d){return this.data[0]?this.data[0].SVGbetterBreak(a,d):!1},SVGmoveLine:function(a,d,b,c,e){return this.data[0]?this.data[0].SVGmoveSlice(a,d,b,c,e):null}});MathJax.Hub.Startup.signal.Post("SVG multiline Ready");MathJax.Ajax.loadComplete(l.autoloadDir+"/multiline.js")});