Coverage for src/jsoncrack_for_sphinx/generators/rst_generator.py: 96%
50 statements
« prev ^ index » next coverage.py v7.10.0, created at 2025-07-24 22:26 +0000
« prev ^ index » next coverage.py v7.10.0, created at 2025-07-24 22:26 +0000
1"""
2RST generation utilities for JSON schemas.
3"""
5import json
6from pathlib import Path
7from typing import Any, Dict, Optional
10def schema_to_rst(schema_path: Path, title: Optional[str] = None) -> str:
11 """
12 Convert a JSON schema file to reStructuredText format.
14 This function is provided as a fixture for tests to convert schema
15 files to reStructuredText format.
17 Args:
18 schema_path: Path to the JSON schema file
19 title: Optional title for the schema section
21 Returns:
22 reStructuredText representation of the schema
23 """
24 if not schema_path.exists():
25 raise FileNotFoundError(f"Schema file not found: {schema_path}")
27 try:
28 # Read and validate JSON schema
29 with open(schema_path, "r", encoding="utf-8") as f:
30 schema_data = json.load(f)
32 # Create simple HTML representation of schema
33 html_content = _generate_simple_schema_html(schema_data)
35 # Convert to RST
36 rst_lines = []
38 if title:
39 rst_lines.extend(
40 [
41 title,
42 "=" * len(title),
43 "",
44 ]
45 )
47 rst_lines.extend(
48 [
49 ".. raw:: html",
50 "",
51 ' <div class="json-schema-container">',
52 f" {html_content}",
53 " </div>",
54 "",
55 ]
56 )
58 return "\n".join(rst_lines)
60 except json.JSONDecodeError as e:
61 raise ValueError(f"Invalid JSON in schema file {schema_path}: {e}")
62 except Exception as e:
63 raise RuntimeError(f"Error processing schema file {schema_path}: {e}")
66def _generate_simple_schema_html(schema_data: Dict[str, Any]) -> str:
67 """
68 Generate simple HTML representation of a JSON schema.
70 Args:
71 schema_data: JSON schema data
73 Returns:
74 HTML string representing the schema
75 """
76 html_parts = []
78 # Add title if present
79 if "title" in schema_data:
80 html_parts.append(f'<h3>{schema_data["title"]}</h3>')
82 # Add description if present
83 if "description" in schema_data:
84 html_parts.append(f'<p>{schema_data["description"]}</p>')
86 # Add basic schema info
87 html_parts.append('<div class="schema-info">')
89 if "type" in schema_data:
90 html_parts.append(f'<p><strong>Type:</strong> {schema_data["type"]}</p>')
92 # Add properties if it's an object schema
93 if schema_data.get("type") == "object" and "properties" in schema_data:
94 html_parts.append("<h4>Properties:</h4>")
95 html_parts.append("<ul>")
96 for prop_name, prop_info in schema_data["properties"].items():
97 prop_type = prop_info.get("type", "unknown")
98 prop_desc = prop_info.get("description", "")
99 is_required = prop_name in schema_data.get("required", [])
100 required_text = " (required)" if is_required else ""
102 prop_line = (
103 f"<li><strong>{prop_name}</strong> " f"({prop_type}){required_text}"
104 )
105 html_parts.append(prop_line)
106 if prop_desc:
107 html_parts.append(f"<br>{prop_desc}")
108 html_parts.append("</li>")
109 html_parts.append("</ul>")
111 # Add raw schema as collapsible section
112 html_parts.append("<details>")
113 html_parts.append("<summary>Raw Schema</summary>")
114 html_parts.append("<pre>")
115 html_parts.append(json.dumps(schema_data, indent=2))
116 html_parts.append("</pre>")
117 html_parts.append("</details>")
119 html_parts.append("</div>")
121 return "\n".join(html_parts)