ts-graphviz 1.0.0 → 1.0.1
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.
- package/README.ja.md +14 -7
- package/README.md +14 -7
- package/lib/ast/index.cjs +543 -527
- package/lib/ast/index.d.ts +215 -49
- package/lib/ast/index.js +543 -527
- package/lib/common/index.cjs +8 -0
- package/lib/common/index.d.ts +195 -6
- package/lib/common/index.js +8 -0
- package/lib/core/index.cjs +58 -113
- package/lib/core/index.d.ts +64 -347
- package/lib/core/index.js +58 -113
- package/package.json +3 -3
package/lib/ast/index.cjs
CHANGED
|
@@ -5,8 +5,12 @@ Object.defineProperty(exports, '__esModule', { value: true });
|
|
|
5
5
|
var utils = require('#lib/utils');
|
|
6
6
|
var common = require('#lib/common');
|
|
7
7
|
|
|
8
|
+
/**
|
|
9
|
+
* @group Create AST
|
|
10
|
+
*/
|
|
8
11
|
class Builder {
|
|
9
12
|
options;
|
|
13
|
+
/** @internal */
|
|
10
14
|
getLocation() {
|
|
11
15
|
return this.options?.locationFunction?.() ?? null;
|
|
12
16
|
}
|
|
@@ -24,6 +28,11 @@ class Builder {
|
|
|
24
28
|
}
|
|
25
29
|
}
|
|
26
30
|
|
|
31
|
+
/**
|
|
32
|
+
* @group Create AST
|
|
33
|
+
*/
|
|
34
|
+
const createElement = Builder.prototype.createElement.bind(new Builder());
|
|
35
|
+
|
|
27
36
|
const EOL = /\r?\n/;
|
|
28
37
|
function joinBy(sep) {
|
|
29
38
|
return (value) => value.join(sep);
|
|
@@ -258,16 +267,16 @@ const defaultPlugins$1 = [
|
|
|
258
267
|
SubgraphPrintPlugin,
|
|
259
268
|
];
|
|
260
269
|
|
|
270
|
+
/**
|
|
271
|
+
* @group Convert AST to DOT
|
|
272
|
+
*/
|
|
261
273
|
class Printer {
|
|
262
274
|
options;
|
|
275
|
+
/** @internal */
|
|
263
276
|
#plugins = [...defaultPlugins$1];
|
|
264
277
|
constructor(options = {}) {
|
|
265
278
|
this.options = options;
|
|
266
279
|
}
|
|
267
|
-
use(plugin) {
|
|
268
|
-
this.#plugins.unshift(plugin);
|
|
269
|
-
return this;
|
|
270
|
-
}
|
|
271
280
|
print(ast) {
|
|
272
281
|
const plugins = [...this.#plugins];
|
|
273
282
|
const { indentSize = 2, indentStyle = 'space', endOfLine = 'lf' } = this.options;
|
|
@@ -289,547 +298,266 @@ class Printer {
|
|
|
289
298
|
}
|
|
290
299
|
}
|
|
291
300
|
|
|
292
|
-
|
|
293
|
-
|
|
294
|
-
|
|
295
|
-
|
|
296
|
-
|
|
297
|
-
|
|
298
|
-
|
|
299
|
-
|
|
300
|
-
|
|
301
|
-
|
|
302
|
-
|
|
303
|
-
value: createElement('Literal', { value: trimmed.slice(1, trimmed.length - 1), quoted: 'html' }, []),
|
|
304
|
-
},
|
|
305
|
-
[],
|
|
306
|
-
);
|
|
307
|
-
} else {
|
|
308
|
-
return createElement(
|
|
309
|
-
'Attribute',
|
|
310
|
-
{
|
|
311
|
-
key: createElement('Literal', { value: key, quoted: false }, []),
|
|
312
|
-
value: createElement('Literal', { value: value, quoted: true }, []),
|
|
313
|
-
},
|
|
314
|
-
[],
|
|
315
|
-
);
|
|
316
|
-
}
|
|
301
|
+
/**
|
|
302
|
+
* Stringify Graphviz AST Node.
|
|
303
|
+
*
|
|
304
|
+
* @param ast Graphviz AST node.
|
|
305
|
+
* @returns DOT language string.
|
|
306
|
+
* @group Convert AST to DOT
|
|
307
|
+
*/
|
|
308
|
+
function stringify(ast, options) {
|
|
309
|
+
const result = new Printer(options).print(ast);
|
|
310
|
+
if (!result) {
|
|
311
|
+
throw new Error();
|
|
317
312
|
}
|
|
318
|
-
return
|
|
319
|
-
'Attribute',
|
|
320
|
-
{
|
|
321
|
-
key: createElement('Literal', { value: key, quoted: false }, []),
|
|
322
|
-
value: createElement('Literal', { value: String(value), quoted: false }, []),
|
|
323
|
-
},
|
|
324
|
-
[],
|
|
325
|
-
);
|
|
313
|
+
return result;
|
|
326
314
|
}
|
|
327
315
|
|
|
328
|
-
|
|
329
|
-
|
|
330
|
-
|
|
331
|
-
|
|
332
|
-
|
|
333
|
-
|
|
334
|
-
|
|
335
|
-
|
|
336
|
-
);
|
|
316
|
+
/* eslint-disable */
|
|
317
|
+
function peg$padEnd(str, targetLength, padString) {
|
|
318
|
+
padString = padString || ' ';
|
|
319
|
+
if (str.length > targetLength) {
|
|
320
|
+
return str;
|
|
321
|
+
}
|
|
322
|
+
targetLength -= str.length;
|
|
323
|
+
padString += padString.repeat(targetLength);
|
|
324
|
+
return str + padString.slice(0, targetLength);
|
|
337
325
|
}
|
|
338
|
-
|
|
339
|
-
|
|
340
|
-
|
|
341
|
-
|
|
342
|
-
|
|
343
|
-
|
|
326
|
+
class SyntaxError$1 extends Error {
|
|
327
|
+
static buildMessage(expected, found) {
|
|
328
|
+
function hex(ch) {
|
|
329
|
+
return ch.charCodeAt(0).toString(16).toUpperCase();
|
|
330
|
+
}
|
|
331
|
+
function literalEscape(s) {
|
|
332
|
+
return s
|
|
333
|
+
.replace(/\\/g, '\\\\')
|
|
334
|
+
.replace(/"/g, '\\"')
|
|
335
|
+
.replace(/\0/g, '\\0')
|
|
336
|
+
.replace(/\t/g, '\\t')
|
|
337
|
+
.replace(/\n/g, '\\n')
|
|
338
|
+
.replace(/\r/g, '\\r')
|
|
339
|
+
.replace(/[\x00-\x0F]/g, (ch) => '\\x0' + hex(ch))
|
|
340
|
+
.replace(/[\x10-\x1F\x7F-\x9F]/g, (ch) => '\\x' + hex(ch));
|
|
341
|
+
}
|
|
342
|
+
function classEscape(s) {
|
|
343
|
+
return s
|
|
344
|
+
.replace(/\\/g, '\\\\')
|
|
345
|
+
.replace(/\]/g, '\\]')
|
|
346
|
+
.replace(/\^/g, '\\^')
|
|
347
|
+
.replace(/-/g, '\\-')
|
|
348
|
+
.replace(/\0/g, '\\0')
|
|
349
|
+
.replace(/\t/g, '\\t')
|
|
350
|
+
.replace(/\n/g, '\\n')
|
|
351
|
+
.replace(/\r/g, '\\r')
|
|
352
|
+
.replace(/[\x00-\x0F]/g, (ch) => '\\x0' + hex(ch))
|
|
353
|
+
.replace(/[\x10-\x1F\x7F-\x9F]/g, (ch) => '\\x' + hex(ch));
|
|
354
|
+
}
|
|
355
|
+
function describeExpectation(expectation) {
|
|
356
|
+
switch (expectation.type) {
|
|
357
|
+
case 'literal':
|
|
358
|
+
return '"' + literalEscape(expectation.text) + '"';
|
|
359
|
+
case 'class':
|
|
360
|
+
const escapedParts = expectation.parts.map((part) => {
|
|
361
|
+
return Array.isArray(part) ? classEscape(part[0]) + '-' + classEscape(part[1]) : classEscape(part);
|
|
362
|
+
});
|
|
363
|
+
return '[' + (expectation.inverted ? '^' : '') + escapedParts + ']';
|
|
364
|
+
case 'any':
|
|
365
|
+
return 'any character';
|
|
366
|
+
case 'end':
|
|
367
|
+
return 'end of input';
|
|
368
|
+
case 'other':
|
|
369
|
+
return expectation.description;
|
|
344
370
|
}
|
|
345
|
-
|
|
346
|
-
|
|
347
|
-
|
|
348
|
-
|
|
371
|
+
}
|
|
372
|
+
function describeExpected(expected1) {
|
|
373
|
+
const descriptions = expected1.map(describeExpectation);
|
|
374
|
+
let i;
|
|
375
|
+
let j;
|
|
376
|
+
descriptions.sort();
|
|
377
|
+
if (descriptions.length > 0) {
|
|
378
|
+
for (i = 1, j = 1; i < descriptions.length; i++) {
|
|
379
|
+
if (descriptions[i - 1] !== descriptions[i]) {
|
|
380
|
+
descriptions[j] = descriptions[i];
|
|
381
|
+
j++;
|
|
349
382
|
}
|
|
350
|
-
yield context.convert(attrs);
|
|
351
383
|
}
|
|
384
|
+
descriptions.length = j;
|
|
352
385
|
}
|
|
353
|
-
|
|
354
|
-
|
|
355
|
-
|
|
356
|
-
|
|
357
|
-
|
|
386
|
+
switch (descriptions.length) {
|
|
387
|
+
case 1:
|
|
388
|
+
return descriptions[0];
|
|
389
|
+
case 2:
|
|
390
|
+
return descriptions[0] + ' or ' + descriptions[1];
|
|
391
|
+
default:
|
|
392
|
+
return descriptions.slice(0, -1).join(', ') + ', or ' + descriptions[descriptions.length - 1];
|
|
358
393
|
}
|
|
359
|
-
|
|
360
|
-
|
|
361
|
-
|
|
394
|
+
}
|
|
395
|
+
function describeFound(found1) {
|
|
396
|
+
return found1 ? '"' + literalEscape(found1) + '"' : 'end of input';
|
|
397
|
+
}
|
|
398
|
+
return 'Expected ' + describeExpected(expected) + ' but ' + describeFound(found) + ' found.';
|
|
399
|
+
}
|
|
400
|
+
message;
|
|
401
|
+
expected;
|
|
402
|
+
found;
|
|
403
|
+
location;
|
|
404
|
+
name;
|
|
405
|
+
constructor(message, expected, found, location) {
|
|
406
|
+
super();
|
|
407
|
+
this.message = message;
|
|
408
|
+
this.expected = expected;
|
|
409
|
+
this.found = found;
|
|
410
|
+
this.location = location;
|
|
411
|
+
this.name = 'SyntaxError';
|
|
412
|
+
if (typeof Object.setPrototypeOf === 'function') {
|
|
413
|
+
Object.setPrototypeOf(this, SyntaxError$1.prototype);
|
|
414
|
+
} else {
|
|
415
|
+
this.__proto__ = SyntaxError$1.prototype;
|
|
416
|
+
}
|
|
417
|
+
if (typeof Error.captureStackTrace === 'function') {
|
|
418
|
+
Error.captureStackTrace(this, SyntaxError$1);
|
|
419
|
+
}
|
|
420
|
+
}
|
|
421
|
+
format(sources) {
|
|
422
|
+
let str = 'Error: ' + this.message;
|
|
423
|
+
if (this.location) {
|
|
424
|
+
let src = null;
|
|
425
|
+
let k;
|
|
426
|
+
for (k = 0; k < sources.length; k++) {
|
|
427
|
+
if (sources[k].source === this.location.source) {
|
|
428
|
+
src = sources[k].text.split(/\r\n|\n|\r/g);
|
|
429
|
+
break;
|
|
362
430
|
}
|
|
363
|
-
yield context.convert(subgraph);
|
|
364
431
|
}
|
|
365
|
-
|
|
366
|
-
|
|
367
|
-
|
|
368
|
-
|
|
369
|
-
|
|
432
|
+
let s = this.location.start;
|
|
433
|
+
let loc = this.location.source + ':' + s.line + ':' + s.column;
|
|
434
|
+
if (src) {
|
|
435
|
+
let e = this.location.end;
|
|
436
|
+
let filler = peg$padEnd('', s.line.toString().length, ' ');
|
|
437
|
+
let line = src[s.line - 1];
|
|
438
|
+
let last = s.line === e.line ? e.column : line.length + 1;
|
|
439
|
+
str +=
|
|
440
|
+
'\n --> ' +
|
|
441
|
+
loc +
|
|
442
|
+
'\n' +
|
|
443
|
+
filler +
|
|
444
|
+
' |\n' +
|
|
445
|
+
s.line +
|
|
446
|
+
' | ' +
|
|
447
|
+
line +
|
|
448
|
+
'\n' +
|
|
449
|
+
filler +
|
|
450
|
+
' | ' +
|
|
451
|
+
peg$padEnd('', s.column - 1, ' ') +
|
|
452
|
+
peg$padEnd('', last - s.column, '^');
|
|
453
|
+
} else {
|
|
454
|
+
str += '\n at ' + loc;
|
|
370
455
|
}
|
|
371
|
-
}
|
|
372
|
-
|
|
456
|
+
}
|
|
457
|
+
return str;
|
|
458
|
+
}
|
|
373
459
|
}
|
|
374
|
-
|
|
375
|
-
|
|
376
|
-
|
|
377
|
-
|
|
378
|
-
|
|
379
|
-
|
|
380
|
-
|
|
381
|
-
|
|
382
|
-
|
|
383
|
-
|
|
384
|
-
|
|
385
|
-
|
|
386
|
-
|
|
387
|
-
}
|
|
388
|
-
|
|
389
|
-
|
|
390
|
-
|
|
391
|
-
|
|
392
|
-
|
|
393
|
-
|
|
394
|
-
|
|
395
|
-
|
|
396
|
-
|
|
397
|
-
|
|
398
|
-
|
|
399
|
-
|
|
400
|
-
|
|
401
|
-
|
|
402
|
-
|
|
403
|
-
|
|
404
|
-
|
|
405
|
-
|
|
406
|
-
|
|
407
|
-
|
|
408
|
-
|
|
409
|
-
|
|
410
|
-
|
|
411
|
-
|
|
412
|
-
|
|
413
|
-
|
|
414
|
-
|
|
415
|
-
|
|
416
|
-
|
|
417
|
-
|
|
418
|
-
|
|
419
|
-
|
|
420
|
-
|
|
421
|
-
|
|
422
|
-
|
|
423
|
-
|
|
424
|
-
|
|
425
|
-
|
|
426
|
-
|
|
427
|
-
? createElement(
|
|
428
|
-
'Literal',
|
|
429
|
-
{
|
|
430
|
-
value: target.port,
|
|
431
|
-
quoted: true,
|
|
432
|
-
},
|
|
433
|
-
[],
|
|
434
|
-
)
|
|
435
|
-
: undefined,
|
|
436
|
-
compass: target.compass
|
|
437
|
-
? createElement(
|
|
438
|
-
'Literal',
|
|
439
|
-
{
|
|
440
|
-
value: target.compass,
|
|
441
|
-
quoted: true,
|
|
442
|
-
},
|
|
443
|
-
[],
|
|
444
|
-
)
|
|
445
|
-
: undefined,
|
|
446
|
-
},
|
|
447
|
-
[],
|
|
448
|
-
);
|
|
460
|
+
function peg$parse(input, options) {
|
|
461
|
+
options = options !== undefined ? options : {};
|
|
462
|
+
const peg$FAILED = {};
|
|
463
|
+
const peg$source = options.grammarSource;
|
|
464
|
+
const peg$startRuleFunctions = {
|
|
465
|
+
Dot: peg$parseDot,
|
|
466
|
+
Graph: peg$parseGraph,
|
|
467
|
+
Subgraph: peg$parseSubgraph,
|
|
468
|
+
Node: peg$parseNode,
|
|
469
|
+
Edge: peg$parseEdge,
|
|
470
|
+
AttributeList: peg$parseAttributeList,
|
|
471
|
+
Attribute: peg$parseAttribute,
|
|
472
|
+
ClusterStatements: peg$parseClusterStatements,
|
|
473
|
+
};
|
|
474
|
+
let peg$startRuleFunction = peg$parseDot;
|
|
475
|
+
const peg$c0 = function (v) {
|
|
476
|
+
return v;
|
|
477
|
+
};
|
|
478
|
+
const peg$c1 = function (c1, graph, c2) {
|
|
479
|
+
return b.createElement('Dot', {}, [...c1, graph, ...c2]);
|
|
480
|
+
};
|
|
481
|
+
const peg$c2 = 'strict';
|
|
482
|
+
const peg$c3 = peg$literalExpectation('strict', true);
|
|
483
|
+
const peg$c4 = 'graph';
|
|
484
|
+
const peg$c5 = peg$literalExpectation('graph', true);
|
|
485
|
+
const peg$c6 = 'digraph';
|
|
486
|
+
const peg$c7 = peg$literalExpectation('digraph', true);
|
|
487
|
+
const peg$c8 = '{';
|
|
488
|
+
const peg$c9 = peg$literalExpectation('{', false);
|
|
489
|
+
const peg$c10 = '}';
|
|
490
|
+
const peg$c11 = peg$literalExpectation('}', false);
|
|
491
|
+
const peg$c12 = function (_strict, _kind, id, children) {
|
|
492
|
+
const strict = !!_strict;
|
|
493
|
+
const kind = _kind.toLowerCase();
|
|
494
|
+
const directed = kind === 'digraph';
|
|
495
|
+
for (const edgeop of edgeops) {
|
|
496
|
+
if (directed) {
|
|
497
|
+
if (edgeop.operator !== '->') {
|
|
498
|
+
error(`In digraph, it's necessary to describe with "->" operator to create edge.`, edgeop.location);
|
|
499
|
+
}
|
|
500
|
+
} else {
|
|
501
|
+
if (edgeop.operator !== '--') {
|
|
502
|
+
error(`In graph, it's necessary to describe with "--" operator to create edge.`, edgeop.location);
|
|
503
|
+
}
|
|
504
|
+
}
|
|
505
|
+
}
|
|
506
|
+
return b.createElement(
|
|
507
|
+
'Graph',
|
|
508
|
+
id !== null
|
|
509
|
+
? {
|
|
510
|
+
id,
|
|
511
|
+
directed,
|
|
512
|
+
strict,
|
|
449
513
|
}
|
|
450
|
-
|
|
514
|
+
: {
|
|
515
|
+
directed,
|
|
516
|
+
strict,
|
|
517
|
+
},
|
|
518
|
+
children,
|
|
519
|
+
);
|
|
520
|
+
};
|
|
521
|
+
const peg$c13 = ';';
|
|
522
|
+
const peg$c14 = peg$literalExpectation(';', false);
|
|
523
|
+
const peg$c15 = function (keyValue) {
|
|
524
|
+
return b.createElement(
|
|
525
|
+
'Attribute',
|
|
526
|
+
{
|
|
527
|
+
...keyValue,
|
|
451
528
|
},
|
|
452
|
-
[
|
|
453
|
-
...(model.attributes.comment ? [convertComment(model.attributes.comment, context.commentKind)] : []),
|
|
454
|
-
...model.attributes.values.map(([key, value]) => convertAttribute(key, value)),
|
|
455
|
-
],
|
|
529
|
+
[],
|
|
456
530
|
);
|
|
457
|
-
}
|
|
458
|
-
|
|
459
|
-
|
|
460
|
-
const
|
|
461
|
-
|
|
462
|
-
|
|
463
|
-
|
|
464
|
-
|
|
465
|
-
return createElement('Dot', {}, [
|
|
466
|
-
...(model.comment ? [convertComment(model.comment, context.commentKind)] : []),
|
|
467
|
-
createElement(
|
|
468
|
-
'Graph',
|
|
469
|
-
{
|
|
470
|
-
directed: model.directed,
|
|
471
|
-
strict: model.strict,
|
|
472
|
-
id: model.id
|
|
473
|
-
? createElement(
|
|
474
|
-
'Literal',
|
|
475
|
-
{
|
|
476
|
-
value: model.id,
|
|
477
|
-
quoted: true,
|
|
478
|
-
},
|
|
479
|
-
[],
|
|
480
|
-
)
|
|
481
|
-
: undefined,
|
|
482
|
-
},
|
|
483
|
-
convertClusterChildren(context, model),
|
|
484
|
-
),
|
|
485
|
-
]);
|
|
486
|
-
},
|
|
487
|
-
};
|
|
488
|
-
|
|
489
|
-
const NodeConvertPlugin = {
|
|
490
|
-
match(model) {
|
|
491
|
-
return model.$$type === 'Node';
|
|
492
|
-
},
|
|
493
|
-
convert(context, model) {
|
|
494
|
-
return createElement(
|
|
495
|
-
'Node',
|
|
531
|
+
};
|
|
532
|
+
const peg$c16 = 'node';
|
|
533
|
+
const peg$c17 = peg$literalExpectation('node', true);
|
|
534
|
+
const peg$c18 = 'edge';
|
|
535
|
+
const peg$c19 = peg$literalExpectation('edge', true);
|
|
536
|
+
const peg$c20 = function (_kind, children) {
|
|
537
|
+
return b.createElement(
|
|
538
|
+
'AttributeList',
|
|
496
539
|
{
|
|
497
|
-
|
|
498
|
-
'Literal',
|
|
499
|
-
{
|
|
500
|
-
value: model.id,
|
|
501
|
-
quoted: true,
|
|
502
|
-
},
|
|
503
|
-
[],
|
|
504
|
-
),
|
|
540
|
+
kind: _kind.toLowerCase(),
|
|
505
541
|
},
|
|
506
|
-
|
|
507
|
-
...(model.attributes.comment ? [convertComment(model.attributes.comment, context.commentKind)] : []),
|
|
508
|
-
...model.attributes.values.map(([key, value]) => convertAttribute(key, value)),
|
|
509
|
-
],
|
|
542
|
+
children,
|
|
510
543
|
);
|
|
511
|
-
}
|
|
512
|
-
|
|
513
|
-
|
|
514
|
-
|
|
515
|
-
|
|
516
|
-
|
|
517
|
-
},
|
|
518
|
-
convert(context, model) {
|
|
519
|
-
return createElement(
|
|
520
|
-
'Subgraph',
|
|
544
|
+
};
|
|
545
|
+
const peg$c21 = function (id, rhs, _children) {
|
|
546
|
+
// @ts-ignore
|
|
547
|
+
return b.createElement(
|
|
548
|
+
// @ts-ignore
|
|
549
|
+
'Edge',
|
|
521
550
|
{
|
|
522
|
-
|
|
523
|
-
? createElement(
|
|
524
|
-
'Literal',
|
|
525
|
-
{
|
|
526
|
-
value: model.id,
|
|
527
|
-
quoted: true,
|
|
528
|
-
},
|
|
529
|
-
[],
|
|
530
|
-
)
|
|
531
|
-
: undefined,
|
|
551
|
+
targets: [id, ...rhs],
|
|
532
552
|
},
|
|
533
|
-
|
|
553
|
+
_children ?? [],
|
|
534
554
|
);
|
|
535
|
-
}
|
|
536
|
-
|
|
537
|
-
|
|
538
|
-
|
|
539
|
-
|
|
540
|
-
|
|
541
|
-
NodeConvertPlugin,
|
|
542
|
-
GraphConvertPlugin,
|
|
543
|
-
SubgraphConvertPlugin,
|
|
544
|
-
];
|
|
545
|
-
|
|
546
|
-
class Converter {
|
|
547
|
-
options;
|
|
548
|
-
#plugins = [...defaultPlugins];
|
|
549
|
-
constructor(options = {}) {
|
|
550
|
-
this.options = options;
|
|
551
|
-
}
|
|
552
|
-
use(plugin) {
|
|
553
|
-
this.#plugins.unshift(plugin);
|
|
554
|
-
return this;
|
|
555
|
-
}
|
|
556
|
-
convert(model) {
|
|
557
|
-
const plugins = [...this.#plugins];
|
|
558
|
-
const { commentKind = 'Slash' } = this.options;
|
|
559
|
-
const context = {
|
|
560
|
-
commentKind,
|
|
561
|
-
convert(m) {
|
|
562
|
-
for (const plugin of plugins) {
|
|
563
|
-
if (plugin.match(m)) {
|
|
564
|
-
return plugin.convert(context, m);
|
|
565
|
-
}
|
|
566
|
-
}
|
|
567
|
-
throw Error();
|
|
568
|
-
},
|
|
569
|
-
};
|
|
570
|
-
return context.convert(model);
|
|
571
|
-
}
|
|
572
|
-
}
|
|
573
|
-
|
|
574
|
-
/**
|
|
575
|
-
* Stringify Graphviz AST Node.
|
|
576
|
-
*
|
|
577
|
-
* @param ast Graphviz AST node.
|
|
578
|
-
* @returns DOT language string.
|
|
579
|
-
*/
|
|
580
|
-
function stringify(ast, options) {
|
|
581
|
-
const result = new Printer(options).print(ast);
|
|
582
|
-
if (!result) {
|
|
583
|
-
throw new Error();
|
|
584
|
-
}
|
|
585
|
-
return result;
|
|
586
|
-
}
|
|
587
|
-
|
|
588
|
-
/* eslint-disable */
|
|
589
|
-
function peg$padEnd(str, targetLength, padString) {
|
|
590
|
-
padString = padString || ' ';
|
|
591
|
-
if (str.length > targetLength) {
|
|
592
|
-
return str;
|
|
593
|
-
}
|
|
594
|
-
targetLength -= str.length;
|
|
595
|
-
padString += padString.repeat(targetLength);
|
|
596
|
-
return str + padString.slice(0, targetLength);
|
|
597
|
-
}
|
|
598
|
-
class SyntaxError extends Error {
|
|
599
|
-
static buildMessage(expected, found) {
|
|
600
|
-
function hex(ch) {
|
|
601
|
-
return ch.charCodeAt(0).toString(16).toUpperCase();
|
|
602
|
-
}
|
|
603
|
-
function literalEscape(s) {
|
|
604
|
-
return s
|
|
605
|
-
.replace(/\\/g, '\\\\')
|
|
606
|
-
.replace(/"/g, '\\"')
|
|
607
|
-
.replace(/\0/g, '\\0')
|
|
608
|
-
.replace(/\t/g, '\\t')
|
|
609
|
-
.replace(/\n/g, '\\n')
|
|
610
|
-
.replace(/\r/g, '\\r')
|
|
611
|
-
.replace(/[\x00-\x0F]/g, (ch) => '\\x0' + hex(ch))
|
|
612
|
-
.replace(/[\x10-\x1F\x7F-\x9F]/g, (ch) => '\\x' + hex(ch));
|
|
613
|
-
}
|
|
614
|
-
function classEscape(s) {
|
|
615
|
-
return s
|
|
616
|
-
.replace(/\\/g, '\\\\')
|
|
617
|
-
.replace(/\]/g, '\\]')
|
|
618
|
-
.replace(/\^/g, '\\^')
|
|
619
|
-
.replace(/-/g, '\\-')
|
|
620
|
-
.replace(/\0/g, '\\0')
|
|
621
|
-
.replace(/\t/g, '\\t')
|
|
622
|
-
.replace(/\n/g, '\\n')
|
|
623
|
-
.replace(/\r/g, '\\r')
|
|
624
|
-
.replace(/[\x00-\x0F]/g, (ch) => '\\x0' + hex(ch))
|
|
625
|
-
.replace(/[\x10-\x1F\x7F-\x9F]/g, (ch) => '\\x' + hex(ch));
|
|
626
|
-
}
|
|
627
|
-
function describeExpectation(expectation) {
|
|
628
|
-
switch (expectation.type) {
|
|
629
|
-
case 'literal':
|
|
630
|
-
return '"' + literalEscape(expectation.text) + '"';
|
|
631
|
-
case 'class':
|
|
632
|
-
const escapedParts = expectation.parts.map((part) => {
|
|
633
|
-
return Array.isArray(part) ? classEscape(part[0]) + '-' + classEscape(part[1]) : classEscape(part);
|
|
634
|
-
});
|
|
635
|
-
return '[' + (expectation.inverted ? '^' : '') + escapedParts + ']';
|
|
636
|
-
case 'any':
|
|
637
|
-
return 'any character';
|
|
638
|
-
case 'end':
|
|
639
|
-
return 'end of input';
|
|
640
|
-
case 'other':
|
|
641
|
-
return expectation.description;
|
|
642
|
-
}
|
|
643
|
-
}
|
|
644
|
-
function describeExpected(expected1) {
|
|
645
|
-
const descriptions = expected1.map(describeExpectation);
|
|
646
|
-
let i;
|
|
647
|
-
let j;
|
|
648
|
-
descriptions.sort();
|
|
649
|
-
if (descriptions.length > 0) {
|
|
650
|
-
for (i = 1, j = 1; i < descriptions.length; i++) {
|
|
651
|
-
if (descriptions[i - 1] !== descriptions[i]) {
|
|
652
|
-
descriptions[j] = descriptions[i];
|
|
653
|
-
j++;
|
|
654
|
-
}
|
|
655
|
-
}
|
|
656
|
-
descriptions.length = j;
|
|
657
|
-
}
|
|
658
|
-
switch (descriptions.length) {
|
|
659
|
-
case 1:
|
|
660
|
-
return descriptions[0];
|
|
661
|
-
case 2:
|
|
662
|
-
return descriptions[0] + ' or ' + descriptions[1];
|
|
663
|
-
default:
|
|
664
|
-
return descriptions.slice(0, -1).join(', ') + ', or ' + descriptions[descriptions.length - 1];
|
|
665
|
-
}
|
|
666
|
-
}
|
|
667
|
-
function describeFound(found1) {
|
|
668
|
-
return found1 ? '"' + literalEscape(found1) + '"' : 'end of input';
|
|
669
|
-
}
|
|
670
|
-
return 'Expected ' + describeExpected(expected) + ' but ' + describeFound(found) + ' found.';
|
|
671
|
-
}
|
|
672
|
-
message;
|
|
673
|
-
expected;
|
|
674
|
-
found;
|
|
675
|
-
location;
|
|
676
|
-
name;
|
|
677
|
-
constructor(message, expected, found, location) {
|
|
678
|
-
super();
|
|
679
|
-
this.message = message;
|
|
680
|
-
this.expected = expected;
|
|
681
|
-
this.found = found;
|
|
682
|
-
this.location = location;
|
|
683
|
-
this.name = 'SyntaxError';
|
|
684
|
-
if (typeof Object.setPrototypeOf === 'function') {
|
|
685
|
-
Object.setPrototypeOf(this, SyntaxError.prototype);
|
|
686
|
-
} else {
|
|
687
|
-
this.__proto__ = SyntaxError.prototype;
|
|
688
|
-
}
|
|
689
|
-
if (typeof Error.captureStackTrace === 'function') {
|
|
690
|
-
Error.captureStackTrace(this, SyntaxError);
|
|
691
|
-
}
|
|
692
|
-
}
|
|
693
|
-
format(sources) {
|
|
694
|
-
let str = 'Error: ' + this.message;
|
|
695
|
-
if (this.location) {
|
|
696
|
-
let src = null;
|
|
697
|
-
let k;
|
|
698
|
-
for (k = 0; k < sources.length; k++) {
|
|
699
|
-
if (sources[k].source === this.location.source) {
|
|
700
|
-
src = sources[k].text.split(/\r\n|\n|\r/g);
|
|
701
|
-
break;
|
|
702
|
-
}
|
|
703
|
-
}
|
|
704
|
-
let s = this.location.start;
|
|
705
|
-
let loc = this.location.source + ':' + s.line + ':' + s.column;
|
|
706
|
-
if (src) {
|
|
707
|
-
let e = this.location.end;
|
|
708
|
-
let filler = peg$padEnd('', s.line.toString().length, ' ');
|
|
709
|
-
let line = src[s.line - 1];
|
|
710
|
-
let last = s.line === e.line ? e.column : line.length + 1;
|
|
711
|
-
str +=
|
|
712
|
-
'\n --> ' +
|
|
713
|
-
loc +
|
|
714
|
-
'\n' +
|
|
715
|
-
filler +
|
|
716
|
-
' |\n' +
|
|
717
|
-
s.line +
|
|
718
|
-
' | ' +
|
|
719
|
-
line +
|
|
720
|
-
'\n' +
|
|
721
|
-
filler +
|
|
722
|
-
' | ' +
|
|
723
|
-
peg$padEnd('', s.column - 1, ' ') +
|
|
724
|
-
peg$padEnd('', last - s.column, '^');
|
|
725
|
-
} else {
|
|
726
|
-
str += '\n at ' + loc;
|
|
727
|
-
}
|
|
728
|
-
}
|
|
729
|
-
return str;
|
|
730
|
-
}
|
|
731
|
-
}
|
|
732
|
-
function peg$parse(input, options) {
|
|
733
|
-
options = options !== undefined ? options : {};
|
|
734
|
-
const peg$FAILED = {};
|
|
735
|
-
const peg$source = options.grammarSource;
|
|
736
|
-
const peg$startRuleFunctions = {
|
|
737
|
-
Dot: peg$parseDot,
|
|
738
|
-
Graph: peg$parseGraph,
|
|
739
|
-
Subgraph: peg$parseSubgraph,
|
|
740
|
-
Node: peg$parseNode,
|
|
741
|
-
Edge: peg$parseEdge,
|
|
742
|
-
AttributeList: peg$parseAttributeList,
|
|
743
|
-
Attribute: peg$parseAttribute,
|
|
744
|
-
ClusterStatements: peg$parseClusterStatements,
|
|
745
|
-
};
|
|
746
|
-
let peg$startRuleFunction = peg$parseDot;
|
|
747
|
-
const peg$c0 = function (v) {
|
|
748
|
-
return v;
|
|
749
|
-
};
|
|
750
|
-
const peg$c1 = function (c1, graph, c2) {
|
|
751
|
-
return b.createElement('Dot', {}, [...c1, graph, ...c2]);
|
|
752
|
-
};
|
|
753
|
-
const peg$c2 = 'strict';
|
|
754
|
-
const peg$c3 = peg$literalExpectation('strict', true);
|
|
755
|
-
const peg$c4 = 'graph';
|
|
756
|
-
const peg$c5 = peg$literalExpectation('graph', true);
|
|
757
|
-
const peg$c6 = 'digraph';
|
|
758
|
-
const peg$c7 = peg$literalExpectation('digraph', true);
|
|
759
|
-
const peg$c8 = '{';
|
|
760
|
-
const peg$c9 = peg$literalExpectation('{', false);
|
|
761
|
-
const peg$c10 = '}';
|
|
762
|
-
const peg$c11 = peg$literalExpectation('}', false);
|
|
763
|
-
const peg$c12 = function (_strict, _kind, id, children) {
|
|
764
|
-
const strict = !!_strict;
|
|
765
|
-
const kind = _kind.toLowerCase();
|
|
766
|
-
const directed = kind === 'digraph';
|
|
767
|
-
for (const edgeop of edgeops) {
|
|
768
|
-
if (directed) {
|
|
769
|
-
if (edgeop.operator !== '->') {
|
|
770
|
-
error(`In digraph, it's necessary to describe with "->" operator to create edge.`, edgeop.location);
|
|
771
|
-
}
|
|
772
|
-
} else {
|
|
773
|
-
if (edgeop.operator !== '--') {
|
|
774
|
-
error(`In graph, it's necessary to describe with "--" operator to create edge.`, edgeop.location);
|
|
775
|
-
}
|
|
776
|
-
}
|
|
777
|
-
}
|
|
778
|
-
return b.createElement(
|
|
779
|
-
'Graph',
|
|
780
|
-
id !== null
|
|
781
|
-
? {
|
|
782
|
-
id,
|
|
783
|
-
directed,
|
|
784
|
-
strict,
|
|
785
|
-
}
|
|
786
|
-
: {
|
|
787
|
-
directed,
|
|
788
|
-
strict,
|
|
789
|
-
},
|
|
790
|
-
children,
|
|
791
|
-
);
|
|
792
|
-
};
|
|
793
|
-
const peg$c13 = ';';
|
|
794
|
-
const peg$c14 = peg$literalExpectation(';', false);
|
|
795
|
-
const peg$c15 = function (keyValue) {
|
|
796
|
-
return b.createElement(
|
|
797
|
-
'Attribute',
|
|
798
|
-
{
|
|
799
|
-
...keyValue,
|
|
800
|
-
},
|
|
801
|
-
[],
|
|
802
|
-
);
|
|
803
|
-
};
|
|
804
|
-
const peg$c16 = 'node';
|
|
805
|
-
const peg$c17 = peg$literalExpectation('node', true);
|
|
806
|
-
const peg$c18 = 'edge';
|
|
807
|
-
const peg$c19 = peg$literalExpectation('edge', true);
|
|
808
|
-
const peg$c20 = function (_kind, children) {
|
|
809
|
-
return b.createElement(
|
|
810
|
-
'AttributeList',
|
|
811
|
-
{
|
|
812
|
-
kind: _kind.toLowerCase(),
|
|
813
|
-
},
|
|
814
|
-
children,
|
|
815
|
-
);
|
|
816
|
-
};
|
|
817
|
-
const peg$c21 = function (id, rhs, _children) {
|
|
818
|
-
// @ts-ignore
|
|
819
|
-
return b.createElement(
|
|
820
|
-
// @ts-ignore
|
|
821
|
-
'Edge',
|
|
822
|
-
{
|
|
823
|
-
targets: [id, ...rhs],
|
|
824
|
-
},
|
|
825
|
-
_children ?? [],
|
|
826
|
-
);
|
|
827
|
-
};
|
|
828
|
-
const peg$c22 = function (id, _children) {
|
|
829
|
-
return b.createElement(
|
|
830
|
-
'Node',
|
|
831
|
-
{
|
|
832
|
-
id,
|
|
555
|
+
};
|
|
556
|
+
const peg$c22 = function (id, _children) {
|
|
557
|
+
return b.createElement(
|
|
558
|
+
'Node',
|
|
559
|
+
{
|
|
560
|
+
id,
|
|
833
561
|
},
|
|
834
562
|
_children ?? [],
|
|
835
563
|
);
|
|
@@ -2766,10 +2494,10 @@ function peg$parse(input, options) {
|
|
|
2766
2494
|
peg$maxFailExpected.push(expected1);
|
|
2767
2495
|
}
|
|
2768
2496
|
function peg$buildSimpleError(message, location1) {
|
|
2769
|
-
return new SyntaxError(message, [], '', location1);
|
|
2497
|
+
return new SyntaxError$1(message, [], '', location1);
|
|
2770
2498
|
}
|
|
2771
2499
|
function peg$buildStructuredError(expected1, found, location1) {
|
|
2772
|
-
return new SyntaxError(SyntaxError.buildMessage(expected1, found), expected1, found, location1);
|
|
2500
|
+
return new SyntaxError$1(SyntaxError$1.buildMessage(expected1, found), expected1, found, location1);
|
|
2773
2501
|
}
|
|
2774
2502
|
function peg$parseDot() {
|
|
2775
2503
|
let s0, s1, s2, s3;
|
|
@@ -5528,13 +5256,301 @@ const parse$1 = peg$parse;
|
|
|
5528
5256
|
function parse(input, options) {
|
|
5529
5257
|
return parse$1(input, options);
|
|
5530
5258
|
}
|
|
5259
|
+
/**
|
|
5260
|
+
* @group Convert DOT to AST
|
|
5261
|
+
*/
|
|
5262
|
+
const SyntaxError = SyntaxError$1;
|
|
5531
5263
|
|
|
5264
|
+
function convertAttribute(key, value) {
|
|
5265
|
+
if (typeof value === 'string') {
|
|
5266
|
+
const trimmed = value.trim();
|
|
5267
|
+
const isHTMLLike = /^<.+>$/ms.test(trimmed);
|
|
5268
|
+
if (isHTMLLike) {
|
|
5269
|
+
return createElement(
|
|
5270
|
+
'Attribute',
|
|
5271
|
+
{
|
|
5272
|
+
key: createElement('Literal', { value: key, quoted: false }, []),
|
|
5273
|
+
value: createElement('Literal', { value: trimmed.slice(1, trimmed.length - 1), quoted: 'html' }, []),
|
|
5274
|
+
},
|
|
5275
|
+
[],
|
|
5276
|
+
);
|
|
5277
|
+
} else {
|
|
5278
|
+
return createElement(
|
|
5279
|
+
'Attribute',
|
|
5280
|
+
{
|
|
5281
|
+
key: createElement('Literal', { value: key, quoted: false }, []),
|
|
5282
|
+
value: createElement('Literal', { value: value, quoted: true }, []),
|
|
5283
|
+
},
|
|
5284
|
+
[],
|
|
5285
|
+
);
|
|
5286
|
+
}
|
|
5287
|
+
}
|
|
5288
|
+
return createElement(
|
|
5289
|
+
'Attribute',
|
|
5290
|
+
{
|
|
5291
|
+
key: createElement('Literal', { value: key, quoted: false }, []),
|
|
5292
|
+
value: createElement('Literal', { value: String(value), quoted: false }, []),
|
|
5293
|
+
},
|
|
5294
|
+
[],
|
|
5295
|
+
);
|
|
5296
|
+
}
|
|
5297
|
+
|
|
5298
|
+
function convertComment(value, kind) {
|
|
5299
|
+
return createElement(
|
|
5300
|
+
'Comment',
|
|
5301
|
+
{
|
|
5302
|
+
kind: kind,
|
|
5303
|
+
value: value,
|
|
5304
|
+
},
|
|
5305
|
+
[],
|
|
5306
|
+
);
|
|
5307
|
+
}
|
|
5308
|
+
|
|
5309
|
+
function convertClusterChildren(context, model) {
|
|
5310
|
+
return Array.from(
|
|
5311
|
+
(function* () {
|
|
5312
|
+
for (const [key, value] of model.values) {
|
|
5313
|
+
yield convertAttribute(key, value);
|
|
5314
|
+
}
|
|
5315
|
+
for (const attrs of Object.values(model.attributes)) {
|
|
5316
|
+
if (attrs.size > 0) {
|
|
5317
|
+
if (attrs.comment) {
|
|
5318
|
+
yield convertComment(attrs.comment, context.commentKind);
|
|
5319
|
+
}
|
|
5320
|
+
yield context.convert(attrs);
|
|
5321
|
+
}
|
|
5322
|
+
}
|
|
5323
|
+
for (const node of model.nodes) {
|
|
5324
|
+
if (node.comment) {
|
|
5325
|
+
yield convertComment(node.comment, context.commentKind);
|
|
5326
|
+
}
|
|
5327
|
+
yield context.convert(node);
|
|
5328
|
+
}
|
|
5329
|
+
for (const subgraph of model.subgraphs) {
|
|
5330
|
+
if (subgraph.comment) {
|
|
5331
|
+
yield convertComment(subgraph.comment, context.commentKind);
|
|
5332
|
+
}
|
|
5333
|
+
yield context.convert(subgraph);
|
|
5334
|
+
}
|
|
5335
|
+
for (const edge of model.edges) {
|
|
5336
|
+
if (edge.comment) {
|
|
5337
|
+
yield convertComment(edge.comment, context.commentKind);
|
|
5338
|
+
}
|
|
5339
|
+
yield context.convert(edge);
|
|
5340
|
+
}
|
|
5341
|
+
})(),
|
|
5342
|
+
);
|
|
5343
|
+
}
|
|
5344
|
+
|
|
5345
|
+
const AttributeListPrintPlugin = {
|
|
5346
|
+
match(model) {
|
|
5347
|
+
return model.$$type === 'AttributeList';
|
|
5348
|
+
},
|
|
5349
|
+
convert(context, model) {
|
|
5350
|
+
return createElement(
|
|
5351
|
+
'AttributeList',
|
|
5352
|
+
{
|
|
5353
|
+
kind: model.$$kind,
|
|
5354
|
+
},
|
|
5355
|
+
model.values.map(([key, value]) => convertAttribute(key, value)),
|
|
5356
|
+
);
|
|
5357
|
+
},
|
|
5358
|
+
};
|
|
5359
|
+
|
|
5360
|
+
const EdgeConvertPlugin = {
|
|
5361
|
+
match(model) {
|
|
5362
|
+
return model.$$type === 'Edge';
|
|
5363
|
+
},
|
|
5364
|
+
convert(context, model) {
|
|
5365
|
+
return createElement(
|
|
5366
|
+
'Edge',
|
|
5367
|
+
{
|
|
5368
|
+
targets: model.targets.map((target) => {
|
|
5369
|
+
if (common.isNodeModel(target)) {
|
|
5370
|
+
return createElement(
|
|
5371
|
+
'NodeRef',
|
|
5372
|
+
{
|
|
5373
|
+
id: createElement(
|
|
5374
|
+
'Literal',
|
|
5375
|
+
{
|
|
5376
|
+
value: target.id,
|
|
5377
|
+
quoted: true,
|
|
5378
|
+
},
|
|
5379
|
+
[],
|
|
5380
|
+
),
|
|
5381
|
+
},
|
|
5382
|
+
[],
|
|
5383
|
+
);
|
|
5384
|
+
} else if (common.isForwardRefNode(target)) {
|
|
5385
|
+
return createElement(
|
|
5386
|
+
'NodeRef',
|
|
5387
|
+
{
|
|
5388
|
+
id: createElement(
|
|
5389
|
+
'Literal',
|
|
5390
|
+
{
|
|
5391
|
+
value: target.id,
|
|
5392
|
+
quoted: true,
|
|
5393
|
+
},
|
|
5394
|
+
[],
|
|
5395
|
+
),
|
|
5396
|
+
port: target.port
|
|
5397
|
+
? createElement(
|
|
5398
|
+
'Literal',
|
|
5399
|
+
{
|
|
5400
|
+
value: target.port,
|
|
5401
|
+
quoted: true,
|
|
5402
|
+
},
|
|
5403
|
+
[],
|
|
5404
|
+
)
|
|
5405
|
+
: undefined,
|
|
5406
|
+
compass: target.compass
|
|
5407
|
+
? createElement(
|
|
5408
|
+
'Literal',
|
|
5409
|
+
{
|
|
5410
|
+
value: target.compass,
|
|
5411
|
+
quoted: true,
|
|
5412
|
+
},
|
|
5413
|
+
[],
|
|
5414
|
+
)
|
|
5415
|
+
: undefined,
|
|
5416
|
+
},
|
|
5417
|
+
[],
|
|
5418
|
+
);
|
|
5419
|
+
}
|
|
5420
|
+
}),
|
|
5421
|
+
},
|
|
5422
|
+
[
|
|
5423
|
+
...(model.attributes.comment ? [convertComment(model.attributes.comment, context.commentKind)] : []),
|
|
5424
|
+
...model.attributes.values.map(([key, value]) => convertAttribute(key, value)),
|
|
5425
|
+
],
|
|
5426
|
+
);
|
|
5427
|
+
},
|
|
5428
|
+
};
|
|
5429
|
+
|
|
5430
|
+
const GraphConvertPlugin = {
|
|
5431
|
+
match(model) {
|
|
5432
|
+
return model.$$type === 'Graph';
|
|
5433
|
+
},
|
|
5434
|
+
convert(context, model) {
|
|
5435
|
+
return createElement('Dot', {}, [
|
|
5436
|
+
...(model.comment ? [convertComment(model.comment, context.commentKind)] : []),
|
|
5437
|
+
createElement(
|
|
5438
|
+
'Graph',
|
|
5439
|
+
{
|
|
5440
|
+
directed: model.directed,
|
|
5441
|
+
strict: model.strict,
|
|
5442
|
+
id: model.id
|
|
5443
|
+
? createElement(
|
|
5444
|
+
'Literal',
|
|
5445
|
+
{
|
|
5446
|
+
value: model.id,
|
|
5447
|
+
quoted: true,
|
|
5448
|
+
},
|
|
5449
|
+
[],
|
|
5450
|
+
)
|
|
5451
|
+
: undefined,
|
|
5452
|
+
},
|
|
5453
|
+
convertClusterChildren(context, model),
|
|
5454
|
+
),
|
|
5455
|
+
]);
|
|
5456
|
+
},
|
|
5457
|
+
};
|
|
5458
|
+
|
|
5459
|
+
const NodeConvertPlugin = {
|
|
5460
|
+
match(model) {
|
|
5461
|
+
return model.$$type === 'Node';
|
|
5462
|
+
},
|
|
5463
|
+
convert(context, model) {
|
|
5464
|
+
return createElement(
|
|
5465
|
+
'Node',
|
|
5466
|
+
{
|
|
5467
|
+
id: createElement(
|
|
5468
|
+
'Literal',
|
|
5469
|
+
{
|
|
5470
|
+
value: model.id,
|
|
5471
|
+
quoted: true,
|
|
5472
|
+
},
|
|
5473
|
+
[],
|
|
5474
|
+
),
|
|
5475
|
+
},
|
|
5476
|
+
[
|
|
5477
|
+
...(model.attributes.comment ? [convertComment(model.attributes.comment, context.commentKind)] : []),
|
|
5478
|
+
...model.attributes.values.map(([key, value]) => convertAttribute(key, value)),
|
|
5479
|
+
],
|
|
5480
|
+
);
|
|
5481
|
+
},
|
|
5482
|
+
};
|
|
5483
|
+
|
|
5484
|
+
const SubgraphConvertPlugin = {
|
|
5485
|
+
match(model) {
|
|
5486
|
+
return model.$$type === 'Subgraph';
|
|
5487
|
+
},
|
|
5488
|
+
convert(context, model) {
|
|
5489
|
+
return createElement(
|
|
5490
|
+
'Subgraph',
|
|
5491
|
+
{
|
|
5492
|
+
id: model.id
|
|
5493
|
+
? createElement(
|
|
5494
|
+
'Literal',
|
|
5495
|
+
{
|
|
5496
|
+
value: model.id,
|
|
5497
|
+
quoted: true,
|
|
5498
|
+
},
|
|
5499
|
+
[],
|
|
5500
|
+
)
|
|
5501
|
+
: undefined,
|
|
5502
|
+
},
|
|
5503
|
+
convertClusterChildren(context, model),
|
|
5504
|
+
);
|
|
5505
|
+
},
|
|
5506
|
+
};
|
|
5507
|
+
|
|
5508
|
+
const defaultPlugins = [
|
|
5509
|
+
AttributeListPrintPlugin,
|
|
5510
|
+
EdgeConvertPlugin,
|
|
5511
|
+
NodeConvertPlugin,
|
|
5512
|
+
GraphConvertPlugin,
|
|
5513
|
+
SubgraphConvertPlugin,
|
|
5514
|
+
];
|
|
5515
|
+
|
|
5516
|
+
/**
|
|
5517
|
+
* @group Convert Model to AST
|
|
5518
|
+
*/
|
|
5519
|
+
class FromModelConverter {
|
|
5520
|
+
options;
|
|
5521
|
+
/** @hidden */
|
|
5522
|
+
#plugins = [...defaultPlugins];
|
|
5523
|
+
constructor(options = {}) {
|
|
5524
|
+
this.options = options;
|
|
5525
|
+
}
|
|
5526
|
+
convert(model) {
|
|
5527
|
+
const plugins = [...this.#plugins];
|
|
5528
|
+
const { commentKind = 'Slash' } = this.options;
|
|
5529
|
+
const context = {
|
|
5530
|
+
commentKind,
|
|
5531
|
+
convert(m) {
|
|
5532
|
+
for (const plugin of plugins) {
|
|
5533
|
+
/* */
|
|
5534
|
+
if (plugin.match(m)) {
|
|
5535
|
+
return plugin.convert(context, m);
|
|
5536
|
+
}
|
|
5537
|
+
}
|
|
5538
|
+
throw Error();
|
|
5539
|
+
},
|
|
5540
|
+
};
|
|
5541
|
+
return context.convert(model);
|
|
5542
|
+
}
|
|
5543
|
+
}
|
|
5544
|
+
|
|
5545
|
+
/**
|
|
5546
|
+
* @group Convert Model to AST
|
|
5547
|
+
*/
|
|
5532
5548
|
function fromModel(model, options) {
|
|
5533
|
-
return new
|
|
5549
|
+
return new FromModelConverter(options).convert(model);
|
|
5534
5550
|
}
|
|
5535
5551
|
|
|
5536
5552
|
exports.Builder = Builder;
|
|
5537
|
-
exports.
|
|
5553
|
+
exports.FromModelConverter = FromModelConverter;
|
|
5538
5554
|
exports.Printer = Printer;
|
|
5539
5555
|
exports.SyntaxError = SyntaxError;
|
|
5540
5556
|
exports.createElement = createElement;
|