改为本地 fonts 字体渲染方案
- 在 message_summary 插件中新增本地字体 CSS 构建逻辑,动态注入模板\n- 使用 fonts/simhei.ttf 与 fonts/simsun.ttf 生成 @font-face,避免外网字体依赖\n- Gemini 总结模板移除 Google Fonts,改用本地字体变量与系统回退栈\n- 补充详细中文注释,说明离线字体加载与容错策略
This commit is contained in:
@@ -521,15 +521,71 @@ class MessageSummaryPlugin(MessagePluginInterface):
|
|||||||
# 约束:模板只负责展示,正文仍然由模型生成并在此做安全转义后注入。
|
# 约束:模板只负责展示,正文仍然由模型生成并在此做安全转义后注入。
|
||||||
renderer = HtmlTemplateRenderer()
|
renderer = HtmlTemplateRenderer()
|
||||||
summary_html = self._summary_markdown_to_html(summary_text)
|
summary_html = self._summary_markdown_to_html(summary_text)
|
||||||
|
# 说明:
|
||||||
|
# 1. 这里注入“本地字体 CSS”到模板,避免依赖 Google Fonts 等外网资源;
|
||||||
|
# 2. 字体文件统一从仓库根目录 fonts/ 下读取,便于部署时统一管理;
|
||||||
|
# 3. 若字体文件缺失,自动回退系统字体,不影响功能可用性。
|
||||||
|
local_font_css = self._build_local_font_css()
|
||||||
return renderer.render(
|
return renderer.render(
|
||||||
self._summary_image_template_path,
|
self._summary_image_template_path,
|
||||||
{
|
{
|
||||||
"title": f"{group_name} 群聊总结",
|
"title": f"{group_name} 群聊总结",
|
||||||
"generated_at": datetime.now().strftime("%Y-%m-%d %H:%M:%S"),
|
"generated_at": datetime.now().strftime("%Y-%m-%d %H:%M:%S"),
|
||||||
"summary_html": Markup(summary_html),
|
"summary_html": Markup(summary_html),
|
||||||
|
"local_font_css": Markup(local_font_css),
|
||||||
},
|
},
|
||||||
)
|
)
|
||||||
|
|
||||||
|
def _build_local_font_css(self) -> str:
|
||||||
|
"""构建模板可注入的本地字体 CSS。"""
|
||||||
|
# 说明:
|
||||||
|
# 1. 使用绝对 file:/// URI,确保 Playwright set_content 场景下也能正确定位字体文件;
|
||||||
|
# 2. 按存在性逐个注册字体,避免硬编码导致不存在文件时报错;
|
||||||
|
# 3. 仅返回 CSS 字符串,不在此处抛异常,保证模板渲染链路稳定。
|
||||||
|
try:
|
||||||
|
project_root = Path(__file__).resolve().parents[2]
|
||||||
|
font_dir = project_root / "fonts"
|
||||||
|
|
||||||
|
simhei_path = font_dir / "simhei.ttf"
|
||||||
|
simsun_path = font_dir / "simsun.ttf"
|
||||||
|
|
||||||
|
css_parts: List[str] = []
|
||||||
|
if simhei_path.exists():
|
||||||
|
css_parts.append(
|
||||||
|
"@font-face {"
|
||||||
|
"font-family: 'ABotSimHei'; "
|
||||||
|
f"src: url('{simhei_path.resolve().as_uri()}') format('truetype'); "
|
||||||
|
"font-weight: 400 900; "
|
||||||
|
"font-style: normal; "
|
||||||
|
"font-display: swap; "
|
||||||
|
"}"
|
||||||
|
)
|
||||||
|
if simsun_path.exists():
|
||||||
|
css_parts.append(
|
||||||
|
"@font-face {"
|
||||||
|
"font-family: 'ABotSimSun'; "
|
||||||
|
f"src: url('{simsun_path.resolve().as_uri()}') format('truetype'); "
|
||||||
|
"font-weight: 400 700; "
|
||||||
|
"font-style: normal; "
|
||||||
|
"font-display: swap; "
|
||||||
|
"}"
|
||||||
|
)
|
||||||
|
|
||||||
|
# 说明:
|
||||||
|
# 1. 通过 CSS 变量统一字体栈,模板端只需引用变量即可;
|
||||||
|
# 2. 先使用本地字体,再回退系统字体,兼顾一致性和容错性。
|
||||||
|
css_parts.append(
|
||||||
|
":root { "
|
||||||
|
"--abot-font-sans: 'ABotSimHei', 'ABotSimSun', 'PingFang SC', "
|
||||||
|
"'Microsoft YaHei', -apple-system, BlinkMacSystemFont, 'Segoe UI', sans-serif; "
|
||||||
|
"--abot-font-code: 'Cascadia Mono', 'JetBrains Mono', 'Consolas', 'SFMono-Regular', Menlo, monospace; "
|
||||||
|
"}"
|
||||||
|
)
|
||||||
|
return "\n".join(css_parts)
|
||||||
|
except Exception as e:
|
||||||
|
self.LOG.warning(f"构建本地字体 CSS 失败,回退系统字体: {e}")
|
||||||
|
return ""
|
||||||
|
|
||||||
async def _render_summary_image(
|
async def _render_summary_image(
|
||||||
self,
|
self,
|
||||||
answer: str,
|
answer: str,
|
||||||
|
|||||||
@@ -5,8 +5,8 @@
|
|||||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||||
<title>{{ title }}</title>
|
<title>{{ title }}</title>
|
||||||
<style>
|
<style>
|
||||||
/* 说明:优先尝试加载与 Gemini 示例一致的 Inter / JetBrains Mono,失败时回退到系统字体,避免服务端无字体时样式崩坏。 */
|
/* 说明:由后端动态注入本地字体 @font-face(fonts 目录),避免外网字体依赖。 */
|
||||||
@import url('https://fonts.googleapis.com/css2?family=Inter:wght@400;600;700;800;900&family=JetBrains+Mono:wght@500;700&display=swap');
|
{{ local_font_css }}
|
||||||
|
|
||||||
:root {
|
:root {
|
||||||
--bg: #f8fafc;
|
--bg: #f8fafc;
|
||||||
@@ -33,7 +33,8 @@
|
|||||||
padding: 10px 0 12px;
|
padding: 10px 0 12px;
|
||||||
background: var(--bg);
|
background: var(--bg);
|
||||||
color: var(--text);
|
color: var(--text);
|
||||||
font-family: "Inter", "PingFang SC", -apple-system, BlinkMacSystemFont, "Segoe UI", sans-serif;
|
/* 说明:优先使用本地字体变量,未命中时回退系统字体。 */
|
||||||
|
font-family: var(--abot-font-sans, "PingFang SC", "Microsoft YaHei", -apple-system, BlinkMacSystemFont, "Segoe UI", sans-serif);
|
||||||
-webkit-font-smoothing: antialiased;
|
-webkit-font-smoothing: antialiased;
|
||||||
}
|
}
|
||||||
.report-container {
|
.report-container {
|
||||||
@@ -177,7 +178,8 @@
|
|||||||
font-style: italic;
|
font-style: italic;
|
||||||
}
|
}
|
||||||
.markdown-body code {
|
.markdown-body code {
|
||||||
font-family: "JetBrains Mono", "SFMono-Regular", Menlo, Consolas, monospace;
|
/* 说明:代码字体优先使用本地/系统等宽字体栈,保证服务端离线场景可读。 */
|
||||||
|
font-family: var(--abot-font-code, "Cascadia Mono", "Consolas", "SFMono-Regular", Menlo, monospace);
|
||||||
font-size: 12px;
|
font-size: 12px;
|
||||||
background: #eff6ff;
|
background: #eff6ff;
|
||||||
color: #1e40af;
|
color: #1e40af;
|
||||||
|
|||||||
Reference in New Issue
Block a user