From e3cfdab3ea4f6de79e69785e1dfb6b74ec9c58d0 Mon Sep 17 00:00:00 2001 From: Giovanni Barillari Date: Sun, 18 Dec 2022 23:59:04 +0100 Subject: [PATCH] Add delimiters option --- README.md | 5 +++-- noir/cli.py | 37 +++++++++++++++++++++++++------------ noir/templating.py | 12 ++++++++++-- tests/test_render.py | 4 +++- 4 files changed, 41 insertions(+), 17 deletions(-) diff --git a/README.md b/README.md index 3fa4fc6..bb8dcc1 100644 --- a/README.md +++ b/README.md @@ -26,13 +26,14 @@ Arguments: SOURCE The template file to use. [required] Options: - -c, --context PATH Context file(s) to use. -e, --eval Parse source as template string. + -v, --var TEXT Context variable(s) to apply. + -c, --context PATH Context file(s) to use. -f, --format [env|ini|json|toml|yaml|yml] Context file format (default: guess from file extension). -o, --output FILENAME Target output (default: stdout) - -v, --var PATH Context variable(s) to apply. + --delimiters TEXT Template delimiters [default: {{,}}] --version Show the version and exit. --install-completion [bash|zsh|fish|powershell|pwsh] Install completion for the specified shell. diff --git a/noir/cli.py b/noir/cli.py index 4bd8417..f6c11b8 100644 --- a/noir/cli.py +++ b/noir/cli.py @@ -6,7 +6,7 @@ from .__version__ import __version__ from ._patch import typer from .ctx import ContextExt, load_context_file -from .templating import templater +from .templating import templater as _build_templater from .types import ContextFilePath, ContextVar, Source from .utils import obj_to_adict @@ -52,18 +52,24 @@ def main( ..., help="The template file to use." ), - context: List[ContextFilePath] = typer.Option( - [], - "--context", - "-c", - help="Context file(s) to use." - ), eval: bool = typer.Option( False, "--eval", "-e", help="Parse source as template string." ), + var: List[ContextVar] = typer.Option( + [], + "--var", + "-v", + help="Context variable(s) to apply." + ), + context: List[ContextFilePath] = typer.Option( + [], + "--context", + "-c", + help="Context file(s) to use." + ), format: Optional[ContextExt] = typer.Option( None, "--format", @@ -77,11 +83,10 @@ def main( show_default=False, help="Target output (default: stdout)" ), - var: List[ContextVar] = typer.Option( - [], - "--var", - "-v", - help="Context variable(s) to apply." + delimiters: str = typer.Option( + "{{,}}", + "--delimiters", + help="Template delimiters" ), _: Optional[bool] = typer.Option( None, "--version", callback=version_callback, is_eager=True, @@ -94,6 +99,12 @@ def main( if not source.is_path and not eval: error(f"Invalid value for 'SOURCE': Path '{source.data}' does not exist.") + try: + delimiters_items = tuple(delimiters.split(",")) + assert len(delimiters_items) == 2 + except Exception: + error(f"Invalid value for delimiters: '{delimiters}'") + stream_reader = lambda: typer.get_text_stream("stdin") tctx = {} for ctx_path in context: @@ -112,6 +123,8 @@ def main( rctx[ns] = rctx.get(ns) or {} rctx = rctx[ns] rctx[var_param.key] = var_param.val + + templater = _build_templater(delimiters_items) try: rendered = ( templater.render(source.data, obj_to_adict(tctx)) if not eval else diff --git a/noir/templating.py b/noir/templating.py index af278ed..def4d08 100644 --- a/noir/templating.py +++ b/noir/templating.py @@ -5,7 +5,7 @@ import os import random -from typing import Any, Dict, Optional +from typing import Any, Dict, Optional, Tuple import tomli_w import yaml @@ -30,6 +30,15 @@ class Templater(Renoir): _writers = {**Renoir._writers, **{ESCAPES.common: Writer}} +def templater(delimiters: Tuple[str, str]): + return Templater( + mode=MODES.plain, + delimiters=delimiters, + adjust_indent=True, + contexts=[base_ctx] + ) + + def _indent(text: str, spaces: int = 2) -> str: offset = " " * spaces rv = f"\n{offset}".join(text.split("\n")) @@ -63,4 +72,3 @@ def base_ctx(ctx: Dict[str, Any]): yaml.add_representer(adict, yaml.representer.Representer.represent_dict) -templater = Templater(mode=MODES.plain, adjust_indent=True, contexts=[base_ctx]) diff --git a/tests/test_render.py b/tests/test_render.py index b561cc8..6022d13 100644 --- a/tests/test_render.py +++ b/tests/test_render.py @@ -1,7 +1,9 @@ import json import os -from noir.templating import templater +from noir.templating import templater as _build_templater + +templater = _build_templater(('{{', '}}')) def test_env():