天天看點

使用ReadtheDocs托管技術文檔

ReadtheDocs

​​Read the Docs​​非常适合寫軟體文檔以及編寫一些教程、電子書之類。對于一些一兩篇文章就能寫清楚的可以記筆記或寫部落格, 但是如果要寫成一個系列的,不如寫成一本書的形式,更美觀,也更系統。

​​Read the Docs​​是一個線上文檔托管系統, 你可以從各種版本控制系統中導入文檔,如果你使用​​webhooks​​, 那麼每次送出代碼後可以自動建構并上傳至readthedocs網站,非常友善。

現有的寫電子書的方式,有以下幾個解決方案,優劣勢也很明顯:

  • 寫部落格,跟散文堆在一起,不便索引。
  • GitHub Wiki,适合做知識整理,但排版一般,不友善檢視。
  • GitBook,樣式不好看,通路速度慢。

經過比較最後鎖定Sphinx + GitHub + ReadtheDocs 作為文檔寫作工具,用 Sphinx 生成文檔,GitHub 托管文檔,再導入到 ReadtheDocs。

​​Sphinx​​

Sphinx是一個基于Python的文檔生成項目,最早隻是用來生成 Python 官方文檔,随着工具的完善, 越來越多的知名的項目也用他來生成文檔,甚至完全可以用他來寫書采用了reStructuredText作為文檔寫作語言, 不過也可以通過子產品支援其他格式,待會我會介紹怎樣支援MarkDown格式。

安裝Sphinx:

pip install sphinx sphinx-autobuild sphinx_rtd_theme

      

Copy

這一步時間會安裝很多python依賴,耐心等等..

初始化:

# 建立文檔根目錄
mkdir -p /root/work/scrapy-cookbook
cd scrapy-cookbook/
# 可以回車按預設配置來寫
sphinx-quickstart

      

下面是我填寫的,其他基本上預設即可:

> Separate source and build directories (y/n) [n]:y
> Project name: scrapy-cookbook
> Author name(s): Xiong Neng
> Project version []: 0.2
> Project release [1.0]: 0.2.2
> Project language [en]: zh_CN

      

安裝軟體tree檢視目錄樹結構:

yum install tree

      

然後運作 ​

​tree -C .​

​ 檢視生成的sphinx結構:

.
├── build
├── make.bat
├── Makefile
└── source
    ├── conf.py
    ├── index.rst
    ├── _static
    └── _templates

      

添加一篇文章,在source目錄下建立hello.rst,内容如下:

hello,world
=============

      

​index.rst​

​ 修改如下:

Contents:
.. toctree::
:maxdepth: 2

hello

      

更改主題 sphinx_rtd_theme

更改source/conf.py:

import sphinx_rtd_theme
html_theme = "sphinx_rtd_theme"
html_theme_path = [sphinx_rtd_theme.get_html_theme_path()]

      

預覽效果

然後在更目錄執行​

​make html​

​,進入​

​build/html​

​目錄後用浏覽器打開​

​index.html​

使用ReadtheDocs托管技術文檔

image

toctree 支援多級目錄,比如要想将python.rst,java.rst筆記在不同的目錄,toctree這樣設定:

Contents:

.. toctree::

python/python
swift/swift

      

注意中間的空行

支援markdown編寫

通過​​recommonmark​​ 來支援markdown

pip install recommonmark

      

然後更改conf.py:

from recommonmark.parser import CommonMarkParser
source_parsers = {
'.md': CommonMarkParser,
}
source_suffix = ['.rst', '.md']

      

AutoStructify

如果想使用進階功能,可以添加AutoStructify配置,在​

​conf.py​

​中添加:

# At top on conf.py (with other import statements)
import recommonmark
from recommonmark.transform import AutoStructify

# At the bottom of conf.py
def setup(app):
app.add_config_value('recommonmark_config', {
'url_resolver': lambda url: github_doc_root + url,
'auto_toc_tree_section': 'Contents',
            }, True)
app.add_transform(AutoStructify)

      

網上有個詳細配置: ​​https://github.com/rtfd/recommonmark/blob/master/docs/conf.py​​

然後修改剛剛的​

​hello.rst​

​,改用熟悉的​

​hello.md​

​編寫:

## hello world

### test markdown

      

再次運作​

​make html​

​後看效果,跟前面一樣。

GitHub托管

一般的做法是将文檔托管到版本控制系統比如github上面,push源碼後自動建構釋出到readthedoc上面, 這樣既有版本控制好處,又能自動釋出到readthedoc,實在是太友善了。

先在GitHub建立一個倉庫名字叫scrapy-cookbook, 然後在本地.gitignore檔案中添加​

​build/​

​目錄,初始化git,commit後,添加遠端倉庫。

具體幾個步驟非常簡單,參考官方文檔:​​https://github.com/rtfd/readthedocs.org​​:

  1. 在Read the Docs上面注冊一個賬号
  2. 登陸後點選 “Import”.
  3. 給該文檔項目填寫一個名字比如 “scrapy-cookbook”, 并添加你在GitHub上面的工程HTTPS連結, 選擇倉庫類型為Git
  4. 其他項目根據自己的需要填寫後點選 “Create”,建立完後會自動去激活Webhooks,不用再去GitHub設定
  5. 一切搞定,從此隻要你往這個倉庫push代碼,readthedoc上面的文檔就會自動更新.

注:在建立read the docs項目時候,語言選擇”Simplified Chinese”

在建構過程中出現任何問題,都可以登入readthedoc找到項目中的”建構”頁檢視建構曆史,點選任何一條檢視詳細日志:

使用ReadtheDocs托管技術文檔

我将自己以前部落格裡面的關于scrapy的文章都遷移至readthedoc,現在看看效果:

使用ReadtheDocs托管技術文檔

生成PDF

首先要安裝TeX Live,CentOS 7的yum庫中的TeX Live版本比較老,是以直接安裝官網上的版本。

在​​官網頁面​​ 下載下傳安裝包​​install-tl-unx.tar.gz​​

如果先安裝依賴包:

yum install perl-Digest-MD5

      

然後解壓縮安裝:

tar zxf install-tl-unx.tar.gz
cd install-tl-*
./install-tl  # install-tl-windows on Windows
[... messages omitted ...]
Enter command: i
[... when done, see below for post-install ...]

      

安裝時間會比較長,我這裡安裝大概要50分鐘左右,請耐心等待…

安裝完後配置PATH,在​

​/etc/profile​

​後面添加:

export PATH=/usr/local/texlive/2016/bin/x86_64-linux:$PATH

      

注意上面的路徑改成你自己正确的路徑,然後執行​

​source /etc/profile​

​即可

如果要生成中文PDF,還需要确認安裝了東亞語言包和字型包

yum -y install fontconfig ttmkfdir
# /usr/share目錄就可以看到fonts和fontconfig目錄
# 首先在/usr/share/fonts目錄下建立一個目錄chinese:
cd /usr/share/fonts
mkdir chinese
# 緊接着需要修改chinese目錄的權限:
chmod -R 755 /usr/share/fonts/chinese
# 從C:/Windows/Fonts目錄複制你想要的字型到chinese檔案夾
# msyh.ttf msyhbd.ttf simhei.ttf simsun.ttc wqy-microhei.ttc YaHeiConsolas.ttf
ttmkfdir -e /usr/share/X11/fonts/encodings/encodings.dir
vi /etc/fonts/fonts.conf
<!-- Font directory list -->
<dir>/usr/share/fonts</dir>
<dir>/usr/share/fonts/chinese</dir>

fc-cache
fc-list :zh

      

要用XeLaTeX 取代 pdflatex,我們需要修改​

​conf.py​

​:

# 注:在生成html的時候這句話要注釋
latex_engine = 'xelatex'

      

然後執行:

make clean
make latexpdf

      

完成之後在​

​build/latex​

​目錄中即可找到生成的pdf檔案了。

  1. ReadTheDocs可以自動生成中文PDF,但ReadTheDocs伺服器裡的TeXLive版本太老, 導緻隻能使用pdflatex而不能使用xelatex編譯,再加上伺服器上中文字型的限制, 是以生成的PDF效果較差,故不采用ReadTheDocs生成的PDF
  2. 本地安裝TeXLive 2016,用xelatex編譯,可生成更好效果的PDF,目前的政策是在本地生成PDF。

生成繁體PDF

先安裝opencc

wget https://github.com/BYVoid/OpenCC/archive/master.zip
unzip master.zip
yum install -y cmake gcc gcc-c++ doxygen
cd OpenCC-master
make && make install
ln -s /usr/lib/libopencc.so.2 /usr/lib64/libopencc.so.2

      

寫一個shell腳本來轉換源碼:

#!/bin/bash
# 将某個檔案夾所有檔案簡體轉換成繁體字

curdir=`pwd`
file_dir=${curdir}/$1
for f in $(find $file_dir -type f); do
#echo $f
    opencc -i "${f}" -o "${f}_"
mv -f "${f}_" "${f}"
done

      

簡體轉繁體

./stot.sh scrapy-cookbook/source/

      

然後上面的生成PDF步驟不變。

FAQ

build的時候出現錯誤:! Package inputenc Error: Unicode char 我 (U+6211)

解決辦法,在​

​conf.py​

latex_elements={# The paper size ('letterpaper' or 'a4paper').
'papersize':'a4paper',# The font size ('10pt', '11pt' or '12pt').
'pointsize':'12pt','classoptions':',oneside','babel':'',#必須
'inputenc':'',#必須
'utf8extra':'',#必須
# Additional stuff for the LaTeX preamble.
'preamble': r"""
\usepackage{xeCJK}
\usepackage{indentfirst}
\setlength{\parindent}{2em}
\setCJKmainfont{WenQuanYi Micro Hei}
\setCJKmonofont[Scale=0.9]{WenQuanYi Micro Hei Mono}
\setCJKfamilyfont{song}{WenQuanYi Micro Hei}
\setCJKfamilyfont{sf}{WenQuanYi Micro Hei}
\XeTeXlinebreaklocale "zh"
\XeTeXlinebreakskip = 0pt plus 1pt
"""}

      

WARNING: Pygments lexer name u’python run.py’ is not known

解決辦法,寫代碼的時候别用’’’python run.py這樣的格式,不支援

WARNING: nonlocal image URI found

解決辦法,更改conf.py

import sphinx.environment
from docutils.utils import get_source_line

def _warn_node(self, msg, node, **kwargs):
if not msg.startswith('nonlocal image URI found:'):
self._warnfunc(msg, '%s:%s' % get_source_line(node), **kwargs)

sphinx.environment.BuildEnvironment.warn_node = _warn_node

      

生成的PDF檔案中圖檔不能顯示的問題

解決辦法,因為文章裡面引用的是外部圖檔連結,導緻不能顯示圖檔, 将圖檔下載下傳到source/images目錄,然後改連結為相對路徑。

如要居中顯示圖檔,使用:

<center>![scrapy架構圖](/images/scrapy.png)</center>

      

自動生成标題問題

修改​

​conf.py​

​将manual改成howto

latex_documents = [
    (master_doc, 'scrapy-cookbook.tex', u'scrapy-cookbook Documentation',
u'Xiong Neng', 'howto'),
]

      

圖檔覆寫文字的問題

養成一個好習慣就是新增圖檔一定要空一行

one line

![scrapy架構圖](/images/scrapy.png)

two line

      

生成的pdf檔案中,每個章節都多了一層編号

我猜測這個問題的原因是sphinx将rst轉為LaTex檔案,再轉為PDF的。sphinx生成的LaTex檔案中, 使用了\Section标記段落,預設情況下\Section是自動編号的章節,而\Section*才是不帶自動編号的。

為了解決這個問題,需要手工編輯sphinx生成的python3-cookbook.tex

cd build/latex/
vi scrapy-cookbook.tex

      

在​

​\setcounter{tocdepth}{2}​

​下增加一行​

​\setcounter{secnumdepth}{-2}​

這行代碼關閉了章節編号的計數器,這樣生成的PDF就是目錄正确且章節不帶自動編号。 請注意别亂動裡面的東西,删除一個空行也不行。

然後執行指令:

xelatex scrapy-cookbook.tex

      

這時候生成的pdf檔案就是正常格式的了。如果一次執行不成功就再執行一次,很奇怪的事情。

具體原了解釋參見​​http://liam0205.me/2015/04/10/how-to-list-unnumbered-section-in-the-table-of-contents/​​

優化PDF顯示

這個參考 ​​https://github.com/yidao620c/python3-cookbook/issues/108​​

編輯tex檔案,在導言區的内容如下:

前面省略...
\title{《Python Cookbook》第三版}
\date{Dec 09, 2017}
\release{3.0.0}
\author{熊能}
\newcommand{\sphinxlogo}{\vbox{@@
\renewcommand{\releasename}{Release}
\makeindex

% 隐藏原目錄名
\renewcommand{\contentsname}{}

% 在 section 前插入分頁
\usepackage{titlesec}
\newcommand{\sectionbreak}{\clearpage}

% 章節編号隻編号到 subsection
\newcommand\normalsecnumdepth{\setcounter{secnumdepth}{2@@

% 所有層次章節都不編号
\newcommand\specialsecnumdepth{\setcounter{secnumdepth}{-2@@  

% toc 到 subsection
\newcommand\normaltocdepth{
    \setcounter{tocdepth}{2}
    \addtocontents{toc}{\setcounter{tocdepth}{2@@
}

% toc 到 section
\newcommand\specialtocdepth{
    \setcounter{tocdepth}{1}
    \addtocontents{toc}{\setcounter{tocdepth}{1@@
}

\begin{document}

\maketitle
\specialsecnumdepth
\specialtocdepth
\renewcommand{\contentsname}{}
\section{目錄}
\vspace{-36pt}
\sphinxtableofcontents
\phantomsection\label{\detokenize{index::doc@@

\section{版權}
\label{\detokenize{copyright::doc@@\label{\detokenize{copyright:copyright@@\label{\detokenize{copyright:python-cookbook-3rd-edition-documentation@@
\begin{DUlineblock}{0em}
\item[] 書名:    《Python Cookbook》3rd Edition
\item[] 作者:     David Beazley, Brian K. Jones
...

      

在 ​

​\section{第一章:資料結構和算法}​

​ 前插入 ​

​\normaltocdepth​

​\section{附錄A}​

​\specialtocdepth​

另外執行下面指令,删除每個章節多餘的Contents和下面的一行空格:

sed -i '/Contents:/,+1 d' python3-cookbook.tex

      

再次運作生成指令即可(最好執行2次):

xelatex python3-cookbook.tex