Skip to content

Commit c4628c7

Browse files
content: Scale inline KaTeX content based on the surrounding text
This applies the correct font scaling if the KaTeX content is inside a header.
1 parent f17ab35 commit c4628c7

File tree

2 files changed

+45
-23
lines changed

2 files changed

+45
-23
lines changed

lib/widgets/content.dart

Lines changed: 25 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -824,22 +824,33 @@ class MathBlock extends StatelessWidget {
824824
child: SingleChildScrollViewWithScrollbar(
825825
scrollDirection: Axis.horizontal,
826826
child: _Katex(
827+
textStyle: ContentTheme.of(context).textStylePlainParagraph,
827828
nodes: nodes)));
828829
}
829830
}
830831

831-
// Base text style from .katex class in katex.scss :
832-
// https://github.com/KaTeX/KaTeX/blob/613c3da8/src/styles/katex.scss#L13-L15
833-
const kBaseKatexTextStyle = TextStyle(
834-
fontSize: kBaseFontSize * 1.21,
835-
fontFamily: 'KaTeX_Main',
836-
height: 1.2);
832+
/// Creates a base text style for rendering KaTeX content.
833+
///
834+
/// This applies the CSS styles defined in .katex class in katex.scss :
835+
/// https://github.com/KaTeX/KaTeX/blob/613c3da8/src/styles/katex.scss#L13-L15
836+
///
837+
/// Requires the [style.fontSize] to be non-null.
838+
TextStyle mkBaseKatexTextStyle(TextStyle style) {
839+
return style.copyWith(
840+
fontSize: style.fontSize! * 1.21,
841+
fontFamily: 'KaTeX_Main',
842+
height: 1.2,
843+
fontWeight: FontWeight.normal,
844+
fontStyle: FontStyle.normal);
845+
}
837846

838847
class _Katex extends StatelessWidget {
839848
const _Katex({
849+
required this.textStyle,
840850
required this.nodes,
841851
});
842852

853+
final TextStyle textStyle;
843854
final List<KatexNode> nodes;
844855

845856
@override
@@ -848,9 +859,8 @@ class _Katex extends StatelessWidget {
848859

849860
return Directionality(
850861
textDirection: TextDirection.ltr,
851-
child: DefaultTextStyle(
852-
style: kBaseKatexTextStyle.copyWith(
853-
color: ContentTheme.of(context).textStylePlainParagraph.color),
862+
child: DefaultTextStyle.merge(
863+
style: mkBaseKatexTextStyle(textStyle),
854864
child: widget));
855865
}
856866
}
@@ -867,9 +877,11 @@ class _KatexNodeList extends StatelessWidget {
867877
return WidgetSpan(
868878
alignment: PlaceholderAlignment.baseline,
869879
baseline: TextBaseline.alphabetic,
870-
child: switch (e) {
871-
KatexSpanNode() => _KatexSpan(e),
872-
});
880+
child: MediaQuery(
881+
data: MediaQueryData(textScaler: TextScaler.noScaling),
882+
child: switch (e) {
883+
KatexSpanNode() => _KatexSpan(e),
884+
}));
873885
}))));
874886
}
875887
}
@@ -1267,7 +1279,7 @@ class _InlineContentBuilder {
12671279
: WidgetSpan(
12681280
alignment: PlaceholderAlignment.baseline,
12691281
baseline: TextBaseline.alphabetic,
1270-
child: _Katex(nodes: nodes));
1282+
child: _Katex(textStyle: widget.style, nodes: nodes));
12711283

12721284
case GlobalTimeNode():
12731285
return WidgetSpan(alignment: PlaceholderAlignment.middle,

test/widgets/content_test.dart

Lines changed: 20 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -595,16 +595,20 @@ void main() {
595595
final content = ContentExample.mathBlockKatexSizing;
596596
await prepareContent(tester, plainContent(content.html));
597597

598+
final context = tester.element(find.byType(MathBlock));
599+
final baseTextStyle =
600+
mkBaseKatexTextStyle(ContentTheme.of(context).textStylePlainParagraph);
601+
598602
final mathBlockNode = content.expectedNodes.single as MathBlockNode;
599603
final baseNode = mathBlockNode.nodes!.single as KatexSpanNode;
600604
final nodes = baseNode.nodes!.skip(1); // Skip .strut node.
601605
for (var katexNode in nodes) {
602606
katexNode = katexNode as KatexSpanNode;
603-
final fontSize = katexNode.styles.fontSizeEm! * kBaseKatexTextStyle.fontSize!;
607+
final fontSize = katexNode.styles.fontSizeEm! * baseTextStyle.fontSize!;
604608
checkKatexText(tester, katexNode.text!,
605609
fontFamily: 'KaTeX_Main',
606610
fontSize: fontSize,
607-
fontHeight: kBaseKatexTextStyle.height!);
611+
fontHeight: baseTextStyle.height!);
608612
}
609613
});
610614

@@ -617,17 +621,21 @@ void main() {
617621
final content = ContentExample.mathBlockKatexNestedSizing;
618622
await prepareContent(tester, plainContent(content.html));
619623

620-
var fontSize = 0.5 * kBaseKatexTextStyle.fontSize!;
624+
final context = tester.element(find.byType(MathBlock));
625+
final baseTextStyle =
626+
mkBaseKatexTextStyle(ContentTheme.of(context).textStylePlainParagraph);
627+
628+
var fontSize = 0.5 * baseTextStyle.fontSize!;
621629
checkKatexText(tester, '1',
622630
fontFamily: 'KaTeX_Main',
623631
fontSize: fontSize,
624-
fontHeight: kBaseKatexTextStyle.height!);
632+
fontHeight: baseTextStyle.height!);
625633

626634
fontSize = 4.976 * fontSize;
627635
checkKatexText(tester, '2',
628636
fontFamily: 'KaTeX_Main',
629637
fontSize: fontSize,
630-
fontHeight: kBaseKatexTextStyle.height!);
638+
fontHeight: baseTextStyle.height!);
631639
});
632640

633641
testWidgets('displays KaTeX content with different delimiter sizing', (tester) async {
@@ -643,13 +651,15 @@ void main() {
643651
final baseNode = mathBlockNode.nodes!.single as KatexSpanNode;
644652
var nodes = baseNode.nodes!.skip(1); // Skip .strut node.
645653

646-
final fontSize = kBaseKatexTextStyle.fontSize!;
654+
final context = tester.element(find.byType(MathBlock));
655+
final baseTextStyle =
656+
mkBaseKatexTextStyle(ContentTheme.of(context).textStylePlainParagraph);
647657

648658
final firstNode = nodes.first as KatexSpanNode;
649659
checkKatexText(tester, firstNode.text!,
650660
fontFamily: 'KaTeX_Main',
651-
fontSize: fontSize,
652-
fontHeight: kBaseKatexTextStyle.height!);
661+
fontSize: baseTextStyle.fontSize!,
662+
fontHeight: baseTextStyle.height!);
653663
nodes = nodes.skip(1);
654664

655665
for (var katexNode in nodes) {
@@ -658,8 +668,8 @@ void main() {
658668
final fontFamily = katexNode.styles.fontFamily!;
659669
checkKatexText(tester, katexNode.text!,
660670
fontFamily: fontFamily,
661-
fontSize: fontSize,
662-
fontHeight: kBaseKatexTextStyle.height!);
671+
fontSize: baseTextStyle.fontSize!,
672+
fontHeight: baseTextStyle.height!);
663673
}
664674
}, skip: true); // TODO: Re-enable this test after adding support for parsing
665675
// `vertical-align` in inline styles. Currently it fails

0 commit comments

Comments
 (0)