nix-community.nixvim/docs/gfm-alerts-to-admonitions/gfm_alerts_to_admonitions/main.py
2024-09-13 12:59:27 +01:00

55 lines
1.9 KiB
Python

import re
from re import Match
from markdown_it import MarkdownIt
from markdown_it.rules_core import StateCore
from markdown_it.token import Token
_ALERT_PATTERN = re.compile(
r"^\[\!(TIP|NOTE|IMPORTANT|WARNING|CAUTION)\]\s*", re.IGNORECASE
)
def gfm_alert_to_admonition(md: MarkdownIt):
def gfm_alert_to_adm(state: StateCore):
# Scan all tokens, looking for blockquotes,
# convert any alert-style blockquotes to admonition tokens
tokens: list[Token] = state.tokens
for i, token in enumerate(tokens):
if token.type == "blockquote_open":
# Store the blockquote's opening token
open = tokens[i]
start_index = i
# Find the blockquote's closing token
while tokens[i].type != "blockquote_close" and i < len(tokens):
i += 1
close = tokens[i]
end_index = i
# Find the first `inline` token in the blockquote
first_content = next(
(
t
for t in tokens[start_index : end_index + 1]
if t.type == "inline"
),
None,
)
if first_content is None:
continue
# Check if the blockquote is actually an alert
m: Match = _ALERT_PATTERN.match(first_content.content)
if m is None:
continue
# Remove ' [!TIP]' from the token's content
first_content.content = first_content.content[m.end(0) :]
# Convert the opening & closing tokens from "blockquote" to "admonition"
open.type = "admonition_open"
open.meta["kind"] = m.group(1).lower()
close.type = "admonition_close"
md.core.ruler.after("block", "github-alerts", gfm_alert_to_adm)