support mermaid diagram

This commit is contained in:
Le Tan 2017-03-21 23:01:22 +08:00
parent bacd112782
commit bed6a0d234
19 changed files with 1044 additions and 4 deletions

View File

@ -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 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-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) - [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 (代码许可) # License (代码许可)
VNote is licensed under the [MIT license](http://opensource.org/licenses/MIT). VNote is licensed under the [MIT license](http://opensource.org/licenses/MIT).

View File

@ -3,9 +3,24 @@ var placeholder = document.getElementById('placeholder');
var updateHtml = function(html) { var updateHtml = function(html) {
placeholder.innerHTML = html; placeholder.innerHTML = html;
var codes = document.getElementsByTagName('code'); var codes = document.getElementsByTagName('code');
var mermaidIdx = 0;
for (var i = 0; i < codes.length; ++i) { for (var i = 0; i < codes.length; ++i) {
if (codes[i].parentElement.tagName.toLowerCase() == 'pre') { var code = codes[i];
hljs.highlightBlock(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);
}
} }
} }
} }

View File

@ -39,6 +39,7 @@ var mdit = window.markdownit({
html: true, html: true,
linkify: true, linkify: true,
typographer: true, typographer: true,
langPrefix: 'lang-',
highlight: function(str, lang) { highlight: function(str, lang) {
if (lang && hljs.getLanguage(lang)) { if (lang && hljs.getLanguage(lang)) {
return hljs.highlight(lang, str).value; return hljs.highlight(lang, str).value;
@ -167,5 +168,6 @@ var updateText = function(text) {
var html = markdownToHtml(text, needToc); var html = markdownToHtml(text, needToc);
placeholder.innerHTML = html; placeholder.innerHTML = html;
handleToc(needToc); handleToc(needToc);
renderMermaid('lang-mermaid');
} }

View File

@ -139,6 +139,12 @@ table tr th :first-child, table tr td :first-child {
table tr th :last-child, table tr td :last-child { table tr th :last-child, table tr td :last-child {
margin-bottom: 0; margin-bottom: 0;
} }
div.mermaid-diagram {
overflow-y: hidden;
}
pre.mermaid-diagram {
overflow-y: hidden;
}
/* Code below this line is copyright Twitter Inc. */ /* Code below this line is copyright Twitter Inc. */

View File

@ -15,6 +15,15 @@ new QWebChannel(qt.webChannelTransport,
content.requestScrollToAnchor.connect(scrollToAnchor); 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 scrollToAnchor = function(anchor) {
var anc = document.getElementById(anchor); var anc = document.getElementById(anchor);
if (anc != null) { if (anc != null) {
@ -122,3 +131,27 @@ document.onkeydown = function(e) {
} }
e.preventDefault(); 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;
}
}
}

View File

@ -121,5 +121,6 @@ var updateText = function(text) {
var html = markdownToHtml(text, needToc); var html = markdownToHtml(text, needToc);
placeholder.innerHTML = html; placeholder.innerHTML = html;
handleToc(needToc); handleToc(needToc);
renderMermaid('lang-mermaid');
}; };

View File

@ -13,6 +13,7 @@ language=System
editor_font_size=12 editor_font_size=12
; 0 - Hoedown, 1 - Marked, 2 - Markdown-it ; 0 - Hoedown, 1 - Marked, 2 - Markdown-it
markdown_converter=2 markdown_converter=2
enable_mermaid=true
[session] [session]
tools_dock_checked=true tools_dock_checked=true

View 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;
}

View 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;
}

View 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

File diff suppressed because one or more lines are too long

View File

@ -82,6 +82,8 @@ void VConfigManager::initialize()
"find_incremental_search").toBool(); "find_incremental_search").toBool();
m_language = getConfigFromSettings("global", "language").toString(); m_language = getConfigFromSettings("global", "language").toString();
m_enableMermaid = getConfigFromSettings("global", "enable_mermaid").toBool();
} }
void VConfigManager::readPredefinedColorsFromSettings() void VConfigManager::readPredefinedColorsFromSettings()

View File

@ -116,6 +116,9 @@ public:
inline QString getLanguage() const; inline QString getLanguage() const;
inline void setLanguage(const QString &p_language); inline void setLanguage(const QString &p_language);
inline bool getEnableMermaid() const;
inline void setEnableMermaid(bool p_enabled);
private: private:
void updateMarkdownEditStyle(); void updateMarkdownEditStyle();
QVariant getConfigFromSettings(const QString &section, const QString &key); QVariant getConfigFromSettings(const QString &section, const QString &key);
@ -174,6 +177,9 @@ private:
// Language // Language
QString m_language; QString m_language;
// Enable Mermaid.
bool m_enableMermaid;
// The name of the config file in each directory // The name of the config file in each directory
static const QString dirConfigFileName; static const QString dirConfigFileName;
// The name of the default configuration file // The name of the default configuration file
@ -491,4 +497,18 @@ inline void VConfigManager::setLanguage(const QString &p_language)
m_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 #endif // VCONFIGMANAGER_H

View File

@ -280,7 +280,7 @@ void VEditTab::setupMarkdownPreview()
switch (mdConverterType) { switch (mdConverterType) {
case MarkdownConverterType::Marked: case MarkdownConverterType::Marked:
jsFile = "qrc" + VNote::c_markedJsFile; jsFile = "qrc" + VNote::c_markedJsFile;
extraFile = "<script src=\"qrc" + VNote::c_markedExtraFile + "\"></script>"; extraFile = "<script src=\"qrc" + VNote::c_markedExtraFile + "\"></script>\n";
break; break;
case MarkdownConverterType::Hoedown: case MarkdownConverterType::Hoedown:
@ -291,12 +291,19 @@ void VEditTab::setupMarkdownPreview()
jsFile = "qrc" + VNote::c_markdownitJsFile; jsFile = "qrc" + VNote::c_markdownitJsFile;
extraFile = "<script src=\"qrc" + VNote::c_markdownitExtraFile + "\"></script>\n" + extraFile = "<script src=\"qrc" + VNote::c_markdownitExtraFile + "\"></script>\n" +
"<script src=\"qrc" + VNote::c_markdownitAnchorExtraFile + "\"></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; break;
default: default:
Q_ASSERT(false); 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; QString htmlTemplate = VNote::s_markdownTemplate;
htmlTemplate.replace(jsHolder, jsFile); htmlTemplate.replace(jsHolder, jsFile);
if (!extraFile.isEmpty()) { if (!extraFile.isEmpty()) {

View File

@ -321,6 +321,15 @@ void VMainWindow::initMarkdownMenu()
} }
initRenderBackgroundMenu(markdownMenu); 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() void VMainWindow::initViewMenu()
@ -590,6 +599,11 @@ void VMainWindow::changeExpandTab(bool checked)
vconfig.setIsExpandTab(checked); vconfig.setIsExpandTab(checked);
} }
void VMainWindow::enableMermaid(bool p_checked)
{
vconfig.setEnableMermaid(p_checked);
}
void VMainWindow::changeHighlightCursorLine(bool p_checked) void VMainWindow::changeHighlightCursorLine(bool p_checked)
{ {
vconfig.setHighlightCursorLine(p_checked); vconfig.setHighlightCursorLine(p_checked);

View File

@ -61,6 +61,7 @@ private slots:
void insertImage(); void insertImage();
void handleFindDialogTextChanged(const QString &p_text, uint p_options); void handleFindDialogTextChanged(const QString &p_text, uint p_options);
void openFindDialog(); void openFindDialog();
void enableMermaid(bool p_checked);
protected: protected:
void closeEvent(QCloseEvent *event) Q_DECL_OVERRIDE; void closeEvent(QCloseEvent *event) Q_DECL_OVERRIDE;

View File

@ -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_markdownitExtraFile = ":/utils/markdown-it/markdown-it.min.js";
const QString VNote::c_markdownitAnchorExtraFile = ":/utils/markdown-it/markdown-it-headinganchor.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_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) VNote::VNote(QObject *parent)
: QObject(parent), m_mainWindow(dynamic_cast<VMainWindow *>(parent)) : QObject(parent), m_mainWindow(dynamic_cast<VMainWindow *>(parent))

View File

@ -40,6 +40,12 @@ public:
static const QString c_markdownitAnchorExtraFile; static const QString c_markdownitAnchorExtraFile;
static const QString c_markdownitTaskListExtraFile; 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; inline const QVector<QPair<QString, QString> > &getPalette() const;
void initPalette(QPalette palette); void initPalette(QPalette palette);
QString getColorFromPalette(const QString &p_name) const; QString getColorFromPalette(const QString &p_name) const;

View File

@ -90,5 +90,9 @@
<file>utils/markdown-it/markdown-it.min.js</file> <file>utils/markdown-it/markdown-it.min.js</file>
<file>utils/markdown-it/markdown-it-headinganchor.js</file> <file>utils/markdown-it/markdown-it-headinganchor.js</file>
<file>utils/markdown-it/markdown-it-task-lists.min.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> </qresource>
</RCC> </RCC>