From 727b2b93098eb36523b12891e0b5154ddbb93a95 Mon Sep 17 00:00:00 2001 From: Cassowary Rusnov Date: Mon, 6 Mar 2023 16:22:10 -0800 Subject: [PATCH] General housekeeping update. - Bump version to 0.6.0 - Add template functions to merge dictionaries for loading JSON data inside them - Add extension management separate from MIME type - Make the `tembed` processor which runs a generic jinja template through embedding in the template --- pixywerk2/__init__.py | 2 +- pixywerk2/__main__.py | 10 ++++++---- pixywerk2/defaults/chains.yaml | 9 ++++++++- pixywerk2/processors/jinja2.py | 1 - pixywerk2/processors/jinja2_page_embed.py | 7 +++---- pixywerk2/processors/processors.py | 3 +++ pixywerk2/utils.py | 9 ++++++--- setup.py | 3 +++ 8 files changed, 30 insertions(+), 14 deletions(-) diff --git a/pixywerk2/__init__.py b/pixywerk2/__init__.py index 2b8877c..ef7eb44 100644 --- a/pixywerk2/__init__.py +++ b/pixywerk2/__init__.py @@ -1 +1 @@ -__version__ = '0.5.0' +__version__ = '0.6.0' diff --git a/pixywerk2/__main__.py b/pixywerk2/__main__.py index d63fcbd..bb5d037 100644 --- a/pixywerk2/__main__.py +++ b/pixywerk2/__main__.py @@ -28,6 +28,7 @@ from .template_tools import ( file_raw, time_iso8601, ) +from .utils import deep_merge_dicts logger = logging.getLogger() @@ -97,27 +98,28 @@ def main() -> int: "author": "", "author_email": "", } - for var in args.define: - default_metadata[var[0]] = var[1] + if args.define: + for var in args.define: + default_metadata[var[0]] = var[1] meta_tree = MetaTree(args.root, default_metadata) file_list_cache = cast(Dict, {}) file_cont_cache = cast(Dict, {}) file_name_cache = cast(Dict, {}) file_raw_cache = cast(Dict, {}) - file_json_cache = cast(Dict, {}) flist = file_list(args.root, file_list_cache) default_metadata["globals"] = { "get_file_list": flist, "get_hier": file_list_hier(args.root, flist), "get_file_name": file_name(args.root, meta_tree, process_chains, file_name_cache), "get_file_content": file_content(args.root, meta_tree, process_chains, file_cont_cache), - "get_json": file_json(args.root, file_json_cache), + "get_json": file_json(args.root), "get_raw": file_raw(args.root, file_raw_cache), "get_file_metadata": file_metadata(meta_tree), "get_time_iso8601": time_iso8601("UTC"), "get_date_iso8601": date_iso8601("UTC"), "pygments_get_css": pygments_get_css, "pygments_markup_contents_html": pygments_markup_contents_html, + "merge_dicts": deep_merge_dicts, } for root, _, files in os.walk(args.root, followlinks=args.follow_links): diff --git a/pixywerk2/defaults/chains.yaml b/pixywerk2/defaults/chains.yaml index 18bb72e..459eae0 100644 --- a/pixywerk2/defaults/chains.yaml +++ b/pixywerk2/defaults/chains.yaml @@ -8,7 +8,14 @@ default: templatable: extension: null chain: - - jinja2 + - jinja2 + +# Any object that needs jinja and to be embedded in a parent template +tembed: + extension: null + chain: + - jinja2 + - jinja2_page_embed # Markdown, BBCode and RST are first run through the templater, and then # they are processed into HTML, and finally embedded in a page template. diff --git a/pixywerk2/processors/jinja2.py b/pixywerk2/processors/jinja2.py index 6957306..52535b6 100644 --- a/pixywerk2/processors/jinja2.py +++ b/pixywerk2/processors/jinja2.py @@ -28,5 +28,4 @@ class Jinja2(PassThrough): tmpl = template_env.from_string("".join([x for x in input_file])) return tmpl.render(metadata=ctx) - processor = Jinja2 diff --git a/pixywerk2/processors/jinja2_page_embed.py b/pixywerk2/processors/jinja2_page_embed.py index 4f89b72..3be143c 100644 --- a/pixywerk2/processors/jinja2_page_embed.py +++ b/pixywerk2/processors/jinja2_page_embed.py @@ -24,8 +24,7 @@ class Jinja2PageEmbed(Processor): str: the new name for the file """ - - return os.path.splitext(oldname)[0] + ".html" + return os.path.splitext(oldname)[0] + "." + self.extension(oldname, ctx) def mime_type(self, oldname: str, ctx: Optional[Dict] = None) -> str: """Return the mimetype of the post-processed file. @@ -38,7 +37,7 @@ class Jinja2PageEmbed(Processor): str: the new mimetype of the file after processing """ - return "text/html" + return ctx.get("mime", "text/html") def process(self, input_file: Iterable, ctx: Optional[Dict] = None) -> Iterable: """Return an iterable object of the post-processed file. @@ -69,7 +68,7 @@ class Jinja2PageEmbed(Processor): str: the new extension of the file after processing """ - return "html" + return ctx.get("extension", "html") processor = Jinja2PageEmbed diff --git a/pixywerk2/processors/processors.py b/pixywerk2/processors/processors.py index 552a872..f3312e7 100644 --- a/pixywerk2/processors/processors.py +++ b/pixywerk2/processors/processors.py @@ -64,3 +64,6 @@ class Processor(abc.ABC): # pragma: no cover Returns: iterable: The post-processed output stream """ + + def repr(self) -> str: + return self.__class__.__name__ diff --git a/pixywerk2/utils.py b/pixywerk2/utils.py index 16e8e10..d12c490 100644 --- a/pixywerk2/utils.py +++ b/pixywerk2/utils.py @@ -1,6 +1,7 @@ +from typing import Dict, Optional +import copy import mimetypes import os -from typing import Dict, Optional def merge_dicts(dict_a: Dict, dict_b: Dict) -> Dict: @@ -19,7 +20,7 @@ def merge_dicts(dict_a: Dict, dict_b: Dict) -> Dict: return dict_z -def deep_merge_dicts(dict_a: Dict, dict_b: Dict, _path=None) -> Dict: +def deep_merge_dicts(dict_a: Dict, dict_b: Dict, _path=None, cpy=False) -> Dict: """Merge two dictionaries (deep). https://stackoverflow.com/questions/7204805/how-to-merge-dictionaries-of-dictionaries/7205107#7205107 @@ -32,6 +33,8 @@ def deep_merge_dicts(dict_a: Dict, dict_b: Dict, _path=None) -> Dict: dict: A new merged dictionary. """ + if cpy: + dict_a = copy.deepcopy(dict_a) if _path is None: _path = [] for key in dict_b: @@ -41,7 +44,7 @@ def deep_merge_dicts(dict_a: Dict, dict_b: Dict, _path=None) -> Dict: elif dict_a[key] == dict_b[key]: pass # same leaf value else: - raise Exception('Conflict at %s' % '.'.join(_path + [str(key)])) + dict_a[key] = copy.deepcopy(dict_b[key]) else: dict_a[key] = dict_b[key] return dict_a diff --git a/setup.py b/setup.py index 9e41013..6097c30 100644 --- a/setup.py +++ b/setup.py @@ -1,6 +1,8 @@ """Package configuration.""" from setuptools import find_packages, setup +from pixywerk2 import __version__ + LONG_DESCRIPTION = """Pixywerk 2 is a filesystem based static site generator.""" INSTALL_REQUIRES = ["yaml-1.3", "markdown", "jstyleson", "jinja2", "pygments"] @@ -56,4 +58,5 @@ setup( use_scm_version=True, url="https://git.antpanethon.com/cas/pixywerk2", zip_safe=False, + version=__version__, )