Add custom markdown syntax for coloring text
<color>(text to color) where color can be a SVG color name, 3 characters hex or 6 characters hex code. Can be used to send colored message from the composer. Other clients that follow the matrix spec should be able to display them (e.g. riot, even if it can't send them)
This commit is contained in:
parent
be61a34ec0
commit
b0d77d74a9
1
TODO.md
1
TODO.md
|
@ -92,7 +92,6 @@
|
|||
- Way to open context menus without a right mouse button
|
||||
- `smartVerticalFlick()` gradual acceleration
|
||||
- Make banner buttons look better
|
||||
- Way to color HTML from the composer
|
||||
|
||||
- Choose a better default easing type for animations
|
||||
- Make HListView scrollbars visible
|
||||
|
|
|
@ -16,17 +16,41 @@ class MarkdownInlineGrammar(mistune.InlineGrammar):
|
|||
Modifications:
|
||||
|
||||
- Disable underscores for bold/italics (e.g. `__bold__`)
|
||||
|
||||
- Add syntax for coloring text: `<color>(text)`,
|
||||
e.g. `<red>(Lorem ipsum)` or `<#000040>(sit dolor amet...)`
|
||||
"""
|
||||
|
||||
escape = re.compile(r"^\\([\\`*{}\[\]()#+\-.!_<>~|])") # Add <
|
||||
emphasis = re.compile(r"^\*((?:\*\*|[^\*])+?)\*(?!\*)")
|
||||
double_emphasis = re.compile(r"^\*{2}([\s\S]+?)\*{2}(?!\*)")
|
||||
|
||||
# test string: r"<b>(x) <r>(x) \<a>b>(x) <a\>b>(x) <b>(\(z) <c>(foo\)xyz)"
|
||||
color = re.compile(
|
||||
r"^<(.+?)>" # capture the color in `<color>`
|
||||
r"\((.+?)" # capture text in `(text`
|
||||
r"(?<!\\)(?:\\\\)*" # ignore the next `)` if it's \escaped
|
||||
r"\)", # finish on a `)`
|
||||
)
|
||||
|
||||
|
||||
class MarkdownInlineLexer(mistune.InlineLexer):
|
||||
"""Apply the changes from `MarkdownInlineGrammar` for Mistune."""
|
||||
|
||||
grammar_class = MarkdownInlineGrammar
|
||||
|
||||
default_rules = [
|
||||
"escape", "color", "autolink", "url", # Add color
|
||||
"footnote", "link", "reflink", "nolink",
|
||||
"double_emphasis", "emphasis", "code",
|
||||
"linebreak", "strikethrough", "text",
|
||||
]
|
||||
inline_html_rules = [
|
||||
"escape", "color", "autolink", "url", "link", "reflink", # Add color
|
||||
"nolink", "double_emphasis", "emphasis", "code",
|
||||
"linebreak", "strikethrough", "text",
|
||||
]
|
||||
|
||||
|
||||
def output_double_emphasis(self, m):
|
||||
return self.renderer.double_emphasis(self.output(m.group(1)))
|
||||
|
@ -36,6 +60,19 @@ class MarkdownInlineLexer(mistune.InlineLexer):
|
|||
return self.renderer.emphasis(self.output(m.group(1)))
|
||||
|
||||
|
||||
def output_color(self, m):
|
||||
color = m.group(1)
|
||||
text = self.output(m.group(2))
|
||||
return self.renderer.color(color, text)
|
||||
|
||||
|
||||
class MarkdownRenderer(mistune.Renderer):
|
||||
def color(self, color: str, text: str):
|
||||
"""Render given text with a color using `<span data-mx-color=...>`."""
|
||||
|
||||
return f'<span data-mx-color="{color}">{text}</span>'
|
||||
|
||||
|
||||
class HTMLProcessor:
|
||||
"""Provide HTML filtering and conversion from Markdown.
|
||||
|
||||
|
@ -95,7 +132,10 @@ class HTMLProcessor:
|
|||
# hard_wrap: convert all \n to <br> without required two spaces
|
||||
# escape: escape HTML characters in the input string, e.g. tags
|
||||
self._markdown_to_html = mistune.Markdown(
|
||||
hard_wrap=True, escape=True, inline=MarkdownInlineLexer,
|
||||
hard_wrap=True,
|
||||
escape=True,
|
||||
inline=MarkdownInlineLexer,
|
||||
renderer=MarkdownRenderer(),
|
||||
)
|
||||
|
||||
self._markdown_to_html.block.default_rules = [
|
||||
|
|
Loading…
Reference in New Issue
Block a user