From feb76d25b408af48c03090dfd1b7402ea6651685 Mon Sep 17 00:00:00 2001 From: Maximilian Hils Date: Thu, 18 Jul 2024 21:01:40 +0200 Subject: [PATCH 1/2] add `alerts` extra --- lib/markdown2.py | 36 ++++++++++++++++++++++++++++++++++++ test/tm-cases/alerts.html | 24 ++++++++++++++++++++++++ test/tm-cases/alerts.opts | 1 + test/tm-cases/alerts.text | 15 +++++++++++++++ 4 files changed, 76 insertions(+) create mode 100644 test/tm-cases/alerts.html create mode 100644 test/tm-cases/alerts.opts create mode 100644 test/tm-cases/alerts.text diff --git a/lib/markdown2.py b/lib/markdown2.py index e8add650..00c509bd 100755 --- a/lib/markdown2.py +++ b/lib/markdown2.py @@ -2722,6 +2722,41 @@ def run(self, text): return self.admonitions_re.sub(self.sub, text) +class Alerts(Extra): + ''' + Markdown Alerts as per + https://docs.github.com/en/get-started/writing-on-github/getting-started-with-writing-and-formatting-on-github/basic-writing-and-formatting-syntax#alerts + ''' + + name = 'alerts' + order = (), (Stage.BLOCK_QUOTES, ) + + alert_re = re.compile(r''' +
\s* +

+ \[!(?PNOTE|TIP|IMPORTANT|WARNING|CAUTION)\] + (?P

[ \t]*\n?)? + (?P[\s\S]+?) +
+ ''', re.X + ) + + def test(self, text): + return "
" in text + + def sub(self, match: re.Match) -> str: + typ = match["type"].lower() + heading = f"{match["type"].title()}" + contents = match["contents"].strip() + if match["closing_tag"]: + return f'
\n{heading}\n{contents}\n
' + else: + return f'
\n{heading}\n

{contents}\n

' + + def run(self, text): + return self.alert_re.sub(self.sub, text) + + class _BreaksExtraOpts(TypedDict, total=False): '''Options for the `Breaks` extra''' on_backslash: bool @@ -3490,6 +3525,7 @@ def test(self, text): # Register extras Admonitions.register() +Alerts.register() Breaks.register() CodeFriendly.register() FencedCodeBlocks.register() diff --git a/test/tm-cases/alerts.html b/test/tm-cases/alerts.html new file mode 100644 index 00000000..c5d957b3 --- /dev/null +++ b/test/tm-cases/alerts.html @@ -0,0 +1,24 @@ +
+Note +

Useful information that users should know, even when skimming content.

+
+ +
+Tip +

Helpful advice for doing things better or more easily.

+
+ +
+Important +

Key information users need to know to achieve their goal.

+
+ +
+Warning +

Urgent info that needs immediate user attention to avoid problems.

+
+ +
+Caution +

Advises about risks or negative outcomes of certain actions.

+
diff --git a/test/tm-cases/alerts.opts b/test/tm-cases/alerts.opts new file mode 100644 index 00000000..2913a414 --- /dev/null +++ b/test/tm-cases/alerts.opts @@ -0,0 +1 @@ +{"extras": ["alerts"]} diff --git a/test/tm-cases/alerts.text b/test/tm-cases/alerts.text new file mode 100644 index 00000000..b00ffbdd --- /dev/null +++ b/test/tm-cases/alerts.text @@ -0,0 +1,15 @@ +> [!NOTE] +> Useful information that users should know, even when skimming content. + +> [!TIP] +> Helpful advice for doing things better or more easily. + +> [!IMPORTANT] +> Key information users need to know to achieve their goal. + +> [!WARNING] +> Urgent info that needs immediate user attention to avoid problems. + +> [!CAUTION] +> +> Advises about risks or negative outcomes of certain actions. From cfae0ace5e876cf2aa1df12103af50addc2ee3bf Mon Sep 17 00:00:00 2001 From: Maximilian Hils Date: Wed, 24 Jul 2024 19:55:33 +0200 Subject: [PATCH 2/2] fix compatibility with Python <3.12 --- lib/markdown2.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/markdown2.py b/lib/markdown2.py index 00c509bd..5f20fbbb 100755 --- a/lib/markdown2.py +++ b/lib/markdown2.py @@ -2746,7 +2746,7 @@ def test(self, text): def sub(self, match: re.Match) -> str: typ = match["type"].lower() - heading = f"{match["type"].title()}" + heading = f"{match['type'].title()}" contents = match["contents"].strip() if match["closing_tag"]: return f'
\n{heading}\n{contents}\n
'