This repository has been archived by the owner on Dec 12, 2022. It is now read-only.
-
-
Notifications
You must be signed in to change notification settings - Fork 1
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
add @ts-graphviz/[email protected] as parser/mode.ts
- Loading branch information
Showing
10 changed files
with
5,163 additions
and
36 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,5 @@ | ||
usecase.ts | ||
ast.ts | ||
convert.ts | ||
dot_pegjs.ts | ||
mod.ts |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,143 @@ | ||
import { Compass } from "../mod.ts"; | ||
import { parse as _parse, SyntaxError } from "./dot_pegjs.ts"; | ||
export namespace AST { | ||
type ValueOf<T> = T[keyof T]; | ||
export const Types = Object.freeze( | ||
{ | ||
Graph: "graph", | ||
Attribute: "attribute", | ||
Attributes: "attributes", | ||
Edge: "edge", | ||
Node: "node", | ||
Subgraph: "subgraph", | ||
} as const, | ||
); | ||
export type Types = ValueOf<typeof Types>; | ||
export interface Graph { | ||
type: typeof Types.Graph; | ||
id?: string; | ||
directed: boolean; | ||
strict: boolean; | ||
children: GraphObject[]; | ||
} | ||
export interface KeyValue { | ||
key: string; | ||
value: string; | ||
} | ||
export interface Attribute extends KeyValue { | ||
type: typeof Types.Attribute; | ||
} | ||
export namespace Attributes { | ||
export const Target = Object.freeze( | ||
{ | ||
Graph: "graph", | ||
Edge: "edge", | ||
Node: "node", | ||
} as const, | ||
); | ||
export type Target = ValueOf<typeof Target>; | ||
} | ||
export interface Attributes { | ||
type: typeof Types.Attributes; | ||
target: Attributes.Target; | ||
attributes: KeyValue[]; | ||
} | ||
export interface ID { | ||
id: string; | ||
port?: string; | ||
commpass?: Compass; | ||
} | ||
export interface Edge { | ||
type: typeof Types.Edge; | ||
targets: ID[]; | ||
attributes: KeyValue[]; | ||
} | ||
export interface Node { | ||
type: typeof Types.Node; | ||
id: string; | ||
attributes: KeyValue[]; | ||
} | ||
export interface Subgraph { | ||
type: typeof Types.Subgraph; | ||
id?: string; | ||
children: GraphObject[]; | ||
} | ||
export type GraphObject = Attribute | Attributes | Edge | Node | Subgraph; | ||
/** | ||
* The basic usage is the same as the `parse` function, | ||
* except that it returns the dot language AST. | ||
* | ||
* ```ts | ||
* import { inspect } from 'util'; | ||
* import { AST } from '@ts-graphviz/parser'; | ||
* | ||
* const ast = AST.parse(` | ||
* strict digraph example { | ||
* subgraph cluster_0 { | ||
* label="Subgraph A"; | ||
* a -> b -> c -> d; | ||
* } | ||
* | ||
* subgraph cluster_1 { | ||
* label="Subgraph B"; | ||
* a -> f; | ||
* f -> c; | ||
* } | ||
* } | ||
* `); | ||
* | ||
* console.log(inspect(ast, false, 6)); | ||
* ``` | ||
* | ||
* In the case of the above code, the structure of AST is as follows. | ||
* | ||
* ```ts | ||
* { | ||
* kind: 'graph', | ||
* id: 'example', | ||
* directed: true, | ||
* strict: true, | ||
* children: [ | ||
* { | ||
* kind: 'subgraph', | ||
* id: 'cluster_0', | ||
* children: [ | ||
* { kind: 'attribute', key: 'label', value: 'Subgraph A' }, | ||
* { | ||
* kind: 'edge', | ||
* targets: [ { id: 'a' }, { id: 'b' }, { id: 'c' }, { id: 'd' } ], | ||
* attributes: [] | ||
* } | ||
* ] | ||
* }, | ||
* { | ||
* kind: 'subgraph', | ||
* id: 'cluster_1', | ||
* children: [ | ||
* { kind: 'attribute', key: 'label', value: 'Subgraph B' }, | ||
* { | ||
* kind: 'edge', | ||
* targets: [ { id: 'a' }, { id: 'f' } ], | ||
* attributes: [] | ||
* }, | ||
* { | ||
* kind: 'edge', | ||
* targets: [ { id: 'f' }, { id: 'c' } ], | ||
* attributes: [] | ||
* } | ||
* ] | ||
* } | ||
* ] | ||
* } | ||
* ``` | ||
* @throws {SyntaxError} | ||
*/ | ||
export function parse(dot: string): Graph { | ||
try { | ||
return _parse(dot); | ||
} catch (error) { | ||
Object.setPrototypeOf(error, SyntaxError.prototype); | ||
throw error; | ||
} | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,62 @@ | ||
import { Digraph, Graph, ICluster, RootCluster } from "../mod.ts"; | ||
import { AST } from "./ast.ts"; | ||
function applyToCluster(cluster: ICluster, stmts: AST.GraphObject[]): void { | ||
for (const stmt of stmts) { | ||
switch (stmt.type) { | ||
case AST.Types.Subgraph: | ||
const subgraph = stmt.id | ||
? cluster.subgraph(stmt.id) | ||
: cluster.subgraph(); | ||
applyToCluster(subgraph, stmt.children); | ||
break; | ||
case AST.Types.Attribute: | ||
cluster.set(stmt.key, stmt.value); | ||
break; | ||
case AST.Types.Node: | ||
cluster.node( | ||
stmt.id, | ||
stmt.attributes.reduce( | ||
(prev, curr) => ({ ...prev, [curr.key]: curr.value }), | ||
{}, | ||
), | ||
); | ||
break; | ||
case AST.Types.Edge: | ||
cluster.edge( | ||
stmt.targets.map((t) => ({ | ||
id: t.id, | ||
port: t.port, | ||
compass: t.commpass, | ||
})), | ||
stmt.attributes.reduce( | ||
(prev, curr) => ({ ...prev, [curr.key]: curr.value }), | ||
{}, | ||
), | ||
); | ||
break; | ||
case AST.Types.Attributes: | ||
const attrs = stmt.attributes.reduce( | ||
(prev, curr) => ({ ...prev, [curr.key]: curr.value }), | ||
{}, | ||
); | ||
switch (stmt.target) { | ||
case AST.Attributes.Target.Edge: | ||
cluster.edge(attrs); | ||
break; | ||
case AST.Attributes.Target.Node: | ||
cluster.node(attrs); | ||
break; | ||
case AST.Attributes.Target.Graph: | ||
cluster.graph(attrs); | ||
break; | ||
} | ||
break; | ||
} | ||
} | ||
} | ||
export function convert(root: AST.Graph): RootCluster { | ||
const Root = root.directed ? Digraph : Graph; | ||
const g = new Root(root.id, root.strict); | ||
applyToCluster(g, root.children); | ||
return g; | ||
} |
Oops, something went wrong.