Source code for lookatme.templating

"""
This module provides basic templating functionality
"""


import json
import os
import re
from typing import Dict


import lookatme.utils.colors as colors


[docs]def get_template_data(template_path: str) -> str: """Return the template data or raise an error.""" if not os.path.exists(template_path) and os.path.isfile(template_path): raise ValueError("Template {!r} doesn't exist".format(template_path)) with open(template_path, "r") as f: template_data = f.read() return template_data
[docs]def render(template_name: str, context: Dict[str, str]) -> str: """Render the indicated template name using the provided context to resolve variables. An error will be thrown if variables are not resolved. """ template_data = get_template_data(template_name) filters = "|".join(get_filters().keys()) regex = r"\{\{([a-zA-Z0-9_\.]+)(?:\|(" + filters + r"))?\}\}" vars_to_replace = set(re.findall(regex, template_data)) undefined_vars = set(r[0] for r in vars_to_replace) - set(context.keys()) if undefined_vars: raise ValueError("Undefined template variables: {!r}".format(undefined_vars)) filters = { "json": json_filter, "css": css_filter, "highlight": highlight_filter, } for var, var_filter in vars_to_replace: replace_val = context[var] if var_filter == "": replace_text = var replace_val = str(replace_val) else: filter_fn = filters.get(var_filter) if filter_fn is None: raise ValueError("Unsupported filter: {!r}".format(var_filter)) replace_text = var + "|" + var_filter replace_val = filter_fn(replace_val) template_data = template_data.replace("{{" + replace_text + "}}", replace_val) return template_data
_FILTERS = {}
[docs]def get_filters() -> Dict: global _FILTERS if not _FILTERS: _FILTERS = { "json": json_filter, "css": css_filter, "highlight": highlight_filter, } return _FILTERS
[docs]def json_filter(value) -> str: return json.dumps(value)
[docs]def css_filter(value: str) -> str: styles = {} parts = [x.strip() for x in value.split(",")] for part in parts: if part.startswith("#"): styles["color"] = part elif part == "underline": styles["text-decoration"] = comma_append( styles.get("text-decoration", ""), "underline" ) elif part == "italic": styles["font-style"] = "italic" elif part == "strikethrough": styles["text-decoration"] = comma_append( styles.get("text-decoration", ""), "line-through" ) elif part == "bold": styles["font-weight"] = "bold" res = [] for style, style_val in styles.items(): res.append(f"{style}: {style_val};") return " ".join(res)
[docs]def highlight_filter(value: str) -> str: return colors.get_highlight_color(value, 0.2)
[docs]def comma_append(val, new_val): if val: return new_val else: return val + "," + new_val