Skip to content

Commit

Permalink
Merge branch 'develop' into feature/4060_Gantt-working-hours
Browse files Browse the repository at this point in the history
  • Loading branch information
sidharthv96 committed May 8, 2024
2 parents b7de58f + 9eb64cd commit 89f919f
Show file tree
Hide file tree
Showing 24 changed files with 1,422 additions and 918 deletions.
Binary file added docs/config/img/mathMLDifferences.png
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
10 changes: 10 additions & 0 deletions docs/config/math.md
Original file line number Diff line number Diff line change
Expand Up @@ -84,3 +84,13 @@ Example with legacy mode enabled (the latest version of KaTeX's stylesheet can b
</body>
</html>
```

## Handling Rendering Differences

Due to differences between default fonts across operating systems and browser's MathML implementations, inconsistent results can be seen across platforms. If having consistent results are important, or the most optimal rendered results are desired, `forceLegacyMathML` can be enabled in the config.

This option will always use KaTeX's stylesheet instead of only when MathML is not supported (as with `legacyMathML`). Note that only `forceLegacyMathML` needs to be set.

If including KaTeX's stylesheet is not a concern, enabling this option is recommended to avoid scenarios where no MathML implementation within a browser provides the desired output (as seen below).

![Image showing differences between Browsers](img/mathMLDifferences.png)
3 changes: 3 additions & 0 deletions docs/ecosystem/integrations-community.md
Original file line number Diff line number Diff line change
Expand Up @@ -240,6 +240,8 @@ Communication tools and platforms

### Other

- [Astro](https://astro.build/)
- [Adding diagrams to your Astro site with MermaidJS and Playwright](https://agramont.net/blog/diagraming-with-mermaidjs-astro/)
- [Bisheng](https://www.npmjs.com/package/bisheng)
- [bisheng-plugin-mermaid](https://github.com/yct21/bisheng-plugin-mermaid)
- [Blazorade Mermaid: Render Mermaid diagrams in Blazor applications](https://github.com/Blazorade/Blazorade-Mermaid/wiki)
Expand All @@ -249,6 +251,7 @@ Communication tools and platforms
- [Jekyll](https://jekyllrb.com/)
- [jekyll-mermaid](https://rubygems.org/gems/jekyll-mermaid)
- [jekyll-mermaid-diagrams](https://github.com/fuzhibo/jekyll-mermaid-diagrams)
- [MarkChart: Preview Mermaid diagrams on macOS](https://markchart.app/)
- [mermaid-isomorphic](https://github.com/remcohaszing/mermaid-isomorphic)
- [mermaid-server: Generate diagrams using a HTTP request](https://github.com/TomWright/mermaid-server)
- [NiceGUI: Let any browser be the frontend of your Python code](https://nicegui.io)
Expand Down
18 changes: 17 additions & 1 deletion docs/syntax/stateDiagram.md
Original file line number Diff line number Diff line change
Expand Up @@ -160,7 +160,7 @@ In a real world use of state diagrams you often end up with diagrams that are mu
have several internal states. These are called composite states in this terminology.

In order to define a composite state you need to use the state keyword followed by an id and the body of the composite
state between {}. See the example below:
state between {}. You can name a composite state on a separate line just like a simple state. See the example below:

```mermaid-example
stateDiagram-v2
Expand All @@ -169,6 +169,14 @@ stateDiagram-v2
[*] --> second
second --> [*]
}
[*] --> NamedComposite
NamedComposite: Another Composite
state NamedComposite {
[*] --> namedSimple
namedSimple --> [*]
namedSimple: Another simple
}
```

```mermaid
Expand All @@ -178,6 +186,14 @@ stateDiagram-v2
[*] --> second
second --> [*]
}
[*] --> NamedComposite
NamedComposite: Another Composite
state NamedComposite {
[*] --> namedSimple
namedSimple --> [*]
namedSimple: Another simple
}
```

You can do this in several layers:
Expand Down
2 changes: 1 addition & 1 deletion packages/mermaid/src/config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ export const updateCurrentConfig = (siteCfg: MermaidConfig, _directives: Mermaid
let sumOfDirectives: MermaidConfig = {};
for (const d of _directives) {
sanitize(d);
// Apply the data from the directive where the the overrides the themeVariables
// Apply the data from the directive where the overrides the themeVariables
sumOfDirectives = assignWithDepth(sumOfDirectives, d);
}

Expand Down
7 changes: 7 additions & 0 deletions packages/mermaid/src/config.type.ts
Original file line number Diff line number Diff line change
Expand Up @@ -120,6 +120,13 @@ export interface MermaidConfig {
*
*/
legacyMathML?: boolean;
/**
* This option forces Mermaid to rely on KaTeX's own stylesheet for rendering MathML. Due to differences between OS
* fonts and browser's MathML implementation, this option is recommended if consistent rendering is important.
* If set to true, ignores legacyMathML.
*
*/
forceLegacyMathML?: boolean;
/**
* This option controls if the generated ids of nodes in the SVG are
* generated randomly or based on a seed.
Expand Down
2 changes: 1 addition & 1 deletion packages/mermaid/src/dagre-wrapper/GraphObjects.md
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,7 @@ flowchart
a --> C2
```

To handle this case a special type of edge is inserted. The edge to/from the cluster is replaced with an edge to/from a node in the cluster which is tagged with toCluster/fromCluster. When rendering this edge the intersection between the edge and the border of the cluster is calculated making the edge start/stop there. In practice this renders like an an edge to/from the cluster.
To handle this case a special type of edge is inserted. The edge to/from the cluster is replaced with an edge to/from a node in the cluster which is tagged with toCluster/fromCluster. When rendering this edge the intersection between the edge and the border of the cluster is calculated making the edge start/stop there. In practice this renders like an edge to/from the cluster.

In the diagram above the root diagram would be rendered with C1 whereas C2 would be rendered recursively.

Expand Down
2 changes: 1 addition & 1 deletion packages/mermaid/src/dagre-wrapper/intersect/index.js
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/*
* Borrowed with love from from dagre-d3. Many thanks to cpettitt!
* Borrowed with love from dagre-d3. Many thanks to cpettitt!
*/

import node from './intersect-node.js';
Expand Down
2 changes: 1 addition & 1 deletion packages/mermaid/src/diagrams/block/blockDB.ts
Original file line number Diff line number Diff line change
Expand Up @@ -262,7 +262,7 @@ const getBlocksFlat = () => {
return [...Object.values(blockDatabase)];
};
/**
* Returns the the hierarchy of blocks
* Returns the hierarchy of blocks
* @returns
*/
const getBlocks = () => {
Expand Down
12 changes: 7 additions & 5 deletions packages/mermaid/src/diagrams/common/common.ts
Original file line number Diff line number Diff line change
Expand Up @@ -337,18 +337,20 @@ export const renderKatex = async (text: string, config: MermaidConfig): Promise<
return text;
}

if (!isMathMLSupported() && !config.legacyMathML) {
if (!(isMathMLSupported() || config.legacyMathML || config.forceLegacyMathML)) {
return text.replace(katexRegex, 'MathML is unsupported in this environment.');
}

const { default: katex } = await import('katex');
const outputMode =
config.forceLegacyMathML || (!isMathMLSupported() && config.legacyMathML)
? 'htmlAndMathml'
: 'mathml';
return text
.split(lineBreakRegex)
.map((line) =>
hasKatex(line)
? `<div style="display: flex; align-items: center; justify-content: center; white-space: nowrap;">
${line}
</div>`
? `<div style="display: flex; align-items: center; justify-content: center; white-space: nowrap;">${line}</div>`
: `<div>${line}</div>`
)
.join('')
Expand All @@ -357,7 +359,7 @@ export const renderKatex = async (text: string, config: MermaidConfig): Promise<
.renderToString(c, {
throwOnError: true,
displayMode: true,
output: isMathMLSupported() ? 'mathml' : 'htmlAndMathml',
output: outputMode,
})
.replace(/\n/g, ' ')
.replace(/<annotation.*<\/annotation>/g, '')
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -141,7 +141,7 @@ describe('when parsing flowcharts', function () {
expect(edges[3].type).toBe('arrow_point');
expect(edges[3].text).toBe('');
});
it('should handle chaining and multiple nodes in in link statement FVC ', function () {
it('should handle chaining and multiple nodes in link statement FVC ', function () {
const res = flow.parser.parse(`
graph TD
A --> B & B2 & C --> D2;
Expand Down Expand Up @@ -181,7 +181,7 @@ describe('when parsing flowcharts', function () {
expect(edges[5].type).toBe('arrow_point');
expect(edges[5].text).toBe('');
});
it('should handle chaining and multiple nodes in in link statement with extra info in statements', function () {
it('should handle chaining and multiple nodes in link statement with extra info in statements', function () {
const res = flow.parser.parse(`
graph TD
A[ h ] -- hello --> B[" test "]:::exClass & C --> D;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -64,7 +64,7 @@ describe('parsing a flow chart', function () {
expect(edges[0].end).toBe('monograph');
});

describe('special characters should be be handled.', function () {
describe('special characters should be handled.', function () {
const charTest = function (char, result) {
const res = flow.parser.parse('graph TD;A(' + char + ')-->B;');

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
* (c) 2014-2015 Knut Sveidqvist
* MIT license.
*
* Based on js sequence diagrams jison grammr
* Based on js sequence diagrams jison grammar
* https://bramp.github.io/js-sequence-diagrams/
* (c) 2012-2013 Andrew Brampton (bramp.net)
* Simplified BSD license.
Expand Down Expand Up @@ -138,8 +138,8 @@ statement
| autonumber NUM 'NEWLINE' { $$ = {type:'sequenceIndex',sequenceIndex: Number($2), sequenceIndexStep:1, sequenceVisible:true, signalType:yy.LINETYPE.AUTONUMBER};}
| autonumber off 'NEWLINE' { $$ = {type:'sequenceIndex', sequenceVisible:false, signalType:yy.LINETYPE.AUTONUMBER};}
| autonumber 'NEWLINE' {$$ = {type:'sequenceIndex', sequenceVisible:true, signalType:yy.LINETYPE.AUTONUMBER}; }
| 'activate' actor 'NEWLINE' {$$={type: 'activeStart', signalType: yy.LINETYPE.ACTIVE_START, actor: $2};}
| 'deactivate' actor 'NEWLINE' {$$={type: 'activeEnd', signalType: yy.LINETYPE.ACTIVE_END, actor: $2};}
| 'activate' actor 'NEWLINE' {$$={type: 'activeStart', signalType: yy.LINETYPE.ACTIVE_START, actor: $2.actor};}
| 'deactivate' actor 'NEWLINE' {$$={type: 'activeEnd', signalType: yy.LINETYPE.ACTIVE_END, actor: $2.actor};}
| note_statement 'NEWLINE'
| links_statement 'NEWLINE'
| link_statement 'NEWLINE'
Expand Down Expand Up @@ -288,11 +288,11 @@ placement
signal
: actor signaltype '+' actor text2
{ $$ = [$1,$4,{type: 'addMessage', from:$1.actor, to:$4.actor, signalType:$2, msg:$5, activate: true},
{type: 'activeStart', signalType: yy.LINETYPE.ACTIVE_START, actor: $4}
{type: 'activeStart', signalType: yy.LINETYPE.ACTIVE_START, actor: $4.actor}
]}
| actor signaltype '-' actor text2
{ $$ = [$1,$4,{type: 'addMessage', from:$1.actor, to:$4.actor, signalType:$2, msg:$5},
{type: 'activeEnd', signalType: yy.LINETYPE.ACTIVE_END, actor: $1}
{type: 'activeEnd', signalType: yy.LINETYPE.ACTIVE_END, actor: $1.actor}
]}
| actor signaltype actor text2
{ $$ = [$1,$3,{type: 'addMessage', from:$1.actor, to:$3.actor, signalType:$2, msg:$4}]}
Expand Down
11 changes: 4 additions & 7 deletions packages/mermaid/src/diagrams/sequence/sequenceDb.ts
Original file line number Diff line number Diff line change
Expand Up @@ -115,17 +115,16 @@ const activationCount = (part: string) => {
if (!part) {
return 0;
}

for (i = 0; i < state.records.messages.length; i++) {
if (
state.records.messages[i].type === LINETYPE.ACTIVE_START &&
state.records.messages[i].from?.actor === part
state.records.messages[i].from === part
) {
count++;
}
if (
state.records.messages[i].type === LINETYPE.ACTIVE_END &&
state.records.messages[i].from?.actor === part
state.records.messages[i].from === part
) {
count--;
}
Expand Down Expand Up @@ -156,12 +155,10 @@ export const addSignal = function (
activate: boolean = false
) {
if (messageType === LINETYPE.ACTIVE_END) {
const cnt = activationCount(idFrom?.actor || '');
const cnt = activationCount(idFrom || '');
if (cnt < 1) {
// Bail out as there is an activation signal from an inactive participant
const error = new Error(
'Trying to inactivate an inactive participant (' + idFrom?.actor + ')'
);
const error = new Error('Trying to inactivate an inactive participant (' + idFrom + ')');

// @ts-ignore: we are passing hash param to the error object, however we should define our own custom error class to make it type safe
error.hash = {
Expand Down
16 changes: 8 additions & 8 deletions packages/mermaid/src/diagrams/sequence/sequenceDiagram.spec.js
Original file line number Diff line number Diff line change
Expand Up @@ -534,10 +534,10 @@ deactivate Bob`;
expect(messages.length).toBe(4);
expect(messages[0].type).toBe(diagram.db.LINETYPE.DOTTED);
expect(messages[1].type).toBe(diagram.db.LINETYPE.ACTIVE_START);
expect(messages[1].from.actor).toBe('Bob');
expect(messages[1].from).toBe('Bob');
expect(messages[2].type).toBe(diagram.db.LINETYPE.DOTTED);
expect(messages[3].type).toBe(diagram.db.LINETYPE.ACTIVE_END);
expect(messages[3].from.actor).toBe('Bob');
expect(messages[3].from).toBe('Bob');
});
it('should handle actor one line notation activation', async () => {
const str = `
Expand All @@ -556,10 +556,10 @@ deactivate Bob`;
expect(messages[0].type).toBe(diagram.db.LINETYPE.DOTTED);
expect(messages[0].activate).toBeTruthy();
expect(messages[1].type).toBe(diagram.db.LINETYPE.ACTIVE_START);
expect(messages[1].from.actor).toBe('Bob');
expect(messages[1].from).toBe('Bob');
expect(messages[2].type).toBe(diagram.db.LINETYPE.DOTTED);
expect(messages[3].type).toBe(diagram.db.LINETYPE.ACTIVE_END);
expect(messages[3].from.actor).toBe('Bob');
expect(messages[3].from).toBe('Bob');
});
it('should handle stacked activations', async () => {
const str = `
Expand All @@ -579,14 +579,14 @@ deactivate Bob`;
expect(messages.length).toBe(8);
expect(messages[0].type).toBe(diagram.db.LINETYPE.DOTTED);
expect(messages[1].type).toBe(diagram.db.LINETYPE.ACTIVE_START);
expect(messages[1].from.actor).toBe('Bob');
expect(messages[1].from).toBe('Bob');
expect(messages[2].type).toBe(diagram.db.LINETYPE.DOTTED);
expect(messages[3].type).toBe(diagram.db.LINETYPE.ACTIVE_START);
expect(messages[3].from.actor).toBe('Carol');
expect(messages[3].from).toBe('Carol');
expect(messages[5].type).toBe(diagram.db.LINETYPE.ACTIVE_END);
expect(messages[5].from.actor).toBe('Bob');
expect(messages[5].from).toBe('Bob');
expect(messages[7].type).toBe(diagram.db.LINETYPE.ACTIVE_END);
expect(messages[7].from.actor).toBe('Carol');
expect(messages[7].from).toBe('Carol');
});
it('should handle fail parsing when activating an inactive participant', async () => {
const str = `
Expand Down
18 changes: 9 additions & 9 deletions packages/mermaid/src/diagrams/sequence/sequenceRenderer.ts
Original file line number Diff line number Diff line change
Expand Up @@ -144,15 +144,15 @@ export const bounds = {
this.updateBounds(_startx, _starty, _stopx, _stopy);
},
newActivation: function (message, diagram, actors) {
const actorRect = actors[message.from.actor];
const stackedSize = actorActivations(message.from.actor).length || 0;
const actorRect = actors[message.from];
const stackedSize = actorActivations(message.from).length || 0;
const x = actorRect.x + actorRect.width / 2 + ((stackedSize - 1) * conf.activationWidth) / 2;
this.activations.push({
startx: x,
starty: this.verticalPos + 2,
stopx: x + conf.activationWidth,
stopy: undefined,
actor: message.from.actor,
actor: message.from,
anchored: svgDraw.anchorElement(diagram),
});
},
Expand All @@ -162,7 +162,7 @@ export const bounds = {
.map(function (activation) {
return activation.actor;
})
.lastIndexOf(message.from.actor);
.lastIndexOf(message.from);
return this.activations.splice(lastActorActivationIdx, 1)[0];
},
createLoop: function (title = { message: undefined, wrap: false, width: undefined }, fill) {
Expand Down Expand Up @@ -836,7 +836,7 @@ export const draw = async function (_text: string, id: string, _version: string,
activationData,
verticalPos,
conf,
actorActivations(msg.from.actor).length
actorActivations(msg.from).length
);

bounds.insert(activationData.startx, verticalPos - 10, activationData.stopx, verticalPos);
Expand Down Expand Up @@ -1545,14 +1545,14 @@ const calculateLoopBounds = async function (messages, actors, _maxWidthPerActor,
break;
case diagObj.db.LINETYPE.ACTIVE_START:
{
const actorRect = actors[msg.from ? msg.from.actor : msg.to.actor];
const stackedSize = actorActivations(msg.from ? msg.from.actor : msg.to.actor).length;
const actorRect = actors[msg.from ? msg.from : msg.to.actor];
const stackedSize = actorActivations(msg.from ? msg.from : msg.to.actor).length;
const x =
actorRect.x + actorRect.width / 2 + ((stackedSize - 1) * conf.activationWidth) / 2;
const toAdd = {
startx: x,
stopx: x + conf.activationWidth,
actor: msg.from.actor,
actor: msg.from,
enabled: true,
};
bounds.activations.push(toAdd);
Expand All @@ -1562,7 +1562,7 @@ const calculateLoopBounds = async function (messages, actors, _maxWidthPerActor,
{
const lastActorActivationIdx = bounds.activations
.map((a) => a.actor)
.lastIndexOf(msg.from.actor);
.lastIndexOf(msg.from);
delete bounds.activations.splice(lastActorActivationIdx, 1)[0];
}
break;
Expand Down
4 changes: 2 additions & 2 deletions packages/mermaid/src/diagrams/sequence/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -20,8 +20,8 @@ export interface Actor {
}

export interface Message {
from?: { actor: string };
to?: { actor: string };
from?: string;
to?: string;
message:
| string
| {
Expand Down
2 changes: 1 addition & 1 deletion packages/mermaid/src/diagrams/state/stateDb.js
Original file line number Diff line number Diff line change
Expand Up @@ -145,7 +145,7 @@ const getRootDocV2 = () => {
* Ex: the section within a fork has its own statements, and incoming and outgoing statements
* refer to the fork as a whole (document).
* See the parser grammar: the definition of a document is a document then a 'line', where a line can be a statement.
* This will push the statement into the the list of statements for the current document.
* This will push the statement into the list of statements for the current document.
*
* @param _doc
*/
Expand Down
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
10 changes: 10 additions & 0 deletions packages/mermaid/src/docs/config/math.md
Original file line number Diff line number Diff line change
Expand Up @@ -60,3 +60,13 @@ Example with legacy mode enabled (the latest version of KaTeX's stylesheet can b
</body>
</html>
```

## Handling Rendering Differences

Due to differences between default fonts across operating systems and browser's MathML implementations, inconsistent results can be seen across platforms. If having consistent results are important, or the most optimal rendered results are desired, `forceLegacyMathML` can be enabled in the config.

This option will always use KaTeX's stylesheet instead of only when MathML is not supported (as with `legacyMathML`). Note that only `forceLegacyMathML` needs to be set.

If including KaTeX's stylesheet is not a concern, enabling this option is recommended to avoid scenarios where no MathML implementation within a browser provides the desired output (as seen below).

![Image showing differences between Browsers](img/mathMLDifferences.png)

0 comments on commit 89f919f

Please sign in to comment.