【问题标题】:Using Sphinx Extension to convert svg to pdf使用 Sphinx 扩展将 svg 转换为 pdf
【发布时间】:2018-04-18 11:39:30
【问题描述】:

我的公司正在使用 Sphinx 为我们的产品创建手册。我们的产品附带 PDF 和 HTML 文档。我们使用 Windows 作为唯一的开发环境。

一个必要的要求是从相同的源(*.rst 文件)生成两种格式。

旧文档使用大量 SVG 图像,但 sphinx 构建格式 latex 不支持 \includegraphics{} 环境中的 SVG 文件。

现在我找到了有前途的 Sphinx-Extension 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 应该自己弄清楚,是否应该用 svg 或 pdf 替换星形,具体取决于构建 html/pdf。我从以前的帖子中获得的这些信息:

  1. Using Sphinx docs how can I specify png image formats for HTML builds and pdf image formats for Latex/PDF builds?

但不知何故,我无法生成我的乳胶。 Using Sphinx docs how can I specify png image formats for HTML builds and pdf image formats for Latex/PDF builds?

而是发出以下警告:

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']

但source 目录和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 在错误的位置寻找转换后的图像。但这只是一个想法。

【问题讨论】:

标签: imagemagick latex python-sphinx imagemagick-convert pdflatex


【解决方案1】:

缩放学者选择svg2pdfconverter

如果您想在 Sphinx-latexpdf 生成的文档中嵌入真正高质量的图像,@user4184837 建议使用 sphinx-svg2pdfconverter 绝对是您的理想之选,因为它确实做到了如在 The Tin™ 上所说的那样:它可以转换将您的 SVG 文件转换为可嵌入的小型 PDF 文档,并保留其可扩展性!这些向量永远不会在输出管道中的任何地方被光栅化,因此它们在任何尺寸下都清晰明了。

渲染后端的安装与选择

要获得 Sphinx 扩展,您只需 pip install sphinxcontrib-svg2pdfconverter,但您还需要一个 SVG 解释器/转换器后端。 (该扩展只处理 Sphinx 端的东西。)目前,支持三个:

  1. Inkscape,这需要您安装……嗯……所有 Inkscape。
  2. rsvg-convert 命令行工具,可以从 Linux 上的相应发行版包中安装,也可以通过其他方式获得。 (该软件包在 Debian 世界中拼写为 librsvg2-bin,而那些更偏爱深红色头饰的人则将其发音为 librsvg2-tools。)
  3. 重量最轻,您只需安装 cairosvg,您可以在安装扩展本身的同时从 PyPi 安装一个 Python 包。使用 Cairosvg 时,Svg2pdfconverter 有几个额外的依赖项,因此您需要将其安装为 sphinxcontrib-svg2pdfconverter[Cairosvg]。

至少对于我相对简单的工具栏图标级复杂性图形而言,后端的选择对输出没有明显的影响。因此,显然 Cairosvg 是那里阻力最小的路径。就像将它插入到 Python 包依赖项列表中一样简单。

Cairosvg 实际上并不是专门在 Python 中实现的,但它是一个纯 Python PyPi 包。顾名思义,它基于 Cairo,使用 cffi 到 dlopen() 并与可用的 libcairo.so / libcairo.dylib / libcairo.dll 接口。

如果您没有,Cairosvg 不会安装 libcairo,但它无处不在:

  • 很难找到没有 cairo 作为系统包的 Linux 系统。
  • 在 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 倍,并且您的正文将被占据近一半页面的嵌入式图形打断。 p>

您可能还想设计内联 SVG 图像,使它们与边界框的最底部中心对齐,并在上方留出相当多的空间。内嵌的 SVG 直接位于文本基线上,仅随着其大小的增加而向上延伸。因此,下方的任何填充只会让它看起来更加尴尬,而您需要上方的填充,因为图像边界框的顶部将决定该文本行的高度。

当我最初为我们的文档导入 SVG 图标时(嗯,在我重新导入它们之后,从 256px 方形缩小到 16px!)它们都有收缩包装的边界盒子。在最终的 PDF 中,每个以表格单元格文本的第一行结尾的 SVG 图像都在其上方戴上边界线作为帽子。

重新对齐图形,使其大致为12px 宽,不高于14px,位于16px 方形页面区域的底部:

...创造了一个小小的喘息空间:

差不多就是这样!

照我说的做,不要像我们的手册作者那样做

(是的,现在我正在查看它,我注意到该特定文本行的可访问性失败了。将图标 plopped 放入文本中意味着一个屏幕读者将没有机会弄清楚如何处理它。在纠正之前,我会记下与责任方交谈。但是,为了我们这里的目的......好吧,见鬼 - 这是风格的一个例子,不是实质!?)

【讨论】:

    【解决方案2】:
    1. 我怀疑这个错误与这个issue 有关。它已在 Sphinx 1.7 中修复,这表明您安装了 Sphinx 提示:始终搜索源代码存储库以获取帮助。
    2. 来自sphinx.ext.imgconverter的文档:

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

      这意味着它必须已安装并位于您的系统路径中。

    【讨论】:

    • 感谢您的建议。我安装了 sphinx-build 1.7.0。我会尝试更新。
    猜你喜欢
    • 2013-06-29
    • 2011-05-06
    • 2016-01-20
    • 2015-10-04
    • 2016-05-23
    • 2020-12-14
    • 2021-03-14
    • 2014-03-22
    相关资源
    最近更新 更多