ts-graphviz 1.1.0 → 1.2.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 +118 -14
- package/README.md +118 -14
- package/lib/ast/index.cjs +226 -18
- package/lib/ast/index.d.ts +94 -4
- package/lib/ast/index.js +237 -20
- package/lib/common/index.cjs +0 -2
- package/lib/common/index.js +0 -2
- package/lib/core/index.cjs +18 -1
- package/lib/core/index.d.ts +27 -2
- package/lib/core/index.js +19 -2
- package/media/state-machine.svg +1 -1
- package/media/ts-graphviz.svg +1 -1
- package/package.json +1 -1
- package/test/class-base.test.ts +109 -1
- package/test/from-dot.test.ts +58 -0
package/lib/ast/index.d.ts
CHANGED
|
@@ -1,4 +1,14 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import {
|
|
2
|
+
Compass,
|
|
3
|
+
AttributeKey,
|
|
4
|
+
ASTType,
|
|
5
|
+
DotObjectModel,
|
|
6
|
+
RootGraphModel,
|
|
7
|
+
EdgeModel,
|
|
8
|
+
NodeModel,
|
|
9
|
+
SubgraphModel,
|
|
10
|
+
ModelsContext,
|
|
11
|
+
} from '#lib/common';
|
|
2
12
|
|
|
3
13
|
/**
|
|
4
14
|
* @group AST
|
|
@@ -432,6 +442,7 @@ declare function parse(input: string, options?: ParseOptions<'AttributeList'>):
|
|
|
432
442
|
declare function parse(input: string, options?: ParseOptions<'Attribute'>): AttributeASTNode;
|
|
433
443
|
declare function parse(input: string, options?: ParseOptions<'Subgraph'>): SubgraphASTNode;
|
|
434
444
|
declare function parse(input: string, options?: ParseOptions<'ClusterStatements'>): ClusterStatementASTNode[];
|
|
445
|
+
declare function parse(input: string, options?: ParseOptions<Rule>): ASTNode | ClusterStatementASTNode[];
|
|
435
446
|
/**
|
|
436
447
|
* @group Convert DOT to AST
|
|
437
448
|
*/
|
|
@@ -440,9 +451,7 @@ declare const SyntaxError: typeof SyntaxError$1;
|
|
|
440
451
|
/**
|
|
441
452
|
* @group AST
|
|
442
453
|
*/
|
|
443
|
-
declare type ModelToAST<T> = T extends
|
|
444
|
-
$$type: infer U extends DotObjectType;
|
|
445
|
-
}
|
|
454
|
+
declare type ModelToAST<T> = T extends DotObjectModel<infer U>
|
|
446
455
|
? U extends 'Graph'
|
|
447
456
|
? GraphASTNode | DotASTNode
|
|
448
457
|
: U extends 'AttributeList'
|
|
@@ -493,6 +502,79 @@ declare class FromModelConverter {
|
|
|
493
502
|
*/
|
|
494
503
|
declare function fromModel<T extends DotObjectModel>(model: T, options?: ConvertFromModelOptions): ModelToAST<T>;
|
|
495
504
|
|
|
505
|
+
/**
|
|
506
|
+
* @group AST
|
|
507
|
+
*/
|
|
508
|
+
declare type ModelOf<T> = T extends 'Dot' | 'Graph'
|
|
509
|
+
? RootGraphModel
|
|
510
|
+
: T extends 'Edge'
|
|
511
|
+
? EdgeModel
|
|
512
|
+
: T extends 'Node'
|
|
513
|
+
? NodeModel
|
|
514
|
+
: T extends 'Subgraph'
|
|
515
|
+
? SubgraphModel
|
|
516
|
+
: never;
|
|
517
|
+
/**
|
|
518
|
+
* @group AST
|
|
519
|
+
*/
|
|
520
|
+
declare type ASTToModel<T> = T extends {
|
|
521
|
+
type: infer U;
|
|
522
|
+
}
|
|
523
|
+
? ModelOf<U>
|
|
524
|
+
: never;
|
|
525
|
+
/**
|
|
526
|
+
* @group Convert AST to Model
|
|
527
|
+
* @beta
|
|
528
|
+
*/
|
|
529
|
+
declare type ToModelConvertableASTNode = DotASTNode | GraphASTNode | SubgraphASTNode | NodeASTNode | EdgeASTNode;
|
|
530
|
+
/**
|
|
531
|
+
* @group Convert AST to Model
|
|
532
|
+
* @alpha
|
|
533
|
+
*/
|
|
534
|
+
interface ConvertToModelOptions {
|
|
535
|
+
models?: Partial<ModelsContext>;
|
|
536
|
+
}
|
|
537
|
+
/**
|
|
538
|
+
* @group Convert AST to Model
|
|
539
|
+
* @alpha
|
|
540
|
+
*/
|
|
541
|
+
interface ConvertToModelContext {
|
|
542
|
+
models: ModelsContext;
|
|
543
|
+
convert<T extends ToModelConvertableASTNode>(ast: T): ASTToModel<T>;
|
|
544
|
+
}
|
|
545
|
+
/**
|
|
546
|
+
* @group Convert AST to Model
|
|
547
|
+
* @alpha
|
|
548
|
+
*/
|
|
549
|
+
interface ConvertToModelPlugin<T extends ToModelConvertableASTNode = ToModelConvertableASTNode> {
|
|
550
|
+
match(ast: T): boolean;
|
|
551
|
+
convert(context: ConvertToModelContext, ast: T): ASTToModel<T>;
|
|
552
|
+
}
|
|
553
|
+
|
|
554
|
+
/**
|
|
555
|
+
* @group Convert AST to Model
|
|
556
|
+
* @alpha
|
|
557
|
+
*/
|
|
558
|
+
declare class ToModelConverter {
|
|
559
|
+
private options;
|
|
560
|
+
/** @hidden */
|
|
561
|
+
protected plugins: ConvertToModelPlugin<ToModelConvertableASTNode>[];
|
|
562
|
+
constructor(options?: ConvertToModelOptions);
|
|
563
|
+
/**
|
|
564
|
+
* Convert AST to Model.
|
|
565
|
+
*
|
|
566
|
+
* @param ast AST node.
|
|
567
|
+
* @alpha
|
|
568
|
+
*/
|
|
569
|
+
convert<T extends ToModelConvertableASTNode>(ast: T): ASTToModel<T>;
|
|
570
|
+
}
|
|
571
|
+
|
|
572
|
+
/**
|
|
573
|
+
* @group Convert AST to Model
|
|
574
|
+
* @beta
|
|
575
|
+
*/
|
|
576
|
+
declare function toModel<T extends ToModelConvertableASTNode>(ast: T, options?: ConvertToModelOptions): ASTToModel<T>;
|
|
577
|
+
|
|
496
578
|
export {
|
|
497
579
|
ASTBaseNode,
|
|
498
580
|
ASTBaseParentNode,
|
|
@@ -500,6 +582,7 @@ export {
|
|
|
500
582
|
ASTChildNode,
|
|
501
583
|
ASTCommonPropaties,
|
|
502
584
|
ASTNode,
|
|
585
|
+
ASTToModel,
|
|
503
586
|
AttributeASTNode,
|
|
504
587
|
AttributeASTPropaties,
|
|
505
588
|
AttributeListASTNode,
|
|
@@ -514,6 +597,9 @@ export {
|
|
|
514
597
|
ConvertFromModelContext,
|
|
515
598
|
ConvertFromModelOptions,
|
|
516
599
|
ConvertFromModelPlugin,
|
|
600
|
+
ConvertToModelContext,
|
|
601
|
+
ConvertToModelOptions,
|
|
602
|
+
ConvertToModelPlugin,
|
|
517
603
|
CreateElement,
|
|
518
604
|
DotASTNode,
|
|
519
605
|
DotASTPropaties,
|
|
@@ -529,6 +615,7 @@ export {
|
|
|
529
615
|
IndentStyle,
|
|
530
616
|
LiteralASTNode,
|
|
531
617
|
LiteralASTPropaties,
|
|
618
|
+
ModelOf,
|
|
532
619
|
ModelToAST,
|
|
533
620
|
NodeASTNode,
|
|
534
621
|
NodeASTPropaties,
|
|
@@ -546,8 +633,11 @@ export {
|
|
|
546
633
|
SubgraphASTNode,
|
|
547
634
|
SubgraphASTPropaties,
|
|
548
635
|
SyntaxError,
|
|
636
|
+
ToModelConvertableASTNode,
|
|
637
|
+
ToModelConverter,
|
|
549
638
|
createElement,
|
|
550
639
|
fromModel,
|
|
551
640
|
parse,
|
|
552
641
|
stringify,
|
|
642
|
+
toModel,
|
|
553
643
|
};
|
package/lib/ast/index.js
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { pipe, map } from '#lib/utils';
|
|
2
|
-
import { isNodeModel, isForwardRefNode } from '#lib/common';
|
|
2
|
+
import { isNodeModel, isForwardRefNode, createModelsContext } from '#lib/common';
|
|
3
3
|
|
|
4
4
|
/**
|
|
5
5
|
* @group Create AST
|
|
@@ -55,7 +55,7 @@ const endOfLine = (eol) => {
|
|
|
55
55
|
}
|
|
56
56
|
};
|
|
57
57
|
|
|
58
|
-
const AttributeListPrintPlugin
|
|
58
|
+
const AttributeListPrintPlugin = {
|
|
59
59
|
match(ast) {
|
|
60
60
|
return ast.type === 'AttributeList';
|
|
61
61
|
},
|
|
@@ -244,8 +244,8 @@ const SubgraphPrintPlugin = {
|
|
|
244
244
|
},
|
|
245
245
|
};
|
|
246
246
|
|
|
247
|
-
const defaultPlugins$
|
|
248
|
-
AttributeListPrintPlugin
|
|
247
|
+
const defaultPlugins$2 = [
|
|
248
|
+
AttributeListPrintPlugin,
|
|
249
249
|
AttributePrintPlugin,
|
|
250
250
|
CommentPrintPlugin,
|
|
251
251
|
DotPrintPlugin,
|
|
@@ -264,7 +264,7 @@ const defaultPlugins$1 = [
|
|
|
264
264
|
class Printer {
|
|
265
265
|
options;
|
|
266
266
|
/** @internal */
|
|
267
|
-
#plugins = [...defaultPlugins$
|
|
267
|
+
#plugins = [...defaultPlugins$2];
|
|
268
268
|
constructor(options = {}) {
|
|
269
269
|
this.options = options;
|
|
270
270
|
}
|
|
@@ -5333,7 +5333,7 @@ function convertClusterChildren(context, model) {
|
|
|
5333
5333
|
);
|
|
5334
5334
|
}
|
|
5335
5335
|
|
|
5336
|
-
const
|
|
5336
|
+
const AttributeListPlugin = {
|
|
5337
5337
|
match(model) {
|
|
5338
5338
|
return model.$$type === 'AttributeList';
|
|
5339
5339
|
},
|
|
@@ -5348,7 +5348,7 @@ const AttributeListPrintPlugin = {
|
|
|
5348
5348
|
},
|
|
5349
5349
|
};
|
|
5350
5350
|
|
|
5351
|
-
const
|
|
5351
|
+
const EdgePlugin$1 = {
|
|
5352
5352
|
match(model) {
|
|
5353
5353
|
return model.$$type === 'Edge';
|
|
5354
5354
|
},
|
|
@@ -5418,7 +5418,7 @@ const EdgeConvertPlugin = {
|
|
|
5418
5418
|
},
|
|
5419
5419
|
};
|
|
5420
5420
|
|
|
5421
|
-
const
|
|
5421
|
+
const GraphPlugin$1 = {
|
|
5422
5422
|
match(model) {
|
|
5423
5423
|
return model.$$type === 'Graph';
|
|
5424
5424
|
},
|
|
@@ -5447,7 +5447,7 @@ const GraphConvertPlugin = {
|
|
|
5447
5447
|
},
|
|
5448
5448
|
};
|
|
5449
5449
|
|
|
5450
|
-
const
|
|
5450
|
+
const NodePlugin$1 = {
|
|
5451
5451
|
match(model) {
|
|
5452
5452
|
return model.$$type === 'Node';
|
|
5453
5453
|
},
|
|
@@ -5472,7 +5472,7 @@ const NodeConvertPlugin = {
|
|
|
5472
5472
|
},
|
|
5473
5473
|
};
|
|
5474
5474
|
|
|
5475
|
-
const
|
|
5475
|
+
const SubgraphPlugin$1 = {
|
|
5476
5476
|
match(model) {
|
|
5477
5477
|
return model.$$type === 'Subgraph';
|
|
5478
5478
|
},
|
|
@@ -5496,13 +5496,7 @@ const SubgraphConvertPlugin = {
|
|
|
5496
5496
|
},
|
|
5497
5497
|
};
|
|
5498
5498
|
|
|
5499
|
-
const defaultPlugins = [
|
|
5500
|
-
AttributeListPrintPlugin,
|
|
5501
|
-
EdgeConvertPlugin,
|
|
5502
|
-
NodeConvertPlugin,
|
|
5503
|
-
GraphConvertPlugin,
|
|
5504
|
-
SubgraphConvertPlugin,
|
|
5505
|
-
];
|
|
5499
|
+
const defaultPlugins$1 = [AttributeListPlugin, EdgePlugin$1, NodePlugin$1, GraphPlugin$1, SubgraphPlugin$1];
|
|
5506
5500
|
|
|
5507
5501
|
/**
|
|
5508
5502
|
* @group Convert Model to AST
|
|
@@ -5510,7 +5504,7 @@ const defaultPlugins = [
|
|
|
5510
5504
|
class FromModelConverter {
|
|
5511
5505
|
options;
|
|
5512
5506
|
/** @hidden */
|
|
5513
|
-
#plugins = [...defaultPlugins];
|
|
5507
|
+
#plugins = [...defaultPlugins$1];
|
|
5514
5508
|
constructor(options = {}) {
|
|
5515
5509
|
this.options = options;
|
|
5516
5510
|
}
|
|
@@ -5521,7 +5515,6 @@ class FromModelConverter {
|
|
|
5521
5515
|
commentKind,
|
|
5522
5516
|
convert(m) {
|
|
5523
5517
|
for (const plugin of plugins) {
|
|
5524
|
-
/* */
|
|
5525
5518
|
if (plugin.match(m)) {
|
|
5526
5519
|
return plugin.convert(context, m);
|
|
5527
5520
|
}
|
|
@@ -5540,4 +5533,228 @@ function fromModel(model, options) {
|
|
|
5540
5533
|
return new FromModelConverter(options).convert(model);
|
|
5541
5534
|
}
|
|
5542
5535
|
|
|
5543
|
-
|
|
5536
|
+
class CommentHolder {
|
|
5537
|
+
comment = null;
|
|
5538
|
+
set(comment) {
|
|
5539
|
+
this.comment = comment;
|
|
5540
|
+
}
|
|
5541
|
+
reset() {
|
|
5542
|
+
this.comment = null;
|
|
5543
|
+
}
|
|
5544
|
+
apply(model, location) {
|
|
5545
|
+
if (location && this.comment?.location) {
|
|
5546
|
+
if (this.comment?.kind === 'Block') {
|
|
5547
|
+
if (this.comment.location.end.line === location.start.line - 1) {
|
|
5548
|
+
model.comment = this.comment.value;
|
|
5549
|
+
}
|
|
5550
|
+
} else {
|
|
5551
|
+
if (this.comment.location.end.line === location.start.line) {
|
|
5552
|
+
model.comment = this.comment.value;
|
|
5553
|
+
}
|
|
5554
|
+
}
|
|
5555
|
+
} else {
|
|
5556
|
+
model.comment = this.comment?.value;
|
|
5557
|
+
}
|
|
5558
|
+
this.reset();
|
|
5559
|
+
}
|
|
5560
|
+
}
|
|
5561
|
+
|
|
5562
|
+
const DotPlugin = {
|
|
5563
|
+
match(ast) {
|
|
5564
|
+
return ast.type === 'Dot';
|
|
5565
|
+
},
|
|
5566
|
+
convert(context, ast) {
|
|
5567
|
+
const commentHolder = new CommentHolder();
|
|
5568
|
+
for (const stmt of ast.children) {
|
|
5569
|
+
switch (stmt.type) {
|
|
5570
|
+
case 'Comment':
|
|
5571
|
+
commentHolder.set(stmt);
|
|
5572
|
+
break;
|
|
5573
|
+
case 'Graph':
|
|
5574
|
+
const graph = context.convert(stmt);
|
|
5575
|
+
commentHolder.apply(graph, stmt.location);
|
|
5576
|
+
return graph;
|
|
5577
|
+
}
|
|
5578
|
+
}
|
|
5579
|
+
throw Error();
|
|
5580
|
+
},
|
|
5581
|
+
};
|
|
5582
|
+
|
|
5583
|
+
function convertToEdgeTargetTuple(edge) {
|
|
5584
|
+
return edge.targets.map((t) => {
|
|
5585
|
+
switch (t.type) {
|
|
5586
|
+
case 'NodeRef':
|
|
5587
|
+
return { id: t.id.value, port: t.port?.value, compass: t.compass?.value };
|
|
5588
|
+
case 'NodeRefGroup':
|
|
5589
|
+
return t.children.map((t) => ({ id: t.id.value, port: t.port?.value, compass: t.compass?.value }));
|
|
5590
|
+
}
|
|
5591
|
+
});
|
|
5592
|
+
}
|
|
5593
|
+
|
|
5594
|
+
const EdgePlugin = {
|
|
5595
|
+
match(ast) {
|
|
5596
|
+
return ast.type === 'Edge';
|
|
5597
|
+
},
|
|
5598
|
+
convert(context, ast) {
|
|
5599
|
+
const edge = new context.models.Edge(
|
|
5600
|
+
convertToEdgeTargetTuple(ast),
|
|
5601
|
+
ast.children
|
|
5602
|
+
.filter((v) => v.type === 'Attribute')
|
|
5603
|
+
.reduce((prev, curr) => ({ ...prev, [curr.key.value]: curr.value.value }), {}),
|
|
5604
|
+
);
|
|
5605
|
+
return edge;
|
|
5606
|
+
},
|
|
5607
|
+
};
|
|
5608
|
+
|
|
5609
|
+
function applyStatements(graph, statements) {
|
|
5610
|
+
const commentHolder = new CommentHolder();
|
|
5611
|
+
for (const stmt of statements) {
|
|
5612
|
+
switch (stmt.type) {
|
|
5613
|
+
case 'Subgraph':
|
|
5614
|
+
const subgraph = stmt.id ? graph.subgraph(stmt.id.value) : graph.subgraph();
|
|
5615
|
+
applyStatements(subgraph, stmt.children);
|
|
5616
|
+
commentHolder.apply(subgraph, stmt.location);
|
|
5617
|
+
break;
|
|
5618
|
+
case 'Attribute':
|
|
5619
|
+
graph.set(stmt.key.value, stmt.value.value);
|
|
5620
|
+
commentHolder.reset();
|
|
5621
|
+
break;
|
|
5622
|
+
case 'Node':
|
|
5623
|
+
commentHolder.apply(
|
|
5624
|
+
graph.node(
|
|
5625
|
+
stmt.id.value,
|
|
5626
|
+
stmt.children
|
|
5627
|
+
.filter((v) => v.type === 'Attribute')
|
|
5628
|
+
.reduce((prev, curr) => ({ ...prev, [curr.key.value]: curr.value.value }), {}),
|
|
5629
|
+
),
|
|
5630
|
+
stmt.location,
|
|
5631
|
+
);
|
|
5632
|
+
break;
|
|
5633
|
+
case 'Edge':
|
|
5634
|
+
commentHolder.apply(
|
|
5635
|
+
graph.edge(
|
|
5636
|
+
convertToEdgeTargetTuple(stmt),
|
|
5637
|
+
stmt.children
|
|
5638
|
+
.filter((v) => v.type === 'Attribute')
|
|
5639
|
+
.reduce((prev, curr) => ({ ...prev, [curr.key.value]: curr.value.value }), {}),
|
|
5640
|
+
),
|
|
5641
|
+
stmt.location,
|
|
5642
|
+
);
|
|
5643
|
+
break;
|
|
5644
|
+
case 'AttributeList':
|
|
5645
|
+
const attrs = stmt.children
|
|
5646
|
+
.filter((v) => v.type === 'Attribute')
|
|
5647
|
+
.reduce((prev, curr) => ({ ...prev, [curr.key.value]: curr.value.value }), {});
|
|
5648
|
+
switch (stmt.kind) {
|
|
5649
|
+
case 'Edge':
|
|
5650
|
+
graph.edge(attrs);
|
|
5651
|
+
break;
|
|
5652
|
+
case 'Node':
|
|
5653
|
+
graph.node(attrs);
|
|
5654
|
+
break;
|
|
5655
|
+
case 'Graph':
|
|
5656
|
+
graph.graph(attrs);
|
|
5657
|
+
break;
|
|
5658
|
+
}
|
|
5659
|
+
commentHolder.reset();
|
|
5660
|
+
break;
|
|
5661
|
+
case 'Comment':
|
|
5662
|
+
commentHolder.set(stmt);
|
|
5663
|
+
}
|
|
5664
|
+
}
|
|
5665
|
+
}
|
|
5666
|
+
|
|
5667
|
+
const GraphPlugin = {
|
|
5668
|
+
match(ast) {
|
|
5669
|
+
return ast.type === 'Graph';
|
|
5670
|
+
},
|
|
5671
|
+
convert(context, ast) {
|
|
5672
|
+
const G = ast.directed ? context.models.Digraph : context.models.Graph;
|
|
5673
|
+
const graph = new G(ast.id?.value, ast.strict);
|
|
5674
|
+
applyStatements(graph, ast.children);
|
|
5675
|
+
return graph;
|
|
5676
|
+
},
|
|
5677
|
+
};
|
|
5678
|
+
|
|
5679
|
+
const SubgraphPlugin = {
|
|
5680
|
+
match(ast) {
|
|
5681
|
+
return ast.type === 'Subgraph';
|
|
5682
|
+
},
|
|
5683
|
+
convert(context, ast) {
|
|
5684
|
+
const subgraph = new context.models.Subgraph(ast.id?.value);
|
|
5685
|
+
applyStatements(subgraph, ast.children);
|
|
5686
|
+
return subgraph;
|
|
5687
|
+
},
|
|
5688
|
+
};
|
|
5689
|
+
|
|
5690
|
+
const NodePlugin = {
|
|
5691
|
+
match(ast) {
|
|
5692
|
+
return ast.type === 'Node';
|
|
5693
|
+
},
|
|
5694
|
+
convert(context, ast) {
|
|
5695
|
+
const node = new context.models.Node(
|
|
5696
|
+
ast.id.value,
|
|
5697
|
+
ast.children
|
|
5698
|
+
.filter((v) => v.type === 'Attribute')
|
|
5699
|
+
.reduce((prev, curr) => ({ ...prev, [curr.key.value]: curr.value.value }), {}),
|
|
5700
|
+
);
|
|
5701
|
+
return node;
|
|
5702
|
+
},
|
|
5703
|
+
};
|
|
5704
|
+
|
|
5705
|
+
const defaultPlugins = [NodePlugin, EdgePlugin, SubgraphPlugin, GraphPlugin, DotPlugin];
|
|
5706
|
+
|
|
5707
|
+
/**
|
|
5708
|
+
* @group Convert AST to Model
|
|
5709
|
+
* @alpha
|
|
5710
|
+
*/
|
|
5711
|
+
class ToModelConverter {
|
|
5712
|
+
options;
|
|
5713
|
+
/** @hidden */
|
|
5714
|
+
plugins = [...defaultPlugins];
|
|
5715
|
+
constructor(options = {}) {
|
|
5716
|
+
this.options = options;
|
|
5717
|
+
}
|
|
5718
|
+
/**
|
|
5719
|
+
* Convert AST to Model.
|
|
5720
|
+
*
|
|
5721
|
+
* @param ast AST node.
|
|
5722
|
+
* @alpha
|
|
5723
|
+
*/
|
|
5724
|
+
convert(ast) {
|
|
5725
|
+
const plugins = [...this.plugins];
|
|
5726
|
+
const context = {
|
|
5727
|
+
models: createModelsContext(this.options.models ?? {}),
|
|
5728
|
+
convert(m) {
|
|
5729
|
+
for (const plugin of plugins) {
|
|
5730
|
+
if (plugin.match(m)) {
|
|
5731
|
+
return plugin.convert(context, m);
|
|
5732
|
+
}
|
|
5733
|
+
}
|
|
5734
|
+
throw Error();
|
|
5735
|
+
},
|
|
5736
|
+
};
|
|
5737
|
+
return context.convert(ast);
|
|
5738
|
+
}
|
|
5739
|
+
}
|
|
5740
|
+
|
|
5741
|
+
/**
|
|
5742
|
+
* @group Convert AST to Model
|
|
5743
|
+
* @beta
|
|
5744
|
+
*/
|
|
5745
|
+
function toModel(ast, options) {
|
|
5746
|
+
return new ToModelConverter(options).convert(ast);
|
|
5747
|
+
}
|
|
5748
|
+
|
|
5749
|
+
export {
|
|
5750
|
+
Builder,
|
|
5751
|
+
FromModelConverter,
|
|
5752
|
+
Printer,
|
|
5753
|
+
SyntaxError,
|
|
5754
|
+
ToModelConverter,
|
|
5755
|
+
createElement,
|
|
5756
|
+
fromModel,
|
|
5757
|
+
parse,
|
|
5758
|
+
stringify,
|
|
5759
|
+
toModel,
|
|
5760
|
+
};
|
package/lib/common/index.cjs
CHANGED
package/lib/common/index.js
CHANGED
package/lib/core/index.cjs
CHANGED
|
@@ -389,7 +389,7 @@ function withContext(models) {
|
|
|
389
389
|
*
|
|
390
390
|
* @group Convert Model to DOT
|
|
391
391
|
*
|
|
392
|
-
* @param model Dot Object Model, like {@link Digraph}, {@link Graph}, {@link Node}, and {@link Edge}
|
|
392
|
+
* @param model Dot Object Model, like {@link Digraph}, {@link Graph}, {@link Subgraph}, {@link Node}, and {@link Edge}
|
|
393
393
|
* @param options
|
|
394
394
|
* @returns DOT string
|
|
395
395
|
*/
|
|
@@ -398,6 +398,22 @@ function toDot(model, options) {
|
|
|
398
398
|
return ast.stringify(ast$1, options?.print);
|
|
399
399
|
}
|
|
400
400
|
|
|
401
|
+
function fromDot(dot, options) {
|
|
402
|
+
const ast$1 = ast.parse(dot, options?.parse);
|
|
403
|
+
if (
|
|
404
|
+
Array.isArray(ast$1) ||
|
|
405
|
+
ast$1.type === 'Attribute' ||
|
|
406
|
+
ast$1.type === 'AttributeList' ||
|
|
407
|
+
ast$1.type === 'Comment' ||
|
|
408
|
+
ast$1.type === 'NodeRef' ||
|
|
409
|
+
ast$1.type === 'NodeRefGroup' ||
|
|
410
|
+
ast$1.type === 'Literal'
|
|
411
|
+
) {
|
|
412
|
+
throw new Error();
|
|
413
|
+
}
|
|
414
|
+
return ast.toModel(ast$1, options?.convert);
|
|
415
|
+
}
|
|
416
|
+
|
|
401
417
|
exports.AttributeList = AttributeList;
|
|
402
418
|
exports.AttributesBase = AttributesBase;
|
|
403
419
|
exports.AttributesGroup = AttributesGroup;
|
|
@@ -411,6 +427,7 @@ exports.RootGraph = RootGraph;
|
|
|
411
427
|
exports.Subgraph = Subgraph;
|
|
412
428
|
exports.attribute = attribute;
|
|
413
429
|
exports.digraph = digraph;
|
|
430
|
+
exports.fromDot = fromDot;
|
|
414
431
|
exports.graph = graph;
|
|
415
432
|
exports.strict = strict;
|
|
416
433
|
exports.toDot = toDot;
|
package/lib/core/index.d.ts
CHANGED
|
@@ -29,7 +29,7 @@ import {
|
|
|
29
29
|
ClusterSubgraphAttributeKey,
|
|
30
30
|
DotObjectModel,
|
|
31
31
|
} from '#lib/common';
|
|
32
|
-
import { ConvertFromModelOptions, PrintOptions } from '#lib/ast';
|
|
32
|
+
import { ConvertFromModelOptions, PrintOptions, ParseOptions, ConvertToModelOptions } from '#lib/ast';
|
|
33
33
|
|
|
34
34
|
/**
|
|
35
35
|
* @group Attribute
|
|
@@ -2741,12 +2741,35 @@ interface ToDotOptions {
|
|
|
2741
2741
|
*
|
|
2742
2742
|
* @group Convert Model to DOT
|
|
2743
2743
|
*
|
|
2744
|
-
* @param model Dot Object Model, like {@link Digraph}, {@link Graph}, {@link Node}, and {@link Edge}
|
|
2744
|
+
* @param model Dot Object Model, like {@link Digraph}, {@link Graph}, {@link Subgraph}, {@link Node}, and {@link Edge}
|
|
2745
2745
|
* @param options
|
|
2746
2746
|
* @returns DOT string
|
|
2747
2747
|
*/
|
|
2748
2748
|
declare function toDot(model: DotObjectModel, options?: ToDotOptions): string;
|
|
2749
2749
|
|
|
2750
|
+
/**
|
|
2751
|
+
* @group Convert DOT to DOT
|
|
2752
|
+
* @alpha
|
|
2753
|
+
*/
|
|
2754
|
+
interface FromDotOptions<T extends 'Dot' | 'Graph' | 'Node' | 'Edge' | 'Subgraph'> {
|
|
2755
|
+
parse?: ParseOptions<T>;
|
|
2756
|
+
convert?: ConvertToModelOptions;
|
|
2757
|
+
}
|
|
2758
|
+
/**
|
|
2759
|
+
* Convert DOT string to Model.
|
|
2760
|
+
*
|
|
2761
|
+
* @group Convert DOT to Model
|
|
2762
|
+
*
|
|
2763
|
+
* @param dot DOT string
|
|
2764
|
+
* @param options
|
|
2765
|
+
* @returns Dot Object Model, like {@link Digraph}, {@link Graph}, {@link Subgraph}, {@link Node}, and {@link Edge}
|
|
2766
|
+
* @beta
|
|
2767
|
+
*/
|
|
2768
|
+
declare function fromDot(dot: string, options?: FromDotOptions<'Dot' | 'Graph'>): RootGraphModel;
|
|
2769
|
+
declare function fromDot(dot: string, options?: FromDotOptions<'Node'>): NodeModel;
|
|
2770
|
+
declare function fromDot(dot: string, options?: FromDotOptions<'Edge'>): EdgeModel;
|
|
2771
|
+
declare function fromDot(dot: string, options?: FromDotOptions<'Subgraph'>): SubgraphModel;
|
|
2772
|
+
|
|
2750
2773
|
export {
|
|
2751
2774
|
AttributeKeyDict,
|
|
2752
2775
|
AttributeList,
|
|
@@ -2755,6 +2778,7 @@ export {
|
|
|
2755
2778
|
Digraph,
|
|
2756
2779
|
DotObject,
|
|
2757
2780
|
Edge,
|
|
2781
|
+
FromDotOptions,
|
|
2758
2782
|
Graph,
|
|
2759
2783
|
GraphBase,
|
|
2760
2784
|
ModelFactories,
|
|
@@ -2766,6 +2790,7 @@ export {
|
|
|
2766
2790
|
ToDotOptions,
|
|
2767
2791
|
attribute,
|
|
2768
2792
|
digraph,
|
|
2793
|
+
fromDot,
|
|
2769
2794
|
graph,
|
|
2770
2795
|
strict,
|
|
2771
2796
|
toDot,
|
package/lib/core/index.js
CHANGED
|
@@ -6,7 +6,7 @@ import {
|
|
|
6
6
|
toNodeRef,
|
|
7
7
|
isNodeRefLike,
|
|
8
8
|
} from '#lib/common';
|
|
9
|
-
import { fromModel, stringify } from '#lib/ast';
|
|
9
|
+
import { fromModel, stringify, parse, toModel } from '#lib/ast';
|
|
10
10
|
|
|
11
11
|
/**
|
|
12
12
|
* @group Attribute
|
|
@@ -392,7 +392,7 @@ function withContext(models) {
|
|
|
392
392
|
*
|
|
393
393
|
* @group Convert Model to DOT
|
|
394
394
|
*
|
|
395
|
-
* @param model Dot Object Model, like {@link Digraph}, {@link Graph}, {@link Node}, and {@link Edge}
|
|
395
|
+
* @param model Dot Object Model, like {@link Digraph}, {@link Graph}, {@link Subgraph}, {@link Node}, and {@link Edge}
|
|
396
396
|
* @param options
|
|
397
397
|
* @returns DOT string
|
|
398
398
|
*/
|
|
@@ -401,6 +401,22 @@ function toDot(model, options) {
|
|
|
401
401
|
return stringify(ast, options?.print);
|
|
402
402
|
}
|
|
403
403
|
|
|
404
|
+
function fromDot(dot, options) {
|
|
405
|
+
const ast = parse(dot, options?.parse);
|
|
406
|
+
if (
|
|
407
|
+
Array.isArray(ast) ||
|
|
408
|
+
ast.type === 'Attribute' ||
|
|
409
|
+
ast.type === 'AttributeList' ||
|
|
410
|
+
ast.type === 'Comment' ||
|
|
411
|
+
ast.type === 'NodeRef' ||
|
|
412
|
+
ast.type === 'NodeRefGroup' ||
|
|
413
|
+
ast.type === 'Literal'
|
|
414
|
+
) {
|
|
415
|
+
throw new Error();
|
|
416
|
+
}
|
|
417
|
+
return toModel(ast, options?.convert);
|
|
418
|
+
}
|
|
419
|
+
|
|
404
420
|
export {
|
|
405
421
|
AttributeList,
|
|
406
422
|
AttributesBase,
|
|
@@ -415,6 +431,7 @@ export {
|
|
|
415
431
|
Subgraph,
|
|
416
432
|
attribute,
|
|
417
433
|
digraph,
|
|
434
|
+
fromDot,
|
|
418
435
|
graph,
|
|
419
436
|
strict,
|
|
420
437
|
toDot,
|
package/media/state-machine.svg
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
<svg width="
|
|
1
|
+
<svg width="404" height="197pt" viewBox="0 0 302.59 196.79" xmlns="http://www.w3.org/2000/svg"><g class="graph" transform="translate(4 192.79)"><path fill="#fff" stroke="transparent" d="M-4 4v-196.79h302.59V4H-4z"/><g class="node"><circle fill="none" stroke="#000" cx="52.59" cy="-149.14" r="39.79"/><text text-anchor="middle" x="52.59" y="-145.44" font-family="Times,serif" font-size="14">Model</text></g><g class="node"><circle fill="none" stroke="#000" cx="218.59" cy="-149.14" r="31.4"/><text text-anchor="middle" x="218.59" y="-145.44" font-family="Times,serif" font-size="14">DOT</text></g><g class="edge"><path fill="none" stroke="#000" d="M90.64-137.1c9.44 2.47 19.6 4.7 29.18 5.96 17.63 2.32 22.42 2.63 40 0 6.37-.96 13.01-2.46 19.43-4.2"/><path stroke="#000" d="m178.51-138.77 10.58.54-8.61 6.17-1.97-6.71z"/><text text-anchor="middle" x="139.82" y="-134.94" font-family="Times,serif" font-size="14">toDot</text></g><g class="node"><circle fill="none" stroke="#000" cx="146.59" cy="-29.25" r="29.5"/><text text-anchor="middle" x="146.59" y="-25.55" font-family="Times,serif" font-size="14">AST</text></g><g class="edge"><path fill="none" stroke="#000" d="M21.2-124.93C5.91-110.76-6.93-92.37 4.59-76.49c23.16 31.9 68.9 42.22 102.23 45.34"/><path stroke="#000" d="m107.45-34.61 9.71 4.24-10.23 2.74.52-6.98z"/><text text-anchor="middle" x="44.09" y="-80.29" font-family="Times,serif" font-size="14">fromModel</text></g><g class="edge"><path fill="none" stroke="#000" d="M187.19-149.14h-84.61"/><path stroke="#000" d="m102.36-145.64-10-3.5 10-3.5v7z"/><text text-anchor="middle" x="139.82" y="-155.94" font-family="Times,serif" font-size="14">fromDot</text></g><g class="edge"><path fill="none" stroke="#000" d="M202.62-121.98c-10.54 17.26-24.44 40.01-35.75 58.54"/><path stroke="#000" d="m169.75-61.44-8.2 6.71 2.22-10.36 5.98 3.65z"/><text text-anchor="middle" x="202.59" y="-80.29" font-family="Times,serif" font-size="14">parse</text></g><g class="edge"><path fill="none" stroke="#000" d="M128.8-52.57c-12.81-16.06-30.42-38.14-45.48-57.03"/><path stroke="#000" d="m80.54-107.47-3.49-10 8.97 5.63-5.48 4.37z"/><text text-anchor="middle" x="138.09" y="-80.29" font-family="Times,serif" font-size="14">toModel</text></g><g class="edge"><path fill="none" stroke="#000" d="M174.74-37.96c18.87-6.8 42.31-18.78 53.85-38.53 5.88-10.07 6.19-22.25 4.18-33.7"/><path stroke="#000" d="m229.35-109.45 1.15-10.53 5.67 8.95-6.82 1.58z"/><text text-anchor="middle" x="264.09" y="-80.29" font-family="Times,serif" font-size="14">stringify</text></g></g></svg>
|
package/media/ts-graphviz.svg
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
<svg width="
|
|
1
|
+
<svg width="503pt" height="196pt" viewBox="0 0 502.69 195.5" xmlns="http://www.w3.org/2000/svg"><g class="graph" transform="translate(4 191.5)"><path fill="#fff" stroke="transparent" d="M-4 4v-195.5h502.69V4H-4z"/><g class="node"><path fill="none" stroke="#000" d="M13-96v-91h194v91H13z"/><text text-anchor="middle" x="110" y="-171.8" font-family="Times,serif" font-size="14">Model Factory Functions</text><path fill="none" stroke="#000" d="M13-164h194"/><text x="21" y="-148.8" font-family="Times,serif" font-size="14">strict.digraph(...)</text><text x="21" y="-133.8" font-family="Times,serif" font-size="14">strict.graph(...)</text><text x="21" y="-118.8" font-family="Times,serif" font-size="14">digraph(...)</text><text x="21" y="-103.8" font-family="Times,serif" font-size="14">graph(...)</text></g><g class="node"><circle fill="none" stroke="#000" cx="296.65" cy="-89.5" r="39.79"/><text text-anchor="middle" x="296.65" y="-85.8" font-family="Times,serif" font-size="14">Model</text></g><g class="edge"><path fill="none" stroke="#000" d="M207.11-114.43c14.38 4.05 28.64 8.06 41.38 11.65"/><path stroke="#000" d="m249.67-106.08 8.68 6.08-10.57.65 1.89-6.73z"/></g><g class="node"><path fill="none" stroke="#000" d="M0-.5v-76h220v76H0z"/><text text-anchor="middle" x="110" y="-61.3" font-family="Times,serif" font-size="14">Object Oriented Programing</text><path fill="none" stroke="#000" d="M0-53.5h220"/><text x="8" y="-38.3" font-family="Times,serif" font-size="14">new Digraph(...)</text><text x="8" y="-23.3" font-family="Times,serif" font-size="14">new Graph(...)</text><text x="8" y="-8.3" font-family="Times,serif" font-size="14">...</text></g><g class="edge"><path fill="none" stroke="#000" d="M220.01-68.61c9.87-2.73 19.48-5.38 28.35-7.83"/><path stroke="#000" d="m247.47-79.82 10.57.71-8.7 6.03-1.87-6.74z"/></g><g class="node"><circle fill="none" stroke="#000" cx="463.49" cy="-89.5" r="31.4"/><text text-anchor="middle" x="463.49" y="-85.8" font-family="Times,serif" font-size="14">DOT</text></g><g class="edge"><path fill="none" stroke="#000" d="M336.3-89.5h85.43"/><path stroke="#000" d="m422.05-93 10 3.5-10 3.5v-7z"/><text text-anchor="middle" x="384.29" y="-93.3" font-family="Times,serif" font-size="14">toDot</text></g><g class="edge"><path fill="none" stroke="#000" d="M434.99-76.62c-6.64 2.54-13.8 4.81-20.7 6.12-26.2 4.98-33.68 4.3-60 0-3.48-.57-7.04-1.32-10.59-2.2"/><path stroke="#000" d="m342.47-69.41-8.7-6.05 10.58-.69-1.88 6.74z"/><text text-anchor="middle" x="384.29" y="-74.3" font-family="Times,serif" font-size="14">fromDot</text></g></g></svg>
|