98 lines
3.1 KiB
Dart
98 lines
3.1 KiB
Dart
// ignore_for_file: depend_on_referenced_packages
|
|
|
|
import 'package:flutter/foundation.dart';
|
|
import 'package:flutter/material.dart';
|
|
import 'package:markdown_widget/markdown_widget.dart';
|
|
import 'package:flutter_math_fork/flutter_math.dart';
|
|
import 'package:markdown/markdown.dart' as m;
|
|
|
|
SpanNodeGeneratorWithTag latexGenerator = SpanNodeGeneratorWithTag(
|
|
tag: _latexTag,
|
|
generator: (e, config, visitor) =>
|
|
LatexNode(e.attributes, e.textContent, config));
|
|
|
|
const _latexTag = 'latex';
|
|
|
|
class LatexSyntax extends m.InlineSyntax {
|
|
LatexSyntax() : super(r'(\$\$[\s\S]+\$\$)|(\$.+?\$)');
|
|
|
|
@override
|
|
bool onMatch(m.InlineParser parser, Match match) {
|
|
final input = match.input;
|
|
final matchValue = input.substring(match.start, match.end);
|
|
String content = '';
|
|
bool isInline = true;
|
|
|
|
const blockSyntax = '\$\$';
|
|
const inlineSyntax = '\$';
|
|
if (matchValue.startsWith(blockSyntax) &&
|
|
matchValue.endsWith(blockSyntax) &&
|
|
(matchValue != blockSyntax)) {
|
|
content = matchValue.substring(2, matchValue.length - 2);
|
|
isInline = false;
|
|
} else if (matchValue.startsWith(inlineSyntax) &&
|
|
matchValue.endsWith(inlineSyntax) &&
|
|
matchValue != inlineSyntax) {
|
|
content = matchValue.substring(1, matchValue.length - 1);
|
|
}
|
|
m.Element el = m.Element.text(_latexTag, matchValue);
|
|
el.attributes['content'] = content;
|
|
el.attributes['isInline'] = '$isInline';
|
|
parser.addNode(el);
|
|
return true;
|
|
}
|
|
}
|
|
|
|
class LatexNode extends SpanNode {
|
|
final Map<String, String> attributes;
|
|
final String textContent;
|
|
final MarkdownConfig config;
|
|
|
|
LatexNode(this.attributes, this.textContent, this.config);
|
|
|
|
@override
|
|
InlineSpan build() {
|
|
final content = attributes['content'] ?? '';
|
|
final isInline = attributes['isInline'] == 'true';
|
|
final style = parentStyle ?? config.code.style;
|
|
if (content.isEmpty) return TextSpan(style: style, text: textContent);
|
|
final latex = Math.tex(
|
|
content,
|
|
mathStyle: MathStyle.text,
|
|
textScaleFactor: 1,
|
|
textStyle: config.code.style.copyWith(
|
|
fontSize: 14,
|
|
fontWeight: FontWeight.bold,
|
|
),
|
|
onErrorFallback: (error) {
|
|
if (kDebugMode) {
|
|
print("Error is: $error");
|
|
}
|
|
return Text(
|
|
textContent,
|
|
style: style,
|
|
);
|
|
},
|
|
);
|
|
return WidgetSpan(
|
|
alignment: PlaceholderAlignment.middle,
|
|
style: style,
|
|
child: Directionality(
|
|
textDirection: TextDirection.ltr, // Change text direction here
|
|
|
|
child: !isInline
|
|
? Container(
|
|
width: double.infinity,
|
|
margin: const EdgeInsets.symmetric(vertical: 12),
|
|
decoration: BoxDecoration(
|
|
color: config.code.style.backgroundColor,
|
|
borderRadius: BorderRadius.circular(10)),
|
|
padding:
|
|
const EdgeInsets.symmetric(horizontal: 2, vertical: 24),
|
|
child: Center(child: Flexible(child: latex)),
|
|
)
|
|
: latex,
|
|
));
|
|
}
|
|
}
|