使用 Google Code Prettify 高亮 Markdown / Org 至 HTML 中的代码块

Emacs 处理 markdown 时代码高亮的最佳解决方案? 继续讨论:

我的印象中[1],支持 Emacs Lisp 的代码高亮工具本来就很少,而且这当中还有把 Emacs Lisp 当作 Common Lisp 或 Clojure 等其它 Lisp 来高亮的,不太清楚为什么这么做,总之我觉得效果不太好(所以我在论坛里贴 Emacs Lisp 代码从不用高亮)。我感觉 Google Code Prettify 的效果好一些[2],貌似它有专门的 Emacs Lisp 支持,也不会当作别的 Lisp 或 Scheme 来高亮。

所以我目前打算用它来高亮 Markdown 和 Org mode 导出至 HTML 中的代码块,透过 Pandoc

(setq markdown-command
      "pandoc -s -f markdown -t html --no-highlight -A ~/include-code-prettify.html | code-prettify")

文件 ~/include-code-prettify.html 是用来 Include Google Code Prettify 的 JS 文件的,内容是:

<script src="https://cdn.rawgit.com/google/code-prettify/master/loader/run_prettify.js?lang=lisp"></script>

脚本 code-prettify 是用来把 Pandoc 的 <pre> 写法转化成 Google Code Prettify 所支持的写法:

#!/usr/bin/env ruby
#
# code-prettify - Convert Pandoc's <pre> for Google Code Prettify
#
# Pandoc outputs:
# 
#   <pre class="elisp"><code>...</code></pre>
#
# but Google Code Prettify requires
#
#   <pre class="prettyprint"><code class="language-el">...</code></pre>
#
# Usage: 

require "nokogiri"

doc = Nokogiri::HTML(ARGF.read)

doc.css('pre > code').each do |element|
  # Skip if no class in <pre>
  next unless element.parent['class']
  # Skip if the class is Org mode's example block
  next if element.parent['class'] == 'example'

  element['class'] ||= ""
  element.parent['class'].split(/\s+/).each do |cl|
    cl = 'el' if cl == 'elisp'
    element['class'] <<= " language-#{cl}"
  end
  element.parent['class'] = 'prettyprint'
  element['class'] = element['class'].strip
end

print doc.to_html

暂时用来测试 Org mode 的命令

(defun chunyang-org-preview-via-pandoc ()
  (interactive)
  (unless (eq 'org-mode major-mode)
    (user-error "Error: this is not Org mode"))
  (let ((input (buffer-file-name))
        (output (org-export-output-file-name ".html")))
    (shell-command
     (format "pandoc -s -f org -t html --no-highlight -A ~/include-code-prettify.html %s | code-prettify > %s"
             (shell-quote-argument input)
             (shell-quote-argument output)))
    (browse-url output)))

直接从命令行调用的话

$ pandoc -s --no-highlight -A ~/include-code-prettify.html -t html foo.md  | code-prettify

[1] 我了解过的代码高亮工具:

[2] 一组效果对比:

这是 highlight.js 的效果:

(defun sort-sexps (reverse beg end)
  "Sort sexps in the Region."
  (interactive "*P\nr")
  (save-restriction
    (narrow-to-region beg end)
    (goto-char (point-min))
    (let ((nextrecfun (lambda () (skip-syntax-forward "-.>")))
          (endrecfun  #'forward-sexp))
      (sort-subr reverse nextrecfun endrecfun))))

这是 Google Code Prettify 的效果(来源: Sort Sexps )

2 个赞