Skip to content

Commit 27988df

Browse files
katex: Handle nulldelimiter class in spans
Fixes: #1677
1 parent 2a163b2 commit 27988df

File tree

3 files changed

+51
-1
lines changed

3 files changed

+51
-1
lines changed

lib/model/katex.dart

Lines changed: 15 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -386,6 +386,7 @@ class _KatexParser {
386386
final spanClasses = element.className != ''
387387
? List<String>.unmodifiable(element.className.split(' '))
388388
: const <String>[];
389+
double? widthEm;
389390
String? fontFamily;
390391
double? fontSizeEm;
391392
KatexSpanFontWeight? fontWeight;
@@ -576,7 +577,11 @@ class _KatexParser {
576577
_ => throw _KatexHtmlParseError(),
577578
};
578579

579-
// TODO handle .nulldelimiter and .delimcenter .
580+
case 'nulldelimiter':
581+
// .nulldelimiter { display: inline-block; width: 0.12em; }
582+
widthEm = 0.12;
583+
584+
// TODO .delimcenter .
580585

581586
case 'op-symbol':
582587
// .op-symbol { ... }
@@ -621,6 +626,7 @@ class _KatexParser {
621626

622627
final inlineStyles = _parseInlineStyles(element);
623628
final styles = KatexSpanStyles(
629+
widthEm: widthEm,
624630
fontFamily: fontFamily,
625631
fontSizeEm: fontSizeEm,
626632
fontWeight: fontWeight,
@@ -810,6 +816,8 @@ class KatexSpanColor {
810816

811817
@immutable
812818
class KatexSpanStyles {
819+
final double? widthEm;
820+
813821
// TODO(#1674) does height actually appear on generic spans?
814822
// In a corpus, the only occurrences that we don't already handle separately
815823
// (i.e. occurrences other than on struts, vlists, etc) seem to be within
@@ -834,6 +842,7 @@ class KatexSpanStyles {
834842
final KatexSpanColor? color;
835843

836844
const KatexSpanStyles({
845+
this.widthEm,
837846
this.heightEm,
838847
this.topEm,
839848
this.marginRightEm,
@@ -849,6 +858,7 @@ class KatexSpanStyles {
849858
@override
850859
int get hashCode => Object.hash(
851860
'KatexSpanStyles',
861+
widthEm,
852862
heightEm,
853863
topEm,
854864
marginRightEm,
@@ -864,6 +874,7 @@ class KatexSpanStyles {
864874
@override
865875
bool operator ==(Object other) {
866876
return other is KatexSpanStyles &&
877+
other.widthEm == widthEm &&
867878
other.heightEm == heightEm &&
868879
other.topEm == topEm &&
869880
other.marginRightEm == marginRightEm &&
@@ -879,6 +890,7 @@ class KatexSpanStyles {
879890
@override
880891
String toString() {
881892
final args = <String>[];
893+
if (widthEm != null) args.add('widthEm: $widthEm');
882894
if (heightEm != null) args.add('heightEm: $heightEm');
883895
if (topEm != null) args.add('topEm: $topEm');
884896
if (marginRightEm != null) args.add('marginRightEm: $marginRightEm');
@@ -893,6 +905,7 @@ class KatexSpanStyles {
893905
}
894906

895907
KatexSpanStyles filter({
908+
bool widthEm = true,
896909
bool heightEm = true,
897910
bool verticalAlignEm = true,
898911
bool topEm = true,
@@ -906,6 +919,7 @@ class KatexSpanStyles {
906919
bool color = true,
907920
}) {
908921
return KatexSpanStyles(
922+
widthEm: widthEm ? this.widthEm : null,
909923
heightEm: heightEm ? this.heightEm : null,
910924
topEm: topEm ? this.topEm : null,
911925
marginRightEm: marginRightEm ? this.marginRightEm : null,

lib/widgets/katex.dart

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -160,6 +160,9 @@ class _KatexSpan extends StatelessWidget {
160160
}
161161

162162
widget = SizedBox(
163+
width: styles.widthEm != null
164+
? styles.widthEm! * em
165+
: null,
163166
height: styles.heightEm != null
164167
? styles.heightEm! * em
165168
: null,

test/model/katex_test.dart

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -643,6 +643,38 @@ class KatexExample extends ContentExample {
643643
text: '∗'),
644644
]),
645645
]);
646+
647+
static final nulldelimiter = KatexExample.block(
648+
r'\{left,middle,right}. : spans with "nulldelimiter" class',
649+
// https://chat.zulip.org/#narrow/channel/7-test-here/topic/Rajesh/near/2205534
650+
r'\left. a \middle. b \right.',
651+
'<p>'
652+
'<span class="katex-display"><span class="katex">'
653+
'<span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML" display="block"><semantics><mrow><mi>a</mi><mo fence="true" lspace="0.05em" rspace="0.05em">.</mo><mi>b</mi></mrow><annotation encoding="application/x-tex">\\left. a \\middle. b \\right.</annotation></semantics></math></span>'
654+
'<span class="katex-html" aria-hidden="true">'
655+
'<span class="base">'
656+
'<span class="strut" style="height:0.6944em;"></span>'
657+
'<span class="minner">'
658+
'<span class="mopen nulldelimiter"></span>'
659+
'<span class="mord mathnormal">a</span>'
660+
'<span class="nulldelimiter"></span>'
661+
'<span class="mord mathnormal">b</span>'
662+
'<span class="mclose nulldelimiter"></span></span></span></span></span></span></p>', [
663+
KatexSpanNode(nodes: [
664+
KatexStrutNode(heightEm: 0.6944, verticalAlignEm: null),
665+
KatexSpanNode(nodes: [
666+
KatexSpanNode(styles: KatexSpanStyles(widthEm: 0.12), nodes: []),
667+
KatexSpanNode(
668+
styles: KatexSpanStyles(fontFamily: 'KaTeX_Math', fontStyle: KatexSpanFontStyle.italic),
669+
text: 'a'),
670+
KatexSpanNode(styles: KatexSpanStyles(widthEm: 0.12), nodes: []),
671+
KatexSpanNode(
672+
styles: KatexSpanStyles(fontFamily: 'KaTeX_Math', fontStyle: KatexSpanFontStyle.italic),
673+
text: 'b'),
674+
KatexSpanNode(styles: KatexSpanStyles(widthEm: 0.12), nodes: []),
675+
]),
676+
]),
677+
]);
646678
}
647679

648680
void main() async {
@@ -663,6 +695,7 @@ void main() async {
663695
testParseExample(KatexExample.textColor);
664696
testParseExample(KatexExample.customColorMacro);
665697
testParseExample(KatexExample.phantom);
698+
testParseExample(KatexExample.nulldelimiter);
666699

667700
group('parseCssHexColor', () {
668701
const testCases = [

0 commit comments

Comments
 (0)