flutter_mathjax 0.0.1
flutter_mathjax: ^0.0.1 copied to clipboard
A Flutter package for rendering LaTeX using MathJax v2 with support for automatic line breaking, offline caching, and performance optimizations.
import 'dart:ui' as ui;
import 'package:flutter/foundation.dart';
import 'package:flutter/material.dart';
import 'package:flutter/rendering.dart';
import 'package:flutter_inappwebview/flutter_inappwebview.dart';
import 'package:flutter_mathjax/flutter_mathjax.dart';
void main() async {
WidgetsFlutterBinding.ensureInitialized();
if (!kIsWeb && defaultTargetPlatform == TargetPlatform.android) {
await InAppWebViewController.setWebContentsDebuggingEnabled(false);
PlatformInAppWebViewController.debugLoggingSettings.enabled = false;
}
await MathJaxManager.inst.init();
runApp(MaterialApp(home: const DemoLatexPage()));
}
class DemoLatexPage extends StatefulWidget {
const DemoLatexPage({super.key});
@override
State<DemoLatexPage> createState() => _DemoLatexPageState();
}
class _DemoLatexPageState extends State<DemoLatexPage> {
final GlobalKey _scaffoldKey = GlobalKey();
Uint8List? _capturedScaffoldImage;
@override
Widget build(BuildContext context) {
return RepaintBoundary(
key: _scaffoldKey,
child: Scaffold(
backgroundColor: Colors.amberAccent,
body: SingleChildScrollView(
padding: const EdgeInsets.all(16.0),
child: Column(
crossAxisAlignment: CrossAxisAlignment.stretch,
children: [
const SizedBox(height: 20),
const Text('MathJax Rendering Test:'),
const SizedBox(height: 20),
...testCase.entries.map((e) => MathJaxView(latex: e.value)),
const SizedBox(height: 20),
ElevatedButton(
onPressed: _captureSnapshot,
child: const Text('Snapshot'),
),
if (_capturedScaffoldImage != null) ...[
const SizedBox(height: 20),
const Text('Captured Snapshot:'),
const SizedBox(height: 10),
Image.memory(_capturedScaffoldImage!, fit: BoxFit.contain),
],
],
),
),
),
);
}
// You can capture if latex can be cached, otherwise it will be blank
Future<void> _captureSnapshot() async {
final boundary =
_scaffoldKey.currentContext!.findRenderObject()
as RenderRepaintBoundary;
final image = await boundary.toImage(pixelRatio: 3.0);
final byteData = await image.toByteData(format: ui.ImageByteFormat.png);
if (byteData != null) {
setState(() {
_capturedScaffoldImage = byteData.buffer.asUint8List();
});
}
}
final testCase = {
1: r"""
### Test ngắt dòng tự động (V2 Engine):
$$ \large \begin{gathered} B = \dfrac{5x^2 + 10xy}{x^2 + 2xy + 4y^2} : \dfrac{x + 2y}{x^3 - 8y^3} = \dfrac{5x(x + 2y)}{x^2 + 2xy + 4y^2} . \dfrac{(x - 2y)(x^2 + 2xy + 4y^2)}{x + 2y} = 5x(x - 2y) \end{gathered} $$
Dãy số siêu dài:
$$ 1+2+3+4+5+6+7+8+9+10+11+12+13+14+15+16+17+18+19+20+21+22+23+24+25+26+27+28+29+30+31+32+33+34+35+36+37+38+39+40 $$
""",
2: r'''<p>Giải phương trình bậc hai sau:</p>
<div class="math-box">
$$ax^2 + bx + c = 0 \Rightarrow x = \frac{-b \pm \sqrt{b^2 - 4ac}}{2a}$$
</div>''',
3: r'''<p><b>Hình minh họa:</b></p>
<img src="https://baitoan.com/wp-content/uploads/2021/10/bai-toan-ve-do-thi-ham-so-y-x.png" alt="Đồ thị">
<p><b>Công thức dài (Test Line Break):</b></p>
<div class="math-box">
$$P(x) = a_n x^n + a_{n-1} x^{n-1} + a_{n-2} x^{n-2} + a_{n-3} x^{n-3} + a_{n-4} x^{n-4} + a_{n-5} x^{n-5} + a_0 = 0$$
</div>
<p><b>Video bài giảng:</b></p>
<video controls>
<source src="https://www.w3schools.com/html/mov_bbb.mp4" type="video/mp4">
Trình duyệt của bạn không hỗ trợ video.
</video>
<p><b>Giải thích bằng âm thanh:</b></p>
<audio controls>
<source src="https://www.w3schools.com/html/horse.ogg" type="audio/ogg">
</audio>''',
};
}