放牧代码和思想
专注自然语言处理、机器学习算法

使用rst2pdf拓展sphinx生成PDF

目录

当初项目文档是用sphinx写的,一套rst下来make html得到一整个漂亮的在线文档。现在想要将文档导出为离线的handbook pdf,于是找到了rst2pdf这个项目,作为sphinx的拓展,然后加上少量配置即可输出中文PDF。

rst2pdf

简介

rst2pdf是一个将 reStructuredText 转换为 PDF 的工具,具有下列特性:

  • 自定义页面布局

  • 支持层叠样式表

  • 支持内嵌TTF和Type1字体

  • 支持几乎所有语言的语法高亮

  • 使用reStructuredText作为源文件

  • 支持字间距调整

安装

easy_install rst2pdf

配置rst2pdf

注册到sphinx项目

需要告诉sphinx我们安装了rst2pdf,并且将其作为插件使用。只需在项目根目录下的conf.py中配置:

# Add any Sphinx extension module names here, as strings. They can be
# extensions coming with Sphinx (named 'sphinx.ext.*') or your custom
# ones.
extensions = [
    'sphinx.ext.autodoc',
    'rst2pdf.pdfbuilder'
]

即可。然后,在conf.py中拷入PDF相关的配置:

# -- Options for PDF output --------------------------------------------------

# Grouping the document tree into PDF files. List of tuples
# (source start file, target name, title, author, options).
#
# If there is more than one author, separate them with \\.
# For example: r'Guido van Rossum\\Fred L. Drake, Jr., editor'
#
# The options element is a dictionary that lets you override
# this config per-document.
# For example,
# ('index', u'MyProject', u'My Project', u'Author Name',
#  dict(pdf_compressed = True))
# would mean that specific document would be compressed
# regardless of the global pdf_compressed setting.

pdf_documents = [
    ('index', u'HanLP Handbook', u'HanLP Handbook', u'hankcs'),
]

# A comma-separated list of custom stylesheets. Example:
pdf_stylesheets = ['a3','zh_CN']

# Create a compressed PDF
# Use True/False or 1/0
# Example: compressed=True
#pdf_compressed = False

# A colon-separated list of folders to search for fonts. Example:
pdf_font_path = ['C:\\Windows\\Fonts']

# Language to be used for hyphenation support
pdf_language = "zh_CN"

# Mode for literal blocks wider than the frame. Can be
# overflow, shrink or truncate
pdf_fit_mode = "shrink"

# Section level that forces a break page.
# For example: 1 means top-level sections start in a new page
# 0 means disabled
#pdf_break_level = 0

# When a section starts in a new page, force it to be 'even', 'odd',
# or just use 'any'
#pdf_breakside = 'any'

# Insert footnotes where they are defined instead of
# at the end.
#pdf_inline_footnotes = True

# verbosity level. 0 1 or 2
#pdf_verbosity = 0

# If false, no index is generated.
#pdf_use_index = True

# If false, no modindex is generated.
#pdf_use_modindex = True

# If false, no coverpage is generated.
#pdf_use_coverpage = True

# Documents to append as an appendix to all manuals.
#pdf_appendices = []

# Enable experimental feature to split table cells. Use it
# if you get "DelayedTable too big" errors
#pdf_splittables = False

# Set the default DPI for images
#pdf_default_dpi = 72

# Enable rst2pdf extension modules (default is only vectorpdf)
# you need vectorpdf if you want to use sphinx's graphviz support
#pdf_extensions = ['vectorpdf']

# Page template name for "regular" pages
#pdf_page_template = 'cutePage'

# Show Table Of Contents at the beginning?
# pdf_use_toc = False

# How many levels deep should the table of contents be?
pdf_toc_depth = 2

# Add section number to section references
pdf_use_numbered_links = False

# Background images fitting mode
pdf_fit_background_mode = 'scale'

具体配置项的值请自行调整,不需要严格按照我的来。

样式表

在项目根目录下创建一个zh_CN.json,写入:

{
  "embeddedFonts": [
    "simsun.ttc"
  ],
  "fontsAlias": {
    "stdFont": "simsun",
    "stdBold": "simsun",
    "stdItalic": "simsun",
    "stdBoldItalic": "simsun",
    "stdMono": "simsun",
    "stdMonoBold": "simsun",
    "stdMonoItalic": "simsun",
    "stdMonoBoldItalic": "simsun",
    "stdSans": "simsun",
    "stdSansBold": "simsun",
    "stdSansItalic": "simsun",
    "stdSansBoldItalic": "simsun"
  },
  "styles": [
    [
      "base",
      {
        "wordWrap": "CJK"
      }
    ],
    [
      "literal",
      {
        "wordWrap": "None"
      }
    ]
  ]
}

关于以上样式的说明:

  • embeddedFonts用于嵌入字体,经试验,必须包含至少四个值才不会报错。不过这四个字体值可以是重复的。

  • fontsAlias用来指定各类字形用什么字体。如stdFont指正文字体,stdBold指粗体,stdItalic指斜体。其他的还有stdBoldItalic粗斜体,stdMono等宽体,等等。确保所用字体已经安装在你的操作系统上,且字体必须是TTF类型的(Windows环境下限制比较多~)。

  • wordWrap用于指定换行规则,CJK就是适用于中日韩文字的规则。这是从网上的模板抄来的,但经我的测试发现,如果用CJK规则的话,中英混排的文档里面英文部分就没法正常断行,这真是个遗憾。实际上,fontsAlias的分类很多都只对英文字体有意义,如严格来讲中文是没有所谓斜体的(不过因为Word的普及,经常看到中文被设置为斜体的情形)。如果是纯中文文档,当然随便用哪些中文字体都行,如宋体。现实中,经常会有中英文混排的情形,所以如果全用中文字体的话,英文部分就没法显示斜体等字形了。

  • 关于pdf_stylesheets的说明:这个参数中默认使用的某些样式包含了一些字体,而这些字体并非在所有操作系统上都找得到。'sphinx'和'kerning'都是默认提供的样式,要么不用它们,要么直接修改其包含的字体。'a4'指设置输出的PDF为A4纸大小。默认的样式文件可以在rst2pdf的安装路径下找到。

然后配置编译脚本

Windows用户,在make.bat中加入:

if "%1" == "pdf" (
   %SPHINXBUILD% -b pdf %ALLSPHINXOPTS% %BUILDDIR%/pdf
   if errorlevel 1 exit /b 1
   echo.
   echo.Build finished. The pdf files are in %BUILDDIR%/pdf.
   goto end
)

类Unix用户修改Makefile:

pdf:
    $(SPHINXBUILD) -b pdf $(ALLSPHINXOPTS) $(BUILDDIR)/pdf
    @echo
    @echo "Build finished. The PDF files are in _build/pdf."

输出PDF

然后一句:

make pdf

就能输出PDF了。

解决findfonts.py:249 Unknown font:

这应该是由于pdf_font_path配置有误造成的,事实上,我确定配置无误rst2pdf还是找不到字体文件,于是我修改了X:\Program Files (x86)\Python27\Lib\site-packages\rst2pdf\findfonts.py第236行,在

fontfile = get_nt_fname(fname)

后面加了一句:

fontfile = 'C:\\Windows\\Fonts\\simsun.ttc'

强行解决问题。

解决rst2pdf输出PDF为空白文档

事实上,在字体正常的情况下,我发现输出的PDF依然是空白的:

在使用二分法排除rst文件中的问题后,我发现这是由于PDF开头的目录造成的。当目录超出一页时就会发生这种情况,我倾向于认为这是rst2pdf的一个bug。

解决方法是将pdf_toc_depth调小一点,或者干脆不生成目录,pdf_use_toc = False。

PDF效果

于是再次重试,可以生成漂亮的PDF了:

Reference

http://sphinx-users.jp/cookbook/pdf/rst2pdf.html

http://ralsina.me/static/manual.pdf

Sphinx reStructuredText中文PDF输出解决方案之rst2pdf

知识共享许可协议 知识共享署名-非商业性使用-相同方式共享码农场 » 使用rst2pdf拓展sphinx生成PDF

分享到:更多 ()

评论 4

  • 昵称 (必填)
  • 邮箱 (必填)
  • 网址
  1. #3

    = =! 在哪里能下载到HanLP啊?

    cibiluozu3年前 (2015-03-27)回复
  2. #2

    你好,能否做个友情链接啊?

    lovehack5283年前 (2015-03-25)回复
  3. #1

    您好,请问一下,启动server ,到IO method(auto thread):epoll (with changelist)都是正常的,但是接着就跳出Segmentation fault(core dumped),怎么处理?

    曼城荒芜3年前 (2015-03-19)回复

我的开源项目

HanLP自然语言处理包基于DoubleArrayTrie的Aho Corasick自动机