最近折腾了一下自己的主页,为了方便(不需要在每次发布的时候「构建」静态网页),文章使用RsML写成,可以全部在客户端渲染。
但是EWW缺省配置下不支持XSLT,所以我就糊了一个函数,调用xsltproc
(其他实现当然也行)生成HTML再用它预览:
(defun eww-extract-xslt ()
(save-excursion
(goto-char (point-min))
(when (re-search-forward "<\\?xml-stylesheet [^>]*href=['\"]\\([^'\"]+\\)['\"]" nil t)
(let ((xslt (match-string 1))
(link (url-generic-parse-url (eww-current-url))))
(if (file-name-absolute-p xslt)
(progn
(setf (url-filename link) xslt)
(url-recreate-url link))
(let* ((path (file-name-directory (url-filename link)))
(xslt (expand-file-name xslt path)))
(setf (url-filename link) xslt)
(url-recreate-url link)))))))
(defun eww-render-xslt ()
(interactive)
(when (or (string-match "\\.xml$" (eww-current-url))
(save-excursion
(goto-char (point-min))
(or (looking-at "<\\?xml")
(re-search-forward "<\\?xml" nil t))))
(when-let* ((link (eww-extract-xslt))
(xslt (make-temp-file "sty" nil ".xsl"))
(xml (make-temp-file "src" nil ".xml"))
(html (make-temp-file "res" nil ".html"))
(command (format "xsltproc %S %S > %S" xslt xml html)))
(url-copy-file link xslt t)
(append-to-file nil nil xml)
(call-process-shell-command command nil nil)
(eww-open-file html))))
(add-hook 'eww-after-render-hook #'eww-render-xslt)
效果如此: