辛萬苦寫了篇技術分享,貼了一堆代碼,興高采烈地發到了自己的博客網站上。結果卻發現代碼全是白底黑字,字體還難看得很,你瞬間就沒了興致。能不能讓網頁也能像 IDE 那樣,做帶語法高亮的炫酷顯示呢?來看一看 Highlight.js 吧,看這個語法高亮庫如何點亮你的代碼。
Highlight.js
Highlight.js,是在 Github 上由 highlight.js 組織開源的前端代碼語法高亮庫,代碼倉庫在 https://github.com/highlightjs/highlight.js,目前版本為 10.1.0。其不依賴于任何框架,自帶對于大量編程語言和標記語言的語法高亮規則,和主流的高亮色彩方案,且可以自由擴展。其支持自動語言檢測,使用極為方便,是在網頁上進行語法高亮的不二之選。
highlight.js語法高亮庫
Highlight.js 的 CSS 文件的選擇決定高亮配色方案,默認為 Default,另外還有如 Monokai Sublime、Ocean、Solarized Dark、Tomorrow 等經典的主流配色方案。
而 JS 文件的選擇決定可以支持的語言。主要的 highlight.min.js 包含了一些主流的語言,包括 C++、XML、Markdown、Java 等。如果需要一些其他的語言,則要另外引用該語言對應JS文件。
Highlight.js 在瀏覽器中可以簡單的引用 CDN 來使用:
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/highlight.js/10.1.0/styles/default.min.css">
<script src="https://cdnjs.cloudflare.com/ajax/libs/highlight.js/10.1.0/highlight.min.js"></script>
Highlight.js 使用十分簡單,在引用了 CSS 和 JS 后,執行
hljs.initHighlightingOnLoad();
Highlight.js就會自動查找網頁中以標簽 pre 和 code 所包裹的代碼
<pre><code>...</code></pre>
并自動檢測代碼語言,進行高亮渲染。我們也可以為 code 標簽添加語言名稱的 class,來顯式地標明代碼語言。我們可以看一個使用示例,注意實際代碼中尖括號等 HTML 轉義字符需要進行轉義處理:
<html>
<head>
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/highlight.js/10.1.0/styles/monokai-sublime.min.css">
<script src="https://cdnjs.cloudflare.com/ajax/libs/highlight.js/10.1.0/highlight.min.js"></script>
</head>
<body>
<pre><code class="cpp">#include <iostream>
int main(int argc, char *argv[]) {
/* An annoying "Hello World" example */
for (auto i = 0; i < 0xFFFF; i++)
cout << "Hello, World!" << endl;
char c = '\n';
unordered_map <string, vector<string> > m;
m["key"] = "\\\\"; // this is an error
return -2e3 + 12l;
}
</code></pre>
<script>
hljs.initHighlightingOnLoad();
</script>
</body>
</html>
該網頁對于 C++ 語言片段使用了 Monokai Sublime 主題進行了語法高亮渲染:
使用Highlight.js渲染C++代碼
可以看到,包括關鍵字、注釋和字面值等都有了不同顏色的渲染,輸出十分美觀。以下則是使 Dracula 主題對 Javascript 代碼渲染的例子:
使用Highlight.js渲染Javascript代碼
我們也可以不使用 pre 和 code 標簽來包裹代碼,改為使用自定義的容器,使用時需要注意換行和等寬字體的問題。
document.querySelectorAll('div.code').forEach((block) => {
hljs.highlightBlock(block);
});
在渲染大量代碼時,為避免瀏覽器卡死,可以使用 Web Worker 來在后臺進行渲染:
// index.html
addEventListener('load', () => {
const code = document.querySelector('#code');
const worker = new Worker('worker.js'); // 新建Worker
worker.onmessage = (event) => { code.innerHTML = event.data; } // 接受渲染后的HTML
worker.postMessage(code.textContent); // 傳遞代碼
});
// worker.js
onmessage = (event) => {
importScripts('<path>/highlight.min.js');
const result = self.hljs.highlightAuto(event.data); // 高亮渲染
postMessage(result.value); // 返回HTML
};
Highlight.js 使得在前端頁面進行語法高亮變得十分方便,為在網頁顯示的代碼增添了顏色和生機。
Highlight.js 文檔詳盡,設計簡潔,為編寫新的語言支持和配色方案提供了很大支持,定制化能力和可擴展性極強。Highlight.js 的代碼包含了對于各種語言的語法解析,和不同配色方案的設計,對于對編程語言和語法高亮領域感興趣的開發者是一座珍貴的寶庫。
行代碼就能讓我的網站支持代碼高亮的工具庫,也支持在 Vue 中使用,強烈推薦給大家。
highlight.js 是一款使用 javascript 開發代碼高亮工具庫,能夠讓網頁上的代碼顯示接近我們使用的代碼編輯器的高亮樣式,從而看起來更舒服,增強閱讀體驗。
highlight.js 官網截圖
常來我網站的小伙伴都知道,我的文章有一個欄目是“前端”,主要推薦一下實用的前端開源項目或者組件庫,寫技術類文章免不了要貼代碼,我的網站基于 wordpress 搭建,此前我一直為找一款代碼高亮插件煩惱,但大部分 wordpress 的代碼高亮插件實在太臃腫,出來的樣式又不美觀。大多時候是截圖 VsCode 的代碼界面,甚至還用過 codepng 這個工具把代碼變成圖片貼在文章中,但這樣做是美觀了,但也存在2個問題:
最終還是找到了 highlight.js,完美解決了上面兩個問題,而且配置簡單,演示漂亮,定制化簡單。不禁感嘆:用純前端的方式解決,才能精準控制,實現想要的效果。
下面以我的網站為例,展示將 highlight.js 用在我們的項目上的方法。首先 highlight.js 支持 cdn 直接引入和 npm 安裝,我的網站基于 wordpress 開發,主題是自己寫的,最簡單的方式就是在文章詳情頁引入 highlight.js 和主題樣式。
雖然 highlight.js 支持幾百種開發語言,但為了將文件體積控制到最小,我們可以點擊“get version”按鈕進入下載頁,通過勾選我們需要的開發語言,來構建最輕量的庫。
下載解壓后得到的 highlight.min.js 就是我們需要引入的 js 文件,主題樣式都在 style 文件夾里,我選擇了一個比較喜歡的 monokai-sublime 主題,只需要一個 css 文件,然后初始化:
<link href="/js/monokai-sublime.min.css" rel="stylesheet" type="text/css">
<script src="/js/highlight.min.js"></script>
<script>
hljs.highlightAll();
</script>
就是這么簡單,highlight.js 會自動將文章中的 <pre><code></code></pre> 代碼進行識別語言并且高亮,一切就是這么簡單。為了讓代碼顯示更協調,我用幾行 css 控制了包裹層的圓角以及背景顏色、字體大小等,大功告成。
.post-content .wp-block-code {
background-color: #F6F8FF;
border-radius: 16px;
font-size: 16px;
padding: 22px 22px 22px 38px;
margin-top: 22px;
margin-bottom: 22px;
}
.post-content .wp-block-code {
line-height: 1.2;
font-size: 15px;
padding: 10px;
overflow-x: auto;
}
.post-content .wp-block-code code {
position: relative;
background-color: unset !important;
}
當然 highlight.js 也能在 vue 項目中使用,安裝:
npm install highlight.js
在 Vue 文件中使用 (通過 highlight.js for Vue ) :
<div id="app">
<!-- bind to a data property named `code` -->
<highlightjs autodetect :code="code" />
<!-- or literal code works as well -->
<highlightjs language='javascript' code="var x = 5;" />
</div>
需要注意的是,自動識別模式不能100%識別出代碼所屬的開發語言,識別錯誤會導致高亮樣式是別的語言的,這種情況下可以手動設置一個 class 來精準控制:
<pre><code class="language-javascript">...</code></pre>
官網提供了詳盡的使用文檔,有更多代碼高亮的控制,但不足的就是 highlight.js 沒有顯示行號的支持,需要通過再引入一個庫 (highlightjs-line-numbers.js) 或者自行實現。
highlight.js 是一款基于 BSD 許可證開源的 javascript 工具庫,任何個人和公司都可以免費下載用于自己的項目,包括商用項目。
關注我,持續分享高質量的免費開源、免費商用的資源。
↓↓點擊查看本次分享的網址以及代碼高亮效果
highlight.js - 讓網頁上的代碼高亮美化的免費開源工具庫|那些免費的磚
些在線圖文編輯器不支持直接插入代碼塊,但可以直接粘貼 HTML 格式的高亮代碼塊。
花了一點時間研究了一下各家的編輯器,規則卻各不相同。有的要求代碼塊被包含于 <code> ... </code> 或者 <pre> <code> ... </code> </pre> , 有些要求 class 屬性里包含 "code" 關鍵詞,或者要求代碼塊里必須包含至少一個 <br> 。如果不符合這些要求,不是變成普通文本,就是丟失換行縮進,或者丟失顏色樣式。
所以,這就難了。先得找個支持代碼高亮的編輯器,仔細地選擇并復制代碼塊,復制完還得編輯剪貼板里的 HTML 。這就不如干脆寫個轉換工具了。
因為瀏覽器操作系統剪貼板可能不太方便,下面用 aardio 寫一個工具軟件。
先看軟件成品演示:
軟件用法:
1、輸入編程語言名稱(支持自動完成)。
2、然后在輸入框中粘貼要轉換的編程代碼。
3、點擊「復制高亮代碼塊」按鈕。
然后我們就可以打開在線圖文編輯器直接粘貼生成的高亮代碼塊了。
下面是這個軟件的 aardio 源代碼:
import win.ui;
/*DSG{{*/
var winform = win.form(text="HTML 代碼塊生成工具 - 本工具使用 aardio 語言編寫";right=1055;bottom=674;bgcolor=16777215)
winform.add(
button={cls="button";text="復制高亮代碼塊";left=633;top=609;right=1000;bottom=665;bgcolor=16777215;color=14120960;db=1;dr=1;font=LOGFONT(h=-14);note="可在網頁編輯器直接粘貼";z=4};
cmbLangs={cls="combobox";left=262;top=625;right=446;bottom=651;db=1;dl=1;edge=1;items={"javascript"};mode="dropdown";z=2};
editCode={cls="edit";left=1;top=4;right=1052;bottom=599;db=1;dl=1;dr=1;dt=1;edge=1;hscroll=1;multiline=1;vscroll=1;z=5};
static={cls="static";text="請選擇語言:";left=70;top=629;right=248;bottom=649;align="right";db=1;dl=1;transparent=1;z=3};
webCtrl={cls="custom";text="自定義控件";left=8;top=10;right=1048;bottom=604;db=1;dl=1;dr=1;dt=1;hide=1;z=1}
)
/*}}*/
import web.view;
var wb = web.view(winform.webCtrl);
import win.clip.html;
wb.export({
onHighlight = function(html,background,foreground){
html = `<pre class="code" style="overflow-x:auto;text-align:left;box-shadow: rgba(216, 216, 216, 0.5) 0px 0px 0px 1px inset;padding:10px;border-radius:3px;background-color:`+background+`;color:`+foreground+`;white-space:pre;word-break:break-all;display:block;font-size:14px;font-style:normal;font-variant-ligatures:normal;font-variant-caps: normal;font-family: "Consolas", Consolas, "Liberation Mono", Menlo, Courier, monospace"><code>`
+ html + `</code></pre>`;
html,count = string.replace(html,'\n',"<br>");
if(!count){
html = string.replace(html,`\</code\>\</pre\>$`,`<br></code></pre>`);
}
var cb = win.clip.html();
cb.write(html);
winform.setTimeout(
function(){
winform.editCode.show(true);
winform.webCtrl.show(false);
winform.text = "HTML 代碼塊生成工具 - 已復制高亮代碼塊到剪貼板,可在網頁直接粘貼";
},1000);
};
setLanguages = function(langs){
winform.languages = langs;
}
})
winform.cmbLangs.onEditChange = function(){
var text = string.lower(winform.cmbLangs.text);
var items = table.filter( winform.languages : {}, lambda(v) string.startWith(v,text) );
winform.cmbLangs.autoComplete(items);
}
winform.cmbLangs.editBox.disableInputMethod();
import web.prism;
import wsock.tcp.asynHttpServer;
var httpServer = wsock.tcp.asynHttpServer();
httpServer.run(web.prism,{
["/index.html"] = /*****
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8" />
<link href="prism.css" rel="stylesheet" />
</head>
<body>
<pre id="code-pre"><code id="code" class="lang-javascript"></code></pre>
<script src="prism.js"></script>
<script>
function computedColorStyle(element, options = {}) {
Array.prototype.forEach.call(element.children,child => {
computedColorStyle(child, options);
});
const computedStyle = getComputedStyle(element);
element.style["color"] = computedStyle.getPropertyValue("color");
}
highlight = function(code,language){
var html = Prism.highlight(code, Prism.languages[language], language);
var codeEle = document.getElementById("code");
codeEle.innerHTML = html;
computedColorStyle(codeEle);
const computedStyle = getComputedStyle(codeEle);
onHighlight(codeEle.innerHTML
,getComputedStyle(document.getElementById("code-pre")).getPropertyValue("background-color")
,computedStyle.getPropertyValue("color"));
}
setLanguages( Object.keys(Prism.languages) );
</script>
</body>
</html>
*****/
});
wb.go( httpServer.getUrl("/index.html"));
winform.button.oncommand = function(id,event){
winform.text = "HTML 代碼塊生成工具 - 本工具使用 aardio 語言編寫"
winform.editCode.show(false);
winform.webCtrl.show(true);
wb.xcall("highlight",winform.editCode.text,winform.cmbLangs.text);
}
winform.show();
win.loopMessage();
打開 aardio 創建工程,然后復制粘貼上面的代碼到 main.aardio 里面就可以直接運行,或生成獨立 EXE 文件:
這個軟件的原理:
1、首先通過 WebView2 調用 Prism.js 高亮代碼。為了可以內存加載 Prism.js ( 支持生成獨立 EXE ),我寫了一個 aardio 擴展庫 web.prism 。關于 WebView2 請參考:放棄 Electron,擁抱 WebView2!JavaScript 快速開發獨立 EXE 程序
2、因為 Prism.js 生成的 HTML 代碼塊都是使用 class 屬性指定樣式,所以我們需要調用 getComputedStyle 獲取最終渲染的字體顏色屬性。
3、最后在 JavaScript 里調用 aardio 函數處理生成的 HTML 代碼塊,aardio 的任務是將 HTML 修改為更合適直接粘貼的格式,并盡可能地處理各圖文編輯器的兼容問題。然后調用 win.clip.html 將處理好的 HTML 復制到系統剪貼板:
import win.clip.html;
var cb = win.clip.html();
cb.write(html);
然后只要愉快地粘貼代碼塊就可以。
如果是 aardio 代碼不需要用這個工具,在 aardio 編輯器里右鍵直接點『 復制全部到 HTML 代碼塊 』就可以了:
*請認真填寫需求信息,我們會在24小時內與您取得聯系。