leancode_markup 0.1.0
leancode_markup: ^0.1.0 copied to clipboard
Simple package that allows you parse text with predefined tags, and returns styled Flutter text.
leancode_markup #
Simple package that allows you parse text with predefined tags, and returns styled Flutter text.
Available tags #
None. Dart part of this package is agnostic to any semantics of tags.
Basic tag styles #
However, we provide a list of basic tag styles for quick use. Read more in usage.
Usage #
- MarkupTagStyle - define custom tag style
- DefaultMarkupTheme - apply tag styles to descendant
- MarkupText - widget for markup text
- Example
MarkupTagStyle #
Define custom tag and style using MarkupTagStyle.delegate
. Pass tag name and desired style, e.g. to use tag [b] to apply FontWeight.bold
to text do:
MarkupTagStyle.delegate(
tagName: 'b',
styleCreator: (_) => const TextStyle(fontWeight: FontWeight.bold),
),
MarkupTagSpanFactory #
You could wrap your tagged text into any widgets. To do so, define tag factory for specified tag. Tag factory could be only defined in the tagFactories parameter in DefaultMarkupTheme
, that take as argument Map of pairs tag
:MarkupTagSpanFactory
. It's done like that, so there's a guarantee that every tag has only one factory.
MarkupTagSpanFactory
takes as parameters child Widget
, that needs to be wraped with desired widgets and optional parameter
taken from tag parsing.
It returns WidgetSpan.
DefaultMarkupTheme #
DefaultMarkupTheme
is equivalent of well known DefaultTextStyle
, but for the MarkupTagStyle
. It apply markup tag styles to descendant MarkupText
widgets.
DefaultMarkupTheme
also has Map<String, MarkupTagSpanFactory> tagFactories
parameter to wrap specified tagged text with Widgets.
DefaultMarkupTheme(
logger: debugPrint,
tagStyles: [
MarkupTagStyle.delegate(
tagName: 'b',
styleCreator: (_) => const TextStyle(fontWeight: FontWeight.bold),
),
MarkupTagStyle.delegate(
tagName: 'i',
styleCreator: (_) => const TextStyle(fontStyle: FontStyle.italic),
),
],
tagFactories: {
'url': (child, parameter) {
return WidgetSpan(
child: GestureDetector(
onTap: () => launchUrl(Uri.parse(parameter!)),
child: child,
),
);
},
// More factories...
},
child: ...
),
Logging
If you want to log invalid tags, pass logging method as DefaultMarkupTheme
param.
MarkupText #
Converts passed String
into Text.rich
with applied TextStyles
.
Use tag styles from ancestor DefaultMarkupTheme
const MarkupText(
'[u]underline[/u][i][b]Italic, bold text[/b][/i]',
),
Use predefined DefaultMarkupTheme.basicTag
MarkupText(
'[u]underline[/u][i][b]Italic, bold text[/b][/i]',
tagStyles: DefaultMarkupTheme.basicTags,
),
Use custom tag styles
MarkupText(
'[green][u]underline[/u][/green][i][b]Italic, bold text[/b][/i]',
tagStyles: [
MarkupTagStyle.delegate(
tagName: 'green',
styleCreator: (_) => const TextStyle(color: Colors.green),
),
],
),
Overwrite tag styles from ancestor
DefaultMarkupTheme(
tagStyles: DefaultMarkupTheme.basicTags,
child: MarkupText(
'[u]underline[/u][i][b]Italic, bold text[/b][/i]',
tagStyles: [
MarkupTagStyle.delegate(
tagName: 'b',
styleCreator: (_) => const TextStyle(fontWeight: FontWeight.w900),
),
],
),
),
Escape tag
Center(
child: MarkupText(
r'[u][i]Lorem ipsum dolor sit amet, \[b]consectetur adipiscing elit\[/b][/i][/u]',
tagStyles: DefaultMarkupTheme.basicTags,
),
),
Example #
This code shows an example of usage DefaultMarkupTheme
and MarkupText
.
Column(
mainAxisAlignment: MainAxisAlignment.center,
children: [
// You can use `DefaultMarkupTheme` to define common tag styles for children.
DefaultMarkupTheme(
tagStyles: [
MarkupTagStyle.delegate(
tagName: 'b',
styleCreator: (_) =>
const TextStyle(fontWeight: FontWeight.bold),
),
MarkupTagStyle.delegate(
tagName: 'i',
styleCreator: (_) =>
const TextStyle(fontStyle: FontStyle.italic),
),
MarkupTagStyle.delegate(
tagName: 'u',
styleCreator: (_) =>
const TextStyle(decoration: TextDecoration.underline),
),
MarkupTagStyle.delegate(
tagName: 'url',
styleCreator: (_) => const TextStyle(color: Colors.lightBlue),
),
MarkupTagStyle.delegate(
tagName: 'yellow',
styleCreator: (_) => const TextStyle(
backgroundColor: Colors.black,
),
),
],
// Add tag factories to wrap your tagged text into any widget
tagFactories: {
// Make clickable link
'url': (child, parameter) {
return WidgetSpan(
child: GestureDetector(
onTap: () async {
if (parameter != null &&
await canLaunchUrl(Uri.parse(parameter))) {
await launchUrl(Uri.parse(parameter));
}
},
child: child,
),
);
},
// Transform text
'sup': (child, parameter) {
return WidgetSpan(
child: Transform.translate(
offset: const Offset(2, -4),
child: child,
),
);
},
},
child: Column(
children: [
// Use tag styles from `DefaultMarkupTheme` parent
const MarkupText(
'[i]Lorem ipsum dolor sit amet, [b]consectetur adipiscing elit[/b][/i]',
),
const SizedBox(height: 8),
MarkupText(
'[yellow][i]Lorem ipsum dolor sit amet, [b]consectetur adipiscing elit[/b][/i][/yellow]',
tagStyles: [
// You can add custom tag styles just for `MarkupText`.
// The rest of the tag styles will still be taken from the parent.
MarkupTagStyle.delegate(
tagName: 'yellow',
styleCreator: (_) =>
const TextStyle(color: Color(0xFFFEFF00)),
),
// You can overwrite tag styles from `DefaultMarkupTheme` parent
MarkupTagStyle.delegate(
tagName: 'b',
styleCreator: (_) =>
const TextStyle(fontWeight: FontWeight.w900),
),
],
),
const SizedBox(height: 8),
// Use tag factories to create e.g. clickable text to open link
const MarkupText(
'[url="https://leancode.co"][i]Lorem ipsum dolor sit amet, [b]consectetur adipiscing elit[/b][/i][/url]',
),
],
),
),
const SizedBox(height: 8),
// You can use `basicTags` just in `MarkupText` widget.
Center(
child: MarkupText(
'[u][i]Lorem ipsum dolor sit amet, [b]consectetur adipiscing elit[/b][/i][/u]',
tagStyles: DefaultMarkupTheme.basicTags,
),
),
const SizedBox(height: 8),
// You can escape tags using "\".
Center(
child: MarkupText(
r'[u][i]Lorem ipsum dolor sit amet, \[b]consectetur adipiscing elit\[/b][/i][/u]',
tagStyles: DefaultMarkupTheme.basicTags,
),
),
],
),
TODOs: #
- Flutter tests
- Optimize rendering. Some style computations can be cached/precomputed at
DefaultMarkupTheme
level - Better error reporting