Merge pull request #2716 from tk0miya/rstdim_to_latexdim

Refactoring latex writer
This commit is contained in:
Takeshi KOMIYA 2016-06-27 11:18:28 +09:00 committed by GitHub
commit 3d3ee6fef3
4 changed files with 72 additions and 25 deletions

View File

@ -15,6 +15,8 @@ Incompatible changes
sphinxVerbatimintable which handles captions and wraps lines(ref #2704).
* latex, replace ``pt`` by TeX equivalent ``bp`` if found in ``width`` or
``height`` attribute of an image.
* latex, if ``width`` or ``height`` attribute of an image is given with no unit,
use ``px`` rather than ignore it.
Features added
@ -49,6 +51,8 @@ Features added
lines wrapped to fit table cell (ref: #2704)
* #2597: Show warning messages as darkred
* latex, allow image dimensions using px unit (default is 96px=1in)
* Show warnings if invalid dimension units found
Bugs fixed
----------

View File

@ -363,8 +363,9 @@ directory on building (e.g. the ``_static`` directory for HTML output.)
Interpretation of image size options (``width`` and ``height``) is as follows:
if the size has no unit or the unit is pixels, the given size will only be
respected for output channels that support pixels (i.e. not in LaTeX output).
Other units (like ``pt`` for points) will be used for HTML and LaTeX output.
respected for output channels that support pixels. Other units (like ``pt``
for points) will be used for HTML and LaTeX output (the latter replaces ``pt``
by ``bp`` as this is the TeX unit such that ``72bp=1in``).
Sphinx extends the standard docutils behavior by allowing an asterisk for the
extension::
@ -386,6 +387,9 @@ Note that image file names should not contain spaces.
.. versionchanged:: 0.6
Image paths can now be absolute.
.. versionchanged:: 1.5
latex target supports pixels (default is ``96px=1in``).
Footnotes
---------

View File

@ -275,6 +275,23 @@ def escape_abbr(text):
return re.sub('\.(?=\s|$)', '.\\@', text)
def rstdim_to_latexdim(width_str):
"""Convert `width_str` with rst length to LaTeX length."""
match = re.match('^(\d*\.?\d*)\s*(\S*)$', width_str)
if not match:
raise ValueError
res = width_str
amount, unit = match.groups()[:2]
float(amount) # validate amount is float
if unit in ('', "px"):
res = "%s\\sphinxpxdimen" % amount
elif unit == 'pt':
res = '%sbp' % amount # convert to 'bp'
elif unit == "%":
res = "%.3f\\linewidth" % (float(amount) / 100.0)
return res
class LaTeXTranslator(nodes.NodeVisitor):
sectionnames = ["part", "chapter", "section", "subsection",
"subsubsection", "paragraph", "subparagraph"]
@ -1360,25 +1377,10 @@ class LaTeXTranslator(nodes.NodeVisitor):
pass
def latex_image_length(self, width_str):
"""Convert `width_str` with rst length to LaTeX length.
This function is copied from docutils' latex writer
"""
match = re.match('(\d*\.?\d*)\s*(\S*)', width_str)
if not match:
# fallback
return width_str
res = width_str
amount, unit = match.groups()[:2]
if not unit:
return None
elif unit == 'pt':
res = '%sbp' % amount # convert to 'bp'
elif unit == "px":
res = "%.3f\\sphinxpxdimen" % (float(amount))
elif unit == "%":
res = "%.3f\\linewidth" % (float(amount) / 100.0)
return res
try:
return rstdim_to_latexdim(width_str)
except ValueError:
self.builder.warn('dimension unit %s is invalid. Ignored.' % width_str)
def is_inline(self, node):
"""Check whether a node represents an inline element."""
@ -1461,21 +1463,22 @@ class LaTeXTranslator(nodes.NodeVisitor):
# TODO: support align option
if 'width' in node:
length = self.latex_image_length(node['width'])
self.body.append('\\begin{sphinxfigure-in-table}[%s]\n\\centering\n' % length)
if length:
self.body.append('\\begin{sphinxfigure-in-table}[%s]\n'
'\\centering\n' % length)
else:
self.body.append('\\begin{sphinxfigure-in-table}\n\\centering\n')
if any(isinstance(child, nodes.caption) for child in node):
self.body.append('\\capstart')
self.context.append(ids + '\\end{sphinxfigure-in-table}\\relax\n')
elif node.get('align', '') in ('left', 'right'):
length = None
if 'width' in node:
length = self.latex_image_length(node['width'])
elif 'width' in node[0]:
length = self.latex_image_length(node[0]['width'])
else:
length = '0pt'
self.body.append('\\begin{wrapfigure}{%s}{%s}\n\\centering' %
(node['align'] == 'right' and 'r' or 'l', length))
(node['align'] == 'right' and 'r' or 'l', length or '0pt'))
self.context.append(ids + '\\end{wrapfigure}\n')
elif self.in_minipage:
if ('align' not in node.attributes or

View File

@ -0,0 +1,36 @@
# -*- coding: utf-8 -*-
"""
test_writer_latex
~~~~~~~~~~~~~~~~
Test the LaTeX writer
:copyright: Copyright 2007-2016 by the Sphinx team, see AUTHORS.
:license: BSD, see LICENSE for details.
"""
from __future__ import print_function
from sphinx.writers.latex import rstdim_to_latexdim
from util import raises
def test_rstdim_to_latexdim():
# Length units docutils supported
# http://docutils.sourceforge.net/docs/ref/rst/restructuredtext.html#length-units
assert rstdim_to_latexdim('160em') == '160em'
assert rstdim_to_latexdim('160px') == '160\\sphinxpxdimen'
assert rstdim_to_latexdim('160in') == '160in'
assert rstdim_to_latexdim('160cm') == '160cm'
assert rstdim_to_latexdim('160mm') == '160mm'
assert rstdim_to_latexdim('160pt') == '160bp'
assert rstdim_to_latexdim('160pc') == '160pc'
assert rstdim_to_latexdim('30%') == '0.300\\linewidth'
assert rstdim_to_latexdim('160') == '160\\sphinxpxdimen'
# flaot values
assert rstdim_to_latexdim('160.0em') == '160.0em'
assert rstdim_to_latexdim('.5em') == '.5em'
# unknown values (it might be generated by 3rd party extension)
raises(ValueError, rstdim_to_latexdim, 'unknown')
assert rstdim_to_latexdim('160.0unknown') == '160.0unknown'