mirror of
https://gitee.com/vnotex/vnote.git
synced 2025-07-05 13:59:52 +08:00
refine markdown render logics
Add common templates markdown_template.html and markdown_template.js. Hoedow provides hoedown.js. Marked provides marked.js.
This commit is contained in:
parent
ee6fc69bb1
commit
d47dd92f59
41
src/resources/hoedown.js
Normal file
41
src/resources/hoedown.js
Normal file
@ -0,0 +1,41 @@
|
|||||||
|
var placeholder = document.getElementById('placeholder');
|
||||||
|
|
||||||
|
var scrollToAnchor = function(anchor) {
|
||||||
|
var anc = document.getElementById(anchor);
|
||||||
|
if (anc != null) {
|
||||||
|
anc.scrollIntoView();
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
var updateHtml = function(html) {
|
||||||
|
placeholder.innerHTML = html;
|
||||||
|
var codes = document.getElementsByTagName('code');
|
||||||
|
for (var i = 0; i < codes.length; ++i) {
|
||||||
|
if (codes[i].parentElement.tagName.toLowerCase() == 'pre') {
|
||||||
|
hljs.highlightBlock(codes[i]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
var onWindowScroll = function() {
|
||||||
|
var scrollTop = document.documentElement.scrollTop || document.body.scrollTop || window.pageYOffset;
|
||||||
|
var eles = document.querySelectorAll("h1, h2, h3, h4, h5, h6");
|
||||||
|
|
||||||
|
if (eles.length == 0) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
var curIdx = 0;
|
||||||
|
var biaScrollTop = scrollTop + 50;
|
||||||
|
for (var i = 0; i < eles.length; ++i) {
|
||||||
|
if (biaScrollTop >= eles[i].offsetTop) {
|
||||||
|
curIdx = i;
|
||||||
|
} else {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
var curHeader = eles[curIdx].getAttribute("id");
|
||||||
|
if (curHeader != null) {
|
||||||
|
content.setHeader(curHeader);
|
||||||
|
}
|
||||||
|
}
|
19
src/resources/markdown_template.html
Normal file
19
src/resources/markdown_template.html
Normal file
@ -0,0 +1,19 @@
|
|||||||
|
<!doctype html>
|
||||||
|
<html lang="en">
|
||||||
|
<meta charset="utf-8">
|
||||||
|
<head>
|
||||||
|
<style type="text/css">
|
||||||
|
<!-- BACKGROUND_PLACE_HOLDER -->
|
||||||
|
</style>
|
||||||
|
<link rel="stylesheet" type="text/css" href="CSS_PLACE_HOLDER">
|
||||||
|
<link rel="stylesheet" type="text/css" href="qrc:/utils/highlightjs/styles/default.css">
|
||||||
|
<script src="qrc:/resources/qwebchannel.js"></script>
|
||||||
|
<script src="qrc:/utils/highlightjs/highlight.pack.js"></script>
|
||||||
|
<!-- EXTRA_PLACE_HOLDER -->
|
||||||
|
<script src="JS_PLACE_HOLDER" defer></script>
|
||||||
|
<script src="qrc:/resources/markdown_template.js" defer></script>
|
||||||
|
</head>
|
||||||
|
<body>
|
||||||
|
<div id="placeholder"></div>
|
||||||
|
</body>
|
||||||
|
</html>
|
96
src/resources/markdown_template.js
Normal file
96
src/resources/markdown_template.js
Normal file
@ -0,0 +1,96 @@
|
|||||||
|
var content;
|
||||||
|
var keyState = 0;
|
||||||
|
|
||||||
|
new QWebChannel(qt.webChannelTransport,
|
||||||
|
function(channel) {
|
||||||
|
content = channel.objects.content;
|
||||||
|
if (typeof updateHtml == "function") {
|
||||||
|
updateHtml(content.html);
|
||||||
|
content.htmlChanged.connect(updateHtml);
|
||||||
|
}
|
||||||
|
if (typeof updateText == "function") {
|
||||||
|
content.textChanged.connect(updateText);
|
||||||
|
content.updateText();
|
||||||
|
}
|
||||||
|
content.requestScrollToAnchor.connect(scrollToAnchor);
|
||||||
|
});
|
||||||
|
|
||||||
|
window.onscroll = onWindowScroll;
|
||||||
|
|
||||||
|
document.onkeydown = function(e) {
|
||||||
|
e = e || window.event;
|
||||||
|
var key;
|
||||||
|
var shift;
|
||||||
|
var ctrl;
|
||||||
|
if (e.which) {
|
||||||
|
key = e.which;
|
||||||
|
} else {
|
||||||
|
key = e.keyCode;
|
||||||
|
}
|
||||||
|
shift = !!e.shiftKey;
|
||||||
|
ctrl = !!e.ctrlKey;
|
||||||
|
switch (key) {
|
||||||
|
case 74: // J
|
||||||
|
window.scrollBy(0, 100);
|
||||||
|
keyState = 0;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 75: // K
|
||||||
|
window.scrollBy(0, -100);
|
||||||
|
keyState = 0;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 72: // H
|
||||||
|
window.scrollBy(-100, 0);
|
||||||
|
keyState = 0;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 76: // L
|
||||||
|
window.scrollBy(100, 0);
|
||||||
|
keyState = 0;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 71: // G
|
||||||
|
if (shift) {
|
||||||
|
var scrollLeft = document.documentElement.scrollLeft || document.body.scrollLeft || window.pageXOffset;
|
||||||
|
var scrollHeight = document.documentElement.scrollHeight || document.body.scrollHeight;
|
||||||
|
window.scrollTo(scrollLeft, scrollHeight);
|
||||||
|
keyState = 0;
|
||||||
|
break;
|
||||||
|
} else {
|
||||||
|
if (keyState == 0) {
|
||||||
|
keyState = 1;
|
||||||
|
} else if (keyState == 1) {
|
||||||
|
keyState = 0;
|
||||||
|
var scrollLeft = document.documentElement.scrollLeft || document.body.scrollLeft || window.pageXOffset;
|
||||||
|
window.scrollTo(scrollLeft, 0);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
return;
|
||||||
|
|
||||||
|
case 85: // U
|
||||||
|
keyState = 0;
|
||||||
|
if (ctrl) {
|
||||||
|
var clientHeight = document.documentElement.clientHeight;
|
||||||
|
window.scrollBy(0, -clientHeight);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
return;
|
||||||
|
|
||||||
|
case 68: // D
|
||||||
|
keyState = 0;
|
||||||
|
if (ctrl) {
|
||||||
|
var clientHeight = document.documentElement.clientHeight;
|
||||||
|
window.scrollBy(0, clientHeight);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
return;
|
||||||
|
|
||||||
|
default:
|
||||||
|
content.keyPressEvent(key);
|
||||||
|
keyState = 0;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
e.preventDefault();
|
||||||
|
}
|
154
src/resources/marked.js
Normal file
154
src/resources/marked.js
Normal file
@ -0,0 +1,154 @@
|
|||||||
|
var placeholder = document.getElementById('placeholder');
|
||||||
|
var renderer = new marked.Renderer();
|
||||||
|
var toc = []; // Table of contents as a list
|
||||||
|
var nameCounter = 0;
|
||||||
|
|
||||||
|
renderer.heading = function(text, level) {
|
||||||
|
// Use number to avoid issues with Chinese
|
||||||
|
var escapedText = 'toc_' + nameCounter++;
|
||||||
|
toc.push({
|
||||||
|
level: level,
|
||||||
|
anchor: escapedText,
|
||||||
|
title: text
|
||||||
|
});
|
||||||
|
return '<h' + level + ' id="' + escapedText + '">' + text + '</h' + level + '>';
|
||||||
|
};
|
||||||
|
|
||||||
|
// Highlight.js to highlight code block
|
||||||
|
marked.setOptions({
|
||||||
|
highlight: function(code) {
|
||||||
|
return hljs.highlightAuto(code).value;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
var markdownToHtml = function(markdown, needToc) {
|
||||||
|
toc = [];
|
||||||
|
var html = marked(markdown, { renderer: renderer });
|
||||||
|
nameCounter = 0;
|
||||||
|
if (needToc) {
|
||||||
|
return html.replace(/<p>\[TOC\]<\/p>/ig, '<div class="vnote-toc"></div>');
|
||||||
|
} else {
|
||||||
|
return html;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
// Handle wrong title levels, such as '#' followed by '###'
|
||||||
|
var toPerfectToc = function(toc) {
|
||||||
|
var i;
|
||||||
|
var curLevel = 1;
|
||||||
|
var perfToc = [];
|
||||||
|
for (i in toc) {
|
||||||
|
var item = toc[i];
|
||||||
|
while (item.level > curLevel + 1) {
|
||||||
|
curLevel += 1;
|
||||||
|
var tmp = { level: curLevel,
|
||||||
|
anchor: item.anchor,
|
||||||
|
title: '[EMPTY]'
|
||||||
|
};
|
||||||
|
perfToc.push(tmp);
|
||||||
|
}
|
||||||
|
perfToc.push(item);
|
||||||
|
curLevel = item.level;
|
||||||
|
}
|
||||||
|
return perfToc;
|
||||||
|
};
|
||||||
|
|
||||||
|
var itemToHtml = function(item) {
|
||||||
|
return '<a href="#' + item.anchor + '">' + item.title + '</a>';
|
||||||
|
};
|
||||||
|
|
||||||
|
// Turn a perfect toc to a tree using <ul>
|
||||||
|
var tocToTree = function(toc) {
|
||||||
|
var i;
|
||||||
|
var front = '<li>';
|
||||||
|
var ending = ['</li>'];
|
||||||
|
var curLevel = 1;
|
||||||
|
for (i in toc) {
|
||||||
|
var item = toc[i];
|
||||||
|
if (item.level == curLevel) {
|
||||||
|
front += '</li>';
|
||||||
|
front += '<li>';
|
||||||
|
front += itemToHtml(item);
|
||||||
|
} else if (item.level > curLevel) {
|
||||||
|
// assert(item.level - curLevel == 1)
|
||||||
|
front += '<ul>';
|
||||||
|
ending.push('</ul>');
|
||||||
|
front += '<li>';
|
||||||
|
front += itemToHtml(item);
|
||||||
|
ending.push('</li>');
|
||||||
|
curLevel = item.level;
|
||||||
|
} else {
|
||||||
|
while (item.level < curLevel) {
|
||||||
|
var ele = ending.pop();
|
||||||
|
front += ele;
|
||||||
|
if (ele == '</ul>') {
|
||||||
|
curLevel--;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
front += '</li>';
|
||||||
|
front += '<li>';
|
||||||
|
front += itemToHtml(item);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
while (ending.length > 0) {
|
||||||
|
front += ending.pop();
|
||||||
|
}
|
||||||
|
front = front.replace("<li></li>", "");
|
||||||
|
front = '<ul>' + front + '</ul>';
|
||||||
|
return front;
|
||||||
|
};
|
||||||
|
|
||||||
|
var handleToc = function(needToc) {
|
||||||
|
var tocTree = tocToTree(toPerfectToc(toc));
|
||||||
|
content.setToc(tocTree);
|
||||||
|
|
||||||
|
// Add it to html
|
||||||
|
if (needToc) {
|
||||||
|
var eles = document.getElementsByClassName('vnote-toc');
|
||||||
|
for (var i = 0; i < eles.length; ++i) {
|
||||||
|
eles[i].innerHTML = tocTree;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
var mdHasTocSection = function(markdown) {
|
||||||
|
var n = markdown.search(/(\n|^)\[toc\]/i);
|
||||||
|
return n != -1;
|
||||||
|
};
|
||||||
|
|
||||||
|
var updateText = function(text) {
|
||||||
|
var needToc = mdHasTocSection(text);
|
||||||
|
var html = markdownToHtml(text, needToc);
|
||||||
|
placeholder.innerHTML = html;
|
||||||
|
handleToc(needToc);
|
||||||
|
};
|
||||||
|
|
||||||
|
var scrollToAnchor = function(anchor) {
|
||||||
|
var anc = document.getElementById(anchor);
|
||||||
|
if (anc != null) {
|
||||||
|
anc.scrollIntoView();
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
var onWindowScroll = function() {
|
||||||
|
var scrollTop = document.documentElement.scrollTop || document.body.scrollTop || window.pageYOffset;
|
||||||
|
var eles = document.querySelectorAll("h1, h2, h3, h4, h5, h6");
|
||||||
|
|
||||||
|
if (eles.length == 0) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
var curIdx = 0;
|
||||||
|
var biaScrollTop = scrollTop + 50;
|
||||||
|
for (var i = 0; i < eles.length; ++i) {
|
||||||
|
if (biaScrollTop >= eles[i].offsetTop) {
|
||||||
|
curIdx = i;
|
||||||
|
} else {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
var curHeader = eles[curIdx].getAttribute("id");
|
||||||
|
if (curHeader != null) {
|
||||||
|
content.setHeader(curHeader);
|
||||||
|
}
|
||||||
|
}
|
@ -1,2 +0,0 @@
|
|||||||
</body>
|
|
||||||
</html>
|
|
@ -1,145 +0,0 @@
|
|||||||
<!doctype html>
|
|
||||||
<html lang="en">
|
|
||||||
<meta charset="utf-8">
|
|
||||||
<head>
|
|
||||||
<style type="text/css">
|
|
||||||
<!-- BACKGROUND_PLACE_HOLDER -->
|
|
||||||
</style>
|
|
||||||
<link rel="stylesheet" type="text/css" href="CSS_PLACE_HOLDER">
|
|
||||||
<link rel="stylesheet" type="text/css" href="qrc:/utils/highlightjs/styles/default.css">
|
|
||||||
<script src="qrc:/resources/qwebchannel.js"></script>
|
|
||||||
<script src="qrc:/utils/highlightjs/highlight.pack.js"></script>
|
|
||||||
</head>
|
|
||||||
<body>
|
|
||||||
<div id="placeholder"></div>
|
|
||||||
<script>
|
|
||||||
'use strict';
|
|
||||||
var placeholder = document.getElementById('placeholder');
|
|
||||||
var content;
|
|
||||||
var keyState = 0;
|
|
||||||
|
|
||||||
var scrollToAnchor = function(anchor) {
|
|
||||||
document.getElementById(anchor).scrollIntoView();
|
|
||||||
};
|
|
||||||
|
|
||||||
var updateHtml = function(html) {
|
|
||||||
placeholder.innerHTML = html;
|
|
||||||
|
|
||||||
var codes = document.getElementsByTagName('code');
|
|
||||||
for (var i = 0; i < codes.length; ++i) {
|
|
||||||
if (codes[i].parentElement.tagName.toLowerCase() == 'pre') {
|
|
||||||
hljs.highlightBlock(codes[i]);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
new QWebChannel(qt.webChannelTransport,
|
|
||||||
function(channel) {
|
|
||||||
content = channel.objects.content;
|
|
||||||
updateHtml(content.html);
|
|
||||||
content.htmlChanged.connect(updateHtml);
|
|
||||||
content.requestScrollToAnchor.connect(scrollToAnchor);
|
|
||||||
}
|
|
||||||
);
|
|
||||||
|
|
||||||
window.onscroll = function() {
|
|
||||||
var scrollTop = document.documentElement.scrollTop || document.body.scrollTop || window.pageYOffset;
|
|
||||||
var eles = document.querySelectorAll("h1, h2, h3, h4, h5, h6");
|
|
||||||
|
|
||||||
if (eles.length == 0) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
var curIdx = 0;
|
|
||||||
var biaScrollTop = scrollTop + 50;
|
|
||||||
for (var i = 0; i < eles.length; ++i) {
|
|
||||||
if (biaScrollTop >= eles[i].offsetTop) {
|
|
||||||
curIdx = i;
|
|
||||||
} else {
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
var curHeader = eles[curIdx].getAttribute("id");
|
|
||||||
if (curHeader != null) {
|
|
||||||
content.setHeader(curHeader);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
document.onkeydown = function(e) {
|
|
||||||
e = e || window.event;
|
|
||||||
var key;
|
|
||||||
var shift;
|
|
||||||
var ctrl;
|
|
||||||
if (e.which) {
|
|
||||||
key = e.which;
|
|
||||||
} else {
|
|
||||||
key = e.keyCode;
|
|
||||||
}
|
|
||||||
shift = !!e.shiftKey;
|
|
||||||
ctrl = !!e.ctrlKey;
|
|
||||||
switch (key) {
|
|
||||||
case 74: // J
|
|
||||||
window.scrollBy(0, 100);
|
|
||||||
keyState = 0;
|
|
||||||
break;
|
|
||||||
|
|
||||||
case 75: // K
|
|
||||||
window.scrollBy(0, -100);
|
|
||||||
keyState = 0;
|
|
||||||
break;
|
|
||||||
|
|
||||||
case 72: // H
|
|
||||||
window.scrollBy(-100, 0);
|
|
||||||
keyState = 0;
|
|
||||||
break;
|
|
||||||
|
|
||||||
case 76: // L
|
|
||||||
window.scrollBy(100, 0);
|
|
||||||
keyState = 0;
|
|
||||||
break;
|
|
||||||
|
|
||||||
case 71: // G
|
|
||||||
if (shift) {
|
|
||||||
var scrollLeft = document.documentElement.scrollLeft || document.body.scrollLeft || window.pageXOffset;
|
|
||||||
var scrollHeight = document.documentElement.scrollHeight || document.body.scrollHeight;
|
|
||||||
window.scrollTo(scrollLeft, scrollHeight);
|
|
||||||
keyState = 0;
|
|
||||||
break;
|
|
||||||
} else {
|
|
||||||
if (keyState == 0) {
|
|
||||||
keyState = 1;
|
|
||||||
} else if (keyState == 1) {
|
|
||||||
keyState = 0;
|
|
||||||
var scrollLeft = document.documentElement.scrollLeft || document.body.scrollLeft || window.pageXOffset;
|
|
||||||
window.scrollTo(scrollLeft, 0);
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
return;
|
|
||||||
|
|
||||||
case 85: // U
|
|
||||||
keyState = 0;
|
|
||||||
if (ctrl) {
|
|
||||||
var clientHeight = document.documentElement.clientHeight;
|
|
||||||
window.scrollBy(0, -clientHeight);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
return;
|
|
||||||
|
|
||||||
case 68: // D
|
|
||||||
keyState = 0;
|
|
||||||
if (ctrl) {
|
|
||||||
var clientHeight = document.documentElement.clientHeight;
|
|
||||||
window.scrollBy(0, clientHeight);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
return;
|
|
||||||
|
|
||||||
default:
|
|
||||||
content.keyPressEvent(key);
|
|
||||||
keyState = 0;
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
e.preventDefault();
|
|
||||||
}
|
|
||||||
</script>
|
|
@ -1,267 +0,0 @@
|
|||||||
<!doctype html>
|
|
||||||
<html lang="en">
|
|
||||||
<meta charset="utf-8">
|
|
||||||
<head>
|
|
||||||
<style type="text/css">
|
|
||||||
<!-- BACKGROUND_PLACE_HOLDER -->
|
|
||||||
</style>
|
|
||||||
<link rel="stylesheet" type="text/css" href="CSS_PLACE_HOLDER">
|
|
||||||
<link rel="stylesheet" type="text/css" href="qrc:/utils/highlightjs/styles/default.css">
|
|
||||||
<script src="qrc:/utils/marked/marked.min.js"></script>
|
|
||||||
<script src="qrc:/resources/qwebchannel.js"></script>
|
|
||||||
<script src="qrc:/utils/highlightjs/highlight.pack.js"></script>
|
|
||||||
</head>
|
|
||||||
<body>
|
|
||||||
<div id="placeholder"></div>
|
|
||||||
<script>
|
|
||||||
'use strict';
|
|
||||||
|
|
||||||
var placeholder = document.getElementById('placeholder');
|
|
||||||
var renderer = new marked.Renderer();
|
|
||||||
var toc = []; // Table of contents as a list
|
|
||||||
var content; // Channel variable with content
|
|
||||||
var nameCounter = 0;
|
|
||||||
var keyState = 0;
|
|
||||||
|
|
||||||
renderer.heading = function (text, level) {
|
|
||||||
// Use number to avoid issues with Chinese
|
|
||||||
var escapedText = 'toc_' + nameCounter++;
|
|
||||||
toc.push({
|
|
||||||
level: level,
|
|
||||||
anchor: escapedText,
|
|
||||||
title: text
|
|
||||||
});
|
|
||||||
return '<h' + level + ' id="' +
|
|
||||||
escapedText + '">' +
|
|
||||||
text + '</h' + level + '>';
|
|
||||||
};
|
|
||||||
|
|
||||||
// Highlight.js to highlight code block
|
|
||||||
marked.setOptions({
|
|
||||||
highlight: function (code) {
|
|
||||||
return hljs.highlightAuto(code).value;
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
var markdownToHtml = function (markdown, needToc) {
|
|
||||||
toc = [];
|
|
||||||
var html = marked(markdown, { renderer: renderer });
|
|
||||||
nameCounter = 0;
|
|
||||||
if (needToc) {
|
|
||||||
return html.replace(/<p>\[TOC\]<\/p>/ig, '<div class="vnote-toc"></div>');
|
|
||||||
} else {
|
|
||||||
return html;
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
// Handle wrong title levels, such as '#' followed by '###'
|
|
||||||
var toPerfectToc = function (toc) {
|
|
||||||
var i;
|
|
||||||
var curLevel = 1;
|
|
||||||
var perfToc = [];
|
|
||||||
for (i in toc) {
|
|
||||||
var item = toc[i];
|
|
||||||
while (item.level > curLevel + 1) {
|
|
||||||
curLevel += 1;
|
|
||||||
var tmp = { level: curLevel,
|
|
||||||
anchor: item.anchor,
|
|
||||||
title: '[EMPTY]'
|
|
||||||
};
|
|
||||||
perfToc.push(tmp);
|
|
||||||
}
|
|
||||||
perfToc.push(item);
|
|
||||||
curLevel = item.level;
|
|
||||||
}
|
|
||||||
return perfToc;
|
|
||||||
};
|
|
||||||
|
|
||||||
var itemToHtml = function (item) {
|
|
||||||
return '<a href="#' + item.anchor + '">' + item.title + '</a>';
|
|
||||||
};
|
|
||||||
|
|
||||||
// Turn a perfect toc to a tree using <ul>
|
|
||||||
var tocToTree = function (toc) {
|
|
||||||
var i;
|
|
||||||
var front = '<li>';
|
|
||||||
var ending = ['</li>'];
|
|
||||||
var curLevel = 1;
|
|
||||||
for (i in toc) {
|
|
||||||
var item = toc[i];
|
|
||||||
if (item.level == curLevel) {
|
|
||||||
front += '</li>';
|
|
||||||
front += '<li>';
|
|
||||||
front += itemToHtml(item);
|
|
||||||
} else if (item.level > curLevel) {
|
|
||||||
// assert(item.level - curLevel == 1)
|
|
||||||
front += '<ul>';
|
|
||||||
ending.push('</ul>');
|
|
||||||
front += '<li>';
|
|
||||||
front += itemToHtml(item);
|
|
||||||
ending.push('</li>');
|
|
||||||
curLevel = item.level;
|
|
||||||
} else {
|
|
||||||
while (item.level < curLevel) {
|
|
||||||
var ele = ending.pop();
|
|
||||||
front += ele;
|
|
||||||
if (ele == '</ul>') {
|
|
||||||
curLevel--;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
front += '</li>';
|
|
||||||
front += '<li>';
|
|
||||||
front += itemToHtml(item);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
while (ending.length > 0) {
|
|
||||||
front += ending.pop();
|
|
||||||
}
|
|
||||||
front = front.replace("<li></li>", "");
|
|
||||||
front = '<ul>' + front + '</ul>';
|
|
||||||
return front;
|
|
||||||
};
|
|
||||||
|
|
||||||
var handleToc = function(needToc) {
|
|
||||||
var tocTree = tocToTree(toPerfectToc(toc));
|
|
||||||
content.setToc(tocTree);
|
|
||||||
|
|
||||||
// Add it to html
|
|
||||||
if (needToc) {
|
|
||||||
var eles = document.getElementsByClassName('vnote-toc');
|
|
||||||
for (var i = 0; i < eles.length; ++i) {
|
|
||||||
eles[i].innerHTML = tocTree;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
var mdHasTocSection = function(markdown) {
|
|
||||||
var n = markdown.search(/(\n|^)\[toc\]/i);
|
|
||||||
return n != -1;
|
|
||||||
};
|
|
||||||
|
|
||||||
var updateText = function(text) {
|
|
||||||
var needToc = mdHasTocSection(text);
|
|
||||||
var html = markdownToHtml(text, needToc);
|
|
||||||
placeholder.innerHTML = html;
|
|
||||||
|
|
||||||
handleToc(needToc);
|
|
||||||
};
|
|
||||||
|
|
||||||
var scrollToAnchor = function(anchor) {
|
|
||||||
document.getElementById(anchor).scrollIntoView();
|
|
||||||
};
|
|
||||||
|
|
||||||
new QWebChannel(qt.webChannelTransport,
|
|
||||||
function(channel) {
|
|
||||||
content = channel.objects.content;
|
|
||||||
updateText(content.text);
|
|
||||||
content.textChanged.connect(updateText);
|
|
||||||
content.requestScrollToAnchor.connect(scrollToAnchor);
|
|
||||||
}
|
|
||||||
);
|
|
||||||
|
|
||||||
window.onscroll = function() {
|
|
||||||
var scrollTop = document.documentElement.scrollTop || document.body.scrollTop || window.pageYOffset;
|
|
||||||
var eles = document.querySelectorAll("h1, h2, h3, h4, h5, h6");
|
|
||||||
|
|
||||||
if (eles.length == 0) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
var curIdx = 0;
|
|
||||||
var biaScrollTop = scrollTop + 50;
|
|
||||||
for (var i = 0; i < eles.length; ++i) {
|
|
||||||
if (biaScrollTop >= eles[i].offsetTop) {
|
|
||||||
curIdx = i;
|
|
||||||
} else {
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
var curHeader = eles[curIdx].getAttribute("id");
|
|
||||||
if (curHeader != null) {
|
|
||||||
content.setHeader(curHeader);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
document.onkeydown = function(e) {
|
|
||||||
e = e || window.event;
|
|
||||||
var key;
|
|
||||||
var shift;
|
|
||||||
var ctrl;
|
|
||||||
if (e.which) {
|
|
||||||
key = e.which;
|
|
||||||
} else {
|
|
||||||
key = e.keyCode;
|
|
||||||
}
|
|
||||||
shift = !!e.shiftKey;
|
|
||||||
ctrl = !!e.ctrlKey;
|
|
||||||
switch (key) {
|
|
||||||
case 74: // J
|
|
||||||
window.scrollBy(0, 100);
|
|
||||||
keyState = 0;
|
|
||||||
break;
|
|
||||||
|
|
||||||
case 75: // K
|
|
||||||
window.scrollBy(0, -100);
|
|
||||||
keyState = 0;
|
|
||||||
break;
|
|
||||||
|
|
||||||
case 72: // H
|
|
||||||
window.scrollBy(-100, 0);
|
|
||||||
keyState = 0;
|
|
||||||
break;
|
|
||||||
|
|
||||||
case 76: // L
|
|
||||||
window.scrollBy(100, 0);
|
|
||||||
keyState = 0;
|
|
||||||
break;
|
|
||||||
|
|
||||||
case 71: // G
|
|
||||||
if (shift) {
|
|
||||||
var scrollLeft = document.documentElement.scrollLeft || document.body.scrollLeft || window.pageXOffset;
|
|
||||||
var scrollHeight = document.documentElement.scrollHeight || document.body.scrollHeight;
|
|
||||||
window.scrollTo(scrollLeft, scrollHeight);
|
|
||||||
keyState = 0;
|
|
||||||
break;
|
|
||||||
} else {
|
|
||||||
if (keyState == 0) {
|
|
||||||
keyState = 1;
|
|
||||||
} else if (keyState == 1) {
|
|
||||||
keyState = 0;
|
|
||||||
var scrollLeft = document.documentElement.scrollLeft || document.body.scrollLeft || window.pageXOffset;
|
|
||||||
window.scrollTo(scrollLeft, 0);
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
return;
|
|
||||||
|
|
||||||
case 85: // U
|
|
||||||
keyState = 0;
|
|
||||||
if (ctrl) {
|
|
||||||
var clientHeight = document.documentElement.clientHeight;
|
|
||||||
window.scrollBy(0, -clientHeight);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
return;
|
|
||||||
|
|
||||||
case 68: // D
|
|
||||||
keyState = 0;
|
|
||||||
if (ctrl) {
|
|
||||||
var clientHeight = document.documentElement.clientHeight;
|
|
||||||
window.scrollBy(0, clientHeight);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
return;
|
|
||||||
|
|
||||||
default:
|
|
||||||
content.keyPressEvent(key);
|
|
||||||
keyState = 0;
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
e.preventDefault();
|
|
||||||
}
|
|
||||||
</script>
|
|
||||||
</body>
|
|
||||||
</html>
|
|
||||||
|
|
||||||
|
|
||||||
|
|
@ -1,8 +1,5 @@
|
|||||||
[global]
|
[global]
|
||||||
welcome_page_path=:/resources/welcome.html
|
welcome_page_path=:/resources/welcome.html
|
||||||
template_path=:/resources/template.html
|
|
||||||
pre_template_path=:/resources/pre_template.html
|
|
||||||
post_template_path=:/resources/post_template.html
|
|
||||||
template_css_url=qrc:/resources/markdown.css
|
template_css_url=qrc:/resources/markdown.css
|
||||||
current_notebook=0
|
current_notebook=0
|
||||||
tab_stop_width=4
|
tab_stop_width=4
|
||||||
|
@ -43,9 +43,6 @@ void VConfigManager::initialize()
|
|||||||
baseEditPalette = QTextEdit().palette();
|
baseEditPalette = QTextEdit().palette();
|
||||||
|
|
||||||
welcomePagePath = getConfigFromSettings("global", "welcome_page_path").toString();
|
welcomePagePath = getConfigFromSettings("global", "welcome_page_path").toString();
|
||||||
templatePath = getConfigFromSettings("global", "template_path").toString();
|
|
||||||
preTemplatePath = getConfigFromSettings("global", "pre_template_path").toString();
|
|
||||||
postTemplatePath = getConfigFromSettings("global", "post_template_path").toString();
|
|
||||||
templateCssUrl = getConfigFromSettings("global", "template_css_url").toString();
|
templateCssUrl = getConfigFromSettings("global", "template_css_url").toString();
|
||||||
curNotebookIndex = getConfigFromSettings("global", "current_notebook").toInt();
|
curNotebookIndex = getConfigFromSettings("global", "current_notebook").toInt();
|
||||||
|
|
||||||
|
@ -51,8 +51,6 @@ public:
|
|||||||
|
|
||||||
inline QString getWelcomePagePath() const;
|
inline QString getWelcomePagePath() const;
|
||||||
|
|
||||||
inline QString getTemplatePath() const;
|
|
||||||
|
|
||||||
inline QString getTemplateCssUrl() const;
|
inline QString getTemplateCssUrl() const;
|
||||||
|
|
||||||
inline QFont getBaseEditFont() const;
|
inline QFont getBaseEditFont() const;
|
||||||
@ -68,9 +66,6 @@ public:
|
|||||||
inline MarkdownConverterType getMdConverterType() const;
|
inline MarkdownConverterType getMdConverterType() const;
|
||||||
inline void setMarkdownConverterType(MarkdownConverterType type);
|
inline void setMarkdownConverterType(MarkdownConverterType type);
|
||||||
|
|
||||||
inline QString getPreTemplatePath() const;
|
|
||||||
inline QString getPostTemplatePath() const;
|
|
||||||
|
|
||||||
inline int getTabStopWidth() const;
|
inline int getTabStopWidth() const;
|
||||||
inline void setTabStopWidth(int tabStopWidth);
|
inline void setTabStopWidth(int tabStopWidth);
|
||||||
inline bool getIsExpandTab() const;
|
inline bool getIsExpandTab() const;
|
||||||
@ -137,9 +132,6 @@ private:
|
|||||||
QPalette mdEditPalette;
|
QPalette mdEditPalette;
|
||||||
QVector<HighlightingStyle> mdHighlightingStyles;
|
QVector<HighlightingStyle> mdHighlightingStyles;
|
||||||
QString welcomePagePath;
|
QString welcomePagePath;
|
||||||
QString templatePath;
|
|
||||||
QString preTemplatePath;
|
|
||||||
QString postTemplatePath;
|
|
||||||
QString templateCssUrl;
|
QString templateCssUrl;
|
||||||
int curNotebookIndex;
|
int curNotebookIndex;
|
||||||
|
|
||||||
@ -212,11 +204,6 @@ inline QString VConfigManager::getWelcomePagePath() const
|
|||||||
return welcomePagePath;
|
return welcomePagePath;
|
||||||
}
|
}
|
||||||
|
|
||||||
inline QString VConfigManager::getTemplatePath() const
|
|
||||||
{
|
|
||||||
return templatePath;
|
|
||||||
}
|
|
||||||
|
|
||||||
inline QString VConfigManager::getTemplateCssUrl() const
|
inline QString VConfigManager::getTemplateCssUrl() const
|
||||||
{
|
{
|
||||||
return templateCssUrl;
|
return templateCssUrl;
|
||||||
@ -266,16 +253,6 @@ inline MarkdownConverterType VConfigManager::getMdConverterType() const
|
|||||||
return mdConverterType;
|
return mdConverterType;
|
||||||
}
|
}
|
||||||
|
|
||||||
inline QString VConfigManager::getPreTemplatePath() const
|
|
||||||
{
|
|
||||||
return preTemplatePath;
|
|
||||||
}
|
|
||||||
|
|
||||||
inline QString VConfigManager::getPostTemplatePath() const
|
|
||||||
{
|
|
||||||
return postTemplatePath;
|
|
||||||
}
|
|
||||||
|
|
||||||
inline void VConfigManager::setMarkdownConverterType(MarkdownConverterType type)
|
inline void VConfigManager::setMarkdownConverterType(MarkdownConverterType type)
|
||||||
{
|
{
|
||||||
if (mdConverterType == type) {
|
if (mdConverterType == type) {
|
||||||
|
@ -1,29 +1,15 @@
|
|||||||
#include "vdocument.h"
|
#include "vdocument.h"
|
||||||
|
#include "vfile.h"
|
||||||
#include <QDebug>
|
#include <QDebug>
|
||||||
|
|
||||||
VDocument::VDocument(QObject *parent) : QObject(parent)
|
VDocument::VDocument(const VFile *v_file, QObject *p_parent)
|
||||||
|
: QObject(p_parent), m_file(v_file)
|
||||||
{
|
{
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
VDocument::VDocument(const QString &text, QObject *parent)
|
void VDocument::updateText()
|
||||||
: QObject(parent)
|
|
||||||
{
|
{
|
||||||
m_text = text;
|
emit textChanged(m_file->getContent());
|
||||||
}
|
|
||||||
|
|
||||||
void VDocument::setText(const QString &text)
|
|
||||||
{
|
|
||||||
if (text == m_text) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
m_text = text;
|
|
||||||
emit textChanged(m_text);
|
|
||||||
}
|
|
||||||
|
|
||||||
QString VDocument::getText()
|
|
||||||
{
|
|
||||||
return m_text;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void VDocument::setToc(const QString &toc)
|
void VDocument::setToc(const QString &toc)
|
||||||
|
@ -4,6 +4,8 @@
|
|||||||
#include <QObject>
|
#include <QObject>
|
||||||
#include <QString>
|
#include <QString>
|
||||||
|
|
||||||
|
class VFile;
|
||||||
|
|
||||||
class VDocument : public QObject
|
class VDocument : public QObject
|
||||||
{
|
{
|
||||||
Q_OBJECT
|
Q_OBJECT
|
||||||
@ -12,10 +14,7 @@ class VDocument : public QObject
|
|||||||
Q_PROPERTY(QString html MEMBER m_html NOTIFY htmlChanged)
|
Q_PROPERTY(QString html MEMBER m_html NOTIFY htmlChanged)
|
||||||
|
|
||||||
public:
|
public:
|
||||||
explicit VDocument(QObject *parent = 0);
|
VDocument(const VFile *p_file, QObject *p_parent = 0);
|
||||||
VDocument(const QString &text, QObject *parent = 0);
|
|
||||||
void setText(const QString &text);
|
|
||||||
QString getText();
|
|
||||||
QString getToc();
|
QString getToc();
|
||||||
void scrollToAnchor(const QString &anchor);
|
void scrollToAnchor(const QString &anchor);
|
||||||
void setHtml(const QString &html);
|
void setHtml(const QString &html);
|
||||||
@ -26,6 +25,7 @@ public slots:
|
|||||||
void setHeader(const QString &anchor);
|
void setHeader(const QString &anchor);
|
||||||
void setLog(const QString &p_log);
|
void setLog(const QString &p_log);
|
||||||
void keyPressEvent(int p_key);
|
void keyPressEvent(int p_key);
|
||||||
|
void updateText();
|
||||||
|
|
||||||
signals:
|
signals:
|
||||||
void textChanged(const QString &text);
|
void textChanged(const QString &text);
|
||||||
@ -37,10 +37,16 @@ signals:
|
|||||||
void keyPressed(int p_key);
|
void keyPressed(int p_key);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
QString m_text;
|
|
||||||
QString m_toc;
|
QString m_toc;
|
||||||
QString m_header;
|
QString m_header;
|
||||||
|
|
||||||
|
// m_text does NOT contain actual content.
|
||||||
|
QString m_text;
|
||||||
|
|
||||||
|
// When using Hoedown, m_html will contain the html content.
|
||||||
QString m_html;
|
QString m_html;
|
||||||
|
|
||||||
|
const VFile *m_file;
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif // VDOCUMENT_H
|
#endif // VDOCUMENT_H
|
||||||
|
@ -21,7 +21,7 @@
|
|||||||
extern VConfigManager vconfig;
|
extern VConfigManager vconfig;
|
||||||
|
|
||||||
VEditTab::VEditTab(VFile *p_file, OpenFileMode p_mode, QWidget *p_parent)
|
VEditTab::VEditTab(VFile *p_file, OpenFileMode p_mode, QWidget *p_parent)
|
||||||
: QStackedWidget(p_parent), m_file(p_file), isEditMode(false),
|
: QStackedWidget(p_parent), m_file(p_file), isEditMode(false), document(p_file, this),
|
||||||
mdConverterType(vconfig.getMdConverterType()), m_fileModified(false),
|
mdConverterType(vconfig.getMdConverterType()), m_fileModified(false),
|
||||||
m_editArea(NULL)
|
m_editArea(NULL)
|
||||||
{
|
{
|
||||||
@ -109,7 +109,7 @@ void VEditTab::showFileReadMode()
|
|||||||
break;
|
break;
|
||||||
case DocType::Markdown:
|
case DocType::Markdown:
|
||||||
if (mdConverterType == MarkdownConverterType::Marked) {
|
if (mdConverterType == MarkdownConverterType::Marked) {
|
||||||
document.setText(m_file->getContent());
|
document.updateText();
|
||||||
updateTocFromHtml(document.getToc());
|
updateTocFromHtml(document.getToc());
|
||||||
} else {
|
} else {
|
||||||
previewByConverter();
|
previewByConverter();
|
||||||
@ -140,7 +140,7 @@ void VEditTab::scrollPreviewToHeader(int p_outlineIndex)
|
|||||||
void VEditTab::previewByConverter()
|
void VEditTab::previewByConverter()
|
||||||
{
|
{
|
||||||
VMarkdownConverter mdConverter;
|
VMarkdownConverter mdConverter;
|
||||||
QString &content = m_file->getContent();
|
const QString &content = m_file->getContent();
|
||||||
QString html = mdConverter.generateHtml(content, vconfig.getMarkdownExtensions());
|
QString html = mdConverter.generateHtml(content, vconfig.getMarkdownExtensions());
|
||||||
QRegularExpression tocExp("<p>\\[TOC\\]<\\/p>", QRegularExpression::CaseInsensitiveOption);
|
QRegularExpression tocExp("<p>\\[TOC\\]<\\/p>", QRegularExpression::CaseInsensitiveOption);
|
||||||
QString toc = mdConverter.generateToc(content, vconfig.getMarkdownExtensions());
|
QString toc = mdConverter.generateToc(content, vconfig.getMarkdownExtensions());
|
||||||
@ -259,6 +259,9 @@ bool VEditTab::saveFile()
|
|||||||
|
|
||||||
void VEditTab::setupMarkdownPreview()
|
void VEditTab::setupMarkdownPreview()
|
||||||
{
|
{
|
||||||
|
const QString jsHolder("JS_PLACE_HOLDER");
|
||||||
|
const QString extraHolder("<!-- EXTRA_PLACE_HOLDER -->");
|
||||||
|
|
||||||
webPreviewer = new QWebEngineView(this);
|
webPreviewer = new QWebEngineView(this);
|
||||||
VPreviewPage *page = new VPreviewPage(this);
|
VPreviewPage *page = new VPreviewPage(this);
|
||||||
webPreviewer->setPage(page);
|
webPreviewer->setPage(page);
|
||||||
@ -273,14 +276,26 @@ void VEditTab::setupMarkdownPreview()
|
|||||||
this, &VEditTab::handleWebKeyPressed);
|
this, &VEditTab::handleWebKeyPressed);
|
||||||
page->setWebChannel(channel);
|
page->setWebChannel(channel);
|
||||||
|
|
||||||
if (mdConverterType == MarkdownConverterType::Marked) {
|
QString jsFile, extraFile;
|
||||||
webPreviewer->setHtml(VNote::templateHtml,
|
switch (mdConverterType) {
|
||||||
QUrl::fromLocalFile(m_file->retriveBasePath() + QDir::separator()));
|
case MarkdownConverterType::Marked:
|
||||||
} else {
|
jsFile = "qrc" + VNote::c_markedJsFile;
|
||||||
webPreviewer->setHtml(VNote::preTemplateHtml + VNote::postTemplateHtml,
|
extraFile = "<script src=\"qrc" + VNote::c_markedExtraFile + "\"></script>";
|
||||||
QUrl::fromLocalFile(m_file->retriveBasePath() + QDir::separator()));
|
break;
|
||||||
}
|
|
||||||
|
|
||||||
|
case MarkdownConverterType::Hoedown:
|
||||||
|
jsFile = "qrc" + VNote::c_hoedownJsFile;
|
||||||
|
break;
|
||||||
|
|
||||||
|
default:
|
||||||
|
Q_ASSERT(false);
|
||||||
|
}
|
||||||
|
QString htmlTemplate = VNote::s_markdownTemplate;
|
||||||
|
htmlTemplate.replace(jsHolder, jsFile);
|
||||||
|
if (!extraFile.isEmpty()) {
|
||||||
|
htmlTemplate.replace(extraHolder, extraFile);
|
||||||
|
}
|
||||||
|
webPreviewer->setHtml(htmlTemplate, QUrl::fromLocalFile(m_file->retriveBasePath() + QDir::separator()));
|
||||||
addWidget(webPreviewer);
|
addWidget(webPreviewer);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -25,7 +25,7 @@ public:
|
|||||||
inline VDirectory *getDirectory();
|
inline VDirectory *getDirectory();
|
||||||
inline const VDirectory *getDirectory() const;
|
inline const VDirectory *getDirectory() const;
|
||||||
inline DocType getDocType() const;
|
inline DocType getDocType() const;
|
||||||
inline QString &getContent();
|
inline const QString &getContent() const;
|
||||||
inline void setContent(const QString &p_content);
|
inline void setContent(const QString &p_content);
|
||||||
inline VNotebook *getNotebook();
|
inline VNotebook *getNotebook();
|
||||||
inline QString getNotebookName() const;
|
inline QString getNotebookName() const;
|
||||||
@ -78,7 +78,7 @@ inline DocType VFile::getDocType() const
|
|||||||
return m_docType;
|
return m_docType;
|
||||||
}
|
}
|
||||||
|
|
||||||
inline QString &VFile::getContent()
|
inline const QString &VFile::getContent() const
|
||||||
{
|
{
|
||||||
return m_content;
|
return m_content;
|
||||||
}
|
}
|
||||||
|
@ -85,7 +85,7 @@ void VMdEdit::saveFile()
|
|||||||
|
|
||||||
void VMdEdit::reloadFile()
|
void VMdEdit::reloadFile()
|
||||||
{
|
{
|
||||||
QString &content = m_file->getContent();
|
const QString &content = m_file->getContent();
|
||||||
Q_ASSERT(content.indexOf(QChar::ObjectReplacementCharacter) == -1);
|
Q_ASSERT(content.indexOf(QChar::ObjectReplacementCharacter) == -1);
|
||||||
setPlainText(content);
|
setPlainText(content);
|
||||||
setModified(false);
|
setModified(false);
|
||||||
|
@ -10,9 +10,10 @@
|
|||||||
|
|
||||||
extern VConfigManager vconfig;
|
extern VConfigManager vconfig;
|
||||||
|
|
||||||
QString VNote::templateHtml;
|
QString VNote::s_markdownTemplate;
|
||||||
QString VNote::preTemplateHtml;
|
const QString VNote::c_hoedownJsFile = ":/resources/hoedown.js";
|
||||||
QString VNote::postTemplateHtml;
|
const QString VNote::c_markedJsFile = ":/resources/marked.js";
|
||||||
|
const QString VNote::c_markedExtraFile = ":/utils/marked/marked.min.js";
|
||||||
|
|
||||||
VNote::VNote(QObject *parent)
|
VNote::VNote(QObject *parent)
|
||||||
: QObject(parent), m_mainWindow(dynamic_cast<VMainWindow *>(parent))
|
: QObject(parent), m_mainWindow(dynamic_cast<VMainWindow *>(parent))
|
||||||
@ -83,14 +84,15 @@ QString VNote::getColorFromPalette(const QString &p_name) const
|
|||||||
|
|
||||||
void VNote::initTemplate()
|
void VNote::initTemplate()
|
||||||
{
|
{
|
||||||
if (templateHtml.isEmpty() || preTemplateHtml.isEmpty()
|
if (s_markdownTemplate.isEmpty()) {
|
||||||
|| postTemplateHtml.isEmpty()) {
|
|
||||||
updateTemplate();
|
updateTemplate();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void VNote::updateTemplate()
|
void VNote::updateTemplate()
|
||||||
{
|
{
|
||||||
|
const QString c_markdownTemplatePath(":/resources/markdown_template.html");
|
||||||
|
|
||||||
// Get background color
|
// Get background color
|
||||||
QString rgb;
|
QString rgb;
|
||||||
const QString &curRenderBg = vconfig.getCurRenderBackgroundColor();
|
const QString &curRenderBg = vconfig.getCurRenderBackgroundColor();
|
||||||
@ -109,19 +111,12 @@ void VNote::updateTemplate()
|
|||||||
}
|
}
|
||||||
QString styleHolder("<!-- BACKGROUND_PLACE_HOLDER -->");
|
QString styleHolder("<!-- BACKGROUND_PLACE_HOLDER -->");
|
||||||
QString cssHolder("CSS_PLACE_HOLDER");
|
QString cssHolder("CSS_PLACE_HOLDER");
|
||||||
templateHtml = VUtils::readFileFromDisk(vconfig.getTemplatePath());
|
|
||||||
templateHtml.replace(cssHolder, vconfig.getTemplateCssUrl());
|
|
||||||
if (!cssStyle.isEmpty()) {
|
|
||||||
templateHtml.replace(styleHolder, cssStyle);
|
|
||||||
}
|
|
||||||
|
|
||||||
preTemplateHtml = VUtils::readFileFromDisk(vconfig.getPreTemplatePath());
|
s_markdownTemplate = VUtils::readFileFromDisk(c_markdownTemplatePath);
|
||||||
preTemplateHtml.replace(cssHolder, vconfig.getTemplateCssUrl());
|
s_markdownTemplate.replace(cssHolder, vconfig.getTemplateCssUrl());
|
||||||
if (!cssStyle.isEmpty()) {
|
if (!cssStyle.isEmpty()) {
|
||||||
preTemplateHtml.replace(styleHolder, cssStyle);
|
s_markdownTemplate.replace(styleHolder, cssStyle);
|
||||||
}
|
}
|
||||||
|
|
||||||
postTemplateHtml = VUtils::readFileFromDisk(vconfig.getPostTemplatePath());
|
|
||||||
}
|
}
|
||||||
|
|
||||||
const QVector<VNotebook *> &VNote::getNotebooks() const
|
const QVector<VNotebook *> &VNote::getNotebooks() const
|
||||||
|
10
src/vnote.h
10
src/vnote.h
@ -25,12 +25,10 @@ public:
|
|||||||
|
|
||||||
void initTemplate();
|
void initTemplate();
|
||||||
|
|
||||||
// Used by Marked
|
static QString s_markdownTemplate;
|
||||||
static QString templateHtml;
|
static const QString c_hoedownJsFile;
|
||||||
|
static const QString c_markedJsFile;
|
||||||
// Used by other markdown converter
|
static const QString c_markedExtraFile;
|
||||||
static QString preTemplateHtml;
|
|
||||||
static QString postTemplateHtml;
|
|
||||||
|
|
||||||
inline const QVector<QPair<QString, QString> > &getPalette() const;
|
inline const QVector<QPair<QString, QString> > &getPalette() const;
|
||||||
void initPalette(QPalette palette);
|
void initPalette(QPalette palette);
|
||||||
|
@ -2,11 +2,8 @@
|
|||||||
<qresource prefix="/">
|
<qresource prefix="/">
|
||||||
<file>resources/welcome.html</file>
|
<file>resources/welcome.html</file>
|
||||||
<file>resources/qwebchannel.js</file>
|
<file>resources/qwebchannel.js</file>
|
||||||
<file>resources/template.html</file>
|
|
||||||
<file>resources/markdown.css</file>
|
<file>resources/markdown.css</file>
|
||||||
<file>utils/marked/marked.min.js</file>
|
<file>utils/marked/marked.min.js</file>
|
||||||
<file>resources/post_template.html</file>
|
|
||||||
<file>resources/pre_template.html</file>
|
|
||||||
<file>utils/highlightjs/highlight.pack.js</file>
|
<file>utils/highlightjs/highlight.pack.js</file>
|
||||||
<file>utils/highlightjs/styles/androidstudio.css</file>
|
<file>utils/highlightjs/styles/androidstudio.css</file>
|
||||||
<file>utils/highlightjs/styles/atom-one-dark.css</file>
|
<file>utils/highlightjs/styles/atom-one-dark.css</file>
|
||||||
@ -85,5 +82,9 @@
|
|||||||
<file>resources/icons/find_replace.svg</file>
|
<file>resources/icons/find_replace.svg</file>
|
||||||
<file>resources/icons/search_wrap.svg</file>
|
<file>resources/icons/search_wrap.svg</file>
|
||||||
<file>resources/icons/settings.svg</file>
|
<file>resources/icons/settings.svg</file>
|
||||||
|
<file>resources/markdown_template.html</file>
|
||||||
|
<file>resources/markdown_template.js</file>
|
||||||
|
<file>resources/hoedown.js</file>
|
||||||
|
<file>resources/marked.js</file>
|
||||||
</qresource>
|
</qresource>
|
||||||
</RCC>
|
</RCC>
|
||||||
|
Loading…
x
Reference in New Issue
Block a user