Showing
7 changed files
with
201 additions
and
78 deletions
tex_text/.vscode/settings.json
0 → 100644
| 1 | +## 0.1.5 | ||
| 2 | + | ||
| 3 | +* New shortcut added. | ||
| 4 | +* Font fixed. | ||
| 5 | + | ||
| 6 | +## 0.1.4 | ||
| 7 | + | ||
| 8 | +* Html parser math fixed. | ||
| 9 | + | ||
| 10 | +## 0.1.3 | ||
| 11 | + | ||
| 12 | +* Html parser fixed. | ||
| 13 | + | ||
| 14 | +## 0.1.2 | ||
| 15 | + | ||
| 16 | +* Baseline fixed. | ||
| 17 | + | ||
| 18 | +## 0.1.1 | ||
| 19 | + | ||
| 20 | +* Bug fixed. | ||
| 21 | + | ||
| 22 | +## 0.1.0 | ||
| 23 | + | ||
| 24 | +* Color scheme fixed. | ||
| 25 | + | ||
| 26 | +## 0.0.9 | ||
| 27 | + | ||
| 28 | +* Color scheme fixed. | ||
| 29 | + | ||
| 1 | ## 0.0.8 | 30 | ## 0.0.8 |
| 2 | 31 | ||
| 3 | * Error display fixed. | 32 | * Error display fixed. |
| 1 | import 'package:flutter/material.dart'; | 1 | import 'package:flutter/material.dart'; |
| 2 | +// ignore: depend_on_referenced_packages | ||
| 2 | import 'package:tex_text/tex_text.dart'; | 3 | import 'package:tex_text/tex_text.dart'; |
| 3 | 4 | ||
| 4 | void main(List<String> args) { | 5 | void main(List<String> args) { |
| @@ -19,34 +20,62 @@ class _MyAppState extends State<MyApp> { | @@ -19,34 +20,62 @@ class _MyAppState extends State<MyApp> { | ||
| 19 | return MaterialApp( | 20 | return MaterialApp( |
| 20 | home: Scaffold( | 21 | home: Scaffold( |
| 21 | appBar: AppBar(title: const Text("Tex Text.")), | 22 | appBar: AppBar(title: const Text("Tex Text.")), |
| 22 | - body: Padding( | ||
| 23 | - padding: const EdgeInsets.all(8.0), | ||
| 24 | - child: Column( | ||
| 25 | - mainAxisAlignment: MainAxisAlignment.start, | ||
| 26 | - crossAxisAlignment: CrossAxisAlignment.start, | ||
| 27 | - children: [ | ||
| 28 | - AnimatedBuilder( | ||
| 29 | - animation: _text, | ||
| 30 | - builder: (context, child) { | ||
| 31 | - return TexText( | ||
| 32 | - _text.text, | ||
| 33 | - alignment: TexAlignment.start, | ||
| 34 | - style: Theme.of(context).textTheme.titleLarge?.copyWith(), | ||
| 35 | - mathStyle: MathStyle.text, | ||
| 36 | - ); | ||
| 37 | - }), | ||
| 38 | - const SizedBox( | ||
| 39 | - height: 100, | 23 | + body: Column( |
| 24 | + mainAxisAlignment: MainAxisAlignment.start, | ||
| 25 | + crossAxisAlignment: CrossAxisAlignment.start, | ||
| 26 | + children: [ | ||
| 27 | + Expanded( | ||
| 28 | + child: ListView( | ||
| 29 | + padding: const EdgeInsets.all(10), | ||
| 30 | + children: [ | ||
| 31 | + AnimatedBuilder( | ||
| 32 | + animation: _text, | ||
| 33 | + builder: (context, child) { | ||
| 34 | + return Material( | ||
| 35 | + shape: RoundedRectangleBorder( | ||
| 36 | + borderRadius: BorderRadius.circular(4), | ||
| 37 | + side: const BorderSide(width: 1), | ||
| 38 | + ), | ||
| 39 | + child: TexText( | ||
| 40 | + // TexText.newEasySyntax(_text.text), | ||
| 41 | + _text.text, | ||
| 42 | + alignment: TexAlignment.start, | ||
| 43 | + style: Theme.of(context) | ||
| 44 | + .textTheme | ||
| 45 | + .headlineLarge | ||
| 46 | + ?.copyWith( | ||
| 47 | + // color: Colors.red, | ||
| 48 | + ), | ||
| 49 | + mathStyle: MathStyle.displayCramped, | ||
| 50 | + ), | ||
| 51 | + ); | ||
| 52 | + }), | ||
| 53 | + ], | ||
| 40 | ), | 54 | ), |
| 41 | - TextField( | ||
| 42 | - controller: _text, | ||
| 43 | - maxLines: null, | ||
| 44 | - decoration: const InputDecoration( | ||
| 45 | - border: OutlineInputBorder(), | ||
| 46 | - ), | 55 | + ), |
| 56 | + TextField( | ||
| 57 | + controller: _text, | ||
| 58 | + maxLines: null, | ||
| 59 | + decoration: const InputDecoration( | ||
| 60 | + border: OutlineInputBorder(), | ||
| 47 | ), | 61 | ), |
| 48 | - ], | ||
| 49 | - ), | 62 | + ), |
| 63 | + Builder(builder: (context) { | ||
| 64 | + return FilledButton( | ||
| 65 | + onPressed: () { | ||
| 66 | + showDialog( | ||
| 67 | + context: context, | ||
| 68 | + builder: (context) => SimpleDialog( | ||
| 69 | + children: [ | ||
| 70 | + SelectableText(TexText.toHtmlData((_text.text))) | ||
| 71 | + ], | ||
| 72 | + ), | ||
| 73 | + ); | ||
| 74 | + }, | ||
| 75 | + child: const Text("To html"), | ||
| 76 | + ); | ||
| 77 | + }) | ||
| 78 | + ], | ||
| 50 | ), | 79 | ), |
| 51 | ), | 80 | ), |
| 52 | ); | 81 | ); |
| @@ -238,7 +238,7 @@ packages: | @@ -238,7 +238,7 @@ packages: | ||
| 238 | path: ".." | 238 | path: ".." |
| 239 | relative: true | 239 | relative: true |
| 240 | source: path | 240 | source: path |
| 241 | - version: "0.0.8" | 241 | + version: "0.1.5" |
| 242 | tuple: | 242 | tuple: |
| 243 | dependency: transitive | 243 | dependency: transitive |
| 244 | description: | 244 | description: |
| @@ -47,7 +47,7 @@ dev_dependencies: | @@ -47,7 +47,7 @@ dev_dependencies: | ||
| 47 | # rules and activating additional ones. | 47 | # rules and activating additional ones. |
| 48 | flutter_lints: ^2.0.0 | 48 | flutter_lints: ^2.0.0 |
| 49 | tex_text: | 49 | tex_text: |
| 50 | - path: ../ | 50 | + path: ../../tex_text |
| 51 | 51 | ||
| 52 | # For information on the generic Dart part of this file, see the | 52 | # For information on the generic Dart part of this file, see the |
| 53 | # following page: https://dart.dev/tools/pub/pubspec | 53 | # following page: https://dart.dev/tools/pub/pubspec |
| @@ -27,78 +27,137 @@ enum TexAlignment { | @@ -27,78 +27,137 @@ enum TexAlignment { | ||
| 27 | class TexText extends StatelessWidget { | 27 | class TexText extends StatelessWidget { |
| 28 | const TexText(this.text, | 28 | const TexText(this.text, |
| 29 | {super.key, | 29 | {super.key, |
| 30 | - this.style, | ||
| 31 | - this.mathStyle = MathStyle.display, | ||
| 32 | - this.alignment = TexAlignment.start}); | 30 | + TextStyle? style, |
| 31 | + this.mathStyle = MathStyle.text, | ||
| 32 | + this.alignment = TexAlignment.start}) | ||
| 33 | + : _style = style; | ||
| 33 | final String text; | 34 | final String text; |
| 34 | - final TextStyle? style; | 35 | + final TextStyle? _style; |
| 35 | final MathStyle mathStyle; | 36 | final MathStyle mathStyle; |
| 36 | final TexAlignment alignment; | 37 | final TexAlignment alignment; |
| 37 | 38 | ||
| 38 | - List<Widget> generateWidget(String e) { | 39 | + /// LaTex to HTML parser |
| 40 | + String toHtml() { | ||
| 41 | + return toHtmlData(text); | ||
| 42 | + } | ||
| 43 | + | ||
| 44 | + static String _newEasySyntax(String data) { | ||
| 45 | + return data | ||
| 46 | + .replaceAll(r"\frac", r"\cfrac") | ||
| 47 | + .replaceAll(r"\left[", r"[") | ||
| 48 | + .replaceAll(r"\right]", r"]") | ||
| 49 | + .replaceAll(r"[", r"{\left[") | ||
| 50 | + .replaceAll(r"]", r"\right]}") | ||
| 51 | + .replaceAll(r"\left\{", r"\{") | ||
| 52 | + .replaceAll(r"\right\}", r"\}") | ||
| 53 | + .replaceAll(r"\{", r"{\left\{") | ||
| 54 | + .replaceAll(r"\}", r"\right\}}") | ||
| 55 | + .replaceAll(r"\left(", r"(") | ||
| 56 | + .replaceAll(r"\right)", r")") | ||
| 57 | + .replaceAll(r"(", r"{\left(") | ||
| 58 | + .replaceAll(r")", r"\right)}") | ||
| 59 | + .replaceAll(RegExp(r"\\tf"), r"\therefore") | ||
| 60 | + .replaceAll(RegExp(r"\\bc"), r"\because") | ||
| 61 | + .replaceAllMapped( | ||
| 62 | + RegExp(r"([^A-Za-z]|^)(sin|cos|tan|cosec|sec|cot)([^A-Za-z]|$)"), | ||
| 63 | + (match) => "{\\${match[2].toString()}}${match[3].toString()}") | ||
| 64 | + .replaceAll(r"=>", r"{\Rightarrow}") | ||
| 65 | + .replaceAll(RegExp(r"\\AA(\s|$)"), r"{Å}") | ||
| 66 | + .replaceAll(r"*", r"{\times}") | ||
| 67 | + .replaceAllMapped( | ||
| 68 | + RegExp(r"\\([a-z]?)mat(\s+?\S.*?)\\([a-z]?)mat"), | ||
| 69 | + (match) => | ||
| 70 | + "\\begin{${match[1].toString()}matrix}${match[2].toString().replaceAll("\\&", r"{\&}").replaceAll(",", "&").replaceAll("&&", "\\\\")}\\end{${match[3].toString()}matrix}"); | ||
| 71 | + } | ||
| 72 | + | ||
| 73 | + /// LaTex to HTML parser | ||
| 74 | + static String toHtmlData(String data) { | ||
| 39 | const dollar = r"\[-~`::36]"; | 75 | const dollar = r"\[-~`::36]"; |
| 40 | - List<Widget> widgets = []; | 76 | + return data.replaceAll("\\\$", dollar).splitMapJoin( |
| 77 | + RegExp( | ||
| 78 | + r"(?!\\)\$(.*?)(?!\\)\$", | ||
| 79 | + ), | ||
| 80 | + onMatch: (p0) { | ||
| 81 | + return "\\(${_newEasySyntax(p0[1].toString().replaceAll(dollar, "\\\$"))}\\)"; | ||
| 82 | + }, | ||
| 83 | + onNonMatch: (p0) { | ||
| 84 | + return p0 | ||
| 85 | + .replaceAll(dollar, "\$") | ||
| 86 | + .replaceAll("\n", "</br>") | ||
| 87 | + .replaceAll(" ", r" "); | ||
| 88 | + }, | ||
| 89 | + ).trim(); | ||
| 90 | + } | ||
| 91 | + | ||
| 92 | + Widget _generateWidget(BuildContext context, String e) { | ||
| 93 | + TextStyle? style = _style ?? Theme.of(context).textTheme.bodyMedium; | ||
| 94 | + const dollar = r"\[-~`::36]"; | ||
| 95 | + List<InlineSpan> widgets = []; | ||
| 41 | 96 | ||
| 42 | e.replaceAll("\\\$", dollar).splitMapJoin( | 97 | e.replaceAll("\\\$", dollar).splitMapJoin( |
| 43 | RegExp( | 98 | RegExp( |
| 44 | - r"(?!\\)\$(.*?)(?!\\)\$", | 99 | + r"\$(.*?)\$", |
| 45 | ), | 100 | ), |
| 46 | onMatch: (p0) { | 101 | onMatch: (p0) { |
| 47 | widgets.add( | 102 | widgets.add( |
| 48 | - Math.tex( | ||
| 49 | - p0[1].toString().replaceAll(dollar, "\\\$"), | ||
| 50 | - textStyle: style, | ||
| 51 | - mathStyle: mathStyle, | ||
| 52 | - textScaleFactor: 1, | ||
| 53 | - onErrorFallback: (err) { | ||
| 54 | - return Text( | ||
| 55 | - "\$${p0[1]}\$", | ||
| 56 | - style: style?.copyWith(color: Colors.red), | ||
| 57 | - ); | ||
| 58 | - }, | 103 | + WidgetSpan( |
| 104 | + alignment: PlaceholderAlignment.baseline, | ||
| 105 | + baseline: TextBaseline.alphabetic, | ||
| 106 | + child: Math.tex( | ||
| 107 | + _newEasySyntax(p0[1].toString().replaceAll(dollar, "\\\$")), | ||
| 108 | + textStyle: style?.copyWith( | ||
| 109 | + fontFamily: "SansSerif", | ||
| 110 | + ), | ||
| 111 | + mathStyle: mathStyle, | ||
| 112 | + textScaleFactor: 1.3, | ||
| 113 | + options: MathOptions( | ||
| 114 | + sizeUnderTextStyle: MathSize.large, | ||
| 115 | + color: style?.color ?? Theme.of(context).colorScheme.onSurface, | ||
| 116 | + fontSize: style?.fontSize ?? | ||
| 117 | + Theme.of(context).textTheme.bodyMedium?.fontSize, | ||
| 118 | + mathFontOptions: FontOptions( | ||
| 119 | + fontFamily: "Main", | ||
| 120 | + fontWeight: style?.fontWeight ?? FontWeight.normal, | ||
| 121 | + ), | ||
| 122 | + textFontOptions: FontOptions( | ||
| 123 | + fontFamily: "Main", | ||
| 124 | + fontWeight: style?.fontWeight ?? FontWeight.normal, | ||
| 125 | + ), | ||
| 126 | + style: mathStyle, | ||
| 127 | + ), | ||
| 128 | + onErrorFallback: (err) { | ||
| 129 | + return Text( | ||
| 130 | + "\$${p0[1]}\$", | ||
| 131 | + style: style?.copyWith( | ||
| 132 | + color: Theme.of(context).colorScheme.error) ?? | ||
| 133 | + TextStyle(color: Theme.of(context).colorScheme.error), | ||
| 134 | + ); | ||
| 135 | + }, | ||
| 136 | + ), | ||
| 59 | ), | 137 | ), |
| 60 | ); | 138 | ); |
| 61 | return p0[1].toString(); | 139 | return p0[1].toString(); |
| 62 | }, | 140 | }, |
| 63 | onNonMatch: (p0) { | 141 | onNonMatch: (p0) { |
| 64 | - p0 | ||
| 65 | - .toString() | ||
| 66 | - .replaceAll(dollar, "\$") | ||
| 67 | - .split(" ") | ||
| 68 | - .asMap() | ||
| 69 | - .forEach((key, element) { | ||
| 70 | - if (key != 0) { | ||
| 71 | - widgets.add(Text( | ||
| 72 | - " ", | ||
| 73 | - textAlign: TextAlign.values[alignment.index], | ||
| 74 | - style: style, | ||
| 75 | - )); | ||
| 76 | - } | ||
| 77 | - widgets.add(Text( | ||
| 78 | - element, | ||
| 79 | - textAlign: TextAlign.values[alignment.index], | 142 | + widgets.add( |
| 143 | + TextSpan( | ||
| 144 | + text: p0.toString().replaceAll(dollar, "\$"), | ||
| 80 | style: style, | 145 | style: style, |
| 81 | - )); | ||
| 82 | - }); | 146 | + ), |
| 147 | + ); | ||
| 83 | return p0; | 148 | return p0; |
| 84 | }, | 149 | }, |
| 85 | ); | 150 | ); |
| 86 | - return widgets; | 151 | + return Text.rich( |
| 152 | + TextSpan( | ||
| 153 | + children: widgets, | ||
| 154 | + ), | ||
| 155 | + textAlign: TextAlign.values[alignment.index], | ||
| 156 | + ); | ||
| 87 | } | 157 | } |
| 88 | 158 | ||
| 89 | @override | 159 | @override |
| 90 | Widget build(BuildContext context) { | 160 | Widget build(BuildContext context) { |
| 91 | - return Column( | ||
| 92 | - mainAxisSize: MainAxisSize.min, | ||
| 93 | - crossAxisAlignment: CrossAxisAlignment.values[alignment.index], | ||
| 94 | - children: text.split('\n').map<Widget>( | ||
| 95 | - (e) { | ||
| 96 | - return Wrap( | ||
| 97 | - alignment: WrapAlignment.values[alignment.index], | ||
| 98 | - crossAxisAlignment: WrapCrossAlignment.center, | ||
| 99 | - children: generateWidget(e)); | ||
| 100 | - }, | ||
| 101 | - ).toList(), | ||
| 102 | - ); | 161 | + return _generateWidget(context, text); |
| 103 | } | 162 | } |
| 104 | } | 163 | } |
| 1 | name: tex_text | 1 | name: tex_text |
| 2 | description: This package for Flutter allows you to show text on a Flutter app with LaTex math formula and normal text from string. It is vary easy to use and works for all of the platforms. | 2 | description: This package for Flutter allows you to show text on a Flutter app with LaTex math formula and normal text from string. It is vary easy to use and works for all of the platforms. |
| 3 | -version: 0.0.8 | 3 | +version: 0.1.5 |
| 4 | homepage: https://github.com/saminsohag/flutter_packages/tree/main/tex_text | 4 | homepage: https://github.com/saminsohag/flutter_packages/tree/main/tex_text |
| 5 | 5 | ||
| 6 | environment: | 6 | environment: |
-
Please register or login to post a comment