mirror of
https://github.com/mermaid-js/mermaid.git
synced 2025-09-23 17:29:54 +02:00
Add directive parsing functionality to timeline diagram
This commit is contained in:
@@ -55,7 +55,7 @@
|
|||||||
</head>
|
</head>
|
||||||
<body>
|
<body>
|
||||||
<div>Security check</div>
|
<div>Security check</div>
|
||||||
<pre id="diagram" class="mermaid">
|
<pre id="diagram" class="mermaid2">
|
||||||
timeline
|
timeline
|
||||||
title My day
|
title My day
|
||||||
section section with no tasks
|
section section with no tasks
|
||||||
@@ -71,7 +71,7 @@
|
|||||||
I am a big big big tasks
|
I am a big big big tasks
|
||||||
I am not so big tasks
|
I am not so big tasks
|
||||||
</pre>
|
</pre>
|
||||||
<pre id="diagram" class="mermaid">
|
<pre id="diagram" class="mermaid2">
|
||||||
timeline
|
timeline
|
||||||
title England's History Timeline
|
title England's History Timeline
|
||||||
section Stone Age
|
section Stone Age
|
||||||
@@ -85,21 +85,7 @@
|
|||||||
|
|
||||||
</pre>
|
</pre>
|
||||||
<pre id="diagram" class="mermaid">
|
<pre id="diagram" class="mermaid">
|
||||||
timeline
|
%%{init: { 'logLevel': 'debug', 'theme': 'default', 'timeline': {'disableMulticolor':false} } }%%
|
||||||
title History of Social Media Platform
|
|
||||||
section Rise of Social Media
|
|
||||||
2002 : LinkedIn
|
|
||||||
2004 : Facebook : Google : Pixar
|
|
||||||
2005 : Youtube
|
|
||||||
2006 : Twitter
|
|
||||||
2007 : Tumblr
|
|
||||||
2008s : Instagram
|
|
||||||
2010 : Pinterest
|
|
||||||
</pre>
|
|
||||||
<pre id="diagram" class="mermaid">
|
|
||||||
---
|
|
||||||
timeline:disableMulticolor: true
|
|
||||||
---
|
|
||||||
timeline
|
timeline
|
||||||
title History of Social Media Platform
|
title History of Social Media Platform
|
||||||
2002 : LinkedIn
|
2002 : LinkedIn
|
||||||
@@ -111,6 +97,22 @@ timeline:disableMulticolor: true
|
|||||||
2010 : Pinterest
|
2010 : Pinterest
|
||||||
</pre>
|
</pre>
|
||||||
<pre id="diagram" class="mermaid">
|
<pre id="diagram" class="mermaid">
|
||||||
|
%%{init: { 'logLevel': 'debug', 'theme': 'default', 'themeVariables': {
|
||||||
|
'cScale0': '#ffffff',
|
||||||
|
'cScale1': '#00ff00',
|
||||||
|
'cScale2': '#0000ff',
|
||||||
|
} } }%%
|
||||||
|
timeline
|
||||||
|
title History of Social Media Platform
|
||||||
|
2002 : LinkedIn
|
||||||
|
2004 : Facebook : Google : Pixar
|
||||||
|
2005 : Youtube
|
||||||
|
2006 : Twitter
|
||||||
|
2007 : Tumblr
|
||||||
|
2008s : Instagram
|
||||||
|
2010 : Pinterest
|
||||||
|
</pre>
|
||||||
|
<pre id="diagram" class="mermaid2">
|
||||||
timeline
|
timeline
|
||||||
title History of Social Media Platform
|
title History of Social Media Platform
|
||||||
2002 : LinkedIn
|
2002 : LinkedIn
|
||||||
|
@@ -24,6 +24,9 @@ export let setLogLevel: (level: keyof typeof LEVELS | number | string) => void;
|
|||||||
export let getConfig: () => object;
|
export let getConfig: () => object;
|
||||||
export let sanitizeText: (str: string) => string;
|
export let sanitizeText: (str: string) => string;
|
||||||
export const getCommonDb = () => localCommonDb;
|
export const getCommonDb = () => localCommonDb;
|
||||||
|
export let parseDirective = (p: any, statement: string, context: string, type: string) => {
|
||||||
|
return;
|
||||||
|
}
|
||||||
/**
|
/**
|
||||||
* Placeholder for the real function that will be injected by mermaid.
|
* Placeholder for the real function that will be injected by mermaid.
|
||||||
*/
|
*/
|
||||||
@@ -52,9 +55,11 @@ export const injectUtils = (
|
|||||||
_getConfig: any,
|
_getConfig: any,
|
||||||
_sanitizeText: any,
|
_sanitizeText: any,
|
||||||
_setupGraphViewbox: any,
|
_setupGraphViewbox: any,
|
||||||
_commonDb: any
|
_commonDb: any,
|
||||||
|
_parseDirective: any
|
||||||
) => {
|
) => {
|
||||||
_log.info('Mermaid utils injected into timeline-diagram');
|
_log.info('Mermaid utils injected into timeline-diagram');
|
||||||
|
_log.info('123 ' , _parseDirective);
|
||||||
log.trace = _log.trace;
|
log.trace = _log.trace;
|
||||||
log.debug = _log.debug;
|
log.debug = _log.debug;
|
||||||
log.info = _log.info;
|
log.info = _log.info;
|
||||||
@@ -66,5 +71,6 @@ export const injectUtils = (
|
|||||||
sanitizeText = _sanitizeText;
|
sanitizeText = _sanitizeText;
|
||||||
setupGraphViewbox = _setupGraphViewbox;
|
setupGraphViewbox = _setupGraphViewbox;
|
||||||
localCommonDb = _commonDb;
|
localCommonDb = _commonDb;
|
||||||
|
parseDirective = _parseDirective;
|
||||||
|
|
||||||
};
|
};
|
||||||
|
@@ -1,4 +1,4 @@
|
|||||||
import { getCommonDb as _getCommonDb,log } from './mermaidUtils';
|
import { getCommonDb as _getCommonDb, parseDirective as _parseDirective ,log } from './mermaidUtils';
|
||||||
|
|
||||||
let currentSection = '';
|
let currentSection = '';
|
||||||
let currentTaskId = 0;
|
let currentTaskId = 0;
|
||||||
@@ -9,6 +9,10 @@ const rawTasks = [];
|
|||||||
|
|
||||||
export const getCommonDb = _getCommonDb;
|
export const getCommonDb = _getCommonDb;
|
||||||
|
|
||||||
|
export const parseDirective = ( statement, context, type) => {
|
||||||
|
_parseDirective(this, statement, context, type);
|
||||||
|
};
|
||||||
|
|
||||||
export const clear = function () {
|
export const clear = function () {
|
||||||
sections.length = 0;
|
sections.length = 0;
|
||||||
tasks.length = 0;
|
tasks.length = 0;
|
||||||
@@ -79,14 +83,14 @@ const compileTasks = function () {
|
|||||||
};
|
};
|
||||||
|
|
||||||
let allProcessed = true;
|
let allProcessed = true;
|
||||||
for (let i = 0; i < rawTasks.length; i++) {
|
for (const [i, rawTask] of rawTasks.entries()) {
|
||||||
compileTask(i);
|
compileTask(i);
|
||||||
|
|
||||||
allProcessed = allProcessed && rawTasks[i].processed;
|
allProcessed = allProcessed && rawTask.processed;
|
||||||
}
|
}
|
||||||
return allProcessed;
|
return allProcessed;
|
||||||
};
|
};
|
||||||
|
log.info('456 parseDirective',parseDirective);
|
||||||
export default {
|
export default {
|
||||||
clear,
|
clear,
|
||||||
getCommonDb,
|
getCommonDb,
|
||||||
@@ -96,5 +100,6 @@ export default {
|
|||||||
addTask,
|
addTask,
|
||||||
addTaskOrg,
|
addTaskOrg,
|
||||||
addEvent,
|
addEvent,
|
||||||
|
parseDirective
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@@ -17,7 +17,8 @@ export const draw = function (text, id, version, diagObj) {
|
|||||||
//1. Fetch the configuration
|
//1. Fetch the configuration
|
||||||
const conf = getConfig();
|
const conf = getConfig();
|
||||||
const LEFT_MARGIN = conf.leftMargin?conf.leftMargin:50;
|
const LEFT_MARGIN = conf.leftMargin?conf.leftMargin:50;
|
||||||
|
//log conf
|
||||||
|
log.info('conf', conf);
|
||||||
//2. Clear the diagram db before parsing
|
//2. Clear the diagram db before parsing
|
||||||
diagObj.db.clear();
|
diagObj.db.clear();
|
||||||
|
|
||||||
|
@@ -314,6 +314,7 @@ export interface TimelineDiagramConfig extends BaseDiagramConfig {
|
|||||||
actorColours?: string[];
|
actorColours?: string[];
|
||||||
sectionFills?: string[];
|
sectionFills?: string[];
|
||||||
sectionColours?: string[];
|
sectionColours?: string[];
|
||||||
|
disableMulticolor?: boolean;
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface GanttDiagramConfig extends BaseDiagramConfig {
|
export interface GanttDiagramConfig extends BaseDiagramConfig {
|
||||||
|
@@ -984,6 +984,8 @@ const config: Partial<MermaidConfig> = {
|
|||||||
*/
|
*/
|
||||||
useMaxWidth: true,
|
useMaxWidth: true,
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* | Parameter | Description | Type | Required | Values |
|
* | Parameter | Description | Type | Required | Values |
|
||||||
* | ----------- | --------------------------------- | ---- | -------- | ----------- |
|
* | ----------- | --------------------------------- | ---- | -------- | ----------- |
|
||||||
@@ -1009,6 +1011,7 @@ const config: Partial<MermaidConfig> = {
|
|||||||
|
|
||||||
sectionFills: ['#191970', '#8B008B', '#4B0082', '#2F4F4F', '#800000', '#8B4513', '#00008B'],
|
sectionFills: ['#191970', '#8B008B', '#4B0082', '#2F4F4F', '#800000', '#8B4513', '#00008B'],
|
||||||
sectionColours: ['#fff'],
|
sectionColours: ['#fff'],
|
||||||
|
disableMulticolor: false,
|
||||||
},
|
},
|
||||||
class: {
|
class: {
|
||||||
/**
|
/**
|
||||||
|
@@ -6,6 +6,7 @@ import { setupGraphViewbox as _setupGraphViewbox } from '../setupGraphViewbox';
|
|||||||
import { addStylesForDiagram } from '../styles';
|
import { addStylesForDiagram } from '../styles';
|
||||||
import { DiagramDefinition, DiagramDetector } from './types';
|
import { DiagramDefinition, DiagramDetector } from './types';
|
||||||
import * as _commonDb from '../commonDb';
|
import * as _commonDb from '../commonDb';
|
||||||
|
import { parseDirective as _parseDirective} from '../directiveUtils';
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@@ -19,6 +20,7 @@ export const getConfig = _getConfig;
|
|||||||
export const sanitizeText = (text: string) => _sanitizeText(text, getConfig());
|
export const sanitizeText = (text: string) => _sanitizeText(text, getConfig());
|
||||||
export const setupGraphViewbox = _setupGraphViewbox;
|
export const setupGraphViewbox = _setupGraphViewbox;
|
||||||
export const getCommonDb = () => { return _commonDb };
|
export const getCommonDb = () => { return _commonDb };
|
||||||
|
export const parseDirective = (p: any, statement: string, context: string, type: string)=>_parseDirective(p, statement, context, type);
|
||||||
|
|
||||||
const diagrams: Record<string, DiagramDefinition> = {};
|
const diagrams: Record<string, DiagramDefinition> = {};
|
||||||
export interface Detectors {
|
export interface Detectors {
|
||||||
@@ -49,7 +51,9 @@ export const registerDiagram = (
|
|||||||
addStylesForDiagram(id, diagram.styles);
|
addStylesForDiagram(id, diagram.styles);
|
||||||
|
|
||||||
if (diagram.injectUtils) {
|
if (diagram.injectUtils) {
|
||||||
diagram.injectUtils(log, setLogLevel, getConfig, sanitizeText, setupGraphViewbox,getCommonDb());
|
console.log('parseDirective', parseDirective);
|
||||||
|
|
||||||
|
diagram.injectUtils(log, setLogLevel, getConfig, sanitizeText, setupGraphViewbox,getCommonDb(),parseDirective);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@@ -7,6 +7,7 @@ export interface InjectUtils {
|
|||||||
_sanitizeText: any;
|
_sanitizeText: any;
|
||||||
_setupGraphViewbox: any;
|
_setupGraphViewbox: any;
|
||||||
_commonDb: any;
|
_commonDb: any;
|
||||||
|
_parseDirective: any;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -31,7 +32,8 @@ export interface DiagramDefinition {
|
|||||||
_getConfig: InjectUtils['_getConfig'],
|
_getConfig: InjectUtils['_getConfig'],
|
||||||
_sanitizeText: InjectUtils['_sanitizeText'],
|
_sanitizeText: InjectUtils['_sanitizeText'],
|
||||||
_setupGraphViewbox: InjectUtils['_setupGraphViewbox'],
|
_setupGraphViewbox: InjectUtils['_setupGraphViewbox'],
|
||||||
_commonDb: InjectUtils['_commonDb']
|
_commonDb: InjectUtils['_commonDb'],
|
||||||
|
_parseDirective: InjectUtils['_parseDirective'],
|
||||||
) => void;
|
) => void;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
84
packages/mermaid/src/directiveUtils.ts
Normal file
84
packages/mermaid/src/directiveUtils.ts
Normal file
@@ -0,0 +1,84 @@
|
|||||||
|
|
||||||
|
|
||||||
|
import * as configApi from './config';
|
||||||
|
|
||||||
|
import { log } from './logger';
|
||||||
|
import { directiveSanitizer } from './utils';
|
||||||
|
|
||||||
|
let currentDirective: { type?: string; args?: any } | undefined = {};
|
||||||
|
|
||||||
|
export const parseDirective = function (p: any, statement: string, context: string, type: string): void {
|
||||||
|
log.info('parseDirective is being called', statement, context, type);
|
||||||
|
try {
|
||||||
|
if (statement !== undefined) {
|
||||||
|
statement = statement.trim();
|
||||||
|
switch (context) {
|
||||||
|
case 'open_directive':
|
||||||
|
currentDirective = {};
|
||||||
|
break;
|
||||||
|
case 'type_directive':
|
||||||
|
if (!currentDirective) {
|
||||||
|
throw new Error('currentDirective is undefined');
|
||||||
|
}
|
||||||
|
currentDirective.type = statement.toLowerCase();
|
||||||
|
break;
|
||||||
|
case 'arg_directive':
|
||||||
|
if (!currentDirective) {
|
||||||
|
throw new Error('currentDirective is undefined');
|
||||||
|
}
|
||||||
|
currentDirective.args = JSON.parse(statement);
|
||||||
|
break;
|
||||||
|
case 'close_directive':
|
||||||
|
handleDirective(p, currentDirective, type);
|
||||||
|
currentDirective = undefined;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} catch (error) {
|
||||||
|
log.error(
|
||||||
|
`Error while rendering sequenceDiagram directive: ${statement} jison context: ${context}`
|
||||||
|
);
|
||||||
|
// @ts-ignore: TODO Fix ts errors
|
||||||
|
log.error(error.message);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
const handleDirective = function (p: any, directive: any, type: string): void {
|
||||||
|
log.info(`Directive type=${directive.type} with args:`, directive.args);
|
||||||
|
switch (directive.type) {
|
||||||
|
case 'init':
|
||||||
|
case 'initialize': {
|
||||||
|
['config'].forEach((prop) => {
|
||||||
|
if (directive.args[prop] !== undefined) {
|
||||||
|
if (type === 'flowchart-v2') {
|
||||||
|
type = 'flowchart';
|
||||||
|
}
|
||||||
|
directive.args[type] = directive.args[prop];
|
||||||
|
delete directive.args[prop];
|
||||||
|
}
|
||||||
|
});
|
||||||
|
log.info('sanitize in handleDirective', directive.args);
|
||||||
|
directiveSanitizer(directive.args);
|
||||||
|
log.info('sanitize in handleDirective (done)', directive.args);
|
||||||
|
configApi.addDirective(directive.args);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case 'wrap':
|
||||||
|
case 'nowrap':
|
||||||
|
if (p && p['setWrap']) {
|
||||||
|
p.setWrap(directive.type === 'wrap');
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case 'themeCss':
|
||||||
|
log.warn('themeCss encountered');
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
log.warn(
|
||||||
|
`Unhandled directive: source: '%%{${directive.type}: ${JSON.stringify(
|
||||||
|
directive.args ? directive.args : {}
|
||||||
|
)}}%%`,
|
||||||
|
directive
|
||||||
|
);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
};
|
@@ -31,6 +31,7 @@ import { MermaidConfig } from './config.type';
|
|||||||
import { evaluate } from './diagrams/common/common';
|
import { evaluate } from './diagrams/common/common';
|
||||||
import isEmpty from 'lodash-es/isEmpty.js';
|
import isEmpty from 'lodash-es/isEmpty.js';
|
||||||
import { setA11yDiagramInfo, addSVGa11yTitleDescription } from './accessibility';
|
import { setA11yDiagramInfo, addSVGa11yTitleDescription } from './accessibility';
|
||||||
|
import { parseDirective } from './directiveUtils';
|
||||||
|
|
||||||
// diagram names that support classDef statements
|
// diagram names that support classDef statements
|
||||||
const CLASSDEF_DIAGRAMS = ['graph', 'flowchart', 'flowchart-v2', 'stateDiagram', 'stateDiagram-v2'];
|
const CLASSDEF_DIAGRAMS = ['graph', 'flowchart', 'flowchart-v2', 'stateDiagram', 'stateDiagram-v2'];
|
||||||
@@ -777,82 +778,6 @@ const renderAsync = async function (
|
|||||||
return svgCode;
|
return svgCode;
|
||||||
};
|
};
|
||||||
|
|
||||||
let currentDirective: { type?: string; args?: any } | undefined = {};
|
|
||||||
|
|
||||||
const parseDirective = function (p: any, statement: string, context: string, type: string): void {
|
|
||||||
try {
|
|
||||||
if (statement !== undefined) {
|
|
||||||
statement = statement.trim();
|
|
||||||
switch (context) {
|
|
||||||
case 'open_directive':
|
|
||||||
currentDirective = {};
|
|
||||||
break;
|
|
||||||
case 'type_directive':
|
|
||||||
if (!currentDirective) {
|
|
||||||
throw new Error('currentDirective is undefined');
|
|
||||||
}
|
|
||||||
currentDirective.type = statement.toLowerCase();
|
|
||||||
break;
|
|
||||||
case 'arg_directive':
|
|
||||||
if (!currentDirective) {
|
|
||||||
throw new Error('currentDirective is undefined');
|
|
||||||
}
|
|
||||||
currentDirective.args = JSON.parse(statement);
|
|
||||||
break;
|
|
||||||
case 'close_directive':
|
|
||||||
handleDirective(p, currentDirective, type);
|
|
||||||
currentDirective = undefined;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} catch (error) {
|
|
||||||
log.error(
|
|
||||||
`Error while rendering sequenceDiagram directive: ${statement} jison context: ${context}`
|
|
||||||
);
|
|
||||||
// @ts-ignore: TODO Fix ts errors
|
|
||||||
log.error(error.message);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
const handleDirective = function (p: any, directive: any, type: string): void {
|
|
||||||
log.debug(`Directive type=${directive.type} with args:`, directive.args);
|
|
||||||
switch (directive.type) {
|
|
||||||
case 'init':
|
|
||||||
case 'initialize': {
|
|
||||||
['config'].forEach((prop) => {
|
|
||||||
if (directive.args[prop] !== undefined) {
|
|
||||||
if (type === 'flowchart-v2') {
|
|
||||||
type = 'flowchart';
|
|
||||||
}
|
|
||||||
directive.args[type] = directive.args[prop];
|
|
||||||
delete directive.args[prop];
|
|
||||||
}
|
|
||||||
});
|
|
||||||
log.debug('sanitize in handleDirective', directive.args);
|
|
||||||
directiveSanitizer(directive.args);
|
|
||||||
log.debug('sanitize in handleDirective (done)', directive.args);
|
|
||||||
configApi.addDirective(directive.args);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
case 'wrap':
|
|
||||||
case 'nowrap':
|
|
||||||
if (p && p['setWrap']) {
|
|
||||||
p.setWrap(directive.type === 'wrap');
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
case 'themeCss':
|
|
||||||
log.warn('themeCss encountered');
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
log.warn(
|
|
||||||
`Unhandled directive: source: '%%{${directive.type}: ${JSON.stringify(
|
|
||||||
directive.args ? directive.args : {}
|
|
||||||
)}}%%`,
|
|
||||||
directive
|
|
||||||
);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @param options - Initial Mermaid options
|
* @param options - Initial Mermaid options
|
||||||
|
Reference in New Issue
Block a user