-
Notifications
You must be signed in to change notification settings - Fork 38
/
transformer.js
93 lines (84 loc) · 2.71 KB
/
transformer.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
define(['viz', 'parser/xdot', 'pegast'], function (viz, xdotparser, pegast) {
return {
generate: function (source) {
var xdot, result;
xdot = viz(source, { format: "xdot" });
try {
var ast = xdotparser.parse(xdot);
result = this.shapeast(ast);
} catch(e) {
throw "Parsing of xdot output failed";
}
return result;
},
shapeast: function(ast) {
var result = [];
var cursor;
function visitSubnodes(propertyName) {
return function (node) {
node[propertyName] && node[propertyName].forEach(visit);
};
}
function startGroup(propertyName) {
return function (node) {
var groupById = result.filter(function(e) {
return e.id === node.id;
});
cursor =
groupById.length > 0 ?
groupById[0] : {id: node.id, class: node.type, shapes: [], labels: []};
groupById.length === 0 && result.push(cursor);
node[propertyName] && node[propertyName].forEach(visit);
};
}
function addShapesAndLabels(node) {
cursor.shapes = cursor.shapes.concat(node.elements.filter(function(e){
return e.shape;
})).map(fixShapeStyles);
cursor.labels = cursor.labels.concat(node.elements.filter(function(e){
return e.text;
}));
}
function fixShapeStyles(element) {
if (element.style) {
var keys = element.style.map(function(e) {return e.key});
keys.indexOf("fill") < 0 && element.style.push({key: 'fill', value: "none"});
keys.indexOf("stroke") < 0 && element.style.push({key: 'stroke', value: "black"});
}
return element;
}
function addNodeAttribute(name) {
return function(node) {
cursor[name] = node.value;
};
}
var visit = pegast.nodeVisitor({
digraph: startGroup('commands'),
graph: visitSubnodes('attributes'),
subgraph: startGroup('commands'),
struct: visitSubnodes('commands'),
node: startGroup('attributes'),
relation: startGroup('attributes'),
draw: addShapesAndLabels,
hdraw: addShapesAndLabels,
tdraw: addShapesAndLabels,
ldraw: addShapesAndLabels,
hldraw: addShapesAndLabels,
tldraw: addShapesAndLabels,
url: addNodeAttribute('url'),
tooltip: addNodeAttribute('tooltip'),
id: addNodeAttribute('identifier'),
size: function(node) {
cursor.size = node.value.map(function(e) {
return e*72;
});
}
});
visit(ast);
return {
main: result.shift(),
groups: result
};
}
};
});