📁 新增 pcb/ 目录:硬件同事(唐磊)PCB 设计文档归档区
This commit is contained in:
@@ -0,0 +1,68 @@
|
||||
#!/usr/bin/env python3
|
||||
"""Extract SVGs from HTML, inline styles (light theme), output standalone .svg files."""
|
||||
import re, sys, html
|
||||
|
||||
SRC = "/root/.openclaw/workspace/loop-detector/loop-detector-principle.html"
|
||||
|
||||
CSS = {
|
||||
"title": {"font-size": "20px", "font-weight": "650", "fill": "#172033"},
|
||||
"label": {"font-size": "14px", "font-weight": "600", "fill": "#172033"},
|
||||
"small": {"font-size": "12px", "fill": "#5b6475"},
|
||||
"tiny": {"font-size": "11px", "fill": "#5b6475"},
|
||||
"node": {"stroke": "#64748b", "stroke-width": "1"},
|
||||
"neutral": {"fill": "#e2e8f0"},
|
||||
"input": {"fill": "#bfdbfe"},
|
||||
"process": {"fill": "#c7d2fe"},
|
||||
"storage": {"fill": "#99f6e4"},
|
||||
"external":{"fill": "#fde68a"},
|
||||
"risk": {"fill": "#fecaca"},
|
||||
"edge": {"stroke": "#64748b", "stroke-width": "1.5", "fill": "none"},
|
||||
"wire": {"stroke": "#64748b", "stroke-width": "1.3", "fill": "none"},
|
||||
"wireb": {"stroke": "#64748b", "stroke-width": "2", "fill": "none"},
|
||||
"zone": {"fill": "none", "stroke": "#64748b", "stroke-width": "1",
|
||||
"stroke-dasharray": "6 5", "opacity": "0.8"},
|
||||
"comp": {"fill": "none", "stroke": "#172033", "stroke-width": "1.6"},
|
||||
"compf": {"fill": "#172033", "stroke": "none"},
|
||||
"rec": {"fill": "#172033", "stroke": "none"},
|
||||
"rec-o": {"fill": "none", "stroke": "#172033", "stroke-width": "1.4"},
|
||||
"badge": {"fill": "#16a34a"},
|
||||
"badge-t": {"fill": "#ffffff", "font-size": "11px", "font-weight": "700"},
|
||||
"hl": {"stroke": "#16a34a", "stroke-width": "2.5"},
|
||||
}
|
||||
|
||||
def inline(el):
|
||||
classes = el.get("class", "").split()
|
||||
merged = {}
|
||||
for c in classes:
|
||||
if c in CSS:
|
||||
merged.update(CSS[c])
|
||||
# element-level attributes override classes (fill attr etc.)
|
||||
for attr in ("fill", "stroke", "stroke-width", "opacity"):
|
||||
v = el.get(attr)
|
||||
if v is not None:
|
||||
merged[attr] = v
|
||||
if merged:
|
||||
style = "; ".join(f"{k}: {v}" for k, v in merged.items())
|
||||
old = el.get("style", "")
|
||||
el.set("style", (old + ";" + style).strip(";") if old else style)
|
||||
el.attrib.pop("class", None)
|
||||
for child in el:
|
||||
inline(child)
|
||||
|
||||
def process(svg_text, out_path):
|
||||
# drop <style> and <defs> references stay; remove style blocks
|
||||
svg_text = re.sub(r"<style>.*?</style>", "", svg_text, flags=re.S)
|
||||
import xml.etree.ElementTree as ET
|
||||
root = ET.fromstring(svg_text)
|
||||
# add width/height for predictable output
|
||||
root.set("xmlns", "http://www.w3.org/2000/svg")
|
||||
inline(root)
|
||||
tree = ET.ElementTree(root)
|
||||
tree.write(out_path, encoding="utf-8", xml_declaration=True)
|
||||
print("wrote", out_path)
|
||||
|
||||
data = open(SRC, encoding="utf-8").read()
|
||||
svgs = re.findall(r"<svg.*?</svg>", data, flags=re.S)
|
||||
print("found", len(svgs), "svgs")
|
||||
process(svgs[0], "/root/.openclaw/workspace/loop-detector/fig1-methods.svg")
|
||||
process(svgs[1], "/root/.openclaw/workspace/loop-detector/fig2-schematic.svg")
|
||||
Reference in New Issue
Block a user