Việc tạo và hiển thị công thức toán, lý, hóa dùng phần mềm như word, laTex, MathType đã không còn xa lạ với nhiều người. Trong bài viết này mình sẽ trình bày cách để hiển thị được các công thức này trên mobile app, cụ thể là framework Flutter.
1. Cài đặt thư viện
1.1. Chạy câu lệnh cài đặt
flutter pub add flutter_tex
Sau khi hoàn tất, file package pubspec.yaml sẽ có thêm dependency sau
dependencies:
flutter_tex: ^4.0.3+4
1.2. Import các cài đặt cần thiết
Flutter có 3 folder tương ứng với 3 nền tảng chạy ứng dụng là android, ios và web. Mình sẽ lần lượt thêm các configuration vào 3 folder này như sau.
Android
Thêm vào file android/app/src/main/AndroidManifest.xml như sau
<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
<uses-permission android:name="android.permission.WAKE_LOCK" />
<application
...
...
android:usesCleartextTraffic="true">
</application>
Vì package flutter_tex sử dụng webview nên yêu cầu quyền truy cập internet, do đó ta phải thêm user-permission như trên, còn về bản chất ứng dụng vẫn hoạt động offline.
iOS
Thêm vào file ios/Runner/Info.plist như sau
<key>NSAppTransportSecurity</key>
<dict>
<key>NSAllowsArbitraryLoads</key> <true/>
</dict>
<key>io.flutter.embedded_views_preview</key> <true/>
web
Thêm vào file web/index.html như sau
<head>
<meta charset="UTF-8">
<title>Flutter TeX</title>
<script src="assets/packages/flutter_tex/js/flutter_tex.js"></script>
<script type="text/javascript">window.flutterWebRenderer = "canvaskit";</script>
</head>
File flutter_tex.js có thể lấy ở link sau
https://github.com/shah-xad/flutter_tex/blob/master/lib/js/flutter_tex.js
2. Sử dụng thư viện
2.1. Import thư viện
import 'package:flutter_tex/flutter_tex.dart';
2.2. Thư viện có các component chính sau
TeXViewWidget là abstract widget, các widget khác đều kế thừa từ widget này, ví dụ như TeXViewDocument, TeXViewMarkdown, TeXViewImage, TeXViewColumn, ...
TeXView là một class giúp hiển thị công thức, với đầy đủ các property như child, fonts, style, trong đó child là TeXViewWidget sẽ được render.
2.3. Chạy thử một example
Mình sẽ chạy lại example dưới đây của thư viện (đã được chỉnh sửa cho gọn)Code
Khai báo công thức dùng widget TeXViewWidget
class TeXExample chứa 2 field quadraticEquation và bohrRadius, cả 2 đều có type là TeXViewWidget.
class TeXExample {
static TeXViewWidget quadraticEquation =
_teXViewWidget(r"<h4>Quadratic Equation</h4>", r"""
When \(a \ne 0 \), there are two solutions to \(ax^2 + bx + c = 0\) and they are
$$x = {-b \pm \sqrt{b^2-4ac} \over 2a}.$$<br>""");
static TeXViewWidget bohrRadius = _teXViewWidget(r"<h4>Bohr's Radius</h4>",
r"""\( a_0 = \frac{{\hbar ^2 }}{{m_e ke^2 }} \)""");
static TeXViewWidget _teXViewWidget(String title, String body) {
return TeXViewColumn(
style: const TeXViewStyle(
margin: TeXViewMargin.all(10),
padding: TeXViewPadding.all(10),
borderRadius: TeXViewBorderRadius.all(10),
border: TeXViewBorder.all(TeXViewBorderDecoration(
borderWidth: 2,
borderStyle: TeXViewBorderStyle.groove,
borderColor: Colors.green))),
children: [
TeXViewDocument(title,
style: const TeXViewStyle(
padding: TeXViewPadding.all(10),
borderRadius: TeXViewBorderRadius.all(10),
textAlign: TeXViewTextAlign.center,
width: 250,
margin: TeXViewMargin.zeroAuto(),
backgroundColor: Colors.green)),
TeXViewDocument(body,
style: const TeXViewStyle(margin: TeXViewMargin.only(top: 10)))
]);
}
}
Render 2 phương trình quadraticEquation và bohrRadius như sau
class TeXViewDocumentExamples extends StatelessWidget {
final TeXViewRenderingEngine renderingEngine;
const TeXViewDocumentExamples(
{Key? key, this.renderingEngine = const TeXViewRenderingEngine.katex()})
: super(key: key);
@override
Widget build(BuildContext context) {
return Scaffold(
backgroundColor: Colors.white,
appBar: AppBar(
title: const Text("TeXViewDocument"),
),
body: TeXView(
renderingEngine: renderingEngine,
child: TeXViewColumn(children: [
TeXExample.quadraticEquation,
TeXExample.bohrRadius,
if (renderingEngine.name == 'mathjax') ...[TeXExample.others]
]),
style: const TeXViewStyle(
margin: TeXViewMargin.all(10),
elevation: 10,
borderRadius: TeXViewBorderRadius.all(25),
border: TeXViewBorder.all(
TeXViewBorderDecoration(
borderColor: Colors.blue,
borderStyle: TeXViewBorderStyle.solid,
borderWidth: 5),
),
backgroundColor: Colors.white,
),
),
);
}
}
Kết qủa
Như ta thấy được các công thức latex đã được render chính xác.