使用 Sphinx 撰寫技術文件並生成 PDF 總結

qiwihui發表於2019-02-24

這幾天準備編排部分翻譯的書籍和文件,找了好些工具,最終定格在 Sphinx 上,並基於 ReadTheDocs 提供的 SaaS 服務進行分發和分享。本篇部落格是對整個過程的一次記錄和總結。

專案程式碼:qiwihui/sphinx-doc-starter

認識 Sphinx

Sphinx 是一個基於 Python 的文件生成專案。最早只是用來生成 Python 的專案文件,使用 reStructuredText 格式。但隨著專案的逐漸完善,很多非 Python 的專案也採用 Sphinx 作為文件寫作工具,甚至完全可以用 Sphinx 來寫書。

使用 Sphinx 生成文件的優點包括:

  • 豐富的輸出格式: 支援輸出為 HTML(包括 Windows 幫助文件),LaTeX(可以列印PDF版本), manual pages(man 文件), 純文字等若干種格式;
  • 完備的交叉引用: 語義化的標籤,並可以自動化連結函式、類、引文、術語等;
  • 明晰的分層結構: 輕鬆定義文件樹,並自動化連結同級/父級/下級文章;
  • 美觀的自動索引: 可自動生成美觀的模組索引;
  • 精確的語法高亮: 基於 Pygments 自動生成語法高亮;
  • 開放的擴充套件: 支援程式碼塊的自動測試,自動包含 Python 的模組自述文件,等等。

開始

這個過程包括如下步驟:

  • 安裝 Sphinx
  • 第一個文件
  • 線上託管
  • 生成 PDF

安裝 Sphinx

Sphinx 依賴於 Python,並提供了 Python 包,所以使用 pip 安裝既可。這裡我只安裝了 sphinx-doc 這個包。

pip install sphinx-doc
複製程式碼

這時,通過 bash 自動補全(連續兩下 tab),可以看到有幾個命令,Sphinx 推薦使用 sphinx-quickstart,這是一個設定嚮導。

$ sphinx-
sphinx-apidoc      sphinx-autogen     sphinx-build       sphinx-quickstart
複製程式碼

設定 Sphinx

執行 sphinx-quickstart,以下主要設定專案名稱,作者名稱以及語言(zh_CN)即可,其他預設。

$ sphinx-quickstart
Welcome to the Sphinx 1.8.4 quickstart utility.

Please enter values for the following settings (just press Enter to
accept a default value, if one is given in brackets).

Selected root path: .

You have two options for placing the build directory for Sphinx output.
Either, you use a directory "_build" within the root path, or you separate
"source" and "build" directories within the root path.
> Separate source and build directories (y/n) [n]: y

Inside the root directory, two more directories will be created; "_templates"
for custom HTML templates and "_static" for custom stylesheets and other static
files. You can enter another prefix (such as ".") to replace the underscore.
> Name prefix for templates and static dir [_]: 

The project name will occur in several places in the built documentation.
> Project name: 一本書
> Author name(s): qiwihui
> Project release []: 0.0.1

If the documents are to be written in a language other than English,
you can select a language here by its language code. Sphinx will then
translate text that it generates into that language.

For a list of supported codes, see
http://sphinx-doc.org/config.html#confval-language.
> Project language [en]: zh_CN

The file name suffix for source files. Commonly, this is either ".txt"
or ".rst".  Only files with this suffix are considered documents.
> Source file suffix [.rst]: 

One document is special in that it is considered the top node of the
"contents tree", that is, it is the root of the hierarchical structure
of the documents. Normally, this is "index", but if your "index"
document is a custom template, you can also set this to another filename.
> Name of your master document (without suffix) [index]: 
Indicate which of the following Sphinx extensions should be enabled:
> autodoc: automatically insert docstrings from modules (y/n) [n]: 
> doctest: automatically test code snippets in doctest blocks (y/n) [n]: 
> intersphinx: link between Sphinx documentation of different projects (y/n) [n]: 
> todo: write "todo" entries that can be shown or hidden on build (y/n) [n]: 
> coverage: checks for documentation coverage (y/n) [n]: 
> imgmath: include math, rendered as PNG or SVG images (y/n) [n]: 
> mathjax: include math, rendered in the browser by MathJax (y/n) [n]: 
> ifconfig: conditional inclusion of content based on config values (y/n) [n]: 
> viewcode: include links to the source code of documented Python objects (y/n) [n]: 
> githubpages: create .nojekyll file to publish the document on GitHub pages (y/n) [n]: 

A Makefile and a Windows command file can be generated for you so that you
only have to run e.g. `make html` instead of invoking sphinx-build
directly.
> Create Makefile? (y/n) [y]: 
> Create Windows command file? (y/n) [y]: 

Creating file ./source/conf.py.
Creating file ./source/index.rst.
Creating file ./Makefile.
Creating file ./make.bat.

Finished: An initial directory structure has been created.

You should now populate your master file ./source/index.rst and create other documentation
source files. Use the Makefile to build the docs, like so:
   make builder
where "builder" is one of the supported builders, e.g. html, latex or linkcheck.
複製程式碼

解釋1,整個設定過程包括:

  1. 是否分離原始檔目錄 source 和生成檔案目錄 build,預設否;

  2. 模板目錄 templates 和靜態檔案目錄 static 字首,預設為_

  3. 專案名稱;

  4. 專案作者;

  5. 專案版本,預設為空;

  6. 專案語言,預設為 en

  7. 文件副檔名,預設為 .rst

  8. 首頁檔名,預設為 index

  9. 開啟的擴充套件,均預設為否:

    • autodoc
    • doctest
    • intersphinx
    • todo
    • coverage
    • imgmath
    • mathjax
    • ifconfig
    • viewcode
    • githubpages
  10. 生成 Makefile,預設是;

  11. 生成 Windows 用命令列,預設是。

解釋2,專案目錄檔案結構如下:

sphinx-test
├── Makefile
├── build
├── make.bat
└── source
    ├── _static
    ├── _templates
    ├── conf.py
    └── index.rst
複製程式碼

其中:

  • Makefile:可以看作是一個包含指令的檔案,在使用 make 命令時,可以使用這些指令來構建文件輸出。
  • build:生成的檔案的輸出目錄。
  • make.bat:Windows 用命令列。
  • _static:靜態檔案目錄,比如圖片等。
  • _templates:模板目錄。
  • conf.py:存放 Sphinx 的配置,包括在 sphinx-quickstart 時選中的那些值,可以自行定義其他的值。
  • index.rst:文件專案起始檔案。

接下來看看預設生成的內容:

$ make html
Running Sphinx v1.8.4
loading translations [zh_CN]... done
making output directory...
building [mo]: targets for 0 po files that are out of date
building [html]: targets for 1 source files that are out of date
updating environment: 1 added, 0 changed, 0 removed
reading sources... [100%] index                                                                                                         looking for now-outdated files... none found
pickling environment... done
checking consistency... done
preparing documents... done
writing output... [100%] index                                                                                                          generating indices... genindex
writing additional pages... search
copying static files... done
copying extra files... done
dumping search index in Chinese (code: zh) ... done
dumping object inventory... done
build succeeded.

The HTML pages are in build/html.
複製程式碼

然後直接在瀏覽器中開啟 build/html/index.html 這個檔案。

initial

預設風格為 alabaster,可以改成 ReadTheDocs 的風格: sphinx_rtd_theme

# -- Options for HTML output -------------------------------------------------

# The theme to use for HTML and HTML Help pages.  See the documentation for
# a list of builtin themes.
#
html_theme = 'sphinx_rtd_theme'
複製程式碼

rtd_theme

第一個文件

我們以一下文件為例:

This is a Title
===============
That has a paragraph about a main subject and is set when the '='
is at least the same length of the title itself.

Subject Subtitle
----------------
Subtitles are set with '-' and are required to have the same length
of the subtitle itself, just like titles.

Lists can be unnumbered like:

 * Item Foo
 * Item Bar

Or automatically numbered:

 #. Item 1
 #. Item 2

Inline Markup
-------------
Words can have *emphasis in italics* or be **bold** and you can define
code samples with back quotes, like when you talk about a command: ``sudo``
gives you super user powers!
複製程式碼

將之寫入 example.rst 中,並修改 index.rst 為:

Welcome to 一本書's documentation!
==================================

.. toctree::
   :maxdepth: 2
   :caption: 目錄:

   example

Indices and tables
==================

* :ref:`genindex`
* :ref:`modindex`
* :ref:`search`
複製程式碼

重新編譯,這時文件已經改變。

first_doc
first_doc_page

線上託管

ReadTheDocs 可是直接用於託管 sphinx 生成的網頁文件。 將之前的文件用 Git 管理,並推送到 Github,然後在 ReadTheDocs 中 Import a Project 即可。

rtd

另外,可以設定自定義域名:

  1. 在域名管理中新增 DNS 的 CNAME 記錄到 readthedocs.io,比如 onebook.qiwihui.com
  2. 在專案的 Admin -> Domains 中設定上一步新增的域名,開啟 HTTPS,儲存即可。

add_new_domain

過程很簡單。

生成 PDF

Sphinx 生成 PDF 的過程先將 rst 轉換為 tex,再生產PDF。這個過程遇到了比較多的坑,最後總結下來過程如下:

首先,安裝 Tex 環境。在 Mac 上,推薦安裝 MacTex 而不是 BasicTex,對於新手來說 BasicTex 上需要自己處理很多以來問題。完成後使用 tlmgr 更新 TexLive。

$ brew cask install mactex
$ sudo tlmgr update --self
複製程式碼

然後,在 con.py 中設定 latex_enginelatex_elements 兩個引數,同時也可以設定 latex_documents 引數來設定文件。

latex_engine = 'xelatex'
latex_elements = {
    'papersize': 'a4paper',
    'pointsize': '11pt',
    'preamble': r'''
\usepackage{xeCJK}
\setCJKmainfont[BoldFont=STZhongsong, ItalicFont=STKaiti]{STSong}
\setCJKsansfont[BoldFont=STHeiti]{STXihei}
\setCJKmonofont{STFangsong}
\XeTeXlinebreaklocale "zh"
\XeTeXlinebreakskip = 0pt plus 1pt
\parindent 2em
\definecolor{VerbatimColor}{rgb}{0.95,0.95,0.95}
\setcounter{tocdepth}{3}
\renewcommand\familydefault{\ttdefault}
\renewcommand\CJKfamilydefault{\CJKrmdefault}
'''
}
# 設定文件
latex_documents = [
    (master_doc, 'sphinx.tex', '你的第一本 Sphinx 書',
     '作者:qiwihui', 'manual', True),
]
複製程式碼

最後,編譯:

$ make latexpdf
複製程式碼

make latexpdf 會完成 rst轉換為 tex 並將 tex 生成 PDF,可以手動分開:

$ make latex
$ cd build/latex
$ make
複製程式碼

build/latex 下可以檢視到生成的 PDF 文件。

字型

使用 fc-list 來獲取字型資訊,修改相應字型設定即可。

$ brew install fontconfig
$ fc-list :lang=zh
複製程式碼

遇到的問題:

  1. 遇到 "! LaTeX Error: File '*.sty' not found." 類的問題:

解決:使用 sudo tlmgr install 安裝相應的包即可。

總結

簡單過了一下整個文件的流程,總體來說,Sphinx非常適合用來編寫專案文件,reStructuredText 比起 Markdown 也有太多的優勢,值得推薦。

GitHub repo: qiwihui/blog

Follow me: @qiwihui

Site: QIWIHUI

相關文章