"use strict" const fs = require("fs") let points = {} let boxes = {} let edges = {} let mode, group, name, x, y, w, h, cx, cy, rx, ry, x2, y2 let labels = [] let labels_uniq = {} function add_point(x, y) { if (!(group in points)) points[group] = [] points[group].push({x,y,name}) } function add_rect(x, y, w, h) { if (!(group in boxes)) boxes[group] = [] boxes[group].push({x,y,w,h,name}) } function add_edge(x1, y1, x2, y2) { if (!(group in edges)) edges[group] = [] edges[group].push({x1,y1,x2,y2,name}) } function flush() { if (mode === 'path') { add_edge(x, y, x2, y2) } if (mode === 'rect') { add_rect(x, y, w, h) add_point( x + w/2, y + h/2 ) } if (mode === 'circle') { add_rect(cx - rx, cy - ry, rx * 2, ry * 2) add_point( cx, cy ) } x = y = x2 = y2 = w = h = cx = cy = rx = ry = 0 name = null } function parse_path_data(path) { let cx = 0 let cy = 0 let abs = 0 for (let i = 0; i < path.length;) { switch (path[i]) { case 'M': x2 = x = cx = Number(path[i+1]) y2 = y = cy = Number(path[i+2]) i += 3 abs = true break case 'm': x2 = x = cx = cx + Number(path[i+1]) y2 = y = cy = cy + Number(path[i+2]) i += 3 abs = false break case 'C': x2 = cx = Number(path[i+5]) y2 = cy = Number(path[i+6]) i += 7 abs = true break case 'L': i += 1 abs = true break case 'H': x2 = cx = Number(path[i+1]) i += 2 abs = true break case 'V': y2 = cy = Number(path[i+1]) i += 2 abs = true break case 'c': x2 = cx = cx + Number(path[i+5]) y2 = cy = cy + Number(path[i+6]) i += 7 abs = false break case 'l': i += 1 abs = false break case 'h': x2 = cx = cx + Number(path[i+1]) i += 2 abs = false break case 'v': y2 = cy = cy + Number(path[i+1]) i += 2 abs = false break default: if (abs) { x2 = cx = Number(path[i+0]) y2 = cy = Number(path[i+1]) } else { x2 = cx = cx + Number(path[i+0]) y2 = cy = cy + Number(path[i+1]) } i += 2 break } } } for (let line of fs.readFileSync("tools/layout.svg", "utf-8").split("\n")) { line = line.trim() if (line.startsWith("")) { let name = line.replace(/^[^>]*>/, "").replace(/<\/tspan.*/, "") if (name in labels_uniq) console.log("DUPLICATE LABEL", name) labels.push({x, y, name}) labels_uniq[name] = 1 } } flush() function find_label(x, y, limit) { let nd = Infinity, nn = null for (let n of labels) { let d = Math.hypot(n.x - x, n.y - y) if (d < nd) { nd = d nn = n } } if (!nn || nd > limit) { console.log("LABEL NOT FOUND", x, y) return null } return nn.name } for (let group in points) { for (let item of points[group]) { if (item.name === null) { item.name = find_label(item.x, item.y, 72) } } } for (let group in boxes) { for (let item of boxes[group]) { if (item.name === null) { item.name = find_label(item.x+item.w/2, item.y+item.w/2, 72) } } } for (let group in edges) { for (let item of edges[group]) { item.name1 = find_label(item.x1, item.y1, 72) item.name2 = find_label(item.x2, item.y2, 72) } } fs.writeFileSync("tools/layout.json", JSON.stringify({boxes,points,edges,labels}, null, 4))