mirror of
https://gitee.com/vnotex/vnote.git
synced 2025-07-05 13:59:52 +08:00
support mermaid diagram
This commit is contained in:
parent
bacd112782
commit
bed6a0d234
@ -315,6 +315,7 @@ If you prefer command line on macOS, you could follow these steps.
|
||||
- [markdown-it 8.3.1](https://github.com/markdown-it/markdown-it) (MIT License)
|
||||
- [markdown-it-headinganchor 1.3.0](https://github.com/adam-p/markdown-it-headinganchor) (MIT License)
|
||||
- [markdown-it-task-lists 1.4.0](https://github.com/revin/markdown-it-task-lists) (ISC License)
|
||||
- [mermaid 7.0.0](https://github.com/knsv/mermaid) (MIT License)
|
||||
|
||||
# License (代码许可)
|
||||
VNote is licensed under the [MIT license](http://opensource.org/licenses/MIT).
|
||||
|
@ -3,9 +3,24 @@ var placeholder = document.getElementById('placeholder');
|
||||
var updateHtml = function(html) {
|
||||
placeholder.innerHTML = html;
|
||||
var codes = document.getElementsByTagName('code');
|
||||
var mermaidIdx = 0;
|
||||
for (var i = 0; i < codes.length; ++i) {
|
||||
if (codes[i].parentElement.tagName.toLowerCase() == 'pre') {
|
||||
hljs.highlightBlock(codes[i]);
|
||||
var code = codes[i];
|
||||
if (code.parentElement.tagName.toLowerCase() == 'pre') {
|
||||
if (VEnableMermaid && code.classList.contains('language-mermaid')) {
|
||||
// Mermaid code block.
|
||||
var graph = mermaidAPI.render('mermaid-diagram-' + mermaidIdx++, code.innerText, function(){});
|
||||
var graphDiv = document.createElement('div');
|
||||
graphDiv.classList.add(VMermaidDivClass);
|
||||
graphDiv.innerHTML = graph;
|
||||
var preNode = code.parentNode;
|
||||
preNode.classList.add(VMermaidDivClass);
|
||||
preNode.replaceChild(graphDiv, code);
|
||||
// replaceChild() will decrease codes.length.
|
||||
--i;
|
||||
} else {
|
||||
hljs.highlightBlock(code);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -39,6 +39,7 @@ var mdit = window.markdownit({
|
||||
html: true,
|
||||
linkify: true,
|
||||
typographer: true,
|
||||
langPrefix: 'lang-',
|
||||
highlight: function(str, lang) {
|
||||
if (lang && hljs.getLanguage(lang)) {
|
||||
return hljs.highlight(lang, str).value;
|
||||
@ -167,5 +168,6 @@ var updateText = function(text) {
|
||||
var html = markdownToHtml(text, needToc);
|
||||
placeholder.innerHTML = html;
|
||||
handleToc(needToc);
|
||||
renderMermaid('lang-mermaid');
|
||||
}
|
||||
|
||||
|
@ -139,6 +139,12 @@ table tr th :first-child, table tr td :first-child {
|
||||
table tr th :last-child, table tr td :last-child {
|
||||
margin-bottom: 0;
|
||||
}
|
||||
div.mermaid-diagram {
|
||||
overflow-y: hidden;
|
||||
}
|
||||
pre.mermaid-diagram {
|
||||
overflow-y: hidden;
|
||||
}
|
||||
|
||||
/* Code below this line is copyright Twitter Inc. */
|
||||
|
||||
|
@ -15,6 +15,15 @@ new QWebChannel(qt.webChannelTransport,
|
||||
content.requestScrollToAnchor.connect(scrollToAnchor);
|
||||
});
|
||||
|
||||
var VMermaidDivClass = 'mermaid-diagram';
|
||||
if (typeof VEnableMermaid == 'undefined') {
|
||||
VEnableMermaid = false;
|
||||
} else if (VEnableMermaid) {
|
||||
mermaidAPI.initialize({
|
||||
startOnLoad: false
|
||||
});
|
||||
}
|
||||
|
||||
var scrollToAnchor = function(anchor) {
|
||||
var anc = document.getElementById(anchor);
|
||||
if (anc != null) {
|
||||
@ -122,3 +131,27 @@ document.onkeydown = function(e) {
|
||||
}
|
||||
e.preventDefault();
|
||||
}
|
||||
|
||||
// @className, the class name of the mermaid code block, such as 'lang-mermaid'.
|
||||
var renderMermaid = function(className) {
|
||||
if (!VEnableMermaid) {
|
||||
return;
|
||||
}
|
||||
var codes = document.getElementsByTagName('code');
|
||||
var mermaidIdx = 0;
|
||||
for (var i = 0; i < codes.length; ++i) {
|
||||
var code = codes[i];
|
||||
if (code.classList.contains(className)) {
|
||||
// Mermaid code block.
|
||||
var graph = mermaidAPI.render('mermaid-diagram-' + mermaidIdx++, code.innerText, function(){});
|
||||
var graphDiv = document.createElement('div');
|
||||
graphDiv.classList.add(VMermaidDivClass);
|
||||
graphDiv.innerHTML = graph;
|
||||
var preNode = code.parentNode;
|
||||
preNode.classList.add(VMermaidDivClass);
|
||||
preNode.replaceChild(graphDiv, code);
|
||||
// replaceChild() will decrease codes.length.
|
||||
--i;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -121,5 +121,6 @@ var updateText = function(text) {
|
||||
var html = markdownToHtml(text, needToc);
|
||||
placeholder.innerHTML = html;
|
||||
handleToc(needToc);
|
||||
renderMermaid('lang-mermaid');
|
||||
};
|
||||
|
||||
|
@ -13,6 +13,7 @@ language=System
|
||||
editor_font_size=12
|
||||
; 0 - Hoedown, 1 - Marked, 2 - Markdown-it
|
||||
markdown_converter=2
|
||||
enable_mermaid=true
|
||||
|
||||
[session]
|
||||
tools_dock_checked=true
|
||||
|
273
src/utils/mermaid/mermaid.css
Normal file
273
src/utils/mermaid/mermaid.css
Normal file
@ -0,0 +1,273 @@
|
||||
/* Flowchart variables */
|
||||
/* Sequence Diagram variables */
|
||||
/* Gantt chart variables */
|
||||
.mermaid .label {
|
||||
color: #333;
|
||||
}
|
||||
.node rect,
|
||||
.node circle,
|
||||
.node ellipse,
|
||||
.node polygon {
|
||||
fill: #ECECFF;
|
||||
stroke: #CCCCFF;
|
||||
stroke-width: 1px;
|
||||
}
|
||||
.edgePath .path {
|
||||
stroke: #333333;
|
||||
}
|
||||
.edgeLabel {
|
||||
background-color: #e8e8e8;
|
||||
}
|
||||
.cluster rect {
|
||||
fill: #ffffde !important;
|
||||
rx: 4 !important;
|
||||
stroke: #aaaa33 !important;
|
||||
stroke-width: 1px !important;
|
||||
}
|
||||
.cluster text {
|
||||
fill: #333;
|
||||
}
|
||||
.actor {
|
||||
stroke: #CCCCFF;
|
||||
fill: #ECECFF;
|
||||
}
|
||||
text.actor {
|
||||
fill: black;
|
||||
stroke: none;
|
||||
}
|
||||
.actor-line {
|
||||
stroke: grey;
|
||||
}
|
||||
.messageLine0 {
|
||||
stroke-width: 1.5;
|
||||
stroke-dasharray: "2 2";
|
||||
marker-end: "url(#arrowhead)";
|
||||
stroke: #333;
|
||||
}
|
||||
.messageLine1 {
|
||||
stroke-width: 1.5;
|
||||
stroke-dasharray: "2 2";
|
||||
stroke: #333;
|
||||
}
|
||||
#arrowhead {
|
||||
fill: #333;
|
||||
}
|
||||
#crosshead path {
|
||||
fill: #333 !important;
|
||||
stroke: #333 !important;
|
||||
}
|
||||
.messageText {
|
||||
fill: #333;
|
||||
stroke: none;
|
||||
}
|
||||
.labelBox {
|
||||
stroke: #CCCCFF;
|
||||
fill: #ECECFF;
|
||||
}
|
||||
.labelText {
|
||||
fill: black;
|
||||
stroke: none;
|
||||
}
|
||||
.loopText {
|
||||
fill: black;
|
||||
stroke: none;
|
||||
}
|
||||
.loopLine {
|
||||
stroke-width: 2;
|
||||
stroke-dasharray: "2 2";
|
||||
marker-end: "url(#arrowhead)";
|
||||
stroke: #CCCCFF;
|
||||
}
|
||||
.note {
|
||||
stroke: #aaaa33;
|
||||
fill: #fff5ad;
|
||||
}
|
||||
.noteText {
|
||||
fill: black;
|
||||
stroke: none;
|
||||
font-family: 'trebuchet ms', verdana, arial;
|
||||
font-size: 14px;
|
||||
}
|
||||
/** Section styling */
|
||||
.section {
|
||||
stroke: none;
|
||||
opacity: 0.2;
|
||||
}
|
||||
.section0 {
|
||||
fill: rgba(102, 102, 255, 0.49);
|
||||
}
|
||||
.section2 {
|
||||
fill: #fff400;
|
||||
}
|
||||
.section1,
|
||||
.section3 {
|
||||
fill: white;
|
||||
opacity: 0.2;
|
||||
}
|
||||
.sectionTitle0 {
|
||||
fill: #333;
|
||||
}
|
||||
.sectionTitle1 {
|
||||
fill: #333;
|
||||
}
|
||||
.sectionTitle2 {
|
||||
fill: #333;
|
||||
}
|
||||
.sectionTitle3 {
|
||||
fill: #333;
|
||||
}
|
||||
.sectionTitle {
|
||||
text-anchor: start;
|
||||
font-size: 11px;
|
||||
text-height: 14px;
|
||||
}
|
||||
/* Grid and axis */
|
||||
.grid .tick {
|
||||
stroke: lightgrey;
|
||||
opacity: 0.3;
|
||||
shape-rendering: crispEdges;
|
||||
}
|
||||
.grid path {
|
||||
stroke-width: 0;
|
||||
}
|
||||
/* Today line */
|
||||
.today {
|
||||
fill: none;
|
||||
stroke: red;
|
||||
stroke-width: 2px;
|
||||
}
|
||||
/* Task styling */
|
||||
/* Default task */
|
||||
.task {
|
||||
stroke-width: 2;
|
||||
}
|
||||
.taskText {
|
||||
text-anchor: middle;
|
||||
font-size: 11px;
|
||||
}
|
||||
.taskTextOutsideRight {
|
||||
fill: black;
|
||||
text-anchor: start;
|
||||
font-size: 11px;
|
||||
}
|
||||
.taskTextOutsideLeft {
|
||||
fill: black;
|
||||
text-anchor: end;
|
||||
font-size: 11px;
|
||||
}
|
||||
/* Specific task settings for the sections*/
|
||||
.taskText0,
|
||||
.taskText1,
|
||||
.taskText2,
|
||||
.taskText3 {
|
||||
fill: white;
|
||||
}
|
||||
.task0,
|
||||
.task1,
|
||||
.task2,
|
||||
.task3 {
|
||||
fill: #8a90dd;
|
||||
stroke: #534fbc;
|
||||
}
|
||||
.taskTextOutside0,
|
||||
.taskTextOutside2 {
|
||||
fill: black;
|
||||
}
|
||||
.taskTextOutside1,
|
||||
.taskTextOutside3 {
|
||||
fill: black;
|
||||
}
|
||||
/* Active task */
|
||||
.active0,
|
||||
.active1,
|
||||
.active2,
|
||||
.active3 {
|
||||
fill: #bfc7ff;
|
||||
stroke: #534fbc;
|
||||
}
|
||||
.activeText0,
|
||||
.activeText1,
|
||||
.activeText2,
|
||||
.activeText3 {
|
||||
fill: black !important;
|
||||
}
|
||||
/* Completed task */
|
||||
.done0,
|
||||
.done1,
|
||||
.done2,
|
||||
.done3 {
|
||||
stroke: grey;
|
||||
fill: lightgrey;
|
||||
stroke-width: 2;
|
||||
}
|
||||
.doneText0,
|
||||
.doneText1,
|
||||
.doneText2,
|
||||
.doneText3 {
|
||||
fill: black !important;
|
||||
}
|
||||
/* Tasks on the critical line */
|
||||
.crit0,
|
||||
.crit1,
|
||||
.crit2,
|
||||
.crit3 {
|
||||
stroke: #ff8888;
|
||||
fill: red;
|
||||
stroke-width: 2;
|
||||
}
|
||||
.activeCrit0,
|
||||
.activeCrit1,
|
||||
.activeCrit2,
|
||||
.activeCrit3 {
|
||||
stroke: #ff8888;
|
||||
fill: #bfc7ff;
|
||||
stroke-width: 2;
|
||||
}
|
||||
.doneCrit0,
|
||||
.doneCrit1,
|
||||
.doneCrit2,
|
||||
.doneCrit3 {
|
||||
stroke: #ff8888;
|
||||
fill: lightgrey;
|
||||
stroke-width: 2;
|
||||
cursor: pointer;
|
||||
shape-rendering: crispEdges;
|
||||
}
|
||||
.doneCritText0,
|
||||
.doneCritText1,
|
||||
.doneCritText2,
|
||||
.doneCritText3 {
|
||||
fill: black !important;
|
||||
}
|
||||
.activeCritText0,
|
||||
.activeCritText1,
|
||||
.activeCritText2,
|
||||
.activeCritText3 {
|
||||
fill: black !important;
|
||||
}
|
||||
.titleText {
|
||||
text-anchor: middle;
|
||||
font-size: 18px;
|
||||
fill: black;
|
||||
}
|
||||
/*
|
||||
|
||||
|
||||
*/
|
||||
.node text {
|
||||
font-family: 'trebuchet ms', verdana, arial;
|
||||
font-size: 14px;
|
||||
}
|
||||
div.mermaidTooltip {
|
||||
position: absolute;
|
||||
text-align: center;
|
||||
max-width: 200px;
|
||||
padding: 2px;
|
||||
font-family: 'trebuchet ms', verdana, arial;
|
||||
font-size: 12px;
|
||||
background: #ffffde;
|
||||
border: 1px solid #aaaa33;
|
||||
border-radius: 2px;
|
||||
pointer-events: none;
|
||||
z-index: 100;
|
||||
}
|
275
src/utils/mermaid/mermaid.dark.css
Normal file
275
src/utils/mermaid/mermaid.dark.css
Normal file
@ -0,0 +1,275 @@
|
||||
/* Flowchart variables */
|
||||
/* Sequence Diagram variables */
|
||||
/* Gantt chart variables */
|
||||
.mermaid .label {
|
||||
color: #323D47;
|
||||
}
|
||||
.node rect,
|
||||
.node circle,
|
||||
.node ellipse,
|
||||
.node polygon {
|
||||
fill: #BDD5EA;
|
||||
stroke: #81B1DB;
|
||||
stroke-width: 1px;
|
||||
}
|
||||
.edgePath .path {
|
||||
stroke: lightgrey;
|
||||
}
|
||||
.edgeLabel {
|
||||
background-color: #e8e8e8;
|
||||
}
|
||||
.cluster rect {
|
||||
fill: #6D6D65 !important;
|
||||
rx: 4 !important;
|
||||
stroke: rgba(255, 255, 255, 0.25) !important;
|
||||
stroke-width: 1px !important;
|
||||
}
|
||||
.cluster text {
|
||||
fill: #F9FFFE;
|
||||
}
|
||||
.actor {
|
||||
stroke: #81B1DB;
|
||||
fill: #BDD5EA;
|
||||
}
|
||||
text.actor {
|
||||
fill: black;
|
||||
stroke: none;
|
||||
}
|
||||
.actor-line {
|
||||
stroke: lightgrey;
|
||||
}
|
||||
.messageLine0 {
|
||||
stroke-width: 1.5;
|
||||
stroke-dasharray: "2 2";
|
||||
marker-end: "url(#arrowhead)";
|
||||
stroke: lightgrey;
|
||||
}
|
||||
.messageLine1 {
|
||||
stroke-width: 1.5;
|
||||
stroke-dasharray: "2 2";
|
||||
stroke: lightgrey;
|
||||
}
|
||||
#arrowhead {
|
||||
fill: lightgrey !important;
|
||||
}
|
||||
#crosshead path {
|
||||
fill: lightgrey !important;
|
||||
stroke: lightgrey !important;
|
||||
}
|
||||
.messageText {
|
||||
fill: lightgrey;
|
||||
stroke: none;
|
||||
}
|
||||
.labelBox {
|
||||
stroke: #81B1DB;
|
||||
fill: #BDD5EA;
|
||||
}
|
||||
.labelText {
|
||||
fill: #323D47;
|
||||
stroke: none;
|
||||
}
|
||||
.loopText {
|
||||
fill: lightgrey;
|
||||
stroke: none;
|
||||
}
|
||||
.loopLine {
|
||||
stroke-width: 2;
|
||||
stroke-dasharray: "2 2";
|
||||
marker-end: "url(#arrowhead)";
|
||||
stroke: #81B1DB;
|
||||
}
|
||||
.note {
|
||||
stroke: rgba(255, 255, 255, 0.25);
|
||||
fill: #fff5ad;
|
||||
}
|
||||
.noteText {
|
||||
fill: black;
|
||||
stroke: none;
|
||||
font-family: 'trebuchet ms', verdana, arial;
|
||||
font-size: 14px;
|
||||
}
|
||||
/** Section styling */
|
||||
.section {
|
||||
stroke: none;
|
||||
opacity: 0.2;
|
||||
}
|
||||
.section0 {
|
||||
fill: rgba(255, 255, 255, 0.3);
|
||||
}
|
||||
.section2 {
|
||||
fill: #EAE8B9;
|
||||
}
|
||||
.section1,
|
||||
.section3 {
|
||||
fill: white;
|
||||
opacity: 0.2;
|
||||
}
|
||||
.sectionTitle0 {
|
||||
fill: #F9FFFE;
|
||||
}
|
||||
.sectionTitle1 {
|
||||
fill: #F9FFFE;
|
||||
}
|
||||
.sectionTitle2 {
|
||||
fill: #F9FFFE;
|
||||
}
|
||||
.sectionTitle3 {
|
||||
fill: #F9FFFE;
|
||||
}
|
||||
.sectionTitle {
|
||||
text-anchor: start;
|
||||
font-size: 11px;
|
||||
text-height: 14px;
|
||||
}
|
||||
/* Grid and axis */
|
||||
.grid .tick {
|
||||
stroke: rgba(255, 255, 255, 0.3);
|
||||
opacity: 0.3;
|
||||
shape-rendering: crispEdges;
|
||||
}
|
||||
.grid .tick text {
|
||||
fill: lightgrey;
|
||||
opacity: 0.5;
|
||||
}
|
||||
.grid path {
|
||||
stroke-width: 0;
|
||||
}
|
||||
/* Today line */
|
||||
.today {
|
||||
fill: none;
|
||||
stroke: #DB5757;
|
||||
stroke-width: 2px;
|
||||
}
|
||||
/* Task styling */
|
||||
/* Default task */
|
||||
.task {
|
||||
stroke-width: 1;
|
||||
}
|
||||
.taskText {
|
||||
text-anchor: middle;
|
||||
font-size: 11px;
|
||||
}
|
||||
.taskTextOutsideRight {
|
||||
fill: #323D47;
|
||||
text-anchor: start;
|
||||
font-size: 11px;
|
||||
}
|
||||
.taskTextOutsideLeft {
|
||||
fill: #323D47;
|
||||
text-anchor: end;
|
||||
font-size: 11px;
|
||||
}
|
||||
/* Specific task settings for the sections*/
|
||||
.taskText0,
|
||||
.taskText1,
|
||||
.taskText2,
|
||||
.taskText3 {
|
||||
fill: #323D47;
|
||||
}
|
||||
.task0,
|
||||
.task1,
|
||||
.task2,
|
||||
.task3 {
|
||||
fill: #BDD5EA;
|
||||
stroke: rgba(255, 255, 255, 0.5);
|
||||
}
|
||||
.taskTextOutside0,
|
||||
.taskTextOutside2 {
|
||||
fill: lightgrey;
|
||||
}
|
||||
.taskTextOutside1,
|
||||
.taskTextOutside3 {
|
||||
fill: lightgrey;
|
||||
}
|
||||
/* Active task */
|
||||
.active0,
|
||||
.active1,
|
||||
.active2,
|
||||
.active3 {
|
||||
fill: #81B1DB;
|
||||
stroke: rgba(255, 255, 255, 0.5);
|
||||
}
|
||||
.activeText0,
|
||||
.activeText1,
|
||||
.activeText2,
|
||||
.activeText3 {
|
||||
fill: #323D47 !important;
|
||||
}
|
||||
/* Completed task */
|
||||
.done0,
|
||||
.done1,
|
||||
.done2,
|
||||
.done3 {
|
||||
fill: lightgrey;
|
||||
}
|
||||
.doneText0,
|
||||
.doneText1,
|
||||
.doneText2,
|
||||
.doneText3 {
|
||||
fill: #323D47 !important;
|
||||
}
|
||||
/* Tasks on the critical line */
|
||||
.crit0,
|
||||
.crit1,
|
||||
.crit2,
|
||||
.crit3 {
|
||||
stroke: #E83737;
|
||||
fill: #E83737;
|
||||
stroke-width: 2;
|
||||
}
|
||||
.activeCrit0,
|
||||
.activeCrit1,
|
||||
.activeCrit2,
|
||||
.activeCrit3 {
|
||||
stroke: #E83737;
|
||||
fill: #81B1DB;
|
||||
stroke-width: 2;
|
||||
}
|
||||
.doneCrit0,
|
||||
.doneCrit1,
|
||||
.doneCrit2,
|
||||
.doneCrit3 {
|
||||
stroke: #E83737;
|
||||
fill: lightgrey;
|
||||
stroke-width: 1;
|
||||
cursor: pointer;
|
||||
shape-rendering: crispEdges;
|
||||
}
|
||||
.doneCritText0,
|
||||
.doneCritText1,
|
||||
.doneCritText2,
|
||||
.doneCritText3 {
|
||||
fill: lightgrey !important;
|
||||
}
|
||||
.activeCritText0,
|
||||
.activeCritText1,
|
||||
.activeCritText2,
|
||||
.activeCritText3 {
|
||||
fill: #323D47 !important;
|
||||
}
|
||||
.titleText {
|
||||
text-anchor: middle;
|
||||
font-size: 18px;
|
||||
fill: lightgrey;
|
||||
}
|
||||
/*
|
||||
|
||||
|
||||
*/
|
||||
.node text {
|
||||
font-family: 'trebuchet ms', verdana, arial;
|
||||
font-size: 14px;
|
||||
}
|
||||
div.mermaidTooltip {
|
||||
position: absolute;
|
||||
text-align: center;
|
||||
max-width: 200px;
|
||||
padding: 2px;
|
||||
font-family: 'trebuchet ms', verdana, arial;
|
||||
font-size: 12px;
|
||||
background: #6D6D65;
|
||||
border: 1px solid rgba(255, 255, 255, 0.25);
|
||||
border-radius: 2px;
|
||||
pointer-events: none;
|
||||
z-index: 100;
|
||||
}
|
353
src/utils/mermaid/mermaid.forest.css
Normal file
353
src/utils/mermaid/mermaid.forest.css
Normal file
@ -0,0 +1,353 @@
|
||||
/* Flowchart variables */
|
||||
/* Sequence Diagram variables */
|
||||
/* Gantt chart variables */
|
||||
.mermaid .label {
|
||||
font-family: 'trebuchet ms', verdana, arial;
|
||||
color: #333;
|
||||
}
|
||||
.node rect,
|
||||
.node circle,
|
||||
.node ellipse,
|
||||
.node polygon {
|
||||
fill: #cde498;
|
||||
stroke: #13540c;
|
||||
stroke-width: 1px;
|
||||
}
|
||||
.edgePath .path {
|
||||
stroke: green;
|
||||
stroke-width: 1.5px;
|
||||
}
|
||||
.edgeLabel {
|
||||
background-color: #e8e8e8;
|
||||
}
|
||||
.cluster rect {
|
||||
fill: #cdffb2 !important;
|
||||
rx: 4 !important;
|
||||
stroke: #6eaa49 !important;
|
||||
stroke-width: 1px !important;
|
||||
}
|
||||
.cluster text {
|
||||
fill: #333;
|
||||
}
|
||||
.actor {
|
||||
stroke: #13540c;
|
||||
fill: #cde498;
|
||||
}
|
||||
text.actor {
|
||||
fill: black;
|
||||
stroke: none;
|
||||
}
|
||||
.actor-line {
|
||||
stroke: grey;
|
||||
}
|
||||
.messageLine0 {
|
||||
stroke-width: 1.5;
|
||||
stroke-dasharray: "2 2";
|
||||
marker-end: "url(#arrowhead)";
|
||||
stroke: #333;
|
||||
}
|
||||
.messageLine1 {
|
||||
stroke-width: 1.5;
|
||||
stroke-dasharray: "2 2";
|
||||
stroke: #333;
|
||||
}
|
||||
#arrowhead {
|
||||
fill: #333;
|
||||
}
|
||||
#crosshead path {
|
||||
fill: #333 !important;
|
||||
stroke: #333 !important;
|
||||
}
|
||||
.messageText {
|
||||
fill: #333;
|
||||
stroke: none;
|
||||
}
|
||||
.labelBox {
|
||||
stroke: #326932;
|
||||
fill: #cde498;
|
||||
}
|
||||
.labelText {
|
||||
fill: black;
|
||||
stroke: none;
|
||||
}
|
||||
.loopText {
|
||||
fill: black;
|
||||
stroke: none;
|
||||
}
|
||||
.loopLine {
|
||||
stroke-width: 2;
|
||||
stroke-dasharray: "2 2";
|
||||
marker-end: "url(#arrowhead)";
|
||||
stroke: #326932;
|
||||
}
|
||||
.note {
|
||||
stroke: #6eaa49;
|
||||
fill: #fff5ad;
|
||||
}
|
||||
.noteText {
|
||||
fill: black;
|
||||
stroke: none;
|
||||
font-family: 'trebuchet ms', verdana, arial;
|
||||
font-size: 14px;
|
||||
}
|
||||
/** Section styling */
|
||||
.section {
|
||||
stroke: none;
|
||||
opacity: 0.2;
|
||||
}
|
||||
.section0 {
|
||||
fill: #6eaa49;
|
||||
}
|
||||
.section2 {
|
||||
fill: #6eaa49;
|
||||
}
|
||||
.section1,
|
||||
.section3 {
|
||||
fill: white;
|
||||
opacity: 0.2;
|
||||
}
|
||||
.sectionTitle0 {
|
||||
fill: #333;
|
||||
}
|
||||
.sectionTitle1 {
|
||||
fill: #333;
|
||||
}
|
||||
.sectionTitle2 {
|
||||
fill: #333;
|
||||
}
|
||||
.sectionTitle3 {
|
||||
fill: #333;
|
||||
}
|
||||
.sectionTitle {
|
||||
text-anchor: start;
|
||||
font-size: 11px;
|
||||
text-height: 14px;
|
||||
}
|
||||
/* Grid and axis */
|
||||
.grid .tick {
|
||||
stroke: lightgrey;
|
||||
opacity: 0.3;
|
||||
shape-rendering: crispEdges;
|
||||
}
|
||||
.grid path {
|
||||
stroke-width: 0;
|
||||
}
|
||||
/* Today line */
|
||||
.today {
|
||||
fill: none;
|
||||
stroke: red;
|
||||
stroke-width: 2px;
|
||||
}
|
||||
/* Task styling */
|
||||
/* Default task */
|
||||
.task {
|
||||
stroke-width: 2;
|
||||
}
|
||||
.taskText {
|
||||
text-anchor: middle;
|
||||
font-size: 11px;
|
||||
}
|
||||
.taskTextOutsideRight {
|
||||
fill: black;
|
||||
text-anchor: start;
|
||||
font-size: 11px;
|
||||
}
|
||||
.taskTextOutsideLeft {
|
||||
fill: black;
|
||||
text-anchor: end;
|
||||
font-size: 11px;
|
||||
}
|
||||
/* Specific task settings for the sections*/
|
||||
.taskText0,
|
||||
.taskText1,
|
||||
.taskText2,
|
||||
.taskText3 {
|
||||
fill: white;
|
||||
}
|
||||
.task0,
|
||||
.task1,
|
||||
.task2,
|
||||
.task3 {
|
||||
fill: #487e3a;
|
||||
stroke: #13540c;
|
||||
}
|
||||
.taskTextOutside0,
|
||||
.taskTextOutside2 {
|
||||
fill: black;
|
||||
}
|
||||
.taskTextOutside1,
|
||||
.taskTextOutside3 {
|
||||
fill: black;
|
||||
}
|
||||
/* Active task */
|
||||
.active0,
|
||||
.active1,
|
||||
.active2,
|
||||
.active3 {
|
||||
fill: #cde498;
|
||||
stroke: #13540c;
|
||||
}
|
||||
.activeText0,
|
||||
.activeText1,
|
||||
.activeText2,
|
||||
.activeText3 {
|
||||
fill: black !important;
|
||||
}
|
||||
/* Completed task */
|
||||
.done0,
|
||||
.done1,
|
||||
.done2,
|
||||
.done3 {
|
||||
stroke: grey;
|
||||
fill: lightgrey;
|
||||
stroke-width: 2;
|
||||
}
|
||||
.doneText0,
|
||||
.doneText1,
|
||||
.doneText2,
|
||||
.doneText3 {
|
||||
fill: black !important;
|
||||
}
|
||||
/* Tasks on the critical line */
|
||||
.crit0,
|
||||
.crit1,
|
||||
.crit2,
|
||||
.crit3 {
|
||||
stroke: #ff8888;
|
||||
fill: red;
|
||||
stroke-width: 2;
|
||||
}
|
||||
.activeCrit0,
|
||||
.activeCrit1,
|
||||
.activeCrit2,
|
||||
.activeCrit3 {
|
||||
stroke: #ff8888;
|
||||
fill: #cde498;
|
||||
stroke-width: 2;
|
||||
}
|
||||
.doneCrit0,
|
||||
.doneCrit1,
|
||||
.doneCrit2,
|
||||
.doneCrit3 {
|
||||
stroke: #ff8888;
|
||||
fill: lightgrey;
|
||||
stroke-width: 2;
|
||||
cursor: pointer;
|
||||
shape-rendering: crispEdges;
|
||||
}
|
||||
.doneCritText0,
|
||||
.doneCritText1,
|
||||
.doneCritText2,
|
||||
.doneCritText3 {
|
||||
fill: black !important;
|
||||
}
|
||||
.activeCritText0,
|
||||
.activeCritText1,
|
||||
.activeCritText2,
|
||||
.activeCritText3 {
|
||||
fill: black !important;
|
||||
}
|
||||
.titleText {
|
||||
text-anchor: middle;
|
||||
font-size: 18px;
|
||||
fill: black;
|
||||
}
|
||||
/*
|
||||
|
||||
|
||||
*/
|
||||
g.classGroup text {
|
||||
fill: #13540c;
|
||||
stroke: none;
|
||||
font-family: 'trebuchet ms', verdana, arial;
|
||||
font-size: 14px;
|
||||
}
|
||||
g.classGroup rect {
|
||||
fill: #cde498;
|
||||
stroke: #13540c;
|
||||
}
|
||||
g.classGroup line {
|
||||
stroke: #13540c;
|
||||
stroke-width: 1;
|
||||
}
|
||||
svg .classLabel .box {
|
||||
stroke: none;
|
||||
stroke-width: 0;
|
||||
fill: #cde498;
|
||||
opacity: 0.5;
|
||||
}
|
||||
svg .classLabel .label {
|
||||
fill: #13540c;
|
||||
}
|
||||
.relation {
|
||||
stroke: #13540c;
|
||||
stroke-width: 1;
|
||||
fill: none;
|
||||
}
|
||||
.composition {
|
||||
fill: #13540c;
|
||||
stroke: #13540c;
|
||||
stroke-width: 1;
|
||||
}
|
||||
#compositionStart {
|
||||
fill: #13540c;
|
||||
stroke: #13540c;
|
||||
stroke-width: 1;
|
||||
}
|
||||
#compositionEnd {
|
||||
fill: #13540c;
|
||||
stroke: #13540c;
|
||||
stroke-width: 1;
|
||||
}
|
||||
.aggregation {
|
||||
fill: #cde498;
|
||||
stroke: #13540c;
|
||||
stroke-width: 1;
|
||||
}
|
||||
#aggregationStart {
|
||||
fill: #cde498;
|
||||
stroke: #13540c;
|
||||
stroke-width: 1;
|
||||
}
|
||||
#aggregationEnd {
|
||||
fill: #cde498;
|
||||
stroke: #13540c;
|
||||
stroke-width: 1;
|
||||
}
|
||||
#dependencyStart {
|
||||
fill: #13540c;
|
||||
stroke: #13540c;
|
||||
stroke-width: 1;
|
||||
}
|
||||
#dependencyEnd {
|
||||
fill: #13540c;
|
||||
stroke: #13540c;
|
||||
stroke-width: 1;
|
||||
}
|
||||
#extensionStart {
|
||||
fill: #13540c;
|
||||
stroke: #13540c;
|
||||
stroke-width: 1;
|
||||
}
|
||||
#extensionEnd {
|
||||
fill: #13540c;
|
||||
stroke: #13540c;
|
||||
stroke-width: 1;
|
||||
}
|
||||
.node text {
|
||||
font-family: 'trebuchet ms', verdana, arial;
|
||||
font-size: 14px;
|
||||
}
|
||||
div.mermaidTooltip {
|
||||
position: absolute;
|
||||
text-align: center;
|
||||
max-width: 200px;
|
||||
padding: 2px;
|
||||
font-family: 'trebuchet ms', verdana, arial;
|
||||
font-size: 12px;
|
||||
background: #cdffb2;
|
||||
border: 1px solid #6eaa49;
|
||||
border-radius: 2px;
|
||||
pointer-events: none;
|
||||
z-index: 100;
|
||||
}
|
22
src/utils/mermaid/mermaidAPI.min.js
vendored
Normal file
22
src/utils/mermaid/mermaidAPI.min.js
vendored
Normal file
File diff suppressed because one or more lines are too long
@ -82,6 +82,8 @@ void VConfigManager::initialize()
|
||||
"find_incremental_search").toBool();
|
||||
|
||||
m_language = getConfigFromSettings("global", "language").toString();
|
||||
|
||||
m_enableMermaid = getConfigFromSettings("global", "enable_mermaid").toBool();
|
||||
}
|
||||
|
||||
void VConfigManager::readPredefinedColorsFromSettings()
|
||||
|
@ -116,6 +116,9 @@ public:
|
||||
inline QString getLanguage() const;
|
||||
inline void setLanguage(const QString &p_language);
|
||||
|
||||
inline bool getEnableMermaid() const;
|
||||
inline void setEnableMermaid(bool p_enabled);
|
||||
|
||||
private:
|
||||
void updateMarkdownEditStyle();
|
||||
QVariant getConfigFromSettings(const QString §ion, const QString &key);
|
||||
@ -174,6 +177,9 @@ private:
|
||||
// Language
|
||||
QString m_language;
|
||||
|
||||
// Enable Mermaid.
|
||||
bool m_enableMermaid;
|
||||
|
||||
// The name of the config file in each directory
|
||||
static const QString dirConfigFileName;
|
||||
// The name of the default configuration file
|
||||
@ -491,4 +497,18 @@ inline void VConfigManager::setLanguage(const QString &p_language)
|
||||
m_language);
|
||||
}
|
||||
|
||||
inline bool VConfigManager::getEnableMermaid() const
|
||||
{
|
||||
return m_enableMermaid;
|
||||
}
|
||||
|
||||
inline void VConfigManager::setEnableMermaid(bool p_enabled)
|
||||
{
|
||||
if (m_enableMermaid == p_enabled) {
|
||||
return;
|
||||
}
|
||||
m_enableMermaid = p_enabled;
|
||||
setConfigToSettings("global", "enable_mermaid", m_enableMermaid);
|
||||
}
|
||||
|
||||
#endif // VCONFIGMANAGER_H
|
||||
|
@ -280,7 +280,7 @@ void VEditTab::setupMarkdownPreview()
|
||||
switch (mdConverterType) {
|
||||
case MarkdownConverterType::Marked:
|
||||
jsFile = "qrc" + VNote::c_markedJsFile;
|
||||
extraFile = "<script src=\"qrc" + VNote::c_markedExtraFile + "\"></script>";
|
||||
extraFile = "<script src=\"qrc" + VNote::c_markedExtraFile + "\"></script>\n";
|
||||
break;
|
||||
|
||||
case MarkdownConverterType::Hoedown:
|
||||
@ -291,12 +291,19 @@ void VEditTab::setupMarkdownPreview()
|
||||
jsFile = "qrc" + VNote::c_markdownitJsFile;
|
||||
extraFile = "<script src=\"qrc" + VNote::c_markdownitExtraFile + "\"></script>\n" +
|
||||
"<script src=\"qrc" + VNote::c_markdownitAnchorExtraFile + "\"></script>\n" +
|
||||
"<script src=\"qrc" + VNote::c_markdownitTaskListExtraFile + "\"></script>";
|
||||
"<script src=\"qrc" + VNote::c_markdownitTaskListExtraFile + "\"></script>\n";
|
||||
break;
|
||||
|
||||
default:
|
||||
Q_ASSERT(false);
|
||||
}
|
||||
|
||||
if (vconfig.getEnableMermaid()) {
|
||||
extraFile += "<link rel=\"stylesheet\" type=\"text/css\" href=\"qrc" + VNote::c_mermaidCssFile +
|
||||
"\"/>\n" + "<script src=\"qrc" + VNote::c_mermaidApiJsFile + "\"></script>\n" +
|
||||
"<script>var VEnableMermaid = true;</script>\n";
|
||||
}
|
||||
|
||||
QString htmlTemplate = VNote::s_markdownTemplate;
|
||||
htmlTemplate.replace(jsHolder, jsFile);
|
||||
if (!extraFile.isEmpty()) {
|
||||
|
@ -321,6 +321,15 @@ void VMainWindow::initMarkdownMenu()
|
||||
}
|
||||
|
||||
initRenderBackgroundMenu(markdownMenu);
|
||||
|
||||
QAction *mermaidAct = new QAction(tr("&Mermaid Diagram"), this);
|
||||
mermaidAct->setStatusTip(tr("Enable Mermaid for graph and diagram"));
|
||||
mermaidAct->setCheckable(true);
|
||||
connect(mermaidAct, &QAction::triggered,
|
||||
this, &VMainWindow::enableMermaid);
|
||||
markdownMenu->addAction(mermaidAct);
|
||||
|
||||
mermaidAct->setChecked(vconfig.getEnableMermaid());
|
||||
}
|
||||
|
||||
void VMainWindow::initViewMenu()
|
||||
@ -590,6 +599,11 @@ void VMainWindow::changeExpandTab(bool checked)
|
||||
vconfig.setIsExpandTab(checked);
|
||||
}
|
||||
|
||||
void VMainWindow::enableMermaid(bool p_checked)
|
||||
{
|
||||
vconfig.setEnableMermaid(p_checked);
|
||||
}
|
||||
|
||||
void VMainWindow::changeHighlightCursorLine(bool p_checked)
|
||||
{
|
||||
vconfig.setHighlightCursorLine(p_checked);
|
||||
|
@ -61,6 +61,7 @@ private slots:
|
||||
void insertImage();
|
||||
void handleFindDialogTextChanged(const QString &p_text, uint p_options);
|
||||
void openFindDialog();
|
||||
void enableMermaid(bool p_checked);
|
||||
|
||||
protected:
|
||||
void closeEvent(QCloseEvent *event) Q_DECL_OVERRIDE;
|
||||
|
@ -18,6 +18,10 @@ const QString VNote::c_markdownitJsFile = ":/resources/markdown-it.js";
|
||||
const QString VNote::c_markdownitExtraFile = ":/utils/markdown-it/markdown-it.min.js";
|
||||
const QString VNote::c_markdownitAnchorExtraFile = ":/utils/markdown-it/markdown-it-headinganchor.js";
|
||||
const QString VNote::c_markdownitTaskListExtraFile = ":/utils/markdown-it/markdown-it-task-lists.min.js";
|
||||
const QString VNote::c_mermaidApiJsFile = ":/utils/mermaid/mermaidAPI.min.js";
|
||||
const QString VNote::c_mermaidCssFile = ":/utils/mermaid/mermaid.css";
|
||||
const QString VNote::c_mermaidDarkCssFile = ":/utils/mermaid/mermaid.dark.css";
|
||||
const QString VNote::c_mermaidForestCssFile = ":/utils/mermaid/mermaid.forest.css";
|
||||
|
||||
VNote::VNote(QObject *parent)
|
||||
: QObject(parent), m_mainWindow(dynamic_cast<VMainWindow *>(parent))
|
||||
|
@ -40,6 +40,12 @@ public:
|
||||
static const QString c_markdownitAnchorExtraFile;
|
||||
static const QString c_markdownitTaskListExtraFile;
|
||||
|
||||
// Mermaid
|
||||
static const QString c_mermaidApiJsFile;
|
||||
static const QString c_mermaidCssFile;
|
||||
static const QString c_mermaidDarkCssFile;
|
||||
static const QString c_mermaidForestCssFile;
|
||||
|
||||
inline const QVector<QPair<QString, QString> > &getPalette() const;
|
||||
void initPalette(QPalette palette);
|
||||
QString getColorFromPalette(const QString &p_name) const;
|
||||
|
@ -90,5 +90,9 @@
|
||||
<file>utils/markdown-it/markdown-it.min.js</file>
|
||||
<file>utils/markdown-it/markdown-it-headinganchor.js</file>
|
||||
<file>utils/markdown-it/markdown-it-task-lists.min.js</file>
|
||||
<file>utils/mermaid/mermaid.css</file>
|
||||
<file>utils/mermaid/mermaid.dark.css</file>
|
||||
<file>utils/mermaid/mermaid.forest.css</file>
|
||||
<file>utils/mermaid/mermaidAPI.min.js</file>
|
||||
</qresource>
|
||||
</RCC>
|
||||
|
Loading…
x
Reference in New Issue
Block a user