fix: Use AST to replace notes & warnings.

pull/3678/head
Sidharth Vinod 2022-10-28 14:13:24 +05:30
parent 6b3892baf1
commit d7bf92b39f
No known key found for this signature in database
GPG Key ID: FB5CCD378D3907CD
11 changed files with 68 additions and 127 deletions

11
.vscode/launch.json vendored
View File

@ -12,6 +12,17 @@
"args": ["run", "${relativeFile}"], "args": ["run", "${relativeFile}"],
"smartStep": true, "smartStep": true,
"console": "integratedTerminal" "console": "integratedTerminal"
},
{
"name": "Docs generation",
"type": "node",
"request": "launch",
"args": ["src/docs.mts"],
"runtimeArgs": ["--loader", "ts-node/esm"],
"cwd": "${workspaceRoot}/packages/mermaid",
"skipFiles": ["<node_internals>/**", "**/node_modules/**"],
"smartStep": true,
"internalConsoleOptions": "openOnSessionStart"
} }
] ]
} }

View File

@ -2,19 +2,20 @@
"version": "0.2", "version": "0.2",
"language": "en", "language": "en",
"words": [ "words": [
"blockquotes",
"customizability", "customizability",
"Gantt", "Gantt",
"jison", "jison",
"knsv", "knsv",
"Knut", "Knut",
"mermiad",
"mindmap", "mindmap",
"Mindmaps", "Mindmaps",
"mitigations", "mitigations",
"sandboxed", "sandboxed",
"Sveidqvist", "Sveidqvist",
"verdana", "verdana",
"Visio", "Visio"
"mermiad"
], ],
"ignoreWords": [ "ignoreWords": [
"Faber", "Faber",

View File

@ -32,10 +32,8 @@ statement
In the extract of the grammar above, it is defined that a call to the setTitle method in the data object will be done when parsing and the title keyword is encountered. In the extract of the grammar above, it is defined that a call to the setTitle method in the data object will be done when parsing and the title keyword is encountered.
> **Note**\ > **Note**
> Make sure that the `parseError` function for the parser is defined and calling `mermaid.parseError`. This way a common way of detecting parse errors is provided for the end-user. > Make sure that the `parseError` function for the parser is defined and calling `mermaid.parseError`. This way a common way of detecting parse errors is provided for the end-user.
>
> >
For more info look in the example diagram type: For more info look in the example diagram type:
@ -50,8 +48,7 @@ exports.parseError = function (err, hash) {
when parsing the `yy` object is initialized as per below: when parsing the `yy` object is initialized as per below:
```javascript ```javascript
var parser; const parser = exampleParser.parser;
parser = exampleParser.parser;
parser.yy = db; parser.yy = db;
``` ```
@ -74,8 +71,8 @@ At this point when mermaid is trying to render the diagram, it will detect it as
### Setup ### Setup
```javascript ```javascript
var graph = require('./graphDb'); const graph = require('./graphDb');
var flow = require('./parser/flow'); const flow = require('./parser/flow');
flow.parser.yy = graph; flow.parser.yy = graph;
``` ```
@ -96,7 +93,7 @@ graph.getEdges();
The parser is also exposed in the mermaid api by calling: The parser is also exposed in the mermaid api by calling:
```javascript ```javascript
var parser = mermaid.getParser(); const parser = mermaid.getParser();
``` ```
Note that the parse needs a graph object to store the data as per: Note that the parse needs a graph object to store the data as per:

View File

@ -52,10 +52,8 @@ Implementors can only modify configurations using directives, and cannot change
The Two types of directives: are `init` (or `initialize`) and `wrap`. The Two types of directives: are `init` (or `initialize`) and `wrap`.
> **Note**\ > **Note**
> All directives are enclosed in `%%{ }%%` > All directives are enclosed in `%%{ }%%`
>
> >
Older versions of mermaid will not parse directives because `%%` will comment out the directive. This makes the update backwards-compatible. Older versions of mermaid will not parse directives because `%%` will comment out the directive. This makes the update backwards-compatible.
@ -67,7 +65,7 @@ Older versions of mermaid will not parse directives because `%%` will comment ou
| --------- | ----------------------- | --------- | -------- | ----------------------------------------------- | | --------- | ----------------------- | --------- | -------- | ----------------------------------------------- |
| init | modifies configurations | Directive | Optional | Any parameters not included in the secure array | | init | modifies configurations | Directive | Optional | Any parameters not included in the secure array |
> **Note**\ > **Note**
> init would be an argument-directive: `%%{init: { **insert argument here**}}%%` > init would be an argument-directive: `%%{init: { **insert argument here**}}%%`
> >
> The json object that is passed as {**argument** } must be valid, quoted json or it will be ignored. > The json object that is passed as {**argument** } must be valid, quoted json or it will be ignored.
@ -78,8 +76,6 @@ Older versions of mermaid will not parse directives because `%%` will comment ou
> Configurations that are passed through init cannot change the parameters in a secure array at a higher level. In the event of a collision, mermaid will give priority to secure arrays and parse the request without changing the values of those parameters in conflict. > Configurations that are passed through init cannot change the parameters in a secure array at a higher level. In the event of a collision, mermaid will give priority to secure arrays and parse the request without changing the values of those parameters in conflict.
> >
> When deployed within code, init is called before the graph/diagram description. > When deployed within code, init is called before the graph/diagram description.
>
> >
**for example**: **for example**:
@ -113,7 +109,7 @@ Older versions of mermaid will not parse directives because `%%` will comment ou
| --------- | ----------------------------- | --------- | -------- | ---------- | | --------- | ----------------------------- | --------- | -------- | ---------- |
| wrap | a callable text-wrap function | Directive | Optional | %%{wrap}%% | | wrap | a callable text-wrap function | Directive | Optional | %%{wrap}%% |
> **Note**\ > **Note**
> Wrap is a function that is currently only deployable for sequence diagrams. > Wrap is a function that is currently only deployable for sequence diagrams.
> >
> `Wrap respects a manually added <br>, so if the user wants to break up their text, they have full control over line breaks by adding <br> tags.` > `Wrap respects a manually added <br>, so if the user wants to break up their text, they have full control over line breaks by adding <br> tags.`
@ -121,8 +117,6 @@ Older versions of mermaid will not parse directives because `%%` will comment ou
> It is a non-argument directive and can be executed thusly: > It is a non-argument directive and can be executed thusly:
> >
> `%%{wrap}%%` . > `%%{wrap}%%` .
>
> >
**An example of text wrapping in a sequence diagram**: **An example of text wrapping in a sequence diagram**:
@ -164,14 +158,12 @@ Example of **object.Assign**:
| --------------- | ------------------------------------- | ----------- | --------------------------------------- | ---------- | ---------- | | --------------- | ------------------------------------- | ----------- | --------------------------------------- | ---------- | ---------- |
| `setSiteConfig` | Sets the siteConfig to desired values | Put Request | Any Values, except ones in secure array | conf | siteConfig | | `setSiteConfig` | Sets the siteConfig to desired values | Put Request | Any Values, except ones in secure array | conf | siteConfig |
> **Note**\ > **Note**
> Sets the siteConfig. The siteConfig is a protected configuration for repeat use. Calls to reset() will reset > Sets the siteConfig. The siteConfig is a protected configuration for repeat use. Calls to reset() will reset
> the currentConfig to siteConfig. Calls to reset(configApi.defaultConfig) will reset siteConfig and currentConfig > the currentConfig to siteConfig. Calls to reset(configApi.defaultConfig) will reset siteConfig and currentConfig
> to the defaultConfig > to the defaultConfig
> Note: currentConfig is set in this function。 > Note: currentConfig is set in this function。
> Default value: will mirror Global Config > Default value: will mirror Global Config
>
> >
## getSiteConfig ## getSiteConfig
@ -179,10 +171,8 @@ Example of **object.Assign**:
| --------------- | --------------------------------------------------- | ----------- | ---------------------------------- | | --------------- | --------------------------------------------------- | ----------- | ---------------------------------- |
| `getSiteConfig` | Returns the current `siteConfig` base configuration | Get Request | Returns Any Values in `siteConfig` | | `getSiteConfig` | Returns the current `siteConfig` base configuration | Get Request | Returns Any Values in `siteConfig` |
> **Note**\ > **Note**
> Returns any values in siteConfig. > Returns any values in siteConfig.
>
> >
## setConfig ## setConfig
@ -190,12 +180,10 @@ Example of **object.Assign**:
| ----------- | ------------------------------------------ | ----------- | --------------------------------- | ---------- | ---------------------------------------------- | | ----------- | ------------------------------------------ | ----------- | --------------------------------- | ---------- | ---------------------------------------------- |
| `setConfig` | Sets the `currentConfig` to desired values | Put Request | Any Values, those in secure array | conf | `currentConfig` merged with the sanitized conf | | `setConfig` | Sets the `currentConfig` to desired values | Put Request | Any Values, those in secure array | conf | `currentConfig` merged with the sanitized conf |
> **Note**\ > **Note**
> Sets the currentConfig. The parameter conf is sanitized based on the siteConfig.secure keys. Any > Sets the currentConfig. The parameter conf is sanitized based on the siteConfig.secure keys. Any
> values found in conf with key found in siteConfig.secure will be replaced with the corresponding > values found in conf with key found in siteConfig.secure will be replaced with the corresponding
> siteConfig value. > siteConfig value.
>
> >
## getConfig ## getConfig
@ -203,10 +191,8 @@ Example of **object.Assign**:
| ----------- | --------------------------- | ----------- | ------------------------------- | | ----------- | --------------------------- | ----------- | ------------------------------- |
| `getConfig` | Obtains the `currentConfig` | Get Request | Any Values from `currentConfig` | | `getConfig` | Obtains the `currentConfig` | Get Request | Any Values from `currentConfig` |
> **Note**\ > **Note**
> Returns any values in currentConfig. > Returns any values in currentConfig.
>
> >
## sanitize ## sanitize
@ -214,11 +200,9 @@ Example of **object.Assign**:
| ---------- | ---------------------------------------- | -------------- | ------ | | ---------- | ---------------------------------------- | -------------- | ------ |
| `sanitize` | Sets the `siteConfig` to desired values. | Put Request(?) | None | | `sanitize` | Sets the `siteConfig` to desired values. | Put Request(?) | None |
> **Note**\ > **Note**
> modifies options in-place > modifies options in-place
> Ensures options parameter does not attempt to override siteConfig secure keys. > Ensures options parameter does not attempt to override siteConfig secure keys.
>
> >
## reset ## reset
@ -232,9 +216,7 @@ Example of **object.Assign**:
| --------- | ------------------------------------------------------------ | ---------- | -------- | -------------------------------------------- | | --------- | ------------------------------------------------------------ | ---------- | -------- | -------------------------------------------- |
| `conf` | base set of values, which `currentConfig` could be reset to. | Dictionary | Required | Any Values, with respect to the secure Array | | `conf` | base set of values, which `currentConfig` could be reset to. | Dictionary | Required | Any Values, with respect to the secure Array |
> **Note**\ > **Note**
> default: current siteConfig (optional, default `getSiteConfig()`) > default: current siteConfig (optional, default `getSiteConfig()`)
>
> >
## For more information, read [Setup](setup/README). ## For more information, read [Setup](setup/README).

View File

@ -156,10 +156,8 @@ You can create your own themes, by changing any of the given variables below. If
## Theme Variables Reference Table ## Theme Variables Reference Table
> **Note**\ > **Note**
> Variables that are unique to some diagrams can be affected by changes in Theme Variables > Variables that are unique to some diagrams can be affected by changes in Theme Variables
>
> >
| Variable | Default/Base/Factor value | Calc | Description | | Variable | Default/Base/Factor value | Calc | Description |
| -------------------- | ------------------------------ | ---- | -------------------------------------------------------------------------------------------------------------------------------- | | -------------------- | ------------------------------ | ---- | -------------------------------------------------------------------------------------------------------------------------------- |

View File

@ -119,11 +119,9 @@ Values:
- **antiscript**: html tags in text are allowed, (only script element is removed), click functionality is enabled - **antiscript**: html tags in text are allowed, (only script element is removed), click functionality is enabled
- **sandbox**: With this security level all rendering takes place in a sandboxed iframe. This prevent any JavaScript running in the context. This may hinder interactive functionality of the diagram like scripts, popups in sequence diagram or links to other tabs/targets etc. - **sandbox**: With this security level all rendering takes place in a sandboxed iframe. This prevent any JavaScript running in the context. This may hinder interactive functionality of the diagram like scripts, popups in sequence diagram or links to other tabs/targets etc.
> **Note**\ > **Note**
> This changes the default behaviour of mermaid so that after upgrade to 8.2, unless the `securityLevel` is not changed, tags in flowcharts are encoded as tags and clicking is disabled. > This changes the default behaviour of mermaid so that after upgrade to 8.2, unless the `securityLevel` is not changed, tags in flowcharts are encoded as tags and clicking is disabled.
> **sandbox** security level is still in the beta version. > **sandbox** security level is still in the beta version.
>
> >
**If you are taking responsibility for the diagram source security you can set the `securityLevel` to a value of your choosing . This allows clicks and tags are allowed.** **If you are taking responsibility for the diagram source security you can set the `securityLevel` to a value of your choosing . This allows clicks and tags are allowed.**
@ -188,10 +186,8 @@ Or with no config object, and a jQuery selection:
mermaid.init(undefined, $('#someId .yetAnotherClass')); mermaid.init(undefined, $('#someId .yetAnotherClass'));
``` ```
> **Warning**\ > **Warning**
> This type of integration is deprecated. Instead the preferred way of handling more complex integration is to use the mermaidAPI instead. > This type of integration is deprecated. Instead the preferred way of handling more complex integration is to use the mermaidAPI instead.
>
> >
## Usage with webpack ## Usage with webpack
@ -230,7 +226,7 @@ The example code below is an extract of what mermaid does when using the API. Th
bind events to an SVG when using the API for rendering. bind events to an SVG when using the API for rendering.
```javascript ```javascript
var insertSvg = function (svgCode, bindFunctions) { const insertSvg = function (svgCode, bindFunctions) {
element.innerHTML = svgCode; element.innerHTML = svgCode;
if (typeof callback !== 'undefined') { if (typeof callback !== 'undefined') {
callback(id); callback(id);
@ -238,7 +234,7 @@ var insertSvg = function (svgCode, bindFunctions) {
bindFunctions(element); bindFunctions(element);
}; };
var id = 'theGraph'; const id = 'theGraph';
mermaidAPI.render(id, txt, insertSvg, element); mermaidAPI.render(id, txt, insertSvg, element);
``` ```
@ -254,7 +250,7 @@ mermaidAPI.render(id, txt, insertSvg, element);
This is the renderer used for transforming the documentation from Markdown to html with mermaid diagrams in the html. This is the renderer used for transforming the documentation from Markdown to html with mermaid diagrams in the html.
```javascript ```javascript
var renderer = new marked.Renderer(); const renderer = new marked.Renderer();
renderer.code = function (code, language) { renderer.code = function (code, language) {
if (code.match(/^sequenceDiagram/) || code.match(/^graph/)) { if (code.match(/^sequenceDiagram/) || code.match(/^graph/)) {
return '<pre class="mermaid">' + code + '</pre>'; return '<pre class="mermaid">' + code + '</pre>';
@ -305,8 +301,8 @@ mermaid.parseError = function (err, hash) {
displayErrorInGui(err); displayErrorInGui(err);
}; };
var textFieldUpdated = function () { const textFieldUpdated = function () {
var textStr = getTextFromFormField('code'); const textStr = getTextFromFormField('code');
if (mermaid.parse(textStr)) { if (mermaid.parse(textStr)) {
reRender(textStr); reRender(textStr);
@ -345,10 +341,8 @@ on what kind of integration you use.
</script> </script>
``` ```
> **Note**\ > **Note**
> This is the preferred way of configuring mermaid. > This is the preferred way of configuring mermaid.
>
> >
### The following methods are deprecated and are kept only for backwards compatibility. ### The following methods are deprecated and are kept only for backwards compatibility.
@ -364,10 +358,8 @@ approach are:
mermaid.startOnLoad = true; mermaid.startOnLoad = true;
``` ```
> **Warning**\ > **Warning**
> This way of setting the configuration is deprecated. Instead the preferred way is to use the initialize method. This functionality is only kept for backwards compatibility. > This way of setting the configuration is deprecated. Instead the preferred way is to use the initialize method. This functionality is only kept for backwards compatibility.
>
> >
## Using the mermaid_config ## Using the mermaid_config
@ -381,10 +373,8 @@ approach are:
mermaid_config.startOnLoad = true; mermaid_config.startOnLoad = true;
``` ```
> **Warning**\ > **Warning**
> This way of setting the configuration is deprecated. Instead the preferred way is to use the initialize method. This functionality is only kept for backwards compatibility. > This way of setting the configuration is deprecated. Instead the preferred way is to use the initialize method. This functionality is only kept for backwards compatibility.
>
> >
## Using the mermaid.init call ## Using the mermaid.init call
@ -397,7 +387,5 @@ To set some configuration via the mermaid object. The two parameters that are su
mermaid_config.startOnLoad = true; mermaid_config.startOnLoad = true;
``` ```
> **Warning**\ > **Warning**
> This way of setting the configuration is deprecated. Instead the preferred way is to use the initialize method. This functionality is only kept for backwards compatibility. > This way of setting the configuration is deprecated. Instead the preferred way is to use the initialize method. This functionality is only kept for backwards compatibility.
>
> >

View File

@ -24,12 +24,10 @@ sequenceDiagram
Alice-)John: See you later! Alice-)John: See you later!
``` ```
> **Note**\ > **Note**
> A note on nodes, the word "end" could potentially break the diagram, due to the way that the mermaid language is scripted. > A note on nodes, the word "end" could potentially break the diagram, due to the way that the mermaid language is scripted.
> >
> If unavoidable, one must use parentheses(), quotation marks "", or brackets {},\[], to enclose the word "end". i.e : (end), \[end], {end}. > If unavoidable, one must use parentheses(), quotation marks "", or brackets {},\[], to enclose the word "end". i.e : (end), \[end], {end}.
>
> >
## Syntax ## Syntax

View File

@ -133,49 +133,15 @@ const copyTransformedContents = (filename: string, doCopy = false, transformedCo
logWasOrShouldBeTransformed(fileInFinalDocDir, doCopy); logWasOrShouldBeTransformed(fileInFinalDocDir, doCopy);
}; };
const transformAnnotation = (content: string, type: 'warning' | 'tip' | 'note') => {
let transformed = content;
let regex = /```note\n[\s\S]+?```/gm;
let text = 'Note';
switch (type) {
case 'note':
regex = /```note\s?\n[\s\S]+?```/gm;
break;
case 'tip':
regex = /```tip\s?\n[\s\S]+?```/gm;
text = 'Note';
break;
case 'warning':
regex = /```warning\s?\n[\s\S]+?```/gm;
text = 'Warning';
break;
default:
break;
}
const matches = content.match(regex);
if (matches) {
console.log(`found ${matches.length} of ${type}`);
const formatted = matches.map((element) =>
element
.replace(`\`\`\`${type}`, `> **${text}** `)
.replace('```', '>')
.split('\n')
.join('\n> ')
);
let n = 0;
for (const match of matches) {
transformed = transformed.replace(match, formatted[n++]);
}
}
return transformed;
};
const readSyncedUTF8file = (filename: string): string => { const readSyncedUTF8file = (filename: string): string => {
return readFileSync(filename, 'utf8'); return readFileSync(filename, 'utf8');
}; };
const transformToBlockQuote = (content: string, type: string) => {
const title = type === 'warning' ? 'Warning' : 'Note';
return `> **${title}** \n> ${content.replace(/\n/g, '\n> ')}`;
};
/** /**
* Transform a markdown file and write the transformed file to the directory for published * Transform a markdown file and write the transformed file to the directory for published
* documentation * documentation
@ -189,24 +155,25 @@ const readSyncedUTF8file = (filename: string): string => {
* @param file {string} name of the file that will be verified * @param file {string} name of the file that will be verified
*/ */
const transformMarkdown = (file: string) => { const transformMarkdown = (file: string) => {
let doc = readSyncedUTF8file(file).replace(/<MERMAID_VERSION>/g, MERMAID_MAJOR_VERSION); const doc = readSyncedUTF8file(file).replace(/<MERMAID_VERSION>/g, MERMAID_MAJOR_VERSION);
doc = transformAnnotation(doc, 'warning');
doc = transformAnnotation(doc, 'tip');
doc = transformAnnotation(doc, 'note');
const ast: Root = remark.parse(doc); const ast: Root = remark.parse(doc);
const out = flatmap(ast, (c: Code) => { const out = flatmap(ast, (c: Code) => {
if (c.type !== 'code') { if (c.type !== 'code' || !c.lang) {
return [c]; return [c];
} }
if (c.lang === 'mermaid' || c.lang === 'mmd') {
// Convert mermaid code blocks to mermaid-example blocks
if (['mermaid', 'mmd', 'mermaid-example'].includes(c.lang)) {
c.lang = 'mermaid-example'; c.lang = 'mermaid-example';
return [c, Object.assign({}, c, { lang: 'mermaid' })];
} }
if (c.lang !== 'mermaid-example') {
return [c]; // Transform codeblocks into block quotes.
if (['note', 'tip', 'warning'].includes(c.lang)) {
return [remark.parse(transformToBlockQuote(c.value, c.lang))];
} }
return [c, Object.assign({}, c, { lang: 'mermaid' })];
return [c];
}); });
// Add the AUTOGENERATED_TEXT to the start of the file // Add the AUTOGENERATED_TEXT to the start of the file

View File

@ -43,8 +43,7 @@ exports.parseError = function (err, hash) {
when parsing the `yy` object is initialized as per below: when parsing the `yy` object is initialized as per below:
```javascript ```javascript
var parser; const parser = exampleParser.parser;
parser = exampleParser.parser;
parser.yy = db; parser.yy = db;
``` ```
@ -67,8 +66,8 @@ At this point when mermaid is trying to render the diagram, it will detect it as
### Setup ### Setup
```javascript ```javascript
var graph = require('./graphDb'); const graph = require('./graphDb');
var flow = require('./parser/flow'); const flow = require('./parser/flow');
flow.parser.yy = graph; flow.parser.yy = graph;
``` ```
@ -89,7 +88,7 @@ graph.getEdges();
The parser is also exposed in the mermaid api by calling: The parser is also exposed in the mermaid api by calling:
```javascript ```javascript
var parser = mermaid.getParser(); const parser = mermaid.getParser();
``` ```
Note that the parse needs a graph object to store the data as per: Note that the parse needs a graph object to store the data as per:

View File

@ -224,7 +224,7 @@ The example code below is an extract of what mermaid does when using the API. Th
bind events to an SVG when using the API for rendering. bind events to an SVG when using the API for rendering.
```javascript ```javascript
var insertSvg = function (svgCode, bindFunctions) { const insertSvg = function (svgCode, bindFunctions) {
element.innerHTML = svgCode; element.innerHTML = svgCode;
if (typeof callback !== 'undefined') { if (typeof callback !== 'undefined') {
callback(id); callback(id);
@ -232,7 +232,7 @@ var insertSvg = function (svgCode, bindFunctions) {
bindFunctions(element); bindFunctions(element);
}; };
var id = 'theGraph'; const id = 'theGraph';
mermaidAPI.render(id, txt, insertSvg, element); mermaidAPI.render(id, txt, insertSvg, element);
``` ```
@ -248,7 +248,7 @@ mermaidAPI.render(id, txt, insertSvg, element);
This is the renderer used for transforming the documentation from Markdown to html with mermaid diagrams in the html. This is the renderer used for transforming the documentation from Markdown to html with mermaid diagrams in the html.
```javascript ```javascript
var renderer = new marked.Renderer(); const renderer = new marked.Renderer();
renderer.code = function (code, language) { renderer.code = function (code, language) {
if (code.match(/^sequenceDiagram/) || code.match(/^graph/)) { if (code.match(/^sequenceDiagram/) || code.match(/^graph/)) {
return '<pre class="mermaid">' + code + '</pre>'; return '<pre class="mermaid">' + code + '</pre>';
@ -299,8 +299,8 @@ mermaid.parseError = function (err, hash) {
displayErrorInGui(err); displayErrorInGui(err);
}; };
var textFieldUpdated = function () { const textFieldUpdated = function () {
var textStr = getTextFromFormField('code'); const textStr = getTextFromFormField('code');
if (mermaid.parse(textStr)) { if (mermaid.parse(textStr)) {
reRender(textStr); reRender(textStr);

View File

@ -508,7 +508,7 @@ export default mermaidAPI;
* *
* ```html * ```html
* <script> * <script>
* var config = { * const config = {
* theme: 'default', * theme: 'default',
* logLevel: 'fatal', * logLevel: 'fatal',
* securityLevel: 'strict', * securityLevel: 'strict',