Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Railroad diagrams #4608

Draft
wants to merge 25 commits into
base: develop
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
25 commits
Select commit Hold shift + click to select a range
30801a4
Started railroad diagrams
nirname Jul 6, 2023
0bbe757
Added railroad config
nirname Sep 10, 2023
3a456fe
Syntax description
nirname Sep 11, 2023
2e99c99
More grammar examples
nirname Sep 11, 2023
f6e9444
Prettify
nirname Sep 11, 2023
438d23e
Started railroad rendering
nirname Sep 13, 2023
c386d49
Added traverse functions to railroad db
nirname Sep 16, 2023
be89ccb
Extended railroad config
nirname Sep 23, 2023
9a04d80
Merge branch 'develop' into feature/4252_railroad-diagrams
nirname Sep 23, 2023
dbaa79c
Renamed some properties of the diagram
nirname Sep 23, 2023
dd5fa3e
Merge branch 'develop' into feature/4252_railroad-diagrams
nirname Sep 23, 2023
681d8c9
Extended railroad config
nirname Sep 24, 2023
a2fc6e8
Railroad: Treat empty string as epsilon, grammar reduction
nirname Sep 24, 2023
6ee69a9
Wokring on grammar
nirname Oct 3, 2023
59ec47d
Merge branch 'develop' into feature/4252_railroad-diagrams
nirname Oct 3, 2023
d7f3320
Merge branch 'develop' into feature/4252_railroad-diagrams
nirname Oct 6, 2023
2915ec2
Merge branch 'develop' into feature/4252_railroad-diagrams
nirname Oct 22, 2023
ad675c1
Merge remote-tracking branch 'nirname/develop' into feature/4252_rail…
nirname Nov 4, 2023
6c82800
Merge branch 'develop' into feature/4252_railroad-diagrams
nirname Nov 11, 2023
336f37f
Merge branch 'develop' into feature/4252_railroad-diagrams
nirname Nov 29, 2023
acc82eb
Merge branch 'develop' into feature/4252_railroad-diagrams
nirname Jun 19, 2024
9f267b5
Example was broken and page was stuck in case of rendering error
nirname Jun 20, 2024
64116f2
Improved development page once more
nirname Jun 20, 2024
5a9e017
Restructuring DB
nirname Jun 21, 2024
4cb8cc1
Separated renderer
nirname Jun 21, 2024
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
13 changes: 13 additions & 0 deletions __mocks__/railroadRenderer.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
/**
* Mocked Railroad diagram renderer
*/

import { vi } from 'vitest';

export const draw = vi.fn().mockImplementation(() => {
return '';
});

export default {
draw,
};
Empty file.
20 changes: 17 additions & 3 deletions demos/dev/example.html
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,8 @@
</style>
</head>
<body>
<h1>Mermaid development page</h1>
<h2>Static diagram example</h2>
<pre id="diagram" class="mermaid">
graph TB
a --> b
Expand All @@ -30,20 +32,26 @@
</pre>

<hr />
<h2>Dynamic diagram example</h2>
Type code to view diagram:
<div class="container">
<textarea name="code" id="code" cols="30" rows="10"></textarea>
<div id="dynamicDiagram"></div>
</div>
<button id="render" type="button">Render</button>
<pre class="mermaid">info</pre>

<script type="module">
import mermaid from '/mermaid.esm.mjs';
import flowchartELK from '/mermaid-flowchart-elk.esm.mjs';
await mermaid.registerExternalDiagrams([flowchartELK]);
async function render(str) {
const { svg } = await mermaid.render('dynamic', str);
document.getElementById('dynamicDiagram').innerHTML = svg;
try {
const { svg } = await mermaid.render('dynamic', str);
document.getElementById('dynamicDiagram').innerHTML = svg;
} catch (error) {
console.error(error);
}
}
const storeKey = window.location.pathname;
const code = localStorage.getItem(storeKey);
Expand All @@ -58,8 +66,14 @@
document.getElementById('code').addEventListener('input', async (e) => {
const value = e.target.value;
localStorage.setItem(storeKey, value);
await render(value);
render(value);
});

document.getElementById('render').addEventListener('click', async (e) => {
const value = document.getElementById('code').target.value;
localStorage.setItem(storeKey, value);
await render(value);
})
</script>

<script src="/dev/reload.js"></script>
Expand Down
4 changes: 3 additions & 1 deletion demos/index.html
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,6 @@
<link rel="icon" type="image/png" href="data:image/png;base64,iVBORw0KGgo=" />
<style>
div.mermaid {
/* font-family: 'trebuchet ms', verdana, arial; */
font-family: 'Courier New', Courier, monospace !important;
}
</style>
Expand Down Expand Up @@ -88,6 +87,9 @@ <h2><a href="./packet.html">Packet</a></h2>
<li>
<h2><a href="./block.html">Layered Blocks</a></h2>
</li>
<li>
<h2><a href="./railroad.html">Railroad</a></h2>
</li>
</ul>
</body>
</html>
60 changes: 60 additions & 0 deletions demos/railroad.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,60 @@
<!DOCTYPE html>
<html lang="en" xmlns="http://www.w3.org/1999/html">
<head>
<meta charset="utf-8" />
<meta http-equiv="X-UA-Compatible" content="IE=edge" />
<title>Railroad Mermaid Quick Test Page</title>
<link rel="icon" type="image/png" href="data:image/png;base64,iVBORw0KGgo=" />
<style>
div.mermaid {
font-family: 'Courier New', Courier, monospace !important;
}
</style>
</head>

<body>
<h1>Railroad diagram demos</h1>
<h2>Example</h2>
<pre class="mermaid">
railroad-beta

commandline ::= list
| list ";"
| list "&"
;

list ::= conditional
| list ";" conditional
| list "&" conditional
;

conditional ::= pipeline
| conditional "&&" pipeline
| conditional "||" pipeline
;

pipeline ::= command
| pipeline "|" command
;

command ::= word
| redirection
| command word
| command redirection
;

redirection ::= redirectionop filename;
redirectionop ::= "<" | ">" | "2>";
</pre>

<script type="module">
import mermaid from './mermaid.esm.mjs';
mermaid.initialize({
theme: 'default',
logLevel: 3,
securityLevel: 'loose',
railroad: {},
});
</script>
</body>
</html>
3 changes: 1 addition & 2 deletions docker-compose.yml
Original file line number Diff line number Diff line change
@@ -1,4 +1,3 @@
version: '3.9'
services:
mermaid:
build:
Expand All @@ -8,7 +7,7 @@ services:
tty: true
working_dir: /mermaid
mem_limit: '8G'
entrypoint: docker-entrypoint.sh
entrypoint: ./docker-entrypoint.sh
environment:
- NODE_OPTIONS=--max_old_space_size=8192
volumes:
Expand Down
1 change: 0 additions & 1 deletion packages/mermaid/scripts/create-types-from-json-schema.mts
Original file line number Diff line number Diff line change
Expand Up @@ -127,7 +127,6 @@ async function generateTypescript(mermaidConfigSchema: JSONSchemaType<MermaidCon
assert.ok(mermaidConfigSchema.$defs);
const modifiedSchema = {
...removeRequired(mermaidConfigSchema),

$defs: Object.fromEntries(
Object.entries(mermaidConfigSchema.$defs).map(([key, subSchema]) => {
return [key, removeRequired(replaceAllOfWithExtends(subSchema))];
Expand Down
82 changes: 82 additions & 0 deletions packages/mermaid/src/config.type.ts
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,15 @@ export type SankeyLinkColor = 'source' | 'target' | 'gradient';
* via the `definition` "SankeyNodeAlignment".
*/
export type SankeyNodeAlignment = 'left' | 'right' | 'center' | 'justify';
export type RailroadDiagramFormat = RailroadDiagramFormat;
/**
* Shapes of the first and the last state in the diagram
*
*
* This interface was referenced by `MermaidConfig`'s JSON-Schema
* via the `definition` "RailroadDiagramBoundaryShape".
*/
export type RailroadDiagramBoundaryShape = 'dot' | 'circle' | 'forward' | 'backward';
/**
* Configuration options to pass to the `dompurify` library.
*/
Expand Down Expand Up @@ -161,6 +170,7 @@ export interface MermaidConfig {
gitGraph?: GitGraphDiagramConfig;
c4?: C4DiagramConfig;
sankey?: SankeyDiagramConfig;
railroad?: RailroadDiagramConfig;
packet?: PacketDiagramConfig;
block?: BlockDiagramConfig;
dompurifyConfig?: DOMPurifyConfiguration;
Expand Down Expand Up @@ -1422,6 +1432,62 @@ export interface SankeyDiagramConfig extends BaseDiagramConfig {
*/
suffix?: string;
}
/**
* The object containing configurations specific for railroad diagrams.
*
* This interface was referenced by `MermaidConfig`'s JSON-Schema
* via the `definition` "RailroadDiagramConfig".
*/
export interface RailroadDiagramConfig extends BaseDiagramConfig {
alignment?: 'left' | 'right' | 'center' | 'justify';
verticalAlignment?: 'top' | 'bottom' | 'center' | 'justify';
/**
* Wrap long grammars similarly to wrapping long lines
*
*/
wrapDiagram?: boolean;
/**
* Specify which standart would be applied
*
*/
syntax?: 'mermaid' | 'w3c' | 'iso';
/**
* Compress rules to get the smallest possible diagram
*
*/
compress?: boolean;
/**
* List of things to render
*
*/
render?: ('railroad' | 'ebnf' | 'bnf' | 'dfa' | 'nfa')[];
format?: RailroadDiagramFormat;
drawArrows?: boolean;
inline?: boolean;
inlineItems?: string[];
/**
* Name of the initial rule in grammar
* First rule will be initial if it is null
*
*/
start?: string | null;
shapes?: {
terminal?: string;
non_terminal?: string;
/**
* Shape or list of shapes for the start element
* They will be applied in the order of occurrence
*
*/
start?: RailroadDiagramBoundaryShape[] | RailroadDiagramBoundaryShape;
/**
* Shape or list of shapes for the end element
* They will be applied in the order of occurrence
*
*/
end?: RailroadDiagramBoundaryShape[] | RailroadDiagramBoundaryShape;
};
}
/**
* The object containing configurations specific for packet diagrams.
*
Expand Down Expand Up @@ -1463,6 +1529,22 @@ export interface PacketDiagramConfig extends BaseDiagramConfig {
export interface BlockDiagramConfig extends BaseDiagramConfig {
padding?: number;
}
/**
* This interface was referenced by `MermaidConfig`'s JSON-Schema
* via the `definition` "RailroadDiagramFormat".
*/
export interface RailroadDiagramFormat1 {
/**
* Force angular brackets around non-terminal symbols
*
*/
forceAngleBrackets?: boolean;
/**
* Force comma as a concatenation symbol in the rule definition
*
*/
forceComma?: boolean;
}
/**
* This interface was referenced by `MermaidConfig`'s JSON-Schema
* via the `definition` "FontConfig".
Expand Down
4 changes: 4 additions & 0 deletions packages/mermaid/src/defaultConfig.ts
Original file line number Diff line number Diff line change
Expand Up @@ -260,6 +260,10 @@ const config: RequiredDeep<MermaidConfig> = {
packet: {
...defaultConfigJson.packet,
},
railroad: {
...defaultConfigJson.railroad,
useMaxWidth: true,
},
};

const keyify = (obj: any, prefix = ''): string[] =>
Expand Down
2 changes: 2 additions & 0 deletions packages/mermaid/src/diagram-api/diagram-orchestration.ts
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@ import { packet } from '../diagrams/packet/detector.js';
import block from '../diagrams/block/blockDetector.js';
import { registerLazyLoadedDiagrams } from './detectType.js';
import { registerDiagram } from './diagramAPI.js';
import { railroad } from '../diagrams/railroad/railroadDetector.js';

let hasLoadedDiagrams = false;
export const addDiagrams = () => {
Expand Down Expand Up @@ -88,6 +89,7 @@ export const addDiagrams = () => {
journey,
quadrantChart,
sankey,
railroad,
packet,
xychart,
block
Expand Down
Loading