add link resolution to markdown renderer

This commit is contained in:
Daniel Fichtinger 2025-06-21 23:50:27 -04:00
parent 070c23720b
commit 2c4de0b72d
2 changed files with 40 additions and 8 deletions

View file

@ -83,9 +83,11 @@ def discover(root: Path, out_dir: Path) -> list[Item]:
def build(root: Path, items: list[Item]): def build(root: Path, items: list[Item]):
templater = Templater(root / "templates") templater = Templater(root / "templates")
for item in items: item_map = {item.source.resolve(): item for item in items}
# print(item_map)
for item in item_map.values():
dst = item.destination dst = item.destination
print(item) # print(item)
# create parent dirs if needed # create parent dirs if needed
if item.type == ItemType.MARKDOWN: if item.type == ItemType.MARKDOWN:
assert item.content is not None assert item.content is not None

View file

@ -1,19 +1,42 @@
from typing import Any, override from typing import Any, override
from pathlib import Path
from marko import Markdown from marko import Markdown
from marko.inline import Link, Image from marko.inline import Link, Image
from marko.html_renderer import HTMLRenderer from marko.html_renderer import HTMLRenderer
from marko.parser import Parser
from zona.models import Item
class ZonaRenderer(HTMLRenderer): class ZonaRenderer(HTMLRenderer):
def __init__(
self,
resolve: bool = False,
source: Path | None = None,
item_map: dict[Path, Item] | None = None,
):
super().__init__()
self.resolve: bool = resolve
if self.resolve:
assert source is not None
assert item_map is not None
self.source: Path = source.resolve()
self.map: dict[Path, Item] = item_map
# TODO: resolve relative links and replace with url? # TODO: resolve relative links and replace with url?
@override @override
def render_link(self, element: Link): def render_link(self, element: Link):
href = element.dest href = element.dest
assert isinstance(href, str) assert isinstance(href, str)
if href.endswith(".md") and not href.startswith("http"): if self.resolve:
href = href[:-3] + ".html" cur = Path(href)
# TODO: fix relative path issue
if not href.startswith(("http", "https")) and cur.is_relative_to(
self.source
):
href = self.map[self.source].url
body: Any = self.render_children(element) body: Any = self.render_children(element)
return f'<a href="{href}" target="_blank"{body}</a>' return f'<a href="{href}" target="_blank">{body}</a>'
@override @override
def render_image(self, element: Image): def render_image(self, element: Image):
@ -29,6 +52,13 @@ class ZonaRenderer(HTMLRenderer):
) )
def md_to_html(content: str) -> str: def md_to_html(
md = Markdown(renderer=ZonaRenderer) content: str,
return md.convert(content) resolve_links: bool = False,
source: Path | None = None,
item_map: dict[Path, Item] | None = None,
) -> str:
parser = Parser()
ast = parser.parse(content)
renderer = ZonaRenderer(resolve_links, source, item_map)
return renderer.render(ast)