81 lines
2.6 KiB
Python
81 lines
2.6 KiB
Python
"""YAML requirements renderer — for request_*.yaml style files."""
|
||
from html import escape
|
||
|
||
|
||
def render(filepath):
|
||
"""Render YAML requirements as grouped tables (F_/P_/S_ sections)."""
|
||
try:
|
||
import yaml
|
||
except ImportError:
|
||
return '<div class="warning">pyyaml not installed. Run: pip install pyyaml</div>'
|
||
|
||
with open(str(filepath), encoding='utf-8') as f:
|
||
data = yaml.safe_load(f)
|
||
|
||
if not isinstance(data, dict):
|
||
return f'<pre><code>{escape(str(data))}</code></pre>'
|
||
|
||
sections = {
|
||
'F_': ('功能需求', []),
|
||
'P_': ('性能需求', []),
|
||
'S_': ('规格需求', []),
|
||
}
|
||
other = []
|
||
|
||
for key, val in data.items():
|
||
if not isinstance(val, dict):
|
||
continue
|
||
name = val.get('name', key)
|
||
desc = val.get('description', '')
|
||
limit = val.get('limit', None)
|
||
|
||
limit_str = ''
|
||
if limit and isinstance(limit, dict):
|
||
parts = []
|
||
if 'min' in limit and limit['min'] is not None:
|
||
parts.append(f'>= {limit["min"]}')
|
||
if 'max' in limit and limit['max'] is not None:
|
||
parts.append(f'<= {limit["max"]}')
|
||
if 'value' in limit:
|
||
parts.append(str(limit['value']))
|
||
if 'unit' in limit:
|
||
parts.append(limit['unit'])
|
||
if 'count' in limit:
|
||
parts.append(f'x{limit["count"]}')
|
||
limit_str = ' '.join(parts)
|
||
|
||
entry = {'id': key, 'name': name, 'desc': desc, 'limit': limit_str}
|
||
placed = False
|
||
for prefix in sections:
|
||
if key.startswith(prefix):
|
||
sections[prefix][1].append(entry)
|
||
placed = True
|
||
break
|
||
if not placed:
|
||
other.append(entry)
|
||
|
||
html = []
|
||
for prefix, (label, items) in sections.items():
|
||
if not items:
|
||
continue
|
||
html.append(f'<h3>{label}({len(items)} 项)</h3>')
|
||
html.append(
|
||
'<table><thead><tr>'
|
||
'<th style="width:16%">ID</th>'
|
||
'<th style="width:16%">名称</th>'
|
||
'<th>描述</th>'
|
||
'<th style="width:20%">指标</th>'
|
||
'</tr></thead><tbody>'
|
||
)
|
||
for e in items:
|
||
html.append(
|
||
f'<tr>'
|
||
f'<td class="text-mono">{escape(e["id"])}</td>'
|
||
f'<td>{escape(e["name"])}</td>'
|
||
f'<td>{escape(e["desc"])}</td>'
|
||
f'<td>{escape(e["limit"])}</td>'
|
||
f'</tr>'
|
||
)
|
||
html.append('</tbody></table>')
|
||
return '\n'.join(html)
|