From 2c4de0b72da46b0015a3c0aec616e28501852cbc Mon Sep 17 00:00:00 2001 From: Daniel Fichtinger Date: Sat, 21 Jun 2025 23:50:27 -0400 Subject: [PATCH] add link resolution to markdown renderer --- src/zona/builder.py | 6 ++++-- src/zona/markdown.py | 42 ++++++++++++++++++++++++++++++++++++------ 2 files changed, 40 insertions(+), 8 deletions(-) diff --git a/src/zona/builder.py b/src/zona/builder.py index 26a868a..4a64e25 100644 --- a/src/zona/builder.py +++ b/src/zona/builder.py @@ -83,9 +83,11 @@ def discover(root: Path, out_dir: Path) -> list[Item]: def build(root: Path, items: list[Item]): 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 - print(item) + # print(item) # create parent dirs if needed if item.type == ItemType.MARKDOWN: assert item.content is not None diff --git a/src/zona/markdown.py b/src/zona/markdown.py index c16a8c7..e2a8d8d 100644 --- a/src/zona/markdown.py +++ b/src/zona/markdown.py @@ -1,19 +1,42 @@ from typing import Any, override +from pathlib import Path from marko import Markdown from marko.inline import Link, Image from marko.html_renderer import HTMLRenderer +from marko.parser import Parser + +from zona.models import Item 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? @override def render_link(self, element: Link): href = element.dest assert isinstance(href, str) - if href.endswith(".md") and not href.startswith("http"): - href = href[:-3] + ".html" + if self.resolve: + 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) - return f'' + return f'{body}' @override def render_image(self, element: Image): @@ -29,6 +52,13 @@ class ZonaRenderer(HTMLRenderer): ) -def md_to_html(content: str) -> str: - md = Markdown(renderer=ZonaRenderer) - return md.convert(content) +def md_to_html( + content: str, + 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)