#3358 Adding support for style statements

This commit is contained in:
Knut Sveidqvist 2024-01-05 20:56:57 +01:00
parent 275e01acba
commit 818cb2fd76
7 changed files with 74 additions and 20 deletions

View File

@ -72,18 +72,38 @@ block-beta
</pre>
<pre id="diagram" class="mermaid">
block-beta
columns 3
columns 3
space Browser space
space:3
A
B
C
space:3
space
db{{"This is the text in the box"}}
classDef green fill:#9f6,stroke:#333,stroke-width:2px;
A
B
class A green
</pre>
<pre id="diagram" class="mermaid">
stateDiagram-v2
classDef green fill:#9f6,stroke:#333,stroke-width:2px;
A
style B fill:#f9F,stroke:#333,stroke-width:4px
class A green
Browser --> A
Browser --> B
Browser --> C
A --> db
B --> db
C--> db
block
D
E
end
</pre>
<pre id="diagram" class="mermaid2">
flowchart
B
style B fill:#f9F,stroke:#333,stroke-width:4px
</pre>
<pre id="diagram" class="mermaid2">
block-beta

View File

@ -56,6 +56,20 @@ export const addStyleClass = function (id: string, styleAttributes = '') {
}
};
/**
* Called when the parser comes across a (style) class definition
* @example classDef my-style fill:#f96;
*
* @param {string} id - the id of this (style) class
* @param {string | null} styles - the string with 1 or more style attributes (each separated by a comma)
*/
export const addStyle2Node = function (id: string, styles = '') {
let foundBlock = blockDatabase[id];
if (styles !== undefined && styles !== null) {
foundBlock.styles = styles.split(STYLECLASS_SEP);
}
};
/**
* Add a (style) class or css class to a state with the given id.
* If the state isn't already in the list of known states, add it.
@ -116,14 +130,21 @@ const populateBlockDatabase = (_blockList: Block[], parent: Block): void => {
const children = [];
for (const block of blockList) {
if (block.type === 'classDef') {
console.log('abc88 classDef', block);
// console.log('abc88 classDef', block);
addStyleClass(block.id, block.css);
continue;
}
if (block.type === 'applyClass') {
console.log('abc88 applyClass', block);
// console.log('abc88 applyClass', block);
// addStyleClass(block.id, block.css);
setCssClass(block.id, block.styleClass);
setCssClass(block.id, block?.styleClass || '');
continue;
}
if (block.type === 'applyStyles') {
console.log('abc88 applyStyles', block);
addStyle2Node(block.id, block.styles);
// addStyleClass(block.id, block.css);
// setCssClass(block.id, block.styles);
continue;
}
if (block.type === 'column-setting') {

View File

@ -30,6 +30,7 @@ export type BlockType =
| 'doublecircle'
| 'classDef'
| 'applyClass'
| 'applyStyles'
| 'composite';
export interface Block {
@ -57,6 +58,7 @@ export interface Block {
directions?: string[];
css?: string;
styleClass?: string;
styles?: string[];
}
export interface Link {

View File

@ -23,6 +23,8 @@
%x CLASS_STYLE
%x CLASSDEF
%x CLASSDEFID
%x STYLE_STMNT
%x STYLE_DEFINITION
// as per section 6.1 of RFC 2234 [2]
@ -53,7 +55,6 @@ CRLF \u000D\u000A
<string>[^"]* { yy.getLogger().debug('LEX: STR end:', yytext); return "STR";}
space[:]\d+ { yytext = yytext.replace(/space\:/,'');yy.getLogger().info('SPACE NUM (LEX)', yytext); return 'SPACE_BLOCK'; }
space { yytext = '1'; yy.getLogger().info('COLUMNS (LEX)', yytext); return 'SPACE_BLOCK'; }
"style" return 'STYLE';
"default" return 'DEFAULT';
"linkStyle" return 'LINKSTYLE';
"interpolate" return 'INTERPOLATE';
@ -67,6 +68,10 @@ space { yytext = '1'; yy.getLogger().info('COLUMNS (LEX)', yyte
<CLASS>(\w+)+((","\s*\w+)*) { this.popState(); this.pushState('CLASS_STYLE'); return 'CLASSENTITY_IDS' }
<CLASS_STYLE>[^\n]* { this.popState(); return 'STYLECLASS' }
"style"\s+ { this.pushState('STYLE_STMNT'); return 'style'; }
<STYLE_STMNT>(\w+)+((","\s*\w+)*) { this.popState(); this.pushState('STYLE_DEFINITION'); return 'STYLE_ENTITY_IDS' }
<STYLE_DEFINITION>[^\n]* { this.popState(); return 'STYLE_DEFINITION_DATA' }
accTitle\s*":"\s* { this.pushState("acc_title");return 'acc_title'; }
<acc_title>(?!\n|;|#)*[^\n]* { this.popState(); return "acc_title_value"; }
accDescr\s*":"\s* { this.pushState("acc_descr");return 'acc_descr'; }
@ -208,6 +213,7 @@ statement
| blockStatement
| classDefStatement
| cssClassStatement
| styleStatement
;
nodeStatement
@ -271,4 +277,11 @@ cssClassStatement
}
;
styleStatement
: style STYLE_ENTITY_IDS STYLE_DEFINITION_DATA {
console.log('abc88 apply class: id(s): ',$2, ' style class: ', $3);
$$={ type: 'applyStyles', id: $2.trim(), styles: $3.trim() };
}
;
%%

View File

@ -16,10 +16,9 @@ function getNodeFromBlock(block: Block, db: BlockDB, positioned = false) {
let classStr = 'default';
if ((vertex?.classes?.length || 0) > 0) {
console.log('abc88 vertex.classes', block.id, vertex?.classes);
classStr = (vertex?.classes || []).join(' ');
}
console.log('abc88 vertex.classes done');
console.log('abc88 vertex.classes styles', block.id, vertex?.styles);
classStr = classStr + ' flowchart-label';
// We create a SVG label, either by delegating to addHtmlLabel or manually
@ -100,8 +99,8 @@ function getNodeFromBlock(block: Block, db: BlockDB, positioned = false) {
_shape = 'rect';
}
// const styles = getStylesFromArray(vertex.styles);
const styles = getStylesFromArray([]);
const styles = getStylesFromArray(vertex?.styles || '');
// const styles = getStylesFromArray([]);
// Use vertex id as text in the box if no text is provided by the graph definition
const vertexText = vertex.label;
@ -116,7 +115,7 @@ function getNodeFromBlock(block: Block, db: BlockDB, positioned = false) {
rx: radious,
ry: radious,
class: classStr,
style: styles.style,
style: styles.style, // + 'fill:#9f9;stroke:#333;stroke-width:4px;',
id: vertex.id,
directions: vertex.directions,
// link: vertex.link,

View File

@ -169,7 +169,7 @@ export const addVertices = function (vert, g, svgId, root, doc, diagObj) {
padding: getConfig().flowchart.padding,
});
log.info('setNode', {
log.info('abc88 setNode', {
labelStyle: styles.labelStyle,
labelType: vertex.labelType,
shape: _shape,

View File

@ -513,7 +513,6 @@ const render = async function (
const a11yTitle: string | undefined = diag.db.getAccTitle?.();
const a11yDescr: string | undefined = diag.db.getAccDescription?.();
addA11yInfo(diagramType, svgNode, a11yTitle, a11yDescr);
// -------------------------------------------------------------------------------
// Clean up SVG code
root.select(`[id="${id}"]`).selectAll('foreignobject > *').attr('xmlns', XMLNS_XHTML_STD);