/
render-template.py
executable file
·78 lines (58 loc) · 1.83 KB
/
render-template.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
#! /usr/bin/env -S pipx run
# /// script
# dependencies = [
# "click==8.*",
# "Jinja2==3.*",
# "tomli==2.*",
# ]
# requires-python = ">=3.8"
# ///
from __future__ import annotations
from dataclasses import dataclass, field
from itertools import starmap
from pathlib import Path
from typing import Any, Iterator
import click
import jinja2 as j2
import tomli
@dataclass
class Project:
name: str
url: str
tags: list[str]
descr: str = ""
props: dict[str, str] = field(default_factory=dict)
@classmethod
def from_dict(cls, name: str, d: dict[str, Any]):
return cls(name=name, **d)
def list_item(proj: Project) -> str:
item = [f"- [{proj.name}]({proj.url})"]
if proj.descr:
item.append(f" **—** {proj.descr}")
if proj.props:
item.extend(
f"\n - **{prop}:** {value}" for prop, value in proj.props.items()
)
return "".join(item)
@click.command()
@click.argument("template-name", type=click.Path(exists=True, path_type=Path))
@click.argument("data-path", type=click.Path(exists=True, path_type=Path))
def main(template_name: Path, data_path: Path) -> None:
data = tomli.loads(data_path.read_text())
projects = list(starmap(Project.from_dict, data.items()))
def proj_data(tag: str) -> Iterator[Project]:
return (proj for proj in projects if tag in proj.tags)
def projs_with_tag(tag: str) -> str:
return "\n".join(list_item(proj) for proj in proj_data(tag))
env = j2.Environment(
loader=j2.FileSystemLoader("."),
autoescape=j2.select_autoescape(),
trim_blocks=True,
lstrip_blocks=True,
)
env.globals["projs_with_tag"] = projs_with_tag
template = env.get_template(str(template_name))
rendered = template.render(data)
click.echo(rendered)
if __name__ == "__main__":
main()