# -*- coding: utf-8 -*- """给导入的各仿真页注入统一外壳: 顶栏 + 配色 token + 返回链接。 只做**加法**(追加一段 style + 在 body 开头插一个顶栏), 不改页面原有 DOM 与 JS, 所以不会破坏各页自己的 canvas 绘制逻辑。canvas 内部配色由各页 JS 决定, 本层不动 —— 这是已知边界。""" import pathlib, re, sys SIM = pathlib.Path("/Users/yuanying/guanlan-rudong-v2/outputs/rudong/windscada/_demo/sim") MARK = "guanlan-shell-v1" PAGES = { "涡激共振模拟器.html": ("涡激共振模拟器", "机理通识 · 十二款机型预设"), "涡激实测核验.html": ("涡激实测核验", "实测 · 九台秒级"), "偏航滑移事件回放.html": ("偏航滑移事件回放", "实测 · 单台"), "故障分布三维视图.html": ("故障分布三维视图", "实测 · 机组 × 系统 × 月份"), "变流器故障仿真.html": ("变流器故障仿真", "注入 · 波形为合成"), "变桨故障仿真.html": ("变桨故障仿真", "注入 · 波形为合成"), "整机联调台_1.5MW.html": ("整机联调台 · 1.5 MW", "正演 · 控制核心层参数"), "整机联调台_4MW.html": ("整机联调台 · 4 MW", "正演 · 控制核心层参数"), } SHELL_CSS = """ """ % MARK def shell(title, sub): return (f'
' f'
{title}{sub}
' f'← 返回仿真集成台
') def apply(path, title, sub): s = path.read_text(encoding="utf-8") if MARK in s: # 幂等剥离。注意: 不能用
.*?
—— 非贪婪会一路扫进页面正文, # 把内容一起删掉(曾把一页删掉 4 KB)。改用唯一的结束锚: 顶栏最后是 。 s = re.sub(r'\s*' % MARK, "", s, flags=re.S) s = re.sub(r'
.*?返回仿真集成台
\s*', "", s, flags=re.S, count=1) # 主路径: 有 / m = re.search(r"", s, re.I) if m: s = s[:m.start()] + SHELL_CSS + s[m.start():] else: # 回退: 片段式 HTML (无 head/body 标签, 浏览器容忍)。锚到 或最后一个 </style> 之后 a = re.search(r"</title\s*>", s, re.I) or re.search(r"</style\s*>(?![\s\S]*</style\s*>)", s, re.I) if not a: return None s = s[:a.end()] + "\n" + SHELL_CSS + s[a.end():] b = re.search(r"<body[^>]*>", s, re.I) if b: s = s[:b.end()] + "\n" + shell(title, sub) + s[b.end():] else: # 回退: 插在最后一个 </style> 之后 (即样式区结束、可见内容开始处) c = None for c in re.finditer(r"</style\s*>", s, re.I): pass if not c: return None s = s[:c.end()] + "\n" + shell(title, sub) + s[c.end():] path.write_text(s, encoding="utf-8"); return len(s) ok = 0 for f,(t,sub) in PAGES.items(): p = SIM/f if not p.exists(): print(f" 缺: {f}"); continue n = apply(p, t, sub) if n: ok += 1; print(f" ✓ {f} ({n//1024} KB)") else: print(f" ✗ {f} 结构不符, 未注入") print(f"\n注入 {ok}/{len(PAGES)} 页")