blob: df4b35ec7cdf779e79836a7f8b5c08bc49df7e3a [file]
#
# Licensed to the Apache Software Foundation (ASF) under one or more
# contributor license agreements. See the NOTICE file distributed with
# this work for additional information regarding copyright ownership.
# The ASF licenses this file to You under the Apache License, Version 2.0
# (the "License"); you may not use this file except in compliance with
# the License. You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
#
"""Render human-readable docs from the JSON Schema.
This is a starting skeleton. It currently generates a single Markdown
field-reference table per published schema version, from
`schema/<version>/sourcelume.schema.json`. It does not yet render SHACL
shapes, cross-link to the prose spec, or produce HTML output — see
SETUP.md for the intended scope.
Usage:
uv run python tools/render-docs.py
Output is written to `spec/<version>/generated-field-reference.md` for
each published schema version. Generated files are not intended to be
committed until the project decides how generated output should be
handled (see the "Notes for contributors" section of SETUP.md).
Note: gitIgnores spec/*/generated-field-reference.md entry exists.
"""
from __future__ import annotations
import json
import sys
from pathlib import Path
REPO_ROOT = Path(__file__).resolve().parent.parent
SCHEMA_DIR = REPO_ROOT / "schema"
SPEC_DIR = REPO_ROOT / "spec"
# Find published schema version directories that should have docs generated.
def find_version_dirs(base: Path) -> list[Path]:
"""Return published version directories under `base` (e.g. schema/0.0.1)."""
if not base.is_dir():
return []
return sorted(
p for p in base.iterdir()
if p.is_dir() and not p.is_symlink() and p.name[0].isdigit()
)
# Build a Markdown field-reference table from a JSON Schema dictionary.
def render_field_table(schema: dict) -> str:
properties = schema.get("properties", {})
required = set(schema.get("required", []))
lines = [
f"# {schema.get('title', 'Schema Reference')}",
"",
"> Generated from the JSON Schema. Do not edit by hand — edit the",
"> schema and re-run `tools/render-docs.py` instead.",
"",
"| Field | Type | Required | Description |",
"|-------|------|----------|-------------|",
]
for field_name, field_def in properties.items():
field_type = field_def.get("type", field_def.get("format", "—"))
is_required = "Yes" if field_name in required else "No"
description = field_def.get("description", "").replace("\n", " ")
lines.append(f"| `{field_name}` | {field_type} | {is_required} | {description} |")
return "\n".join(lines) + "\n"
# Render generated documentation for one schema version and return the output path.
def render_version(version_dir: Path) -> Path | None:
schema_files = list(version_dir.glob("*.schema.json"))
if not schema_files:
return None
schema = json.loads(schema_files[0].read_text())
doc = render_field_table(schema)
output_dir = SPEC_DIR / version_dir.name
output_dir.mkdir(parents=True, exist_ok=True)
output_path = output_dir / "generated-field-reference.md"
output_path.write_text(doc)
return output_path
# Generate documentation for all available schema versions and return an exit code.
def main() -> int:
version_dirs = find_version_dirs(SCHEMA_DIR)
if not version_dirs:
print("No schema versions found under schema/.")
return 0
for version_dir in version_dirs:
output_path = render_version(version_dir)
if output_path:
print(f"Wrote {output_path}")
else:
print(f"Skipped {version_dir}: no *.schema.json file found.")
return 0
if __name__ == "__main__":
sys.exit(main())