修改Markdown代碼框
UPD 2020-03-15
五天前這個主題的作者更新了1.2.6版本,新版本中改善了對MD代碼框的支持,本教程的部分內容已非必要。
初始效果
前幾天換了博客的主題,開始用博客園的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;
vertical-align: top !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);
};
function isexp10(k) {
while (k) {
if (k == 1) return 1;
if (k % 10) return 0;
k /= 10;
}
return 1;
}
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)) + isexp10(j);
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