Extending Mistune 3 to parse inline wikilinks.
Mistune 3 has changed it's internal structure and extension mechanisms.
The mistune advanced documentation has some examples how to create and register inline patterns. After some iterations I came up with the following solution to render wiki links:
import re
from typing import TYPE_CHECKING, Match
if TYPE_CHECKING:
from mistune import Markdown
from mistune.core import BaseRenderer, InlineState
from mistune.inline_parser import InlineParser
def parse_wikilink(inline: "InlineParser", m: Match[str], state: "InlineState") -> int:
"""Parse wikilink syntax [[page title]] or [[page title|display text]]"""
page_title = m.group('page').strip()
display_text = m.group('display')
# Use display text if provided, otherwise use page title
if display_text is not None:
text = display_text.strip()
else:
text = page_title
# Create a wikilink token
state.append_token({
"type": "wikilink",
"children": [{"type": "text", "raw": text}],
"attrs": {
"page": page_title,
"display": text
}
})
return m.end()
def render_wikilink_html(renderer: "BaseRenderer", children: str, page: str, display: str) -> str:
"""Render wikilink as HTML anchor tag"""
url_page = page.replace(' ', '_')
return f'<a href="/wiki/{url_page}" class="wikilink">{children}</a>'
def wikilink_plugin(md: "Markdown") -> None:
"""Plugin function to add wikilink support to mistune"""
# Use named groups
WIKILINK_PATTERN = r'\[\[(?P<page>[^|\]]+)(?:\|(?P<display>[^\]]+))?\]\]'
md.inline.register("wikilink", WIKILINK_PATTERN, parse_wikilink, before="link")
if md.renderer and md.renderer.NAME == "html":
md.renderer.register("wikilink", render_wikilink_html)
# Usage example
if __name__ == "__main__":
from mistune import create_markdown
# Create markdown parser with the wikilink plugin
md = create_markdown(plugins=[wikilink_plugin])
# Test examples
text1 = "Check out [[Main Page]] for more info."
text2 = "Visit [[Installation Guide|the installation guide]] to get started."
text3 = "Multiple links: [[Page One]] and [[Page Two|Custom Text]]."
print("Example 1:")
print(md(text1))
# Output: <p>Check out <a href="/wiki/Main_Page" class="wikilink">Main Page</a> for more info.</p>
print("\nExample 2:")
print(md(text2))
# Output: <p>Visit <a href="/wiki/Installation_Guide" class="wikilink">the installation guide</a> to get started.</p>
print("\nExample 3:")
print(md(text3))
# Output: <p>Multiple links: <a href="/wiki/Page_One" class="wikilink">Page One</a> and <a href="/wiki/Page_Two" class="wikilink">Custom Text</a>.</p>