markdown icon indicating copy to clipboard operation
markdown copied to clipboard

Support for text highlight.

Open devon opened this issue 3 years ago • 7 comments

Some markdown editor like Quilt, iA Writer, Typora support text highlight style:

This is ==highlighted== text.

Any chance we can add the feature?

devon avatar Apr 02 '21 11:04 devon

I'm currently using this to highlight text in my app:


class HighlightSyntax extends TagSyntax {
  HighlightSyntax()
      : super(
          '=+',
          requiresDelimiterRun: true,
          allowIntraWord: true,
        );

  @override
  Node close(
    InlineParser parser,
    Delimiter opener,
    Delimiter closer, {
    required List<Node> Function() getChildren,
  }) {
    return Element('mark', getChildren());
  }
}

wilsonowilson avatar Sep 08 '21 15:09 wilsonowilson

Can you link to the output these renderers use? Is @wilsonowilson 's mark tag the correct rendering? Is it standard? I admit I haven't heard of these three tools, but if they're popular or standard in some way, we could support the syntax.

(Note: I'm very happy that TagSyntax seems to be extensible enough to cover this. 😁 )

srawlins avatar Sep 08 '21 16:09 srawlins

There is no CommonMark standard, but plugins for other languages like markdown-it like: https://github.com/markdown-it/markdown-it-mark use the same tag & delimiter. Apps like AI Writer and Bear export to html using this tag as well.

See https://stackoverflow.com/questions/25104738/text-highlight-in-markdown for more info.

Since there is no standard, the delimiter varies between apps, but the most popular, used by Obsidian.md, Typora, Ai Writer, Quilt, and Nota.md is ==. I've only seen :: in Bear and ^^ in Roam

wilsonowilson avatar Sep 08 '21 16:09 wilsonowilson

@wilsonowilson thanks for that workaround. However it doesn't work as expected in my app.

Here is how I use it

import 'package:flutter/material.dart' hide Element;
import 'package:flutter_markdown/flutter_markdown.dart';
import 'package:markdown/markdown.dart' hide Text;
import 'package:markdown/markdown.dart' as md;

/// Your code exactly
class HighlightSyntax extends TagSyntax {
  HighlightSyntax()
      : super(
          '=+',
          requiresDelimiterRun: true,
          allowIntraWord: true,
        );

  @override
  Node close(
    InlineParser parser,
    Delimiter opener,
    Delimiter closer, {
    required List<Node> Function() getChildren,
  }) {
    return Element('mark', getChildren());
  }
}

/// mark element builder
class HighlightElementBuilder extends MarkdownElementBuilder {
  @override
  Widget? visitElementAfter(md.Element element, preferredStyle) {
    return Text(
      element.textContent,
      style: const TextStyle(
        backgroundColor: Colors.yellow,
        fontWeight: FontWeight.bold,
      ),
    );
  }
}

and in widget I use it as

///This is nested in widget
Markdown(
        data: body,
        inlineSyntaxes: [HighlightSyntax()],
        builders: {
          'mark': HighlightElementBuilder(),
        },
      ),

When I try parsing the following data

# 99.9 Test MD file

==This should be highlighted.==

This should not be highlighted.

it is rendered as 111111111111

as you can see some of words are duplicates. May you help me what I am doing wrong?

kateile avatar Jan 25 '22 16:01 kateile

In #407 @chenzhiguang is changing TagSyntax into DelimiterSyntax which should allow developers to implement a highlight syntax, easier than the current TagSyntax.

Since text highlighting syntax is not currently a standard syntax, or part of a major flavor (like GitHub-flavored Markdown), I don't think we will implement or maintain it in this base package. The new DelimiterSyntax should allow a developer to make their own markdown extension package which implements such extensions.

srawlins avatar Apr 14 '22 15:04 srawlins

Here is an example of implementing a highlight syntax:

final result = markdownToHtml('==highlight==', inlineSyntaxes: [
  DelimiterSyntax('=+',
      requiresDelimiterRun: true,
      allowIntraWord: true,
      tags: [DelimiterTag('mark', 2)]),
]);

or

class HighlightSyntax extends DelimiterSyntax {
  HighlightSyntax()
      : super('=+',
            requiresDelimiterRun: true,
            allowIntraWord: true,
            tags: [DelimiterTag('mark', 2)]);
}

final result = markdownToHtml('==highlight==', inlineSyntaxes: [
  HighlightSyntax(),
]);

chenzhiguang avatar Apr 14 '22 18:04 chenzhiguang

@wilsonowilson thanks for that workaround. However it doesn't work as expected in my app.

Here is how I use it

import 'package:flutter/material.dart' hide Element;
import 'package:flutter_markdown/flutter_markdown.dart';
import 'package:markdown/markdown.dart' hide Text;
import 'package:markdown/markdown.dart' as md;

/// Your code exactly
class HighlightSyntax extends TagSyntax {
  HighlightSyntax()
      : super(
          '=+',
          requiresDelimiterRun: true,
          allowIntraWord: true,
        );

  @override
  Node close(
    InlineParser parser,
    Delimiter opener,
    Delimiter closer, {
    required List<Node> Function() getChildren,
  }) {
    return Element('mark', getChildren());
  }
}

/// mark element builder
class HighlightElementBuilder extends MarkdownElementBuilder {
  @override
  Widget? visitElementAfter(md.Element element, preferredStyle) {
    return Text(
      element.textContent,
      style: const TextStyle(
        backgroundColor: Colors.yellow,
        fontWeight: FontWeight.bold,
      ),
    );
  }
}

and in widget I use it as

///This is nested in widget
Markdown(
        data: body,
        inlineSyntaxes: [HighlightSyntax()],
        builders: {
          'mark': HighlightElementBuilder(),
        },
      ),

When I try parsing the following data

# 99.9 Test MD file

==This should be highlighted.==

This should not be highlighted.

it is rendered as 111111111111

as you can see some of words are duplicates. May you help me what I am doing wrong?

Was running into the same problem when trying to implement this. It seems to be something to do with having an empty line following the highlighted text, appears to be some kind of bug.

Balin-P avatar Oct 25 '23 03:10 Balin-P