面向产品经理的Emacs教程:16. Org文件导出为其他格式

· 2743字 · 6分钟

1 课程回顾 🔗

通过上节课的学习,我们了解了如何在Emacs里通过Org mode的 plantuml, gnuplot, lilypond 等代码块来画各种图。通过这种方式,我们可以专注在我们的内容上,而不用关心我们的格式,我们图形绘制等。这非常符合Emacs的哲学——文本即一切!

今天我们来学习如何将org文件导出为其他格式。

2 org文件能导出为什么格式? 🔗

前文说到,Org文件是一种基于Markup语言的文本文件,它与Markdown文件异曲同工,而Markup一个重要特点就是很容易转换成其他格式,产品经理常用到的格式有:

  • HTML网页
  • Markdown文件
  • PDF文件
  • Reveal.js幻灯片
  • Hugo博客站点
  • HTML静态站点
  • docx, pptx

其中对我个人而言,最常用的导出格式为HTML网页和PDF。

3 org文件导出通用设置 🔗

我们先来进行org文件导出的通用设置:

(use-package ox
  :ensure nil
  :custom
  (org-export-with-toc t)
  (org-export-with-tags 'not-in-toc)
  (org-export-with-drawers nil)
  (org-export-with-priority t)
  (org-export-with-footnotes t)
  (org-export-with-smart-quotes t)
  (org-export-with-section-numbers t)
  (org-export-with-sub-superscripts '{})
  ;; `org-export-use-babel' set to nil will cause all source block header arguments to be ignored This means that code blocks with the argument :exports none or :exports results will end up in the export.
  ;; See:
  ;; https://stackoverflow.com/questions/29952543/how-do-i-prevent-org-mode-from-executing-all-of-the-babel-source-blocks
  (org-export-use-babel t)
  (org-export-headline-levels 9)
  (org-export-coding-system 'utf-8)
  (org-export-with-broken-links 'mark)
  (org-export-default-language "zh-CN") ; 默认是en
  ;; (org-ascii-text-width 72)
  )

;; export extra
(use-package ox-extra
  :ensure nil
  :config
  (ox-extras-activate '(ignore-headlines))
  )

设置完后,我们按下 C-x C-e 键后,可以看到默认就支持了 iCalendar、HTML、LaTex、ODT、Plain Text、Publish(HTML静态站点)这几个导出格式。

我们按下 h o 键,即导出为 HTML 文件并打开,然后可以看到默认浏览器打开了这个网页:

这个网页的样式也是Org mode自带的CSS样式。后面我们会尝试改造它。

4 org文件导出为网页 🔗

4.1 ox-html导出设置 🔗

我们先来对HTML导出做一个基本设置:

(use-package ox-html
  :ensure nil
  :init
  ;; add support for video
  (defun org-video-link-export (path desc backend)
    (let ((ext (file-name-extension path)))
      (cond
       ((eq 'html backend)
        (format "<video width='800' preload='metadata' controls='controls'><source type='video/%s' src='%s' /></video>" ext path))
       ;; fall-through case for everything else
       (t
        path))))
  (org-link-set-parameters "video" :export 'org-video-link-export)
  :custom
  (org-html-doctype "html5")
  (org-html-html5-fancy t)
  (org-html-checkbox-type 'unicode)
  (org-html-validation-link nil))

(use-package htmlize
  :ensure t
  :custom
  (htmlize-pre-style t)
  (htmlize-output-type 'inline-css))

完成HTML导出设置后,我们再次导出 emacs-config.org 可以看到导出的HTML好看多了,代码块还有了语法高亮。

4.2 修改一下导出的样式 🔗

org-html-themes 项目可以改变org文件导出为html的默认样式,项目的几个主题非常好看,用法也很简单,只需要在每个org文件开始的地方,加上下面这段代码即可(以 readtheorg 这个主题为例):

#+SETUPFILE: https://fniessen.github.io/org-html-themes/org/theme-readtheorg.setup

当然,我们也可以把这个项目的代码克隆到本地,假设项目的本地目录存放在 ~/.emacs.d/org-html-themes/ 文件夹,然后根据自己的需要找到项目文件夹下 src/readtheorg_theme/css/readtheorg.css 文件进行按需修改,例如我就做了以下的调整,将所有的图片都居中显示了。

/* to make image center */
figure{
    margin: 24px 0px 24px 0px;
    text-align:center;
}

修改完后,需要以本地而非在线的方式来引用这些css,可以在 ~/.emacs.d/ 文件夹下创建一个 org-setupfile.org 文件,文件的内容如下:

#+HTML_HEAD: <link rel="stylesheet" type="text/css" href="/Users/randolph/.emacs.d/org-html-themes/src/readtheorg_theme/css/htmlize.css"/>
#+HTML_HEAD: <link rel="stylesheet" type="text/css" href="/Users/randolph/.emacs.d/org-html-themes/src/readtheorg_theme/css/readtheorg.css"/>

#+HTML_HEAD: <script type="text/javascript" src="/Users/randolph/.emacs.d/org-html-themes/src/lib/js/jquery.min.js"></script>
#+HTML_HEAD: <script type="text/javascript" src="/Users/randolph/.emacs.d/org-html-themes/src/lib/js/bootstrap.min.js"></script>
#+HTML_HEAD: <script type="text/javascript" src="/Users/randolph/.emacs.d/org-html-themes/src/lib/js/jquery.stickytableheaders.min.js"></script>
#+HTML_HEAD: <script type="text/javascript" src="/Users/randolph/.emacs.d/org-html-themes/src/readtheorg_theme/js/readtheorg.js"></script>

最后一步,就是在每个org文件的文件头的位置,加上下面这一行代码即可:

#+SETUPFILE: ~/.emacs.d/org-setupfile.org

这样就可以通过本地文件的方式引用 readtheorg 这个主题了,我们可以根据自己的需要修改 css 文件来达到我们要的自定义效果。

我们在 emacs-config.org 文件前面加上这行代码后,再次导出,可以看到样式变成了如下,非常漂亮,也非常适合作为技术文档输出:

  1. 如果不想输出作者、日期等信息,可以在org文件头添加如下配置项即可: #+OPTIONS: author:nil date:nil email:nil timestamp:nil

  2. 除了 org-html-themes 外,还有很多选择,如 https://github.com/gongzhitaao/orgcss 等,也都很好看,可以根据自己的需要选择导出模板。

5 org文件导出为PDF 🔗

org文件导出为PDF有好几种做法:

  • 先导出为HTML,然后通过浏览器的打印为PDF功能生成PDF
  • 通过 ox-latex 导出为PDF
  • 通过 ox-pandoc 导出为PDF

我个人最常使用的是第一种。下面介绍如何设置 ox-latex 来导出PDF。

5.1 ox-latex导出PDF设置 🔗

ox-latex 是Org mode自带的功能,可以将Org文件导出为latex文件和PDF文件。下面我们来设置它:

(use-package ox-latex
  :ensure nil
  :defer t
  :config
  (add-to-list 'org-latex-classes
               '("cn-article"
                 "\\documentclass[UTF8,a4paper]{article}"
                 ("\\section{%s}" . "\\section*{%s}")
                 ("\\subsection{%s}" . "\\subsection*{%s}")
                 ("\\subsubsection{%s}" . "\\subsubsection*{%s}")
                 ("\\paragraph{%s}" . "\\paragraph*{%s}")
                 ("\\subparagraph{%s}" . "\\subparagraph*{%s}")))

  (add-to-list 'org-latex-classes
               '("cn-report"
                 "\\documentclass[11pt,a4paper]{report}"
                 ("\\chapter{%s}" . "\\chapter*{%s}")
                 ("\\section{%s}" . "\\section*{%s}")
                 ("\\subsection{%s}" . "\\subsection*{%s}")
                 ("\\subsubsection{%s}" . "\\subsubsection*{%s}")))
  (setq org-latex-default-class "cn-article")
  (setq org-latex-image-default-height "0.9\\textheight"
        org-latex-image-default-width "\\linewidth")
  (setq org-latex-pdf-process
	    '("xelatex -interaction nonstopmode -output-directory %o %f"
	      "bibtex %b"
	      "xelatex -interaction nonstopmode -output-directory %o %f"
	      "xelatex -interaction nonstopmode -output-directory %o %f"
	      "rm -fr %b.out %b.log %b.tex %b.brf %b.bbl auto"
	      ))
  ;; 使用 Listings 宏包格式化源代码(只是把代码框用 listing 环境框起来,还需要额外的设置)
  (setq org-latex-listings t)
  ;; mapping jupyter-python to Python
  (add-to-list 'org-latex-listings-langs '(jupyter-python "Python"))
  ;; Options for \lset command(reference to listing Manual)
  (setq org-latex-listings-options
        '(
          ("basicstyle" "\\small\\ttfamily")       ; 源代码字体样式
          ("keywordstyle" "\\color{eminence}\\small")                 ; 关键词字体样式
          ;; ("identifierstyle" "\\color{doc}\\small")
          ("commentstyle" "\\color{commentgreen}\\small\\itshape")    ; 批注样式
          ("stringstyle" "\\color{red}\\small")                       ; 字符串样式
          ("showstringspaces" "false")                                ; 字符串空格显示
          ("numbers" "left")                                          ; 行号显示
          ("numberstyle" "\\color{preprocess}")                       ; 行号样式
          ("stepnumber" "1")                                          ; 行号递增
          ("xleftmargin" "2em")                                       ;
          ;; ("backgroundcolor" "\\color{background}")                   ; 代码框背景色
          ("tabsize" "4")                                             ; TAB 等效空格数
          ("captionpos" "t")                                          ; 标题位置 top or buttom(t|b)
          ("breaklines" "true")                                       ; 自动断行
          ("breakatwhitespace" "true")                                ; 只在空格分行
          ("showspaces" "false")                                      ; 显示空格
          ("columns" "flexible")                                      ; 列样式
          ("frame" "tb")                                              ; 代码框:single, or tb 上下线
          ("frameleftmargin" "1.5em")                                 ; frame 向右偏移
          ;; ("frameround" "tttt")                                       ; 代码框: 圆角
          ;; ("framesep" "0pt")
          ;; ("framerule" "1pt")                                         ; 框的线宽
          ;; ("rulecolor" "\\color{background}")                         ; 框颜色
          ;; ("fillcolor" "\\color{white}")
          ;; ("rulesepcolor" "\\color{comdil}")
          ("framexleftmargin" "5mm")                                  ; let line numer inside frame
          ))
  )

设置完后,我们按下 C-c C-e 导出当前文档,然后按下 l o 导出为 PDF 文件并打开,可以看到Emacs打开了生成的PDF文件:

6 org文件导出为Reveal.js幻灯片 🔗

我们可以通过 ox-reveal 插件,将org文件导出为漂亮的幻灯片。需要提前 安装reveal.js

  1. 克隆 reveal.js 项目
    cd ~/.emacs.d/ && git clone https://github.com/hakimel/reveal.js.git
    
  2. 安装依赖
    cd reveal.js && npm install
    

然后我们来安装和配置 ox-reveal 插件:

(use-package ox-reveal
  :ensure t
  :after ox
  :config
  (setq org-reveal-hlevel 1)
  ;; Avalable themes: night, black, white, league, beige, sky, serif, simple, solarized, blood, moon
  (setq org-reveal-theme "moon")
  ;; can also set root to a CDN cloud: https://cdn.jsdelivr.net/npm/reveal.js
  (setq org-reveal-root (expand-file-name "reveal.js" user-emacs-directory))
  (setq org-reveal-mathjax t)
  (setq org-reveal-ignore-speaker-notes t)
  ;; original title font size is TOO large!
  (setq org-reveal-title-slide "<h1><font size=\"8\">%t</font></h1><h2><font size=\"6\">%s</font></h2><p><font size=\"5\">%a</font><br/><font size=\"5\">%d</font></p>")
  ;; don't load highlight, use htmlize instead. If you want to add line-number, add -n in src block header
  (setq org-reveal-plugins '(markdown zoom notes search))
  (setq org-reveal-klipsify-src 'on)
  (setq org-reveal-extra-css (expand-file-name "reveal.js/css/extra.css" user-emacs-directory))
  )

安装完这个插件后,我们就可以通过Org mode来写PPT了,具体关于分页、动画等设置需要阅读一下 ox-reveal 插件的官方文档:

写完后,只需要按下 C-c C-e 导出,选择 R B 导出为 reveal.js 幻灯片网页并打开即可:

7 org文件导出为Markdown 🔗

我们通过 ox-gfm 插件来导出Github样式的Markdown文件。

(use-package ox-gfm
  :ensure t
  :after ox)

安装完插件后,我们可以通过 C-c C-e 导出当前文件,然后选择 g g 导出为 Markdown 文件。我们用marktext打开后可以看到导出的 Markdown 文件非常漂亮:

8 org文件导出为Office文件 🔗

org文件当然也可以导出为Office的Word和PPT文件,我们需要 ox-pandoc 这款插件。

(use-package ox-pandoc
  :ensure t
  :custom
  ;; special extensions for markdown_github output
  (org-pandoc-format-extensions '(markdown_github+pipe_tables+raw_html))
  (org-pandoc-command "/usr/local/bin/pandoc")
  )

安装完后,我们按 C-c C-e 并选择 p x 来导出为Word文件:

我们通过 C-c C-e 并选择 p p 来导出为PPT文件:

9 org文件导出为博客站点 🔗

如何通过Org mode来写博客将在后续的课程中专门讲述,这里就先不讲了。

10 结语 🔗

通过今天的学习,我们进一步了解了Org mode的强大之处,我们可以将org文件导出为各种各样的格式,基本上做到了All-in-one,当你习惯了 Emacs + Org mode 后,你会发现写文档写文章是多么愉悦的事。

这节课的配置文件的快照见:emacs-config-l16.org

你也可以在 这里 查看最新的配置文件。