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
main
Cassowary Rusnov 2 years ago
parent 357db6eca4
commit 727b2b9309
  1. 2
      pixywerk2/__init__.py
  2. 6
      pixywerk2/__main__.py
  3. 7
      pixywerk2/defaults/chains.yaml
  4. 1
      pixywerk2/processors/jinja2.py
  5. 7
      pixywerk2/processors/jinja2_page_embed.py
  6. 3
      pixywerk2/processors/processors.py
  7. 9
      pixywerk2/utils.py
  8. 3
      setup.py

@ -1 +1 @@
__version__ = '0.5.0' __version__ = '0.6.0'

@ -28,6 +28,7 @@ from .template_tools import (
file_raw, file_raw,
time_iso8601, time_iso8601,
) )
from .utils import deep_merge_dicts
logger = logging.getLogger() logger = logging.getLogger()
@ -97,6 +98,7 @@ def main() -> int:
"author": "", "author": "",
"author_email": "", "author_email": "",
} }
if args.define:
for var in args.define: for var in args.define:
default_metadata[var[0]] = var[1] default_metadata[var[0]] = var[1]
meta_tree = MetaTree(args.root, default_metadata) meta_tree = MetaTree(args.root, default_metadata)
@ -104,20 +106,20 @@ def main() -> int:
file_cont_cache = cast(Dict, {}) file_cont_cache = cast(Dict, {})
file_name_cache = cast(Dict, {}) file_name_cache = cast(Dict, {})
file_raw_cache = cast(Dict, {}) file_raw_cache = cast(Dict, {})
file_json_cache = cast(Dict, {})
flist = file_list(args.root, file_list_cache) flist = file_list(args.root, file_list_cache)
default_metadata["globals"] = { default_metadata["globals"] = {
"get_file_list": flist, "get_file_list": flist,
"get_hier": file_list_hier(args.root, 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_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_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_raw": file_raw(args.root, file_raw_cache),
"get_file_metadata": file_metadata(meta_tree), "get_file_metadata": file_metadata(meta_tree),
"get_time_iso8601": time_iso8601("UTC"), "get_time_iso8601": time_iso8601("UTC"),
"get_date_iso8601": date_iso8601("UTC"), "get_date_iso8601": date_iso8601("UTC"),
"pygments_get_css": pygments_get_css, "pygments_get_css": pygments_get_css,
"pygments_markup_contents_html": pygments_markup_contents_html, "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): for root, _, files in os.walk(args.root, followlinks=args.follow_links):

@ -10,6 +10,13 @@ templatable:
chain: 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 # Markdown, BBCode and RST are first run through the templater, and then
# they are processed into HTML, and finally embedded in a page template. # they are processed into HTML, and finally embedded in a page template.
markdown: markdown:

@ -28,5 +28,4 @@ class Jinja2(PassThrough):
tmpl = template_env.from_string("".join([x for x in input_file])) tmpl = template_env.from_string("".join([x for x in input_file]))
return tmpl.render(metadata=ctx) return tmpl.render(metadata=ctx)
processor = Jinja2 processor = Jinja2

@ -24,8 +24,7 @@ class Jinja2PageEmbed(Processor):
str: the new name for the file str: the new name for the file
""" """
return os.path.splitext(oldname)[0] + "." + self.extension(oldname, ctx)
return os.path.splitext(oldname)[0] + ".html"
def mime_type(self, oldname: str, ctx: Optional[Dict] = None) -> str: def mime_type(self, oldname: str, ctx: Optional[Dict] = None) -> str:
"""Return the mimetype of the post-processed file. """Return the mimetype of the post-processed file.
@ -38,7 +37,7 @@ class Jinja2PageEmbed(Processor):
str: the new mimetype of the file after processing 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: def process(self, input_file: Iterable, ctx: Optional[Dict] = None) -> Iterable:
"""Return an iterable object of the post-processed file. """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 str: the new extension of the file after processing
""" """
return "html" return ctx.get("extension", "html")
processor = Jinja2PageEmbed processor = Jinja2PageEmbed

@ -64,3 +64,6 @@ class Processor(abc.ABC): # pragma: no cover
Returns: Returns:
iterable: The post-processed output stream iterable: The post-processed output stream
""" """
def repr(self) -> str:
return self.__class__.__name__

@ -1,6 +1,7 @@
from typing import Dict, Optional
import copy
import mimetypes import mimetypes
import os import os
from typing import Dict, Optional
def merge_dicts(dict_a: Dict, dict_b: Dict) -> Dict: 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 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). """Merge two dictionaries (deep).
https://stackoverflow.com/questions/7204805/how-to-merge-dictionaries-of-dictionaries/7205107#7205107 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. dict: A new merged dictionary.
""" """
if cpy:
dict_a = copy.deepcopy(dict_a)
if _path is None: if _path is None:
_path = [] _path = []
for key in dict_b: 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]: elif dict_a[key] == dict_b[key]:
pass # same leaf value pass # same leaf value
else: else:
raise Exception('Conflict at %s' % '.'.join(_path + [str(key)])) dict_a[key] = copy.deepcopy(dict_b[key])
else: else:
dict_a[key] = dict_b[key] dict_a[key] = dict_b[key]
return dict_a return dict_a

@ -1,6 +1,8 @@
"""Package configuration.""" """Package configuration."""
from setuptools import find_packages, setup from setuptools import find_packages, setup
from pixywerk2 import __version__
LONG_DESCRIPTION = """Pixywerk 2 is a filesystem based static site generator.""" LONG_DESCRIPTION = """Pixywerk 2 is a filesystem based static site generator."""
INSTALL_REQUIRES = ["yaml-1.3", "markdown", "jstyleson", "jinja2", "pygments"] INSTALL_REQUIRES = ["yaml-1.3", "markdown", "jstyleson", "jinja2", "pygments"]
@ -56,4 +58,5 @@ setup(
use_scm_version=True, use_scm_version=True,
url="https://git.antpanethon.com/cas/pixywerk2", url="https://git.antpanethon.com/cas/pixywerk2",
zip_safe=False, zip_safe=False,
version=__version__,
) )