以前尝试用rst2pdf将Sphinx reStructuredText文档输出为PDF时总是报错,即便是用不含中文的文档也没成功过。rst2pdf其实是个不太完美的作品,其作者甚至说过他一度想要放弃这个项目了(见这里)。前几天偶然看到rst2pdf更新到0.91版本,据说是解决了Sphinx整合问题,我赶紧试了一下,于是便有了本文(基于Windows XP平台)。
截至本文发布时,如果你直接使用setuptool的命令esay_install rst2pdf来安装rst2pdf,那么你本地取到的版本依然是0.16。所以,若要使用最新的0.91版本,需要稍微改一下这个命令:easy_install “rst2pdf==0.91″。
接下来,按照rst2pdf用户手册的说明,在Sphinx的配置文件confy.py中添加了扩展名rst2pdf.pdfbuilder,并在该文件底部添加一系列代码(Options for PDF output)用于定制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’MyProject’, u’My Project’, u’Author Name’),
]
# A comma-separated list of custom stylesheets. Example:
pdf_stylesheets = [‘sphinx’,’kerning’,’a4′]
# A list of folders to search for stylesheets. Example:
pdf_style_path = [‘.’, ‘_styles’]
# 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 = [‘/usr/share/fonts’, ‘/usr/share/texmf-dist/fonts/’]
# Language to be used for hyphenation support
#pdf_language = “en_US”
# 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
# Name of the cover page template to use
#pdf_cover_template = ‘sphinxcover.tmpl’
# 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 = True
# How many levels deep should the table of contents be?
Sphinxpdf_toc_depth = 9999
# Add section number to section references
pdf_use_numbered_links = False
# Background images fitting mode
pdf_fit_background_mode = ‘scale’
在Windows环境下,还要把以下代码添加到make.bat文件中:
if “%1” == “pdf” (
%SPHINXBUILD% -b pdf %ALLSPHINXOPTS% %BUILDDIR%/pdf
echo.
echo.Build finished. The PDF files are in %BUILDDIR%/pdf
goto end
)
完成以上步骤后,无需做其他改动,即可将Sphinx默认项目的源文件index.rst转换成PDF格式,命令为make pdf。不过你会发现,即便能够生成PDF文档,命令行窗口依然会出现很多报错提示,主要意思是说找不到某些字体,但rst2pdf自动用一些默认字体将其替换掉了。
问题来了,当你的rst源文档中包含了中文时,执行完make pdf命令后,所有的中文字符都没法显示。这是因为,rst2pdf默认使用的字体不适用于中文。那解决问题的思路就出来了,换字体呗。根据rst2pdf的用户手册说明,可以使用自定义的style样式表来指定字体,并将这些字体嵌入PDF文档中。Google了一下,发现一个常用的中文模板:
{
“styles”:
{
“base”:
{
“wordWrap”: “CJK”
}
},
“embeddedFonts” : [[“wqy-zenhei.ttf”,”msyhbd.ttf”,”wqy-zenhei.ttf”,”wqy-zenhei.ttf”]],
“fontsAlias” : {
“stdFont”: “wqy-zenhei”,
“stdBold”: “msyhbd”,
“stdItalic”: “wqy-zenhei”
}
}
将以上代码另存为一个名为chinese.style的文档,并放进rst2pdf安装目录下的styles文件夹中(我机器上的实际路径是C:\Python27\Lib\site-packages\rst2pdf-0.91-py2.7.egg\rst2pdf\styles)。
关于以上样式的说明:
- embeddedFonts用于嵌入字体,经试验,必须包含至少四个值才不会报错。不过这四个字体值可以是重复的。
- fontsAlias用来指定各类字形用什么字体。如stdFont指正文字体,stdBold指粗体,stdItalic指斜体。其他的还有stdBoldItalic粗斜体,stdMono等宽体,等等。
- 确保所用字体已经安装在你的操作系统上,且字体必须是TTF类型的(Windows环境下限制比较多~)。
- wordWrap用于指定换行规则,CJK就是适用于中日韩文字的规则。这是从网上的模板抄来的,但经我的测试发现,如果用CJK规则的话,中英混排的文档里面英文部分就没法正常断行,这真是个遗憾。
实际上,fontsAlias的分类很多都只对英文字体有意义,如严格来讲中文是没有所谓斜体的(不过因为Word的普及,经常看到中文被设置为斜体的情形)。如果是纯中文文档,当然随便用哪些中文字体都行,如宋体。现实中,经常会有中英文混排的情形,所以如果全用中文字体的话,英文部分就没法显示斜体等字形了。
创建完自定义样式表后,需要把它用到make pdf命令中。导入样式表的方式是,修改conf.py中的pdf_stylesheets参数(在前面自定义添加过的PDF参数中):
默认是:
pdf_stylesheets = [‘sphinx’,’kerning’,’a4′]
改为:
pdf_stylesheets = [‘chinese’,’a4′]
关于pdf_stylesheets的说明:
- 这个参数中默认使用的某些样式包含了一些字体,而这些字体并非在所有操作系统上都找得到。’sphinx’和’kerning’都是默认提供的样式,要么不用它们,要么直接修改其包含的字体。
- ‘a4’指设置输出的PDF为A4纸大小。
- 默认的样式文件可以在rst2pdf的安装路径下找到。
我试验了一下,用微软雅黑Bold来显示粗体,用文泉驿正黑(wqy-zenhei)显示正文字体,效果还行,如下图所示:
本文只是一个简单的尝试,如果有兴趣深入研究的,可以参考rst2pdf手册。个人觉得rst2pdf还是有很多小问题,仍待进一步完善。不过,Sphinx作为一个轻量级的技术文档写作工具,还是值得一试的。
其他补充:
- rst2pdf自带的配置文件似乎只是在linux系统上才有,Windows上找不到……
- 如果不用make pdf,而是用rst2pdf自带的命令(如rst2pdf index.rst -s chinese -o output.pdf)来生成PDF,则相当于绕开了Sphinx的配置文件中所做的定义。真要这么做的话,最好是使用标准的rst语法来写文档,因为Sphinx特有的一些指令如toctree在这个情形下会报错,说明rst2pdf自带的PDF输出命令对Sphinx rst文档不是百分百支持。
本文主要参考资料:
http://d.hatena.ne.jp/tk0miya/20111208
http://code.google.com/p/rst2pdf/
Update: 本文提到的方法对最新版Sphinx/rst2pdf已失效,可参考《使用rst2pdf生成中文PDF》。
“Sphinx reStructuredText中文PDF输出解决方案之rst2pdf”的3个回复