added syntax highlighting config
This commit is contained in:
parent
c792a6bb07
commit
3bd1eddfac
4 changed files with 58 additions and 15 deletions
|
@ -12,7 +12,9 @@ from rich import print
|
|||
|
||||
class ZonaBuilder:
|
||||
def __init__(
|
||||
self, cli_root: Path | None = None, cli_output: Path | None = None
|
||||
self,
|
||||
cli_root: Path | None = None,
|
||||
cli_output: Path | None = None,
|
||||
):
|
||||
self.layout: Layout = discover_layout(cli_root, cli_output)
|
||||
self.config: ZonaConfig = ZonaConfig.from_file(
|
||||
|
@ -37,7 +39,9 @@ class ZonaBuilder:
|
|||
destination=destination,
|
||||
url=str(destination.relative_to(layout.output)),
|
||||
)
|
||||
if path.name.endswith(".md") and not path.is_relative_to(
|
||||
if path.name.endswith(
|
||||
".md"
|
||||
) and not path.is_relative_to(
|
||||
layout.root / "content" / "static"
|
||||
):
|
||||
item.metadata, item.content = parse_metadata(path)
|
||||
|
@ -52,9 +56,13 @@ class ZonaBuilder:
|
|||
item.copy = False
|
||||
name = destination.stem
|
||||
if name == "index":
|
||||
item.destination = item.destination.with_suffix(".html")
|
||||
item.destination = (
|
||||
item.destination.with_suffix(".html")
|
||||
)
|
||||
else:
|
||||
relative = path.relative_to(base).with_suffix("")
|
||||
relative = path.relative_to(base).with_suffix(
|
||||
""
|
||||
)
|
||||
name = relative.stem
|
||||
item.destination = (
|
||||
layout.output
|
||||
|
@ -62,9 +70,13 @@ class ZonaBuilder:
|
|||
/ name
|
||||
/ "index.html"
|
||||
)
|
||||
rel_url = item.destination.parent.relative_to(layout.output)
|
||||
rel_url = item.destination.parent.relative_to(
|
||||
layout.output
|
||||
)
|
||||
item.url = (
|
||||
"" if rel_url == Path(".") else rel_url.as_posix()
|
||||
""
|
||||
if rel_url == Path(".")
|
||||
else rel_url.as_posix()
|
||||
)
|
||||
items.append(item)
|
||||
# print(item)
|
||||
|
@ -74,13 +86,17 @@ class ZonaBuilder:
|
|||
assert self.items
|
||||
post_list: list[Item] = sorted(
|
||||
[item for item in self.items if item.post],
|
||||
key=lambda item: item.metadata.date if item.metadata else date.min,
|
||||
key=lambda item: item.metadata.date
|
||||
if item.metadata
|
||||
else date.min,
|
||||
reverse=True,
|
||||
)
|
||||
templater = Templater(
|
||||
template_dir=self.layout.templates, post_list=post_list
|
||||
)
|
||||
self.item_map = {item.source.resolve(): item for item in self.items}
|
||||
self.item_map = {
|
||||
item.source.resolve(): item for item in self.items
|
||||
}
|
||||
# print(item_map)
|
||||
for item in self.item_map.values():
|
||||
dst = item.destination
|
||||
|
@ -90,6 +106,7 @@ class ZonaBuilder:
|
|||
assert item.content is not None
|
||||
# parse markdown and render as html
|
||||
raw_html = zmd.md_to_html(
|
||||
config=self.config,
|
||||
content=item.content,
|
||||
resolve_links=True,
|
||||
source=item.source,
|
||||
|
|
|
@ -19,15 +19,24 @@ class BlogConfig:
|
|||
dir: str = "blog"
|
||||
|
||||
|
||||
@dataclass
|
||||
class HighlightingConfig:
|
||||
enabled: bool = True
|
||||
theme: str = "ashen"
|
||||
wrap: bool = False
|
||||
|
||||
|
||||
@dataclass
|
||||
class MarkdownConfig:
|
||||
image_labels: bool = True
|
||||
syntax_highlighting: HighlightingConfig = field(
|
||||
default_factory=HighlightingConfig
|
||||
)
|
||||
|
||||
|
||||
@dataclass
|
||||
class ThemeConfig:
|
||||
name: str = "default"
|
||||
syntax_highlighting: bool = True
|
||||
|
||||
|
||||
@dataclass
|
||||
|
|
|
@ -5,6 +5,7 @@ from marko.inline import Link, Image
|
|||
from marko.block import FencedCode
|
||||
from marko.html_renderer import HTMLRenderer
|
||||
from marko.parser import Parser
|
||||
from zona.config import ZonaConfig
|
||||
from zona.layout import Layout
|
||||
|
||||
from pygments import highlight
|
||||
|
@ -18,6 +19,7 @@ from zona.models import Item
|
|||
class ZonaRenderer(HTMLRenderer):
|
||||
def __init__(
|
||||
self,
|
||||
config: ZonaConfig | None,
|
||||
resolve: bool = False,
|
||||
source: Path | None = None,
|
||||
layout: Layout | None = None,
|
||||
|
@ -33,6 +35,7 @@ class ZonaRenderer(HTMLRenderer):
|
|||
self.source: Path = source.resolve()
|
||||
self.layout: Layout = layout
|
||||
self.item_map: dict[Path, Item] = item_map
|
||||
self.config: ZonaConfig | None = config
|
||||
|
||||
@override
|
||||
def render_link(self, element: Link):
|
||||
|
@ -80,16 +83,23 @@ class ZonaRenderer(HTMLRenderer):
|
|||
|
||||
@override
|
||||
def render_fenced_code(self, element: FencedCode):
|
||||
# code = element.children
|
||||
assert self.config
|
||||
config = self.config.markdown.syntax_highlighting
|
||||
code = "".join(child.children for child in element.children) # type: ignore
|
||||
lang = element.lang or "text"
|
||||
if not config.enabled:
|
||||
return f"<pre><code>{code}</code></pre>"
|
||||
|
||||
try:
|
||||
lexer = get_lexer_by_name(lang, stripall=False)
|
||||
except Exception:
|
||||
lexer = TextLexer(stripall=False) # type: ignore
|
||||
|
||||
formatter = HtmlFormatter(style="ashen", nowrap=True, noclasses=True)
|
||||
formatter = HtmlFormatter(
|
||||
style=config.theme,
|
||||
nowrap=not config.wrap,
|
||||
noclasses=True,
|
||||
)
|
||||
highlighted = highlight(code, lexer, formatter) # type: ignore
|
||||
|
||||
return (
|
||||
|
@ -100,18 +110,25 @@ class ZonaRenderer(HTMLRenderer):
|
|||
|
||||
def md_to_html(
|
||||
content: str,
|
||||
config: ZonaConfig | None,
|
||||
resolve_links: bool = False,
|
||||
source: Path | None = None,
|
||||
layout: Layout | None = None,
|
||||
item_map: dict[Path, Item] | None = None,
|
||||
) -> str:
|
||||
if resolve_links and (source is None or layout is None or item_map is None):
|
||||
if resolve_links and (
|
||||
source is None or layout is None or item_map is None
|
||||
):
|
||||
raise TypeError(
|
||||
"md_to_html() missing source and ctx when resolve_links is true"
|
||||
)
|
||||
parser = Parser()
|
||||
ast = parser.parse(content)
|
||||
renderer = ZonaRenderer(
|
||||
resolve_links, source, layout=layout, item_map=item_map
|
||||
config,
|
||||
resolve_links,
|
||||
source,
|
||||
layout=layout,
|
||||
item_map=item_map,
|
||||
)
|
||||
return renderer.render(ast)
|
||||
|
|
|
@ -9,7 +9,7 @@ def get_header(template_dir: Path) -> str | None:
|
|||
md_header = template_dir / "header.md"
|
||||
html_header = template_dir / "header.html"
|
||||
if md_header.exists():
|
||||
return md_to_html(md_header.read_text())
|
||||
return md_to_html(md_header.read_text(), None)
|
||||
elif html_header.exists():
|
||||
return html_header.read_text()
|
||||
|
||||
|
@ -18,7 +18,7 @@ def get_footer(template_dir: Path) -> str | None:
|
|||
md_footer = template_dir / "footer.md"
|
||||
html_footer = template_dir / "footer.html"
|
||||
if md_footer.exists():
|
||||
return md_to_html(md_footer.read_text())
|
||||
return md_to_html(md_footer.read_text(), None)
|
||||
elif html_footer.exists():
|
||||
return html_footer.read_text()
|
||||
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue