Coverage for webapp/markdown.py: 100%
23 statements
« prev ^ index » next coverage.py v7.8.0, created at 2025-04-28 22:05 +0000
« prev ^ index » next coverage.py v7.8.0, created at 2025-04-28 22:05 +0000
1import re
2import html
4from mistune import HTMLRenderer, Markdown
5from mistune.block_parser import (
6 BlockParser,
7 expand_leading_tab,
8)
9from mistune.inline_parser import InlineParser
10from mistune.plugins.extra import plugin_strikethrough, plugin_url
12# All the overrides were discussed here:
13# https://forum.snapcraft.io/t/use-of-markdown-in-snap-metadata-summary-description/2128
15_INDENT_CODE_TRIM = re.compile(r"^ {1,3}", flags=re.M)
18class SnapcraftBlockParser(BlockParser):
19 # Indent code is 3 spaces instead of 4
20 INDENT_CODE = re.compile(r"(?:\n*)(?:(?: {3}| *\t)[^\n]+\n*)+")
22 # We removed many block rules
23 RULE_NAMES = (
24 "newline",
25 "thematic_break",
26 "indent_code",
27 "list_start",
28 )
30 def parse_indent_code(self, m, state):
31 text = expand_leading_tab(m.group(0))
32 code = _INDENT_CODE_TRIM.sub("", text)
33 code = code.lstrip("\n")
34 return self.tokenize_block_code(code, None, state)
37class SnapcraftInlineParser(InlineParser):
38 CODESPAN = r"(`)([ \S]*?[^`])\1(?!`)"
40 # We removed many inline rules
41 RULE_NAMES = (
42 "escape",
43 "auto_link",
44 "ref_link", # Kept so we don't have to override more code but not used
45 "ref_link2", # Same as above
46 "asterisk_emphasis",
47 "underscore_emphasis",
48 "codespan",
49 "linebreak",
50 )
53renderer = HTMLRenderer()
54parser = Markdown(
55 renderer=renderer,
56 block=SnapcraftBlockParser(),
57 inline=SnapcraftInlineParser(renderer),
58 plugins=[plugin_strikethrough, plugin_url],
59)
62def parse_markdown_description(content):
63 unescaped_content = html.unescape(content)
64 return parser(unescaped_content)