Skip to content

Commit

Permalink
Started railroad rendering
Browse files Browse the repository at this point in the history
  • Loading branch information
nirname committed Sep 13, 2023
1 parent f6e9444 commit 438d23e
Show file tree
Hide file tree
Showing 9 changed files with 215 additions and 120 deletions.
132 changes: 67 additions & 65 deletions packages/mermaid/src/diagrams/railroad/railroadDB.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,13 +8,17 @@ const clear = (): void => {
commonClear();
};

// unite all rules
// split by rules
// show states
// display states
// Styles
//
// unite rules
// split rules
//
// show states / display states
// hide states
// shape of non-terminals
// shape of terminals
//
// shapes of non-terminals
// shapes of terminals
//
// start
// end

Expand All @@ -27,30 +31,46 @@ const clear = (): void => {
// null
// type ruleID = string;

let rules: Record<string, Chunk> = {};
type Rules = Record<string, Chunk>;

let rules: Rules = {};

Check failure on line 36 in packages/mermaid/src/diagrams/railroad/railroadDB.ts

View workflow job for this annotation

GitHub Actions / lint (18.x)

'rules' is never reassigned. Use 'const' instead

const getConsole = () => console;

class Chunk {
// start?: State;
// end?: State;
// render: () => void;
type(): string {
return 'Chunk';
interface Chunk {
traverse<T>(callback: (item: Chunk, nested?: T[]) => T): T;
toString(): string;
}

class Leaf implements Chunk {
constructor(public label: string) {}

traverse<T>(callback: (item: Chunk, nested?: T[]) => T): T {
return callback(this);
}

// [util.inspect.custom](): string {
// return this.toString();
// }
toString(): string {
return this.label;
}
}

class Node implements Chunk {
constructor(public child: Chunk) {}

// should be wrapped?
traverse<T>(callback: (item: Chunk, nested?: T[]) => T): T {
const nested = this.child.traverse(callback);

needsWrapping(): boolean {
return false;
return callback(this, [nested]);
}
}

class Chain implements Chunk {
constructor(public children: Chunk[]) {}

traverse<T>(callback: (item: Chunk, nested?: T[]) => T): T {
const nested = this.children.map((child) => child.traverse(callback));

wrap(): string {
return '(' + this.toString() + ')';
return callback(this, nested);
}
}

Expand All @@ -59,87 +79,63 @@ class Chunk {
// It is implied that every chunk has `start` and `end` states
// But we do not create them, simply keeping transition 'body' with label
//
class Epsilon extends Chunk {
toString(): string {
return 'ɛ';
class Epsilon extends Leaf {
constructor() {
super('ɛ');
}
}

class Term extends Chunk {
// remote quote???
class Term extends Leaf {
constructor(public label: string, public quote: string) {
super();
}
toString(): string {
return this.quote + this.label + this.quote;
super(label);
}
}

class NonTerm extends Chunk {
constructor(public label: string) {
super();
}
toString(): string {
return '<' + this.label + '>';
return this.quote + super.toString() + this.quote;
}
}

class Chain extends Chunk {
constructor(public chunks: Chunk[]) {
super();
}

needsWrapping(): boolean {
return this.chunks.length > 1;
class NonTerm extends Leaf {
toString(): string {
return '<' + super.toString() + '>';
}
}

// Chain of chunks splitted by |
//
class Choice extends Chain {
toString(): string {
// const content = '[a' + (this.needsWrapping() ? 'Y' : 'N') + this.chunks.join('|') + 'a]';
const content = this.chunks.join('|');
const content = this.children.join('|');
// if (this.needsWrapping())
return '(a' + content + 'a)';
// return content;
}
}

// Chain of chunks splitted by , (optionally)
//
class Sequence extends Chain {
toString(): string {
// return '[d' + (this.needsWrapping() ? 'Y' : 'N') + this.chunks.join(',') + 'd]';
const content = this.chunks.join(',');
const content = this.children.join(',');
// if (this.needsWrapping())
return '(c' + content + 'c)';
}
}

class OneOrMany extends Chunk {
constructor(public chunk: Chunk) {
super();
}
class OneOrMany extends Node {
toString(): string {
return this.chunk + '+';
return this.child + '+';
}
}

class ZeroOrOne extends Chunk {
constructor(public chunk: Chunk) {
super();
}
class ZeroOrOne extends Node {
toString(): string {
return this.chunk + '?';
return this.child + '?';
}
}

class ZeroOrMany extends Chunk {
constructor(public chunk: Chunk) {
super();
}
class ZeroOrMany extends Node {
toString(): string {
return this.chunk + '?';
return this.child + '?';
}
}

Expand Down Expand Up @@ -178,7 +174,7 @@ const addSequence = (chunks: Chunk[]): Chunk => {
chunks = chunks
.map((chunk) => {

Check failure on line 175 in packages/mermaid/src/diagrams/railroad/railroadDB.ts

View workflow job for this annotation

GitHub Actions / lint (18.x)

Prefer `.flatMap(…)` over `.map(…).flat()`
if (chunk instanceof Sequence) {
return chunk.chunks;
return chunk.children;
}
return chunk;
})
Expand All @@ -201,7 +197,7 @@ const addChoice = (chunks: Chunk[]): Chunk => {
chunks = chunks
.map((chunk) => {

Check failure on line 198 in packages/mermaid/src/diagrams/railroad/railroadDB.ts

View workflow job for this annotation

GitHub Actions / lint (18.x)

Prefer `.flatMap(…)` over `.map(…).flat()`
if (chunk instanceof Choice) {
return chunk.chunks;
return chunk.children;
}
return chunk;
})
Expand All @@ -219,6 +215,10 @@ const addEpsilon = (): Chunk => {
return new Epsilon();
};

const getRules = (): Rules => {
return rules;
};

export interface RailroadDB extends DiagramDB {
addChoice: (chunks: Chunk[]) => Chunk;
addEpsilon: () => Chunk;
Expand All @@ -231,6 +231,7 @@ export interface RailroadDB extends DiagramDB {
addZeroOrOne: (chunk: Chunk) => Chunk;
clear: () => void;
getConsole: () => Console;
getRules: () => Rules;
}

export const db: RailroadDB = {
Expand All @@ -246,4 +247,5 @@ export const db: RailroadDB = {
clear,
getConfig: () => configApi.getConfig().railroad,
getConsole,
getRules,
};
Loading

0 comments on commit 438d23e

Please sign in to comment.