API Reference
Use the basic guide first. This page is the lookup sheet for parameters, builders, and advanced customization.
The three things you usually need
Use styleSheet.
Use a component builder.
Use inlinePatterns.
Full constructor signature show
1const GptMarkdown(
2 this.data, { // required positional String
3 super.key,
4
5 // ── Text ───────────────────────────────────────────
6 this.style, // TextStyle?
7 this.textDirection = TextDirection.ltr,
8 this.textAlign, // TextAlign?
9 this.textScaler, // TextScaler?
10 this.maxLines, // int?
11 this.overflow, // TextOverflow?
12
13 // ── Appearance ─────────────────────────────────────
14 this.styleSheet, // GptMarkdownStyleSheet? — 12 per-component styles
15 this.inlineCodeStyle, // InlineCodeStyle? — inline code only
16
17 // ── Links ──────────────────────────────────────────
18 this.followLinkColor = false,
19 this.onLinkTap, // void Function(String url, String title)?
20 this.linkBuilder, // LinkBuilder?
21
22 // ── Autolinks ──────────────────────────────────────
23 this.autolink = true,
24 this.autolinkSchemes = const <String>{},
25
26 // ── LaTeX ──────────────────────────────────────────
27 this.useDollarSignsForLatex = false,
28 this.latexWorkaround, // String Function(String tex)?
29 this.latexBuilder, // LatexBuilder?
30
31 // ── Code blocks ────────────────────────────────────
32 this.codeBuilder, // CodeBlockBuilder?
33
34 // ── Inline code ────────────────────────────────────
35 this.inlineCodeBuilder, // InlineCodeBuilder? — returns InlineSpan, not Widget
36 ('Use inlineCodeBuilder. Will be removed in 2.0.0.')
37 this.highlightBuilder, // HighlightBuilder? — returns Widget
38
39 // ── Images ─────────────────────────────────────────
40 this.imageBuilder, // ImageBuilder?
41 this.onImageTap, // void Function(String url)?
42
43 // ── Lists ──────────────────────────────────────────
44 this.orderedListBuilder, // OrderedListBuilder?
45 this.unOrderedListBuilder, // UnOrderedListBuilder?
46
47 // ── Tables ─────────────────────────────────────────
48 this.tableBuilder, // TableBuilder?
49
50 // ── Headings ───────────────────────────────────────
51 this.headingBuilder, // HeadingBuilder?
52
53 // ── Block quotes ───────────────────────────────────
54 this.blockQuoteBuilder, // BlockQuoteBuilder?
55
56 // ── Checkboxes / radio ─────────────────────────────
57 this.checkboxBuilder, // CheckboxBuilder?
58 this.radioOptionBuilder, // RadioOptionBuilder?
59 this.onCheckboxChanged, // void Function(bool value)?
60
61 // ── Horizontal rules ───────────────────────────────
62 this.hrBuilder, // HrBuilder?
63
64 // ── Source tags (citations) ────────────────────────
65 this.sourceTagBuilder, // SourceTagBuilder?
66 this.onSourceTagTap, // void Function(String content)?
67
68 // ── Copy ───────────────────────────────────────────
69 this.onCodeCopy, // void Function(String code)?
70
71 // ── Custom components ──────────────────────────────
72 this.components, // List<MarkdownComponent>? — replaces block defaults if set
73 this.inlineComponents, // List<MarkdownComponent>? — replaces inline defaults if set
74 this.inlinePatterns, // List<InlinePattern>? — @mention, #channel, :emoji:
75
76 // ── Streaming ──────────────────────────────────────
77 this.animation = GptMarkdownAnimation.none,
78 this.isStreaming = true,
79 this.charactersPerSecond = 300,
80})All parameters show reference
Open a category only when you need to look up a specific option.
| Parameter | Type | Req. | Description |
|---|---|---|---|
| data | String | ✅ | The Markdown string to render. Positional. |
| style | TextStyle? | Base text style applied to all text. | |
| textDirection | TextDirection | LTR (default) or RTL for Arabic, Hebrew, etc. | |
| textAlign | TextAlign? | Text alignment within the widget. | |
| textScaler | TextScaler? | Scales text size; also propagated to inline widgets via MediaQuery. | |
| maxLines | int? | Limit rendered lines. null = unlimited. | |
| overflow | TextOverflow? | Overflow behaviour when maxLines is set. |
| Parameter | Type | Req. | Description |
|---|---|---|---|
| styleSheet | GptMarkdownStyleSheet? | 12 per-component style objects. Widget values win over theme values per field. | |
| inlineCodeStyle | InlineCodeStyle? | Inline code style for this widget only. Unset fields derive from ColorScheme. |
| Parameter | Type | Req. | Description |
|---|---|---|---|
| followLinkColor | bool | If true, links inherit the base text colour instead of linkColor. | |
| onLinkTap | void Function(String url, String title)? | Callback when a Markdown link is tapped. title is the label text. | |
| linkBuilder | LinkBuilder? | Fully replace the link widget. Receives the resolved label InlineSpan. |
| Parameter | Type | Req. | Description |
|---|---|---|---|
| autolink | bool | Bare URLs, www. hosts, emails and <…> autolinks become links. Default true. | |
| autolinkSchemes | Set<String> | Extra URI schemes linked bare (http/https/mailto/xmpp always included). |
| Parameter | Type | Req. | Description |
|---|---|---|---|
| useDollarSignsForLatex | bool | Enable $…$ and $$…$$ syntax in addition to \(…\) and \[…\]. | |
| latexWorkaround | String Function(String)? | Transform LaTeX strings before rendering (normalise AI output quirks). | |
| latexBuilder | LatexBuilder? | Replace the default LaTeX renderer. inline is true for \(…\). |
| Parameter | Type | Req. | Description |
|---|---|---|---|
| codeBuilder | CodeBlockBuilder? | Replace the fenced code block renderer. closed is false while still streaming. | |
| inlineCodeBuilder | InlineCodeBuilder? | Replace inline `code` span. Return CodeTextSpan to retain the painted chip, baseline alignment, selection, and wrapping; another TextSpan drops the chip. | |
| highlightBuilder ⚠️ | HighlightBuilder? (deprecated) | Deprecated. Returns Widget, causing baseline/selection/iOS issues. Use inlineCodeStyle or inlineCodeBuilder. | |
| onCodeCopy | void Function(String code)? | Called with the code string after the copy button is used. |
| Parameter | Type | Req. | Description |
|---|---|---|---|
| imageBuilder | ImageBuilder? | Replace the image renderer. width/height come from alt text parsed as WxH. | |
| onImageTap | void Function(String url)? | Called with the image URL when an image is tapped. |
| Parameter | Type | Req. | Description |
|---|---|---|---|
| orderedListBuilder | OrderedListBuilder? | Replace the ordered list item renderer. no is the number string, e.g. '1'. | |
| unOrderedListBuilder | UnOrderedListBuilder? | Replace the unordered list item renderer. |
| Parameter | Type | Req. | Description |
|---|---|---|---|
| tableBuilder | TableBuilder? | Replace the table renderer. Receives List<CustomTableRow>, the resolved TextStyle and GptMarkdownConfig. |
| Parameter | Type | Req. | Description |
|---|---|---|---|
| headingBuilder | HeadingBuilder? | Replace the whole heading widget. level is 1–6. Owns the h1 divider rule. |
| Parameter | Type | Req. | Description |
|---|---|---|---|
| blockQuoteBuilder | BlockQuoteBuilder? | Replace the whole blockquote. content is already-rendered; style is resolved BlockQuoteStyle. |
| Parameter | Type | Req. | Description |
|---|---|---|---|
| checkboxBuilder | CheckboxBuilder? | Replace the task-list checkbox row. Wire taps through onCheckboxChanged. | |
| radioOptionBuilder | RadioOptionBuilder? | Replace the radio option row. | |
| onCheckboxChanged | void Function(bool)? | Called on checkbox tap. Only fires when CheckboxStyle(interactive: true). |
| Parameter | Type | Req. | Description |
|---|---|---|---|
| hrBuilder | HrBuilder? | Replace the horizontal rule. style is the resolved HrStyle. |
| Parameter | Type | Req. | Description |
|---|---|---|---|
| sourceTagBuilder | SourceTagBuilder? | Render [1] citation chips. content is the number/text inside the brackets. | |
| onSourceTagTap | void Function(String)? | Called with the tag content when a citation chip is tapped. |
| Parameter | Type | Req. | Description |
|---|---|---|---|
| components | List<MarkdownComponent>? | Replaces the block component list entirely if set. Prepend custom items and append MarkdownComponent.globalComponents. | |
| inlineComponents | List<MarkdownComponent>? | Replaces the inline component list entirely if set. Prepend custom items and append MarkdownComponent.inlineComponents. | |
| inlinePatterns | List<InlinePattern>? | @mention, #channel, :emoji: patterns. Matched ahead of built-ins. Default scope excludes link labels. |
| Parameter | Type | Req. | Description |
|---|---|---|---|
| animation | GptMarkdownAnimation | GptMarkdownAnimation.none (default) or .fade for a streaming reveal. | |
| isStreaming | bool | Whether more text may still arrive. Flip to false when the stream ends. | |
| charactersPerSecond | double | Baseline reveal speed. The reveal auto-accelerates when behind the incoming text. |
Builder & callback signatures show reference
Builder arguments depend on the component. Builders that accept a style receive the resolved style; other builders receive component data such as code, dimensions, or the streaming closed flag.inlineCodeBuilder returns an InlineSpan. Return a CodeTextSpan to preserve the package's painted chip, baseline alignment, selection, and wrapping; a different TextSpan deliberately drops the chip.
1// ── Builders ─────────────────────────────────────────────────────────────────
2
3typedef HeadingBuilder =
4 Widget Function(BuildContext context, int level, Widget content, HeadingStyle style);
5
6typedef BlockQuoteBuilder =
7 Widget Function(BuildContext context, Widget content, BlockQuoteStyle style);
8
9typedef CheckboxBuilder =
10 Widget Function(BuildContext context, bool checked, Widget content, CheckboxStyle style);
11
12typedef RadioOptionBuilder =
13 Widget Function(BuildContext context, bool selected, Widget content, CheckboxStyle style);
14
15typedef HrBuilder = Widget Function(BuildContext context, HrStyle style);
16
17typedef CodeBlockBuilder =
18 Widget Function(BuildContext context, String name, String code, bool closed);
19
20typedef TableBuilder =
21 Widget Function(BuildContext context, List<CustomTableRow> tableRows,
22 TextStyle textStyle, GptMarkdownConfig config);
23
24typedef ImageBuilder =
25 Widget Function(BuildContext context, String imageUrl, double? width, double? height);
26
27typedef LatexBuilder =
28 Widget Function(BuildContext context, String tex, TextStyle textStyle, bool inline);
29
30typedef LinkBuilder =
31 Widget Function(BuildContext context, InlineSpan text, String url, TextStyle style);
32
33// Returns InlineSpan. Return CodeTextSpan to keep the package's painted,
34// baseline-aligned, selectable, wrappable chip; another TextSpan drops the chip.
35typedef InlineCodeBuilder =
36 InlineSpan Function(BuildContext context, String code, TextStyle style,
37 InlineCodeStyle codeStyle);
38
39typedef SourceTagBuilder =
40 Widget Function(BuildContext context, String content, TextStyle textStyle);
41
42typedef OrderedListBuilder =
43 Widget Function(BuildContext context, String no, Widget child, GptMarkdownConfig config);
44
45typedef UnOrderedListBuilder =
46 Widget Function(BuildContext context, Widget child, GptMarkdownConfig config);
47
48// ── Deprecated ───────────────────────────────────────────────────────────────
49
50// highlightBuilder: returns Widget (wrapped in WidgetSpan — cannot wrap across
51// lines, skipped by selection, invisible on iOS inside a link label).
52// Deprecated in v1.2.0. Will be removed in 2.0.0.
53// Prefer inlineCodeStyle for restyling, or inlineCodeBuilder for a custom span.
54('Use inlineCodeBuilder. Will be removed in 2.0.0.')
55typedef HighlightBuilder =
56 Widget Function(BuildContext context, String text, TextStyle style);Migrating from highlightBuilder show migration
Deprecated — scheduled for removal in 2.0.0
highlightBuilder returned a Widget wrapped in a WidgetSpan at a hardcoded PlaceholderAlignment.middle. That placement sat off the baseline, could not wrap across lines, was skipped by text selection, and did not paint on iOS inside a link label. Most callers only needed restyling and no longer need a builder at all.
1// Before (highlightBuilder — deprecated)
2GptMarkdown(
3 text,
4 highlightBuilder: (context, code, style) => MyChip(code, style),
5)
6
7// After — restyle only, no builder needed
8GptMarkdown(
9 text,
10 inlineCodeStyle: const InlineCodeStyle(fontFamily: 'GeistMono'),
11)
12
13// After — custom span (stays on baseline, wraps, stays selectable)
14GptMarkdown(
15 text,
16 inlineCodeBuilder: (context, code, style, codeStyle) => CodeTextSpan(
17 text: code,
18 style: style,
19 codeStyle: codeStyle.copyWith(
20 backgroundColor: code.startsWith('TODO') ? Colors.amber : null,
21 ),
22 ),
23)
24
25// After — widget genuinely required
26GptMarkdown(
27 text,
28 inlineCodeBuilder: (context, code, style, codeStyle) =>
29 baselineWidgetSpan(MyChip(code: code, style: style)),
30)Builder & callback matrix show reference
Use this as a lookup table when you know which component you want to replace.
| Component | Style class | Builder param | Callback param |
|---|---|---|---|
| Heading | HeadingStyle | headingBuilder | — |
| Block quote | BlockQuoteStyle | blockQuoteBuilder | — |
| Horizontal rule | HrStyle | hrBuilder | — |
| Checkbox / task list | CheckboxStyle | checkboxBuilder | onCheckboxChanged |
| Radio option | CheckboxStyle | radioOptionBuilder | onCheckboxChanged |
| Fenced code block | CodeBlockStyle | codeBuilder | onCodeCopy |
| Inline code | InlineCodeStyle | inlineCodeBuilder | — |
| Table | TableStyle | tableBuilder | — |
| Image | ImageStyle | imageBuilder | onImageTap |
| Link | LinkStyle | linkBuilder | onLinkTap |
| Ordered list item | ListStyle | orderedListBuilder | — |
| Unordered list item | ListStyle | unOrderedListBuilder | — |
| LaTeX (block & inline) | LatexStyle | latexBuilder | — |
| Citation chip [1] | SourceTagStyle | sourceTagBuilder | onSourceTagTap |
Common mistakes show tips
Changing a builder at runtime does nothing
GptMarkdownConfig.isSame cannot compare closures — a consumer that writes builders inline creates a new one every build, so span regeneration would happen on every frame. Builder changes therefore require a key change or a remount. Style objects compare by value and update live. Pattern and component lists use element identity: rebuilding the list is fine when it contains the same instances, but replace an element instance when its matching behavior changes.
A raw WidgetSpan scales twice
A paragraph lays inline children out in scaled space and multiplies their reported size back. A child that also scales its own text is counted twice — up to 39× excess at a 2× system font setting. Use baselineWidgetSpan, or wrap the child in MediaQuery.withNoTextScaling. InlinePattern does this for you.
