texBreak method
Line breaking results using standard TeX-style line breaking.
This function will return a list of EquationRowNode
along with a list
of line breaking penalties.
This function will break the equation into pieces according to TeX spec
as much as possible (some exceptions exist when enforceNoBreak: true
). Then, you can assemble the pieces in whatever way you like. The most
simple way is to put the parts inside a Wrap
.
If you wish to implement a custom line breaking policy to manage the
penalties, you can access the penalties in BreakResult.penalties
. The
values in BreakResult.penalties
represent the line-breaking penalty
generated at the right end of each BreakResult.parts
. Note that
\nobreak
or \penalty<number>=10000>
are left unbroken by default, you
need to supply enforceNoBreak: false
into Math.texBreak
to expose
those break points and their penalties.
Implementation
BreakResult<EquationRowNode> texBreak({
int relPenalty = 500,
int binOpPenalty = 700,
bool enforceNoBreak = true,
}) {
final breakIndices = <int>[];
final penalties = <int>[];
for (var i = 0; i < flattenedChildList.length; i++) {
final child = flattenedChildList[i];
// Peek ahead to see if the next child is a no-break
if (i < flattenedChildList.length - 1) {
final nextChild = flattenedChildList[i + 1];
if (nextChild is SpaceNode &&
nextChild.breakPenalty != null &&
nextChild.breakPenalty! >= 10000) {
if (!enforceNoBreak) {
// The break point should be moved to the next child, which is a \nobreak.
continue;
} else {
// In enforced mode, we should cancel the break point all together.
i++;
continue;
}
}
}
if (child.rightType == AtomType.bin) {
breakIndices.add(i);
penalties.add(binOpPenalty);
} else if (child.rightType == AtomType.rel) {
breakIndices.add(i);
penalties.add(relPenalty);
} else if (child is SpaceNode && child.breakPenalty != null) {
breakIndices.add(i);
penalties.add(child.breakPenalty!);
}
}
final res = <EquationRowNode>[];
var pos = 1;
for (var i = 0; i < breakIndices.length; i++) {
final breakEnd = caretPositions[breakIndices[i] + 1];
res.add(this.clipChildrenBetween(pos, breakEnd).wrapWithEquationRow());
pos = breakEnd;
}
if (pos != caretPositions.last) {
res.add(this
.clipChildrenBetween(pos, caretPositions.last)
.wrapWithEquationRow());
penalties.add(10000);
}
return BreakResult<EquationRowNode>(
parts: res,
penalties: penalties,
);
}