Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add some colour #87

Open
JCKodel opened this issue May 26, 2023 · 1 comment
Open

Add some colour #87

JCKodel opened this issue May 26, 2023 · 1 comment

Comments

@JCKodel
Copy link

JCKodel commented May 26, 2023

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));
  }
}
@chenzhiguang
Copy link
Contributor

@JCKodel Thanks a lot! I will have a look at it later soon

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants