Showing
7 changed files
with
111 additions
and
181 deletions
1 | import 'dart:developer'; | 1 | import 'dart:developer'; |
2 | - | ||
3 | import 'package:flutter/material.dart'; | 2 | import 'package:flutter/material.dart'; |
4 | import 'package:flutter_math_fork/flutter_math.dart'; | 3 | import 'package:flutter_math_fork/flutter_math.dart'; |
5 | import 'package:gpt_markdown/gpt_markdown.dart'; | 4 | import 'package:gpt_markdown/gpt_markdown.dart'; |
@@ -123,69 +122,84 @@ Markdown and LaTeX can be powerful tools for formatting text and mathematical ex | @@ -123,69 +122,84 @@ Markdown and LaTeX can be powerful tools for formatting text and mathematical ex | ||
123 | Column( | 122 | Column( |
124 | children: [ | 123 | children: [ |
125 | Expanded( | 124 | Expanded( |
126 | - child: ListView( | ||
127 | - children: [ | ||
128 | - AnimatedBuilder( | ||
129 | - animation: _controller, | ||
130 | - builder: (context, _) { | ||
131 | - return Material( | ||
132 | - // color: Theme.of(context).colorScheme.surfaceVariant, | ||
133 | - shape: RoundedRectangleBorder( | ||
134 | - side: BorderSide( | ||
135 | - width: 1, | ||
136 | - color: Theme.of(context).colorScheme.outline), | ||
137 | - ), | ||
138 | - child: LayoutBuilder(builder: (context, constraints) { | ||
139 | - return Theme( | ||
140 | - data: Theme.of(context).copyWith( | ||
141 | - textTheme: const TextTheme( | ||
142 | - // For H1. | ||
143 | - headlineLarge: TextStyle(fontSize: 55), | ||
144 | - // For H2. | ||
145 | - headlineMedium: TextStyle(fontSize: 45), | ||
146 | - // For H3. | ||
147 | - headlineSmall: TextStyle(fontSize: 35), | ||
148 | - // For H4. | ||
149 | - titleLarge: TextStyle(fontSize: 25), | ||
150 | - // For H5. | ||
151 | - titleMedium: TextStyle(fontSize: 15), | ||
152 | - // For H6. | ||
153 | - titleSmall: TextStyle(fontSize: 10), | 125 | + child: SingleChildScrollView( |
126 | + child: Column( | ||
127 | + children: [ | ||
128 | + AnimatedBuilder( | ||
129 | + animation: _controller, | ||
130 | + builder: (context, _) { | ||
131 | + return Material( | ||
132 | + // color: Theme.of(context).colorScheme.surfaceVariant, | ||
133 | + shape: RoundedRectangleBorder( | ||
134 | + side: BorderSide( | ||
135 | + width: 1, | ||
136 | + color: Theme.of(context).colorScheme.outline), | ||
137 | + ), | ||
138 | + child: | ||
139 | + LayoutBuilder(builder: (context, constraints) { | ||
140 | + return Theme( | ||
141 | + data: Theme.of(context).copyWith( | ||
142 | + textTheme: const TextTheme( | ||
143 | + // For H1. | ||
144 | + headlineLarge: TextStyle(fontSize: 55), | ||
145 | + // For H2. | ||
146 | + headlineMedium: TextStyle(fontSize: 45), | ||
147 | + // For H3. | ||
148 | + headlineSmall: TextStyle(fontSize: 35), | ||
149 | + // For H4. | ||
150 | + titleLarge: TextStyle(fontSize: 25), | ||
151 | + // For H5. | ||
152 | + titleMedium: TextStyle(fontSize: 15), | ||
153 | + // For H6. | ||
154 | + titleSmall: TextStyle(fontSize: 10), | ||
155 | + ), | ||
154 | ), | 156 | ), |
155 | - ), | ||
156 | - child: TexMarkdown( | ||
157 | - _controller.text, | ||
158 | - textDirection: _direction, | ||
159 | - onLinkTab: (url, title) { | ||
160 | - log(title, name: "title"); | ||
161 | - log(url, name: "url"); | ||
162 | - }, | ||
163 | - textAlign: TextAlign.justify, | ||
164 | - // textScaler: const TextScaler.linear(1.3), | ||
165 | - textScaler: MediaQuery.textScalerOf(context), | ||
166 | - style: const TextStyle( | ||
167 | - // Regular text font size here. | ||
168 | - fontSize: 15, | 157 | + child: TexMarkdown( |
158 | + _controller.text, | ||
159 | + textDirection: _direction, | ||
160 | + onLinkTab: (url, title) { | ||
161 | + log(title, name: "title"); | ||
162 | + log(url, name: "url"); | ||
163 | + }, | ||
164 | + textAlign: TextAlign.justify, | ||
165 | + // textScaler: const TextScaler.linear(1.3), | ||
166 | + textScaler: MediaQuery.textScalerOf(context), | ||
167 | + style: const TextStyle( | ||
168 | + // Regular text font size here. | ||
169 | + fontSize: 15, | ||
170 | + ), | ||
171 | + latexWorkaround: (tex) => | ||
172 | + tex.replaceAllMapped(RegExp(r"align\*"), | ||
173 | + (match) => "aligned"), | ||
174 | + latexBuilder: (contex, tex) { | ||
175 | + var controller = ScrollController(); | ||
176 | + return Column( | ||
177 | + children: [ | ||
178 | + Scrollbar( | ||
179 | + controller: controller, | ||
180 | + child: SingleChildScrollView( | ||
181 | + controller: controller, | ||
182 | + scrollDirection: Axis.horizontal, | ||
183 | + child: Math.tex( | ||
184 | + tex, | ||
185 | + textStyle: const TextStyle( | ||
186 | + fontSize: 17, | ||
187 | + ), | ||
188 | + ), | ||
189 | + ), | ||
190 | + ), | ||
191 | + ], | ||
192 | + ); | ||
193 | + }, | ||
169 | ), | 194 | ), |
170 | - latexWorkaround: (tex) => tex.replaceAllMapped( | ||
171 | - RegExp(r"align\*"), (match) => "aligned"), | ||
172 | - latexBuilder: (contex, tex) { | ||
173 | - return SingleChildScrollView( | ||
174 | - scrollDirection: Axis.horizontal, | ||
175 | - child: Math.tex( | ||
176 | - tex, | ||
177 | - textStyle: const TextStyle(fontSize: 17), | ||
178 | - ), | ||
179 | - ); | ||
180 | - }, | ||
181 | - ), | ||
182 | - // child: const Text("Hello"), | ||
183 | - ); | ||
184 | - }), | ||
185 | - ); | ||
186 | - }, | ||
187 | - ), | ||
188 | - ], | 195 | + // child: const Text("Hello"), |
196 | + ); | ||
197 | + }), | ||
198 | + ); | ||
199 | + }, | ||
200 | + ), | ||
201 | + ], | ||
202 | + ), | ||
189 | ), | 203 | ), |
190 | ), | 204 | ), |
191 | ConstrainedBox( | 205 | ConstrainedBox( |
@@ -182,7 +182,7 @@ packages: | @@ -182,7 +182,7 @@ packages: | ||
182 | path: ".." | 182 | path: ".." |
183 | relative: true | 183 | relative: true |
184 | source: path | 184 | source: path |
185 | - version: "0.0.3" | 185 | + version: "0.0.4" |
186 | http: | 186 | http: |
187 | dependency: transitive | 187 | dependency: transitive |
188 | description: | 188 | description: |
@@ -191,6 +191,28 @@ class UnorderedListRenderObject extends RenderProxyBox { | @@ -191,6 +191,28 @@ class UnorderedListRenderObject extends RenderProxyBox { | ||
191 | offset + _bulletOffset, _bulletSize, Paint()..color = _bulletColor); | 191 | offset + _bulletOffset, _bulletSize, Paint()..color = _bulletColor); |
192 | } | 192 | } |
193 | } | 193 | } |
194 | + | ||
195 | + @override | ||
196 | + bool hitTestSelf(Offset position) { | ||
197 | + return false; | ||
198 | + } | ||
199 | + | ||
200 | + @override | ||
201 | + bool hitTestChildren(BoxHitTestResult result, {required Offset position}) { | ||
202 | + Offset offset = (child!.parentData as BoxParentData).offset; | ||
203 | + return result.addWithPaintOffset( | ||
204 | + offset: offset, | ||
205 | + position: position, | ||
206 | + hitTest: (result, newOffset) { | ||
207 | + return child?.hitTest(result, position: newOffset) ?? false; | ||
208 | + }, | ||
209 | + ); | ||
210 | + } | ||
211 | + | ||
212 | + @override | ||
213 | + bool hitTest(BoxHitTestResult result, {required Offset position}) { | ||
214 | + return hitTestChildren(result, position: position); | ||
215 | + } | ||
194 | } | 216 | } |
195 | 217 | ||
196 | class OrderedListView extends SingleChildRenderObjectWidget { | 218 | class OrderedListView extends SingleChildRenderObjectWidget { |
@@ -249,12 +249,6 @@ class HTag extends BlockMd { | @@ -249,12 +249,6 @@ class HTag extends BlockMd { | ||
249 | textDirection: textDirection, | 249 | textDirection: textDirection, |
250 | ); | 250 | ); |
251 | } | 251 | } |
252 | - | ||
253 | - // @override | ||
254 | - // String toHtml(String text) { | ||
255 | - // var match = exp.firstMatch(text.trim()); | ||
256 | - // return "<h${match![1]!.length}>${TexText.toHtmlData(match[2].toString().trim())}<h${match[1]!.length}>"; | ||
257 | - // } | ||
258 | } | 252 | } |
259 | 253 | ||
260 | /// Horizontal line component | 254 | /// Horizontal line component |
@@ -480,7 +474,7 @@ class BoldMd extends InlineMd { | @@ -480,7 +474,7 @@ class BoldMd extends InlineMd { | ||
480 | } | 474 | } |
481 | } | 475 | } |
482 | 476 | ||
483 | -class LatexMathMultyLine extends InlineMd { | 477 | +class LatexMathMultyLine extends BlockMd { |
484 | @override | 478 | @override |
485 | RegExp get exp => RegExp( | 479 | RegExp get exp => RegExp( |
486 | r"\\\[(.*?)\\\]|(\\begin.*?\\end{.*?})", | 480 | r"\\\[(.*?)\\\]|(\\begin.*?\\end{.*?})", |
@@ -488,14 +482,14 @@ class LatexMathMultyLine extends InlineMd { | @@ -488,14 +482,14 @@ class LatexMathMultyLine extends InlineMd { | ||
488 | ); | 482 | ); |
489 | 483 | ||
490 | @override | 484 | @override |
491 | - InlineSpan span( | 485 | + Widget build( |
492 | BuildContext context, | 486 | BuildContext context, |
493 | String text, | 487 | String text, |
494 | TextStyle? style, | 488 | TextStyle? style, |
495 | TextDirection textDirection, | 489 | TextDirection textDirection, |
496 | - final void Function(String url, String title)? onLinkTab, | ||
497 | - final String Function(String tex)? latexWorkaround, | ||
498 | - final Widget Function(BuildContext context, String tex)? latexBuilder, | 490 | + void Function(String url, String title)? onLinkTab, |
491 | + String Function(String tex)? latexWorkaround, | ||
492 | + Widget Function(BuildContext context, String tex)? latexBuilder, | ||
499 | ) { | 493 | ) { |
500 | var p0 = exp.firstMatch(text.trim()); | 494 | var p0 = exp.firstMatch(text.trim()); |
501 | p0?.group(0); | 495 | p0?.group(0); |
@@ -504,7 +498,7 @@ class LatexMathMultyLine extends InlineMd { | @@ -504,7 +498,7 @@ class LatexMathMultyLine extends InlineMd { | ||
504 | 498 | ||
505 | var builder = latexBuilder ?? | 499 | var builder = latexBuilder ?? |
506 | (BuildContext context, String tex) => Math.tex( | 500 | (BuildContext context, String tex) => Math.tex( |
507 | - workaround(tex), | 501 | + tex, |
508 | textStyle: style?.copyWith( | 502 | textStyle: style?.copyWith( |
509 | fontFamily: "SansSerif", | 503 | fontFamily: "SansSerif", |
510 | ), | 504 | ), |
@@ -540,12 +534,7 @@ class LatexMathMultyLine extends InlineMd { | @@ -540,12 +534,7 @@ class LatexMathMultyLine extends InlineMd { | ||
540 | ); | 534 | ); |
541 | }, | 535 | }, |
542 | ); | 536 | ); |
543 | - | ||
544 | - return WidgetSpan( | ||
545 | - alignment: PlaceholderAlignment.baseline, | ||
546 | - baseline: TextBaseline.alphabetic, | ||
547 | - child: builder(context, mathText), | ||
548 | - ); | 537 | + return builder(context, workaround(mathText)); |
549 | } | 538 | } |
550 | } | 539 | } |
551 | 540 |
1 | -// library tex_text; | ||
2 | -// | ||
3 | -// import 'package:flutter/material.dart'; | ||
4 | -// import 'package:flutter_math_fork/flutter_math.dart'; | ||
5 | -// | ||
6 | -// /// A LaTex text view. | ||
7 | -// /// | ||
8 | -// /// Example: | ||
9 | -// /// ```dart | ||
10 | -// /// TexText(r"The equation is $x^2+y^2=z^2$") //Output: The equation is <LaTex formatted equation> | ||
11 | -// /// | ||
12 | -// /// // \$ shows $ result | ||
13 | -// /// TexText(r"The equation is \$") //Output: The equation is $ | ||
14 | -// /// ``` | ||
15 | -// class TexText { | ||
16 | -// const TexText( | ||
17 | -// this.text, { | ||
18 | -// TextStyle? style, | ||
19 | -// this.textDirection = TextDirection.ltr, | ||
20 | -// this.mathStyle = MathStyle.text, | ||
21 | -// }) : _style = style; | ||
22 | -// final String text; | ||
23 | -// final TextStyle? _style; | ||
24 | -// final TextDirection textDirection; | ||
25 | -// final MathStyle mathStyle; | ||
26 | -// // final TexAlignment alignment; | ||
27 | -// | ||
28 | -// List<InlineSpan> getSpans(BuildContext context) { | ||
29 | -// // | ||
30 | -// String e = text; | ||
31 | -// TextStyle? style = _style ?? Theme.of(context).textTheme.bodyMedium; | ||
32 | -// List<InlineSpan> spans = []; | ||
33 | -// | ||
34 | -// e.splitMapJoin( | ||
35 | -// RegExp( | ||
36 | -// r"\\\[(.*?)\\\]|\\\((.*?)\\\)", | ||
37 | -// multiLine: true, | ||
38 | -// dotAll: true, | ||
39 | -// ), | ||
40 | -// onMatch: (p0) { | ||
41 | -// spans.add( | ||
42 | -// WidgetSpan( | ||
43 | -// alignment: PlaceholderAlignment.baseline, | ||
44 | -// baseline: TextBaseline.alphabetic, | ||
45 | -// child: Math.tex( | ||
46 | -// // _newEasySyntax(p0[1].toString().replaceAll(dollar, "\\\$")), | ||
47 | -// p0[1]?.toString() ?? p0[2].toString(), | ||
48 | -// textStyle: style?.copyWith( | ||
49 | -// fontFamily: "SansSerif", | ||
50 | -// ), | ||
51 | -// mathStyle: mathStyle, | ||
52 | -// textScaleFactor: 1, | ||
53 | -// settings: const TexParserSettings( | ||
54 | -// strict: Strict.ignore, | ||
55 | -// ), | ||
56 | -// options: MathOptions( | ||
57 | -// sizeUnderTextStyle: MathSize.large, | ||
58 | -// color: style?.color ?? Theme.of(context).colorScheme.onSurface, | ||
59 | -// fontSize: style?.fontSize ?? | ||
60 | -// Theme.of(context).textTheme.bodyMedium?.fontSize, | ||
61 | -// mathFontOptions: FontOptions( | ||
62 | -// fontFamily: "Main", | ||
63 | -// fontWeight: style?.fontWeight ?? FontWeight.normal, | ||
64 | -// fontShape: FontStyle.normal, | ||
65 | -// ), | ||
66 | -// textFontOptions: FontOptions( | ||
67 | -// fontFamily: "Main", | ||
68 | -// fontWeight: style?.fontWeight ?? FontWeight.normal, | ||
69 | -// fontShape: FontStyle.normal, | ||
70 | -// ), | ||
71 | -// style: mathStyle, | ||
72 | -// ), | ||
73 | -// onErrorFallback: (err) { | ||
74 | -// return Text( | ||
75 | -// "\\(${p0[1] ?? p0[2]}\\)", | ||
76 | -// textDirection: textDirection, | ||
77 | -// style: style?.copyWith( | ||
78 | -// color: Theme.of(context).colorScheme.error) ?? | ||
79 | -// TextStyle(color: Theme.of(context).colorScheme.error), | ||
80 | -// ); | ||
81 | -// }, | ||
82 | -// ), | ||
83 | -// ), | ||
84 | -// ); | ||
85 | -// return p0[1].toString(); | ||
86 | -// }, | ||
87 | -// onNonMatch: (p0) { | ||
88 | -// spans.add( | ||
89 | -// TextSpan( | ||
90 | -// text: p0.toString(), | ||
91 | -// style: style, | ||
92 | -// ), | ||
93 | -// ); | ||
94 | -// return p0; | ||
95 | -// }, | ||
96 | -// ); | ||
97 | -// return spans; | ||
98 | -// } | ||
99 | -// } |
1 | name: gpt_markdown | 1 | name: gpt_markdown |
2 | description: "The purpose of this package is to render the response of ChatGPT into a Flutter app." | 2 | description: "The purpose of this package is to render the response of ChatGPT into a Flutter app." |
3 | -version: 0.0.3 | 3 | +version: 0.0.4 |
4 | homepage: https://github.com/saminsohag/flutter_packages/tree/main/gpt_markdown | 4 | homepage: https://github.com/saminsohag/flutter_packages/tree/main/gpt_markdown |
5 | 5 | ||
6 | environment: | 6 | environment: |
-
Please register or login to post a comment