completeOpenMath function
The formula left open at the end of source, closed so that it parses.
Returns where its opener starts and the text to render in place of
source.substring(start), or null when every formula in source is
closed. Returns null too when a code span is still open, since its
backticks swallow any \( inside.
\( and \[ are always maths; $$ and $ only when dollarsAreMath.
A $ before a digit is a price, as elsewhere in the streaming hold.
Implementation
({int start, String completed})? completeOpenMath(
String source, {
required bool dollarsAreMath,
}) {
final n = source.length;
var i = 0;
while (i < n) {
final c = source.codeUnitAt(i);
if (c == 0x60 /* ` */ ) {
final close = source.indexOf('`', i + 1);
if (close == -1) return null;
i = close + 1;
continue;
}
if (c == 0x5C /* \ */ && i + 1 < n) {
final next = source.codeUnitAt(i + 1);
if (next == 0x28 /* ( */ || next == 0x5B /* [ */ ) {
final closer = next == 0x28 ? r'\)' : r'\]';
final end = source.indexOf(closer, i + 2);
if (end == -1) {
return _open(source, i, i + 2, source.substring(i, i + 2), closer);
}
i = end + 2;
continue;
}
// Any other escape, `\$` included, is one unit.
i += 2;
continue;
}
if (dollarsAreMath && c == 0x24 /* $ */ ) {
if (i + 1 < n && source.codeUnitAt(i + 1) == 0x24) {
final end = source.indexOf(r'$$', i + 2);
if (end == -1) return _open(source, i, i + 2, r'\[', r'\]');
i = end + 2;
continue;
}
final next = i + 1 < n ? source.codeUnitAt(i + 1) : -1;
if (next >= 0x30 && next <= 0x39) {
i += 1;
continue;
}
final end = _unescapedDollar(source, i + 1);
if (end == -1) return _open(source, i, i + 1, r'\(', r'\)');
i = end + 1;
continue;
}
i += 1;
}
return null;
}