|
|
@@ -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>
|
|
|
-
|
|
|
-
|
|
|
-
|