platform-core/modules/serviceCenter/services/serviceGeneration/styleDefaults.py
ValueOn AG 2eb1a5589d
Some checks failed
Deploy Plattform-Core (Int) / test (push) Failing after 18s
Deploy Plattform-Core (Int) / deploy (push) Has been skipped
fixes doc generation and renderers
2026-06-03 16:45:17 +02:00

109 lines
3.5 KiB
Python

# Copyright (c) 2025 Patrick Motsch
# All rights reserved.
"""Default style definitions and style resolution for document rendering."""
from typing import Any, Dict
DEFAULT_STYLE: Dict[str, Any] = {
"fonts": {
"primary": "Calibri",
"monospace": "Consolas",
},
"colors": {
"primary": "#24292e",
"secondary": "#586069",
"accent": "#0366d6",
"background": "#FFFFFF",
},
"documentTitle": {
"sizePt": 28,
"weight": "bold",
"color": "#24292e",
"spaceBeforePt": 0,
"spaceAfterPt": 18,
"align": "center",
},
"headings": {
"h1": {"sizePt": 22, "weight": "bold", "color": "#24292e", "spaceBeforePt": 24, "spaceAfterPt": 8},
"h2": {"sizePt": 18, "weight": "bold", "color": "#24292e", "spaceBeforePt": 20, "spaceAfterPt": 6},
"h3": {"sizePt": 14, "weight": "bold", "color": "#586069", "spaceBeforePt": 16, "spaceAfterPt": 4},
"h4": {"sizePt": 12, "weight": "bold", "color": "#586069", "spaceBeforePt": 12, "spaceAfterPt": 3},
},
"paragraph": {"sizePt": 11, "lineSpacing": 1.5, "color": "#24292e", "align": "left"},
"table": {
"headerBg": "#f6f8fa",
"headerFg": "#24292e",
"headerSizePt": 10,
"bodySizePt": 10,
"rowBandingEven": "#f6f8fa",
"rowBandingOdd": "#FFFFFF",
"borderColor": "#e1e4e8",
"borderWidthPt": 0.5,
"borderStyle": "grid",
"bandingEnabled": True,
"cellPaddingPt": 4,
},
"list": {"bulletChar": "\u2022", "indentPt": 18, "sizePt": 11},
"image": {"defaultWidthPt": 480, "maxWidthPt": 800, "alignment": "center"},
"codeBlock": {"fontSizePt": 9, "background": "#f6f8fa", "borderColor": "#e1e4e8"},
"coverPage": {
"titleSizePt": 28,
"subtitleSizePt": 16,
"authorSizePt": 12,
"dateSizePt": 12,
"titleColor": "#24292e",
"subtitleColor": "#586069",
},
"caption": {
"sizePt": 10,
"color": "#586069",
"italic": True,
"align": "center",
},
"page": {
"format": "A4",
"marginsPt": {"top": 60, "bottom": 60, "left": 60, "right": 60},
"showPageNumbers": True,
"headerHeight": 30,
"footerHeight": 30,
"headerLogo": None,
"headerText": "",
"footerText": "",
},
}
def deepMerge(base: Dict[str, Any], override: Dict[str, Any]) -> Dict[str, Any]:
"""Recursively merge override into base. Both dicts left unchanged; returns new dict."""
result = {}
for key in base:
if key in override:
baseVal = base[key]
overVal = override[key]
if isinstance(baseVal, dict) and isinstance(overVal, dict):
result[key] = deepMerge(baseVal, overVal)
else:
result[key] = overVal
else:
result[key] = base[key]
for key in override:
if key not in base:
result[key] = override[key]
return result
def resolveStyle(agentStyle: dict | None = None) -> Dict[str, Any]:
"""Resolve the effective style: ``DEFAULT_STYLE <- agentStyle``.
Precedence (lowest to highest): platform defaults, then any explicit
per-call ``agentStyle`` override. With no override this returns plain
:data:`DEFAULT_STYLE`. Context-aware styling is handled by the AI
enhancement step in ``mainServiceGeneration.renderReport``.
"""
resolved = dict(DEFAULT_STYLE)
if agentStyle:
resolved = deepMerge(resolved, agentStyle)
return resolved