Add support for classDiagram labels

This commit is contained in:
Sidharth Vinod
2023-02-14 00:36:43 +05:30
parent 46f2aebabc
commit 102900749e
6 changed files with 52 additions and 43 deletions

View File

@@ -19,6 +19,7 @@
"brkt", "brkt",
"brolin", "brolin",
"brotli", "brotli",
"Città",
"classdef", "classdef",
"codedoc", "codedoc",
"colour", "colour",
@@ -109,7 +110,11 @@
"yash" "yash"
], ],
"patterns": [ "patterns": [
{ "name": "Markdown links", "pattern": "\\((.*)\\)", "description": "" }, {
"name": "Markdown links",
"pattern": "\\((.*)\\)",
"description": ""
},
{ {
"name": "Markdown code blocks", "name": "Markdown code blocks",
"pattern": "/^(\\s*`{3,}).*[\\s\\S]*?^\\1/gmx", "pattern": "/^(\\s*`{3,}).*[\\s\\S]*?^\\1/gmx",
@@ -120,14 +125,25 @@
"pattern": "\\`([^\\`\\r\\n]+?)\\`", "pattern": "\\`([^\\`\\r\\n]+?)\\`",
"description": "https://stackoverflow.com/questions/41274241/how-to-capture-inline-markdown-code-but-not-a-markdown-code-fence-with-regex" "description": "https://stackoverflow.com/questions/41274241/how-to-capture-inline-markdown-code-but-not-a-markdown-code-fence-with-regex"
}, },
{ "name": "Link contents", "pattern": "\\<a(.*)\\>", "description": "" }, {
{ "name": "Snippet references", "pattern": "-- snippet:(.*)", "description": "" }, "name": "Link contents",
"pattern": "\\<a(.*)\\>",
"description": ""
},
{
"name": "Snippet references",
"pattern": "-- snippet:(.*)",
"description": ""
},
{ {
"name": "Snippet references 2", "name": "Snippet references 2",
"pattern": "\\<\\[sample:(.*)", "pattern": "\\<\\[sample:(.*)",
"description": "another kind of snippet reference" "description": "another kind of snippet reference"
}, },
{ "name": "Multi-line code blocks", "pattern": "/^\\s*```[\\s\\S]*?^\\s*```/gm" }, {
"name": "Multi-line code blocks",
"pattern": "/^\\s*```[\\s\\S]*?^\\s*```/gm"
},
{ {
"name": "HTML Tags", "name": "HTML Tags",
"pattern": "<[^>]*>", "pattern": "<[^>]*>",

View File

@@ -22,7 +22,7 @@ export const mermaidUrl = (graphStr, options, api) => {
return url; return url;
}; };
export const imgSnapshotTest = (graphStr, _options, api = false, validation) => { export const imgSnapshotTest = (graphStr, _options = {}, api = false, validation = undefined) => {
cy.log(_options); cy.log(_options);
const options = Object.assign(_options); const options = Object.assign(_options);
if (!options.fontFamily) { if (!options.fontFamily) {

View File

@@ -772,7 +772,7 @@ const class_box = (parent, node) => {
maxWidth += interfaceBBox.width; maxWidth += interfaceBBox.width;
} }
let classTitleString = node.classData.id; let classTitleString = node.classData.label;
if (node.classData.type !== undefined && node.classData.type !== '') { if (node.classData.type !== undefined && node.classData.type !== '') {
if (getConfig().flowchart.htmlLabels) { if (getConfig().flowchart.htmlLabels) {

View File

@@ -13,33 +13,12 @@ import {
setDiagramTitle, setDiagramTitle,
getDiagramTitle, getDiagramTitle,
} from '../../commonDb'; } from '../../commonDb';
import { ClassRelation, ClassNode, ClassNote, ClassMap } from './classTypes';
const MERMAID_DOM_ID_PREFIX = 'classid-'; const MERMAID_DOM_ID_PREFIX = 'classId-';
interface ClassNode {
id: string;
type: string;
cssClasses: string[];
methods: string[];
members: string[];
annotations: string[];
domId: string;
link?: string;
linkTarget?: string;
haveCallback?: boolean;
tooltip?: string;
}
interface ClassNote {
id: string;
class: string;
text: string;
}
type ClassRelation = any;
let relations: ClassRelation[] = []; let relations: ClassRelation[] = [];
let classes: Record<string, ClassNode> = {}; let classes: ClassMap = {};
let notes: ClassNote[] = []; let notes: ClassNote[] = [];
let classCounter = 0; let classCounter = 0;
@@ -58,9 +37,8 @@ const splitClassNameAndType = function (id: string) {
if (id.indexOf('~') > 0) { if (id.indexOf('~') > 0) {
const split = id.split('~'); const split = id.split('~');
className = split[0]; className = sanitizeText(split[0]);
genericType = sanitizeText(split[1]);
genericType = common.sanitizeText(split[1], configApi.getConfig());
} }
return { className: className, type: genericType }; return { className: className, type: genericType };
@@ -70,18 +48,24 @@ const splitClassNameAndType = function (id: string) {
* Function called by parser when a node definition has been found. * Function called by parser when a node definition has been found.
* *
* @param id - Id of the class to add * @param id - Id of the class to add
* @param label - Optional label of the class
* @public * @public
*/ */
export const addClass = function (id: string) { export const addClass = function (id: string, label?: string) {
const classId = splitClassNameAndType(id); const classId = splitClassNameAndType(id);
// Only add class if not exists // Only add class if not exists
if (classes[classId.className] !== undefined) { if (classes[classId.className] !== undefined) {
return; return;
} }
if (label) {
label = sanitizeText(label);
}
classes[classId.className] = { classes[classId.className] = {
id: classId.className, id: classId.className,
type: classId.type, type: classId.type,
label: label ?? classId.className,
cssClasses: [], cssClasses: [],
methods: [], methods: [],
members: [], members: [],
@@ -121,7 +105,7 @@ export const getClasses = function () {
return classes; return classes;
}; };
export const getRelations = function () { export const getRelations = function (): ClassRelation[] {
return relations; return relations;
}; };
@@ -182,7 +166,6 @@ export const addMember = function (className: string, member: string) {
if (memberString.startsWith('<<') && memberString.endsWith('>>')) { if (memberString.startsWith('<<') && memberString.endsWith('>>')) {
// Remove leading and trailing brackets // Remove leading and trailing brackets
// theClass.annotations.push(memberString.substring(2, memberString.length - 2));
theClass.annotations.push(sanitizeText(memberString.substring(2, memberString.length - 2))); theClass.annotations.push(sanitizeText(memberString.substring(2, memberString.length - 2)));
} else if (memberString.indexOf(')') > 0) { } else if (memberString.indexOf(')') > 0) {
theClass.methods.push(sanitizeText(memberString)); theClass.methods.push(sanitizeText(memberString));
@@ -359,8 +342,7 @@ export const relationType = {
}; };
const setupToolTips = function (element: Element) { const setupToolTips = function (element: Element) {
let tooltipElem: Selection<HTMLDivElement, unknown, HTMLElement, unknown> = let tooltipElem: Selection<HTMLDivElement, unknown, HTMLElement, unknown> = select('.mermaidTooltip');
select('.mermaidTooltip');
// @ts-ignore - _groups is a dynamic property // @ts-ignore - _groups is a dynamic property
if ((tooltipElem._groups || tooltipElem)[0][0] === null) { if ((tooltipElem._groups || tooltipElem)[0][0] === null) {
tooltipElem = select('body').append('div').attr('class', 'mermaidTooltip').style('opacity', 0); tooltipElem = select('body').append('div').attr('class', 'mermaidTooltip').style('opacity', 0);

View File

@@ -8,7 +8,7 @@ import { curveLinear } from 'd3';
import { interpolateToCurve, getStylesFromArray } from '../../utils'; import { interpolateToCurve, getStylesFromArray } from '../../utils';
import { setupGraphViewbox } from '../../setupGraphViewbox'; import { setupGraphViewbox } from '../../setupGraphViewbox';
import common from '../common/common'; import common from '../common/common';
import { ClassRelation, ClassNode, ClassNote, ClassMap, EdgeData } from './classTypes'; import { ClassRelation, ClassNote, ClassMap, EdgeData } from './classTypes';
const sanitizeText = (txt: string) => common.sanitizeText(txt, getConfig()); const sanitizeText = (txt: string) => common.sanitizeText(txt, getConfig());

View File

@@ -119,6 +119,8 @@ Function arguments are optional: 'call <callback_name>()' simply executes 'callb
"=" return 'EQUALS'; "=" return 'EQUALS';
\= return 'EQUALS'; \= return 'EQUALS';
\w+ return 'ALPHA'; \w+ return 'ALPHA';
"[" return 'SQS';
"]" return 'SQE';
[!"#$%&'*+,-.`?\\/] return 'PUNCTUATION'; [!"#$%&'*+,-.`?\\/] return 'PUNCTUATION';
[0-9]+ return 'NUM'; [0-9]+ return 'NUM';
[\u00AA\u00B5\u00BA\u00C0-\u00D6\u00D8-\u00F6]| [\u00AA\u00B5\u00BA\u00C0-\u00D6\u00D8-\u00F6]|
@@ -249,6 +251,10 @@ statements
| statement NEWLINE statements | statement NEWLINE statements
; ;
classLabel
: SQS STR SQE { $$=$2; }
;
className className
: alphaNumToken { $$=$1; } : alphaNumToken { $$=$1; }
| classLiteralName { $$=$1; } | classLiteralName { $$=$1; }
@@ -274,10 +280,15 @@ statement
; ;
classStatement classStatement
: CLASS className {yy.addClass($2);} : classIdentifier
| CLASS className STYLE_SEPARATOR alphaNumToken {yy.addClass($2);yy.setCssClass($2, $4);} | classIdentifier STYLE_SEPARATOR alphaNumToken {yy.setCssClass($1, $3);}
| CLASS className STRUCT_START members STRUCT_STOP {/*console.log($2,JSON.stringify($4));*/yy.addClass($2);yy.addMembers($2,$4);} | classIdentifier STRUCT_START members STRUCT_STOP {yy.addMembers($1,$3);}
| CLASS className STYLE_SEPARATOR alphaNumToken STRUCT_START members STRUCT_STOP {yy.addClass($2);yy.setCssClass($2, $4);yy.addMembers($2,$6);} | classIdentifier STYLE_SEPARATOR alphaNumToken STRUCT_START members STRUCT_STOP {yy.setCssClass($1, $3);yy.addMembers($1,$3);}
;
classIdentifier
: CLASS className {$$=$2; yy.addClass($2);}
| CLASS className classLabel {$$=$2; yy.addClass($2, $3);}
; ;
annotationStatement annotationStatement