Skip to content

Commit 2cb36c2

Browse files
authored
Merge pull request #618 from EnergySystemsModellingLab/jinja
Change input format doc script to use jinja templates
2 parents c8b2743 + bc6bf7e commit 2cb36c2

5 files changed

Lines changed: 90 additions & 36 deletions

File tree

.pre-commit-config.yaml

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,14 @@ repos:
2626
rev: v1.0
2727
hooks:
2828
- id: clippy
29+
- repo: https://github.com/astral-sh/ruff-pre-commit
30+
rev: v0.11.6
31+
hooks:
32+
- id: ruff
33+
types_or: [python]
34+
args: [--fix]
35+
- id: ruff-format
36+
types_or: [python]
2937
- repo: https://github.com/codespell-project/codespell
3038
rev: v2.2.6
3139
hooks:

.vscode/extensions.json

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44
"vadimcn.vscode-lldb",
55
"editorconfig.editorconfig",
66
"esbenp.prettier-vscode",
7-
"davidanson.vscode-markdownlint"
7+
"davidanson.vscode-markdownlint",
8+
"samuelcolvin.jinjahtml"
89
]
910
}

doc-requirements.txt

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1 +1,3 @@
1+
pyyaml
12
table2md
3+
jinja2

docs/generate_input_format_doc.py

Lines changed: 43 additions & 35 deletions
Original file line numberDiff line numberDiff line change
@@ -2,9 +2,12 @@
22
#
33
# A script to generate markdown documentation from table schemas.
44

5+
from typing import Iterable
56
from table2md import MarkdownTable
67
import yaml
78
from pathlib import Path
9+
from dataclasses import dataclass
10+
from jinja2 import Environment, FileSystemLoader
811

912
_DOCS_DIR = Path(__file__).parent
1013
_SCHEMA_DIR = _DOCS_DIR.parent / "schemas" / "input"
@@ -18,52 +21,57 @@
1821
}
1922

2023

24+
@dataclass
25+
class Notes:
26+
description: str | None
27+
table: str | None
28+
29+
30+
@dataclass
31+
class File:
32+
name: str
33+
description: str
34+
table: str
35+
notes: Notes | None
36+
37+
38+
@dataclass
39+
class Section:
40+
title: str
41+
files: Iterable[File]
42+
43+
2144
def generate_markdown() -> str:
22-
out = (
23-
"# Input file format\n"
24-
f"<!-- Automatically generated by {Path(__file__).name}. Do not edit manually. -->\n"
25-
"<!-- markdownlint-disable MD013 -->\n"
26-
"<!-- markdownlint-disable MD033 -->\n"
27-
)
45+
"""Generate markdown from Jinja template using metadata in schemas."""
46+
env = Environment(loader=FileSystemLoader(_DOCS_DIR))
47+
template = env.get_template("input_format.md.jinja")
48+
return template.render(script_name=Path(__file__).name, sections=load_sections())
2849

29-
for title, patterns in _FILE_ORDER.items():
30-
out += f"\n## {title}\n"
3150

51+
def load_sections() -> Iterable[Section]:
52+
for title, patterns in _FILE_ORDER.items():
3253
for pattern in patterns:
3354
paths = map(str, _SCHEMA_DIR.glob(f"{pattern}.yaml"))
34-
for path in map(Path, sorted(paths)):
35-
out += process_file(path)
36-
37-
return out
55+
files = (load_file(Path(path)) for path in sorted(paths))
56+
yield Section(title, files)
3857

3958

40-
def process_file(path: Path) -> str:
41-
out = f"\n### `{path.stem}.csv`\n\n"
59+
def load_file(path: Path) -> File:
4260
with path.open() as f:
4361
data = yaml.safe_load(f)
4462

45-
out += f"{add_full_stop(data['title'])}\n\n"
46-
4763
try:
48-
table_str, notes_str = fields2table(data["fields"])
49-
out += table_str
64+
table, notes_table = fields2table(data["fields"])
5065
except KeyError:
5166
print(f"MISSING VALUE IN {path}")
5267
raise
5368

54-
desc = data.get("description", "")
55-
if not desc and not notes_str:
56-
return out
57-
58-
out += "\n#### Notes\n\n"
59-
60-
if desc:
61-
out += f"{add_full_stop(desc)}\n\n"
62-
63-
if notes_str:
64-
out += notes_str
65-
66-
return out
69+
name = f"{path.stem}.csv"
70+
title = add_full_stop(data["title"])
71+
if desc := data.get("description", None):
72+
desc = add_full_stop(desc)
73+
notes = Notes(desc, notes_table) if desc or notes_table else None
74+
return File(name, title, table, notes)
6775

6876

6977
def add_full_stop(s: str) -> str:
@@ -74,7 +82,7 @@ def add_full_stop(s: str) -> str:
7482
return f"{s}."
7583

7684

77-
def fields2table(fields: list[dict[str, str]]) -> tuple[str, str]:
85+
def fields2table(fields: list[dict[str, str]]) -> tuple[str, str | None]:
7886
data = []
7987
notes = []
8088
for f in fields:
@@ -95,9 +103,9 @@ def fields2table(fields: list[dict[str, str]]) -> tuple[str, str]:
95103
for f in fields
96104
]
97105

98-
table_str = str(MarkdownTable.from_dicts(data))
99-
notes_str = str(MarkdownTable.from_dicts(notes)) if notes else ""
100-
return table_str, notes_str
106+
table = str(MarkdownTable.from_dicts(data))
107+
notes_table = str(MarkdownTable.from_dicts(notes)) if notes else None
108+
return table, notes_table
101109

102110

103111
if __name__ == "__main__":

docs/input_format.md.jinja

Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
1+
# Input file format
2+
3+
<!-- Automatically generated by {{ script_name }}. Do not edit manually. -->
4+
<!-- markdownlint-disable MD013 -->
5+
<!-- markdownlint-disable MD024 -->
6+
<!-- markdownlint-disable MD033 -->
7+
8+
This file contains information about the input file format for MUSE 2.0.
9+
10+
{# "Sections" are broad categories representing multiple files (e.g. "commodities") -#}
11+
{% for section in sections -%}
12+
## {{ section.title }}
13+
14+
{# Documentation for individual CSV files -#}
15+
{% for file in section.files -%}
16+
### `{{ file.name }}`
17+
18+
{# Short description of file -#}
19+
{{ file.description }}
20+
21+
{# Table of fields with a short description -#}
22+
{{ file.table }}
23+
24+
{#- Optional notes section. This can include a longer description of the file, including validation
25+
checks that are performed, as well as a table containing extra information about CSV fields
26+
(such as a requirement that the value is >=0 etc.). -#}
27+
{%- if file.notes %}
28+
#### Notes
29+
{% if file.notes.description %}
30+
{{ file.notes.description }}{% endif %}
31+
{% if file.notes.table %}
32+
{{ file.notes.table }}{% endif -%}
33+
{%- endif %}
34+
{% endfor -%}
35+
{% endfor %}

0 commit comments

Comments
 (0)