使用Sphinx扩展将SVG转换为PDF

6
我的公司正在使用Sphinx为我们的产品创建手册。我们的产品随附有PDF和HTML文档。我们使用Windows作为唯一的开发环境。
必要的要求是从相同的源文件(*.rst文件)生成两种格式。
一个传统的文档使用大量的SVG图像,但是sphinx构建格式latex不支持在includegraphics{}环境中使用SVG文件。
现在我找到了很有前途的Sphinx扩展程序sphinx.ext.imgconverter,并将其包含在我的conf.py中。
extensions = [
    'sphinx.ext.imgmath',
    'sphinx.ext.ifconfig',
    'sphinx.ext.imgconverter'
]

希望在构建LaTeX时将所有SVG文件转换为PDF文件。不幸的是,该扩展的文档非常简短,没有可用的示例。

http://www.sphinx-doc.org/en/master/ext/imgconverter.html#module-sphinx.ext.imgconverter

我们的rst文件内容基本上是:
.. image:: Image.*
   :width: 100px

Sphinx 应该自行判断,在构建 HTML/PDF 时,星号是否应替换为 SVG 或 PDF。我从先前的帖子中获得了这些信息:

  1. 使用 Sphinx 文档,如何指定 PNG 图像格式用于 HTML 构建和 Latex/PDF 构建的 PDF 图像格式?

但不知何故,我无法生成我的 LaTeX。 使用 Sphinx 文档,如何指定 PNG 图像格式用于 HTML 构建和 Latex/PDF 构建的 PDF 图像格式?

相反,会发出以下警告:

WARNING: no matching candidate for image URI u'Image.*'

但只有当我想要在HTML的情况下构建LaTeX时才会出现警告。

我需要安装ImageMagick吗?还是有什么问题?Sphinx如何知道在哪里搜索ImageMagick?

更新

我刚刚将我的Sphinx更新到版本1.7.2。它仍然不起作用。由于我无法安装ImageMagick,我暂时从我的conf.py中删除了扩展名为sphinx.ext.imgconverter的扩展,以测试手动解决方案。我使用inkscape手动将所有图像转换为pdf/png。

现在,如果我使用make latex编译,就会得到以下警告。

WARNING: a suitable image for latex builder not found: ['image/svg+xml']

但是在源目录和build/latex目录中都有手动转换的图像(pdf,png)。

我的LaTeX文件编译后类似于:

\noindent\sphinxincludegraphics[width=100\sphinxpxdimen]{{Image}.*}

而且我无法使用pdflatex编译它。

LaTeX Error: Unknown graphics extension: .*.

我在conf.py中是否有一些设置可以让LaTeX Builder接受我的转换后的图片?

如果我在conf.py中加入以下行,会发生一些意外的情况:

from sphinx.builders.latex import LaTeXBuilder
LaTeXBuilder.supported_image_types = ['image/png', 'image/pdf','image/svg+xml' ]

我的LaTeX文件的输出现在包含以下内容:
\noindent\sphinxincludegraphics[width=100\sphinxpxdimen]{{Image}.svg}

如果我从supported_image_types中删除类型为image/svg+xml,我会再次遇到先前的错误。我的印象是,sphinx-build在错误的位置查找转换后的图像。但这只是一个想法。

1
请查看sphinxcontrib-svg2pdfconverter,它可以帮助将svg文件即时转换为pdf文件,以便与Sphinx的latex构建器一起使用。它基于sphinx.ext.imgconverter,通过inkscape或rsvg-convert进行转换。 - user4184837
2个回答

4

学者们选择svg2pdfconverter进行扩展

如果您想在Sphinx-latexpdf生成的文档中嵌入高质量的图像,@user4184837建议使用sphinx-svg2pdfconverter是绝对正确的选择,因为它正好符合其名称的意思:它将SVG文件转换为保留可伸缩性的小型嵌入式PDF文档!矢量图像在输出过程中不会被栅格化,因此无论大小如何,它们都是清晰锐利的。

安装和选择渲染后端

要获取Sphinx扩展,只需执行pip install sphinxcontrib-svg2pdfconverter,但您还需要一个SVG解释器/转换后端(该扩展仅处理Sphinx部分)。目前支持三个后端:

  1. Inkscape,需要你安装...嗯...所有的Inkscape。
  2. rsvg-convert 命令行工具,可以从适用于Linux的发行包中安装,也可以通过其他方式获取。(在Debian宇宙中,该软件包拼写为librsvg2-bin,而那些更倾向于深红色帽子的人则发音为librsvg2-tools。)
  3. 最轻量级的是,你可以只安装 cairosvg,这是一个Python包,可以与扩展本身同时从PyPi安装。使用Cairosvg时,Svg2pdfconverter还有一些额外的依赖关系,所以你可能想将其安装为sphinxcontrib-svg2pdfconverter[Cairosvg]

至少对于我相对简单的工具栏图标级别的图形来说,选择后端在输出上没有明显的差异。因此,很明显,Cairosvg是最低阻力的选择。只需将其插入到你的Python包依赖列表中即可。

Cairosvg并非完全使用Python实现,但它是一个纯Python PyPi包。正如其名称所示,它基于Cairo,并使用cffi与可用的libcairo.so / libcairo.dylib / libcairo.dll进行接口交互。
如果没有libcairo,Cairosvg不会安装它,但它在很多地方都很常见: - 在Linux系统中很难找到没有cairo作为系统包的情况。 - 在macOS上,它会检测到现有的/usr/local/lib/libcairo.dylib;Homebrew表示它作为ffmpeg、opencv和gtk+3等的依赖项安装。 - Windows稍微困难一些,但如果您已经安装了MSYS2,您已经在C:\msys64\mingw64\bin\中有一个libcairo.dll。即使在cmd.exe/pwsh.exe中,将该目录添加到路径中,cairosvg也将检测到该DLL文件。
你可以通过导入它的cffi接口来确认它是否看到了该库。
>>> import cairocffi
>>> # If you DON'T see any error messages, you're good to go
>>> # or confirm and check the library location with...
>>> cairocffi.cairo
<Lib object for '/usr/local/lib/libcairo.dylib'>

将所有内容整合在一起

svg2pdfconverter有一些可配置的选项,但很可能你不需要它,至少最初是这样。它绝对会直接开箱即用,除了将其添加到conf.py中的extensions列表之外,无需任何其他配置。

通过添加扩展类来选择要使用的后端:

  • sphinxcontrib.inkscapeconverter
  • sphinxcontrib.rsvgconverter
  • sphinxcontrib.cairosvgconverter
挑选你已经有必要依赖的那个,然后你就可以开始了。
更可能需要调整的是你的SVG文件,稍微使它们更适合嵌入到你的Sphinx文档中。
我不想打破你的幻想,但是大小确实很重要。
第一个问题是布局 - 如果你想将SVG图像与文本内容内联放置,你需要相应地缩放和定位它们。一个16px的方形图标可能是你想要使用的最大尺寸,即便如此,它也会稍微压过周围的文字。如果你导入一个128px的方形图标设计,它的大小将成比例地增加8倍,你的正文将被一个占据近一半页面的图片打断。
你还可能希望设计内联SVG图像,使它们与其边界框的底部中心对齐,并且在上方保留足够的空间。内联嵌入的SVG直接位于文本基线上,随着尺寸增加,只向上扩展。因此,下方的任何填充都会使它看起来更尴尬,而你需要上方的填充,因为图像边界框的顶部将决定该行文本的高度。
当我最初为我们的文档导入SVG图标时(嗯,在我重新导入它们之后,从256像素的正方形缩小到16像素!),它们都有包裹紧密的边界框。在最终的PDF中,每个出现在表格单元格第一行文本中的SVG图像上方都带着一个边框线作为帽子。
重新调整这些图形,使它们大约宽12像素,高度不超过14像素,底部对齐于一个16像素的正方形页面区域。

plus-sign icon laid out on an Inkscape canvas, with empty space on three sides, but no gap along the bottom edge

创造了一点喘息的空间。

zoomed-in detail of a rendered PDF, showing text with an SVG icon embedded inline

那基本上就是这样!


1
  1. 我怀疑这个错误与这个问题有关。它在Sphinx 1.7中得到了修复,这表明你安装的Sphinx版本小于1.7。请升级到Sphinx 1.7或更高版本。提示:始终在源代码库中搜索帮助。
  2. sphinx.ext.imgconverter的文档中可以看出:

    在内部,此扩展使用Imagemagick来转换图像。

    这意味着它必须被安装并在您的系统路径中。


谢谢您的建议。我已经安装了sphinx-build 1.7.0。我会尝试更新。 - Aleph0

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接