Compare commits

..

38 Commits

Author SHA1 Message Date
Knut Sveidqvist
48e5d743b3 Merge pull request #4445 from mermaid-js/4438-revering-to-non-esm-use-of-dayjs
#4438 Reverted to the changes from #4285
2023-06-01 13:03:14 +02:00
Knut Sveidqvist
98e75959cc #4438 Reverted to the changes from #4285 2023-06-01 12:53:21 +02:00
Sidharth Vinod
0cec854f3b Fix download 2023-05-31 19:33:30 +05:30
Sidharth Vinod
abcae14fa7 Fix compile error in docs. 2023-05-31 19:10:42 +05:30
Sidharth Vinod
641098e602 Fix Contributor link in homepage 2023-05-31 19:06:36 +05:30
Sidharth Vinod
ca5d78098e Merge pull request #4426 from aloisklink/chore/fix-broken-lockfile
Merge PR #4425 to `master` to fix uploading v10.2.0 docs to `mermaid.js.org` website
2023-05-25 07:13:58 +05:30
Alois Klink
6093383d45 build(deps): fix broken pnpm-lock.yaml file
Looks like a bad merge conflict resolution broke this file,
and for some reason, the `packages/mermaid/src/vitepress` bit got
removed when releasing v10.2.0-rc.4.

Fixes: bd1343648e
Fixes: 9c12c42a26
2023-05-24 22:19:49 +01:00
Knut Sveidqvist
bd1343648e Merge branch 'master' into develop 2023-05-24 19:20:47 +02:00
Knut Sveidqvist
3517314390 Merge branch 'release/10.2.0' 2023-05-24 19:19:41 +02:00
Knut Sveidqvist
8d43b87200 Mermaid version 10.2.0 2023-05-24 19:03:22 +02:00
Knut Sveidqvist
9c12c42a26 Mermaid Version 10.2.0-rc.4 2023-05-24 18:18:54 +02:00
Knut Sveidqvist
5bfe32524d Label background fix 2023-05-24 12:53:28 +02:00
Knut Sveidqvist
bd616e0ef5 Test commit 2023-05-24 12:27:30 +02:00
Knut Sveidqvist
9fb25310e8 Fix for regression error in sequenceDiagrams 2023-05-24 11:27:17 +02:00
renovate[bot]
ac23787084 Update all minor dependencies 2023-05-22 07:53:27 +00:00
renovate[bot]
ad61f4c6b1 Update all patch dependencies 2023-05-22 06:06:37 +00:00
renovate[bot]
b1590c2211 Update all minor dependencies 2023-05-17 13:32:09 +00:00
renovate[bot]
9eeeb97e15 Update all patch dependencies 2023-05-17 09:17:43 +00:00
Sidharth Vinod
0ef115f69a Fix vitepress build 2023-05-17 11:28:17 +05:30
Justin Greywolf
78efac2c51 Fix visibility issue for fields 2023-05-16 06:13:37 -07:00
Justin Greywolf
58ec2686da Merge branch 'release/10.2.0' of https://github.com/mermaid-js/mermaid into release/10.2.0 2023-05-16 04:12:27 -07:00
Justin Greywolf
3a5c4a149f fix parsing issue with class diagrams 2023-05-16 04:12:03 -07:00
Knut Sveidqvist
132ce2fb4b Merge branch 'develop' into release/10.2.0 2023-05-15 09:50:02 +02:00
Knut Sveidqvist
fa3e800802 Merge remote-tracking branch 'origin/release/10.2.0' into release/10.2.0 2023-05-15 08:52:13 +02:00
Knut Sveidqvist
f616663f2f Merge branch 'develop' into release/10.2.0 2023-05-15 08:51:47 +02:00
Sidharth Vinod
6eef09661d Merge branch 'develop' into release/10.2.0
* develop:
  Fix blog linting
2023-05-09 10:25:27 +05:30
Sidharth Vinod
93370a8e11 Merge branch 'develop' into release/10.2.0
* develop:
  Updated url
  Updated url
  Updated url
  Updated url
  add blog post to blog page
  add the latest blog post
2023-05-09 10:24:38 +05:30
Sidharth Vinod
fbd35ae95a fix lint command 2023-05-09 10:24:05 +05:30
Sidharth Vinod
75e73a4f03 Bump version 2023-05-09 10:20:33 +05:30
Sidharth Vinod
17c798a1b3 Merge branch 'develop' into release/10.2.0
* develop: (49 commits)
  Debug fetch-contributors
  Fix lockfile
  Revert "Replace esno & ts-node with tsx"
  Fix lockfile
  Fix build
  Update pnpm-lock
  Replace esno & ts-node with tsx
  chore(deps): update all minor dependencies
  chore(deps): update all patch dependencies
  Fix missing `await` in usage document
  Add integrations
  test: fix classDiagramGrammer unit test
  restore path calculation for grammar test
  Allow overlapping notes
  remove spellcheck warnings
  Fix path in test
  fix import issue
  requested update
  Reject ridiculous years in Gantt charts.
  Remove unnecessary dependencies
  ...
2023-05-09 10:13:15 +05:30
Knut Sveidqvist
29c8f8c867 Merge pull request #4350 from mermaid-js/sidv/removeSimpleMarkdown
remove SimpleMarkdown
2023-05-08 09:16:28 +02:00
Sidharth Vinod
91f1ef9c42 Back to JS with jsdoc types 2023-04-26 11:00:35 +05:30
Sidharth Vinod
eba3a7bdcc Add unsupported text 2023-04-26 10:55:37 +05:30
Sidharth Vinod
5bbce45c56 Reduce changes in test 2023-04-26 10:51:54 +05:30
Sidharth Vinod
395a794758 Fix deps 2023-04-26 10:37:03 +05:30
Sidharth Vinod
1f2af83a0c Fix lockfile 2023-04-26 10:35:24 +05:30
Sidharth Vinod
4d3e5e42e1 Use mdast-util-from-markdown instead of simple-markdown 2023-04-26 10:30:13 +05:30
Sidharth Vinod
9b912c4a59 handleMarkdown JS -> TS 2023-04-26 10:11:19 +05:30
29 changed files with 788 additions and 904 deletions

View File

@@ -36,7 +36,7 @@ jobs:
restore-keys: cache-lychee- restore-keys: cache-lychee-
- name: Link Checker - name: Link Checker
uses: lycheeverse/lychee-action@v1.7.0 uses: lycheeverse/lychee-action@v1.8.0
with: with:
args: >- args: >-
--verbose --verbose

View File

@@ -42,7 +42,7 @@ jobs:
if ! pnpm run lint; then if ! pnpm run lint; then
# print a nice error message on lint failure # print a nice error message on lint failure
ERROR_MESSAGE='Running `pnpm run lint` failed.' ERROR_MESSAGE='Running `pnpm run lint` failed.'
ERROR_MESSAGE+=' Running `pnpm run lint:fix` may fix this issue. ' ERROR_MESSAGE+=' Running `pnpm -w run lint:fix` may fix this issue. '
ERROR_MESSAGE+=" If this error doesn't occur on your local machine," ERROR_MESSAGE+=" If this error doesn't occur on your local machine,"
ERROR_MESSAGE+=' make sure your packages are up-to-date by running `pnpm install`.' ERROR_MESSAGE+=' make sure your packages are up-to-date by running `pnpm install`.'
ERROR_MESSAGE+=' You may also need to delete your prettier cache by running' ERROR_MESSAGE+=' You may also need to delete your prettier cache by running'

View File

@@ -42,368 +42,86 @@
</style> </style>
</head> </head>
<body> <body>
<pre class="mermaid2" style="width: 50%"> <pre class="mermaid" style="width: 50%">
%%{init: {"flowchart": {"htmlLabels": true}} }%%
flowchart LR flowchart LR
subgraph one b("`The dog in **the** hog.(1).. a a a a *very long text* about it
direction LR Word!
A[myClass1] --> B[default]
subgraph two
direction BT
C[myClass2] --> D[default]
end
end
Another line with many, many words. Another line with many, many words. Another line with many, many words. Another line with many, many words. Another line with many, many words. Another line with many, many words. Another line with many, many words. Another line with many, many words.`") --apa--> c
</pre
>
<pre class="mermaid" style="width: 50%">
classDiagram-v2
classA -- classB : Inheritance
classA -- classC : link
classC -- classD : link
classB -- classD
</pre> </pre>
<pre class="mermaid2" style="width: 50%"> <pre class="mermaid" style="width: 50%">
sequenceDiagram
Alice->>Bob: Extremely utterly long line of longness which had previously overflown the actor box as it is much longer than what it should be
loop Loopy
Bob->>Alice: Pasten
end
</pre>
<pre class="mermaid" style="width: 50%">
%%{init: {"flowchart": {"htmlLabels": false}} }%%
flowchart LR flowchart LR
classDef aPID stroke:#4e4403,fill:#fdde29,color:#4e4403,rx:5px,ry:5px; b("`The dog in **the** hog.(1)
classDef crm stroke:#333333,fill:#DCDCDC,color:#333333,rx:5px,ry:5px; NL`") --"`1o **bold**`"--> c[new strings svg labels]
classDef type stroke:#502604,fill:#FAB565,color:#502604,rx:20px,ry:20px;;
O0("Joe")
class O0 aPID;
O1("Person")
class O1 crm;
O0 -- has type -->O1["Person"]
O2("aat:300411314")
class O2 type;
click O2 function "Sorry the newline html tags are not being processed correctly<br/> So all of this appears on the <br/> same line."
O0 -- has type -->O2["Bug"]
click O0 function "Lots of great info about Joe<br>Lots of great info about Joe<br>burt<br>fred";
</pre> </pre>
<pre class="mermaid2" style="width: 50%"> <pre class="mermaid" style="width: 50%">
flowchart TD %%{init: {"flowchart": {"htmlLabels": true}} }%%
subgraph test
direction TB
subgraph test2
direction LR
F --> D
end
subgraph test3
direction TB
G --> H
end
end
</pre>
<pre class="mermaid2" style="width: 50%">
flowchart TD
release-branch[Create Release Branch]:::relClass
develop-branch[Update Develop Branch]:::relClass
github-release-draft[GitHub Release Draft]:::relClass
trigger-pipeline[Trigger Jenkins pipeline]:::fixClass
github-release[GitHub Release]:::postClass
build-ready --> release-branch
build-ready --> develop-branch
release-branch --> jenkins-release-build
jenkins-release-build --> github-release-draft
jenkins-release-build --> install-release
install-release --> verify-release
jenkins-release-build --> announce
github-release-draft --> github-release
verify-release --> verify-check
verify-check -- Yes --> github-release
verify-check -- No --> release-fix
release-fix --> release-branch-pr
verify-check -- No --> delete-artifacts
release-branch-pr --> trigger-pipeline
delete-artifacts --> trigger-pipeline
trigger-pipeline --> jenkins-release-build
</pre>
<pre class="mermaid2" style="width: 50%">
flowchart LR flowchart LR
a["<strong>Haiya</strong>"]===>b b("`The dog in **the** hog.(1)
NL`") --"`1o **bold**`"--> c[new strings html labels]
</pre> </pre>
<pre class="mermaid2" style="width: 50%"> <pre class="mermaid" style="width: 50%">
flowchart TD %%{init: {"flowchart": {"htmlLabels": true}} }%%
A --> B flowchart LR
A --> C b("The dog in the hog.(1)\nNL") --"1o bold"--> c[old strings svg labels]
B --> C
</pre> </pre>
<pre class="mermaid2" style="width: 50%"> <script type="module">
flowchart TD // import mindmap from '../../packages/mermaid-mindmap/src/detector';
A([stadium shape test]) // import example from '../../packages/mermaid-example-diagram/src/mermaid-example-diagram.core.mjs';
A -->|Get money| B([Go shopping]) import mermaid from './mermaid.esm.mjs';
B --> C([Let me think...<br />Do I want something for work,<br />something to spend every free second with,<br />or something to get around?]) // await mermaid.registerExternalDiagrams([example]);
C -->|One| D([Laptop])
C -->|Two| E([iPhone])
C -->|Three| F([Car<br/>wroom wroom])
click A "index.html#link-clicked" "link test"
click B testClick "click test"
classDef someclass fill:#f96;
class A someclass;
class C someclass;
</pre>
<pre class="mermaid2" style="width: 50%">
sequenceDiagram
title: My Sequence Diagram Title
accTitle: My Acc Sequence Diagram
accDescr: My Sequence Diagram Description
Alice->>John: Hello John, how are you?
John-->>Alice: Great!
Alice-)John: See you later!
</pre>
<pre class="mermaid2" style="width: 50%">
graph TD
A -->|000| B
B -->|111| C
linkStyle 1 stroke:#ff3,stroke-width:4px,color:red;
</pre>
<pre class="mermaid2" style="width: 100%">
journey
accTitle: My User Journey Diagram
accDescr: My User Journey Diagram Description
title My working day
section Go to work
Make tea: 5: Me
Go upstairs: 3: Me
Do work: 1: Me, Cat
section Go home
Go downstairs: 5: Me
Sit down: 5: Me
</pre>
<pre class="mermaid2" style="width: 100%">
info
</pre>
<pre class="mermaid2" style="width: 100%">
requirementDiagram
accTitle: My req Diagram
accDescr: My req Diagram Description
requirement test_req {
id: 1
text: the test text.
risk: high
verifymethod: test
}
functionalRequirement test_req2 {
id: 1.1
text: the second test text.
risk: low
verifymethod: inspection
}
performanceRequirement test_req3 {
id: 1.2
text: the third test text.
risk: medium
verifymethod: demonstration
}
element test_entity {
type: simulation
}
element test_entity2 {
type: word doc
docRef: reqs/test_entity
}
test_entity - satisfies -> test_req2
test_req - traces -> test_req2
test_req - contains -> test_req3
test_req <- copies - test_entity2
</pre>
<pre class="mermaid2" style="width: 100%">
gantt
dateFormat YYYY-MM-DD
title Adding GANTT diagram functionality to mermaid
excludes weekends
%% (`excludes` accepts specific dates in YYYY-MM-DD format, days of the week ("sunday") or "weekends", but not the word "weekdays".)
section A section
Completed task :done, des1, 2014-01-06,2014-01-08
Active task :active, des2, 2014-01-09, 3d
Future task : des3, after des2, 5d
Future task2 : des4, after des3, 5d
section Critical tasks
Completed task in the critical line :crit, done, 2014-01-06,24h
Implement parser and jison :crit, done, after des1, 2d
Create tests for parser :crit, active, 3d
Future task in critical line :crit, 5d
Create tests for renderer :2d
Add to mermaid :1d
Functionality added :milestone, 2014-01-25, 0d
section Documentation
Describe gantt syntax :active, a1, after des1, 3d
Add gantt diagram to demo page :after a1 , 20h
Add another diagram to demo page :doc1, after a1 , 48h
section Last section
Describe gantt syntax :after doc1, 3d
Add gantt diagram to demo page :20h
Add another diagram to demo page :48h
</pre>
<pre class="mermaid2" style="width: 100%">
stateDiagram
state Active {
Idle
}
Inactive --> Idle: ACT
Active --> Active: LOG
</pre>
<pre class="mermaid2" style="width: 100%">
flowchart TB
accTitle: My flowchart
accDescr: My flowchart Description
subgraph One
a1-->a2-->a3
end
</pre>
<pre class="mermaid2" style="width: 100%">
sequenceDiagram
A ->> B: 1
rect rgb(204, 0, 102)
break yes
rect rgb(0, 204, 204)
C ->> C: 0
end
end
end
B ->> A: Return
</pre>
<pre class="mermaid2" style="width: 100%">
classDiagram
accTitle: My class diagram
accDescr: My class diagram Description
Class01 <|-- AveryLongClass : Cool
Class09 --> C2 : Where am i?
Class09 --* C3
Class09 --|> Class07
Class07 : equals()
Class07 : Object[] elementData
Class01 : size()
Class01 : int chimp
Class01 : int gorilla
class Class10 {
int id
size()
}
</pre>
<pre class="mermaid2" style="width: 100%">
%%{init: {'config': {'wrap': true }}}%%
sequenceDiagram
participant A as Extremely utterly long line of longness which had previously overflown the actor box as it is much longer than what it should be
A->>Bob: Hola
Bob-->A: Pasten !
</pre>
<pre class="mermaid2" style="width: 100%">
gitGraph
commit id: "ZERO"
branch develop
commit id:"A"
checkout main
commit id:"ONE"
checkout develop
commit id:"B"
branch featureA
commit id:"FIX"
commit id: "FIX-2"
checkout main
commit id:"TWO"
cherry-pick id:"A"
commit id:"THREE"
cherry-pick id:"FIX"
checkout develop
commit id:"C"
merge featureA
</pre>
<pre class="mermaid2" style="width: 100%">
flowchart TD
A[Christmas] -->|Get money| B(Go shopping)
B --> C{Let me think}
C -->|One| D[Laptop]
C -->|Two| E[iPhone]
C -->|Three| F[fa:fa-car Car]
</pre>
<pre class="mermaid2" style="width: 100%">
classDiagram
Animal "1" <|-- Duck
Animal <|-- Fish
Animal <--o Zebra
Animal : +int age
Animal : +String gender
Animal: +isMammal()
Animal: +mate()
class Duck{
+String beakColor
+swim()
+quack()
}
class Fish{
-int sizeInFeet
-canEat()
}
class Zebra{
+bool is_wild
+run()
}
</pre>
<pre class="mermaid2" style="width: 100%">
erDiagram
CAR ||--o{ NAMED-DRIVER : allows
CAR {
string registrationNumber
string make
string model
}
PERSON ||--o{ NAMED-DRIVER : is
PERSON {
string firstName
string lastName
int age
}
</pre>
<!-- <script src="./mermaid.js"></script> -->
<script src="./mermaid.js"></script>
<script>
mermaid.parseError = function (err, hash) { mermaid.parseError = function (err, hash) {
// console.error('Mermaid error: ', err); // console.error('Mermaid error: ', err);
}; };
mermaid.initialize({ mermaid.initialize({
maxTextSize: 900000, // theme: 'forest',
startOnLoad: true, startOnLoad: true,
securityLevel: 'loose',
logLevel: 0, logLevel: 0,
fontFamily: 'courier',
flowchart: { flowchart: {
// curve: 'curveLinear', // defaultRenderer: 'elk',
useMaxWidth: true, useMaxWidth: false,
htmlLabels: false, // htmlLabels: false,
fontFamily: 'courier', htmlLabels: true,
}, },
lazyLoadedDiagrams: ['./mermaid-mindmap-detector.js'], // htmlLabels: false,
gantt: {
useMaxWidth: false,
},
sequence: {
wrap: true,
},
useMaxWidth: false,
}); });
function callback() { function callback() {
alert('It worked'); alert('It worked');
} }
function clickByFlow(elemName) {
const div = document.createElement('div');
div.className = 'created-by-click';
div.style = 'padding: 20px; background: green; color: white;';
div.innerText = 'Clicked By Flow';
document.getElementsByTagName('body')[0].appendChild(div);
}
mermaid.parseError = function (err, hash) { mermaid.parseError = function (err, hash) {
console.error('In parse error:'); console.error('In parse error:');
console.error(err); console.error(err);
}; };
// mermaid.test1('first_slow', 1200).then((r) => console.info(r));
// mermaid.test1('second_fast', 200).then((r) => console.info(r));
// mermaid.test1('third_fast', 200).then((r) => console.info(r));
// mermaid.test1('forth_slow', 1200).then((r) => console.info(r));
</script> </script>
</body> </body>
</html> </html>

View File

@@ -96,7 +96,7 @@ mermaid.initialize(config);
#### Defined in #### Defined in
[mermaidAPI.ts:673](https://github.com/mermaid-js/mermaid/blob/master/packages/mermaid/src/mermaidAPI.ts#L673) [mermaidAPI.ts:667](https://github.com/mermaid-js/mermaid/blob/master/packages/mermaid/src/mermaidAPI.ts#L667)
## Functions ## Functions
@@ -127,7 +127,7 @@ Return the last node appended
#### Defined in #### Defined in
[mermaidAPI.ts:312](https://github.com/mermaid-js/mermaid/blob/master/packages/mermaid/src/mermaidAPI.ts#L312) [mermaidAPI.ts:306](https://github.com/mermaid-js/mermaid/blob/master/packages/mermaid/src/mermaidAPI.ts#L306)
--- ---
@@ -153,7 +153,7 @@ the cleaned up svgCode
#### Defined in #### Defined in
[mermaidAPI.ts:263](https://github.com/mermaid-js/mermaid/blob/master/packages/mermaid/src/mermaidAPI.ts#L263) [mermaidAPI.ts:257](https://github.com/mermaid-js/mermaid/blob/master/packages/mermaid/src/mermaidAPI.ts#L257)
--- ---
@@ -179,7 +179,7 @@ the string with all the user styles
#### Defined in #### Defined in
[mermaidAPI.ts:192](https://github.com/mermaid-js/mermaid/blob/master/packages/mermaid/src/mermaidAPI.ts#L192) [mermaidAPI.ts:186](https://github.com/mermaid-js/mermaid/blob/master/packages/mermaid/src/mermaidAPI.ts#L186)
--- ---
@@ -202,7 +202,7 @@ the string with all the user styles
#### Defined in #### Defined in
[mermaidAPI.ts:240](https://github.com/mermaid-js/mermaid/blob/master/packages/mermaid/src/mermaidAPI.ts#L240) [mermaidAPI.ts:234](https://github.com/mermaid-js/mermaid/blob/master/packages/mermaid/src/mermaidAPI.ts#L234)
--- ---
@@ -229,7 +229,7 @@ with an enclosing block that has each of the cssClasses followed by !important;
#### Defined in #### Defined in
[mermaidAPI.ts:176](https://github.com/mermaid-js/mermaid/blob/master/packages/mermaid/src/mermaidAPI.ts#L176) [mermaidAPI.ts:170](https://github.com/mermaid-js/mermaid/blob/master/packages/mermaid/src/mermaidAPI.ts#L170)
--- ---
@@ -295,7 +295,7 @@ Put the svgCode into an iFrame. Return the iFrame code
#### Defined in #### Defined in
[mermaidAPI.ts:291](https://github.com/mermaid-js/mermaid/blob/master/packages/mermaid/src/mermaidAPI.ts#L291) [mermaidAPI.ts:285](https://github.com/mermaid-js/mermaid/blob/master/packages/mermaid/src/mermaidAPI.ts#L285)
--- ---
@@ -320,4 +320,4 @@ Remove any existing elements from the given document
#### Defined in #### Defined in
[mermaidAPI.ts:362](https://github.com/mermaid-js/mermaid/blob/master/packages/mermaid/src/mermaidAPI.ts#L362) [mermaidAPI.ts:356](https://github.com/mermaid-js/mermaid/blob/master/packages/mermaid/src/mermaidAPI.ts#L356)

View File

@@ -54,7 +54,45 @@ flowchart LR
id1[This is the text in the box] id1[This is the text in the box]
``` ```
## Graph #### Unicode text
Use `"` to enclose the unicode text.
```mermaid-example
flowchart LR
id["This ❤ Unicode"]
```
```mermaid
flowchart LR
id["This ❤ Unicode"]
```
#### Markdown formatting
Use double quotes and backticks "\` text \`" to enclose the markdown text.
```mermaid-example
%%{init: {"flowchart": {"htmlLabels": false}} }%%
flowchart LR
markdown["`This **is** _Markdown_`"]
newLines["`Line1
Line 2
Line 3`"]
markdown --> newLines
```
```mermaid
%%{init: {"flowchart": {"htmlLabels": false}} }%%
flowchart LR
markdown["`This **is** _Markdown_`"]
newLines["`Line1
Line 2
Line 3`"]
markdown --> newLines
```
### Direction
This statement declares the direction of the Flowchart. This statement declares the direction of the Flowchart.
@@ -82,15 +120,13 @@ flowchart LR
Start --> Stop Start --> Stop
``` ```
## Flowchart Orientation
Possible FlowChart orientations are: Possible FlowChart orientations are:
- TB - top to bottom - TB - Top to bottom
- TD - top-down/ same as top to bottom - TD - Top-down/ same as top to bottom
- BT - bottom to top - BT - Bottom to top
- RL - right to left - RL - Right to left
- LR - left to right - LR - Left to right
## Node shapes ## Node shapes

View File

@@ -46,9 +46,6 @@ quadrantChart
## Syntax ## Syntax
> **Note**
> In place of `<text>` you can use text like `this is a sample text` or inside **double quotes** like `"This type of text may contain unicode like ❤"`.
> **Note** > **Note**
> If there is no points available in the chart both **axis** text and **quadrant** will be rendered in the center of the respective quadrant. > If there is no points available in the chart both **axis** text and **quadrant** will be rendered in the center of the respective quadrant.
> If there are points **x-axis** labels will rendered from left of the respective quadrant also they will be displayed in bottom of the chart, and **y-axis** lables will be rendered in bottom of the respective quadrant, the quadrant text will render at top of the respective quadrant. > If there are points **x-axis** labels will rendered from left of the respective quadrant also they will be displayed in bottom of the chart, and **y-axis** lables will be rendered in bottom of the respective quadrant, the quadrant text will render at top of the respective quadrant.
@@ -152,7 +149,7 @@ Points are used to plot a circle inside the quadrantChart. The syntax is `<text>
%%{init: {"quadrantChart": {"chartWidth": 400, "chartHeight": 400}, "themeVariables": {"quadrant1TextFill": "#ff0000"} }}%% %%{init: {"quadrantChart": {"chartWidth": 400, "chartHeight": 400}, "themeVariables": {"quadrant1TextFill": "#ff0000"} }}%%
quadrantChart quadrantChart
x-axis Urgent --> Not Urgent x-axis Urgent --> Not Urgent
y-axis Not Important --> important y-axis Not Important --> "Important ❤"
quadrant-1 Plan quadrant-1 Plan
quadrant-2 Do quadrant-2 Do
quadrant-3 Deligate quadrant-3 Deligate
@@ -163,7 +160,7 @@ quadrantChart
%%{init: {"quadrantChart": {"chartWidth": 400, "chartHeight": 400}, "themeVariables": {"quadrant1TextFill": "#ff0000"} }}%% %%{init: {"quadrantChart": {"chartWidth": 400, "chartHeight": 400}, "themeVariables": {"quadrant1TextFill": "#ff0000"} }}%%
quadrantChart quadrantChart
x-axis Urgent --> Not Urgent x-axis Urgent --> Not Urgent
y-axis Not Important --> important y-axis Not Important --> "Important ❤"
quadrant-1 Plan quadrant-1 Plan
quadrant-2 Do quadrant-2 Do
quadrant-3 Deligate quadrant-3 Deligate

View File

@@ -1,10 +1,10 @@
{ {
"name": "mermaid-monorepo", "name": "mermaid-monorepo",
"private": true, "private": true,
"version": "10.1.0", "version": "10.2.1",
"description": "Markdownish syntax for generating flowcharts, sequence diagrams, class diagrams, gantt charts and git graphs.", "description": "Markdownish syntax for generating flowcharts, sequence diagrams, class diagrams, gantt charts and git graphs.",
"type": "module", "type": "module",
"packageManager": "pnpm@8.4.0", "packageManager": "pnpm@8.5.1",
"keywords": [ "keywords": [
"diagram", "diagram",
"markdown", "markdown",

View File

@@ -1,6 +1,6 @@
{ {
"name": "mermaid", "name": "mermaid",
"version": "10.2.0-rc.2", "version": "10.2.1",
"description": "Markdown-ish syntax for generating flowcharts, sequence diagrams, class diagrams, gantt charts and git graphs.", "description": "Markdown-ish syntax for generating flowcharts, sequence diagrams, class diagrams, gantt charts and git graphs.",
"type": "module", "type": "module",
"module": "./dist/mermaid.core.mjs", "module": "./dist/mermaid.core.mjs",
@@ -28,7 +28,7 @@
"docs:build": "rimraf ../../docs && pnpm docs:spellcheck && pnpm docs:code && ts-node-esm src/docs.mts", "docs:build": "rimraf ../../docs && pnpm docs:spellcheck && pnpm docs:code && ts-node-esm src/docs.mts",
"docs:verify": "pnpm docs:spellcheck && pnpm docs:code && ts-node-esm src/docs.mts --verify", "docs:verify": "pnpm docs:spellcheck && pnpm docs:code && ts-node-esm src/docs.mts --verify",
"docs:pre:vitepress": "rimraf src/vitepress && pnpm docs:code && ts-node-esm src/docs.mts --vitepress", "docs:pre:vitepress": "rimraf src/vitepress && pnpm docs:code && ts-node-esm src/docs.mts --vitepress",
"docs:build:vitepress": "pnpm docs:pre:vitepress && (cd src/vitepress && pnpm --filter ./ install && pnpm run build) && cpy --flat src/docs/landing/ ./src/vitepress/.vitepress/dist/landing", "docs:build:vitepress": "pnpm docs:pre:vitepress && (cd src/vitepress && pnpm --filter ./ install --no-frozen-lockfile --ignore-scripts && pnpm run build) && cpy --flat src/docs/landing/ ./src/vitepress/.vitepress/dist/landing",
"docs:dev": "pnpm docs:pre:vitepress && concurrently \"pnpm --filter ./ src/vitepress dev\" \"ts-node-esm src/docs.mts --watch --vitepress\"", "docs:dev": "pnpm docs:pre:vitepress && concurrently \"pnpm --filter ./ src/vitepress dev\" \"ts-node-esm src/docs.mts --watch --vitepress\"",
"docs:serve": "pnpm docs:build:vitepress && vitepress serve src/vitepress", "docs:serve": "pnpm docs:build:vitepress && vitepress serve src/vitepress",
"docs:spellcheck": "cspell --config ../../cSpell.json \"src/docs/**/*.md\"", "docs:spellcheck": "cspell --config ../../cSpell.json \"src/docs/**/*.md\"",
@@ -53,7 +53,6 @@
}, },
"dependencies": { "dependencies": {
"@braintree/sanitize-url": "^6.0.2", "@braintree/sanitize-url": "^6.0.2",
"@khanacademy/simple-markdown": "^0.9.0",
"cytoscape": "^3.23.0", "cytoscape": "^3.23.0",
"cytoscape-cose-bilkent": "^4.1.0", "cytoscape-cose-bilkent": "^4.1.0",
"cytoscape-fcose": "^2.1.0", "cytoscape-fcose": "^2.1.0",
@@ -64,6 +63,7 @@
"elkjs": "^0.8.2", "elkjs": "^0.8.2",
"khroma": "^2.0.0", "khroma": "^2.0.0",
"lodash-es": "^4.17.21", "lodash-es": "^4.17.21",
"mdast-util-from-markdown": "^1.3.0",
"non-layered-tidy-tree-layout": "^2.0.2", "non-layered-tidy-tree-layout": "^2.0.2",
"stylis": "^4.1.3", "stylis": "^4.1.3",
"ts-dedent": "^2.2.0", "ts-dedent": "^2.2.0",

View File

@@ -361,72 +361,6 @@ export const drawNote = function (elem, note, conf, diagObj) {
}; };
export const parseMember = function (text) { export const parseMember = function (text) {
// Note: these two regular expressions don't parse the official UML syntax for attributes
// and methods. They parse a Java-style syntax of the form
// "String name" (for attributes) and "String name(int x)" for methods
const fieldRegEx = /^([#+~-])?(\w+)(~\w+~|\[])?\s+(\w+) *([$*])?$/;
const methodRegEx = /^([#+|~-])?(\w+) *\( *(.*)\) *([$*])? *(\w*[[\]|~]*\s*\w*~?)$/;
let fieldMatch = text.match(fieldRegEx);
let methodMatch = text.match(methodRegEx);
if (fieldMatch && !methodMatch) {
return buildFieldDisplay(fieldMatch);
} else if (methodMatch) {
return buildMethodDisplay(methodMatch);
} else {
return buildLegacyDisplay(text);
}
};
const buildFieldDisplay = function (parsedText) {
let cssStyle = '';
let displayText = '';
try {
let visibility = parsedText[1] ? parsedText[1].trim() : '';
let fieldType = parsedText[2] ? parsedText[2].trim() : '';
let genericType = parsedText[3] ? parseGenericTypes(parsedText[3].trim()) : '';
let fieldName = parsedText[4] ? parsedText[4].trim() : '';
let classifier = parsedText[5] ? parsedText[5].trim() : '';
displayText = visibility + fieldType + genericType + ' ' + fieldName;
cssStyle = parseClassifier(classifier);
} catch (err) {
displayText = parsedText;
}
return {
displayText: displayText,
cssStyle: cssStyle,
};
};
const buildMethodDisplay = function (parsedText) {
let cssStyle = '';
let displayText = '';
try {
let visibility = parsedText[1] ? parsedText[1].trim() : '';
let methodName = parsedText[2] ? parsedText[2].trim() : '';
let parameters = parsedText[3] ? parseGenericTypes(parsedText[3].trim()) : '';
let classifier = parsedText[4] ? parsedText[4].trim() : '';
let returnType = parsedText[5] ? ' : ' + parseGenericTypes(parsedText[5]).trim() : '';
displayText = visibility + methodName + '(' + parameters + ')' + returnType;
cssStyle = parseClassifier(classifier);
} catch (err) {
displayText = parsedText;
}
return {
displayText: displayText,
cssStyle: cssStyle,
};
};
const buildLegacyDisplay = function (text) {
// if for some reason we don't have any match, use old format to parse text
let displayText = ''; let displayText = '';
let cssStyle = ''; let cssStyle = '';
let returnType = ''; let returnType = '';
@@ -444,14 +378,15 @@ const buildLegacyDisplay = function (text) {
cssStyle = parseClassifier(lastChar); cssStyle = parseClassifier(lastChar);
} }
let startIndex = visibility === '' ? 0 : 1; const startIndex = visibility === '' ? 0 : 1;
let endIndex = cssStyle === '' ? text.length : text.length - 1; let endIndex = cssStyle === '' ? text.length : text.length - 1;
text = text.substring(startIndex, endIndex); text = text.substring(startIndex, endIndex);
let methodStart = text.indexOf('('); const methodStart = text.indexOf('(');
let methodEnd = text.indexOf(')'); const methodEnd = text.indexOf(')');
const isMethod = methodStart > 1 && methodEnd > methodStart && methodEnd <= text.length;
if (methodStart > 1 && methodEnd > methodStart && methodEnd <= text.length) { if (isMethod) {
let methodName = text.substring(0, methodStart).trim(); let methodName = text.substring(0, methodStart).trim();
const parameters = text.substring(methodStart + 1, methodEnd); const parameters = text.substring(methodStart + 1, methodEnd);
@@ -478,7 +413,7 @@ const buildLegacyDisplay = function (text) {
} }
} else { } else {
// finally - if all else fails, just send the text back as written (other than parsing for generic types) // finally - if all else fails, just send the text back as written (other than parsing for generic types)
displayText = parseGenericTypes(text); displayText = visibility + parseGenericTypes(text);
} }
return { return {

View File

@@ -1,3 +1,6 @@
// import khroma from 'khroma';
import * as khroma from 'khroma';
/** Returns the styles given options */ /** Returns the styles given options */
export interface FlowChartStyleOptions { export interface FlowChartStyleOptions {
arrowheadColor: string; arrowheadColor: string;
@@ -15,6 +18,18 @@ export interface FlowChartStyleOptions {
titleColor: string; titleColor: string;
} }
const fade = (color: string, opacity: number) => {
// @ts-ignore TODO: incorrect types from khroma
const channel = khroma.channel;
const r = channel(color, 'r');
const g = channel(color, 'g');
const b = channel(color, 'b');
// @ts-ignore incorrect types from khroma
return khroma.rgba(r, g, b, opacity);
};
const getStyles = (options: FlowChartStyleOptions) => const getStyles = (options: FlowChartStyleOptions) =>
`.label { `.label {
font-family: ${options.fontFamily}; font-family: ${options.fontFamily};
@@ -82,6 +97,12 @@ const getStyles = (options: FlowChartStyleOptions) =>
text-align: center; text-align: center;
} }
/* For html labels only */
.labelBkg {
background-color: ${fade(options.edgeLabelBackground, 0.5)};
// background-color:
}
.cluster rect { .cluster rect {
fill: ${options.clusterBkg}; fill: ${options.clusterBkg};
stroke: ${options.clusterBorder}; stroke: ${options.clusterBorder};

View File

@@ -1,8 +1,8 @@
import { sanitizeUrl } from '@braintree/sanitize-url'; import { sanitizeUrl } from '@braintree/sanitize-url';
import dayjs from 'dayjs/esm/index.js'; import dayjs from 'dayjs';
import dayjsIsoWeek from 'dayjs/esm/plugin/isoWeek/index.js'; import dayjsIsoWeek from 'dayjs/plugin/isoWeek.js';
import dayjsCustomParseFormat from 'dayjs/esm/plugin/customParseFormat/index.js'; import dayjsCustomParseFormat from 'dayjs/plugin/customParseFormat.js';
import dayjsAdvancedFormat from 'dayjs/esm/plugin/advancedFormat/index.js'; import dayjsAdvancedFormat from 'dayjs/plugin/advancedFormat.js';
import { log } from '../../logger.js'; import { log } from '../../logger.js';
import * as configApi from '../../config.js'; import * as configApi from '../../config.js';
import utils from '../../utils.js'; import utils from '../../utils.js';

View File

@@ -1,5 +1,5 @@
// @ts-nocheck TODO: Fix TS // @ts-nocheck TODO: Fix TS
import dayjs from 'dayjs/esm/index.js'; import dayjs from 'dayjs';
import ganttDb from './ganttDb.js'; import ganttDb from './ganttDb.js';
import { convert } from '../../tests/util.js'; import { convert } from '../../tests/util.js';

View File

@@ -1,4 +1,4 @@
import dayjs from 'dayjs/esm/index.js'; import dayjs from 'dayjs';
import { log } from '../../logger.js'; import { log } from '../../logger.js';
import { import {
select, select,

View File

@@ -119,10 +119,10 @@ points
axisDetails axisDetails
: X-AXIS text AXIS-TEXT-DELIMITER text {yy.setXAxisLeftText($2); yy.setXAxisRightText($4);} : X-AXIS text AXIS-TEXT-DELIMITER text {yy.setXAxisLeftText($2); yy.setXAxisRightText($4);}
| X-AXIS text AXIS-TEXT-DELIMITER {$2.text += " ⟶ "; yy.setXAxisLeftText($2);} | X-AXIS text AXIS-TEXT-DELIMITER {$2.text += $3; yy.setXAxisLeftText($2);}
| X-AXIS text {yy.setXAxisLeftText($2);} | X-AXIS text {yy.setXAxisLeftText($2);}
| Y-AXIS text AXIS-TEXT-DELIMITER text {yy.setYAxisBottomText($2); yy.setYAxisTopText($4);} | Y-AXIS text AXIS-TEXT-DELIMITER text {yy.setYAxisBottomText($2); yy.setYAxisTopText($4);}
| Y-AXIS text AXIS-TEXT-DELIMITER {$2.text += " ⟶ "; yy.setYAxisBottomText($2);} | Y-AXIS text AXIS-TEXT-DELIMITER {$2.text += $3; yy.setYAxisBottomText($2);}
| Y-AXIS text {yy.setYAxisBottomText($2);} | Y-AXIS text {yy.setYAxisBottomText($2);}
; ;

View File

@@ -93,7 +93,7 @@ describe('Testing quadrantChart jison file', () => {
str = 'quadrantChart\n x-AxIs "Urgent(* +=[❤" --> '; str = 'quadrantChart\n x-AxIs "Urgent(* +=[❤" --> ';
expect(parserFnConstructor(str)).not.toThrow(); expect(parserFnConstructor(str)).not.toThrow();
expect(mockDB.setXAxisLeftText).toHaveBeenCalledWith({ expect(mockDB.setXAxisLeftText).toHaveBeenCalledWith({
text: 'Urgent(* +=[❤ ', text: 'Urgent(* +=[❤ --> ',
type: 'text', type: 'text',
}); });
expect(mockDB.setXAxisRightText).not.toHaveBeenCalled(); expect(mockDB.setXAxisRightText).not.toHaveBeenCalled();
@@ -131,7 +131,7 @@ describe('Testing quadrantChart jison file', () => {
str = 'quadrantChart\n y-AxIs "Urgent(* +=[❤" --> '; str = 'quadrantChart\n y-AxIs "Urgent(* +=[❤" --> ';
expect(parserFnConstructor(str)).not.toThrow(); expect(parserFnConstructor(str)).not.toThrow();
expect(mockDB.setYAxisBottomText).toHaveBeenCalledWith({ expect(mockDB.setYAxisBottomText).toHaveBeenCalledWith({
text: 'Urgent(* +=[❤ ', text: 'Urgent(* +=[❤ --> ',
type: 'text', type: 'text',
}); });
expect(mockDB.setYAxisTopText).not.toHaveBeenCalled(); expect(mockDB.setYAxisTopText).not.toHaveBeenCalled();

View File

@@ -578,7 +578,7 @@ export const drawLoop = function (elem, loopModel, labelText, conf) {
txt.class = 'labelText'; txt.class = 'labelText';
drawLabel(g, txt); drawLabel(g, txt);
txt = svgDrawCommon.getTextObj(); txt = getTextObj();
txt.text = loopModel.title; txt.text = loopModel.title;
txt.x = loopModel.startx + labelBoxWidth / 2 + (loopModel.stopx - loopModel.startx) / 2; txt.x = loopModel.startx + labelBoxWidth / 2 + (loopModel.stopx - loopModel.startx) / 2;
txt.y = loopModel.starty + boxMargin + boxTextMargin; txt.y = loopModel.starty + boxMargin + boxTextMargin;
@@ -764,6 +764,37 @@ export const insertArrowCrossHead = function (elem) {
// this is actual shape for arrowhead // this is actual shape for arrowhead
}; };
export const getTextObj = function () {
return {
x: 0,
y: 0,
fill: undefined,
anchor: undefined,
style: '#666',
width: undefined,
height: undefined,
textMargin: 0,
rx: 0,
ry: 0,
tspan: true,
valign: undefined,
};
};
export const getNoteRect = function () {
return {
x: 0,
y: 0,
fill: '#EDF2AE',
stroke: '#666',
width: 100,
anchor: 'start',
height: 100,
rx: 0,
ry: 0,
};
};
const _drawTextCandidateFunc = (function () { const _drawTextCandidateFunc = (function () {
/** /**
* @param {any} content * @param {any} content
@@ -1004,6 +1035,8 @@ export default {
insertDatabaseIcon, insertDatabaseIcon,
insertComputerIcon, insertComputerIcon,
insertClockIcon, insertClockIcon,
getTextObj,
getNoteRect,
popupMenu, popupMenu,
popdownMenu, popdownMenu,
fixLifeLineHeights, fixLifeLineHeights,

View File

@@ -5,12 +5,12 @@ import { contributors } from '../contributors';
<template> <template>
<div flex="~ wrap gap2" justify-center> <div flex="~ wrap gap2" justify-center>
<a <a
v-for="{ name, avatar } of contributors" v-for="{ username, avatar } of contributors"
:key="name" :key="username"
:href="`https://github.com/${name}`" :href="`https://github.com/${username}`"
m-0 m-0
rel="noopener noreferrer" rel="noopener noreferrer"
:aria-label="`${name} on GitHub`" :aria-label="`${username} on GitHub`"
> >
<img <img
loading="lazy" loading="lazy"
@@ -20,7 +20,7 @@ import { contributors } from '../contributors';
rounded-full rounded-full
h-12 h-12
w-12 w-12
:alt="`${name}'s avatar`" :alt="`${username}'s avatar`"
/> />
</a> </a>
</div> </div>

View File

@@ -1,3 +1,4 @@
/* eslint-disable no-console */
import { mkdir, writeFile, readFile } from 'node:fs/promises'; import { mkdir, writeFile, readFile } from 'node:fs/promises';
import { existsSync } from 'node:fs'; import { existsSync } from 'node:fs';
import { fileURLToPath } from 'url'; import { fileURLToPath } from 'url';
@@ -12,22 +13,23 @@ async function download(url: string, fileName: URL) {
if (existsSync(fileName)) { if (existsSync(fileName)) {
return; return;
} }
// eslint-disable-next-line no-console console.log('downloading', url);
console.log('downloading', fileName);
try { try {
const image = await fetch(url); const image = await fetch(url);
await writeFile(fileName, Buffer.from(await image.arrayBuffer())); await writeFile(fileName, Buffer.from(await image.arrayBuffer()));
} catch {} } catch (error) {
console.error(error);
}
} }
async function fetchAvatars() { async function fetchAvatars() {
await mkdir(fileURLToPath(new URL('..', getAvatarPath('none'))), { recursive: true }); await mkdir(fileURLToPath(new URL(getAvatarPath('none'))).replace('none.png', ''), {
recursive: true,
});
contributors = JSON.parse(await readFile(pathContributors, { encoding: 'utf-8' })); contributors = JSON.parse(await readFile(pathContributors, { encoding: 'utf-8' }));
await Promise.allSettled( for (const name of contributors) {
contributors.map((name) => await download(`https://github.com/${name}.png?size=100`, getAvatarPath(name));
download(`https://github.com/${name}.png?size=100`, getAvatarPath(name)) }
)
);
} }
fetchAvatars(); fetchAvatars();

View File

@@ -23,9 +23,8 @@ async function fetchContributors() {
} }
); );
data = await response.json(); data = await response.json();
console.log(response.status, response.statusText);
console.log(data);
collaborators.push(...data.map((i) => i.login)); collaborators.push(...data.map((i) => i.login));
console.log(`Fetched page ${page}`);
page++; page++;
} while (data.length === 100); } while (data.length === 100);
return collaborators.filter((name) => !name.includes('[bot]')); return collaborators.filter((name) => !name.includes('[bot]'));

View File

@@ -20,17 +20,17 @@
}, },
"devDependencies": { "devDependencies": {
"@iconify-json/carbon": "^1.1.16", "@iconify-json/carbon": "^1.1.16",
"@unocss/reset": "^0.51.8", "@unocss/reset": "^0.52.0",
"@vite-pwa/vitepress": "^0.0.5", "@vite-pwa/vitepress": "^0.0.5",
"@vitejs/plugin-vue": "^4.2.1", "@vitejs/plugin-vue": "^4.2.1",
"fast-glob": "^3.2.12", "fast-glob": "^3.2.12",
"https-localhost": "^4.7.1", "https-localhost": "^4.7.1",
"pathe": "^1.1.0", "pathe": "^1.1.0",
"unocss": "^0.51.8", "unocss": "^0.52.0",
"unplugin-vue-components": "^0.24.1", "unplugin-vue-components": "^0.24.1",
"vite": "^4.3.3", "vite": "^4.3.3",
"vite-plugin-pwa": "^0.14.7", "vite-plugin-pwa": "^0.15.0",
"vitepress": "1.0.0-alpha.74", "vitepress": "1.0.0-alpha.76",
"workbox-window": "^6.5.4" "workbox-window": "^6.5.4"
} }
} }

View File

@@ -39,7 +39,30 @@ flowchart LR
id1[This is the text in the box] id1[This is the text in the box]
``` ```
## Graph #### Unicode text
Use `"` to enclose the unicode text.
```mermaid-example
flowchart LR
id["This ❤ Unicode"]
```
#### Markdown formatting
Use double quotes and backticks "\` text \`" to enclose the markdown text.
```mermaid-example
%%{init: {"flowchart": {"htmlLabels": false}} }%%
flowchart LR
markdown["`This **is** _Markdown_`"]
newLines["`Line1
Line 2
Line 3`"]
markdown --> newLines
```
### Direction
This statement declares the direction of the Flowchart. This statement declares the direction of the Flowchart.
@@ -57,15 +80,13 @@ flowchart LR
Start --> Stop Start --> Stop
``` ```
## Flowchart Orientation
Possible FlowChart orientations are: Possible FlowChart orientations are:
- TB - top to bottom - TB - Top to bottom
- TD - top-down/ same as top to bottom - TD - Top-down/ same as top to bottom
- BT - bottom to top - BT - Bottom to top
- RL - right to left - RL - Right to left
- LR - left to right - LR - Left to right
## Node shapes ## Node shapes

View File

@@ -23,10 +23,6 @@ quadrantChart
## Syntax ## Syntax
```note
In place of `<text>` you can use text like `this is a sample text` or inside **double quotes** like `"This type of text may contain unicode like ❤"`.
```
```note ```note
If there is no points available in the chart both **axis** text and **quadrant** will be rendered in the center of the respective quadrant. If there is no points available in the chart both **axis** text and **quadrant** will be rendered in the center of the respective quadrant.
If there are points **x-axis** labels will rendered from left of the respective quadrant also they will be displayed in bottom of the chart, and **y-axis** lables will be rendered in bottom of the respective quadrant, the quadrant text will render at top of the respective quadrant. If there are points **x-axis** labels will rendered from left of the respective quadrant also they will be displayed in bottom of the chart, and **y-axis** lables will be rendered in bottom of the respective quadrant, the quadrant text will render at top of the respective quadrant.
@@ -134,7 +130,7 @@ Points are used to plot a circle inside the quadrantChart. The syntax is `<text>
%%{init: {"quadrantChart": {"chartWidth": 400, "chartHeight": 400}, "themeVariables": {"quadrant1TextFill": "#ff0000"} }}%% %%{init: {"quadrantChart": {"chartWidth": 400, "chartHeight": 400}, "themeVariables": {"quadrant1TextFill": "#ff0000"} }}%%
quadrantChart quadrantChart
x-axis Urgent --> Not Urgent x-axis Urgent --> Not Urgent
y-axis Not Important --> important y-axis Not Important --> "Important ❤"
quadrant-1 Plan quadrant-1 Plan
quadrant-2 Do quadrant-2 Do
quadrant-3 Deligate quadrant-3 Deligate

View File

@@ -2,7 +2,7 @@
/* eslint-disable @typescript-eslint/no-unused-vars */ /* eslint-disable @typescript-eslint/no-unused-vars */
/* eslint-disable @typescript-eslint/no-empty-function */ /* eslint-disable @typescript-eslint/no-empty-function */
/* eslint-disable no-console */ /* eslint-disable no-console */
import dayjs from 'dayjs/esm/index.js'; import dayjs from 'dayjs';
export type LogLevel = 'trace' | 'debug' | 'info' | 'warn' | 'error' | 'fatal'; export type LogLevel = 'trace' | 'debug' | 'info' | 'warn' | 'error' | 'fatal';

View File

@@ -154,13 +154,7 @@ export const encodeEntities = function (text: string): string {
* @returns * @returns
*/ */
export const decodeEntities = function (text: string): string { export const decodeEntities = function (text: string): string {
let txt = text; return text.replace(/fl°°/g, '&#').replace(/fl°/g, '&').replace(/¶ß/g, ';');
txt = txt.replace(/fl°°/g, '&#');
txt = txt.replace(/fl°/g, '&');
txt = txt.replace(/¶ß/g, ';');
return txt;
}; };
// append !important; to each cssClass followed by a final !important, all enclosed in { } // append !important; to each cssClass followed by a final !important, all enclosed in { }

View File

@@ -1,7 +1,4 @@
import { select } from 'd3';
import { log } from '../logger.js'; import { log } from '../logger.js';
import { getConfig } from '../config.js';
import { evaluate } from '../diagrams/common/common.js';
import { decodeEntities } from '../mermaidAPI.js'; import { decodeEntities } from '../mermaidAPI.js';
import { markdownToHTML, markdownToLines } from '../rendering-util/handle-markdown-text.js'; import { markdownToHTML, markdownToLines } from '../rendering-util/handle-markdown-text.js';
/** /**
@@ -19,9 +16,10 @@ function applyStyle(dom, styleFn) {
* @param {any} node * @param {any} node
* @param width * @param width
* @param classes * @param classes
* @param addBackground
* @returns {SVGForeignObjectElement} Node * @returns {SVGForeignObjectElement} Node
*/ */
function addHtmlSpan(element, node, width, classes) { function addHtmlSpan(element, node, width, classes, addBackground = false) {
const fo = element.append('foreignObject'); const fo = element.append('foreignObject');
// const newEl = document.createElementNS('http://www.w3.org/2000/svg', 'foreignObject'); // const newEl = document.createElementNS('http://www.w3.org/2000/svg', 'foreignObject');
// const newEl = document.createElementNS('http://www.w3.org/2000/svg', 'foreignObject'); // const newEl = document.createElementNS('http://www.w3.org/2000/svg', 'foreignObject');
@@ -32,7 +30,8 @@ function addHtmlSpan(element, node, width, classes) {
const label = node.label; const label = node.label;
const labelClass = node.isNode ? 'nodeLabel' : 'edgeLabel'; const labelClass = node.isNode ? 'nodeLabel' : 'edgeLabel';
div.html( div.html(
`<span class="${labelClass} ${classes}" ` + `
<span class="${labelClass} ${classes}" ` +
(node.labelStyle ? 'style="' + node.labelStyle + '"' : '') + (node.labelStyle ? 'style="' + node.labelStyle + '"' : '') +
'>' + '>' +
label + label +
@@ -44,6 +43,9 @@ function addHtmlSpan(element, node, width, classes) {
div.style('white-space', 'nowrap'); div.style('white-space', 'nowrap');
div.style('max-width', width + 'px'); div.style('max-width', width + 'px');
div.attr('xmlns', 'http://www.w3.org/1999/xhtml'); div.attr('xmlns', 'http://www.w3.org/1999/xhtml');
if (addBackground) {
div.attr('class', 'labelBkg');
}
let bbox = div.node().getBoundingClientRect(); let bbox = div.node().getBoundingClientRect();
if (bbox.width === width) { if (bbox.width === width) {
@@ -203,21 +205,10 @@ export const createText = (
), ),
labelStyle: style.replace('fill:', 'color:'), labelStyle: style.replace('fill:', 'color:'),
}; };
let vertexNode = addHtmlSpan(el, node, width, classes); let vertexNode = addHtmlSpan(el, node, width, classes, addSvgBackground);
return vertexNode; return vertexNode;
} else { } else {
const structuredText = markdownToLines(text); const structuredText = markdownToLines(text);
const special = ['"', "'", '.', ',', ':', ';', '!', '?', '(', ')', '[', ']', '{', '}'];
let lastWord;
structuredText.forEach((line) => {
line.forEach((word) => {
if (special.includes(word.content) && lastWord) {
lastWord.content += word.content;
word.content = '';
}
lastWord = word;
});
});
const svgLabel = createFormattedText(width, el, structuredText, addSvgBackground); const svgLabel = createFormattedText(width, el, structuredText, addSvgBackground);
return svgLabel; return svgLabel;
} }

View File

@@ -1,61 +1,55 @@
import SimpleMarkdown from '@khanacademy/simple-markdown'; import { fromMarkdown } from 'mdast-util-from-markdown';
import { dedent } from 'ts-dedent';
/** /**
* * @param {string} markdown markdown to process
* @param markdown * @returns {string} processed markdown
*/ */
function preprocessMarkdown(markdown) { function preprocessMarkdown(markdown) {
// Replace multiple newlines with a single newline // Replace multiple newlines with a single newline
const withoutMultipleNewlines = markdown.replace(/\n{2,}/g, '\n'); const withoutMultipleNewlines = markdown.replace(/\n{2,}/g, '\n');
// Remove extra spaces at the beginning of each line // Remove extra spaces at the beginning of each line
const withoutExtraSpaces = withoutMultipleNewlines.replace(/^\s+/gm, ''); const withoutExtraSpaces = dedent(withoutMultipleNewlines);
return withoutExtraSpaces; return withoutExtraSpaces;
} }
/** /**
* * @param {string} markdown markdown to split into lines
* @param markdown
*/ */
export function markdownToLines(markdown) { export function markdownToLines(markdown) {
const preprocessedMarkdown = preprocessMarkdown(markdown); const preprocessedMarkdown = preprocessMarkdown(markdown);
const mdParse = SimpleMarkdown.defaultBlockParse; const { children } = fromMarkdown(preprocessedMarkdown);
const syntaxTree = mdParse(preprocessedMarkdown); const lines = [[]];
let lines = [[]];
let currentLine = 0; let currentLine = 0;
/** /**
* * @param {import('mdast').Content} node
* @param node * @param {string} [parentType]
* @param parentType
*/ */
function processNode(node, parentType) { function processNode(node, parentType = 'normal') {
if (node.type === 'text') { if (node.type === 'text') {
const textLines = node.content.split('\n'); const textLines = node.value.split('\n');
textLines.forEach((textLine, index) => { textLines.forEach((textLine, index) => {
if (index !== 0) { if (index !== 0) {
currentLine++; currentLine++;
lines.push([]); lines.push([]);
} }
// textLine.split(/ (?=[^!"#$%&'()*+,-./:;<=>?@[\]^_`{|}~]+)/).forEach((word) => {
textLine.split(' ').forEach((word) => { textLine.split(' ').forEach((word) => {
if (word) { if (word) {
lines[currentLine].push({ content: word, type: parentType || 'normal' }); lines[currentLine].push({ content: word, type: parentType });
} }
}); });
}); });
} else if (node.type === 'strong' || node.type === 'em') { } else if (node.type === 'strong' || node.type === 'emphasis') {
node.content.forEach((contentNode) => { node.children.forEach((contentNode) => {
processNode(contentNode, node.type); processNode(contentNode, node.type);
}); });
} }
} }
syntaxTree.forEach((treeNode) => { children.forEach((treeNode) => {
if (treeNode.type === 'paragraph') { if (treeNode.type === 'paragraph') {
treeNode.content.forEach((contentNode) => { treeNode.children.forEach((contentNode) => {
processNode(contentNode); processNode(contentNode);
}); });
} }
@@ -65,30 +59,27 @@ export function markdownToLines(markdown) {
} }
/** /**
* * @param {string} markdown markdown to convert to HTML
* @param markdown * @returns {string} HTML
*/ */
export function markdownToHTML(markdown) { export function markdownToHTML(markdown) {
const mdParse = SimpleMarkdown.defaultBlockParse; const { children } = fromMarkdown(markdown);
const syntaxTree = mdParse(markdown);
/** /**
* * @param {import('mdast').Content} node
* @param node
*/ */
function output(node) { function output(node) {
if (node.type === 'text') { if (node.type === 'text') {
return node.content.replace(/\n/g, '<br/>'); return node.value.replace(/\n/g, '<br/>');
} else if (node.type === 'strong') { } else if (node.type === 'strong') {
return `<strong>${node.content.map(output).join('')}</strong>`; return `<strong>${node.children.map(output).join('')}</strong>`;
} else if (node.type === 'em') { } else if (node.type === 'emphasis') {
return `<em>${node.content.map(output).join('')}</em>`; return `<em>${node.children.map(output).join('')}</em>`;
} else if (node.type === 'paragraph') { } else if (node.type === 'paragraph') {
return `<p>${node.content.map(output).join('')}</p>`; return `<p>${node.children.map(output).join('')}</p>`;
} else {
return '';
} }
return `Unsupported markdown: ${node.type}`;
} }
return syntaxTree.map(output).join(''); return children.map(output).join('');
} }

View File

@@ -1,6 +1,5 @@
// import { test } from 'vitest'; import { markdownToLines, markdownToHTML } from './handle-markdown-text.js';
import { markdownToLines, markdownToHTML } from './handle-markdown-text'; import { test, expect } from 'vitest';
import { test } from 'vitest';
test('markdownToLines - Basic test', () => { test('markdownToLines - Basic test', () => {
const input = `This is regular text const input = `This is regular text
@@ -37,9 +36,9 @@ Here is a line *with an italic* section`;
{ content: 'is', type: 'normal' }, { content: 'is', type: 'normal' },
{ content: 'a', type: 'normal' }, { content: 'a', type: 'normal' },
{ content: 'line', type: 'normal' }, { content: 'line', type: 'normal' },
{ content: 'with', type: 'em' }, { content: 'with', type: 'emphasis' },
{ content: 'an', type: 'em' }, { content: 'an', type: 'emphasis' },
{ content: 'italic', type: 'em' }, { content: 'italic', type: 'emphasis' },
{ content: 'section', type: 'normal' }, { content: 'section', type: 'normal' },
], ],
]; ];
@@ -117,7 +116,6 @@ test('markdownToLines - paragraph 1', () => {
test('markdownToLines - paragraph', () => { test('markdownToLines - paragraph', () => {
const input = `**Start** with const input = `**Start** with
a second line`; a second line`;
const expectedOutput = [ const expectedOutput = [
@@ -144,7 +142,7 @@ test('markdownToLines - Only italic formatting', () => {
{ content: 'This', type: 'normal' }, { content: 'This', type: 'normal' },
{ content: 'is', type: 'normal' }, { content: 'is', type: 'normal' },
{ content: 'an', type: 'normal' }, { content: 'an', type: 'normal' },
{ content: 'italic', type: 'em' }, { content: 'italic', type: 'emphasis' },
{ content: 'test', type: 'normal' }, { content: 'test', type: 'normal' },
], ],
]; ];
@@ -158,7 +156,7 @@ it('markdownToLines - Mixed formatting', () => {
const expectedOutput = [ const expectedOutput = [
[ [
{ content: 'Italic', type: 'em' }, { content: 'Italic', type: 'emphasis' },
{ content: 'and', type: 'normal' }, { content: 'and', type: 'normal' },
{ content: 'bold', type: 'strong' }, { content: 'bold', type: 'strong' },
{ content: 'formatting', type: 'normal' }, { content: 'formatting', type: 'normal' },
@@ -179,21 +177,15 @@ Word!`;
{ content: 'dog', type: 'normal' }, { content: 'dog', type: 'normal' },
{ content: 'in', type: 'normal' }, { content: 'in', type: 'normal' },
{ content: 'the', type: 'strong' }, { content: 'the', type: 'strong' },
{ content: 'hog', type: 'normal' }, { content: 'hog...', type: 'normal' },
{ content: '.', type: 'normal' },
{ content: '.', type: 'normal' },
{ content: '.', type: 'normal' },
{ content: 'a', type: 'normal' }, { content: 'a', type: 'normal' },
{ content: 'very', type: 'em' }, { content: 'very', type: 'emphasis' },
{ content: 'long', type: 'em' }, { content: 'long', type: 'emphasis' },
{ content: 'text', type: 'em' }, { content: 'text', type: 'emphasis' },
{ content: 'about', type: 'normal' }, { content: 'about', type: 'normal' },
{ content: 'it', type: 'normal' }, { content: 'it', type: 'normal' },
], ],
[ [{ content: 'Word!', type: 'normal' }],
{ content: 'Word', type: 'normal' },
{ content: '!', type: 'normal' },
],
]; ];
const output = markdownToLines(input); const output = markdownToLines(input);
@@ -246,8 +238,16 @@ test('markdownToHTML - Only italic formatting', () => {
test('markdownToHTML - Mixed formatting', () => { test('markdownToHTML - Mixed formatting', () => {
const input = `*Italic* and **bold** formatting`; const input = `*Italic* and **bold** formatting`;
const expectedOutput = `<p><em>Italic</em> and <strong>bold</strong> formatting</p>`; const expectedOutput = `<p><em>Italic</em> and <strong>bold</strong> formatting</p>`;
const output = markdownToHTML(input); const output = markdownToHTML(input);
expect(output).toEqual(expectedOutput); expect(output).toEqual(expectedOutput);
}); });
test('markdownToHTML - Unsupported formatting', () => {
expect(
markdownToHTML(`Hello
- l1
- l2
- l3`)
).toMatchInlineSnapshot('"<p>Hello</p>Unsupported markdown: list"');
});

View File

@@ -1,4 +1,4 @@
import { darken, lighten, adjust, invert, isDark } from 'khroma'; import { darken, lighten, adjust, invert, isDark, toRgba } from 'khroma';
import { mkBorder } from './theme-helpers.js'; import { mkBorder } from './theme-helpers.js';
import { import {
oldAttributeBackgroundColorEven, oldAttributeBackgroundColorEven,

824
pnpm-lock.yaml generated

File diff suppressed because it is too large Load Diff