@ohos-ports/graphviz 0.0.9-beta.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,402 @@
1
+ /**
2
+ * Module dependencies
3
+ */
4
+ var Hash = require( './core_ext/hash' ).Hash,
5
+ Node = require( './node' ).Node,
6
+ Edge = require( './edge' ).Edge,
7
+ gvattrs = require( './attributs' ),
8
+ Attributs = gvattrs.Attributs,
9
+ util = require('util'),
10
+ path = require('path'),
11
+ spawn = require('child_process').spawn;
12
+
13
+ /**
14
+ * Create a new graph
15
+ * @constructor
16
+ * @param {Graph} graph Parent Graph
17
+ * @param {String} id The graphID
18
+ * @return {Graph}
19
+ * @api public
20
+ */
21
+ var Graph = exports.Graph = function(graph, id) {
22
+ this.relativeGraph = graph;
23
+ this.id = id;
24
+ this.type = 'graph';
25
+ this.gvPath = '';
26
+ this.nodes = new Hash();
27
+ this.edges = new Array();
28
+ this.clusters = new Hash();
29
+ if( this.relativeGraph == null ) {
30
+ this.graphAttributs = new Attributs("G");
31
+ } else {
32
+ this.graphAttributs = new Attributs("C");
33
+ }
34
+ this.nodesAttributs = new Attributs("N");
35
+ this.edgesAttributs = new Attributs("E");
36
+ this.use = 'dot';
37
+ };
38
+
39
+ /**
40
+ * Create a new node
41
+ *
42
+ * @param {String} id The node ID
43
+ * @param {Object} attrs Node attributs
44
+ * @return {Node}
45
+ * @api public
46
+ */
47
+ Graph.prototype.addNode = function(id, attrs) {
48
+ this.nodes.setItem(id, new Node(this, id));
49
+ if( attrs ) {
50
+ for( k in attrs ) {
51
+ this.nodes.items[id].set( k, attrs[k] );
52
+ }
53
+ }
54
+
55
+ return this.nodes.items[id];
56
+ }
57
+
58
+ /**
59
+ * Return a node for a given ID
60
+ *
61
+ * @param {String} id The node ID
62
+ * @return {Node}
63
+ * @api public
64
+ */
65
+ Graph.prototype.getNode = function(id) {
66
+ return this.nodes.items[id];
67
+ }
68
+
69
+ Graph.prototype.from = function(id) {
70
+ if( this.nodes.items[id] == undefined ) {
71
+ this.addNode(id);
72
+ }
73
+ return this.nodes.items[id];
74
+ }
75
+
76
+ /**
77
+ * Return the number of nodes in the current graph
78
+ *
79
+ * @return {Integer}
80
+ * @api public
81
+ */
82
+ Graph.prototype.nodeCount = function() {
83
+ return this.nodes.length;
84
+ }
85
+
86
+ /**
87
+ * Create a new edge
88
+ *
89
+ * @param {String|Node} nodeOne
90
+ * @param {String|Node} nodeTwo
91
+ * @param {Object} attrs Node attributs
92
+ * @return {Edge}
93
+ * @api public
94
+ */
95
+ Graph.prototype.addEdge = function(nodeOne, nodeTwo, attrs) {
96
+ var _nodeOne = nodeOne;
97
+ var _nodeTwo = nodeTwo;
98
+ if( typeof(nodeOne) == 'string' ) {
99
+ _nodeOne = this.nodes.items[nodeOne];
100
+ if( _nodeOne == null ) {
101
+ _nodeOne = this.addNode( nodeOne );
102
+ }
103
+ }
104
+ if( typeof(nodeTwo) == 'string' ) {
105
+ _nodeTwo = this.nodes.items[nodeTwo];
106
+ if( _nodeTwo == null ) {
107
+ _nodeTwo = this.addNode( nodeTwo );
108
+ }
109
+ }
110
+
111
+ var edge = new Edge(this, _nodeOne, _nodeTwo);
112
+ if( attrs ) {
113
+ for( k in attrs ) {
114
+ edge.set( k, attrs[k] );
115
+ }
116
+ }
117
+ this.edges.push( edge );
118
+
119
+ return edge;
120
+ }
121
+
122
+ /**
123
+ * Return the number of edges in the current graph
124
+ *
125
+ * @return {Integer}
126
+ * @api public
127
+ */
128
+ Graph.prototype.edgeCount = function() {
129
+ return this.edges.length;
130
+ };
131
+
132
+ /**
133
+ * Create a new subgraph
134
+ *
135
+ * @param {String} id The subgraph ID
136
+ * @return {Graph}
137
+ * @api public
138
+ */
139
+ Graph.prototype.addCluster = function(id) {
140
+ var cluster = new Graph(this, id);
141
+ cluster.type = this.type;
142
+ this.clusters.setItem(id, cluster);
143
+ return cluster;
144
+ }
145
+
146
+ /**
147
+ * Return a subgraph for a given ID
148
+ *
149
+ * @param {String} id The subgraph ID
150
+ * @return {Graph}
151
+ * @api public
152
+ */
153
+ Graph.prototype.getCluster = function(id) {
154
+ return this.clusters.items[id];
155
+ }
156
+
157
+ /**
158
+ * Return the number of subgraphs in the current graph
159
+ *
160
+ * @return {Integer}
161
+ * @api public
162
+ */
163
+ Graph.prototype.clusterCount = function() {
164
+ return this.clusters.length;
165
+ }
166
+
167
+ /**
168
+ * Set a graph attribut
169
+ *
170
+ * @param {String} name The attribut name
171
+ * @param {Void} value The attribut value
172
+ * @api public
173
+ */
174
+ Graph.prototype.set = function(name, value) {
175
+ this.graphAttributs.set(name, value);
176
+ }
177
+
178
+ /**
179
+ * Get a graph attribut
180
+ *
181
+ * @param {String} name The attribut name
182
+ * @return {Void}
183
+ * @api public
184
+ */
185
+ Graph.prototype.get = function(name) {
186
+ return this.graphAttributs.get(name);
187
+ }
188
+
189
+ /**
190
+ * Set a global node attribut
191
+ *
192
+ * @param {String} name The attribut name
193
+ * @param {Void} value The attribut value
194
+ * @api public
195
+ */
196
+ Graph.prototype.setNodeAttribut = function(name, value) {
197
+ this.nodesAttributs.set(name, value);
198
+ }
199
+
200
+ /**
201
+ * Get a global node attribut
202
+ *
203
+ * @param {String} name The attribut name
204
+ * @return {Void}
205
+ * @api public
206
+ */
207
+ Graph.prototype.getNodeAttribut = function(name) {
208
+ return this.nodesAttributs.get(name);
209
+ }
210
+
211
+ /**
212
+ * Set a global edge attribut
213
+ *
214
+ * @param {String} name The attribut name
215
+ * @param {Void} value The attribut value
216
+ * @api public
217
+ */
218
+ Graph.prototype.setEdgeAttribut = function(name, value) {
219
+ this.edgesAttributs.set(name, value);
220
+ }
221
+
222
+ /**
223
+ * Get a global edge attribut
224
+ *
225
+ * @param {String} name The attribut name
226
+ * @return {Void}
227
+ * @api public
228
+ */
229
+ Graph.prototype.getEdgeAttribut = function(name) {
230
+ return this.edgesAttributs.get(name);
231
+ }
232
+
233
+ /**
234
+ * Generate the GraphViz script
235
+ *
236
+ * @return {String}
237
+ * @api public
238
+ */
239
+ Graph.prototype.to_dot = function() {
240
+ var dotScript = '';
241
+ if( this.relativeGraph == null ) {
242
+ dotScript = this.type + ' ' + this.id + ' {\n'
243
+ } else {
244
+ dotScript = 'subgraph ' + this.id + ' {\n'
245
+ }
246
+
247
+ // Graph attributs
248
+ if( this.graphAttributs.length() > 0 ) {
249
+ dotScript = dotScript + " graph" + this.graphAttributs.to_dot() + ";\n";
250
+ }
251
+
252
+ // Nodes attributs
253
+ if( this.nodesAttributs.length() > 0 ) {
254
+ dotScript = dotScript + " node" + this.nodesAttributs.to_dot() + ";\n";
255
+ }
256
+
257
+ // Edges attributs
258
+ if( this.edgesAttributs.length() > 0 ) {
259
+ dotScript = dotScript + " edge" + this.edgesAttributs.to_dot() + ";\n";
260
+ }
261
+
262
+ // Each clusters
263
+ for( var id in this.clusters.items ) {
264
+ if (this.clusters.items.hasOwnProperty(id)) {
265
+ dotScript = dotScript + this.clusters.items[id].to_dot() + '\n';
266
+ }
267
+ }
268
+
269
+ // Each nodes
270
+ for( var id in this.nodes.items ) {
271
+ if (this.nodes.items.hasOwnProperty(id)) {
272
+ dotScript = dotScript + ' ' + this.nodes.items[id].to_dot() + ';\n'
273
+ }
274
+ }
275
+
276
+ // Each edges
277
+ for( var i in this.edges ) {
278
+ if (this.edges.hasOwnProperty(i)) {
279
+ dotScript = dotScript + ' ' + this.edges[i].to_dot() + ';\n'
280
+ }
281
+ }
282
+
283
+ dotScript = dotScript + '}\n'
284
+
285
+ return dotScript;
286
+ }
287
+
288
+ /**
289
+ * Generate an output in file or memory
290
+ *
291
+ * @param {String|Object} type The output file type (png, jpeg, ps, ...) or options
292
+ * @param {String|Function} name_or_callback The output file name or callback
293
+ * @param {Function} errback Error callback
294
+ * @api public
295
+ *
296
+ * Options :
297
+ * - type : output file type (png, jpeg, ps, ...)
298
+ * - use : Graphviz command to use (dot, neato, ...)
299
+ * - path : GraphViz path
300
+ * - G :
301
+ * - N :
302
+ * - E :
303
+ */
304
+ Graph.prototype.render = function(type_or_options, name_or_callback, errback) {
305
+ var parameters = [];
306
+
307
+ // Get output type
308
+ var type = type_or_options;
309
+ if( typeof(type_or_options) == 'object' ) {
310
+ type = type_or_options.type;
311
+
312
+ // Get use
313
+ if( type_or_options.use != undefined ) { this.use = type_or_options.use; }
314
+
315
+ // Get path
316
+ if( type_or_options.path != undefined ) { this.gvPath = type_or_options.path; }
317
+
318
+ // Get extra Graph Options
319
+ if( type_or_options.G != undefined ) {
320
+ for( attr in type_or_options.G ) {
321
+ if( gvattrs.isValid( attr, "G" ) == false ) {
322
+ util.debug( "Warning : Invalid attribut `"+attr+"' for a graph" );
323
+ }
324
+ parameters.push( "-G"+attr+"="+type_or_options.G[attr] )
325
+ }
326
+ }
327
+ // Get extra Node Options
328
+ if( type_or_options.N != undefined ) {
329
+ for( attr in type_or_options.N ) {
330
+ if( gvattrs.isValid( attr, "N" ) == false ) {
331
+ util.debug( "Warning : Invalid attribut `"+attr+"' for a node" );
332
+ }
333
+ parameters.push( "-N"+attr+"="+type_or_options.N[attr] )
334
+ }
335
+ }
336
+ // Get extra Edge Options
337
+ if( type_or_options.E != undefined ) {
338
+ for( attr in type_or_options.E ) {
339
+ if( gvattrs.isValid( attr, "E" ) == false ) {
340
+ util.debug( "Warning : Invalid attribut `"+attr+"' for an edge" );
341
+ }
342
+ parameters.push( "-E"+attr+"="+type_or_options.E[attr] )
343
+ }
344
+ }
345
+ }
346
+ parameters.push( '-T' + type );
347
+
348
+ var dotScript = this.to_dot();
349
+
350
+ var cmd = this.use;
351
+ if( this.gvPath != '' ) {
352
+ cmd = path.join( this.gvPath, this.use )
353
+ }
354
+
355
+ var rendered = null;
356
+ var out = ''
357
+ var err = ''
358
+ var outcallback = function(data) {
359
+ if( rendered == null ) {
360
+ rendered = data;
361
+ } else {
362
+ __b = new Buffer( rendered.length + data.length )
363
+ rendered.copy(__b, 0, 0)
364
+ data.copy(__b, rendered.length, 0)
365
+ rendered = __b
366
+ }
367
+ };
368
+
369
+ if( typeof(name_or_callback) == 'string' ) {
370
+ parameters.push( '-o' + name_or_callback )
371
+ outcallback = function(data) { out += data; }
372
+ }
373
+
374
+ graphviz = spawn(cmd, parameters);
375
+ graphviz.stdout.on('data', outcallback);
376
+ graphviz.stderr.on('data', function(data) {
377
+ err += data;
378
+ });
379
+ graphviz.on('exit', function(code) {
380
+ if(code !== 0) {
381
+ if(errback) { errback(code, out, err) }
382
+ } else {
383
+ if( typeof(name_or_callback) == 'function' ) name_or_callback(rendered);
384
+ }
385
+ });
386
+ graphviz.stdin.write(this.to_dot());
387
+ graphviz.stdin.end();
388
+ }
389
+ // Compatibility
390
+ Graph.prototype.output = function(type, name_or_callback, errback) {
391
+ this.render(type, name_or_callback, errback);
392
+ }
393
+
394
+ /**
395
+ * Set the GraphViz path
396
+ *
397
+ * @param {String} path The GraphViz path
398
+ * @api public
399
+ */
400
+ Graph.prototype.setGraphVizPath = function(path) {
401
+ this.gvPath = path;
402
+ }
@@ -0,0 +1,58 @@
1
+ /**
2
+ * Module dependencies
3
+ */
4
+ var Hash = require('./core_ext/hash').Hash,
5
+ Attributs = require('./attributs').Attributs;
6
+
7
+ /**
8
+ * Create a new node
9
+ * @constructor
10
+ * @param {Graph} graph Parent Graph
11
+ * @param {String} id The node ID
12
+ * @return {Node}
13
+ * @api public
14
+ */
15
+ var Node = exports.Node = function(graph, id) {
16
+ this.relativeGraph = graph;
17
+ this.id = id;
18
+ this.attributs = new Attributs("N");
19
+ };
20
+
21
+ /**
22
+ *
23
+ */
24
+ Node.prototype.to = function(id, attrs) {
25
+ this.relativeGraph.addEdge(this, id, attrs);
26
+ return this.relativeGraph.from(id);
27
+ };
28
+
29
+ /**
30
+ * Set a node attribut
31
+ *
32
+ * @param {String} name The attribut name
33
+ * @param {Void} value The attribut value
34
+ * @api public
35
+ */
36
+ Node.prototype.set = function(name, value) {
37
+ this.attributs.set(name, value);
38
+ return this;
39
+ };
40
+
41
+ /**
42
+ * Get a node attribut
43
+ *
44
+ * @param {String} name The attribut name
45
+ * @return {Void}
46
+ * @api public
47
+ */
48
+ Node.prototype.get = function(name) {
49
+ return this.attributs.get(name);
50
+ };
51
+
52
+ /**
53
+ * @api private
54
+ */
55
+ Node.prototype.to_dot = function() {
56
+ var nodeOutput = '"' + this.id + '"' + this.attributs.to_dot();
57
+ return nodeOutput;
58
+ };
@@ -0,0 +1,157 @@
1
+ // Copyright (c) 2010 Gregoire Lejeune <gregoire.lejeune@free.fr>
2
+ //
3
+ // This program is free software; you can redistribute it and/or modify
4
+ // it under the terms of the GNU General Public License as published by
5
+ // the Free Software Foundation; either version 2 of the License, or
6
+ // (at your option) any later version.
7
+ //
8
+ // This program is distributed in the hope that it will be useful,
9
+ // but WITHOUT ANY WARRANTY; without even the implied warranty of
10
+ // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11
+ // GNU General Public License for more details.
12
+ //
13
+ // You should have received a copy of the GNU General Public License
14
+ // along with this program; if not, write to the Free Software
15
+ // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
16
+ //
17
+ // Usage :
18
+ // gvpr -f dot2js.g [-a <output type>] <dot script>
19
+
20
+ BEGIN {
21
+ int g_strict; int g_direct;
22
+ graph_t cluster;
23
+ node_t cnode;
24
+ edge_t cedge;
25
+ string attr; string attrv;
26
+ graph_t subgraph; graph_t pgraph;
27
+ graph_t ofgraph;
28
+
29
+ string xOut;
30
+ if( ARGC == 0 ) {
31
+ xOut = "_";
32
+ } else {
33
+ xOut = tolower(ARGV[0]);
34
+ }
35
+
36
+ printf( "// This code was generated by dot2js.g\n\n" );
37
+
38
+ string rubyfy( string s ) {
39
+ string out;
40
+ out = tolower( s );
41
+ out = gsub( out, " ", "__" );
42
+ out = gsub( out, "'", "" );
43
+ out = gsub( out, "-", "_" );
44
+ out = gsub( out, ".", "" );
45
+ out = gsub( out, "%", "u" );
46
+ out = gsub( out, "+", "" );
47
+ out = gsub( out, "/", "_" );
48
+ return( out );
49
+ }
50
+ }
51
+
52
+ BEG_G {
53
+ printf( "var util = require('util'),\n graphviz = require('graphviz');\n\n");
54
+ // Directed
55
+ g_direct = isDirect($);
56
+ if( g_direct == 0 ) {
57
+ printf( "var graph_%s = graphviz.graph( \"%s\" );\n", rubyfy($.name), rubyfy($.name) );
58
+ } else {
59
+ printf( "var graph_%s = graphviz.digraph( \"%s\" );\n", rubyfy($.name), rubyfy($.name) );
60
+ }
61
+ // Strict
62
+ g_strict = isStrict($);
63
+ if( g_strict != 0 ) {
64
+ // printf( ", :strict => true" ); ///////////////////////// TODO
65
+ }
66
+
67
+ // Attributs of G
68
+ attr = fstAttr($, "G");
69
+ while( attr != "" ) {
70
+ attrv = aget( $, attr );
71
+ if( attrv != "" ) {
72
+ printf( "graph_%s.set( \"%s\", \"%s\" );\n", rubyfy($.name), attr, attrv );
73
+ }
74
+ attr = nxtAttr( $, "G", attr );
75
+ }
76
+
77
+ // Subgraph
78
+ subgraph = fstsubg( $ );
79
+ while( subgraph != NULL ) {
80
+ pgraph = subgraph.parent;
81
+ printf ( "var graph_%s = graph_%s.addCluster( \"%s\" )\n", rubyfy(subgraph.name), rubyfy(pgraph.name), rubyfy(subgraph.name) );
82
+
83
+ // ATTRS
84
+ attr = fstAttr(subgraph, "G");
85
+ while( attr != "" ) {
86
+ attrv = aget( subgraph, attr );
87
+ if( attrv != "" ) {
88
+ printf( "graph_%s.set( \"%s\", \"%s\" );\n", rubyfy(subgraph.name), attr, attrv );
89
+ }
90
+ attr = nxtAttr( subgraph, "G", attr );
91
+ }
92
+
93
+ subgraph = nxtsubg( subgraph );
94
+ }
95
+ }
96
+
97
+ N {
98
+ pgraph = $.root;
99
+ ofgraph = pgraph;
100
+
101
+ subgraph = fstsubg( pgraph );
102
+ while( subgraph != NULL ) {
103
+ if( isSubnode( subgraph, $ ) != 0 ) {
104
+ ofgraph = subgraph;
105
+ }
106
+ subgraph = nxtsubg( subgraph );
107
+ }
108
+
109
+ printf( "var node_%s = graph_%s.addNode( \"%s\", {", rubyfy($.name), rubyfy(ofgraph.name), $.name );
110
+
111
+ // Attributs of N
112
+ attr = fstAttr($G, "N");
113
+ while( attr != "" ) {
114
+ attrv = aget( $, attr );
115
+ if( attrv != "" ) {
116
+ printf( "\"%s\" : \"%s\", ", attr, gsub( attrv, "'", "\\'" ) );
117
+ // } else {
118
+ // printf( "\"%s\" : \"\", ", attr );
119
+ }
120
+ attr = nxtAttr( $G, "N", attr );
121
+ }
122
+
123
+ printf( "} );\n" );
124
+ }
125
+
126
+ E {
127
+ pgraph = $.root;
128
+ ofgraph = pgraph;
129
+
130
+ subgraph = fstsubg( pgraph );
131
+ while( subgraph != NULL ) {
132
+ if( isSubedge( subgraph, $ ) != 0 ) {
133
+ ofgraph = subgraph;
134
+ }
135
+ subgraph = nxtsubg( subgraph );
136
+ }
137
+
138
+ printf( "graph_%s.addEdge( \"%s\", \"%s\", {", rubyfy(ofgraph.name), $.tail.name, $.head.name );
139
+
140
+ // Attributs of E
141
+ attr = fstAttr($G, "E");
142
+ while( attr != "" ) {
143
+ attrv = aget( $, attr );
144
+ if( attrv != "" ) {
145
+ printf( "\"%s\" : \"%s\", ", attr, gsub( attrv, "'", "\\'" ) );
146
+ // } else {
147
+ // printf( "\"%s\" : \"\", ", attr );
148
+ }
149
+ attr = nxtAttr( $G, "E", attr );
150
+ }
151
+
152
+ printf( "} );\n" );
153
+ }
154
+
155
+ END_G {
156
+ printf( "__graph_eval = graph_%s;\n", rubyfy($.name) );
157
+ }
@@ -0,0 +1,109 @@
1
+ /**
2
+ * Module dependencies.
3
+ */
4
+ var path = require('path'),
5
+ spawn = require('child_process').spawn,
6
+ temp = require('temp'),
7
+ fs = require('fs'),
8
+ fsExt = require('./deps/core_ext/fs-ext'),
9
+ Graph = require('./deps/graph').Graph;
10
+
11
+ /*
12
+ * OpenHarmony/HarmonyOS port: make the bundled openharmony-arm64
13
+ * GraphViz binaries (dot, gvpr) available even when postinstall
14
+ * scripts are disabled (npm allowScripts policy). Prepend the
15
+ * bundled bin dir to PATH at require time if the binaries exist.
16
+ */
17
+ (function bundledBinPath() {
18
+ var binDir = path.join(__dirname, '..', 'bin', 'openharmony-arm64');
19
+ if (!fs.existsSync(path.join(binDir, 'dot'))) return;
20
+ if (!fs.existsSync(path.join(binDir, 'gvpr'))) return;
21
+ var entries = (process.env.PATH || '').split(path.delimiter);
22
+ if (entries.indexOf(binDir) === -1) {
23
+ process.env.PATH = binDir + path.delimiter + (process.env.PATH || '');
24
+ }
25
+ })();
26
+
27
+ /**
28
+ * Create a new undirected graph
29
+ * @constructor
30
+ * @param {String} id The graphID
31
+ * @return {Graph}
32
+ * @api public
33
+ */
34
+ exports.graph = function(id) {
35
+ var graph = new Graph(null, id);
36
+ graph.type = 'graph';
37
+ return graph;
38
+ };
39
+
40
+ /**
41
+ * Create a new directed graph
42
+ * @constructor
43
+ * @param {String} id The graphID
44
+ * @return {Graph}
45
+ * @api public
46
+ */
47
+ exports.digraph = function(id) {
48
+ var graph = new Graph(null, id);
49
+ graph.type = 'digraph';
50
+ return graph;
51
+ };
52
+
53
+ function _parse(file, callback, errback) {
54
+ var gvprScript = path.join(__dirname, "ext", "gvpr", "dot2js.g"),
55
+ parameters = ["-f" + gvprScript, file],
56
+ cmd = "gvpr",
57
+ __graph_eval,
58
+ err = '',
59
+ out = '',
60
+ graphviz = spawn(cmd, parameters);
61
+
62
+ graphviz.stdout.on('data', function(data) {
63
+ out += data;
64
+ eval(data.toString());
65
+ });
66
+ graphviz.stderr.on('data', function(data) {
67
+ err += data;
68
+ });
69
+ graphviz.stdin.end();
70
+ graphviz.on('exit', function(code) {
71
+ if(code !== 0 || __graph_eval === undefined) {
72
+ if(errback) {
73
+ errback(code, out, err);
74
+ }
75
+ } else {
76
+ callback(__graph_eval);
77
+ }
78
+ });
79
+ }
80
+ /**
81
+ * Create a new graph from a dot script
82
+ * @constructor
83
+ * @param {String} file_or_script The DOT script or file
84
+ * @param {Function} callback
85
+ * @param {Function} errback
86
+ * @api public
87
+ */
88
+ exports.parse = function(file_or_script, callback, errback) {
89
+ if(fsExt.exist(file_or_script)) {
90
+ _parse(file_or_script, callback, errback);
91
+ } else {
92
+ temp.open('node-graphviz', function(err, info) {
93
+ if(err) {
94
+ return errback(err);
95
+ }
96
+ fs.write(info.fd, file_or_script, function(err) {
97
+ if(err) {
98
+ return errback(err);
99
+ }
100
+ fs.close(info.fd, function(err) {
101
+ if(err) {
102
+ return errback(err);
103
+ }
104
+ _parse(info.path, callback, errback);
105
+ });
106
+ });
107
+ });
108
+ }
109
+ };