修改Markdown代码框
初始效果
前几天换了博客的主题,开始用博客园的md编辑器写博客,然而md编辑器的代码高亮支持有些糟糕。
在新主题下<pre>标签与<code>标签背景颜色不统一,代码没有行号,高亮也没有原编辑器的好看。在网上找的的各种解决方案要不就是太丑要不就是因为博客园版本迭代而跑不起来。于是就开始一顿魔改。
修改配色
去highligh.js官网找一个配色下载CSS贴进去即可,下面是我用的
.cnblogs-markdown .hljs {
display: block;
overflow-x: auto;
padding: 0.5em;
background: #1E1E1E !important;
color: #FFF;
white-space: pre;
word-break: normal;
font-family: "Consolas",sans-serif!important;
font-size:14px!important;
}
.hljs {
display: block;
overflow-x: auto;
padding: 0.5em;
background: #1E1E1E;
color: #DCDCDC;
}
code.hljs{
display: inline-block !important;
}
.hljs-keyword,
.hljs-literal,
.hljs-symbol,
.hljs-name {
color: #569CD6;
}
.hljs-link {
color: #569CD6;
text-decoration: underline;
}
.hljs-built_in,
.hljs-type {
color: #4EC9B0;
}
.hljs-number,
.hljs-class {
color: #B8D7A3;
}
.hljs-string,
.hljs-meta-string {
color: #D69D85;
}
.hljs-regexp,
.hljs-template-tag {
color: #9A5334;
}
.hljs-subst,
.hljs-function,
.hljs-title,
.hljs-params,
.hljs-formula {
color: #DCDCDC;
}
.hljs-comment,
.hljs-quote {
color: #57A64A;
font-style: italic;
}
.hljs-doctag {
color: #608B4E;
}
.hljs-meta,
.hljs-meta-keyword,
.hljs-tag {
color: #9B9B9B;
}
.hljs-variable,
.hljs-template-variable {
color: #BD63C5;
}
.hljs-attr,
.hljs-attribute,
.hljs-builtin-name {
color: #9CDCFE;
}
.hljs-section {
color: gold;
}
.hljs-emphasis {
font-style: italic;
}
.hljs-strong {
font-weight: bold;
}
/*.hljs-code {
font-family:'Monospace';
}*/
.hljs-bullet,
.hljs-selector-tag,
.hljs-selector-id,
.hljs-selector-class,
.hljs-selector-attr,
.hljs-selector-pseudo {
color: #D7BA7D;
}
.hljs-addition {
background-color: #144212;
display: inline-block;
width: 100%;
}
.hljs-deletion {
background-color: #600;
display: inline-block;
width: 100%;
}
修改pre
由于有另一个js在写pre的样式,无法保证页脚js与这个js的加载顺序,就创建了个interval,每秒执行一次,直到修改完成。
function getCss(element, attr) {
if (element.currentStyle) {
return element.currentStyle[attr];
} else {
return window.getComputedStyle(element, null)[attr];
}
}
var codebox = document.querySelectorAll("pre");
var code = document.querySelectorAll("code.hljs");
var color = getCss(code[0], "background-color");
var flag = 0;
var intv1 = setInterval(() => {
if (codebox[0].style.backgroundColor == color)
flag++;
if (flag >= 5) clearInterval(intv1);
for (i = 0; i < codebox.length; i++) {
codebox[i].style.borderLeftColor = "#569CD6";
codebox[i].style.backgroundColor = color;
}
}, 100);
后来想了下也可以直接用CSS来改变颜色,加上!important就好:
pre {
background-color:#1e1e1e !important;
}
添加行号
审查元素可以发现代码已经在后台被渲染好了,包上了各种奇奇怪怪的class。
一开始的想法是提取<code>的innerHTML,在第一行每个换行符的后面添加行号。然而改完之后发现,复制代码的功能崩了。。。复制出来的代码是带行号的。
博客园的复制代码用的是clipboard.js,复制代码的按钮有一个属性是data-clipboard-target ,这个属性指向要复制innerText的元素。
于是魔改的思路就是,在原本的<code>左侧新增一个只写行号的<code>,再将原本指向<code-box>的data-clipboard-target改为指向原有的<code>。
因为button是由clipboard.js创建的,同样无法决定js加载顺序,只好再建一个interval。
注意因为要并排放两个<code>,要把原来code.hljs的display属性从block改为inline-block:
code.hljs{
display: inline-block !important;
}
js代码:
var flag2 = 0;
var intv2 = setInterval(() => {
var codebtn = document.querySelectorAll("code-box > button");
if (codebtn.length) {
if (codebtn[0].getAttribute("data-clipboard-target") == "fuckingcode0")
flag2++;
if (flag2 >= 5) clearInterval(intv2);
for (i = 0; i < codebtn.length; i++) {
codebtn[i].setAttribute("data-clipboard-target", "#fuckingcode" + i);
}
}
}, 100);
String.prototype.times = function (n) {
return Array.prototype.join.call({ length: n + 1 }, this);
};
for (i = 0; i < code.length; i++) {
var codelist = code[i].children;
code[i].id = "fuckingcode" + i;
var item = $(code[i]);
str = item.html();
var n = (str.split('\n')).length;
var m = Math.ceil(Math.log(n) / Math.log(10));
str1 = ' '.times(m - 1) + 1;
for (j = 2; j <= n; j++) {
var k = Math.ceil(Math.log(j) / Math.log(10)) + (!(j % 10));
str1 += '\n' + ' '.times(m - k) + j;
}
item.before('<code class="hljs" style="border-right: 1px solid rgba(255,255,255,0.35) !important">' + str1 + '</code>');
}
最终效果
完整代码
https://github.com/woolen-sheep/cnblogs-markdown-code-linenumbers