博客园Markdown模式的MATLAB代码高亮方案
Posted ctgu
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了博客园Markdown模式的MATLAB代码高亮方案相关的知识,希望对你有一定的参考价值。
前言
博客园随笔写作可以使用 Markdown 进行编辑,当展示代码时,可以使用下面的语法来对代码块进行展示:
?```language
code-content
?```
一般来说,指明了 language
后,应该是可以是实现语法高亮的。其基本原理就是将代码中的 关键字
、变量
、函数
等待字符做正则化匹配,将纯文本的代码内容分块,与固定语法内容的着色方案(css样式)对应上。
然鹅!!大部分编程语言都能实现较好的高亮,而 Matlab 效果却很差,语法样式是错误的!看着很不舒服。
就像下面这样:
% 为输出创建文件
!touch testFile.txt
fid = fopen('testFile.txt','w');
for i = 1:10
frprintf(fid,'%6.2f
',i);
end
作为强迫症的我想把 Matlab 代码高亮变成和 Matlab软件中高亮方式一模一样。话不多说,开干!
语法高亮的基本内容
在改造之前,首先得理解语法高亮的基本内容。
一般来说,作为一种编程语言,都包括以下基本语法项目:
- keyword 关键字,也就是我们常用 for、if、else、end等等
- string 字符串,作为文本的一些字符
- params 变量,自己定义的变量
- comment 注释,代码一般都会有注释
- bracket 括号,一般地代码都会有成对出现的圆括号、花括号
以上这些,就是作为一个语法高亮方案,所需要匹配的基本内容。这些语法项目,都会有一定的规律(不然怎么叫语法),通过正则表达式,可以将写好的代码块中,对应的语法基本项目匹配出来。比如你的代码中有很多个 if
,那么通过正则表达式,就可以将他们全部匹配到。
贴上样式标签
当匹配到基本的语法项目后,将他们贴上对应的样式标签,例如对于匹配到的 if
,将其贴上关键字标签:
<span class="matlab-keyword">if</span>
这样,if
这个关键字就会被 matlab-keyword
样式着色。其他的也和这个一样,贴上对应的样式即可。
代码高亮识别
那么,在一堆文字中,我怎么识别这部分文字就是要高亮的代码?
在这里我们通过 <pre>
和</pre>
这样一对标签来包裹代码内容,让代码识别到这段文字是需要高亮的代码。为了区别其他样式,一般在markdown中只需要这样来表示代码需要高亮成 Matlab 样式:
<pre class="matlab-code">
% 为输出创建文件
!touch testFile.txt
fid = fopen('testFile.txt','w');
for i = 1:10
frprintf(fid,'%6.2f
',i);
end
</pre>
博客园后台配置
总的来说,实现代码高亮,基本上主要包括这几大内容:
- 配置语法高亮CSS样式
- 配置语法正则表达式匹配方案JS
- Markown 中以特定标签包裹代码块,实现调用
语法高亮的css样式文件
.cnblogs-markdown .matlab-code{
display: block;
color: #333;
overflow-x: auto;
background: #F2F4F5 !important;
border: none !important;
font-family: 'Microsoft YaHei', 'SF Pro Display', Roboto, Noto, Arial, 'PingFang SC', sans-serif !important;
padding: 1em !important;
font-size: 14px !important
}
pre .matlab-keyword, code .matlab-keyword {color: #0000fe;}
pre .matlab-string, code .matlab-string {color: #a020ef;}
pre .matlab-number, code .matlab-number {color: #333;}
pre .matlab-bracket, code .matlab-bracket {color: #333;}
pre .matlab-comment, code .matlab-comment {color: #228b22;}
pre .matlab-comment span, code .matlab-comment span {color: #228b22; font-weight: normal;}
正则表达式匹配的js文件
/*
MATLAB Highlighter 1.55, a small and lightweight javascript library for colorizing your MATLAB syntax.
http://matlabtricks.com/matlab-highlighter
Licensed under the MIT license
Copyright (c) 2013, Zoltan Fegyver
*/
function highlightMATLABCode(d) {
function g(i) {
return (i >= "A" && i <= "Z") || (i >= "a" && i <= "z") || (i == ")")
}
function m(r, j, i) {
var s = j.index,
t;
while (s >= i) {
t = r.charAt(--s);
if (t == "
") {
break
}
if (t == "'") {
continue
} else {
return !g(t)
}
}
return true
}
function a(i) {
var j = i.length - 1,
r;
while (j > 0) {
r = i.charAt(--j);
if (r == "
") {
return true
}
if (r == "%") {
return false
}
}
return true
}
function n(t) {
var s, u = 0,
r, v = /('[^'
]*')/gi,
j = [];
while (s = v.exec(t)) {
if (m(t, s, u)) {
var w = t.slice(u, s.index);
for (var i = j.length - 2; i >= 0; i -= 2) {
if (w.indexOf("
") > -1) {
break
}
w = w.concat(j[i])
}
if (a(w)) {
r = s.index + s[1].length;
j.push(t.slice(u, s.index));
j.push(t.slice(s.index, r));
u = r
}
}
}
j.push(t.slice(u));
return j
}
function b(u, j) {
var w = '<span class="',
v = "</span>";
if (j) {
return [w, 'matlab-string">', u, v].join("")
} else {
var t = [{
r: /('|break|case|catch|classdef|continue|else|elseif|end|for|function|global|if|otherwise|parfor|persistent|return|spmd|switch|try|while|')/gi,
s: "keyword"
}, {
r: /([0-9]+)/gi,
s: "number"
}, {
r: /([(){}[]]+)/gi,
s: "bracket"
}, {
r: /(%[^
]*)/gi,
s: "comment"
}];
for (var r = 0, s = t.length; r < s; r++) {
u = u.replace(t[r].r, [w, "matlab-", t[r].s, '">$1', v].join(""))
}
return u
}
}
function q(u) {
var w = [],
s = [];
if (typeof u === "undefined") {
u = {
tagPre: true,
tagCode: false,
className: "matlab-code"
}
}
if (typeof u !== "object") {
w.push(document.getElementById(u))
} else {
if (u.tagCode) {
s.push("code")
}
if (u.tagPre) {
s.push("pre")
}
for (var t = 0; t < s.length; t++) {
var x = document.getElementsByTagName(s[t]);
for (var r = 0, v = x.length; r < v; r++) {
if ((u.className == "") || ((x[r].className.toString().length > 0) && ((" " + x[r].className + " ").indexOf(" " +
u.className + " ") > -1))) {
w.push(x[r])
}
}
}
}
return w
}
var p = q(d);
for (var f = 0, o = p.length; f < o; f++) {
var c = n(p[f].innerhtml.toString().replace(/<brs*/?>/mg, "
")),
h = [],
l = " ";
for (var e = 0, k = c.length; e < k; e++) {
h.push(b(c[e], e % 2))
}
p[f].innerHTML = h.join("").replace(/^[ ]/gm, l).replace(/
/gm, "<br>").replace(/ /gm, l + l)
}
};
调用演示
<pre class="matlab-code">
% 为输出创建文件
!touch testFile.txt
fid = fopen('testFile.txt','w');
for i = 1:10
frprintf(fid,'%6.2f
',i);
end
</pre>
高亮结果
% 为输出创建文件 !touch testFile.txt fid = fopen(‘testFile.txt‘,‘w‘); for i = 1:10 frprintf(fid,‘%6.2f ‘,i); end
BUG
虽然这样做可以实现高亮,但是于此同时,代码块右上角的 复制按钮失去了复制功能。原因是正常的代码块是这样被解释成高亮的
<pre>
<code>
</code>
</pre>
复制调用的js代码会将 code
部分加上 id = "copy_target_1"
这样类似的标签,才能被识别成可以复制的内容,而前面的方法并未出现code
,所以功能实现不了!
以上是关于博客园Markdown模式的MATLAB代码高亮方案的主要内容,如果未能解决你的问题,请参考以下文章
使用highlightjs_markdown编辑器自定义博客园代码高亮
博客园自定义页面风格设计 后续篇(页面设计模式及代码高亮 鼠标点击效果升级)