0%

myBase:插件方式实现代码背景高亮

myBase 是一款用于分类管理任意格式文档资料的小型个人数据库软件, 有助于个人用户在( Linux/MacOSX/Windows )桌面电脑系统上实施文档、笔记、日记、图片和网页等知识内容的分类管理。

简单讲,myBase是一款可附加文件的以单文件加密存储的笔记软件。

1. 需求

平时做笔记时,代码都是通过VS Code格式化后存储到myBase中。

效果如下:

最近看微软的教程时,注意到文档中除了给出一段代码外,为了强调某一部分,会额外辅以背景高亮,效果如下:

正好myBase支持插件开发,于是想用插件的方式进行实现。

2. 代码实现

(1) 在 安装目录/plugins/ 路径下新建一个文件:Highlight Code Background.js, 代码如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
//sValidation=nyfjs
//sCaption=代码背景高亮
//sHint=Highlight code snippet background
//sCategory=MainMenu.Edit; Context.HtmlEdit
//sCondition=CURDB; DBRW; CURINFOITEM; HTMLEDIT
//sID=p.CustomCodeBackground
//sAppVerMin=7.0
//sAuthor=IUpdatable

try {
var xNyf = new CNyfDb(-1);
if (xNyf.isOpen()) {
if (!xNyf.isReadonly()) {
if (plugin.isContentEditable()) {
var sEditor = plugin.getCurEditorType().toLowerCase();
if (sEditor == 'htmledit') {
var xFn = new CLocalFile(plugin.getPathToDomScripts(), 'userJs.js');
var jsCode = xFn.loadText('auto');
plugin.runDomScript(-1, jsCode);
plugin.runDomScript(-1, 'userJs.highlightCodeBg();');
}
}
}
}
} catch (error) {
alert("error:" + error);
}

(2)在 安装目录/scripts/ 路径下新建一个文件:userJs.js

说明一下,代码背景高亮的颜色采用的是VS Code选中代码时呈现的背景色:#264F78,如果想修改为自己喜欢的颜色,直接在下面代码中替换该值即可。

代码如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91

! function (e) {
var n = "object" == typeof window && window || "object" == typeof self && self;
"undefined" != typeof exports ? e(exports) : n && (n.userJs = e({}), "function" == typeof define && define.amd && define([], function () {
return n.userJs
}))
}
(
function (e) {

function getParentDiv(node) {
var nodeName = node.nodeName.toLowerCase();
if (nodeName == 'div') {
return node;
} else {
var newNode = node.parentNode;
return getParentDiv(newNode);
}
}

function replaceSelectionWithHtml(html) {
if (window.getSelection && window.getSelection().getRangeAt) {
var range;
range = window.getSelection().getRangeAt(0);
range.deleteContents();
var div = document.createElement("div");
div.innerHTML = html;
var frag = document.createDocumentFragment(),
child;
while ((child = div.firstChild)) {
frag.appendChild(child);
}
range.insertNode(frag);
} else if (document.selection && document.selection.createRange) {
var range;
range = document.selection.createRange();
range.pasteHTML(html);
}
}

function highlightCodeBg() {
var html = "";
var sel = window.getSelection();
if (sel.rangeCount) {
for (var i = 0, len = sel.rangeCount; i < len; ++i) {
var container = document.createElement("div");
container.appendChild(sel.getRangeAt(i).cloneContents());
var curHtml = container.innerHTML;
var nodeName = container.firstChild.nodeName.toLowerCase();
// 先为 #text、span 类型的节点添加一个标记:class: CodeBg

if (nodeName == '#text') {
curHtml = '<a class="CodeBg">' + curHtml + '</a>';
} else if (nodeName == 'span') {
var clas = container.firstChild.setAttribute('class');
if (clas == null) {
container.firstChild.setAttribute('class', 'CodeBg');
} else {
container.firstChild.getAttribute('class', clas + ' CodeBg');
}
curHtml = container.innerHTML;
} else if (nodeName == 'div') {
var queryResult = container.querySelectorAll('div');
if (queryResult.length > 0) {
for (var j = 0; j < queryResult.length; j++) {
queryResult[j].setAttribute('style', 'background-color: #264F78; ');
}
curHtml = container.innerHTML;
}
} else {
alert('其它类型节点:' + nodeName);
}
html += curHtml;
}

replaceSelectionWithHtml(html);

// 全局中选出标记为 CodeBg 的节点,找出其div类型父节点,添加背景色
var queryResult = document.querySelectorAll('.CodeBg');
if (queryResult.length > 0) {
for (var j = 0; j < queryResult.length; j++) {
var parentDiv = getParentDiv(queryResult[j]);
parentDiv.setAttribute('style', 'background-color: #264F78; ');
queryResult[j].classList.remove('CodeBg');
}
}
}
}

return e.replaceSelectionWithHtml = replaceSelectionWithHtml, e.highlightCodeBg = highlightCodeBg, e.getParentDiv = getParentDiv, e;
});

(3)重启一下 myBase

3. 使用演示及说明

(1) 该插件仅适用于网页编辑模式;

(2) 在多行高亮时,选择代码时要确保顶格选中首行,不要在首行左侧留有空白,否则高亮后会改变原有布局。单行高亮时没有该限制。

(3)虽然该插件的功能定位为代码背景高亮,但其实质仅是修改了选中部分 div 元素的背景色,所以同样可以高亮任何选中的文本。

参考