summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--AUTHORS1
-rw-r--r--CHANGES1
-rw-r--r--doc/intro.rst3
-rw-r--r--sphinx/ext/intersphinx.py2
-rw-r--r--sphinx/jinja2glue.py3
-rw-r--r--sphinx/locale/ja/LC_MESSAGES/sphinx.mobin10112 -> 10904 bytes
-rw-r--r--sphinx/locale/ja/LC_MESSAGES/sphinx.po9
-rw-r--r--sphinx/pycode/__init__.py25
-rw-r--r--sphinx/quickstart.py9
-rw-r--r--sphinx/util/pycompat.py6
-rw-r--r--sphinx/writers/latex.py37
-rw-r--r--tests/root/markup.txt12
-rw-r--r--tests/test_intersphinx.py24
13 files changed, 103 insertions, 29 deletions
diff --git a/AUTHORS b/AUTHORS
index acee4627..a24d6a54 100644
--- a/AUTHORS
+++ b/AUTHORS
@@ -40,6 +40,7 @@ Other contributors, listed alphabetically, are:
* John Waltman -- Texinfo builder
* Barry Warsaw -- setup command improvements
* Sebastian Wiesner -- image handling, distutils support
+* Joel Wurtz -- cellspanning support in LaTeX
Many thanks for all contributions!
diff --git a/CHANGES b/CHANGES
index c3a4a083..fd5ae44f 100644
--- a/CHANGES
+++ b/CHANGES
@@ -59,6 +59,7 @@ Features added
requests and allow configuring the timeout. New config values:
:confval:`linkcheck_timeout` and :confval:`linkcheck_workers`.
- #521: Added :confval:`linkcheck_ignore` config value.
+ - #28: Support row/colspans in tables in the LaTeX builder.
* Configuration and extensibility:
diff --git a/doc/intro.rst b/doc/intro.rst
index 0e6e5247..5562f39b 100644
--- a/doc/intro.rst
+++ b/doc/intro.rst
@@ -24,8 +24,7 @@ This section is intended to collect helpful hints for those wanting to migrate
to reStructuredText/Sphinx from other documentation systems.
* Gerard Flanagan has written a script to convert pure HTML to reST; it can be
- found at `BitBucket
- <https://bitbucket.org/djerdo/musette/src/tip/musette/html/html2rest.py>`_.
+ found at the `Python Package Index <http://pypi.python.org/pypi/html2rest>`_.
* For converting the old Python docs to Sphinx, a converter was written which
can be found at `the Python SVN repository
diff --git a/sphinx/ext/intersphinx.py b/sphinx/ext/intersphinx.py
index 709428a3..9bfd53fd 100644
--- a/sphinx/ext/intersphinx.py
+++ b/sphinx/ext/intersphinx.py
@@ -158,7 +158,7 @@ def load_mappings(app):
# new format
name, (uri, inv) = key, value
if not name.isalnum():
- env.warn('intersphinx identifier %r is not alphanumeric' % name)
+ env.warn(docname=None, msg='intersphinx identifier %r is not alphanumeric' % name)
else:
# old format, no name
name, uri, inv = None, key, value
diff --git a/sphinx/jinja2glue.py b/sphinx/jinja2glue.py
index 629bce30..ffe3a0b3 100644
--- a/sphinx/jinja2glue.py
+++ b/sphinx/jinja2glue.py
@@ -46,9 +46,10 @@ class idgen(object):
self.id = 0
def current(self):
return self.id
- def next(self):
+ def __next__(self):
self.id += 1
return self.id
+ next = __next__ # Python 2/Jinja compatibility
class SphinxFileSystemLoader(FileSystemLoader):
diff --git a/sphinx/locale/ja/LC_MESSAGES/sphinx.mo b/sphinx/locale/ja/LC_MESSAGES/sphinx.mo
index 09535b7a..6a1065fd 100644
--- a/sphinx/locale/ja/LC_MESSAGES/sphinx.mo
+++ b/sphinx/locale/ja/LC_MESSAGES/sphinx.mo
Binary files differ
diff --git a/sphinx/locale/ja/LC_MESSAGES/sphinx.po b/sphinx/locale/ja/LC_MESSAGES/sphinx.po
index 9d5488ec..6069002a 100644
--- a/sphinx/locale/ja/LC_MESSAGES/sphinx.po
+++ b/sphinx/locale/ja/LC_MESSAGES/sphinx.po
@@ -2,14 +2,15 @@
# Copyright (C) 2008 ORGANIZATION
# This file is distributed under the same license as the Sphinx project.
# Yasushi Masuda <whosaysni@gmail.com>, 2008.
-# Kouhei Sutou <kou@clear-code.com, 2011.
+# Kouhei Sutou <kou@clear-code.com>, 2011.
+# Akitoshi Ohta <fire.kuma8@gmail.com>, 2011.
#
msgid ""
msgstr ""
"Project-Id-Version: Sphinx 1.1pre\n"
"POT-Creation-Date: 2008-09-11 23:58+0200\n"
-"PO-Revision-Date: 2011-05-15 21:25+0900\n"
-"Last-Translator: Kouhei Sutou <kou@clear-code.com>\n"
+"PO-Revision-Date: 2011-08-27 17:50+0900\n"
+"Last-Translator: Akitoshi Ohta <fire.kuma8@gmail.com>\n"
"Language-Team: Japanese\n"
"Plural-Forms: nplurals=1; plural=0\n"
"MIME-Version: 1.0\n"
@@ -753,7 +754,7 @@ msgstr "前のページからの続き"
#: sphinx/writers/latex.py:677
msgid "Continued on next page"
-msgstr "総索引"
+msgstr "次のページに続く"
#: sphinx/writers/text.py:430
msgid "[image]"
diff --git a/sphinx/pycode/__init__.py b/sphinx/pycode/__init__.py
index bf51e740..ac840750 100644
--- a/sphinx/pycode/__init__.py
+++ b/sphinx/pycode/__init__.py
@@ -9,16 +9,13 @@
:license: BSD, see LICENSE for details.
"""
-import re
-import sys
from os import path
-from cStringIO import StringIO
from sphinx.errors import PycodeError
from sphinx.pycode import nodes
from sphinx.pycode.pgen2 import driver, token, tokenize, parse, literals
from sphinx.util import get_module_source, detect_encoding
-from sphinx.util.pycompat import next
+from sphinx.util.pycompat import next, StringIO, BytesIO, TextIOWrapper
from sphinx.util.docstrings import prepare_docstring, prepare_commentdoc
@@ -172,14 +169,16 @@ class ModuleAnalyzer(object):
@classmethod
def for_string(cls, string, modname, srcname='<string>'):
- return cls(StringIO(string), modname, srcname)
+ if isinstance(string, bytes):
+ return cls(BytesIO(string), modname, srcname)
+ return cls(StringIO(string), modname, srcname, decoded=True)
@classmethod
def for_file(cls, filename, modname):
if ('file', filename) in cls.cache:
return cls.cache['file', filename]
try:
- fileobj = open(filename, 'r')
+ fileobj = open(filename, 'rb')
except Exception, err:
raise PycodeError('error opening %r' % filename, err)
obj = cls(fileobj, modname, filename)
@@ -206,7 +205,7 @@ class ModuleAnalyzer(object):
cls.cache['module', modname] = obj
return obj
- def __init__(self, source, modname, srcname):
+ def __init__(self, source, modname, srcname, decoded=False):
# name of the module
self.modname = modname
# name of the source file
@@ -216,9 +215,15 @@ class ModuleAnalyzer(object):
# cache the source code as well
pos = self.source.tell()
- self.encoding = detect_encoding(self.source.readline)
- self.code = self.source.read()
- self.source.seek(pos)
+ if not decoded:
+ self.encoding = detect_encoding(self.source.readline)
+ self.code = self.source.read().decode(self.encoding)
+ self.source.seek(pos)
+ self.source = TextIOWrapper(self.source, self.encoding)
+ else:
+ self.encoding = None
+ self.code = self.source.read()
+ self.source.seek(pos)
# will be filled by tokenize()
self.tokens = None
diff --git a/sphinx/quickstart.py b/sphinx/quickstart.py
index 876e7182..ad7b3ce5 100644
--- a/sphinx/quickstart.py
+++ b/sphinx/quickstart.py
@@ -253,7 +253,7 @@ latex_documents = [
# One entry per manual page. List of tuples
# (source start file, name, description, authors, manual section).
man_pages = [
- ('%(master_str)s', '%(project_manpage)s', u'%(project_doc)s',
+ ('%(master_str)s', '%(project_manpage)s', u'%(project_doc_str)s',
[u'%(author_str)s'], 1)
]
@@ -267,7 +267,7 @@ man_pages = [
# (source start file, target name, title, author,
# dir menu entry, description, category)
texinfo_documents = [
- ('%(master_str)s', '%(project_fn)s', u'%(project_doc)s', u'%(author_str)s',
+ ('%(master_str)s', '%(project_fn)s', u'%(project_doc_str)s', u'%(author_str)s',
'%(project_fn)s', 'One line description of project.', 'Miscellaneous'),
]
@@ -932,8 +932,9 @@ directly.'''
# escape backslashes and single quotes in strings that are put into
# a Python string literal
- for key in ('project', 'copyright', 'author', 'author_texescaped',
- 'project_doc_texescaped', 'version', 'release', 'master'):
+ for key in ('project', 'project_doc', 'project_doc_texescaped',
+ 'author', 'author_texescaped', 'copyright',
+ 'version', 'release', 'master'):
d[key + '_str'] = d[key].replace('\\', '\\\\').replace("'", "\\'")
if not path.isdir(d['path']):
diff --git a/sphinx/util/pycompat.py b/sphinx/util/pycompat.py
index a95c9332..375f6920 100644
--- a/sphinx/util/pycompat.py
+++ b/sphinx/util/pycompat.py
@@ -25,6 +25,8 @@ if sys.version_info >= (3, 0):
bytes = bytes
# prefix for Unicode strings
u = ''
+ # StringIO/BytesIO classes
+ from io import StringIO, BytesIO, TextIOWrapper
# support for running 2to3 over config files
def convert_with_2to3(filepath):
from lib2to3.refactor import RefactoringTool, get_fixers_from_package
@@ -48,8 +50,12 @@ else:
b = str
bytes = str
u = 'u'
+ from StringIO import StringIO
+ BytesIO = StringIO
# no need to refactor on 2.x versions
convert_with_2to3 = None
+ def TextIOWrapper(stream, encoding):
+ return codecs.lookup(encoding or 'ascii')[2](stream)
# ------------------------------------------------------------------------------
diff --git a/sphinx/writers/latex.py b/sphinx/writers/latex.py
index ccd7a8bf..d9f1fad9 100644
--- a/sphinx/writers/latex.py
+++ b/sphinx/writers/latex.py
@@ -40,6 +40,7 @@ HEADER = r'''%% Generated by Sphinx.
%(fncychap)s
%(longtable)s
\usepackage{sphinx}
+\usepackage{multirow}
%(preamble)s
\title{%(title)s}
@@ -251,6 +252,9 @@ class LaTeXTranslator(nodes.NodeVisitor):
self.no_contractions = 0
self.compact_list = 0
self.first_param = 0
+ self.previous_spanning_row = 0
+ self.previous_spanning_column = 0
+ self.remember_multirow = {}
def astext(self):
return (HEADER % self.elements +
@@ -715,22 +719,41 @@ class LaTeXTranslator(nodes.NodeVisitor):
def visit_row(self, node):
self.table.col = 0
def depart_row(self, node):
- self.body.append('\\\\\\hline\n')
+ if self.previous_spanning_row == 1:
+ self.previous_spanning_row = 0
+ self.body.append('\\\\\n')
+ else:
+ self.body.append('\\\\\\hline\n')
self.table.rowcount += 1
def visit_entry(self, node):
- if 'morerows' in node or 'morecols' in node:
- raise UnsupportedError('%s:%s: column or row spanning cells are '
- 'not yet implemented.' %
- (self.curfilestack[-1], node.line or ''))
+ if self.remember_multirow.get(0, 0) > 1:
+ self.body.append(' & ')
if self.table.col > 0:
self.body.append(' & ')
self.table.col += 1
+ self.context.append('')
+ if 'morerows' in node:
+ self.body.append(' \multirow{')
+ self.previous_spanning_row = 1
+ self.body.append(str(node.get('morerows') + 1))
+ self.body.append('}{*}{')
+ self.context.append('}')
+ self.remember_multirow[self.table.col] = node.get('morerows') + 1
+ if 'morecols' in node:
+ self.body.append(' \multicolumn{')
+ self.body.append(str(node.get('morecols') + 1))
+ if self.table.col == 1:
+ self.body.append('}{|l|}{')
+ else:
+ self.body.append('}{l|}{')
+ self.context.append('}')
if isinstance(node.parent.parent, nodes.thead):
self.body.append('\\textbf{')
self.context.append('}')
- else:
- self.context.append('')
+ if self.remember_multirow.get(self.table.col + 1, 0) > 1:
+ self.remember_multirow[self.table.col + 1] -= 1
+ self.context.append(' & ')
def depart_entry(self, node):
self.body.append(self.context.pop()) # header
diff --git a/tests/root/markup.txt b/tests/root/markup.txt
index 71197689..dde13a6b 100644
--- a/tests/root/markup.txt
+++ b/tests/root/markup.txt
@@ -169,6 +169,18 @@ Tables
| 2 | Empty cells: | |
+----+----------------+----+
+Table with multicol:
+
+.. only:: latex
+
+ +----+---------------------+
+ | 1 | test! |
+ +----+---------+------+----+
+ | 2 | col | col | c |
+ | y +---------+------+----+
+ | x | test |
+ +----+---------------------+
+
Figures
-------
diff --git a/tests/test_intersphinx.py b/tests/test_intersphinx.py
index 839a3e3d..563750f6 100644
--- a/tests/test_intersphinx.py
+++ b/tests/test_intersphinx.py
@@ -152,3 +152,27 @@ def test_missing_reference(tempdir, app):
rn = missing_reference(app, app.env, node, contnode)
assert rn is None
assert contnode[0].astext() == 'py3k:unknown'
+
+
+@with_app(confoverrides={'extensions': 'sphinx.ext.intersphinx'})
+@with_tempdir
+def test_load_mappings_warnings(tempdir, app):
+ """
+ load_mappings issues a warning if new-style mapping
+ identifiers are not alphanumeric
+ """
+ inv_file = tempdir / 'inventory'
+ write_file(inv_file, inventory_v2)
+ app.config.intersphinx_mapping = {
+ 'http://docs.python.org/': inv_file,
+ 'py3k': ('http://docs.python.org/py3k/', inv_file),
+ 'repoze.workflow': ('http://docs.repoze.org/workflow/', inv_file),
+ 'django-taggit': ('http://django-taggit.readthedocs.org/en/latest/', inv_file)
+ }
+
+ app.config.intersphinx_cache_limit = 0
+ # load the inventory and check if it's done correctly
+ load_mappings(app)
+ assert len(app._warning.content) == 2
+
+