diff --git a/cSpell.json b/cSpell.json index d860c5e33..94276b683 100644 --- a/cSpell.json +++ b/cSpell.json @@ -47,6 +47,7 @@ "graphviz", "grav", "greywolf", + "huynh", "inkdrop", "jaoude", "jison", @@ -90,6 +91,7 @@ "sidharthv", "sphinxcontrib", "statediagram", + "steph", "stylis", "substate", "sveidqvist", diff --git a/cypress/platform/knsv2.html b/cypress/platform/knsv2.html index 08a4c0e68..49fe075c3 100644 --- a/cypress/platform/knsv2.html +++ b/cypress/platform/knsv2.html @@ -29,9 +29,9 @@ } .mermaid svg { /* font-size: 18px !important; */ - background-color: #eee; - background-image: radial-gradient(#fff 1%, transparent 11%), - radial-gradient(#fff 1%, transparent 11%); + background-color: #efefef; + background-image: radial-gradient(#fff 51%, transparent 91%), + radial-gradient(#fff 51%, transparent 91%); background-size: 20px 20px; background-position: 0 0, 10px 10px; background-repeat: repeat; @@ -58,43 +58,96 @@
-      %%{init: {"flowchart": {"htmlLabels": false}} }%%
-flowchart-elk LR
-b(`The dog in **the** hog(2)... a a a a *very long text* about it
-Word!
-Another line with many, many words. Another line with many, many words. Another line with many, many words. Another line with many, many words. Another line with many, many words. Another line with many, many words. Another line with many, many words. Another line with many, many words. `)
+stateDiagram-v2
+    [*] --> Still
+    Still --> [*]
+    Still --> Moving
+    Moving --> Still
+    Moving --> Crash
+    Crash --> [*]    
+
+flowchart RL
+    subgraph "`one`"
+      a1 -- l1 --> a2
+      a1 -- l2 --> a2
+    end
+    
+
+flowchart RL
+    subgraph "`one`"
+      a1 -- l1 --> a2
+      a1 -- l2 --> a2
+    end
+    
+
+flowchart
+id["`A root with a long text that wraps to keep the node size in check. A root with a long text that wraps to keep the node size in check`"]
+
+flowchart LR
+    A[A text that needs to be wrapped wraps to another line]
+    B[A text that needs to be
wrapped wraps to another line] + C["`A text that needs to be wrapped to another line`"]
+
+flowchart LR
+    C["`A text
+        that needs
+        to be wrapped
+        in another
+        way`"]
+  
+
+      classDiagram-v2
+        note "I love this diagram!\nDo you love it?"
+    
+
+    stateDiagram-v2
+    State1: The state with a note with minus - and plus + in it
+    note left of State1
+      Important information! You can write
+      notes with . and  in them.
+    end note    
+
+mindmap
+root
+  Child3(A node with an icon and with a long text that wraps to keep the node size in check)
 
-flowchart-elk LR
-b("The dog in the hog... a very
long text about it
Word!") -
-
-flowchart-elk LR
-b("The dog in the hog... a very
long text about it
Word!") -
- > + %%{init: {"theme": "forest"} }%% +mindmap + id1[**Start2**
end] + id2[**Start2**
end] + %% Another comment + id3[**Start2**
end] %% Comment + id4[**Start2**
end
the very end] +
 mindmap
-    id1[`**Start2**
-    second line 😎 with long text that is wrapping to the next line`]
-      id2[`Child **with bold** text`]
-      id3[`Children of which some
-      is using *italic type of* text`]
+    id1["`**Start2**
+    second line 😎 with long text that is wrapping to the next line`"]
+      id2["`Child **with bold** text`"]
+      id3["`Children of which some
+      is using *italic type of* text`"]
       id4[Child]
-      id5[`Child
+      id5["`Child
       Row
       and another
-      `]
-    
-
-mindmap
-    id1["`**Start** with
-    a second line 😎`"]
-      id2["`The dog in **the** hog... a *very long text* about it
-Word!`"]
+      `"]
     
+mindmap
+    id1("`**Root**`"]
+      id2["`A formatted text... with **bold** and *italics*`"]
+      id3[Regular labels works as usual]
+      id4["`Emojis and unicode works too: 🤓
+      शान्तिः سلام  和平 `"]
+
+    
+
 %%{init: {"flowchart": {"defaultRenderer": "elk"}} }%%
 flowchart TB
   %% I could not figure out how to use double quotes in labels in Mermaid
@@ -110,7 +163,7 @@ flowchart TB
     rom --> core2
   end
 
-  subgraph amd[AMD Latte GPU]
+  subgraph amd["`**AMD** Latte GPU`"]
     mem[Memory & I/O Bridge]
     dram[DRAM Controller]
     edram[32 MB EDRAM MEM1]
@@ -149,6 +202,62 @@ flowchart TB
   rtc{{rtc}}
 
+
+%%{init: {"flowchart": {"defaultRenderer": "elk", "htmlLabels": false}} }%%
+flowchart TB
+  %% I could not figure out how to use double quotes in labels in Mermaid
+  subgraph ibm[IBM Espresso CPU]
+    core0[IBM PowerPC Broadway Core 0]
+    core1[IBM PowerPC Broadway Core 1]
+    core2[IBM PowerPC Broadway Core 2]
+
+    rom[16 KB ROM]
+
+    core0 --- core2
+
+    rom --> core2
+  end
+
+  subgraph amd["`**AMD** Latte GPU`"]
+    mem[Memory & I/O Bridge]
+    dram[DRAM Controller]
+    edram[32 MB EDRAM MEM1]
+    rom[512 B SEEPROM]
+
+    sata[SATA IF]
+    exi[EXI]
+
+    subgraph gx[GX]
+      sram[3 MB 1T-SRAM]
+    end
+
+    radeon[AMD Radeon R7xx GX2]
+
+    mem --- gx
+    mem --- radeon
+
+    rom --- mem
+
+    mem --- sata
+    mem --- exi
+
+    dram --- sata
+    dram --- exi
+  end
+
+  ddr3[2 GB DDR3 RAM MEM2]
+
+  mem --- ddr3
+  dram --- ddr3
+  edram --- ddr3
+
+  core1 --- mem
+
+  exi --- rtc
+  rtc{{rtc}}
+
+
 flowchart TB
@@ -291,16 +400,16 @@ mindmap
         // console.error('Mermaid error: ', err);
       };
       mermaid.initialize({
-        theme: 'forest',
+        // theme: 'forest',
         startOnLoad: true,
         logLevel: 0,
         flowchart: {
           // defaultRenderer: 'elk',
           useMaxWidth: false,
-          htmlLabels: false,
-          // htmlLabels: true,
+          // htmlLabels: false,
+          htmlLabels: true,
         },
-        // htmlLabels: true,
+        // htmlLabels: false,
         gantt: {
           useMaxWidth: false,
         },
diff --git a/docs/news/announcements.md b/docs/news/announcements.md
new file mode 100644
index 000000000..112bde52c
--- /dev/null
+++ b/docs/news/announcements.md
@@ -0,0 +1,13 @@
+> **Warning**
+>
+> ## THIS IS AN AUTOGENERATED FILE. DO NOT EDIT.
+>
+> ## Please edit the corresponding file in [/packages/mermaid/src/docs/news/announcements.md](../../packages/mermaid/src/docs/news/announcements.md).
+
+# Announcements
+
+## [Automatic text wrapping in flowcharts is here!](https://www.mermaidchart.com/blog/posts/automatic-text-wrapping-in-flowcharts-is-here)
+
+3 April 2023 · 3 mins
+
+Markdown Strings reduce the hassle # Starting from v10.
diff --git a/docs/news/blog.md b/docs/news/blog.md
new file mode 100644
index 000000000..dc6f3f635
--- /dev/null
+++ b/docs/news/blog.md
@@ -0,0 +1,31 @@
+> **Warning**
+>
+> ## THIS IS AN AUTOGENERATED FILE. DO NOT EDIT.
+>
+> ## Please edit the corresponding file in [/packages/mermaid/src/docs/news/blog.md](../../packages/mermaid/src/docs/news/blog.md).
+
+# Blog
+
+## [Mermaid Chart officially launched with sharable diagram links and presentation mode](https://www.mermaidchart.com/blog/posts/mermaid-chart-officially-launched-with-sharable-diagram-links-and-presentation-mode/)
+
+27 March 2023 · 2 mins
+
+Exciting news for all Mermaid OSS fans: Mermaid Chart has officially launched with Mermaid Chart!
+
+## [If you're not excited about ChatGPT, then you're not being creative](https://www.mermaidchart.com/blog/posts/if-youre-not-excited-about-chatgpt-then-youre-not-being-creative-enough/)
+
+8 March 2023 · 9 mins
+
+The hype around AI in general and ChatGPT, in particular, is so intense that it’s very understandable to assume the hype train is driving straight toward the trough of disillusionment.
+
+## [Flow charts are O(n)2 complex, so don't go over 100 connections](https://www.mermaidchart.com/blog/posts/flow-charts-are-on2-complex-so-dont-go-over-100-connections/)
+
+1 March 2023 · 12 mins
+
+Flowchart design is a game of balance: Read about the importance of dialling in the right level of detail and how to manage complexity in large flowcharts.
+
+## [Busting the myth that developers can't write](https://www.mermaidchart.com/blog/posts/busting-the-myth-that-developers-cant-write/)
+
+10 February 2023 · 10 mins
+
+Busting the myth that developers can’t write # It’s an annoying stereotype that developers don’t know how to write, speak, and otherwise communicate.
diff --git a/docs/public/favicon.ico b/docs/public/favicon.ico
index d41818c5b..05d8a737b 100644
Binary files a/docs/public/favicon.ico and b/docs/public/favicon.ico differ
diff --git a/docs/syntax/flowchart.md b/docs/syntax/flowchart.md
index c79f12b23..6f5b973e8 100644
--- a/docs/syntax/flowchart.md
+++ b/docs/syntax/flowchart.md
@@ -710,6 +710,44 @@ flowchart LR
   B1 --> B2
 ```
 
+## Markdown Strings
+
+The "Markdown Strings" feature enhances flowcharts and mind maps by offering a more versatile string type, which supports text formatting options such as bold and italics, and automatically wraps text within labels.
+
+```mermaid-example
+%%{init: {"flowchart": {"htmlLabels": false}} }%%
+flowchart LR
+subgraph "One"
+  a("`The **cat**
+  in the hat`") -- "edge label" --> b{{"`The **dog** in the hog`"}}
+end
+subgraph "`**Two**`"
+  c("`The **cat**
+  in the hat`") -- "`Bold **edge label**`" --> d("The dog in the hog")
+end
+```
+
+```mermaid
+%%{init: {"flowchart": {"htmlLabels": false}} }%%
+flowchart LR
+subgraph "One"
+  a("`The **cat**
+  in the hat`") -- "edge label" --> b{{"`The **dog** in the hog`"}}
+end
+subgraph "`**Two**`"
+  c("`The **cat**
+  in the hat`") -- "`Bold **edge label**`" --> d("The dog in the hog")
+end
+```
+
+Formatting:
+
+- For bold text, use double asterisks \*\* before and after the text.
+- For italics, use single asterisks \* before and after the text.
+- With traditional strings, you needed to add 
tags for text to wrap in nodes. However, markdown strings automatically wrap text when it becomes too long and allows you to start a new line by simply using a newline character instead of a
tag. + +This feature is applicable to node labels, edge labels, and subgraph labels. + ## Interaction It is possible to bind a click event to a node, the click can lead to either a javascript callback or to a link which will be opened in a new browser tab. **Note**: This functionality is disabled when using `securityLevel='strict'` and enabled when using `securityLevel='loose'`. diff --git a/docs/syntax/mindmap.md b/docs/syntax/mindmap.md index babe47756..9687bbef7 100644 --- a/docs/syntax/mindmap.md +++ b/docs/syntax/mindmap.md @@ -254,6 +254,34 @@ Root C ``` +## Markdown Strings + +The "Markdown Strings" feature enhances mind maps by offering a more versatile string type, which supports text formatting options such as bold and italics, and automatically wraps text within labels. + +```mermaid-example +mindmap + id1["`**Root** with +a second line +Unicode works too: 🤓`"] + id2["`The dog in **the** hog... a *very long text* that wraps to a new line`"] + id3[Regular labels still works] +``` + +```mermaid +mindmap + id1["`**Root** with +a second line +Unicode works too: 🤓`"] + id2["`The dog in **the** hog... a *very long text* that wraps to a new line`"] + id3[Regular labels still works] +``` + +Formatting: + +- For bold text, use double asterisks \*\* before and after the text. +- For italics, use single asterisks \* before and after the text. +- With traditional strings, you needed to add
tags for text to wrap in nodes. However, markdown strings automatically wrap text when it becomes too long and allows you to start a new line by simply using a newline character instead of a
tag. + ## Integrating with your library/website. Mindmap uses the experimental lazy loading & async rendering features which could change in the future. From version 9.4.0 this diagram is included in mermaid but use lazy loading in order to keep the size of mermaid down. This is important in order to be able to add additional diagrams going forward. diff --git a/package.json b/package.json index ca642e890..92b979d75 100644 --- a/package.json +++ b/package.json @@ -1,7 +1,7 @@ { "name": "mermaid-monorepo", "private": true, - "version": "10.0.2", + "version": "10.1.0", "description": "Markdownish syntax for generating flowcharts, sequence diagrams, class diagrams, gantt charts and git graphs.", "type": "module", "packageManager": "pnpm@7.30.1", diff --git a/packages/mermaid/package.json b/packages/mermaid/package.json index 82a641719..02edc874b 100644 --- a/packages/mermaid/package.json +++ b/packages/mermaid/package.json @@ -1,6 +1,6 @@ { "name": "mermaid", - "version": "10.0.2", + "version": "10.1.0", "description": "Markdown-ish syntax for generating flowcharts, sequence diagrams, class diagrams, gantt charts and git graphs.", "type": "module", "module": "./dist/mermaid.core.mjs", diff --git a/packages/mermaid/src/dagre-wrapper/clusters.js b/packages/mermaid/src/dagre-wrapper/clusters.js index 453fcb8f5..2b87b91a6 100644 --- a/packages/mermaid/src/dagre-wrapper/clusters.js +++ b/packages/mermaid/src/dagre-wrapper/clusters.js @@ -63,13 +63,20 @@ const rect = (parent, node) => { .attr('width', width) .attr('height', node.height + padding); + if (useHtmlLabels) { + label.attr( + 'transform', + // This puts the labal on top of the box instead of inside it + 'translate(' + (node.x - bbox.width / 2) + ', ' + (node.y - node.height / 2) + ')' + ); + } else { + label.attr( + 'transform', + // This puts the labal on top of the box instead of inside it + 'translate(' + node.x + ', ' + (node.y - node.height / 2) + ')' + ); + } // Center the label - label.attr( - 'transform', - // This puts the labal on top of the box instead of inside it - // 'translate(' + (node.x - bbox.width / 2) + ', ' + (node.y - node.height / 2 - bbox.height) + ')' - 'translate(' + node.x + ', ' + (node.y - node.height / 2) + ')' - ); const rectBox = rect.node().getBBox(); node.width = rectBox.width; diff --git a/packages/mermaid/src/dagre-wrapper/nodes.js b/packages/mermaid/src/dagre-wrapper/nodes.js index 3e71f500a..d5af81c1b 100644 --- a/packages/mermaid/src/dagre-wrapper/nodes.js +++ b/packages/mermaid/src/dagre-wrapper/nodes.js @@ -316,15 +316,19 @@ const rect = (parent, node) => { // add the rect const rect = shapeSvg.insert('rect', ':first-child'); - const totalWidth = bbox.width + node.padding * 2; - const totalHeight = bbox.height + node.padding * 2; + // const totalWidth = bbox.width + node.padding * 2; + // const totalHeight = bbox.height + node.padding * 2; + const totalWidth = bbox.width + node.padding; + const totalHeight = bbox.height + node.padding; rect .attr('class', 'basic label-container') .attr('style', node.style) .attr('rx', node.rx) .attr('ry', node.ry) - .attr('x', -bbox.width / 2 - node.padding) - .attr('y', -bbox.height / 2 - node.padding) + // .attr('x', -bbox.width / 2 - node.padding) + // .attr('y', -bbox.height / 2 - node.padding) + .attr('x', -bbox.width / 2 - halfPadding) + .attr('y', -bbox.height / 2 - halfPadding) .attr('width', totalWidth) .attr('height', totalHeight); @@ -351,7 +355,7 @@ const rect = (parent, node) => { const labelRect = (parent, node) => { const { shapeSvg } = labelHelper(parent, node, 'label', true); - log.info('Classes = ', node.classes); + log.trace('Classes = ', node.classes); // add the rect const rect = shapeSvg.insert('rect', ':first-child'); diff --git a/packages/mermaid/src/dagre-wrapper/shapes/note.js b/packages/mermaid/src/dagre-wrapper/shapes/note.js index 6b693fdf6..a39450d54 100644 --- a/packages/mermaid/src/dagre-wrapper/shapes/note.js +++ b/packages/mermaid/src/dagre-wrapper/shapes/note.js @@ -1,8 +1,13 @@ import { updateNodeBounds, labelHelper } from './util'; import { log } from '../../logger'; +import { getConfig } from '../../config'; import intersect from '../intersect/index.js'; const note = (parent, node) => { + const useHtmlLabels = node.useHtmlLabels || getConfig().flowchart.htmlLabels; + if (!useHtmlLabels) { + node.centerLabel = true; + } const { shapeSvg, bbox, halfPadding } = labelHelper(parent, node, 'node ' + node.classes, true); log.info('Classes = ', node.classes); diff --git a/packages/mermaid/src/dagre-wrapper/shapes/util.js b/packages/mermaid/src/dagre-wrapper/shapes/util.js index b5de2bd6b..1eeeebb72 100644 --- a/packages/mermaid/src/dagre-wrapper/shapes/util.js +++ b/packages/mermaid/src/dagre-wrapper/shapes/util.js @@ -6,6 +6,7 @@ import { select } from 'd3'; import { evaluate, sanitizeText } from '../../diagrams/common/common'; export const labelHelper = (parent, node, _classes, isNode) => { let classes; + const useHtmlLabels = node.useHtmlLabels || evaluate(getConfig().flowchart.htmlLabels); if (!_classes) { classes = 'node default'; } else { @@ -33,7 +34,7 @@ export const labelHelper = (parent, node, _classes, isNode) => { if (node.labelType === 'markdown') { // text = textNode; text = createText(label, sanitizeText(decodeEntities(labelText), getConfig()), { - useHtmlLabels: getConfig().flowchart.htmlLabels, + useHtmlLabels, width: node.width || getConfig().flowchart.wrappingWidth, classes: 'markdown-node-label', }); @@ -62,11 +63,14 @@ export const labelHelper = (parent, node, _classes, isNode) => { const halfPadding = node.padding / 2; // Center the label - if (getConfig().flowchart.htmlLabels) { + if (useHtmlLabels) { label.attr('transform', 'translate(' + -bbox.width / 2 + ', ' + -bbox.height / 2 + ')'); } else { label.attr('transform', 'translate(' + 0 + ', ' + -bbox.height / 2 + ')'); } + if (node.centerLabel) { + label.attr('transform', 'translate(' + -bbox.width / 2 + ', ' + -bbox.height / 2 + ')'); + } label.insert('rect', ':first-child'); return { shapeSvg, bbox, halfPadding, label }; }; diff --git a/packages/mermaid/src/diagrams/flowchart/elk/flowRenderer-elk.js b/packages/mermaid/src/diagrams/flowchart/elk/flowRenderer-elk.js index 5849177b9..4748807d1 100644 --- a/packages/mermaid/src/diagrams/flowchart/elk/flowRenderer-elk.js +++ b/packages/mermaid/src/diagrams/flowchart/elk/flowRenderer-elk.js @@ -934,9 +934,12 @@ const drawNodes = (relX, relY, nodeArray, svg, subgraphsEl, diagObj, depth) => { .attr('width', node.width) .attr('height', node.height); const label = subgraphEl.insert('g').attr('class', 'label'); + const labelCentering = getConfig().flowchart.htmlLabels ? node.labelData.width / 2 : 0; label.attr( 'transform', - `translate(${node.labels[0].x + relX + node.x}, ${node.labels[0].y + relY + node.y})` + `translate(${node.labels[0].x + relX + node.x + labelCentering}, ${ + node.labels[0].y + relY + node.y + 3 + })` ); label.node().appendChild(node.labelData.labelNode); diff --git a/packages/mermaid/src/diagrams/flowchart/styles.ts b/packages/mermaid/src/diagrams/flowchart/styles.ts index 86ffcb7ed..964505c2d 100644 --- a/packages/mermaid/src/diagrams/flowchart/styles.ts +++ b/packages/mermaid/src/diagrams/flowchart/styles.ts @@ -23,11 +23,11 @@ const getStyles = (options: FlowChartStyleOptions) => .cluster-label text { fill: ${options.titleColor}; } - .cluster-label span { + .cluster-label span,p { color: ${options.titleColor}; } - .label text,span { + .label text,span,p { fill: ${options.nodeTextColor || options.textColor}; color: ${options.nodeTextColor || options.textColor}; } @@ -92,7 +92,7 @@ const getStyles = (options: FlowChartStyleOptions) => fill: ${options.titleColor}; } - .cluster span { + .cluster span,p { color: ${options.titleColor}; } /* .cluster div { diff --git a/packages/mermaid/src/diagrams/mindmap/mindmapRenderer.js b/packages/mermaid/src/diagrams/mindmap/mindmapRenderer.js index a2a4def59..86260e155 100644 --- a/packages/mermaid/src/diagrams/mindmap/mindmapRenderer.js +++ b/packages/mermaid/src/diagrams/mindmap/mindmapRenderer.js @@ -175,7 +175,7 @@ export const draw = async (text, id, version, diagObj) => { // Parse the graph definition diagObj.parser.parse(text); - log.debug('Renering mindmap diagram\n' + text, diagObj); + log.debug('Rendering mindmap diagram\n' + text, diagObj.parser); const securityLevel = getConfig().securityLevel; // Handle root and Document for when rendering in sandbox mode diff --git a/packages/mermaid/src/diagrams/mindmap/parser/mindmap.jison b/packages/mermaid/src/diagrams/mindmap/parser/mindmap.jison index 84a6191cf..9dd046a3d 100644 --- a/packages/mermaid/src/diagrams/mindmap/parser/mindmap.jison +++ b/packages/mermaid/src/diagrams/mindmap/parser/mindmap.jison @@ -18,7 +18,7 @@ %% -\s*\%\%.* {yy.getLogger().trace('Found comment',yytext);} +\s*\%\%.* {yy.getLogger().trace('Found comment',yytext); return 'SPACELINE';} // \%\%[^\n]*\n /* skip comments */ "mindmap" return 'MINDMAP'; ":::" { this.begin('CLASS'); } diff --git a/packages/mermaid/src/diagrams/mindmap/svgDraw.js b/packages/mermaid/src/diagrams/mindmap/svgDraw.js index 8b58c11a3..ab7dcc1e3 100644 --- a/packages/mermaid/src/diagrams/mindmap/svgDraw.js +++ b/packages/mermaid/src/diagrams/mindmap/svgDraw.js @@ -217,7 +217,8 @@ export const drawNode = function (elem, node, fullSection, conf) { // Create the wrapped text element const textElem = nodeElem.append('g'); - const newEl = createText(textElem, node.descr, { + const description = node.descr.replace(/()/g, '\n'); + const newEl = createText(textElem, description, { useHtmlLabels: htmlLabels, width: node.width, classes: 'mindmap-node-label', diff --git a/packages/mermaid/src/diagrams/state/stateRenderer-v2.js b/packages/mermaid/src/diagrams/state/stateRenderer-v2.js index 8629f74db..c2b1a9b6d 100644 --- a/packages/mermaid/src/diagrams/state/stateRenderer-v2.js +++ b/packages/mermaid/src/diagrams/state/stateRenderer-v2.js @@ -232,6 +232,9 @@ const setupNode = (g, parent, parsedItem, diagramStates, diagramDb, altFlag) => type: newNode.type, padding: 15, //getConfig().flowchart.padding }; + // if (useHtmlLabels) { + nodeData.centerLabel = true; + // } if (parsedItem.note) { // Todo: set random id @@ -240,6 +243,7 @@ const setupNode = (g, parent, parsedItem, diagramStates, diagramDb, altFlag) => shape: SHAPE_NOTE, labelText: parsedItem.note.text, classes: CSS_DIAGRAM_NOTE, + // useHtmlLabels: false, style: '', // styles.style, id: itemId + NOTE_ID + '-' + graphItemCount, domId: stateDomId(itemId, graphItemCount, NOTE), diff --git a/packages/mermaid/src/docs/.vitepress/config.ts b/packages/mermaid/src/docs/.vitepress/config.ts index 9b01fdbde..040b6a71a 100644 --- a/packages/mermaid/src/docs/.vitepress/config.ts +++ b/packages/mermaid/src/docs/.vitepress/config.ts @@ -28,7 +28,16 @@ export default defineConfig({ }, socialLinks: [ { icon: 'github', link: 'https://github.com/mermaid-js/mermaid' }, - { icon: 'slack', link: 'https://mermaid-talk.slack.com' }, + { + icon: 'slack', + link: 'https://join.slack.com/t/mermaid-talk/shared_invite/enQtNzc4NDIyNzk4OTAyLWVhYjQxOTI2OTg4YmE1ZmJkY2Y4MTU3ODliYmIwOTY3NDJlYjA0YjIyZTdkMDMyZTUwOGI0NjEzYmEwODcwOTE', + }, + { + icon: { + svg: '', + }, + link: 'https://www.mermaidchart.com/', + }, ], }, }); @@ -42,6 +51,11 @@ function nav() { activeMatch: '/config/', }, { text: 'Integrations', link: '/ecosystem/integrations', activeMatch: '/ecosystem/' }, + { + text: 'Latest News', + link: '/news/announcements', + activeMatch: '/announcements', + }, { text: version, items: [ @@ -80,6 +94,7 @@ function sidebarAll() { ...sidebarEcosystem(), ...sidebarConfig(), ...sidebarCommunity(), + ...sidebarNews(), ]; } @@ -162,3 +177,16 @@ function sidebarCommunity() { }, ]; } + +function sidebarNews() { + return [ + { + text: '📰 Latest News', + collapsible: true, + items: [ + { text: 'Announcements', link: '/news/announcements' }, + { text: 'Blog', link: '/news/blog' }, + ], + }, + ]; +} diff --git a/packages/mermaid/src/docs/index.md b/packages/mermaid/src/docs/index.md index b0b38bd79..59b6607fe 100644 --- a/packages/mermaid/src/docs/index.md +++ b/packages/mermaid/src/docs/index.md @@ -23,15 +23,15 @@ features: - title: ➕ Easy to use! details: Easily create and render detailed diagrams and charts with the Mermaid Live Editor. link: https://mermaid.live/ - - title: 🎥 Video Tutorials! - details: Curated list of video tutorials and examples created by the community. - link: ../../config/Tutorials.html - title: 🧩 Integrations available! details: Use Mermaid with your favorite applications, check out the integrations list. link: ../../ecosystem/integrations.md - title: 🏆 Award winning! details: 2019 JavaScript Open Source Award winner for "The Most Exciting Use of Technology". link: https://osawards.com/javascript/2019 + - title: 🥰 Mermaid + Mermaid Chart + details: Mermaid Chart is a major supporter of the Mermaid project. + link: https://www.mermaidchart.com/ --- diff --git a/packages/mermaid/src/docs/news/announcements.md b/packages/mermaid/src/docs/news/announcements.md new file mode 100644 index 000000000..4dd07bf3b --- /dev/null +++ b/packages/mermaid/src/docs/news/announcements.md @@ -0,0 +1,7 @@ +# Announcements + +## [Automatic text wrapping in flowcharts is here!](https://www.mermaidchart.com/blog/posts/automatic-text-wrapping-in-flowcharts-is-here) + +3 April 2023 · 3 mins + +Markdown Strings reduce the hassle # Starting from v10. diff --git a/packages/mermaid/src/docs/news/blog.md b/packages/mermaid/src/docs/news/blog.md new file mode 100644 index 000000000..b835bbe35 --- /dev/null +++ b/packages/mermaid/src/docs/news/blog.md @@ -0,0 +1,25 @@ +# Blog + +## [Mermaid Chart officially launched with sharable diagram links and presentation mode](https://www.mermaidchart.com/blog/posts/mermaid-chart-officially-launched-with-sharable-diagram-links-and-presentation-mode/) + +27 March 2023 · 2 mins + +Exciting news for all Mermaid OSS fans: Mermaid Chart has officially launched with Mermaid Chart! + +## [If you're not excited about ChatGPT, then you're not being creative](https://www.mermaidchart.com/blog/posts/if-youre-not-excited-about-chatgpt-then-youre-not-being-creative-enough/) + +8 March 2023 · 9 mins + +The hype around AI in general and ChatGPT, in particular, is so intense that it’s very understandable to assume the hype train is driving straight toward the trough of disillusionment. + +## [Flow charts are O(n)2 complex, so don't go over 100 connections](https://www.mermaidchart.com/blog/posts/flow-charts-are-on2-complex-so-dont-go-over-100-connections/) + +1 March 2023 · 12 mins + +Flowchart design is a game of balance: Read about the importance of dialling in the right level of detail and how to manage complexity in large flowcharts. + +## [Busting the myth that developers can't write](https://www.mermaidchart.com/blog/posts/busting-the-myth-that-developers-cant-write/) + +10 February 2023 · 10 mins + +Busting the myth that developers can’t write # It’s an annoying stereotype that developers don’t know how to write, speak, and otherwise communicate. diff --git a/packages/mermaid/src/docs/public/favicon.ico b/packages/mermaid/src/docs/public/favicon.ico index d41818c5b..05d8a737b 100644 Binary files a/packages/mermaid/src/docs/public/favicon.ico and b/packages/mermaid/src/docs/public/favicon.ico differ diff --git a/packages/mermaid/src/docs/syntax/flowchart.md b/packages/mermaid/src/docs/syntax/flowchart.md index 8e73f597b..936607cbd 100644 --- a/packages/mermaid/src/docs/syntax/flowchart.md +++ b/packages/mermaid/src/docs/syntax/flowchart.md @@ -446,6 +446,31 @@ flowchart LR B1 --> B2 ``` +## Markdown Strings + +The "Markdown Strings" feature enhances flowcharts and mind maps by offering a more versatile string type, which supports text formatting options such as bold and italics, and automatically wraps text within labels. + +```mermaid-example +%%{init: {"flowchart": {"htmlLabels": false}} }%% +flowchart LR +subgraph "One" + a("`The **cat** + in the hat`") -- "edge label" --> b{{"`The **dog** in the hog`"}} +end +subgraph "`**Two**`" + c("`The **cat** + in the hat`") -- "`Bold **edge label**`" --> d("The dog in the hog") +end +``` + +Formatting: + +- For bold text, use double asterisks \*\* before and after the text. +- For italics, use single asterisks \* before and after the text. +- With traditional strings, you needed to add
tags for text to wrap in nodes. However, markdown strings automatically wrap text when it becomes too long and allows you to start a new line by simply using a newline character instead of a
tag. + +This feature is applicable to node labels, edge labels, and subgraph labels. + ## Interaction It is possible to bind a click event to a node, the click can lead to either a javascript callback or to a link which will be opened in a new browser tab. **Note**: This functionality is disabled when using `securityLevel='strict'` and enabled when using `securityLevel='loose'`. diff --git a/packages/mermaid/src/docs/syntax/mindmap.md b/packages/mermaid/src/docs/syntax/mindmap.md index 1cb1f68d4..64a25821a 100644 --- a/packages/mermaid/src/docs/syntax/mindmap.md +++ b/packages/mermaid/src/docs/syntax/mindmap.md @@ -162,6 +162,25 @@ Root C ``` +## Markdown Strings + +The "Markdown Strings" feature enhances mind maps by offering a more versatile string type, which supports text formatting options such as bold and italics, and automatically wraps text within labels. + +```mermaid-example +mindmap + id1["`**Root** with +a second line +Unicode works too: 🤓`"] + id2["`The dog in **the** hog... a *very long text* that wraps to a new line`"] + id3[Regular labels still works] +``` + +Formatting: + +- For bold text, use double asterisks \*\* before and after the text. +- For italics, use single asterisks \* before and after the text. +- With traditional strings, you needed to add
tags for text to wrap in nodes. However, markdown strings automatically wrap text when it becomes too long and allows you to start a new line by simply using a newline character instead of a
tag. + ## Integrating with your library/website. Mindmap uses the experimental lazy loading & async rendering features which could change in the future. From version 9.4.0 this diagram is included in mermaid but use lazy loading in order to keep the size of mermaid down. This is important in order to be able to add additional diagrams going forward. diff --git a/packages/mermaid/src/rendering-util/createText.js b/packages/mermaid/src/rendering-util/createText.js index 1097cd0df..f20736f3a 100644 --- a/packages/mermaid/src/rendering-util/createText.js +++ b/packages/mermaid/src/rendering-util/createText.js @@ -152,26 +152,8 @@ function updateTextContentAndStyles(tspan, wrappedLine) { .attr('font-style', word.type === 'em' ? 'italic' : 'normal') .attr('class', 'text-inner-tspan') .attr('font-weight', word.type === 'strong' ? 'bold' : 'normal'); - const special = [ - '<', - '>', - '&', - '"', - "'", - '.', - ',', - ':', - ';', - '!', - '?', - '(', - ')', - '[', - ']', - '{', - '}', - ]; - if (index !== 0 && special.includes(word.content)) { + const special = ['"', "'", '.', ',', ':', ';', '!', '?', '(', ')', '[', ']', '{', '}']; + if (index === 0) { innerTspan.text(word.content); } else { innerTspan.text(' ' + word.content); @@ -225,7 +207,17 @@ export const createText = ( return vertexNode; } else { const structuredText = markdownToLines(text); - + const special = ['"', "'", '.', ',', ':', ';', '!', '?', '(', ')', '[', ']', '{', '}']; + let lastWord; + structuredText.forEach((line) => { + line.forEach((word) => { + if (special.includes(word.content) && lastWord) { + lastWord.content += word.content; + word.content = ''; + } + lastWord = word; + }); + }); const svgLabel = createFormattedText(width, el, structuredText, addSvgBackground); return svgLabel; } diff --git a/packages/mermaid/src/rendering-util/handle-markdown-text.js b/packages/mermaid/src/rendering-util/handle-markdown-text.js index cd79623fe..93704b2fe 100644 --- a/packages/mermaid/src/rendering-util/handle-markdown-text.js +++ b/packages/mermaid/src/rendering-util/handle-markdown-text.js @@ -38,6 +38,8 @@ export function markdownToLines(markdown) { currentLine++; lines.push([]); } + + // textLine.split(/ (?=[^!"#$%&'()*+,-./:;<=>?@[\]^_`{|}~]+)/).forEach((word) => { textLine.split(' ').forEach((word) => { if (word) { lines[currentLine].push({ content: word, type: parentType || 'normal' });