diff --git a/omicron/ssg/output/__init__.py b/omicron/ssg/output/__init__.py index 3acffc8..5c21e28 100644 --- a/omicron/ssg/output/__init__.py +++ b/omicron/ssg/output/__init__.py @@ -1,6 +1,7 @@ from omicron.ssg.output.output import Output from omicron.ssg.output.content import Content, ContentError from omicron.ssg.output.factory import create_content, is_content +from omicron.ssg.output.memory import Memory __all__ = [ "Output", @@ -8,4 +9,5 @@ __all__ = [ "ContentError", "create_content", "is_content", + "Memory", ] diff --git a/omicron/ssg/output/memory.py b/omicron/ssg/output/memory.py new file mode 100644 index 0000000..b43e9ca --- /dev/null +++ b/omicron/ssg/output/memory.py @@ -0,0 +1,22 @@ +import logging +from typing import TYPE_CHECKING +from omicron.ssg.output.output import Output + +log = logging.getLogger(__name__) + +if TYPE_CHECKING: + from omicron.ssg.site import Site +else: + Site = "omicron.ssg.site.Site" + + +class Memory(Output): + def __init__(self, uri: str, content: str): + super().__init__(uri) + self.content = content + + def write(self, site: Site) -> None: + dest = site.output_path / self.uri + dest.parent.mkdir(parents=True, exist_ok=True) + dest.write_text(self.content, encoding="utf-8") + log.debug("Wrote %s", dest) diff --git a/omicron/ssg/site.py b/omicron/ssg/site.py index 1a0e1fd..91b9670 100644 --- a/omicron/ssg/site.py +++ b/omicron/ssg/site.py @@ -4,7 +4,14 @@ from urllib.parse import urlparse from itertools import batched from math import ceil -from omicron.ssg.output import Content, ContentError, is_content, create_content +from omicron.ssg.output import ( + Output, + Content, + ContentError, + is_content, + create_content, + Memory, +) from omicron.ssg.markdown import highlight_style from pathlib import Path @@ -22,8 +29,9 @@ class Site: def __init__(self, site: Path): self.site_path = site.absolute() self.content: list[Content] = [] + self.other_outputs: list[Output] = [] self.by_tag: dict[str, list[Content]] = {} - self.by_uri: dict[str, Content] = {} + self.by_uri: dict[str, Output] = {} self.by_section: dict[str, list[Content]] = {} self.tags_by_count: list[tuple[str, int]] = [] @@ -84,14 +92,12 @@ class Site: self.by_tag[tag] = [] self.by_tag[tag].append(content) - def add_by_uri(self, content: Content) -> None: - if content.uri in self.by_uri: - conflict = self.by_uri[content.uri] + def add_by_uri(self, output: Output) -> None: + if output.uri in self.by_uri: raise ContentError( - f"the file at '{content.source}' maps to the same uri as the " - f"file at '{conflict.source}'" + f"uri '{output.uri}' is already claimed by another output" ) - self.by_uri[content.uri] = content + self.by_uri[output.uri] = output def update_tags_by_count(self) -> None: tags = [(tag, len(items)) for tag, items in self.by_tag.items()] @@ -100,6 +106,9 @@ class Site: def discover(self) -> None: log.info("Discovering content...") + pygments = Memory("pygments.css", highlight_style()) + self.other_outputs.append(pygments) + self.add_by_uri(pygments) content_path = self.site_path / "content" for file in content_path.rglob("*"): if file.is_file() and is_content(file): @@ -184,9 +193,8 @@ class Site: raise ConfigError("base_uri config value must be an absolute path") self.discover() self.output_path.mkdir(parents=True, exist_ok=True) - (self.output_path / "pygments.css").write_text( - highlight_style(), encoding="utf-8" - ) for content in self.content: content.write(self) self.render_indices() + for output in self.other_outputs: + output.write(self)