Stream: allow edge attributes, autoclose nodes
This commit is contained in:
@ -22,7 +22,11 @@ interface Stringable {
|
||||
|
||||
export class GraphStream extends Transform {
|
||||
private _path: string[] = [];
|
||||
private _state: GraphStreamCommand | '' = '';
|
||||
private _state: (GraphStreamCommand | '')[] = [
|
||||
'',
|
||||
''
|
||||
];
|
||||
|
||||
private _directional = false;
|
||||
|
||||
public get path (): string {
|
||||
@ -33,6 +37,16 @@ export class GraphStream extends Transform {
|
||||
return ' '.repeat (this._path.length);
|
||||
}
|
||||
|
||||
private finish_node ():void {
|
||||
if (
|
||||
[
|
||||
'ce',
|
||||
'cn'
|
||||
].includes (this._state[1])
|
||||
)
|
||||
this.push ('\n');
|
||||
}
|
||||
|
||||
private expect_state (instr: GraphStreamCommand): void {
|
||||
const states: (GraphStreamCommand|'')[] = [];
|
||||
if ([
|
||||
@ -47,24 +61,21 @@ export class GraphStream extends Transform {
|
||||
'csg',
|
||||
'ce'
|
||||
].includes (instr))
|
||||
states.push ('en', 'at', 'eg', 'cug', 'cdg', 'csg', 'ce');
|
||||
states.push ('at', 'eg', 'cug', 'cdg', 'csg', 'ce', 'cn');
|
||||
|
||||
switch (instr) {
|
||||
case 'en':
|
||||
states.push ('cn', 'at');
|
||||
break;
|
||||
case 'at':
|
||||
states.push ('cn', 'cug', 'cdg', 'csg');
|
||||
states.push ('cn', 'cug', 'cdg', 'csg', 'ce');
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
if (!states.includes (this._state)) {
|
||||
if (!states.includes (this._state[1])) {
|
||||
throw new Error (`invalid state to execute command ${
|
||||
translate_command (instr)}
|
||||
expected: ${states.map ((s) => translate_command (s))
|
||||
.join (', ')}
|
||||
actual: ${translate_command (this._state)}`);
|
||||
actual: ${translate_command (this._state[1])}`);
|
||||
}
|
||||
}
|
||||
|
||||
@ -89,24 +100,27 @@ export class GraphStream extends Transform {
|
||||
this._directional = true;
|
||||
break;
|
||||
case 'csg': // create subgraph
|
||||
this.finish_node ();
|
||||
this.push (
|
||||
`${this.level}subgraph cluster_${this.path}_${instr.args[0]} {\n`
|
||||
);
|
||||
this._path.push (instr.args[0]);
|
||||
break;
|
||||
case 'eg': // end graph
|
||||
this.finish_node ();
|
||||
this._path.pop ();
|
||||
this.push (`${this.level}}\n\n`);
|
||||
break;
|
||||
case 'cn': // create node
|
||||
this.finish_node ();
|
||||
this.push (`${this.level}${this.path}_${instr.args[0]}`);
|
||||
break;
|
||||
case 'en': // end node
|
||||
this.push ('\n');
|
||||
break;
|
||||
case 'at': // add attributes
|
||||
if (this._state === 'cn') {
|
||||
this.push (` [${instr.args.join (', ')}]`);
|
||||
if ([
|
||||
'cn',
|
||||
'ce'
|
||||
].includes (this._state[1])) {
|
||||
this.push (` [${instr.args.join (', ')}]\n`);
|
||||
}
|
||||
else {
|
||||
this.push (`${this.level}${
|
||||
@ -116,14 +130,16 @@ export class GraphStream extends Transform {
|
||||
}
|
||||
break;
|
||||
case 'ce':
|
||||
this.finish_node ();
|
||||
this.push (`${this.level}${
|
||||
instr.args[0]
|
||||
} -${this._directional ? '>' : '-'} ${instr.args[1]}\n`);
|
||||
} -${this._directional ? '>' : '-'} ${instr.args[1]}`);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
this._state = instr.type;
|
||||
this._state.push (instr.type);
|
||||
this._state.shift ();
|
||||
callback ();
|
||||
}
|
||||
|
||||
@ -139,8 +155,11 @@ export class GraphStream extends Transform {
|
||||
return `${this.path}_${node_name}`;
|
||||
}
|
||||
|
||||
/**
|
||||
* @deprecated calling this method is not needed anymore
|
||||
*/
|
||||
public end_node (): void {
|
||||
this.write ({ type: 'en', args: [] });
|
||||
// this.write ({ type: 'en', args: [] });
|
||||
}
|
||||
|
||||
public create_graph (name: string, type: 'u'|'d'|'s' = 's'): void {
|
||||
|
Reference in New Issue
Block a user