浏览代码

support flowchart.js

VNote supports flowchart.js in all for renderers.
Le Tan 8 年之前
父节点
当前提交
f911c60c79

+ 1 - 0
README.md

@@ -314,6 +314,7 @@ If you prefer command line on macOS, you could follow these steps.
 - [mermaid 7.0.0](https://github.com/knsv/mermaid) (MIT License)
 - [MathJax](https://www.mathjax.org/) (Apache-2.0)
 - [showdown](https://github.com/showdownjs/showdown) (Unknown)
+- [flowchart.js](https://github.com/adrai/flowchart.js) (MIT License)
 
 # License (代码许可)
 VNote is licensed under the [MIT license](http://opensource.org/licenses/MIT).

+ 10 - 18
src/resources/hoedown.js

@@ -23,29 +23,21 @@ var updateHtml = function(html) {
         if (code.parentElement.tagName.toLowerCase() == 'pre') {
             if (VEnableMermaid && code.classList.contains('language-mermaid')) {
                 // Mermaid code block.
-                mermaidParserErr = false;
-                mermaidIdx++;
-                try {
-                    // Do not increment mermaidIdx here.
-                    var graph = mermaidAPI.render('mermaid-diagram-' + mermaidIdx, code.innerText, function(){});
-                } catch (err) {
-                    content.setLog("err: " + err);
+                if (renderMermaidOne(code)) {
+                    // replaceChild() will decrease codes.length.
+                    --i;
                     continue;
                 }
-                if (mermaidParserErr || typeof graph == "undefined") {
+            } else if (VEnableFlowchart && code.classList.contains('language-flowchart')) {
+                // Flowchart code block.
+                if (renderFlowchartOne(code)) {
+                    // replaceChild() will decrease codes.length.
+                    --i;
                     continue;
                 }
-                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);
             }
+
+            hljs.highlightBlock(code);
         }
     }
 

+ 1 - 0
src/resources/markdown-it.js

@@ -93,6 +93,7 @@ var updateText = function(text) {
     handleToc(needToc);
     insertImageCaption();
     renderMermaid('lang-mermaid');
+    renderFlowchart('lang-flowchart');
 
     // If you add new logics after handling MathJax, please pay attention to
     // finishLoading logic.

+ 92 - 19
src/resources/markdown_template.js

@@ -2,6 +2,7 @@ var content;
 var keyState = 0;
 
 var VMermaidDivClass = 'mermaid-diagram';
+var VFlowchartDivClass = 'flowchart-diagram';
 if (typeof VEnableMermaid == 'undefined') {
     VEnableMermaid = false;
 } else if (VEnableMermaid) {
@@ -10,6 +11,10 @@ if (typeof VEnableMermaid == 'undefined') {
     });
 }
 
+if (typeof VEnableFlowchart == 'undefined') {
+    VEnableFlowchart = false;
+}
+
 if (typeof VEnableMathjax == 'undefined') {
     VEnableMathjax = false;
 }
@@ -199,36 +204,104 @@ var renderMermaid = function(className) {
     if (!VEnableMermaid) {
         return;
     }
+
     var codes = document.getElementsByTagName('code');
     mermaidIdx = 0;
     for (var i = 0; i < codes.length; ++i) {
         var code = codes[i];
         if (code.classList.contains(className)) {
-            // Mermaid code block.
-            mermaidParserErr = false;
-            mermaidIdx++;
-            try {
-                // Do not increment mermaidIdx here.
-                var graph = mermaidAPI.render('mermaid-diagram-' + mermaidIdx, code.innerText, function(){});
-            } catch (err) {
-                content.setLog("err: " + err);
-                continue;
+            if (renderMermaidOne(code)) {
+                // replaceChild() will decrease codes.length.
+                --i;
             }
-            if (mermaidParserErr || typeof graph == "undefined") {
-                continue;
+        }
+    }
+};
+
+// Render @code as Mermaid graph.
+// Returns true if succeeded.
+var renderMermaidOne = function(code) {
+    // Mermaid code block.
+    mermaidParserErr = false;
+    mermaidIdx++;
+    try {
+        // Do not increment mermaidIdx here.
+        var graph = mermaidAPI.render('mermaid-diagram-' + mermaidIdx, code.innerText, function(){});
+    } catch (err) {
+        content.setLog("err: " + err);
+        return false;
+    }
+
+    if (mermaidParserErr || typeof graph == "undefined") {
+        return false;
+    }
+
+    var graphDiv = document.createElement('div');
+    graphDiv.classList.add(VMermaidDivClass);
+    graphDiv.innerHTML = graph;
+    var preNode = code.parentNode;
+    preNode.classList.add(VMermaidDivClass);
+    preNode.replaceChild(graphDiv, code);
+    return true;
+};
+
+var flowchartIdx = 0;
+
+// @className, the class name of the flowchart code block, such as 'lang-flowchart'.
+var renderFlowchart = function(className) {
+    if (!VEnableFlowchart) {
+        return;
+    }
+
+    var codes = document.getElementsByTagName('code');
+    flowchartIdx = 0;
+    for (var i = 0; i < codes.length; ++i) {
+        var code = codes[i];
+        if (code.classList.contains(className)) {
+            if (renderFlowchartOne(code, flowchartIdx)) {
+                // replaceChild() will decrease codes.length.
+                --i;
             }
-            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;
         }
     }
 };
 
+// Render @code as Flowchart.js graph.
+// Returns true if succeeded.
+var renderFlowchartOne = function(code) {
+    // Flowchart code block.
+    flowchartIdx++;
+    try {
+        var graph = flowchart.parse(code.innerText);
+    } catch (err) {
+        content.setLog("err: " + err);
+        return false;
+    }
+
+    if (typeof graph == "undefined") {
+        return false;
+    }
+
+    var graphDiv = document.createElement('div');
+    graphDiv.id = 'flowchart-diagram-' + flowchartIdx;
+    graphDiv.classList.add(VFlowchartDivClass);
+    var preNode = code.parentNode;
+    preNode.replaceChild(graphDiv, code);
+
+    // Draw on it after adding it to page.
+    try {
+        graph.drawSVG(graphDiv.id);
+    } catch (err) {
+        content.setLog("err: " + err);
+        preNode.replaceChild(code, graphDiv);
+        delete graphDiv;
+        return false;
+    }
+
+    preNode.classList.add(VMermaidDivClass);
+    return true;
+};
+
 var isImageBlock = function(img) {
     var pn = img.parentNode;
     return (pn.children.length == 1) && (pn.innerText == '');

+ 1 - 0
src/resources/marked.js

@@ -48,6 +48,7 @@ var updateText = function(text) {
     handleToc(needToc);
     insertImageCaption();
     renderMermaid('lang-mermaid');
+    renderFlowchart('lang-flowchart');
 
     // If you add new logics after handling MathJax, please pay attention to
     // finishLoading logic.

+ 7 - 3
src/resources/showdown.js

@@ -49,7 +49,7 @@ var mdHasTocSection = function(markdown) {
     return n != -1;
 };
 
-var highlightCodeBlocks = function(doc, enableMermaid) {
+var highlightCodeBlocks = function(doc, enableMermaid, enableFlowchart) {
     var codes = doc.getElementsByTagName('code');
     for (var i = 0; i < codes.length; ++i) {
         var code = codes[i];
@@ -57,6 +57,9 @@ var highlightCodeBlocks = function(doc, enableMermaid) {
             if (enableMermaid && code.classList.contains('language-mermaid')) {
                 // Mermaid code block.
                 continue;
+            } if (enableFlowchart && code.classList.contains('language-flowchart')) {
+                // Flowchart code block.
+                continue;
             } else {
                 hljs.highlightBlock(code);
             }
@@ -70,8 +73,9 @@ var updateText = function(text) {
     placeholder.innerHTML = html;
     handleToc(needToc);
     insertImageCaption();
-    highlightCodeBlocks(document, VEnableMermaid);
+    highlightCodeBlocks(document, VEnableMermaid, VEnableFlowchart);
     renderMermaid('language-mermaid');
+    renderFlowchart('language-flowchart');
 
     // If you add new logics after handling MathJax, please pay attention to
     // finishLoading logic.
@@ -92,7 +96,7 @@ var highlightText = function(text, id, timeStamp) {
 
     var parser = new DOMParser();
     var htmlDoc = parser.parseFromString("<div id=\"showdown-container\">" + html + "</div>", 'text/html');
-    highlightCodeBlocks(htmlDoc, false);
+    highlightCodeBlocks(htmlDoc, false, false);
 
     html = htmlDoc.getElementById('showdown-container').innerHTML;
 

+ 8 - 0
src/resources/styles/default.css

@@ -161,6 +161,14 @@ pre.mermaid-diagram {
     overflow-y: hidden;
 }
 
+div.flowchart-diagram {
+    overflow-y: hidden;
+}
+
+pre.flowchart-diagram {
+    overflow-y: hidden;
+}
+
 .img-package {
     text-align: center;
 }

+ 3 - 0
src/resources/vnote.ini

@@ -20,6 +20,9 @@ markdown_converter=2
 enable_mermaid=false
 enable_mathjax=false
 
+; Enable flowchart.js
+enable_flowchart=false
+
 ; -1 - calculate the factor
 web_zoom_factor=-1
 

+ 6 - 0
src/utils/flowchart.js/README.md

@@ -0,0 +1,6 @@
+# [flowchart.js](https://github.com/adrai/flowchart.js)
+v1.6.6  
+Adriano Raiano
+
+# [Raphael](https://github.com/DmitryBaranovskiy/raphael)
+v2.2.7

文件差异内容过多而无法显示
+ 5 - 0
src/utils/flowchart.js/flowchart.min.js


文件差异内容过多而无法显示
+ 0 - 0
src/utils/flowchart.js/raphael.min.js


+ 5 - 5
src/utils/markdown-it/README.md

@@ -1,13 +1,13 @@
 # [markdown-it](https://github.com/markdown-it/markdown-it)
-v8.3.1
-Alex Kocharin
+v8.3.1  
+Alex Kocharin  
 Vitaly Puzrin
 
 # [markdown-it-headinganchor](https://github.com/adam-p/markdown-it-headinganchor)
-v1.3.0
-Adam Pritchard
+v1.3.0  
+Adam Pritchard  
 Modified by Le Tan
 
 # [markdown-it-task-lists](https://github.com/revin/markdown-it-task-lists)
-v1.4.0
+v1.4.0  
 Revin Guillen

+ 8 - 2
src/utils/vutils.cpp

@@ -529,11 +529,17 @@ QString VUtils::generateHtmlTemplate(MarkdownConverterType p_conType, bool p_exp
     }
 
     if (vconfig.getEnableMermaid()) {
-        extraFile += "<link rel=\"stylesheet\" type=\"text/css\" href=\"qrc" + VNote::c_mermaidCssFile +
-                     "\"/>\n" + "<script src=\"qrc" + VNote::c_mermaidApiJsFile + "\"></script>\n" +
+        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";
     }
 
+    if (vconfig.getEnableFlowchart()) {
+        extraFile += "<script src=\"qrc" + VNote::c_raphaelJsFile + "\"></script>\n" +
+                     "<script src=\"qrc" + VNote::c_flowchartJsFile + "\"></script>\n" +
+                     "<script>var VEnableFlowchart = true;</script>\n";
+    }
+
     if (vconfig.getEnableMathjax()) {
         extraFile += "<script type=\"text/x-mathjax-config\">"
                      "MathJax.Hub.Config({\n"

+ 2 - 0
src/vconfigmanager.cpp

@@ -113,6 +113,8 @@ void VConfigManager::initialize()
 
     m_enableMermaid = getConfigFromSettings("global", "enable_mermaid").toBool();
 
+    m_enableFlowchart = getConfigFromSettings("global", "enable_flowchart").toBool();
+
     m_enableMathjax = getConfigFromSettings("global", "enable_mathjax").toBool();
 
     m_webZoomFactor = getConfigFromSettings("global", "web_zoom_factor").toReal();

+ 21 - 0
src/vconfigmanager.h

@@ -152,6 +152,9 @@ public:
     inline bool getEnableMermaid() const;
     inline void setEnableMermaid(bool p_enabled);
 
+    inline bool getEnableFlowchart() const;
+    inline void setEnableFlowchart(bool p_enabled);
+
     inline bool getEnableMathjax() const;
     inline void setEnableMathjax(bool p_enabled);
 
@@ -303,6 +306,9 @@ private:
     // Enable Mermaid.
     bool m_enableMermaid;
 
+    // Enable flowchart.js.
+    bool m_enableFlowchart;
+
     // Enable Mathjax.
     bool m_enableMathjax;
 
@@ -729,6 +735,21 @@ inline void VConfigManager::setEnableMermaid(bool p_enabled)
     setConfigToSettings("global", "enable_mermaid", m_enableMermaid);
 }
 
+inline bool VConfigManager::getEnableFlowchart() const
+{
+    return m_enableFlowchart;
+}
+
+inline void VConfigManager::setEnableFlowchart(bool p_enabled)
+{
+    if (m_enableFlowchart == p_enabled) {
+        return;
+    }
+
+    m_enableFlowchart = p_enabled;
+    setConfigToSettings("global", "enable_flowchart", m_enableFlowchart);
+}
+
 inline bool VConfigManager::getEnableMathjax() const
 {
     return m_enableMathjax;

+ 10 - 0
src/vmainwindow.cpp

@@ -457,6 +457,16 @@ void VMainWindow::initMarkdownMenu()
 
     mermaidAct->setChecked(vconfig.getEnableMermaid());
 
+    QAction *flowchartAct = new QAction(tr("&Flowchart.js"), this);
+    flowchartAct->setToolTip(tr("Enable Flowchart.js for flowchart diagram"));
+    flowchartAct->setCheckable(true);
+    connect(flowchartAct, &QAction::triggered,
+            this, [this](bool p_enabled){
+                vconfig.setEnableFlowchart(p_enabled);
+            });
+    markdownMenu->addAction(flowchartAct);
+    flowchartAct->setChecked(vconfig.getEnableFlowchart());
+
     QAction *mathjaxAct = new QAction(tr("Math&Jax"), this);
     mathjaxAct->setToolTip(tr("Enable MathJax for math support in Markdown"));
     mathjaxAct->setCheckable(true);

+ 3 - 0
src/vnote.cpp

@@ -40,6 +40,9 @@ 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";
 
+const QString VNote::c_flowchartJsFile = ":/utils/flowchart.js/flowchart.min.js";
+const QString VNote::c_raphaelJsFile = ":/utils/flowchart.js/raphael.min.js";
+
 const QString VNote::c_mathjaxJsFile = "https://cdn.mathjax.org/mathjax/latest/MathJax.js?config=TeX-MML-AM_CHTML";
 
 const QString VNote::c_shortcutsDocFile_en = ":/resources/docs/shortcuts_en.md";

+ 4 - 0
src/vnote.h

@@ -57,6 +57,10 @@ public:
     static const QString c_mermaidDarkCssFile;
     static const QString c_mermaidForestCssFile;
 
+    // flowchart.js
+    static const QString c_flowchartJsFile;
+    static const QString c_raphaelJsFile;
+
     // Mathjax
     static const QString c_mathjaxJsFile;
 

+ 2 - 0
src/vnote.qrc

@@ -109,5 +109,7 @@
         <file>utils/markdown-it/markdown-it-footnote.min.js</file>
         <file>resources/icons/arrow_dropup.svg</file>
         <file>resources/icons/vnote_update.svg</file>
+        <file>utils/flowchart.js/flowchart.min.js</file>
+        <file>utils/flowchart.js/raphael.min.js</file>
     </qresource>
 </RCC>

部分文件因为文件数量过多而无法显示