75 lines
2.6 KiB
Python
75 lines
2.6 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": "#1F3864",
|
|
"secondary": "#2C3E50",
|
|
"accent": "#2980B9",
|
|
"background": "#FFFFFF",
|
|
},
|
|
"headings": {
|
|
"h1": {"sizePt": 24, "weight": "bold", "color": "#1F3864", "spaceBeforePt": 12, "spaceAfterPt": 6},
|
|
"h2": {"sizePt": 18, "weight": "bold", "color": "#1F3864", "spaceBeforePt": 10, "spaceAfterPt": 4},
|
|
"h3": {"sizePt": 14, "weight": "bold", "color": "#2C3E50", "spaceBeforePt": 8, "spaceAfterPt": 3},
|
|
"h4": {"sizePt": 12, "weight": "bold", "color": "#2C3E50", "spaceBeforePt": 6, "spaceAfterPt": 2},
|
|
},
|
|
"paragraph": {"sizePt": 11, "lineSpacing": 1.15, "color": "#333333"},
|
|
"table": {
|
|
"headerBg": "#1F3864",
|
|
"headerFg": "#FFFFFF",
|
|
"headerSizePt": 10,
|
|
"bodySizePt": 10,
|
|
"rowBandingEven": "#F2F6FC",
|
|
"rowBandingOdd": "#FFFFFF",
|
|
"borderColor": "#CBD5E1",
|
|
"borderWidthPt": 0.5,
|
|
},
|
|
"list": {"bulletChar": "\u2022", "indentPt": 18, "sizePt": 11},
|
|
"image": {"defaultWidthPt": 480, "maxWidthPt": 800, "alignment": "center"},
|
|
"codeBlock": {"fontSizePt": 9, "background": "#F8F9FA", "borderColor": "#E2E8F0"},
|
|
"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) -> Dict[str, Any]:
|
|
"""Deep-merge DEFAULT_STYLE <- agentStyle. Returns fully resolved style dict."""
|
|
if not agentStyle:
|
|
return dict(DEFAULT_STYLE)
|
|
return _deepMerge(DEFAULT_STYLE, agentStyle)
|