leancode_markup 0.0.1 copy "leancode_markup: ^0.0.1" to clipboard
leancode_markup: ^0.0.1 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 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(
    log: 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,
                ),
            );
        },
        ...
    }
    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: #

  1. Flutter tests
  2. Optimize rendering. Some style computations can be cached/precomputed at DefaultMarkupTheme level
  3. Better error reporting
2
likes
160
pub points
60%
popularity

Publisher

verified publisherleancode.co

Simple package that allows you parse text with predefined tags, and returns styled Flutter text.

Homepage
Repository (GitHub)
View/report issues

Documentation

API reference

License

Apache-2.0 (LICENSE)

Dependencies

equatable, flutter, logging, meta, petitparser

More

Packages that depend on leancode_markup