Skip to content

Commit 9ad6a9b

Browse files
authored
Merge pull request #2025 from dpvc/issue1970
Improve line breaking algorithm. #1970
2 parents 2fd04cb + 1558970 commit 9ad6a9b

File tree

3 files changed

+59
-26
lines changed

3 files changed

+59
-26
lines changed

unpacked/jax/output/CommonHTML/autoload/multiline.js

Lines changed: 20 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,11 @@ MathJax.Hub.Register.StartupHook("CommonHTML Jax Ready",function () {
2929
var MML = MathJax.ElementJax.mml,
3030
CONFIG = MathJax.Hub.config,
3131
CHTML = MathJax.OutputJax.CommonHTML;
32-
32+
//
33+
// Fake node used for testing end-of-line potential breakpoint
34+
//
35+
var MO = MML.mo().With({CHTML: CHTML.BBOX.empty()});
36+
3337
//
3438
// Penalties for the various line breaks
3539
//
@@ -110,7 +114,7 @@ MathJax.Hub.Register.StartupHook("CommonHTML Jax Ready",function () {
110114
},
111115
broken = false;
112116

113-
while (this.CHTMLbetterBreak(end,state) &&
117+
while (this.CHTMLbetterBreak(end,state,true) &&
114118
(end.scanW >= CHTML.linebreakWidth || end.penalty === PENALTY.newline)) {
115119
this.CHTMLaddLine(stack,start,end.index,state,end.values,broken);
116120
start = end.index.slice(0); broken = true;
@@ -133,7 +137,7 @@ MathJax.Hub.Register.StartupHook("CommonHTML Jax Ready",function () {
133137
//
134138
// Locate the next linebreak that is better than the current one
135139
//
136-
CHTMLbetterBreak: function (info,state) {
140+
CHTMLbetterBreak: function (info,state,toplevel) {
137141
if (this.isToken) return false; // FIXME: handle breaking of token elements
138142
if (this.isEmbellished()) {
139143
info.embellished = this;
@@ -165,6 +169,13 @@ MathJax.Hub.Register.StartupHook("CommonHTML Jax Ready",function () {
165169
}
166170
info.index = []; i++; broken = false;
167171
}
172+
//
173+
// Check if end-of-line is a better breakpoint
174+
//
175+
if (toplevel && better) {
176+
MO.parent = this.parent; MO.inherit = this.inherit;
177+
if (MO.CHTMLbetterBreak(info,state)) {better = false; index = info.index}
178+
}
168179
if (info.nest) {info.nest--}
169180
info.index = index;
170181
if (better) {info.W = W; info.w = w}
@@ -669,10 +680,10 @@ MathJax.Hub.Register.StartupHook("CommonHTML Jax Ready",function () {
669680
// Get the penalty for this type of break and
670681
// use it to modify the default penalty
671682
//
672-
var linebreak = PENALTY[values.linebreak||MML.LINEBREAK.AUTO];
683+
var linebreak = PENALTY[values.linebreak||MML.LINEBREAK.AUTO]||0;
673684
if (!MathJax.Object.isArray(linebreak)) {
674-
// for breaks past the width, don't modify penalty
675-
if (offset >= 0) {penalty = linebreak * info.nest}
685+
// for breaks past the width, keep original penalty for newline
686+
if (linebreak || offset >= 0) {penalty = linebreak * info.nest}
676687
} else {penalty = Math.max(1,penalty + linebreak[0] * info.nest)}
677688
//
678689
// If the penalty is no better than the current one, return false
@@ -715,13 +726,13 @@ MathJax.Hub.Register.StartupHook("CommonHTML Jax Ready",function () {
715726
// Get the penalty for this type of break and
716727
// use it to modify the default penalty
717728
//
718-
var linebreak = PENALTY[linebreakValue];
729+
var linebreak = PENALTY[linebreakValue]||0;
719730
if (linebreakValue === MML.LINEBREAK.AUTO && w >= PENALTY.spacelimit &&
720731
!this.mathbackground && !this.background)
721732
linebreak = [(w+PENALTY.spaceoffset)*PENALTY.spacefactor];
722733
if (!MathJax.Object.isArray(linebreak)) {
723-
// for breaks past the width, don't modify penalty
724-
if (offset >= 0) {penalty = linebreak * info.nest}
734+
// for breaks past the width, keep original penalty for newline
735+
if (linebreak || offset >= 0) {penalty = linebreak * info.nest}
725736
} else {penalty = Math.max(1,penalty + linebreak[0] * info.nest)}
726737
//
727738
// If the penalty is no better than the current one, return false

unpacked/jax/output/HTML-CSS/autoload/multiline.js

Lines changed: 19 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,10 @@ MathJax.Hub.Register.StartupHook("HTML-CSS Jax Ready",function () {
2828
var VERSION = "2.7.4";
2929
var MML = MathJax.ElementJax.mml,
3030
HTMLCSS = MathJax.OutputJax["HTML-CSS"];
31+
//
32+
// Fake node used for testing end-of-line potential breakpoint
33+
//
34+
var MO = MML.mo().With({HTMLspanElement: function () {return {bbox: {w:0}, style: {}}}});
3135

3236
//
3337
// Penalties for the various line breaks
@@ -109,7 +113,7 @@ MathJax.Hub.Register.StartupHook("HTML-CSS Jax Ready",function () {
109113
},
110114
broken = false;
111115

112-
while (this.HTMLbetterBreak(end,state) &&
116+
while (this.HTMLbetterBreak(end,state,true) &&
113117
(end.scanW >= HTMLCSS.linebreakWidth || end.penalty === PENALTY.newline)) {
114118
this.HTMLaddLine(stack,start,end.index,state,end.values,broken);
115119
start = end.index.slice(0); broken = true;
@@ -140,7 +144,7 @@ MathJax.Hub.Register.StartupHook("HTML-CSS Jax Ready",function () {
140144
//
141145
// Locate the next linebreak that is better than the current one
142146
//
143-
HTMLbetterBreak: function (info,state) {
147+
HTMLbetterBreak: function (info,state,toplevel) {
144148
if (this.isToken) {return false} // FIXME: handle breaking of token elements
145149
if (this.isEmbellished()) {
146150
info.embellished = this;
@@ -172,6 +176,13 @@ MathJax.Hub.Register.StartupHook("HTML-CSS Jax Ready",function () {
172176
}
173177
info.index = []; i++; broken = false;
174178
}
179+
//
180+
// Check if end-of-line is a better breakpoint
181+
//
182+
if (toplevel && better) {
183+
MO.parent = this.parent; MO.inherit = this.inherit;
184+
if (MO.HTMLbetterBreak(info,state)) {better = false; index = info.index}
185+
}
175186
if (info.nest) {info.nest--}
176187
info.index = index;
177188
if (better) {info.W = W; info.w = w}
@@ -686,10 +697,10 @@ MathJax.Hub.Register.StartupHook("HTML-CSS Jax Ready",function () {
686697
// Get the penalty for this type of break and
687698
// use it to modify the default penalty
688699
//
689-
var linebreak = PENALTY[values.linebreak||MML.LINEBREAK.AUTO];
700+
var linebreak = PENALTY[values.linebreak||MML.LINEBREAK.AUTO]||0;
690701
if (!MathJax.Object.isArray(linebreak)) {
691-
// for breaks past the width, don't modify penalty
692-
if (offset >= 0) {penalty = linebreak * info.nest}
702+
// for breaks past the width, keep original penalty for newline
703+
if (linebreak || offset >= 0) {penalty = linebreak * info.nest}
693704
} else {penalty = Math.max(1,penalty + linebreak[0] * info.nest)}
694705
//
695706
// If the penalty is no better than the current one, return false
@@ -733,13 +744,13 @@ MathJax.Hub.Register.StartupHook("HTML-CSS Jax Ready",function () {
733744
// Get the penalty for this type of break and
734745
// use it to modify the default penalty
735746
//
736-
var linebreak = PENALTY[linebreakValue];
747+
var linebreak = PENALTY[linebreakValue]||0;
737748
if (linebreakValue === MML.LINEBREAK.AUTO && w >= PENALTY.spacelimit &&
738749
!this.mathbackground && !this.background)
739750
{linebreak = [(w+PENALTY.spaceoffset)*PENALTY.spacefactor]}
740751
if (!MathJax.Object.isArray(linebreak)) {
741-
// for breaks past the width, don't modify penalty
742-
if (offset >= 0) {penalty = linebreak * info.nest}
752+
// for breaks past the width, keep original penalty for newline
753+
if (linebreak || offset >= 0) {penalty = linebreak * info.nest}
743754
} else {penalty = Math.max(1,penalty + linebreak[0] * info.nest)}
744755
//
745756
// If the penalty is no better than the current one, return false

unpacked/jax/output/SVG/autoload/multiline.js

Lines changed: 20 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,11 @@ MathJax.Hub.Register.StartupHook("SVG Jax Ready",function () {
2929
var MML = MathJax.ElementJax.mml,
3030
SVG = MathJax.OutputJax.SVG,
3131
BBOX = SVG.BBOX;
32-
32+
//
33+
// Fake node used for testing end-of-line potential breakpoint
34+
//
35+
var MO = MML.mo().With({SVGdata: {w: 0, x:0}});
36+
3337
//
3438
// Penalties for the various line breaks
3539
//
@@ -115,7 +119,7 @@ MathJax.Hub.Register.StartupHook("SVG Jax Ready",function () {
115119
//
116120
// Break the expression at its best line breaks
117121
//
118-
while (this.SVGbetterBreak(end,state) &&
122+
while (this.SVGbetterBreak(end,state,true) &&
119123
(end.scanW >= SVG.linebreakWidth || end.penalty === PENALTY.newline)) {
120124
this.SVGaddLine(svg,start,end.index,state,end.values,broken);
121125
start = end.index.slice(0); broken = true;
@@ -145,7 +149,7 @@ MathJax.Hub.Register.StartupHook("SVG Jax Ready",function () {
145149
//
146150
// Locate the next linebreak that is better than the current one
147151
//
148-
SVGbetterBreak: function (info,state) {
152+
SVGbetterBreak: function (info,state,toplevel) {
149153
if (this.isToken) {return false} // FIXME: handle breaking of token elements
150154
if (this.isEmbellished()) {
151155
info.embellished = this;
@@ -177,6 +181,13 @@ MathJax.Hub.Register.StartupHook("SVG Jax Ready",function () {
177181
}
178182
info.index = []; i++; broken = false;
179183
}
184+
//
185+
// Check if end-of-line is a better breakpoint
186+
//
187+
if (toplevel && better) {
188+
MO.parent = this.parent; MO.inherit = this.inherit;
189+
if (MO.SVGbetterBreak(info,state)) {better = false; index = info.index}
190+
}
180191
if (info.nest) {info.nest--}
181192
info.index = index;
182193
if (better) {info.W = W}
@@ -607,10 +618,10 @@ MathJax.Hub.Register.StartupHook("SVG Jax Ready",function () {
607618
// Get the penalty for this type of break and
608619
// use it to modify the default penalty
609620
//
610-
var linebreak = PENALTY[values.linebreak||MML.LINEBREAK.AUTO];
621+
var linebreak = PENALTY[values.linebreak||MML.LINEBREAK.AUTO]||0;
611622
if (!MathJax.Object.isArray(linebreak)) {
612-
// for breaks past the width, don't modify penalty
613-
if (offset >= 0) {penalty = linebreak * info.nest}
623+
// for breaks past the width, keep original penalty for newline
624+
if (linebreak || offset >= 0) {penalty = linebreak * info.nest}
614625
} else {penalty = Math.max(1,penalty + linebreak[0] * info.nest)}
615626
//
616627
// If the penalty is no better than the current one, return false
@@ -653,13 +664,13 @@ MathJax.Hub.Register.StartupHook("SVG Jax Ready",function () {
653664
// Get the penalty for this type of break and
654665
// use it to modify the default penalty
655666
//
656-
var linebreak = PENALTY[linebreakValue];
667+
var linebreak = PENALTY[linebreakValue]||0;
657668
if (linebreakValue === MML.LINEBREAK.AUTO && w >= PENALTY.spacelimit*1000 &&
658669
!this.mathbackground && !this.backrgound)
659670
{linebreak = [(w/1000+PENALTY.spaceoffset)*PENALTY.spacefactor]}
660671
if (!MathJax.Object.isArray(linebreak)) {
661-
// for breaks past the width, don't modify penalty
662-
if (offset >= 0) {penalty = linebreak * info.nest}
672+
// for breaks past the width, keep original penalty for newline
673+
if (linebreak || offset >= 0) {penalty = linebreak * info.nest}
663674
} else {penalty = Math.max(1,penalty + linebreak[0] * info.nest)}
664675
//
665676
// If the penalty is no better than the current one, return false

0 commit comments

Comments
 (0)