saminsohag

new syntax added

## 1.0.6
* `_italic_` and `>Indentation` syntax added.
* `linkBuilder` and `highlightBuilder` added `[f45132b](https://github.com/Infinitix-LLC/gpt_markdown/commit/f45132b2cd4b069d3e5703561deb5c7e51d3c560)`.
## 1.0.5
* Fixed the order of inline and block latex in markdown.
... ...
... ... @@ -269,22 +269,33 @@ Markdown and LaTeX can be powerful tools for formatting text and mathematical ex
),
highlightBuilder: (context, text, style) {
return Container(
padding: const EdgeInsets.symmetric(horizontal: 4, vertical: 2),
padding: const EdgeInsets.symmetric(
horizontal: 4, vertical: 2),
decoration: BoxDecoration(
color: Theme.of(context).colorScheme.secondaryContainer,
borderRadius: BorderRadius.circular(4),
color: Theme.of(context)
.colorScheme
.secondaryContainer,
borderRadius:
BorderRadius.circular(4),
border: Border.all(
color: Theme.of(context).colorScheme.secondary.withOpacity(0.5),
color: Theme.of(context)
.colorScheme
.secondary
.withValues(alpha: 0.5),
width: 1,
),
),
child: Text(
text,
style: TextStyle(
color: Theme.of(context).colorScheme.onSecondaryContainer,
color: Theme.of(context)
.colorScheme
.onSecondaryContainer,
fontFamily: 'monospace',
fontWeight: FontWeight.bold,
fontSize: style.fontSize != null ? style.fontSize! * 0.9 : 13.5,
fontSize: style.fontSize != null
? style.fontSize! * 0.9
: 13.5,
height: style.height,
),
),
... ... @@ -400,21 +411,29 @@ Markdown and LaTeX can be powerful tools for formatting text and mathematical ex
),
);
},
linkBuilder:
(context, label, path, style) {
//
return Text(path);
},
// codeBuilder: (context, name, code) {
// return Padding(
// padding: const EdgeInsets.symmetric(
// horizontal: 16),
// child: Text(
// code.trim(),
// style: TextStyle(
// fontFamily: 'JetBrains Mono',
// fontSize: 14,
// height: 1.5,
// color: Theme.of(context)
// .colorScheme
// .onSurface,
// ),
// ),
// );
// }
);
codeBuilder: (context, name, code) {
return Padding(
padding: const EdgeInsets.symmetric(horizontal: 16),
child: Text(
code.trim(),
style: TextStyle(
fontFamily: 'JetBrains Mono',
fontSize: 14,
height: 1.5,
color: Theme.of(context).colorScheme.onSurface,
),
),
);
};
if (selectable) {
child = SelectionArea(
child: child,
... ...
... ... @@ -126,7 +126,7 @@ packages:
path: ".."
relative: true
source: path
version: "1.0.5"
version: "1.0.6"
http:
dependency: transitive
description:
... ...
import 'package:flutter/material.dart';
class IndentWidget extends StatelessWidget {
const IndentWidget({
super.key,
required this.child,
required this.direction,
required this.color,
});
final Widget child;
final TextDirection direction;
final Color color;
@override
Widget build(BuildContext context) {
return CustomPaint(
foregroundPainter: IndentPainter(color, direction),
child: child,
);
}
}
class IndentPainter extends CustomPainter {
IndentPainter(this.color, this.direction);
final Color color;
final TextDirection direction;
@override
void paint(Canvas canvas, Size size) {
var left = direction == TextDirection.ltr;
var start = left ? 0.0 : size.width - 4;
var rect = Rect.fromLTWH(start, 0, 4, size.height);
var paint = Paint()..color = color;
canvas.drawRect(rect, paint);
}
@override
bool shouldRepaint(covariant CustomPainter oldDelegate) {
return true;
}
}
... ...
... ... @@ -34,8 +34,11 @@ class GptMarkdownConfig {
codeBuilder;
final int? maxLines;
final TextOverflow? overflow;
final Widget Function(BuildContext context, String text, TextStyle style)? highlightBuilder;
final Widget Function(BuildContext context, String text, String url, TextStyle style)? linkBuilder;
final Widget Function(BuildContext context, String text, TextStyle style)?
highlightBuilder;
final Widget Function(
BuildContext context, String text, String url, TextStyle style)?
linkBuilder;
GptMarkdownConfig copyWith({
TextStyle? style,
... ... @@ -55,8 +58,11 @@ class GptMarkdownConfig {
codeBuilder,
final int? maxLines,
final TextOverflow? overflow,
final Widget Function(BuildContext context, String text, TextStyle style)? highlightBuilder,
final Widget Function(BuildContext context, String text, String url, TextStyle style)? linkBuilder,
final Widget Function(BuildContext context, String text, TextStyle style)?
highlightBuilder,
final Widget Function(
BuildContext context, String text, String url, TextStyle style)?
linkBuilder,
}) {
return GptMarkdownConfig(
style: style ?? this.style,
... ...
... ... @@ -13,6 +13,7 @@ import 'package:gpt_markdown/custom_widgets/unordered_ordered_list.dart';
import 'dart:math';
import 'custom_widgets/code_field.dart';
import 'custom_widgets/indent_widget.dart';
import 'custom_widgets/link_button.dart';
part 'theme.dart';
... ... @@ -55,8 +56,11 @@ class GptMarkdown extends StatelessWidget {
final Widget Function(BuildContext context, String name, String code)?
codeBuilder;
final Widget Function(BuildContext, String, TextStyle)? sourceTagBuilder;
final Widget Function(BuildContext context, String text, TextStyle style)? highlightBuilder;
final Widget Function(BuildContext context, String text, String url, TextStyle style)? linkBuilder;
final Widget Function(BuildContext context, String text, TextStyle style)?
highlightBuilder;
final Widget Function(
BuildContext context, String text, String url, TextStyle style)?
linkBuilder;
@override
Widget build(BuildContext context) {
... ...
... ... @@ -2,28 +2,28 @@ part of 'gpt_markdown.dart';
/// Markdown components
abstract class MarkdownComponent {
static final List<MarkdownComponent> components = [
CodeBlockMd(),
NewLines(),
// IndentMd(),
ImageMd(),
TableMd(),
HTag(),
UnOrderedList(),
OrderedList(),
RadioButtonMd(),
CheckBoxMd(),
HrLine(),
LatexMath(),
LatexMathMultiLine(),
ImageMd(),
HighlightedText(),
StrikeMd(),
BoldMd(),
ItalicMd(),
ATagMd(),
SourceTag(),
];
static List<MarkdownComponent> get components => [
CodeBlockMd(),
NewLines(),
IndentMd(),
ImageMd(),
TableMd(),
HTag(),
UnOrderedList(),
OrderedList(),
RadioButtonMd(),
CheckBoxMd(),
HrLine(),
LatexMath(),
LatexMathMultiLine(),
ImageMd(),
HighlightedText(),
StrikeMd(),
BoldMd(),
ItalicMd(),
ATagMd(),
SourceTag(),
];
/// Generate widget for markdown widget
static List<InlineSpan> generate(
... ... @@ -311,7 +311,7 @@ class IndentMd extends InlineMd {
@override
RegExp get exp =>
// RegExp(r"(?<=\n\n)(\ +)(.+?)(?=\n\n)", dotAll: true, multiLine: true);
RegExp(r"(?:\n\n+)^(\ *)(.+?)$(?:\n\n+)", dotAll: true, multiLine: true);
RegExp(r"^>([^\n]+)$", dotAll: true, multiLine: true);
@override
InlineSpan span(
... ... @@ -320,8 +320,7 @@ class IndentMd extends InlineMd {
final GptMarkdownConfig config,
) {
var match = exp.firstMatch(text);
int spaces = (match?[1] ?? "").length;
var data = "${match?[2]}".trim();
var data = "${match?[1]}".trim();
// data = data.replaceAll(RegExp(r'\n\ {' '$spaces' '}'), '\n').trim();
data = data.trim();
var child = TextSpan(
... ... @@ -331,23 +330,21 @@ class IndentMd extends InlineMd {
config,
),
);
var leftPadding = 20.0;
if (spaces < 4) {
leftPadding = 0;
}
var padding = config.style?.fontSize ?? 16.0;
return TextSpan(
children: [
WidgetSpan(
child: Padding(
padding: EdgeInsets.symmetric(vertical: padding),
child: Row(
children: [
SizedBox(
width: leftPadding,
child: Directionality(
textDirection: config.textDirection,
child: Padding(
padding: const EdgeInsets.symmetric(vertical: 2),
child: IndentWidget(
color: Theme.of(context).colorScheme.onSurfaceVariant,
direction: config.textDirection,
child: Padding(
padding: const EdgeInsetsDirectional.only(start: 10.0),
child: Expanded(child: config.getRich(child)),
),
Expanded(child: config.getRich(child)),
],
),
),
),
),
... ... @@ -517,7 +514,8 @@ class StrikeMd extends InlineMd {
class ItalicMd extends InlineMd {
@override
RegExp get exp =>
RegExp(r"(?<!\*)\*(?<!\s)(.+?)(?<!\s)\*(?!\*)", dotAll: true);
RegExp(r"(?<!\*)\*(?<!\s)(.+?)(?<!\s)\*(?!\*)|\_(?<!\s)(.+?)(?<!\s)\_",
dotAll: true);
@override
InlineSpan span(
... ... @@ -526,13 +524,14 @@ class ItalicMd extends InlineMd {
final GptMarkdownConfig config,
) {
var match = exp.firstMatch(text.trim());
var data = match?[1] ?? match?[2];
var conf = config.copyWith(
style: (config.style ?? const TextStyle())
.copyWith(fontStyle: FontStyle.italic));
return TextSpan(
children: MarkdownComponent.generate(
context,
"${match?[1]}",
"$data",
conf,
),
style: conf.style,
... ... @@ -733,10 +732,10 @@ class ATagMd extends InlineMd {
if (match?[1] == null && match?[2] == null) {
return const TextSpan();
}
final linkText = match?[1] ?? "";
final url = match?[2] ?? "";
// Use custom builder if provided
if (config.linkBuilder != null) {
return WidgetSpan(
... ... @@ -924,9 +923,8 @@ class CodeBlockMd extends BlockMd {
String codes = this.exp.firstMatch(text)?[2] ?? "";
String name = this.exp.firstMatch(text)?[1] ?? "";
codes = codes.replaceAll(r"```", "").trim();
return config.codeBuilder != null
? config.codeBuilder!(context, name, codes)
: CodeField(name: name, codes: codes);
return config.codeBuilder?.call(context, name, codes) ??
CodeField(name: name, codes: codes);
}
}
... ...
name: gpt_markdown
description: "Powerful Markdown & LaTeX Renderer for Flutter: Rich Text, Math, Tables, Links, and Text Selection. Ideal for ChatGPT, Gemini, and more."
version: 1.0.5
version: 1.0.6
homepage: https://github.com/Infinitix-LLC/gpt_markdown
environment:
... ...