Toggle navigation
Toggle navigation
This project
Loading...
Sign in
flutter_package
/
gpt_markdown
Go to a project
Toggle navigation
Projects
Groups
Snippets
Help
Toggle navigation pinning
Project
Activity
Repository
Pipelines
Graphs
Issues
0
Merge Requests
0
Wiki
Network
Create a new issue
Builds
Commits
Authored by
saminsohag
2025-03-07 16:09:39 +0600
Browse Files
Options
Browse Files
Download
Email Patches
Plain Diff
Commit
4a4e737e68f8efc30f8be8b16f820e947a1ff48b
4a4e737e
1 parent
2533adf3
imagebuilder added and doc improved
Hide whitespace changes
Inline
Side-by-side
Showing
15 changed files
with
286 additions
and
29 deletions
CHANGELOG.md
lib/custom_widgets/code_field.dart
lib/custom_widgets/custom_divider.dart
lib/custom_widgets/custom_error_image.dart
lib/custom_widgets/custom_rb_cb.dart
lib/custom_widgets/indent_widget.dart
lib/custom_widgets/link_button.dart
lib/custom_widgets/markdown_config.dart
lib/custom_widgets/selectable_adapter.dart
lib/custom_widgets/unordered_ordered_list.dart
lib/gpt_markdown.dart
lib/markdown_component.dart
lib/md_widget.dart
lib/theme.dart
pubspec.yaml
CHANGELOG.md
View file @
4a4e737
## 1.0.12
*
imageBuilder parameter added.
## 1.0.11
*
dart format.
...
...
lib/custom_widgets/code_field.dart
View file @
4a4e737
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
;
...
...
lib/custom_widgets/custom_divider.dart
View file @
4a4e737
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
;
...
...
lib/custom_widgets/custom_error_image.dart
View file @
4a4e737
...
...
@@ -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
,
...
...
lib/custom_widgets/custom_rb_cb.dart
View file @
4a4e737
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
,
...
...
lib/custom_widgets/indent_widget.dart
View file @
4a4e737
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
;
...
...
lib/custom_widgets/link_button.dart
View file @
4a4e737
...
...
@@ -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
({
...
...
lib/custom_widgets/markdown_config.dart
View file @
4a4e737
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
,
...
...
lib/custom_widgets/selectable_adapter.dart
View file @
4a4e737
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
,
...
...
lib/custom_widgets/unordered_ordered_list.dart
View file @
4a4e737
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
...
...
lib/gpt_markdown.dart
View file @
4a4e737
...
...
@@ -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
),
...
...
lib/markdown_component.dart
View file @
4a4e737
...
...
@@ -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
);
}
}
...
...
lib/md_widget.dart
View file @
4a4e737
...
...
@@ -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
)
{
...
...
lib/theme.dart
View file @
4a4e737
...
...
@@ -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
=
...
...
pubspec.yaml
View file @
4a4e737
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.1
1
version
:
1.0.1
2
homepage
:
https://github.com/Infinitix-LLC/gpt_markdown
environment
:
...
...
Please
register
or
login
to post a comment