Skip to content

Commit a658cc7

Browse files
Merge pull request #3 from ClassicMiniDIY/port-444-template-dir
Add --template-dir CLI option (port of upstream PR wireviz#444)
2 parents c8d9469 + c0f8eee commit a658cc7

4 files changed

Lines changed: 80 additions & 5 deletions

File tree

src/wireviz/Harness.py

Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -678,6 +678,7 @@ def output(
678678
cleanup: bool = True,
679679
output_dir: Optional[Union[str, Path]] = None,
680680
output_name: Optional[str] = None,
681+
template_dir: Optional[Union[str, Path]] = None,
681682
) -> None:
682683
"""Render the harness in the requested formats.
683684
@@ -686,13 +687,34 @@ def output(
686687
``filename`` is None, exactly one format must be requested and
687688
its bytes/text are written to stdout — supports piping the CLI
688689
into other tools.
690+
691+
Args:
692+
filename: Output base path (without extension). ``None``
693+
routes a single format to stdout instead of writing files.
694+
fmt: One or more formats from ``html``, ``png``, ``svg``,
695+
``gv``, ``tsv``, ``csv``, ``pdf``. A bare string is
696+
normalized to a one-tuple.
697+
view: Reserved (unused — kept for API compatibility with the
698+
pre-refactor signature).
699+
cleanup: Reserved (unused — kept for API compatibility).
700+
output_dir: Output directory. Used only to populate the
701+
``<!-- %filename% -->`` HTML template placeholder and to
702+
resolve a custom ``metadata.template.name`` reference.
703+
output_name: Output base name (without extension). Used only
704+
to populate the ``<!-- %filename_stem% -->`` HTML
705+
template placeholder.
706+
template_dir: Explicit directory to search first when
707+
resolving a ``metadata.template.name`` reference. Falls
708+
through to the YAML source directory, then ``output_dir``,
709+
then the built-in templates shipped with WireViz.
689710
"""
690711
if isinstance(fmt, str):
691712
fmt = (fmt,)
692713
outputs: Dict[str, Union[str, bytes]] = self._render(
693714
fmt,
694715
output_dir=output_dir,
695716
output_name=output_name,
717+
template_dir=template_dir,
696718
)
697719

698720
if "csv" in fmt:
@@ -728,12 +750,33 @@ def _render(
728750
fmt: Union[str, Tuple[str, ...], List[str]],
729751
output_dir: Optional[Union[str, Path]] = None,
730752
output_name: Optional[str] = None,
753+
template_dir: Optional[Union[str, Path]] = None,
731754
) -> Dict[str, Union[str, bytes]]:
732755
"""Produce in-memory representations of each requested format.
733756
734757
Pipes graphviz once per binary output rather than via ``render()``
735758
+ temporary files so the caller can write files OR pipe to stdout
736759
without the SVG-file roundtrip the previous implementation used.
760+
761+
Args:
762+
fmt: One or more formats from ``html``, ``png``, ``svg``,
763+
``gv``, ``tsv``. ``csv`` and ``pdf`` are recognized at
764+
the dispatch layer but not produced here. A bare string
765+
is normalized to a one-tuple.
766+
output_dir: Forwarded to ``generate_html_output`` for
767+
``<!-- %filename% -->`` and ``<!-- %diagram_png_b64% -->``
768+
template-placeholder resolution, and as the third-priority
769+
directory in the custom-template search path.
770+
output_name: Forwarded to ``generate_html_output`` for
771+
``<!-- %filename_stem% -->`` resolution.
772+
template_dir: Forwarded to ``generate_html_output`` as the
773+
first-priority directory in the custom-template search
774+
path.
775+
776+
Returns:
777+
``{format: bytes|str}``. Binary formats (``png``) yield
778+
bytes; text formats (``svg``, ``html``, ``gv``, ``tsv``)
779+
yield str.
737780
"""
738781
if isinstance(fmt, str):
739782
fmt = (fmt,)
@@ -788,6 +831,7 @@ def _render(
788831
output_name=output_name,
789832
png_b64=png_b64,
790833
source_path=self.source_path,
834+
template_dir=template_dir,
791835
)
792836

793837
return outputs

src/wireviz/wireviz.py

Lines changed: 19 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,7 @@ def parse(
3232
output_name: Union[None, str] = None,
3333
image_paths: Union[Path, str, List] = [],
3434
source_path: Union[Path, str, None] = None,
35+
template_dir: Union[Path, str, None] = None,
3536
) -> Any:
3637
"""
3738
This function takes an input, parses it as a WireViz Harness file,
@@ -76,6 +77,17 @@ def parse(
7677
Paths to use when resolving any image paths included in the data.
7778
Note: If inp is a path to a YAML file,
7879
its parent directory will automatically be included in the list.
80+
source_path (Path | str, optional):
81+
Path of the originating YAML file when ``inp`` is a string or dict.
82+
Used to: (1) resolve a custom ``metadata.template.name`` reference
83+
against the source's directory, and (2) resolve relative
84+
``<image src=...>`` paths embedded in graphviz output.
85+
When ``inp`` is itself a Path, this is filled in automatically.
86+
template_dir (Path | str, optional):
87+
Explicit first-priority directory to search when resolving a
88+
``metadata.template.name`` reference. Searched before the YAML
89+
source directory and the output directory; the built-in
90+
templates ship as the final fallback.
7991
8092
Returns:
8193
Depending on the return_types parameter, may return:
@@ -421,14 +433,20 @@ def alternate_type(): # flip between connector and cable/arrow
421433
raise ValueError(
422434
"Exactly one output format must be specified when writing to stdout."
423435
)
424-
harness.output(filename=None, fmt=output_formats, view=False)
436+
harness.output(
437+
filename=None,
438+
fmt=output_formats,
439+
view=False,
440+
template_dir=template_dir,
441+
)
425442
else:
426443
harness.output(
427444
filename=output_file,
428445
fmt=output_formats,
429446
view=False,
430447
output_dir=output_dir,
431448
output_name=output_name,
449+
template_dir=template_dir,
432450
)
433451

434452
if return_types:

src/wireviz/wv_cli.py

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -64,14 +64,21 @@
6464
type=str,
6565
help="File name (without extension) to use for output files, if different from input file name.",
6666
)
67+
@click.option(
68+
"-t",
69+
"--template-dir",
70+
default=None,
71+
type=Path,
72+
help="Directory searched first when resolving a metadata.template.name reference.",
73+
)
6774
@click.option(
6875
"-V",
6976
"--version",
7077
is_flag=True,
7178
default=False,
7279
help=f"Output {APP_NAME} version and exit.",
7380
)
74-
def wireviz(file, format, prepend, output_dir, output_name, version):
81+
def wireviz(file, format, prepend, output_dir, output_name, template_dir, version):
7582
"""
7683
Parses the provided FILE and generates the specified outputs.
7784
@@ -165,6 +172,7 @@ def wireviz(file, format, prepend, output_dir, output_name, version):
165172
output_name=_output_name,
166173
image_paths=list(image_paths),
167174
source_path=file,
175+
template_dir=template_dir,
168176
)
169177

170178
sys.stderr.write("\n")

src/wireviz/wv_html.py

Lines changed: 8 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -24,19 +24,24 @@ def generate_html_output(
2424
output_name: Union[str, None] = None,
2525
png_b64: Union[str, None] = None,
2626
source_path: Union[str, Path, None] = None,
27+
template_dir: Union[str, Path, None] = None,
2728
) -> str:
2829
# load HTML template
2930
templatename = metadata.get("template", {}).get("name")
3031
builtin_template_dir = Path(__file__).parent / "templates"
3132
if templatename:
32-
# custom template lookup order: directory of the input YAML
33-
# (source_path), then the output directory, then the built-in
34-
# templates shipped with WireViz.
33+
# custom template lookup order, highest priority first:
34+
# 1. explicit template_dir (CLI -t / parse template_dir)
35+
# 2. YAML source directory (source_path.parent)
36+
# 3. output directory
37+
# 4. built-in templates shipped with WireViz
3538
search_paths = [builtin_template_dir]
3639
if output_dir is not None:
3740
search_paths.insert(0, Path(output_dir))
3841
if source_path is not None:
3942
search_paths.insert(0, Path(source_path).parent)
43+
if template_dir is not None:
44+
search_paths.insert(0, Path(template_dir))
4045
templatefile = smart_file_resolve(
4146
f"{templatename}.html",
4247
search_paths,

0 commit comments

Comments
 (0)