痞客邦部落格程式上色相關文章:



  • highlight.js 的介紹文章貼在後面.
  • highlight.js 的插件 CopyButtonPlugin 的介紹文章貼在這裡

highlight.js 加行號



一開始在痞客邦套用 highlight.js 時, 沒有找到可以設定行號的功能. 隨後又在它的文件網站上看到作者希望保持原本 highlight.js 的設計初衷 "單純" (simplicity). 不只是程式上的單純化, 還有應用上的單純化, 簡單化. 因此原作者也就堅持不加上行號的功能(註一). 所以使用時也就沒有多想, 沒有行號就沒有行號唄.

後來 (2016/10/19) 不經意在 GitHub 上發現有人幫它寫了個加行號的 plugin(註二). 當時因為工作比較忙, 只是簡單的記錄下來, 想說以後有空再試吧. 沒想到一放就是好幾年, 今天清理未完成的貼文時看到它, 那就馬上來試試吧!

註一: 原文參見 https://highlightjs.readthedocs.io/en/latest/line-numbers.html.

註二: highlight.js line numbers Plugin 的 GitHub 網址: https://github.com/wcoder/highlightjs-line-numbers.js/

highlightjs-line-numbers.js 使用方法


使用時, 貼程式的地方和 highlight.js 一樣: 同樣的, 程式的第一行緊接<code> tag 之後.

<div><pre>
<code class="C">從這裡開始寫你要上色的程式碼
...
你要上色的程式碼
...
</code>
</pre></div>

差別只在引入 highlight.js 之後, 附加一行 (下例的 line 3) 引入 highlightjs-line-numbers.js. 還有, 執行 hljs.highlightAll(); 之後, 附加執行 hljs.initLineNumbersOnLoad(); (line 6). 同樣的痞客邦會阻斷我們執行自定義的 JS 程式, 所以我們必需將 JS 程式碼變成 HTML 註解 目前 (2024/10) 痞客邦已經放開執行自定義的 JS 程式的大部份限制, 我們已經無需將 JS 程式碼變成 HTML 註解:

  • <script> tag 後面要加 <!--
  • </script> tag 前面要加 -->

另外 hljs.initLineNumbersOnLoad(); 預設不會幫只有一行的程式段附加行號. 如果真的有這個需要, 可以附帶參數 {singleLine: true}只有一行的程式段也可以附加行號 (v2.1 新增功能).

<link href="//cdnjs.cloudflare.com/ajax/libs/highlight.js/11.10.0/styles/night-owl.min.css" rel="stylesheet" />
<script src="//cdnjs.cloudflare.com/ajax/libs/highlight.js/11.10.0/highlight.min.js"></script>
<script src="//cdnjs.cloudflare.com/ajax/libs/highlightjs-line-numbers.js/2.8.0/highlightjs-line-numbers.min.js"></script>
<script><!--
hljs.highlightAll();
hljs.initLineNumbersOnLoad({singleLine: true});
--></script>

還有如果啟始行號不是 1 時, JS 可以使用 startFrom 指定 (v2.8 新增功能).

hljs.lineNumbersBlock(myCodeBlock, {
	startFrom: 10
})

HTML 頁面, 則使用 data-ln-start-from 屬性指定.

<pre>
	<code data-ln-start-from="10">
	...
	</code>
</pre>

如果你在套用 highlightjs-line-numbers.js 之後, 還有自己客製化的需要, 它也很貼心的為大家準備了一些 selector.

CSS selector描述
.hljs-ln-line 選擇整個上色的程式 (包含行號部份)
.hljs-ln-line[data-line-number="i"] 選擇第i行程式 (包含行號部份)
.hljs-ln-numbers 選擇整個行號部份
.hljs-ln-numbers[data-line-number="i"] 選擇第i行行號
.hljs-ln-code 選擇整個上色的程式 (不包含行號)
.hljs-ln-code[data-line-number="i"] 選擇第i行程式 (不包含行號)

highlightjs-line-numbers.js 自定義 CSS


當然我們免不了有時會需要自定義 CSS. 但是這又會觸犯到痞客邦不給手機版自定義 CSS 的潛規則. 比較容易的方法是把以下的程式碼直接貼在文章的最後面:

<p id="myCSS"></p>
<script><!--
document.getElementById("myCSS").outerHTML=[
  '<style type="text/css">'
 ,'.hljs-ln tr { background-color:inherit }'
 ,'.hljs-ln td { border:inherit }'
 ,'.hljs-ln td.hljs-ln-numbers { text-align:right; padding-right:4px}'
 ,'.hljs-ln td.hljs-ln-code { border-left:2px solid #999; padding-left:5px }'
 ,'</style>'].join('');
--></script>

其中, 第 5~8 行應該是大家都會需要的部份: 調整行高, 行號靠右, 還有行號和程式之間加一直槓.

這段小程式其實大家也可以用在為某一篇文章附加專用的 CSS.

CopyButtonPlugin 插件



今日 (2024/09/28) 不小心瞄了一下別人介紹 highlight.js 的文章, 提到有 Copy to Clipboard 的插件. 所以就順便研究了一下, 不過看完了之後覺得那個不好用. 於是又動手搜了一下, 並找到了這個: highlightjs-copy

它的使用方法也很簡單, 先引入 JS 及 CSS 檔.

<link href="//unpkg.com/highlightjs-copy/dist/highlightjs-copy.min.css" rel="stylesheet" />
<script src="//unpkg.com/highlightjs-copy/dist/highlightjs-copy.min.js"></script>
  • 基礎用法:
    hljs.addPlugin(new CopyButtonPlugin())
    
  • 自動隠藏功能開關:
    hljs.addPlugin(
      new CopyButtonPlugin({
        autohide: false, // Always show the copy button
      })
    )
    
  • 附加 callback 函數:
    hljs.addPlugin(
      new CopyButtonPlugin({
        callback: (text, el) => console.log("Copied to clipboard", text),
      })
    )
    
  • 附加修改拷貝後文字的函數:
    hljs.addPlugin(
      new CopyButtonPlugin({
        hook: (text, el) => text + "\nCopied from my cool website.",
      })
    )
    
  • 本地化:
    hljs.addPlugin(
      new CopyButtonPlugin({
        lang: "zh-tw",
      })
    );
    
    如果你的網頁已經指定語言 <html lang="zh-tw">, 則可以不必另行指定 lang.
    目前支援十種語言: en, es, pt-BR, fr, de, ja, ko, ru, zh, zh-tw.

我在使用時唯一遇到的問題是: 按鈕有點大 (操作上方便些), 但是如果程式只有一行時, 就有點 '杯具' 了. 所以我把它的大小改小了一些.

.hljs-copy-button { font-size:.8em; top:.5em; right:.5em; width:2em; height:2em }

最後貼上我自己在 pixnet 痞客邦部落格使用 highlight.js 的 HTML 片段.

<link href="//unpkg.com/highlightjs-copy/dist/highlightjs-copy.min.css" rel="stylesheet" />
<script src="//unpkg.com/highlightjs-copy/dist/highlightjs-copy.min.js"></script>

<link href="//cdnjs.cloudflare.com/ajax/libs/highlight.js/11.10.0/styles/night-owl.min.css" rel="stylesheet" />
<script src="//cdnjs.cloudflare.com/ajax/libs/highlight.js/11.10.0/highlight.min.js"></script>
<script src="//cdnjs.cloudflare.com/ajax/libs/highlightjs-line-numbers.js/2.8.0/highlightjs-line-numbers.min.js"></script>
<p id='myCSS'></p>
<script>
document.getElementById('myCSS').outerHTML=[
 '<style>'
,'.hljs-ln tr { background-color:inherit }'
,'.hljs-ln td { border:inherit }'
,'.hljs-ln td.hljs-ln-numbers { text-align:right; padding-right:4px}'
,'.hljs-ln td.hljs-ln-code { border-left:2px solid #999; padding-left:5px }'
,'.hljs-copy-button { font-size:.8em; top:.5em; right:.5em; width:2em; height:2em }'
,'</style>'].join('');
if (typeof(hljs) !== 'undefined') {
	hljs.addPlugin(new CopyButtonPlugin({lang:'zh-tw'}))
	hljs.highlightAll()
	hljs.initLineNumbersOnLoad({singleLine: true})
}
</script>

更新 2024/10/17


今日收到作者在 github issue 的回覆, 問題已經解決了. 真是太好了. 所以就順便測了一下, 發現目前的版本將 copy icon 的 padding 變小了, 剛好可以放在一行裡, 同時也多了讓使用者自行客製化的設定.

不過, 也有個小缺點: 在行動裝置上它會有誤判的情形. 這主要是在痞客邦部落格上我的 CSS 整個是由 MS OneDrive 非同步載入 JS 再產生的. 但還沒輸到它執行, hljs 就準備好, 並開始執行了. 所以就這麼抓取到錯誤的設定. 正好 mergeHTMLPlugin 的問題也解決了, 於是乾脆都轉 v11 好了. 前面貼的 HTML 片斷的第 15 行也可以順便刪了, 換成下面這行好及時修正 CSS, 讓 CopyButtonPlugin 可以正確無誤.

,'.article-content-inner .hljs {line-height:1.25em; padding:.25em }'


為了大家閱讀上的方便, 我把原本貼在 "Syntax High Light (在 痞客邦部落格 中使用)" 後面, 介紹 highlight.js 的部份都搬過來了.

還有麻煩注意一下, 本文中所列的 JS 使用部落格舊編輯模擬器這個 plugin (在擴充管理功能裡安裝) 來修改你的貼文, 並且需要切換到純文字模式, 並勾選 "不要系統換行" 才能正常運作.

highlight.js



網址 https://highlightjs.org/

後來發現這個好像比較易用一些, 預設的調色組合也多一些. 8.6 版共支援 125 種語言及 63 種調色組合(styles)

比起 syntaxhighlighter, 它的缺點是:

  • (內建功能) 不支援自動加行號
  • C 語法有些許錯誤 (據稱 8.7 版已修正)

優點是:

  • 這個功能由於資安漏洞在 v11 被取消了, 想要在 v11 裡繼續使用這個功能, 需要加掛一個插件: mergeHTMLPlugin, 細節請參看 "JavaScript: 客製化 highligh.js" 這一篇貼文. 要額外上色的文字段落可以帶有 <span></span>, 所以可加上一些自訂的變化, 如: 粗體, 加上刪除線, 自訂顏色...
  • 可以 HTML, CSS, Javascript 一起上色, syntaxhighlighter 一次只能套用一種 (有點機車)

下面例子的調色組合 night-owl

<link href="//cdnjs.cloudflare.com/ajax/libs/highlight.js/11.10.0/styles/night-owl.min.css" rel="stylesheet" />
<script src="//cdnjs.cloudflare.com/ajax/libs/highlight.js/11.10.0/highlight.min.js"></script>
<script><!--hljs.highlightAll();--></script>

<div><pre>
<code class="C++">從這裡開始寫你要上色的程式碼
...
你要上色的程式碼
...
</code>
</pre></div>

用法說明:

2015/10/06 更新


目前版本更新為 8.8.0 版共支援 135 種語言及 65 種調色組合(styles)

2016/10/19 更新


目前版本更新為 9.7.0 版共支援 166 種語言及 77 種調色組合(styles)

發現可以顯示行號的 plugin: https://github.com/wcoder/highlightjs-line-numbers.js/

2020/04/04 更新


目前版本更新為 9.18.1 版共支援 185 種語言及 91 種調色組合(styles)

痞客邦的手機版, 會破壞它的分行, 用 PC 看則沒有這個問題.

2020/04/18 更新


"痞客邦的手機版, 會破壞它的分行" 的部份已經查清楚且修復. 原因是手機版的 CSS 多了一個設定:

.article-content-inner{overflow-wrap:break-word;line-height:1.5}

問題就出在 overflow-wrap:break-word 由於這個屬性會繼承, 所以迼成 .article-content-inner 這個容器以下的許多元素都不產生 overflow 了, 尤其是 <code>, <pre> 這二個需要保持內文原樣的 HTML tag 也都發生了在不應該斷行的地方出現了斷行. 所以只要自訂一個 CSS 把它改回來即可. 不過會產一些副作用: 太長的英文字串如 URL 之類的不會在版面邊界折返, 而是在依符號, 英文單字邊界折返. 這會讓這類 URL 在手機直立版面時, 影響週邊, 使得文章不好閱讀.

.article-content-inner{overflow-wrap:normal}

插入上述 CSS 的辦法. 簡單的:

<p id='myCSS'></p>
<script><!--
document.getElementById("myCSS").outerHTML=[
    '<style type="text/css">'
   ,'.article-content-inner{overflow-wrap:normal}'
   ,'</style>'].join('');
--></script>

複雜的: 請參考我的這一篇貼文 [置頂] 關於 痞客邦 的手機版廣告

2020/05/02 更新


目前版本更新為 10.0.1 版共支援 189 種語言及 91 種調色組合(styles)

2024/09/20 更新


目前版本更新為 11.10.0 版共支援 192 種語言及 498 種調色組合(themes)

2024/09/24 更新


修正 highlight.js使用方法: 改為 v11.10, 並因應 v11 改版改用新的啟動函數. 原始如下:

<link href="//cdnjs.cloudflare.com/ajax/libs/highlight.js/10.0.1/styles/night-owl.min.css" rel="stylesheet" />
<script src="//cdnjs.cloudflare.com/ajax/libs/highlight.js/10.0.1/highlight.min.js" type="text/javascript"></script>
<script><!--hljs.initHighlightingOnLoad();--></script>

<div><pre>
<code class="C++">從這裡開始寫你要上色的程式碼
...
你要上色的程式碼
...
</code>
</pre></div>

修正後: 第 3 行的 hljs.initHighlightingOnLoad() 改為 hljs.highlightAll(), 並取消 HTML 註解 (因 Pixnet 放寬了 JS 的執行)

<link href="//cdnjs.cloudflare.com/ajax/libs/highlight.js/11.10.0/styles/night-owl.min.css" rel="stylesheet" />
<script src="//cdnjs.cloudflare.com/ajax/libs/highlight.js/11.10.0/highlight.min.js"></script>
<script>hljs.highlightAll();</script>

<div><pre>
<code class="C++">從這裡開始寫你要上色的程式碼
...
你要上色的程式碼
...
</code>
</pre></div>

修正 highlightjs-line-numbers.js使用方法: highlightjs-line-numbers.js 改為 v2.8. 原始如下:

<link href="//cdnjs.cloudflare.com/ajax/libs/highlight.js/10.0.1/styles/night-owl.min.css" rel="stylesheet" />
<script src="//cdnjs.cloudflare.com/ajax/libs/highlight.js/10.0.1/highlight.min.js" type="text/javascript"></script>
<script src="//cdnjs.cloudflare.com/ajax/libs/highlightjs-line-numbers.js/2.7.0/highlightjs-line-numbers.min.js" type="text/javascript"></script>
<script><!--
hljs.initHighlightingOnLoad();
hljs.initLineNumbersOnLoad({singleLine: true});
--></script>

修正後:

<link href="//cdnjs.cloudflare.com/ajax/libs/highlight.js/11.10.0/styles/night-owl.min.css" rel="stylesheet" />
<script src="//cdnjs.cloudflare.com/ajax/libs/highlight.js/11.10.0/highlight.min.js"></script>
<script src="//cdnjs.cloudflare.com/ajax/libs/highlightjs-line-numbers.js/2.8.0/highlightjs-line-numbers.min.js"></script>
<script>
hljs.highlightAll();
hljs.initLineNumbersOnLoad({singleLine: true});
</script>

arrow
arrow
    創作者介紹
    創作者 MagicJackTing 的頭像
    MagicJackTing

    傑克! 真是太神奇了!

    MagicJackTing 發表在 痞客邦 留言(0) 人氣()