refactor: 重构文档结构,采用渐进式信息披露模式
将 README.md 拆分为多个专题文档,减少认知负荷: - 用户文档迁移到 docs/ (用户指南、元素、模板、参考等) - 开发文档迁移到 docs/development/ (架构、模块、规范) - README.md 精简至 ~290 行,仅保留概览和导航 - 删除 README_DEV.md,内容已迁移 - 归档 OpenSpec 变更 refactor-docs-progressive-disclosure
This commit is contained in:
144
docs/development/font-system.md
Normal file
144
docs/development/font-system.md
Normal file
@@ -0,0 +1,144 @@
|
||||
# 字体系统实现
|
||||
|
||||
字体解析和继承链处理的实现。
|
||||
|
||||
## 职责
|
||||
|
||||
- 字体引用解析
|
||||
- 继承链处理
|
||||
- 预设类别映射
|
||||
- 循环引用检测
|
||||
|
||||
## PRESET_FONT_MAPPING
|
||||
|
||||
预设字体类别映射常量:
|
||||
|
||||
```python
|
||||
PRESET_FONT_MAPPING = {
|
||||
'sans': 'Arial',
|
||||
'serif': 'Times New Roman',
|
||||
'mono': 'Courier New',
|
||||
'cjk-sans': 'Microsoft YaHei',
|
||||
'cjk-serif': 'SimSun',
|
||||
}
|
||||
```
|
||||
|
||||
## FontResolver 类
|
||||
|
||||
### 初始化
|
||||
|
||||
```python
|
||||
class FontResolver:
|
||||
def __init__(self, fonts, fonts_default, scope="document", template_fonts=None):
|
||||
"""
|
||||
Args:
|
||||
fonts: 当前作用域的字体字典
|
||||
fonts_default: 当前作用域的默认字体
|
||||
scope: 作用域标识 ("document" 或 "template")
|
||||
template_fonts: 模板库字体字典(仅文档作用域需要)
|
||||
"""
|
||||
```
|
||||
|
||||
### resolve_font()
|
||||
|
||||
解析字体配置的主入口:
|
||||
|
||||
```python
|
||||
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()
|
||||
|
||||
解析字体引用:
|
||||
|
||||
```python
|
||||
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()
|
||||
|
||||
解析字体字典:
|
||||
|
||||
```python
|
||||
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)
|
||||
```
|
||||
|
||||
## 字体引用解析逻辑
|
||||
|
||||
1. 如果 `font_config` 为 None,使用 `fonts_default`
|
||||
2. 如果是字符串(`"@xxx"`),解析为整体引用
|
||||
3. 如果是字典且包含 `parent`,先解析 `parent` 再覆盖当前属性
|
||||
4. 如果是字典且不包含 `parent`,直接使用字典属性
|
||||
5. 未定义的属性从 `fonts_default` 继承
|
||||
6. 如果 `family` 是预设类别,映射到具体字体名称
|
||||
7. 返回完整的 `FontConfig` 对象
|
||||
|
||||
## 继承链
|
||||
|
||||
属性继承顺序:
|
||||
|
||||
```
|
||||
parent → 当前属性 → fonts_default → 系统默认
|
||||
```
|
||||
|
||||
## 循环引用检测
|
||||
|
||||
- 维护已访问集合 `visited`
|
||||
- 检测重复引用
|
||||
- 最大引用深度限制:10 层
|
||||
|
||||
## 预设类别映射
|
||||
|
||||
在 `family` 字段中识别预设类别名称:
|
||||
|
||||
```python
|
||||
if family in PRESET_FONT_MAPPING:
|
||||
family = PRESET_FONT_MAPPING[family]
|
||||
```
|
||||
|
||||
## 相关文档
|
||||
|
||||
- [作用域系统](scope-system.md) - 字体作用域规则
|
||||
- [字体主题系统](../../fonts.md) - 用户指南
|
||||
|
||||
[返回开发文档索引](../README.md)
|
||||
Reference in New Issue
Block a user