added highlightBuilder, removed default padding on codeBuilder
Showing
4 changed files
with
52 additions
and
11 deletions
| @@ -99,6 +99,7 @@ class MarkdownHelper { | @@ -99,6 +99,7 @@ class MarkdownHelper { | ||
| 99 | 99 | ||
| 100 | You can use Markdown to format text easily. Here are some examples: | 100 | You can use Markdown to format text easily. Here are some examples: |
| 101 | 101 | ||
| 102 | +- `Highlighted Text`: `This text is highlighted` | ||
| 102 | - **Bold Text**: **This text is bold** | 103 | - **Bold Text**: **This text is bold** |
| 103 | - *Italic Text*: *This text is italicized* | 104 | - *Italic Text*: *This text is italicized* |
| 104 | - [Link](https://www.example.com): [This is a link](https://www.example.com) | 105 | - [Link](https://www.example.com): [This is a link](https://www.example.com) |
| @@ -266,6 +267,29 @@ Markdown and LaTeX can be powerful tools for formatting text and mathematical ex | @@ -266,6 +267,29 @@ Markdown and LaTeX can be powerful tools for formatting text and mathematical ex | ||
| 266 | style: const TextStyle( | 267 | style: const TextStyle( |
| 267 | fontSize: 15, | 268 | fontSize: 15, |
| 268 | ), | 269 | ), |
| 270 | + highlightBuilder: (context, text, style) { | ||
| 271 | + return Container( | ||
| 272 | + padding: const EdgeInsets.symmetric(horizontal: 4, vertical: 2), | ||
| 273 | + decoration: BoxDecoration( | ||
| 274 | + color: Theme.of(context).colorScheme.secondaryContainer, | ||
| 275 | + borderRadius: BorderRadius.circular(4), | ||
| 276 | + border: Border.all( | ||
| 277 | + color: Theme.of(context).colorScheme.secondary.withOpacity(0.5), | ||
| 278 | + width: 1, | ||
| 279 | + ), | ||
| 280 | + ), | ||
| 281 | + child: Text( | ||
| 282 | + text, | ||
| 283 | + style: TextStyle( | ||
| 284 | + color: Theme.of(context).colorScheme.onSecondaryContainer, | ||
| 285 | + fontFamily: 'monospace', | ||
| 286 | + fontWeight: FontWeight.bold, | ||
| 287 | + fontSize: style.fontSize != null ? style.fontSize! * 0.9 : 13.5, | ||
| 288 | + height: style.height, | ||
| 289 | + ), | ||
| 290 | + ), | ||
| 291 | + ); | ||
| 292 | + }, | ||
| 269 | latexWorkaround: (tex) { | 293 | latexWorkaround: (tex) { |
| 270 | List<String> stack = []; | 294 | List<String> stack = []; |
| 271 | tex = tex.splitMapJoin( | 295 | tex = tex.splitMapJoin( |
| @@ -12,6 +12,7 @@ class GptMarkdownConfig { | @@ -12,6 +12,7 @@ class GptMarkdownConfig { | ||
| 12 | this.followLinkColor = false, | 12 | this.followLinkColor = false, |
| 13 | this.codeBuilder, | 13 | this.codeBuilder, |
| 14 | this.sourceTagBuilder, | 14 | this.sourceTagBuilder, |
| 15 | + this.highlightBuilder, | ||
| 15 | this.maxLines, | 16 | this.maxLines, |
| 16 | this.overflow, | 17 | this.overflow, |
| 17 | }); | 18 | }); |
| @@ -32,6 +33,7 @@ class GptMarkdownConfig { | @@ -32,6 +33,7 @@ class GptMarkdownConfig { | ||
| 32 | codeBuilder; | 33 | codeBuilder; |
| 33 | final int? maxLines; | 34 | final int? maxLines; |
| 34 | final TextOverflow? overflow; | 35 | final TextOverflow? overflow; |
| 36 | + final Widget Function(BuildContext context, String text, TextStyle style)? highlightBuilder; | ||
| 35 | 37 | ||
| 36 | GptMarkdownConfig copyWith({ | 38 | GptMarkdownConfig copyWith({ |
| 37 | TextStyle? style, | 39 | TextStyle? style, |
| @@ -51,6 +53,7 @@ class GptMarkdownConfig { | @@ -51,6 +53,7 @@ class GptMarkdownConfig { | ||
| 51 | codeBuilder, | 53 | codeBuilder, |
| 52 | final int? maxLines, | 54 | final int? maxLines, |
| 53 | final TextOverflow? overflow, | 55 | final TextOverflow? overflow, |
| 56 | + final Widget Function(BuildContext context, String text, TextStyle style)? highlightBuilder, | ||
| 54 | }) { | 57 | }) { |
| 55 | return GptMarkdownConfig( | 58 | return GptMarkdownConfig( |
| 56 | style: style ?? this.style, | 59 | style: style ?? this.style, |
| @@ -65,6 +68,7 @@ class GptMarkdownConfig { | @@ -65,6 +68,7 @@ class GptMarkdownConfig { | ||
| 65 | sourceTagBuilder: sourceTagBuilder ?? this.sourceTagBuilder, | 68 | sourceTagBuilder: sourceTagBuilder ?? this.sourceTagBuilder, |
| 66 | maxLines: maxLines ?? this.maxLines, | 69 | maxLines: maxLines ?? this.maxLines, |
| 67 | overflow: overflow ?? this.overflow, | 70 | overflow: overflow ?? this.overflow, |
| 71 | + highlightBuilder: highlightBuilder ?? this.highlightBuilder, | ||
| 68 | ); | 72 | ); |
| 69 | } | 73 | } |
| 70 | 74 |
| @@ -34,6 +34,7 @@ class GptMarkdown extends StatelessWidget { | @@ -34,6 +34,7 @@ class GptMarkdown extends StatelessWidget { | ||
| 34 | this.latexBuilder, | 34 | this.latexBuilder, |
| 35 | this.codeBuilder, | 35 | this.codeBuilder, |
| 36 | this.sourceTagBuilder, | 36 | this.sourceTagBuilder, |
| 37 | + this.highlightBuilder, | ||
| 37 | this.maxLines, | 38 | this.maxLines, |
| 38 | this.overflow, | 39 | this.overflow, |
| 39 | }); | 40 | }); |
| @@ -53,6 +54,7 @@ class GptMarkdown extends StatelessWidget { | @@ -53,6 +54,7 @@ class GptMarkdown extends StatelessWidget { | ||
| 53 | final Widget Function(BuildContext context, String name, String code)? | 54 | final Widget Function(BuildContext context, String name, String code)? |
| 54 | codeBuilder; | 55 | codeBuilder; |
| 55 | final Widget Function(BuildContext, String, TextStyle)? sourceTagBuilder; | 56 | final Widget Function(BuildContext, String, TextStyle)? sourceTagBuilder; |
| 57 | + final Widget Function(BuildContext context, String text, TextStyle style)? highlightBuilder; | ||
| 56 | 58 | ||
| 57 | @override | 59 | @override |
| 58 | Widget build(BuildContext context) { | 60 | Widget build(BuildContext context) { |
| @@ -93,6 +95,7 @@ class GptMarkdown extends StatelessWidget { | @@ -93,6 +95,7 @@ class GptMarkdown extends StatelessWidget { | ||
| 93 | maxLines: maxLines, | 95 | maxLines: maxLines, |
| 94 | overflow: overflow, | 96 | overflow: overflow, |
| 95 | sourceTagBuilder: sourceTagBuilder, | 97 | sourceTagBuilder: sourceTagBuilder, |
| 98 | + highlightBuilder: highlightBuilder, | ||
| 96 | ), | 99 | ), |
| 97 | )); | 100 | )); |
| 98 | } | 101 | } |
| @@ -422,8 +422,20 @@ class HighlightedText extends InlineMd { | @@ -422,8 +422,20 @@ class HighlightedText extends InlineMd { | ||
| 422 | final GptMarkdownConfig config, | 422 | final GptMarkdownConfig config, |
| 423 | ) { | 423 | ) { |
| 424 | var match = exp.firstMatch(text.trim()); | 424 | var match = exp.firstMatch(text.trim()); |
| 425 | - var conf = config.copyWith( | ||
| 426 | - style: config.style?.copyWith( | 425 | + var highlightedText = match?[1] ?? ""; |
| 426 | + | ||
| 427 | + if (config.highlightBuilder != null) { | ||
| 428 | + return WidgetSpan( | ||
| 429 | + alignment: PlaceholderAlignment.middle, | ||
| 430 | + child: config.highlightBuilder!( | ||
| 431 | + context, | ||
| 432 | + highlightedText, | ||
| 433 | + config.style ?? const TextStyle(), | ||
| 434 | + ), | ||
| 435 | + ); | ||
| 436 | + } | ||
| 437 | + | ||
| 438 | + var style = config.style?.copyWith( | ||
| 427 | fontWeight: FontWeight.bold, | 439 | fontWeight: FontWeight.bold, |
| 428 | background: Paint() | 440 | background: Paint() |
| 429 | ..color = GptMarkdownTheme.of(context).highlightColor | 441 | ..color = GptMarkdownTheme.of(context).highlightColor |
| @@ -436,11 +448,11 @@ class HighlightedText extends InlineMd { | @@ -436,11 +448,11 @@ class HighlightedText extends InlineMd { | ||
| 436 | ..color = GptMarkdownTheme.of(context).highlightColor | 448 | ..color = GptMarkdownTheme.of(context).highlightColor |
| 437 | ..strokeCap = StrokeCap.round | 449 | ..strokeCap = StrokeCap.round |
| 438 | ..strokeJoin = StrokeJoin.round, | 450 | ..strokeJoin = StrokeJoin.round, |
| 439 | - ), | ||
| 440 | ); | 451 | ); |
| 452 | + | ||
| 441 | return TextSpan( | 453 | return TextSpan( |
| 442 | - text: match?[1], | ||
| 443 | - style: conf.style, | 454 | + text: highlightedText, |
| 455 | + style: style, | ||
| 444 | ); | 456 | ); |
| 445 | } | 457 | } |
| 446 | } | 458 | } |
| @@ -892,11 +904,9 @@ class CodeBlockMd extends BlockMd { | @@ -892,11 +904,9 @@ class CodeBlockMd extends BlockMd { | ||
| 892 | String codes = this.exp.firstMatch(text)?[2] ?? ""; | 904 | String codes = this.exp.firstMatch(text)?[2] ?? ""; |
| 893 | String name = this.exp.firstMatch(text)?[1] ?? ""; | 905 | String name = this.exp.firstMatch(text)?[1] ?? ""; |
| 894 | codes = codes.replaceAll(r"```", "").trim(); | 906 | codes = codes.replaceAll(r"```", "").trim(); |
| 895 | - return Padding( | ||
| 896 | - padding: const EdgeInsets.all(16.0), | ||
| 897 | - child: config.codeBuilder != null | ||
| 898 | - ? config.codeBuilder?.call(context, name, codes) | ||
| 899 | - : CodeField(name: name, codes: codes), | ||
| 900 | - ); | 907 | + |
| 908 | + return config.codeBuilder != null | ||
| 909 | + ? config.codeBuilder!(context, name, codes) | ||
| 910 | + : CodeField(name: name, codes: codes); | ||
| 901 | } | 911 | } |
| 902 | } | 912 | } |
-
Please register or login to post a comment