-
-
Notifications
You must be signed in to change notification settings - Fork 6.6k
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
Auto generate shape docs #5924
Auto generate shape docs #5924
Conversation
|
915d1fe
to
3f21f59
Compare
The latest updates on your projects. Learn more about Argos notifications ↗︎
|
Codecov ReportAttention: Patch coverage is
Additional details and impacted files@@ Coverage Diff @@
## develop #5924 +/- ##
==========================================
- Coverage 4.65% 4.64% -0.01%
==========================================
Files 374 375 +1
Lines 51863 51970 +107
Branches 587 587
==========================================
Hits 2414 2414
- Misses 49449 49556 +107
Flags with carried forward coverage won't be shown. Click here to find out more.
|
d049490
to
24a3a25
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I don't really like moving these build scripts outside of packages/mermaid/scripts/docs.mts
.
It means that pnpm run --filter mermaid docs:build
, docs:verify
, docs:dev
, etc. will all only partially build the docs.
Could we instead move that code there, and instead use a Node.JS customization hook (e.g. like what tsx
does) to handle importing ./shapes.js
?
E.g. we could make a dummy hook that just replaces all imports to .schema.yaml
files with an empty object, since shapeDefs
doesn't actually require the contents:
[PATCH] build(docs): autogenerate shape table in docs
From 8b68647f04be71732cde52c82e73f52234bb5647 Mon Sep 17 00:00:00 2001
From: Alois Klink <[email protected]>
Date: Tue, 8 Oct 2024 01:57:07 +0900
Subject: [PATCH] build(docs): autogenerate shape table in docs
Autogenerate the shape table in the docs from
`src/rendering-util/rendering-elements/shapes.js`.
Since we can't import this file from `tsx` directly, since it imports a
`.schema.yaml` file in the import chain (which is normally handled by
ESBuild/Vite), I've added a dummy `scripts/loadHook.mjs` that handles it
instead.
---
scripts/docs.mts | 64 +++++++++++++++++++++++++++++++++++-
scripts/docs.spec.ts | 57 +++++++++++++++++++++++++++++++-
scripts/loadHook.mjs | 24 ++++++++++++++
src/docs/syntax/flowchart.md | 49 ++-------------------------
4 files changed, 145 insertions(+), 49 deletions(-)
create mode 100644 packages/mermaid/scripts/loadHook.mjs
diff --git a/scripts/docs.mts b/scripts/docs.mts
index 374e78870..f5a25dd2a 100644
--- a/scripts/docs.mts
+++ b/scripts/docs.mts
@@ -41,7 +41,8 @@ import { exec } from 'child_process';
import { globby } from 'globby';
import { JSDOM } from 'jsdom';
import { dump, load, JSON_SCHEMA } from 'js-yaml';
-import type { Code, ListItem, Root, Text, YAML } from 'mdast';
+import type { Code, ListItem, PhrasingContent, Root, Text, YAML } from 'mdast';
+import { register } from 'node:module';
import { posix, dirname, relative, join } from 'path';
import prettier from 'prettier';
import { remark } from 'remark';
@@ -53,6 +54,10 @@ import mm from 'micromatch';
import flatmap from 'unist-util-flatmap';
import { visit } from 'unist-util-visit';
+// short-circuit `.schema.yaml` imports, so that we can safely import `shapes.js`
+register('./loadHook.mjs', import.meta.url);
+const { shapesDefs } = await import('../src/rendering-util/rendering-elements/shapes.js');
+
export const MERMAID_RELEASE_VERSION = JSON.parse(readFileSync('../mermaid/package.json', 'utf8'))
.version as string;
const MERMAID_MAJOR_VERSION = MERMAID_RELEASE_VERSION.split('.')[0];
@@ -103,6 +108,60 @@ const generateHeader = (file: string): string => {
> ## Please edit the corresponding file in [${filePathFromRoot}](${sourcePathRelativeToGenerated}).`;
};
+/**
+ * Builds a markdown list of shapes supported in flowcharts.
+ */
+export function buildShapeDoc() {
+ const data = shapesDefs
+ .sort((a, b) => a.semanticName.localeCompare(b.semanticName))
+ .map((shape): PhrasingContent[][] => {
+ const { name, semanticName, description, shortName, aliases = [] } = shape;
+ return [
+ [{ type: 'text', value: semanticName }],
+ [{ type: 'text', value: name }],
+ [{ type: 'inlineCode', value: shortName }],
+ [{ type: 'text', value: description }],
+ aliases.sort().flatMap((alias, index) => [
+ ...(index !== 0 ? ([{ type: 'text', value: ', ' }] as const) : []),
+ {
+ type: 'inlineCode',
+ value: alias,
+ },
+ ]),
+ ];
+ });
+
+ // don't prettify this table, since we'd do it later
+ return remark()
+ .use(remarkGfm)
+ .stringify({
+ type: 'root',
+ children: [
+ {
+ type: 'table',
+ children: [
+ ['Semantic Name', 'Shape Name', 'Short Name', 'Description', 'Alias Supported'].map(
+ (s): PhrasingContent[] => [
+ {
+ type: 'strong',
+ children: [{ type: 'text', value: s }],
+ },
+ ]
+ ),
+ ...data,
+ ].map((row) => ({
+ type: 'tableRow',
+ children: row.map((cell) => ({
+ type: 'tableCell',
+ children: cell,
+ })),
+ })),
+ },
+ ],
+ })
+ .toString();
+}
+
/**
* Given a source file name and path, return the documentation destination full path and file name
* Create the destination path if it does not already exist.
@@ -196,6 +255,9 @@ const transformIncludeStatements = (file: string, text: string): string => {
// resolve includes - src https://github.com/vuejs/vitepress/blob/428eec3750d6b5648a77ac52d88128df0554d4d1/src/node/markdownToVue.ts#L65-L76
return text.replace(includesRE, (m, m1) => {
try {
+ if (m1 === './shapesTable.md') {
+ return buildShapeDoc();
+ }
const includePath = join(dirname(file), m1).replaceAll('\\', '/');
const content = readSyncedUTF8file(includePath);
includedFiles.add(changeToFinalDocDir(includePath));
diff --git a/scripts/docs.spec.ts b/scripts/docs.spec.ts
index c84bc1bac..13bcda7b5 100644
--- a/scripts/docs.spec.ts
+++ b/scripts/docs.spec.ts
@@ -1,4 +1,4 @@
-import { transformMarkdownAst, transformToBlockQuote } from './docs.mjs';
+import { buildShapeDoc, transformMarkdownAst, transformToBlockQuote } from './docs.mjs';
import { remark } from 'remark'; // import it this way so we can mock it
import remarkFrontmatter from 'remark-frontmatter';
@@ -105,6 +105,61 @@ This Markdown should be kept.
});
});
+ describe('buildShapeDoc', () => {
+ it('should build shapesTable based on the shapeDefs', () => {
+ expect(buildShapeDoc()).toMatchInlineSnapshot(`
+ "| **Semantic Name** | **Shape Name** | **Short Name** | **Description** | **Alias Supported** |
+ | --------------------------------- | ---------------------- | -------------- | ------------------------------ | ---------------------------------------------------------------- |
+ | Card | Notched Rectangle | \`notch-rect\` | Represents a card | \`card\`, \`notched-rectangle\` |
+ | Collate | Hourglass | \`hourglass\` | Represents a collate operation | \`collate\`, \`hourglass\` |
+ | Com Link | Lightning Bolt | \`bolt\` | Communication link | \`com-link\`, \`lightning-bolt\` |
+ | Comment | Curly Brace | \`brace\` | Adds a comment | \`brace-l\`, \`comment\` |
+ | Comment Right | Curly Brace | \`brace-r\` | Adds a comment | |
+ | Comment with braces on both sides | Curly Braces | \`braces\` | Adds a comment | |
+ | Data Input/Output | Lean Right | \`lean-r\` | Represents input or output | \`in-out\`, \`lean-right\` |
+ | Data Input/Output | Lean Left | \`lean-l\` | Represents output or input | \`lean-left\`, \`out-in\` |
+ | Database | Cylinder | \`cyl\` | Database storage | \`cylinder\`, \`database\`, \`db\` |
+ | Decision | Diamond | \`diam\` | Decision-making step | \`decision\`, \`diamond\`, \`question\` |
+ | Delay | Half-Rounded Rectangle | \`delay\` | Represents a delay | \`half-rounded-rectangle\` |
+ | Direct Access Storage | Horizontal Cylinder | \`h-cyl\` | Direct access storage | \`das\`, \`horizontal-cylinder\` |
+ | Disk Storage | Lined Cylinder | \`lin-cyl\` | Disk storage | \`disk\`, \`lined-cylinder\` |
+ | Display | Curved Trapezoid | \`curv-trap\` | Represents a display | \`curved-trapezoid\`, \`display\` |
+ | Divided Process | Divided Rectangle | \`div-rect\` | Divided process shape | \`div-proc\`, \`divided-process\`, \`divided-rectangle\` |
+ | Document | Document | \`doc\` | Represents a document | \`doc\`, \`document\` |
+ | Event | Rounded Rectangle | \`rounded\` | Represents an event | \`event\` |
+ | Extract | Triangle | \`tri\` | Extraction process | \`extract\`, \`triangle\` |
+ | Fork/Join | Filled Rectangle | \`fork\` | Fork or join in process flow | \`join\` |
+ | Internal Storage | Window Pane | \`win-pane\` | Internal storage | \`internal-storage\`, \`window-pane\` |
+ | Junction | Filled Circle | \`f-circ\` | Junction point | \`filled-circle\`, \`junction\` |
+ | Lined Document | Lined Document | \`lin-doc\` | Lined document | \`lined-document\` |
+ | Lined/Shaded Process | Lined Rectangle | \`lin-rect\` | Lined process shape | \`lin-proc\`, \`lined-process\`, \`lined-rectangle\`, \`shaded-process\` |
+ | Loop Limit | Trapezoidal Pentagon | \`notch-pent\` | Loop limit step | \`loop-limit\`, \`notched-pentagon\` |
+ | Manual File | Flipped Triangle | \`flip-tri\` | Manual file operation | \`flipped-triangle\`, \`manual-file\` |
+ | Manual Input | Sloped Rectangle | \`sl-rect\` | Manual input step | \`manual-input\`, \`sloped-rectangle\` |
+ | Manual Operation | Trapezoid Base Top | \`trap-t\` | Represents a manual task | \`inv-trapezoid\`, \`manual\`, \`trapezoid-top\` |
+ | Multi-Document | Stacked Document | \`docs\` | Multiple documents | \`documents\`, \`st-doc\`, \`stacked-document\` |
+ | Multi-Process | Stacked Rectangle | \`st-rect\` | Multiple processes | \`processes\`, \`procs\`, \`stacked-rectangle\` |
+ | Odd | Odd | \`odd\` | Odd shape | |
+ | Paper Tape | Flag | \`flag\` | Paper tape | \`paper-tape\` |
+ | Prepare Conditional | Hexagon | \`hex\` | Preparation or condition step | \`hexagon\`, \`prepare\` |
+ | Priority Action | Trapezoid Base Bottom | \`trap-b\` | Priority action | \`priority\`, \`trapezoid\`, \`trapezoid-bottom\` |
+ | Process | Rectangle | \`rect\` | Standard process shape | \`proc\`, \`process\`, \`rectangle\` |
+ | Start | Circle | \`circle\` | Starting point | \`circ\` |
+ | Start | Small Circle | \`sm-circ\` | Small starting point | \`small-circle\`, \`start\` |
+ | Stop | Double Circle | \`dbl-circ\` | Represents a stop point | \`double-circle\` |
+ | Stop | Framed Circle | \`fr-circ\` | Stop point | \`framed-circle\`, \`stop\` |
+ | Stored Data | Bow Tie Rectangle | \`bow-rect\` | Stored data | \`bow-tie-rectangle\`, \`stored-data\` |
+ | Subprocess | Framed Rectangle | \`fr-rect\` | Subprocess | \`framed-rectangle\`, \`subproc\`, \`subprocess\`, \`subroutine\` |
+ | Summary | Crossed Circle | \`cross-circ\` | Summary | \`crossed-circle\`, \`summary\` |
+ | Tagged Document | Tagged Document | \`tag-doc\` | Tagged document | \`tag-doc\`, \`tagged-document\` |
+ | Tagged Process | Tagged Rectangle | \`tag-rect\` | Tagged process | \`tag-proc\`, \`tagged-process\`, \`tagged-rectangle\` |
+ | Terminal Point | Stadium | \`stadium\` | Terminal point | \`pill\`, \`terminal\` |
+ | Text Block | Text Block | \`text\` | Text block | |
+ "
+ `);
+ });
+ });
+
it('should add an editLink in the YAML frontmatter if `addEditLink: true`', async () => {
const contents = `---
title: Flowcharts Syntax
diff --git a/scripts/loadHook.mjs b/scripts/loadHook.mjs
new file mode 100644
index 000000000..551bb9936
--- /dev/null
+++ b/scripts/loadHook.mjs
@@ -0,0 +1,24 @@
+import { fileURLToPath } from 'node:url';
+
+/** @import import { LoadHook } from "node:module"; */
+/**
+ * @type {LoadHook}
+ *
+ * Load hook that short circuits the loading of `.schema.yaml` files with `export default {}`.
+ * These would normally be loaded using ESBuild, but that doesn't work for these local scripts.
+ *
+ * @see https://nodejs.org/api/module.html#loadurl-context-nextload
+ */
+export const load = async (url, context, nextLoad) => {
+ const filePath = url.startsWith('file://') ? fileURLToPath(url) : url;
+
+ if (filePath.endsWith('.schema.yaml')) {
+ return {
+ format: 'module',
+ shortCircuit: true,
+ source: `export default {}`,
+ };
+ } else {
+ return await nextLoad(url, context);
+ }
+};
diff --git a/src/docs/syntax/flowchart.md b/src/docs/syntax/flowchart.md
index 9d37a4033..2ce539d7c 100644
--- a/src/docs/syntax/flowchart.md
+++ b/src/docs/syntax/flowchart.md
@@ -212,53 +212,8 @@ This syntax creates a node A as a rectangle. It renders in the same way as `A["A
Below is a comprehensive list of the newly introduced shapes and their corresponding semantic meanings, short names, and aliases:
-| **Semantic Name** | **Shape Name** | **Short Name** | **Description** | **Alias Supported** |
-| ------------------------------------- | ---------------------- | -------------- | ------------------------------ | -------------------------------------------------------------- |
-| **Process** | Rectangle | `rect` | Standard process shape | `proc`, `process`, `rectangle` |
-| **Event** | Rounded Rectangle | `rounded` | Represents an event | `event` |
-| **Terminal Point** | Stadium | `stadium` | Terminal point | `terminal`, `pill` |
-| **Subprocess** | Framed Rectangle | `fr-rect` | Subprocess | `subprocess`,`subproc`, `framed-rectangle`, `subroutine` |
-| **Database** | Cylinder | `cyl` | Database storage | `db`, `database`, `cylinder` |
-| **Start** | Circle | `circle` | Starting point | `circ` |
-| **Odd** | Odd | `odd` | Odd shape | |
-| **Decision** | Diamond | `diam` | Decision-making step | `decision`, `diamond` |
-| **Prepare Conditional** | Hexagon | `hex` | Preparation or condition step | `hexagon`, `prepare` |
-| **Data Input/Output** | Lean Right | `lean-r` | Represents input or output | `lean-right`, `in-out` |
-| **Data Input/Output** | Lean Left | `lean-l` | Represents output or input | `lean-left`, `out-in` |
-| **Priority Action** | Trapezoid Base Bottom | `trap-b` | Priority action | `priority`, `trapezoid-bottom` |
-| **Manual Operation** | Trapezoid Base Top | `trap-t` | Represents a manual task | `manual`, `trapezoid-top` |
-| **Stop** | Double Circle | `dbl-circ` | Represents a stop point | `double-circle` |
-| **Text Block** | Text Block | `text` | Text block | - |
-| **Card** | Notched Rectangle | `notch-rect` | Represents a card | `card`, `notched-rectangle` |
-| **Lined/Shaded Process** | Lined Rectangle | `lin-rect` | Lined process shape | `lined-rectangle`,`lined-process`, `lin-proc`,`shaded-process` |
-| **Start** | Small Circle | `sm-circ` | Small starting point | `start`, `small-circle` |
-| **Stop** | Framed Circle | `fr-circ` | Stop point | `stop`, `framed-circle` |
-| **Fork/Join** | Filled Rectangle | `fork` | Fork or join in process flow | `join` |
-| **Collate** | Hourglass | `hourglass` | Represents a collate operation | `hourglass` |
-| **Comment** | Curly Brace | `brace` | Adds a comment | `comment`, `brace-l` |
-| **Comment Right** | Curly Brace | `brace-r` | Adds a comment | - |
-| **Comment with braces on both sides** | Curly Braces | `braces` | Adds a comment | - |
-| **Com Link** | Lightning Bolt | `bolt` | Communication link | `com-link`, `lightning-bolt` |
-| **Document** | Document | `doc` | Represents a document | `doc`, `document` |
-| **Delay** | Half-Rounded Rectangle | `delay` | Represents a delay | `half-rounded-rectangle` |
-| **Direct Access Storage** | Horizontal Cylinder | `h-cyl` | Direct access storage | `das`, `horizontal-cylinder` |
-| **Disk Storage** | Lined Cylinder | `lin-cyl` | Disk storage | `disk`, `lined-cylinder` |
-| **Display** | Curved Trapezoid | `curv-trap` | Represents a display | `curved-trapezoid`, `display` |
-| **Divided Process** | Divided Rectangle | `div-rect` | Divided process shape | `div-proc`, `divided-rectangle`, `divided-process` |
-| **Extract** | Triangle | `tri` | Extraction process | `extract`, `triangle` |
-| **Internal Storage** | Window Pane | `win-pane` | Internal storage | `internal-storage`, `window-pane` |
-| **Junction** | Filled Circle | `f-circ` | Junction point | `junction`, `filled-circle` |
-| **Lined Document** | Lined Document | `lin-doc` | Lined document | `lined-document` |
-| **Loop Limit** | Trapezoidal Pentagon | `notch-pent` | Loop limit step | `loop-limit`, `notched-pentagon` |
-| **Manual File** | Flipped Triangle | `flip-tri` | Manual file operation | `manual-file`, `flipped-triangle` |
-| **Manual Input** | Sloped Rectangle | `sl-rect` | Manual input step | `manual-input`, `sloped-rectangle` |
-| **Multi-Document** | Stacked Document | `docs` | Multiple documents | `documents`, `st-doc`, `stacked-document` |
-| **Multi-Process** | Stacked Rectangle | `st-rect` | Multiple processes | `procs`, `processes`, `stacked-rectangle` |
-| **Paper Tape** | Flag | `flag` | Paper tape | `paper-tape` |
-| **Stored Data** | Bow Tie Rectangle | `bow-rect` | Stored data | `stored-data`, `bow-tie-rectangle` |
-| **Summary** | Crossed Circle | `cross-circ` | Summary | `summary`, `crossed-circle` |
-| **Tagged Document** | Tagged Document | `tag-doc` | Tagged document | `tag-doc`, `tagged-document` |
-| **Tagged Process** | Tagged Rectangle | `tag-rect` | Tagged process | `tagged-rectangle`,`tag-proc`, `tagged-process` |
+<!-- Will be auto generated with `pnpm --filter mermaid docs:build` -->
+<!--@include: ./shapesTable.md -->
### Example Flowchart with New Shapes
--
2.43.0
Not keen on how it's currently run, open to suggestions on better ways.
24a3a25
to
efa47e3
Compare
✅ Deploy Preview for mermaid-js ready!
To edit notification comments on pull requests, go to your Netlify site configuration. |
commit: |
Co-authored-by: Alois Klink <[email protected]>
📑 Summary
Generate the shapes table based on the shape definition.
📏 Design Decisions
This will avoid mistakes and inconsistencies in the shape documentation.
📋 Tasks
Make sure you
MERMAID_RELEASE_VERSION
is used for all new features.pnpm changeset
and following the prompts. Changesets that add features should beminor
and those that fix bugs should bepatch
. Please prefix changeset messages withfeat:
,fix:
, orchore:
.