"""Рендерит представления из .archimate в один самодостаточный HTML со встроенным SVG.
Нужен, чтобы схемы можно было посмотреть без установки Archi."""
import sys, io, pathlib, html
import xml.etree.ElementTree as ET
sys.stdout = io.TextIOWrapper(sys.stdout.buffer, encoding="utf-8")
XSI = "{http://www.w3.org/2001/XMLSchema-instance}type"
src, dst = pathlib.Path(sys.argv[1]), pathlib.Path(sys.argv[2])
root = ET.parse(src).getroot()
LAYER = { # цвета Archi по слоям
"ApplicationComponent": "#B5FFFF", "ApplicationService": "#B5FFFF",
"Node": "#C9E7B7", "SystemSoftware": "#C9E7B7",
"TechnologyService": "#C9E7B7", "Artifact": "#C9E7B7",
}
STROKE = {"Application": "#2a7f8f", "Technology": "#4a7f3a"}
concepts, rels = {}, {}
for folder in root.findall("folder"):
for e in folder.findall("element"):
et = (e.get(XSI) or "").split(":")[-1]
if et.endswith("Relationship"):
rels[e.get("id")] = (et[:-len("Relationship")], e.get("source"), e.get("target"))
elif et != "ArchimateDiagramModel":
concepts[e.get("id")] = (et, e.get("name") or "")
def collect(node, ox, oy, nodes, conns):
b = node.find("bounds")
x, y = ox + int(b.get("x", 0)), oy + int(b.get("y", 0))
w, h = int(b.get("width", 120)), int(b.get("height", 55))
nodes[node.get("id")] = (node.get("archimateElement"), x, y, w, h)
for c in node.findall("sourceConnection"):
conns.append((c.get("relationship"), c.get("source"), c.get("target")))
for ch in node.findall("child"):
collect(ch, x, y, nodes, conns)
def wrap(s, width):
out, line = [], ""
for word in s.split():
if len(line) + len(word) + 1 > width and line:
out.append(line); line = word
else:
line = f"{line} {word}".strip()
if line:
out.append(line)
return out[:4]
def edge_point(x, y, w, h, tx, ty):
"""Точка пересечения луча к (tx,ty) с границей прямоугольника."""
cx, cy = x + w / 2, y + h / 2
dx, dy = tx - cx, ty - cy
if dx == 0 and dy == 0:
return cx, cy
sx = (w / 2) / abs(dx) if dx else float("inf")
sy = (h / 2) / abs(dy) if dy else float("inf")
s = min(sx, sy)
return cx + dx * s, cy + dy * s
MARKERS = """
{html.escape(doc.text)}{html.escape(v.get("name") or "")}
'
+ (f'
Автогенерация из ugmk-technology.archimate. Зелёный — технологический слой,
голубой — прикладной. Пунктир с полым треугольником — realization, стрелка — serving,
ромб — composition, линия с шариком — assignment.