From 4daef2591d937181c5081e24ab01e24165a0eca0 Mon Sep 17 00:00:00 2001 From: jakobskrym Date: Sat, 30 Mar 2024 12:03:55 +0100 Subject: [PATCH 1/6] feat: add support for fa-kit icons --- packages/mermaid/src/diagrams/flowchart/flowRenderer.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/packages/mermaid/src/diagrams/flowchart/flowRenderer.js b/packages/mermaid/src/diagrams/flowchart/flowRenderer.js index c9e152012d..9edfb6f471 100644 --- a/packages/mermaid/src/diagrams/flowchart/flowRenderer.js +++ b/packages/mermaid/src/diagrams/flowchart/flowRenderer.js @@ -59,7 +59,7 @@ export const addVertices = async function (vert, g, svgId, root, _doc, diagObj) const node = { label: await renderKatex( vertexText.replace( - /fa[blrs]?:fa-[\w-]+/g, // cspell:disable-line + /fa[bklrs]?:fa-[\w-]+/g, // cspell:disable-line (s) => `` ), getConfig() @@ -244,7 +244,7 @@ export const addEdges = async function (edges, g, diagObj) { edgeData.labelStyle }">${await renderKatex( edge.text.replace( - /fa[blrs]?:fa-[\w-]+/g, // cspell:disable-line + /fa[bklrs]?:fa-[\w-]+/g, // cspell:disable-line (s) => `` ), getConfig() From 0aa526d707a7dcbe139f7746c8c885d9422839f5 Mon Sep 17 00:00:00 2001 From: jakobskrym Date: Sat, 30 Mar 2024 12:08:16 +0100 Subject: [PATCH 2/6] feat: add in additional files --- packages/mermaid/src/dagre-wrapper/createLabel.js | 2 +- packages/mermaid/src/rendering-util/createText.ts | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/packages/mermaid/src/dagre-wrapper/createLabel.js b/packages/mermaid/src/dagre-wrapper/createLabel.js index 22496a2509..ab0be63531 100644 --- a/packages/mermaid/src/dagre-wrapper/createLabel.js +++ b/packages/mermaid/src/dagre-wrapper/createLabel.js @@ -60,7 +60,7 @@ const createLabel = (_vertexText, style, isTitle, isNode) => { const node = { isNode, label: decodeEntities(vertexText).replace( - /fa[blrs]?:fa-[\w-]+/g, // cspell: disable-line + /fa[bklrs]?:fa-[\w-]+/g, // cspell: disable-line (s) => `` ), labelStyle: style.replace('fill:', 'color:'), diff --git a/packages/mermaid/src/rendering-util/createText.ts b/packages/mermaid/src/rendering-util/createText.ts index 725d65da66..c4cc2792c9 100644 --- a/packages/mermaid/src/rendering-util/createText.ts +++ b/packages/mermaid/src/rendering-util/createText.ts @@ -192,7 +192,7 @@ export const createText = ( const node = { isNode, label: decodeEntities(htmlText).replace( - /fa[blrs]?:fa-[\w-]+/g, // cspell: disable-line + /fa[bklrs]?:fa-[\w-]+/g, // cspell: disable-line (s) => `` ), labelStyle: style.replace('fill:', 'color:'), From 90b11113826aff6beb44dc142849cf914174f8d0 Mon Sep 17 00:00:00 2001 From: jakobskrym Date: Sat, 30 Mar 2024 12:21:01 +0100 Subject: [PATCH 3/6] docs: update docs with new info --- docs/syntax/flowchart.md | 10 ++++++++++ packages/mermaid/src/docs/syntax/flowchart.md | 10 ++++++++++ 2 files changed, 20 insertions(+) diff --git a/docs/syntax/flowchart.md b/docs/syntax/flowchart.md index 83676b0e41..e578af0796 100644 --- a/docs/syntax/flowchart.md +++ b/docs/syntax/flowchart.md @@ -1178,6 +1178,16 @@ Adding this snippet in the `` would add support for Font Awesome v6.5.1 /> ``` +It is possible to use custom icons served from Font Awesome as long as the website imports the corresponding kit. Note that this is currently a paid feature from Font Awesome. + +For custom icons, you need to use the `fak` prefix. + +``` +flowchart TD + B["fa:fa-twitter for peace"] + B-->E(fak:fa-custom-icon-name) %% this will try to find your kit's custom icon +``` + ## Graph declarations with spaces between vertices and link and without semicolon - In graph declarations, the statements also can now end without a semicolon. After release 0.2.16, ending a graph statement with semicolon is just optional. So the below graph declaration is also valid along with the old declarations of the graph. diff --git a/packages/mermaid/src/docs/syntax/flowchart.md b/packages/mermaid/src/docs/syntax/flowchart.md index 462a9aecc9..571e753532 100644 --- a/packages/mermaid/src/docs/syntax/flowchart.md +++ b/packages/mermaid/src/docs/syntax/flowchart.md @@ -799,6 +799,16 @@ Adding this snippet in the `` would add support for Font Awesome v6.5.1 /> ``` +It is possible to use custom icons served from Font Awesome as long as the website imports the corresponding kit. Note that this is currently a paid feature from Font Awesome. + +For custom icons, you need to use the `fak` prefix. + +``` +flowchart TD + B["fa:fa-twitter for peace"] + B-->E(fak:fa-custom-icon-name) %% this will try to find your kit's custom icon +``` + ## Graph declarations with spaces between vertices and link and without semicolon - In graph declarations, the statements also can now end without a semicolon. After release 0.2.16, ending a graph statement with semicolon is just optional. So the below graph declaration is also valid along with the old declarations of the graph. From 63f9d3e0b49c568df1c812589587a81207c7a83f Mon Sep 17 00:00:00 2001 From: jakobskrym Date: Sat, 30 Mar 2024 12:28:18 +0100 Subject: [PATCH 4/6] docs: finish docs --- docs/syntax/flowchart.md | 12 +++++++++--- packages/mermaid/src/docs/syntax/flowchart.md | 12 +++++++++--- 2 files changed, 18 insertions(+), 6 deletions(-) diff --git a/docs/syntax/flowchart.md b/docs/syntax/flowchart.md index e578af0796..1dd9fc22e2 100644 --- a/docs/syntax/flowchart.md +++ b/docs/syntax/flowchart.md @@ -1178,14 +1178,20 @@ Adding this snippet in the `` would add support for Font Awesome v6.5.1 /> ``` -It is possible to use custom icons served from Font Awesome as long as the website imports the corresponding kit. Note that this is currently a paid feature from Font Awesome. +### Custom icons + +It is possible to use custom icons served from Font Awesome as long as the website imports the corresponding kit. + +Note that this is currently a paid feature from Font Awesome. For custom icons, you need to use the `fak` prefix. +**Example** + ``` flowchart TD - B["fa:fa-twitter for peace"] - B-->E(fak:fa-custom-icon-name) %% this will try to find your kit's custom icon + B[fa:fa-twitter] %% standard icon + B-->E(fak:fa-custom-icon-name) %% custom icon ``` ## Graph declarations with spaces between vertices and link and without semicolon diff --git a/packages/mermaid/src/docs/syntax/flowchart.md b/packages/mermaid/src/docs/syntax/flowchart.md index 571e753532..86f7446a5a 100644 --- a/packages/mermaid/src/docs/syntax/flowchart.md +++ b/packages/mermaid/src/docs/syntax/flowchart.md @@ -799,14 +799,20 @@ Adding this snippet in the `` would add support for Font Awesome v6.5.1 /> ``` -It is possible to use custom icons served from Font Awesome as long as the website imports the corresponding kit. Note that this is currently a paid feature from Font Awesome. +### Custom icons + +It is possible to use custom icons served from Font Awesome as long as the website imports the corresponding kit. + +Note that this is currently a paid feature from Font Awesome. For custom icons, you need to use the `fak` prefix. +**Example** + ``` flowchart TD - B["fa:fa-twitter for peace"] - B-->E(fak:fa-custom-icon-name) %% this will try to find your kit's custom icon + B[fa:fa-twitter] %% standard icon + B-->E(fak:fa-custom-icon-name) %% custom icon ``` ## Graph declarations with spaces between vertices and link and without semicolon From 0051620840cd195efdfea84d408842ba17040636 Mon Sep 17 00:00:00 2001 From: jakobskrym Date: Mon, 1 Apr 2024 19:05:35 +0200 Subject: [PATCH 5/6] feat: create utils func + test cases --- docs/syntax/flowchart.md | 14 ++++++++ .../mermaid/src/dagre-wrapper/createLabel.js | 6 ++-- .../src/diagrams/flowchart/flowRenderer.js | 18 +++------- packages/mermaid/src/docs/syntax/flowchart.md | 8 +++++ .../src/rendering-util/createText.spec.ts | 34 +++++++++++++++++++ .../mermaid/src/rendering-util/createText.ts | 21 +++++++++--- 6 files changed, 79 insertions(+), 22 deletions(-) create mode 100644 packages/mermaid/src/rendering-util/createText.spec.ts diff --git a/docs/syntax/flowchart.md b/docs/syntax/flowchart.md index 1dd9fc22e2..8edb5e208d 100644 --- a/docs/syntax/flowchart.md +++ b/docs/syntax/flowchart.md @@ -1194,6 +1194,20 @@ flowchart TD B-->E(fak:fa-custom-icon-name) %% custom icon ``` +And trying to render it + +```mermaid-example +flowchart TD + B["fa:fa-twitter for peace"] + B-->C["fab:fa-truck-bold a custom icon"] +``` + +```mermaid +flowchart TD + B["fa:fa-twitter for peace"] + B-->C["fab:fa-truck-bold a custom icon"] +``` + ## Graph declarations with spaces between vertices and link and without semicolon - In graph declarations, the statements also can now end without a semicolon. After release 0.2.16, ending a graph statement with semicolon is just optional. So the below graph declaration is also valid along with the old declarations of the graph. diff --git a/packages/mermaid/src/dagre-wrapper/createLabel.js b/packages/mermaid/src/dagre-wrapper/createLabel.js index ab0be63531..f49d65f251 100644 --- a/packages/mermaid/src/dagre-wrapper/createLabel.js +++ b/packages/mermaid/src/dagre-wrapper/createLabel.js @@ -3,6 +3,7 @@ import { log } from '../logger.js'; import { getConfig } from '../diagram-api/diagramAPI.js'; import { evaluate } from '../diagrams/common/common.js'; import { decodeEntities } from '../utils.js'; +import { replaceIconSubstring } from '../rendering-util/createText.js'; /** * @param dom @@ -59,10 +60,7 @@ const createLabel = (_vertexText, style, isTitle, isNode) => { log.debug('vertexText' + vertexText); const node = { isNode, - label: decodeEntities(vertexText).replace( - /fa[bklrs]?:fa-[\w-]+/g, // cspell: disable-line - (s) => `` - ), + label: replaceIconSubstring(decodeEntities(vertexText)), labelStyle: style.replace('fill:', 'color:'), }; let vertexNode = addHtmlLabel(node); diff --git a/packages/mermaid/src/diagrams/flowchart/flowRenderer.js b/packages/mermaid/src/diagrams/flowchart/flowRenderer.js index 9edfb6f471..b2e6bcc9cb 100644 --- a/packages/mermaid/src/diagrams/flowchart/flowRenderer.js +++ b/packages/mermaid/src/diagrams/flowchart/flowRenderer.js @@ -9,6 +9,7 @@ import common, { evaluate, renderKatex } from '../common/common.js'; import { interpolateToCurve, getStylesFromArray } from '../../utils.js'; import { setupGraphViewbox } from '../../setupGraphViewbox.js'; import flowChartShapes from './flowChartShapes.js'; +import { replaceIconSubstring } from '../../rendering-util/createText.js'; const conf = {}; export const setConf = function (cnf) { @@ -56,14 +57,9 @@ export const addVertices = async function (vert, g, svgId, root, _doc, diagObj) let vertexNode; if (evaluate(getConfig().flowchart.htmlLabels)) { // TODO: addHtmlLabel accepts a labelStyle. Do we possibly have that? + const replacedVertexText = replaceIconSubstring(vertexText); const node = { - label: await renderKatex( - vertexText.replace( - /fa[bklrs]?:fa-[\w-]+/g, // cspell:disable-line - (s) => `` - ), - getConfig() - ), + label: await renderKatex(replacedVertexText, getConfig()), }; vertexNode = addHtmlLabel(svg, node).node(); vertexNode.parentNode.removeChild(vertexNode); @@ -242,13 +238,7 @@ export const addEdges = async function (edges, g, diagObj) { edgeData.labelType = 'html'; edgeData.label = `${await renderKatex( - edge.text.replace( - /fa[bklrs]?:fa-[\w-]+/g, // cspell:disable-line - (s) => `` - ), - getConfig() - )}`; + }">${await renderKatex(replaceIconSubstring(edge.text), getConfig())}`; } else { edgeData.labelType = 'text'; edgeData.label = edge.text.replace(common.lineBreakRegex, '\n'); diff --git a/packages/mermaid/src/docs/syntax/flowchart.md b/packages/mermaid/src/docs/syntax/flowchart.md index 86f7446a5a..ba0e9ce9e9 100644 --- a/packages/mermaid/src/docs/syntax/flowchart.md +++ b/packages/mermaid/src/docs/syntax/flowchart.md @@ -815,6 +815,14 @@ flowchart TD B-->E(fak:fa-custom-icon-name) %% custom icon ``` +And trying to render it + +```mermaid-example +flowchart TD + B["fa:fa-twitter for peace"] + B-->C["fab:fa-truck-bold a custom icon"] +``` + ## Graph declarations with spaces between vertices and link and without semicolon - In graph declarations, the statements also can now end without a semicolon. After release 0.2.16, ending a graph statement with semicolon is just optional. So the below graph declaration is also valid along with the old declarations of the graph. diff --git a/packages/mermaid/src/rendering-util/createText.spec.ts b/packages/mermaid/src/rendering-util/createText.spec.ts new file mode 100644 index 0000000000..da0505ad8d --- /dev/null +++ b/packages/mermaid/src/rendering-util/createText.spec.ts @@ -0,0 +1,34 @@ +import { describe, it, expect } from 'vitest'; +import { replaceIconSubstring } from './createText.js'; + +describe('replaceIconSubstring', () => { + it('converts FontAwesome icon notations to HTML tags', () => { + const input = 'This is an icon: fa:fa-user and fab:fa-github'; + const output = replaceIconSubstring(input); + const expected = + "This is an icon: and "; + expect(output).toEqual(expected); + }); + + it('handles strings without FontAwesome icon notations', () => { + const input = 'This string has no icons'; + const output = replaceIconSubstring(input); + expect(output).toEqual(input); // No change expected + }); + + it('correctly processes multiple FontAwesome icon notations in one string', () => { + const input = 'Icons galore: fa:fa-arrow-right, fak:fa-truck, fas:fa-home'; + const output = replaceIconSubstring(input); + const expected = + "Icons galore: , , "; + expect(output).toEqual(expected); + }); + + it('correctly replaces a very long icon name with the fak prefix', () => { + const input = 'Here is a long icon: fak:fa-truck-driving-long-winding-road in use'; + const output = replaceIconSubstring(input); + const expected = + "Here is a long icon: in use"; + expect(output).toEqual(expected); + }); +}); diff --git a/packages/mermaid/src/rendering-util/createText.ts b/packages/mermaid/src/rendering-util/createText.ts index c4cc2792c9..ba872ac76a 100644 --- a/packages/mermaid/src/rendering-util/createText.ts +++ b/packages/mermaid/src/rendering-util/createText.ts @@ -168,6 +168,21 @@ function updateTextContentAndStyles(tspan: any, wrappedLine: MarkdownWord[]) { }); } +/** + * + * @param text - The raw string to adjust + * @returns + */ + +// Used for converting substrings in node labels/edges/text into fontawesome icons by using a regex pattern +// The letters 'bklrs' stand for possible endings of the fontawesome prefix (e.g. 'fab' for brands, 'fak' for fa-kit) // cspell: disable-line +export function replaceIconSubstring(text: string) { + return text.replace( + /fa[bklrs]?:fa-[\w-]+/g, // cspell: disable-line + (s) => `` + ); +} + // Note when using from flowcharts converting the API isNode means classes should be set accordingly. When using htmlLabels => to sett classes to'nodeLabel' when isNode=true otherwise 'edgeLabel' // When not using htmlLabels => to set classes to 'title-row' when isTitle=true otherwise 'title-row' export const createText = ( @@ -189,12 +204,10 @@ export const createText = ( // TODO: addHtmlLabel accepts a labelStyle. Do we possibly have that? const htmlText = markdownToHTML(text, config); + const decodedReplacedText = replaceIconSubstring(decodeEntities(htmlText)); const node = { isNode, - label: decodeEntities(htmlText).replace( - /fa[bklrs]?:fa-[\w-]+/g, // cspell: disable-line - (s) => `` - ), + label: decodedReplacedText, labelStyle: style.replace('fill:', 'color:'), }; const vertexNode = addHtmlSpan(el, node, width, classes, addSvgBackground); From 3555577581a33135239ae0b235c2a2ea6ea959bc Mon Sep 17 00:00:00 2001 From: Jakob <66998665+jakobskrym@users.noreply.github.com> Date: Wed, 3 Apr 2024 09:02:20 +0200 Subject: [PATCH 6/6] Update createText.ts Co-authored-by: Sidharth Vinod --- packages/mermaid/src/rendering-util/createText.ts | 10 ++++------ 1 file changed, 4 insertions(+), 6 deletions(-) diff --git a/packages/mermaid/src/rendering-util/createText.ts b/packages/mermaid/src/rendering-util/createText.ts index ba872ac76a..0a7e3bbb09 100644 --- a/packages/mermaid/src/rendering-util/createText.ts +++ b/packages/mermaid/src/rendering-util/createText.ts @@ -169,14 +169,12 @@ function updateTextContentAndStyles(tspan: any, wrappedLine: MarkdownWord[]) { } /** - * - * @param text - The raw string to adjust - * @returns + * Convert fontawesome labels into fontawesome icons by using a regex pattern + * @param text - The raw string to convert + * @returns string with fontawesome icons as i tags */ - -// Used for converting substrings in node labels/edges/text into fontawesome icons by using a regex pattern -// The letters 'bklrs' stand for possible endings of the fontawesome prefix (e.g. 'fab' for brands, 'fak' for fa-kit) // cspell: disable-line export function replaceIconSubstring(text: string) { + // The letters 'bklrs' stand for possible endings of the fontawesome prefix (e.g. 'fab' for brands, 'fak' for fa-kit) // cspell: disable-line return text.replace( /fa[bklrs]?:fa-[\w-]+/g, // cspell: disable-line (s) => ``