Skip to content

Add some colour #87

@JCKodel

Description

@JCKodel

Since this parser doesn't render HTML, I made this custom syntax for colours:

#f00[This is red] renders Text("This is red", style: TextStyle(color: 0xffff0000)
#ff0000[This is red] renders Text("This is red", style: TextStyle(color: 0xffff0000)
#7fff0000[This is red] renders Text("This is red", style: TextStyle(color: 0x7fff0000)

It accepts 3 (RGB), 6 (RRGGBB) or 8 (AARRGGBB) hex codes.

class _ColorSyntax extends MdInlineSyntax {
  _ColorSyntax()
      : super(
          RegExp(r"#([0-9A-Fa-f]{3}|[0-9A-Fa-f]{6}|[0-9A-Fa-f]{8})\[([^\]]*)\]"),
        );

  @override
  MdInlineObject? parse(MdInlineParser parser, Match match) {
    final color = match.group(1)!;
    final text = match.group(2)!;

    final markers = [
      parser.consume(),
      ...parser.consumeBy(color.length),
      parser.consume(),
    ];

    final content = parser.consumeBy(text.length);

    markers.add(parser.consume());

    final children = content.map((e) => MdText.fromSpan(e)).toList();

    return MdInlineElement(
      "color",
      attributes: {"color": color},
      markers: markers,
      children: children,
      start: markers.first.start,
      end: children.last.end,
    );
  }
}

class _ColorBuilder extends MarkdownElementBuilder {
  _ColorBuilder();

  @override
  bool isBlock(element) => false;

  @override
  List<String> matchTypes = <String>["color"];

  @override
  TextStyle? buildTextStyle(MarkdownElement element, TextStyle defaultStyle) {
    final currentStyle = textStyle ?? textStyleMap?[element.type];
    final colorAttr = element.attributes["color"]!;

    final color = switch (colorAttr.length) {
      3 => _parseColor3(colorAttr),
      6 => _parseColor6(colorAttr),
      8 => _parseColor8(colorAttr),
      _ => throw FormatException("Unrecognized color pattern '${colorAttr}'"),
    };

    return defaultStyle
        .merge(parentStyle)
        .merge(currentStyle)
        .merge(TextStyle(color: color));
  }

  @override
  TextSpan buildText(
    String text,
    MarkdownTreeElement parent,
  ) =>
      TextSpan(
        text: text,
        style: parent.style,
        mouseCursor: renderer.mouseCursor,
      );

  Color _parseColor3(String color) {
    final r = color[0] + color[0];
    final g = color[1] + color[1];
    final b = color[2] + color[2];

    return Color(int.parse("ff$r$g$b", radix: 16));
  }

  Color _parseColor6(String color) {
    return Color(int.parse("ff${color}", radix: 16));
  }

  Color _parseColor8(String color) {
    return Color(int.parse(color, radix: 16));
  }
}

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions