将 README.md 拆分为多个专题文档,减少认知负荷: - 用户文档迁移到 docs/ (用户指南、元素、模板、参考等) - 开发文档迁移到 docs/development/ (架构、模块、规范) - README.md 精简至 ~290 行,仅保留概览和导航 - 删除 README_DEV.md,内容已迁移 - 归档 OpenSpec 变更 refactor-docs-progressive-disclosure
3.5 KiB
3.5 KiB
字体系统实现
字体解析和继承链处理的实现。
职责
- 字体引用解析
- 继承链处理
- 预设类别映射
- 循环引用检测
PRESET_FONT_MAPPING
预设字体类别映射常量:
PRESET_FONT_MAPPING = {
'sans': 'Arial',
'serif': 'Times New Roman',
'mono': 'Courier New',
'cjk-sans': 'Microsoft YaHei',
'cjk-serif': 'SimSun',
}
FontResolver 类
初始化
class FontResolver:
def __init__(self, fonts, fonts_default, scope="document", template_fonts=None):
"""
Args:
fonts: 当前作用域的字体字典
fonts_default: 当前作用域的默认字体
scope: 作用域标识 ("document" 或 "template")
template_fonts: 模板库字体字典(仅文档作用域需要)
"""
resolve_font()
解析字体配置的主入口:
def resolve_font(self, font_config):
"""解析字体配置(主入口)"""
if font_config is None:
return self._get_default_config(set())
if isinstance(font_config, str):
# "@xxx" 格式
return self._resolve_reference(font_config.strip('@'), set())
if isinstance(font_config, dict):
if 'parent' in font_config:
# {parent: "@xxx", ...} 格式
return self._resolve_font_dict(font_config, set())
else:
# 独立定义
return FontConfig(**font_config)
_resolve_reference()
解析字体引用:
def _resolve_reference(self, reference, visited):
"""解析字体引用"""
if reference in visited:
raise ValueError(f"检测到字体引用循环: {' -> '.join(visited + [reference])}")
visited.add(reference)
# 检查作用域
if reference in self.fonts:
font_data = self.fonts[reference]
elif self.template_fonts and reference in self.template_fonts:
font_data = self.template_fonts[reference]
else:
raise ValueError(f"字体配置不存在: @{reference}")
return self._build_font_config(font_data, visited)
_resolve_font_dict()
解析字体字典:
def _resolve_font_dict(self, font_dict, visited):
"""解析字体字典"""
parent_ref = font_dict.get('parent', '').strip('@')
if parent_ref:
# 先解析父级
parent_config = self._resolve_reference(parent_ref, visited.copy())
# 合并当前属性
return self._merge_with_parent(font_dict, parent_config)
# 独立定义
return FontConfig(**font_dict)
字体引用解析逻辑
- 如果
font_config为 None,使用fonts_default - 如果是字符串(
"@xxx"),解析为整体引用 - 如果是字典且包含
parent,先解析parent再覆盖当前属性 - 如果是字典且不包含
parent,直接使用字典属性 - 未定义的属性从
fonts_default继承 - 如果
family是预设类别,映射到具体字体名称 - 返回完整的
FontConfig对象
继承链
属性继承顺序:
parent → 当前属性 → fonts_default → 系统默认
循环引用检测
- 维护已访问集合
visited - 检测重复引用
- 最大引用深度限制:10 层
预设类别映射
在 family 字段中识别预设类别名称:
if family in PRESET_FONT_MAPPING:
family = PRESET_FONT_MAPPING[family]