rst2pdf中图片的处理
一般情况下,使用 reStructuredText(ReST) 生成 PDF 格式的文件需要先转化成 LaTeX 格式。而 rst2pdf 通过调用 reportlab 工具包直接生成 PDF 文件。
配置文件
rst2pdf 会读取配置文件 (如果存在)/etc/rst2pdf.conf 和 ~/.rst2pdf/config ,也可以通过命令参数 --config=FILE 来设置配置文件的路径。配置文件的格式如下:[general] # Footnote backlinks enabled or not (default: enabled) footnote_backlinks=True # Show footnotes inline instead of at the end of the document inline_footnotes=False配置文件的选项可以从 rst2pdf 命令选项中得到,从源代码 createpdf.py 文件 parse_commandline() 方法中就可以看出配置文件的作用是设定默认值:
def_footnote_backlinks = config.getValue("general", "footnote_backlinks", True) parser.add_option('--no-footnote-backlinks', action='store_false', dest='footnote_backlinks', default=def_footnote_backlinks, help='Disable footnote backlinks.'\ ' Default=%s' % str(not def_footnote_backlinks))
图片处理
rst2pdf 是通过 PIL (Python Imaging Library)来处理图片。图片宽和高的单位可以使用 em ex px in cm mm pt pc % 或者什么都不写,默认的单位是 px 。rst2pdf 默认是300 dpi,但是可以通过命令选项 --default-dpi 或者在配置文件中设置。但是命令参数 --default-dpi 也并不是万能的,图片后缀的不同,图片的大小最后也不同。 --default-dpi 的值是通过 createpdf.py 文件传给了 style.py 文件中的类StyleSheet的属性def_dpi如下:def_dpi = config.getValue("general", "default_dpi", 300) parser.add_option('--default-dpi', dest='def_dpi', metavar='NUMBER', default=def_dpi, help='DPI for objects sized in pixels. Default=%d'%def_dpi) ...... self.styles = sty.StyleSheet(styleSheets, self.font_path, self.style_path, def_dpi=self.def_dpi)命令选项 --default-dpi 的值赋予xdpi,ydpi,但是根据图片后缀的不同又将进一步变化。
xdpi, ydpi = client.styles.def_dpi, client.styles.def_dpi # 赋值 extension = imgname.split('.')[-1].lower() # 后缀 if extension in ['svg','svgz'] and SVGImage.available(): iw, ih = SVGImage(imgname, srcinfo=srcinfo).wrap(0, 0) iw = iw * xdpi / 72 ih = ih * ydpi / 72 elif extension in ["ai", "ccx", "cdr", "cgm", "cmx", "sk1", "sk", "xml", "wmf", "fig"] and VectorImage.available(): iw, ih = VectorImage(imgname, srcinfo=srcinfo).wrap(0, 0) iw = iw * xdpi / 72 ih = ih * ydpi / 72 ...... else: keeptrying = True if LazyImports.PILImage: try: img = LazyImports.PILImage.open(imgname) img.load() iw, ih = img.size xdpi, ydpi = img.info.get('dpi', (xdpi, ydpi)) keeptrying = False ......图片处理中 ydpi xdpi 的值我们可以通过以下代码来验证,在 image.py 380行代码出加入 print xdpi,ydpi。如果图片后缀是 gif,则与 --default-dpi 相同,后缀是 png ,则返回 72,72。
w = node.get('width') h = node.get('height') print xdpi,ydpi以上代码中出现的iw,ih表示图片原宽和原高,w,h,scale是从ReST文档中得到的数值。
iw = img.size().width() ih = img.size().height() w = node.get('width') h = node.get('height') scale = float(node.get('scale', 100))/100最后图片通过以下几种情况的处理,就会得到最后的宽和高:
- 如果 w,h 都为none,则 w = iw*inch/xdpi h = ih*inch/ydpi。
- 如果w,h 都不为 none, 则w = client.styles.adjustUnits(w, client.styles.tw,default_unit='px') h = client.styles.adjustUnits(h, ih*inch/ydpi, default_unit='px')。
- 如果 w,h 只有一个为 none,则会通过 iw/ih 来得到另一个。
- scale的默认值为100%,最后的宽和高都会乘以scale,即w = w*scale h = h*scale。