saminsohag

imagebuilder added and doc improved

## 1.0.12
* imageBuilder parameter added.
## 1.0.11
* dart format.
... ...
import 'package:flutter/material.dart';
import 'package:flutter/services.dart';
/// A widget that displays code with syntax highlighting and a copy button.
///
/// The [CodeField] widget takes a [name] parameter which is displayed as a label
/// above the code block, and a [codes] parameter containing the actual code text
/// to display.
///
/// Features:
/// - Displays code in a Material container with rounded corners
/// - Shows the code language/name as a label
/// - Provides a copy button to copy code to clipboard
/// - Visual feedback when code is copied
/// - Themed colors that adapt to light/dark mode
class CodeField extends StatefulWidget {
const CodeField({super.key, required this.name, required this.codes});
final String name;
... ...
import 'package:flutter/material.dart';
/// A custom divider widget that extends LeafRenderObjectWidget.
///
/// The [CustomDivider] widget is used to create a horizontal divider line in the UI.
/// It takes an optional [color] parameter to specify the color of the divider,
/// and an optional [height] parameter to set the height of the divider.
///
class CustomDivider extends LeafRenderObjectWidget {
const CustomDivider({super.key, this.height, this.color});
/// The color of the divider.
///
/// If not provided, the divider will use the color of the current theme.
final Color? color;
/// The height of the divider.
///
/// If not provided, the divider will have a default height of 2.
final double? height;
@override
... ... @@ -25,6 +39,12 @@ class CustomDivider extends LeafRenderObjectWidget {
}
}
/// A custom render object for the [CustomDivider] widget.
///
/// The [RenderDivider] class extends RenderBox and is responsible for
/// painting the divider line. It takes a [color], [width], and [height]
/// and uses them to draw a horizontal line in the UI.
///
class RenderDivider extends RenderBox {
RenderDivider(Color color, double width, double height)
: _color = color,
... ... @@ -33,6 +53,8 @@ class RenderDivider extends RenderBox {
Color _color;
double _height;
double _width;
/// The color of the divider.
set color(Color value) {
if (value == _color) {
return;
... ... @@ -41,6 +63,7 @@ class RenderDivider extends RenderBox {
markNeedsPaint();
}
/// The height of the divider.
set height(double value) {
if (value == _height) {
return;
... ... @@ -49,6 +72,7 @@ class RenderDivider extends RenderBox {
markNeedsLayout();
}
/// The width of the divider.
set width(double value) {
if (value == _width) {
return;
... ...
... ... @@ -3,6 +3,13 @@ import 'dart:math';
import 'package:flutter/material.dart';
import 'package:flutter/rendering.dart';
/// A custom widget that displays an error image with customizable colors.
///
/// The [CustomImageError] widget is used to display an error image in the UI.
/// It takes an optional [iconColor], [backgroundColor], and [outlineColor] parameter
/// to customize the appearance of the error image.
///
class CustomImageError extends LeafRenderObjectWidget {
const CustomImageError({
super.key,
... ... @@ -38,6 +45,13 @@ class CustomImageError extends LeafRenderObjectWidget {
}
}
/// A custom render object for the [CustomImageError] widget.
///
/// The [RenderCustomImageError] class extends RenderProxyBox and is responsible for
/// painting the error image. It takes a [iconColor], [backgroundColor], and [outlineColor]
/// and uses them to draw an error image in the UI.
///
class RenderCustomImageError extends RenderProxyBox {
RenderCustomImageError(
this._iconColor,
... ... @@ -47,6 +61,8 @@ class RenderCustomImageError extends RenderProxyBox {
Color _iconColor;
Color _outlineColor;
Color _backgroundColor;
/// The color of the icon.
set iconColor(Color value) {
if (value == _iconColor) {
return;
... ... @@ -55,6 +71,7 @@ class RenderCustomImageError extends RenderProxyBox {
markNeedsPaint();
}
/// The background color of the error image.
set backgroundColor(Color value) {
if (value == _backgroundColor) {
return;
... ... @@ -63,6 +80,7 @@ class RenderCustomImageError extends RenderProxyBox {
markNeedsPaint();
}
/// The outline color of the error image.
set outlineColor(Color value) {
if (value == _outlineColor) {
return;
... ... @@ -125,6 +143,13 @@ class RenderCustomImageError extends RenderProxyBox {
}
}
/// A custom widget that displays a loading image with customizable colors.
///
/// The [CustomImageLoading] widget is used to display a loading image in the UI.
/// It takes an optional [iconColor], [backgroundColor], [outlineColor], and [progress] parameter
/// to customize the appearance of the loading image.
///
class CustomImageLoading extends LeafRenderObjectWidget {
const CustomImageLoading({
super.key,
... ... @@ -133,9 +158,17 @@ class CustomImageLoading extends LeafRenderObjectWidget {
this.outlineColor,
this.progress = 1,
});
/// The color of the icon.
final Color? iconColor;
/// The background color of the loading image.
final Color? backgroundColor;
/// The outline color of the loading image.
final Color? outlineColor;
/// The progress of the loading image.
final double progress;
@override
... ... @@ -164,6 +197,13 @@ class CustomImageLoading extends LeafRenderObjectWidget {
}
}
/// A custom render object for the [CustomImageLoading] widget.
///
/// The [RenderCustomImageLoading] class extends RenderProxyBox and is responsible for
/// painting the loading image. It takes a [iconColor], [backgroundColor], [outlineColor], and [progress]
/// and uses them to draw a loading image in the UI.
///
class RenderCustomImageLoading extends RenderProxyBox {
RenderCustomImageLoading(
this._iconColor,
... ...
import 'package:flutter/material.dart';
/// A custom radio button widget that extends StatelessWidget.
///
/// The [CustomRb] widget is used to create a radio button in the UI.
/// It takes a [child] parameter which is the content of the radio button,
/// a [value] parameter which is the value of the radio button,
/// and an optional [spacing] parameter to set the spacing between the radio button and its label.
class CustomRb extends StatelessWidget {
const CustomRb({
super.key,
... ... @@ -45,6 +51,12 @@ class CustomRb extends StatelessWidget {
}
}
/// A custom checkbox widget that extends StatelessWidget.
///
/// The [CustomCb] widget is used to create a checkbox in the UI.
/// It takes a [child] parameter which is the content of the checkbox,
/// a [value] parameter which is the value of the checkbox,
/// and an optional [spacing] parameter to set the spacing between the checkbox and its label.
class CustomCb extends StatelessWidget {
const CustomCb({
super.key,
... ...
import 'package:flutter/material.dart';
/// A custom widget that adds an indent to the left or right of its child.
///
/// The [IndentWidget] widget is used to create a visual indent in the UI.
/// It takes a [child] parameter which is the content of the widget,
/// a [direction] parameter which specifies the direction of the indent,
/// and a [color] parameter to set the color of the indent.
class IndentWidget extends StatelessWidget {
const IndentWidget({
super.key,
... ... @@ -7,8 +13,14 @@ class IndentWidget extends StatelessWidget {
required this.direction,
required this.color,
});
/// The child widget to be indented.
final Widget child;
/// The direction of the indent.
final TextDirection direction;
/// The color of the indent.
final Color color;
@override
... ... @@ -20,6 +32,11 @@ class IndentWidget extends StatelessWidget {
}
}
/// A custom painter that draws an indent on a canvas.
///
/// The [IndentPainter] class extends CustomPainter and is responsible for
/// painting the indent on a canvas. It takes a [color] and [direction] parameter
/// and uses them to draw an indent in the UI.
class IndentPainter extends CustomPainter {
IndentPainter(this.color, this.direction);
final Color color;
... ...
... ... @@ -2,13 +2,33 @@ import 'package:flutter/material.dart';
import 'markdown_config.dart';
/// A custom button widget that displays a link with customizable colors and styles.
///
/// The [LinkButton] widget is used to create a button that displays a link in the UI.
/// It takes a [text] parameter which is the text of the link,
/// a [config] parameter which is the configuration for the link,
/// a [color] parameter to set the color of the link,
class LinkButton extends StatefulWidget {
/// The text of the link.
final String text;
/// The callback function to be called when the link is pressed.
final VoidCallback? onPressed;
/// The style of the text.
final TextStyle? textStyle;
/// The URL of the link.
final String? url;
/// The configuration for the link.
final GptMarkdownConfig config;
/// The color of the link.
final Color color;
/// The color of the link when hovering.
final Color hoverColor;
const LinkButton({
... ...
import 'package:flutter/material.dart';
/// A configuration class for the GPT Markdown component.
///
/// The [GptMarkdownConfig] class is used to configure the GPT Markdown component.
/// It takes a [style] parameter to set the style of the text,
/// a [textDirection] parameter to set the direction of the text,
/// and an optional [onLinkTab] parameter to handle link clicks.
class GptMarkdownConfig {
const GptMarkdownConfig({
this.style,
... ... @@ -18,12 +24,26 @@ class GptMarkdownConfig {
this.maxLines,
this.overflow,
});
/// The direction of the text.
final TextDirection textDirection;
/// The style of the text.
final TextStyle? style;
/// The alignment of the text.
final TextAlign? textAlign;
/// The text scaler.
final TextScaler? textScaler;
/// The callback function to handle link clicks.
final void Function(String url, String title)? onLinkTab;
/// The LaTeX workaround.
final String Function(String tex)? latexWorkaround;
/// The LaTeX builder.
final Widget Function(
BuildContext context,
String tex,
... ... @@ -31,13 +51,19 @@ class GptMarkdownConfig {
bool inline,
)?
latexBuilder;
/// The source tag builder.
final Widget Function(
BuildContext context,
String content,
TextStyle textStyle,
)?
sourceTagBuilder;
/// Whether to follow the link color.
final bool followLinkColor;
/// The code builder.
final Widget Function(
BuildContext context,
String name,
... ... @@ -45,8 +71,14 @@ class GptMarkdownConfig {
bool closed,
)?
codeBuilder;
/// The maximum number of lines.
final int? maxLines;
/// The overflow.
final TextOverflow? overflow;
/// The highlight builder.
final Widget Function(BuildContext context, String text, TextStyle style)?
highlightBuilder;
final Widget Function(
... ... @@ -56,8 +88,11 @@ class GptMarkdownConfig {
TextStyle style,
)?
linkBuilder;
/// The image builder.
final Widget Function(BuildContext, String imageUrl)? imageBuilder;
/// A copy of the configuration with the specified parameters.
GptMarkdownConfig copyWith({
TextStyle? style,
TextDirection? textDirection,
... ... @@ -118,6 +153,7 @@ class GptMarkdownConfig {
);
}
/// A method to get a rich text widget from an inline span.
Text getRich(InlineSpan span) {
return Text.rich(
span,
... ...
import 'package:flutter/material.dart';
import 'package:flutter/rendering.dart';
/// A custom widget that allows text selection in a widget.
///
/// The [SelectableAdapter] widget is used to create a widget that allows text selection.
/// It takes a [child] parameter which is the content of the widget,
/// and a [selectedText] parameter which is the text to be selected.
class SelectableAdapter extends StatelessWidget {
const SelectableAdapter({
super.key,
... ...
import 'package:flutter/material.dart';
/// A custom widget that displays an unordered list of items.
///
/// The [UnorderedListView] widget is used to create a list of items with bullet points.
/// It takes a [child] parameter which is the content of the list item,
/// a [spacing] parameter to set the spacing between items,
/// a [padding] parameter to set the padding of the list item,
class UnorderedListView extends StatelessWidget {
const UnorderedListView({
super.key,
... ... @@ -10,11 +16,21 @@ class UnorderedListView extends StatelessWidget {
this.textDirection = TextDirection.ltr,
required this.child,
});
/// The size of the bullet point.
final double bulletSize;
/// The spacing between items.
final double spacing;
/// The padding of the list item.
final double padding;
final TextDirection textDirection;
/// The color of the bullet point.
final Color? bulletColor;
/// The child widget to be displayed in the list item.
final Widget child;
@override
... ... @@ -54,6 +70,12 @@ class UnorderedListView extends StatelessWidget {
}
}
/// A custom widget that displays an ordered list of items.
///
/// The [OrderedListView] widget is used to create a list of items with numbered points.
/// It takes a [child] parameter which is the content of the list item,
/// a [spacing] parameter to set the spacing between items,
/// a [padding] parameter to set the padding of the list item,
class OrderedListView extends StatelessWidget {
final String no;
final double spacing;
... ... @@ -67,8 +89,14 @@ class OrderedListView extends StatelessWidget {
this.textDirection = TextDirection.ltr,
required this.no,
}) : _style = style;
/// The style of the text.
final TextStyle? _style;
/// The direction of the text.
final TextDirection textDirection;
/// The child widget to be displayed in the list item.
final Widget child;
@override
... ...
... ... @@ -39,15 +39,33 @@ class GptMarkdown extends StatelessWidget {
this.maxLines,
this.overflow,
});
/// The direction of the text.
final TextDirection textDirection;
/// The data to be displayed.
final String data;
/// The style of the text.
final TextStyle? style;
/// The alignment of the text.
final TextAlign? textAlign;
/// The text scaler.
final TextScaler? textScaler;
/// The callback function to handle link clicks.
final void Function(String url, String title)? onLinkTab;
/// The LaTeX workaround.
final String Function(String tex)? latexWorkaround;
final int? maxLines;
/// The overflow.
final TextOverflow? overflow;
/// The LaTeX builder.
final Widget Function(
BuildContext context,
String tex,
... ... @@ -55,7 +73,11 @@ class GptMarkdown extends StatelessWidget {
bool inline,
)?
latexBuilder;
/// Whether to follow the link color.
final bool followLinkColor;
/// The code builder.
final Widget Function(
BuildContext context,
String name,
... ... @@ -63,9 +85,15 @@ class GptMarkdown extends StatelessWidget {
bool closed,
)?
codeBuilder;
/// The source tag builder.
final Widget Function(BuildContext, String, TextStyle)? sourceTagBuilder;
/// The highlight builder.
final Widget Function(BuildContext context, String text, TextStyle style)?
highlightBuilder;
/// The link builder.
final Widget Function(
BuildContext context,
String text,
... ... @@ -73,7 +101,11 @@ class GptMarkdown extends StatelessWidget {
TextStyle style,
)?
linkBuilder;
/// The image builder.
final Widget Function(BuildContext, String imageUrl)? imageBuilder;
/// A method to remove extra lines inside block LaTeX.
String _removeExtraLinesInsideBlockLatex(String text) {
return text.replaceAllMapped(
RegExp(r"\\\[(.*?)\\\]", multiLine: true, dotAll: true),
... ...
... ... @@ -755,38 +755,39 @@ class ImageMd extends InlineMd {
width = double.tryParse(size?[1]?.toString().trim() ?? 'a');
height = double.tryParse(size?[2]?.toString().trim() ?? 'a');
}
late final Widget image;
final Widget image;
if (config.imageBuilder != null) {
image = config.imageBuilder!(context, '${match?[2]}');
} else {
image = Image(
image: NetworkImage("${match?[2]}"),
loadingBuilder: (
BuildContext context,
Widget child,
ImageChunkEvent? loadingProgress,
) {
if (loadingProgress == null) {
return child;
}
return CustomImageLoading(
progress:
loadingProgress.expectedTotalBytes != null
? loadingProgress.cumulativeBytesLoaded /
loadingProgress.expectedTotalBytes!
: 1,
);
},
fit: BoxFit.fill,
errorBuilder: (context, error, stackTrace) {
return const CustomImageError();
},
image = SizedBox(
width: width,
height: height,
child: Image(
image: NetworkImage("${match?[2]}"),
loadingBuilder: (
BuildContext context,
Widget child,
ImageChunkEvent? loadingProgress,
) {
if (loadingProgress == null) {
return child;
}
return CustomImageLoading(
progress:
loadingProgress.expectedTotalBytes != null
? loadingProgress.cumulativeBytesLoaded /
loadingProgress.expectedTotalBytes!
: 1,
);
},
fit: BoxFit.fill,
errorBuilder: (context, error, stackTrace) {
return const CustomImageError();
},
),
);
}
return WidgetSpan(
alignment: PlaceholderAlignment.bottom,
child: SizedBox(width: width, height: height, child: image),
);
return WidgetSpan(alignment: PlaceholderAlignment.bottom, child: image);
}
}
... ...
... ... @@ -3,7 +3,11 @@ part of 'gpt_markdown.dart';
/// It creates a markdown widget closed to each other.
class MdWidget extends StatelessWidget {
const MdWidget(this.exp, {super.key, required this.config});
/// The expression to be displayed.
final String exp;
/// The configuration of the markdown widget.
final GptMarkdownConfig config;
@override
... ... @@ -32,6 +36,7 @@ class MdWidget extends StatelessWidget {
}
}
/// A custom table column width.
class CustomTableColumnWidth extends TableColumnWidth {
@override
double maxIntrinsicWidth(Iterable<RenderBox> cells, double containerWidth) {
... ...
... ... @@ -16,6 +16,7 @@ class GptMarkdownThemeData extends ThemeExtension<GptMarkdownThemeData> {
required this.linkHoverColor,
});
/// A factory constructor for `GptMarkdownThemeData`.
factory GptMarkdownThemeData({
required Brightness brightness,
Color? highlightColor,
... ... @@ -89,19 +90,38 @@ class GptMarkdownThemeData extends ThemeExtension<GptMarkdownThemeData> {
);
}
/// The highlight color.
Color highlightColor;
/// The style of the h1 text.
TextStyle? h1;
/// The style of the h2 text.
TextStyle? h2;
/// The style of the h3 text.
TextStyle? h3;
/// The style of the h4 text.
TextStyle? h4;
/// The style of the h5 text.
TextStyle? h5;
/// The style of the h6 text.
TextStyle? h6;
double hrLineThickness;
/// The color of the horizontal line.
Color hrLineColor;
/// The color of the link.
Color linkColor;
/// The color of the link when hovering.
Color linkHoverColor;
/// Define default attributes.
/// A method to copy the `GptMarkdownThemeData`.
@override
GptMarkdownThemeData copyWith({
Color? highlightColor,
... ... @@ -166,6 +186,7 @@ class GptMarkdownTheme extends InheritedWidget {
});
final GptMarkdownThemeData gptThemeData;
/// A method to get the `GptMarkdownThemeData` from the `BuildContext`.
static GptMarkdownThemeData of(BuildContext context) {
var theme = Theme.of(context);
final provider =
... ...
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.11
version: 1.0.12
homepage: https://github.com/Infinitix-LLC/gpt_markdown
environment:
... ...