RibbonMarkDownView: improve performance and add mermaid support.

This commit is contained in:
Mentalflow 2024-03-17 03:17:13 +08:00
parent 138b233365
commit 4992e61376
Signed by: Mentalflow
GPG Key ID: 5AE68D4401A2EE71
19 changed files with 224391 additions and 152 deletions

View File

@ -5,7 +5,7 @@
<h1 align="center"> ProtocolParser 协议解析器 V1.0.4</h1>
## 一、介绍
这是一个用于与DKY的THM3682实验箱搭配使用的上位机协议解析器具体如何使用请看[使用说明](#使用说明)。
这是一个用于与DKY的THM3682实验箱搭配使用的上位机协议解析器具体如何使用请看[使用说明](#使用说明)。
<div align="center">
<div align="center">
<img src="documents/pictures/home-light.png" alt="主界面(浅色)" style="width:45%; height:auto;">
@ -14,7 +14,7 @@
<p align="center"> 主界面(浅色/深色模式) </p>
</div>
## 二、使用说明
## <div id = "使用说明">二、使用说明<div>
## 1. [协议解析](documents/protocol.md)
+ 概述
+ 密钥

View File

@ -4,6 +4,7 @@ project(ProtocolParser VERSION ${CMAKE_PROJECT_VERSION} LANGUAGES CXX)
set(CMAKE_CXX_STANDARD_REQUIRED ON)
if(QT_VERSION VERSION_GREATER_EQUAL "6.3")
qt_standard_project_setup()
qt_policy(SET QTP0001 NEW)
@ -53,12 +54,14 @@ set(
set(js_files js/markdown-it.js js/markdown-it-deflist.js js/markdown-it-emoji.js
js/markdown-it-sub.js js/markdown-it-abbr.js js/markdown-it-container.js js/markdown-it-footnote.js
js/markdown-it-ins.js js/markdown-it-mark.js js/markdown-it-sup.js js/prism.js
js/markdown-it-ins.js js/markdown-it-mark.js js/markdown-it-sup.js
js/jquery.js js/mermaid.js_packaged js/highlight.js
)
set(doc_files ${CMAKE_SOURCE_DIR}/documents/menu.md ${CMAKE_SOURCE_DIR}/documents/protocol.md
set(doc_files ${CMAKE_SOURCE_DIR}/README.md ${CMAKE_SOURCE_DIR}/documents/protocol.md
${CMAKE_SOURCE_DIR}/documents/serialport.md ${CMAKE_SOURCE_DIR}/documents/zigbee.md
${CMAKE_SOURCE_DIR}/documents/others.md
${CMAKE_SOURCE_DIR}/documents/others.md ${CMAKE_SOURCE_DIR}/documents/pictures/home-dark.png
${CMAKE_SOURCE_DIR}/documents/pictures/home-light.png ${CMAKE_SOURCE_DIR}/app_source/resources/imgs/icon.png
)
INCLUDE_DIRECTORIES(dlln3x include)
@ -123,7 +126,7 @@ qt_add_qml_module(${PROJECT_NAME}
URI ${PROJECT_NAME}
QML_FILES ${qml_files}
RESOURCE_PREFIX "/qt/qml/"
RESOURCES ${js_files} ${doc_files} resources/theme.css resources/default.css resources/prism-light.css resources/prism-dark.css
RESOURCES ${js_files} ${doc_files} resources/theme.css resources/default.css resources/github-light.css resources/github-dark.css
VERSION ${CMAKE_PROJECT_VERSION_MAJOR}.${CMAKE_PROJECT_VERSION_MINOR}
)

View File

@ -4,6 +4,7 @@
#include <QObject>
#include <QQmlEngine>
#include <QQuickTextDocument>
#include "../3rdparty/RibbonUI/lib_source/definitions.h"
class Tools : public QObject
{
@ -11,6 +12,7 @@ class Tools : public QObject
QML_ELEMENT
QML_SINGLETON
QML_NAMED_ELEMENT(Tools)
Q_PROPERTY_RW(QString, baseDir)
public:
static Tools* instance();
static Tools* create(QQmlEngine *qmlEngine, QJSEngine *jsEngine){return instance();}
@ -19,9 +21,12 @@ public:
Q_INVOKABLE void setBaseUrl(QQuickTextDocument *qd, QUrl url);
Q_INVOKABLE QString fileSuffix(const QString &filePath);
Q_INVOKABLE QString fileDir(const QString &filePath);
Q_INVOKABLE void writeDirtoTempDir(QString path);
Q_INVOKABLE void writeFiletoDir(QString content, QString path, QString name);
private:
explicit Tools(QObject *parent = nullptr);
~Tools();
Q_DISABLE_COPY_MOVE(Tools)
signals:

17471
app_source/js/highlight.js Normal file

File diff suppressed because it is too large Load Diff

10716
app_source/js/jquery.js vendored Normal file

File diff suppressed because it is too large Load Diff

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

View File

@ -56,7 +56,7 @@ RibbonWindow {
anchors{
left: parent.left
right: parent.right
bottom: parent.bottom
bottom: center_view.bottom
}
}

View File

@ -185,7 +185,7 @@ Item {
}
}
RibbonToolTip{
text: qsTr('类型:')+ qsTr(`${bg.type}, `) + qsTr('长度:') + `${bg.data_size}B`
text: qsTr('类型:')+ `${bg.type}, ` + qsTr('长度:') + `${bg.data_size}B`
visible: text && mouse.containsMouse
}

View File

@ -7,9 +7,10 @@ import "."
Item {
id:root
implicitHeight: 500
implicitWidth: 500
implicitHeight: 550
implicitWidth: 550
property string title: qsTr("帮助")
Component.onCompleted: Tools.writeDirtoTempDir(":/qt/qml/ProtocolParser/")
RibbonButton{
anchors{
@ -35,8 +36,9 @@ Item {
RibbonMarkDownViewer{
id: viewer
anchors.fill: parent
text: Tools.readAll(':/qt/qml/ProtocolParser/documents/menu.md')
base_url: 'qrc:/qt/qml/ProtocolParser/documents/'
file_name: 'qrc:/qt/qml/ProtocolParser/README.md'
base_url: 'qrc:/qt/qml/ProtocolParser/'
resource_dir: Tools.baseDir
}
RibbonButton{

View File

@ -15,13 +15,15 @@ import "qrc:/qt/qml/ProtocolParser/markdown-it-mark.js" as MarkdownItMark
Item {
id:root
property string text: ""
property string file_name: ""
property string base_url: ""
property string current_path: ""
property string resource_dir: ""
property int page_height: 0
property alias can_goback: viewer.canGoBack
property alias can_goforward: viewer.canGoForward
onTextChanged: reload()
onFile_nameChanged: reload()
WebView{
id: viewer
@ -32,6 +34,9 @@ Item {
}
width: parent.width
height: parent.height
settings.allowFileAccess: true
settings.localStorageEnabled: true
settings.javaScriptEnabled: true
property int pre_height: 0
onLoadingChanged: function(request){
if (request.status === WebView.LoadStartedStatus)
@ -43,10 +48,8 @@ Item {
}
else if (request.url.toString().match(/^qrc?:\/.+/))
{
console.log(request.url)
text = Tools.readAll(request.url.toString().replace("qrc:/",":/"))
pre_height = 0
load()
load(request.url.toString())
}
}
else if (request.status === WebView.LoadSucceededStatus)
@ -63,7 +66,7 @@ Item {
Component.onCompleted: {
load()
load(file_name)
}
Connections{
@ -90,56 +93,123 @@ Item {
{
viewer.runJavaScript("document.body.scrollTop", function(height) {
viewer.pre_height = height
load()
load(current_path)
});
}
function load()
function load(file_path)
{
var style = Tools.readAll(":/qt/qml/ProtocolParser/resources/theme.css")
var prism = Tools.readAll(`:/qt/qml/ProtocolParser/resources/prism-${RibbonTheme.dark_mode ? 'dark' : 'light'}.css`)
var prismjs = Tools.readAll(":/qt/qml/ProtocolParser/prism.js")
var ex = `
html {
height:100%;
overflow:hidden;
position:relative;
}
.markdown-body {
box-sizing: border-box;
min-width: 200px;
max-width: 980px;
margin: 0 auto;
padding: 45px;
height:100%;
overflow:auto;
position:relative;
if(!file_path)
{
viewer.url = "about:blank"
return
}
current_path = file_path
let text = Tools.readAll(file_path)
var script = `
var md;
let base_url = '${base_url}';
var defaults = {
html: true,
xhtmlOut: false,
breaks: false,
linkify: true,
typographer: true,
};
mermaid.initialize({
startOnLoad:true,
darkMode:${RibbonTheme.dark_mode},
theme: "${RibbonTheme.dark_mode ? 'dark' : 'neutral'}",
htmlLabels:true
});
const mermaidChart = (code) => {
console.log(code)
try {
return \`<div class=\"mermaid\">\${code}</div>\`
} catch ({ str, hash }) {
return \`<pre>\${str}</pre>\`
}
}
defaults.highlight = function (str, lang) {
var esc = md.utils.escapeHtml;
if (lang && hljs.getLanguage(lang)) {
try {
return '<pre class="hljs"><code>' +
hljs.highlight(lang, str, true).value +
'</code></pre>';
} catch (__) {}
}else if(lang == 'mermaid'){
return mermaidChart(str)
}else{
return '<pre class="hljs"><code>' + esc(str) + '</code></pre>';
}
};
md = window.markdownit(defaults);
md.use(markdownitDeflist);
md.use(markdownitEmoji);
md.use(markdownitSub);
md.use(markdownitSup);
md.use(markdownitAbbr);
md.use(markdownitContainer);
md.use(markdownitFootnote);
md.use(markdownitIns);
md.use(markdownitMark);
@media (max-width: 767px) {
.markdown-body {
padding: 15px;
}
}`
var md = markdownit({
html: true,
linkify: true,
typographer: true
});
md.use(markdownitDeflist)
md.use(markdownitEmoji)
md.use(markdownitSub)
md.use(markdownitSup)
md.use(markdownitAbbr)
md.use(markdownitContainer)
md.use(markdownitFootnote)
md.use(markdownitIns)
md.use(markdownitMark)
var result = md.render(text);
result = result.replace(new RegExp("href=\"(./)?", "gi"), 'href="'+base_url);
viewer.loadHtml(`<html data-theme=${RibbonTheme.dark_mode ? 'dark' : 'light'}>` + '<head><meta charset="UTF-8", name="viewport" content="width=device-width, initial-scale=1">' +
"<style>" + ex + prism + style + "</style></head>" + "<body>" + '<script>' + prismjs + '</script>' +
'<article class="markdown-body">' + result + '</article>' + "</body></html>")
let result = md.render($('.markdown-source').html());
if (base_url.match(/^qrc?:\\/.+/g))
result = result.replace(/href="(\\.\\/)?(.*?).md"/g, 'href="${base_url}/$2.md"');
result = result.replace(/src=\\"(\\.\\/)?/g, \`src=\"${resource_dir}\`);
$('.markdown-body').html(result);
$('.markdown-source').remove();
`
// var md = markdownit({
// html: true,
// linkify: true,
// typographer: true
// });
// md.use(markdownitDeflist)
// md.use(markdownitEmoji)
// md.use(markdownitSub)
// md.use(markdownitSup)
// md.use(markdownitAbbr)
// md.use(markdownitContainer)
// md.use(markdownitFootnote)
// md.use(markdownitIns)
// md.use(markdownitMark)
// var result = md.render(text);
// if (base_url.match(/^qrc?:\/.+/))
// result = result.replace(new RegExp("href=\"(\.\/)?(.*?).md", "gi"), `href="${base_url}/$2.md"`);
// result = result.replace(new RegExp("src=\"(./)?", "gi"), `src="`+resource_dir);
let parts = file_path.split('/')
let full_file_name = parts[parts.length-1] === '/' ? parts[parts.length-2] : parts[parts.length-1]
let file_name = full_file_name.split('.')
let html_name = `${file_name[0]}.html`
let prefix = `file:${Qt.platform.os === 'windows' ? '///' : '//'}` + Tools.baseDir
let html = `<!DOCTYPE html><html data-theme=${RibbonTheme.dark_mode ? 'dark' : 'light'}>` +
'<head><meta charset="UTF-8", name="viewport" content="width=device-width, initial-scale=1">' +
`<title>${full_file_name}</title>` +
`<link rel="stylesheet" href=${prefix}resources/theme.css></style>` +
`<link rel="stylesheet" href=${prefix}resources/github-${RibbonTheme.dark_mode ? 'dark' : 'light'}.css></style>` +
`<script src=${prefix}jquery.js></script>` +
`<script src=${prefix}markdown-it.js></script>`+
`<script src=${prefix}markdown-it-deflist.js></script>` +
`<script src=${prefix}markdown-it-emoji.js></script>` +
`<script src=${prefix}markdown-it-sub.js></script>` +
`<script src=${prefix}markdown-it-abbr.js></script>` +
`<script src=${prefix}markdown-it-container.js></script>` +
`<script src=${prefix}markdown-it-footnote.js></script>` +
`<script src=${prefix}markdown-it-ins.js></script>` +
`<script src=${prefix}markdown-it-mark.js></script>` +
`<script src=${prefix}markdown-it-sup.js></script>` +
`<script src=${prefix}highlight.js></script>` +
`<script src=${prefix}mermaid.js></script>`+
"</head>" + "<body>" +
'<article class="markdown-body">' + '</article>' +
'<pre class="markdown-source">' + text + '</pre>' +
`<script type="module">${script}</script>` +
"</body></html>"
Tools.writeFiletoDir(html,Tools.baseDir,html_name)
viewer.url = (prefix + html_name)
}
function go_back()

View File

@ -0,0 +1,118 @@
pre code.hljs {
display: block;
overflow-x: auto;
padding: 1em
}
code.hljs {
padding: 3px 5px
}
/*!
Theme: GitHub Dark
Description: Dark theme as seen on github.com
Author: github.com
Maintainer: @Hirse
Updated: 2021-05-15
Outdated base version: https://github.com/primer/github-syntax-dark
Current colors taken from GitHub's CSS
*/
.hljs {
color: #c9d1d9;
background: #0d1117
}
.hljs-doctag,
.hljs-keyword,
.hljs-meta .hljs-keyword,
.hljs-template-tag,
.hljs-template-variable,
.hljs-type,
.hljs-variable.language_ {
/* prettylights-syntax-keyword */
color: #ff7b72
}
.hljs-title,
.hljs-title.class_,
.hljs-title.class_.inherited__,
.hljs-title.function_ {
/* prettylights-syntax-entity */
color: #d2a8ff
}
.hljs-attr,
.hljs-attribute,
.hljs-literal,
.hljs-meta,
.hljs-number,
.hljs-operator,
.hljs-variable,
.hljs-selector-attr,
.hljs-selector-class,
.hljs-selector-id {
/* prettylights-syntax-constant */
color: #79c0ff
}
.hljs-regexp,
.hljs-string,
.hljs-meta .hljs-string {
/* prettylights-syntax-string */
color: #a5d6ff
}
.hljs-built_in,
.hljs-symbol {
/* prettylights-syntax-variable */
color: #ffa657
}
.hljs-comment,
.hljs-code,
.hljs-formula {
/* prettylights-syntax-comment */
color: #8b949e
}
.hljs-name,
.hljs-quote,
.hljs-selector-tag,
.hljs-selector-pseudo {
/* prettylights-syntax-entity-tag */
color: #7ee787
}
.hljs-subst {
/* prettylights-syntax-storage-modifier-import */
color: #c9d1d9
}
.hljs-section {
/* prettylights-syntax-markup-heading */
color: #1f6feb;
font-weight: bold
}
.hljs-bullet {
/* prettylights-syntax-markup-list */
color: #f2cc60
}
.hljs-emphasis {
/* prettylights-syntax-markup-italic */
color: #c9d1d9;
font-style: italic
}
.hljs-strong {
/* prettylights-syntax-markup-bold */
color: #c9d1d9;
font-weight: bold
}
.hljs-addition {
/* prettylights-syntax-markup-inserted */
color: #aff5b4;
background-color: #033a16
}
.hljs-deletion {
/* prettylights-syntax-markup-deleted */
color: #ffdcd7;
background-color: #67060c
}
.hljs-char.escape_,
.hljs-link,
.hljs-params,
.hljs-property,
.hljs-punctuation,
.hljs-tag {
/* purposely ignored */
}

View File

@ -0,0 +1,118 @@
pre code.hljs {
display: block;
overflow-x: auto;
padding: 1em
}
code.hljs {
padding: 3px 5px
}
/*!
Theme: GitHub
Description: Light theme as seen on github.com
Author: github.com
Maintainer: @Hirse
Updated: 2021-05-15
Outdated base version: https://github.com/primer/github-syntax-light
Current colors taken from GitHub's CSS
*/
.hljs {
color: #24292e;
background: #ffffff
}
.hljs-doctag,
.hljs-keyword,
.hljs-meta .hljs-keyword,
.hljs-template-tag,
.hljs-template-variable,
.hljs-type,
.hljs-variable.language_ {
/* prettylights-syntax-keyword */
color: #d73a49
}
.hljs-title,
.hljs-title.class_,
.hljs-title.class_.inherited__,
.hljs-title.function_ {
/* prettylights-syntax-entity */
color: #6f42c1
}
.hljs-attr,
.hljs-attribute,
.hljs-literal,
.hljs-meta,
.hljs-number,
.hljs-operator,
.hljs-variable,
.hljs-selector-attr,
.hljs-selector-class,
.hljs-selector-id {
/* prettylights-syntax-constant */
color: #005cc5
}
.hljs-regexp,
.hljs-string,
.hljs-meta .hljs-string {
/* prettylights-syntax-string */
color: #032f62
}
.hljs-built_in,
.hljs-symbol {
/* prettylights-syntax-variable */
color: #e36209
}
.hljs-comment,
.hljs-code,
.hljs-formula {
/* prettylights-syntax-comment */
color: #6a737d
}
.hljs-name,
.hljs-quote,
.hljs-selector-tag,
.hljs-selector-pseudo {
/* prettylights-syntax-entity-tag */
color: #22863a
}
.hljs-subst {
/* prettylights-syntax-storage-modifier-import */
color: #24292e
}
.hljs-section {
/* prettylights-syntax-markup-heading */
color: #005cc5;
font-weight: bold
}
.hljs-bullet {
/* prettylights-syntax-markup-list */
color: #735c0f
}
.hljs-emphasis {
/* prettylights-syntax-markup-italic */
color: #24292e;
font-style: italic
}
.hljs-strong {
/* prettylights-syntax-markup-bold */
color: #24292e;
font-weight: bold
}
.hljs-addition {
/* prettylights-syntax-markup-inserted */
color: #22863a;
background-color: #f0fff4
}
.hljs-deletion {
/* prettylights-syntax-markup-deleted */
color: #b31d28;
background-color: #ffeef0
}
.hljs-char.escape_,
.hljs-link,
.hljs-params,
.hljs-property,
.hljs-punctuation,
.hljs-tag {
/* purposely ignored */
}

View File

@ -1,5 +0,0 @@
/* PrismJS 1.29.0
https://prismjs.com/download.html#themes=prism-tomorrow&languages=markup+css+clike+javascript+arduino+armasm+bash+c+cpp+docker+git+go+go-module+gradle+http+hpkp+hsts+java+javadoc+javadoclike+jsdoc+js-extras+json+json5+jsonp+jsstacktrace+js-templates+kotlin+latex+log+markup-templating+mermaid+objectivec+perl+php+phpdoc+php-extras+plsql+powerquery+powershell+qml+ruby+rust+shell-session+sql+typescript+wasm+yaml&plugins=line-highlight+line-numbers+highlight-keywords */
code[class*=language-],pre[class*=language-]{color:#ccc;background:0 0;font-family:Consolas,Monaco,'Andale Mono','Ubuntu Mono',monospace;font-size:1em;text-align:left;white-space:pre;word-spacing:normal;word-break:normal;word-wrap:normal;line-height:1.5;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-hyphens:none;-moz-hyphens:none;-ms-hyphens:none;hyphens:none}pre[class*=language-]{padding:1em;margin:.5em 0;overflow:auto}:not(pre)>code[class*=language-],pre[class*=language-]{background:#161b22}:not(pre)>code[class*=language-]{padding:.1em;border-radius:.3em;white-space:normal}.token.block-comment,.token.cdata,.token.comment,.token.doctype,.token.prolog{color:#999}.token.punctuation{color:#ccc}.token.attr-name,.token.deleted,.token.namespace,.token.tag{color:#e2777a}.token.function-name{color:#6196cc}.token.boolean,.token.function,.token.number{color:#f08d49}.token.class-name,.token.constant,.token.property,.token.symbol{color:#f8c555}.token.atrule,.token.builtin,.token.important,.token.keyword,.token.selector{color:#cc99cd}.token.attr-value,.token.char,.token.regex,.token.string,.token.variable{color:#7ec699}.token.entity,.token.operator,.token.url{color:#67cdcc}.token.bold,.token.important{font-weight:700}.token.italic{font-style:italic}.token.entity{cursor:help}.token.inserted{color:green}
pre[data-line]{position:relative;padding:1em 0 1em 3em}.line-highlight{position:absolute;left:0;right:0;padding:inherit 0;margin-top:1em;background:hsla(24,20%,50%,.08);background:linear-gradient(to right,hsla(24,20%,50%,.1) 70%,hsla(24,20%,50%,0));pointer-events:none;line-height:inherit;white-space:pre}@media print{.line-highlight{-webkit-print-color-adjust:exact;color-adjust:exact}}.line-highlight:before,.line-highlight[data-end]:after{content:attr(data-start);position:absolute;top:.4em;left:.6em;min-width:1em;padding:0 .5em;background-color:hsla(24,20%,50%,.4);color:#f4f1ef;font:bold 65%/1.5 sans-serif;text-align:center;vertical-align:.3em;border-radius:999px;text-shadow:none;box-shadow:0 1px #fff}.line-highlight[data-end]:after{content:attr(data-end);top:auto;bottom:.4em}.line-numbers .line-highlight:after,.line-numbers .line-highlight:before{content:none}pre[id].linkable-line-numbers span.line-numbers-rows{pointer-events:all}pre[id].linkable-line-numbers span.line-numbers-rows>span:before{cursor:pointer}pre[id].linkable-line-numbers span.line-numbers-rows>span:hover:before{background-color:rgba(128,128,128,.2)}
pre[class*=language-].line-numbers{position:relative;padding-left:3.8em;counter-reset:linenumber}pre[class*=language-].line-numbers>code{position:relative;white-space:inherit}.line-numbers .line-numbers-rows{position:absolute;pointer-events:none;top:0;font-size:100%;left:-3.8em;width:3em;letter-spacing:-1px;border-right:1px solid #999;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none}.line-numbers-rows>span{display:block;counter-increment:linenumber}.line-numbers-rows>span:before{content:counter(linenumber);color:#999;display:block;padding-right:.8em;text-align:right}

View File

@ -1,5 +0,0 @@
/* PrismJS 1.29.0
https://prismjs.com/download.html#themes=prism&languages=markup+css+clike+javascript+arduino+armasm+bash+c+cpp+docker+git+go+go-module+gradle+http+hpkp+hsts+java+javadoc+javadoclike+jsdoc+js-extras+json+json5+jsonp+jsstacktrace+js-templates+kotlin+latex+log+markup-templating+mermaid+objectivec+perl+php+phpdoc+php-extras+plsql+powerquery+powershell+qml+ruby+rust+shell-session+sql+typescript+wasm+yaml&plugins=line-highlight+line-numbers+highlight-keywords */
code[class*=language-],pre[class*=language-]{color:#000;background:0 0;text-shadow:0 1px #fff;font-family:Consolas,Monaco,'Andale Mono','Ubuntu Mono',monospace;font-size:1em;text-align:left;white-space:pre;word-spacing:normal;word-break:normal;word-wrap:normal;line-height:1.5;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-hyphens:none;-moz-hyphens:none;-ms-hyphens:none;hyphens:none}code[class*=language-] ::-moz-selection,code[class*=language-]::-moz-selection,pre[class*=language-] ::-moz-selection,pre[class*=language-]::-moz-selection{text-shadow:none;background:#b3d4fc}code[class*=language-] ::selection,code[class*=language-]::selection,pre[class*=language-] ::selection,pre[class*=language-]::selection{text-shadow:none;background:#b3d4fc}@media print{code[class*=language-],pre[class*=language-]{text-shadow:none}}pre[class*=language-]{padding:1em;margin:.5em 0;overflow:auto}:not(pre)>code[class*=language-],pre[class*=language-]{background:#f6f8fa}:not(pre)>code[class*=language-]{padding:.1em;border-radius:.3em;white-space:normal}.token.cdata,.token.comment,.token.doctype,.token.prolog{color:#708090}.token.punctuation{color:#999}.token.namespace{opacity:.7}.token.boolean,.token.constant,.token.deleted,.token.number,.token.property,.token.symbol,.token.tag{color:#905}.token.attr-name,.token.builtin,.token.char,.token.inserted,.token.selector,.token.string{color:#690}.language-css .token.string,.style .token.string,.token.entity,.token.operator,.token.url{color:#9a6e3a;background:hsla(0,0%,100%,.5)}.token.atrule,.token.attr-value,.token.keyword{color:#07a}.token.class-name,.token.function{color:#dd4a68}.token.important,.token.regex,.token.variable{color:#e90}.token.bold,.token.important{font-weight:700}.token.italic{font-style:italic}.token.entity{cursor:help}
pre[data-line]{position:relative;padding:1em 0 1em 3em}.line-highlight{position:absolute;left:0;right:0;padding:inherit 0;margin-top:1em;background:hsla(24,20%,50%,.08);background:linear-gradient(to right,hsla(24,20%,50%,.1) 70%,hsla(24,20%,50%,0));pointer-events:none;line-height:inherit;white-space:pre}@media print{.line-highlight{-webkit-print-color-adjust:exact;color-adjust:exact}}.line-highlight:before,.line-highlight[data-end]:after{content:attr(data-start);position:absolute;top:.4em;left:.6em;min-width:1em;padding:0 .5em;background-color:hsla(24,20%,50%,.4);color:#f4f1ef;font:bold 65%/1.5 sans-serif;text-align:center;vertical-align:.3em;border-radius:999px;text-shadow:none;box-shadow:0 1px #fff}.line-highlight[data-end]:after{content:attr(data-end);top:auto;bottom:.4em}.line-numbers .line-highlight:after,.line-numbers .line-highlight:before{content:none}pre[id].linkable-line-numbers span.line-numbers-rows{pointer-events:all}pre[id].linkable-line-numbers span.line-numbers-rows>span:before{cursor:pointer}pre[id].linkable-line-numbers span.line-numbers-rows>span:hover:before{background-color:rgba(128,128,128,.2)}
pre[class*=language-].line-numbers{position:relative;padding-left:3.8em;counter-reset:linenumber}pre[class*=language-].line-numbers>code{position:relative;white-space:inherit}.line-numbers .line-numbers-rows{position:absolute;pointer-events:none;top:0;font-size:100%;left:-3.8em;width:3em;letter-spacing:-1px;border-right:1px solid #999;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none}.line-numbers-rows>span{display:block;counter-increment:linenumber}.line-numbers-rows>span:before{content:counter(linenumber);color:#999;display:block;padding-right:.8em;text-align:right}

View File

@ -125,6 +125,27 @@
vertical-align: text-bottom;
}
.markdown-body {
box-sizing: border-box;
min-width: 200px;
max-width: 980px;
margin: 0 auto;
padding: 45px;
height:100%;
}
@media (max-width: 767px) {
.markdown-body {
padding: 15px;
}
.markdown-source{
height: 0;
overflow: hidden;
visibility: hidden;
}
}
.markdown-body h1:hover .anchor .octicon-link:before,
.markdown-body h2:hover .anchor .octicon-link:before,
.markdown-body h3:hover .anchor .octicon-link:before,

View File

@ -2,10 +2,21 @@
#include <QMutex>
#include <QFile>
#include <QFileInfo>
#include <QStandardPaths>
#include <QDirIterator>
Tools::Tools(QObject *parent)
: QObject{parent}
{}
{
baseDir(QStandardPaths::writableLocation(QStandardPaths::TempLocation) + + "/ProtocolParser/");
}
Tools::~Tools()
{
QDirIterator it(baseDir(), QDirIterator::Subdirectories);
while (it.hasNext())
QFile::remove(it.next());
}
Tools* Tools::instance(){
static QMutex mutex;
@ -26,6 +37,9 @@ void Tools::setDefaultStyleSheet(QQuickTextDocument *qd, QString path)
QString Tools::readAll(QString path)
{
if (path.startsWith("qrc:/")) {
path.replace(0, 3, "");
}
QFile file(path);
if(!file.exists()){
qWarning()<<"File not exist!";
@ -55,3 +69,37 @@ QString Tools::fileDir(const QString &filePath)
QFileInfo info(filePath);
return info.absolutePath();
}
void Tools::writeDirtoTempDir(QString path)
{
if (path.startsWith("qrc:/")) {
path.replace(0, 3, "");
}
QDir tmpdir(baseDir());
QDirIterator it(path, QDirIterator::Subdirectories);
while (it.hasNext()) {
QString tmpfile;
tmpfile = it.next();
if (QFileInfo(tmpfile).isFile()) {
QString original_name = tmpfile;
if(tmpfile.endsWith("js_packaged"))
tmpfile.replace("js_packaged","js");
tmpfile.replace(path,"");
QFileInfo file = QFileInfo(tmpdir.absolutePath() + '/' + tmpfile);
file.dir().mkpath("."); // create full path if necessary
QFile::remove(file.absoluteFilePath()); // remove previous file to make sure we have the latest version
QFile::copy(original_name, file.absoluteFilePath());
}
}
}
void Tools::writeFiletoDir(QString content, QString path, QString name)
{
QFile file(path+'/'+name);
if (!file.open(QIODevice::WriteOnly)) {
qDebug() << "File open fail: " + file.fileName();
return;
}
file.write(content.toLocal8Bit());
file.close();
}

View File

@ -1,19 +0,0 @@
## 目录
## 1. [协议解析](protocol.md)
+ 概述
+ 密钥
+ 认证流程
+ 数据结构
+ 接口解析
## 2. [串口使用](serialport.md)
+ 参数配置
+ 串口消息设置
+ 串口助手设置
+ 串口数据流向
## 3. [紫蜂协议](zigbee.md)
+ 设备列表
+ 密钥管理
+ 调试选项
## 4. [其他](others.md)
+ 主题
+ 数据结构自定义

View File

@ -11,10 +11,10 @@
由于SM2算法会占用一部分资源非对称双向认证一般用于性能较好的终端如性能较强的单片机、树莓派或者PC等设备之间的认证性能较差的单片机将会出现死机等预料外情况板载硬件密码算法模块除外
```mermaid
sequenceDiagram
participant 服务器
participant 客户端
participant 服务器
participant 客户端
客户端-->服务器: 客户端验证服务器
客户端->>服务器: 包含Hello信息的ssl_frame请求
客户端->>服务器: 包含Hello信息的ssl_frame请求
服务器->>客户端: 包含Hello和64Bytes服务器公钥信息的ssl_frame响应
客户端-->>客户端: 用服务器公钥加密自己的公钥
客户端->>服务器: 包含服务器公钥加密的客户端公钥信息的ssl_frame数据包
@ -35,10 +35,10 @@ sequenceDiagram
对称双向认证使用基于SM3的HMAC算法实现。通过验证双方是否共同持有同一对预设定密钥来实现认证在实际运用过程中为节省资源服务器发送给客户端的Identified信息可不加密采用明文传输因为后续传输的数据包均为加密数据包
```mermaid
sequenceDiagram
participant 服务器
participant 客户端
participant 服务器
participant 客户端
客户端-->>客户端: 生成1Byte随机数并对其使用基于SM3的HMAC算法和<br>预设定16Bytes密钥生成值
客户端->>服务器: 包含随机数和使用预设定16Bytes密钥生成的<br>HMAC值信息的hmac_frame请求
客户端->>服务器: 包含随机数和使用预设定16Bytes密钥生成的<br>HMAC值信息的hmac_frame请求
服务器-->>服务器: 使用自己拥有的预设定16Bytes密钥对收到的<br>1Byte随机数进行HMAC运算并将值与收到值进行比对
服务器->>客户端: 包含使用预设定16Bytes密钥加密的<br>Identified信息的crypto_zdata_frame数据包
客户端-->>客户端: 用预设定16Bytes密钥解密出Identified信息