mirror of
https://github.com/sphinx-doc/sphinx.git
synced 2026-09-03 20:52:55 -05:00
Merge branch 'stable' into jumptorightplace-onstable
This commit is contained in:
@@ -23,9 +23,12 @@ Bugs fixed
|
||||
* C++, added support for ``extern`` and ``thread_local``.
|
||||
* C++, type declarations are now using the prefixes ``typedef``, ``using``, and ``type``,
|
||||
depending on the style of declaration.
|
||||
* #2413: C++, fix crash on duplicate declarations
|
||||
* #2394: Fix Sphinx crashes when html_last_updated_fmt is invalid
|
||||
* #2408: dummy builder not available in Makefile and make.bat
|
||||
* #2412: Fix hyperlink targets are broken in LaTeX builder
|
||||
* Fix figure directive crashes if non paragraph item is given as caption
|
||||
* #2418: Fix time formats no longer allowed in today_fmt
|
||||
|
||||
|
||||
Release 1.4 (released Mar 28, 2016)
|
||||
|
||||
+3
-3
@@ -21,8 +21,8 @@ an "unused" primary prompt; this is an example of what *not* to do::
|
||||
2
|
||||
>>>
|
||||
|
||||
Syntax highlighting is done with `Pygments <http://pygments.org>`_ (if it's
|
||||
installed) and handled in a smart way:
|
||||
Syntax highlighting is done with `Pygments <http://pygments.org>`_ and handled
|
||||
in a smart way:
|
||||
|
||||
* There is a "highlighting language" for each source file. Per default, this is
|
||||
``'python'`` as the majority of files will have to highlight Python snippets,
|
||||
@@ -77,7 +77,7 @@ installed) and handled in a smart way:
|
||||
Line numbers
|
||||
^^^^^^^^^^^^
|
||||
|
||||
If installed, Pygments can generate line numbers for code blocks. For
|
||||
Pygments can generate line numbers for code blocks. For
|
||||
automatically-highlighted blocks (those started by ``::``), line numbers must be
|
||||
switched on in a :rst:dir:`highlight` directive, with the ``linenothreshold``
|
||||
option::
|
||||
|
||||
@@ -19,10 +19,11 @@ class Figure(images.Figure):
|
||||
|
||||
def run(self):
|
||||
name = self.options.pop('name', None)
|
||||
(figure_node,) = images.Figure.run(self)
|
||||
if isinstance(figure_node, nodes.system_message):
|
||||
return [figure_node]
|
||||
result = images.Figure.run(self)
|
||||
if len(result) == 2 or isinstance(result[0], nodes.system_message):
|
||||
return result
|
||||
|
||||
(figure_node,) = result
|
||||
if name:
|
||||
self.options['name'] = name
|
||||
self.add_name(figure_node)
|
||||
|
||||
+36
-10
@@ -476,6 +476,17 @@ class DefinitionError(UnicodeMixin, Exception):
|
||||
return self.description
|
||||
|
||||
|
||||
class _DuplicateSymbolError(UnicodeMixin, Exception):
|
||||
def __init__(self, symbol, candSymbol):
|
||||
assert symbol
|
||||
assert candSymbol
|
||||
self.symbol = symbol
|
||||
self.candSymbol = candSymbol
|
||||
|
||||
def __unicode__(self):
|
||||
return "Internal C++ duplicate symbol error:\n%s" % self.symbol.dump(0)
|
||||
|
||||
|
||||
class ASTBase(UnicodeMixin):
|
||||
def __eq__(self, other):
|
||||
if type(self) is not type(other):
|
||||
@@ -2468,14 +2479,23 @@ class Symbol(object):
|
||||
# .. class:: Test
|
||||
symbol._fill_empty(declaration, docname)
|
||||
return symbol
|
||||
# it may simply be a functin overload
|
||||
# TODO: it could be a duplicate but let's just insert anyway
|
||||
# the id generation will warn about it
|
||||
symbol = Symbol(parent=parentSymbol, identifier=identifier,
|
||||
templateParams=templateParams,
|
||||
templateArgs=templateArgs,
|
||||
declaration=declaration,
|
||||
docname=docname)
|
||||
# It may simply be a functin overload, so let's compare ids.
|
||||
candSymbol = Symbol(parent=parentSymbol, identifier=identifier,
|
||||
templateParams=templateParams,
|
||||
templateArgs=templateArgs,
|
||||
declaration=declaration,
|
||||
docname=docname)
|
||||
newId = declaration.get_newest_id()
|
||||
oldId = symbol.declaration.get_newest_id()
|
||||
if newId != oldId:
|
||||
# we already inserted the symbol, so return the new one
|
||||
symbol = candSymbol
|
||||
else:
|
||||
# Redeclaration of the same symbol.
|
||||
# Let the new one be there, but raise an error to the client
|
||||
# so it can use the real symbol as subscope.
|
||||
# This will probably result in a duplicate id warning.
|
||||
raise _DuplicateSymbolError(symbol, candSymbol)
|
||||
else:
|
||||
symbol = Symbol(parent=parentSymbol, identifier=identifier,
|
||||
templateParams=templateParams,
|
||||
@@ -3765,8 +3785,14 @@ class CPPObject(ObjectDescription):
|
||||
symbol = parentSymbol.add_name(name)
|
||||
self.env.ref_context['cpp:lastSymbol'] = symbol
|
||||
raise ValueError
|
||||
symbol = parentSymbol.add_declaration(ast, docname=self.env.docname)
|
||||
self.env.ref_context['cpp:lastSymbol'] = symbol
|
||||
|
||||
try:
|
||||
symbol = parentSymbol.add_declaration(ast, docname=self.env.docname)
|
||||
self.env.ref_context['cpp:lastSymbol'] = symbol
|
||||
except _DuplicateSymbolError as e:
|
||||
# Assume we are actually in the old symbol,
|
||||
# instead of the newly created duplicate.
|
||||
self.env.ref_context['cpp:lastSymbol'] = e.symbol
|
||||
|
||||
if ast.objectType == 'enumerator':
|
||||
self._add_enumerator_to_parent(ast)
|
||||
|
||||
+32
-6
@@ -126,15 +126,21 @@ def find_catalog_source_files(locale_dirs, locale, domains=None, gettext_compact
|
||||
|
||||
return catalogs
|
||||
|
||||
# date_format mappings: ustrftime() to bable.dates.format_date()
|
||||
# date_format mappings: ustrftime() to bable.dates.format_datetime()
|
||||
date_format_mappings = {
|
||||
'%a': 'EEE', # Weekday as locale’s abbreviated name.
|
||||
'%A': 'EEEE', # Weekday as locale’s full name.
|
||||
'%b': 'MMM', # Month as locale’s abbreviated name.
|
||||
'%B': 'MMMM', # Month as locale’s full name.
|
||||
'%c': 'medium', # Locale’s appropriate date and time representation.
|
||||
'%d': 'dd', # Day of the month as a zero-padded decimal number.
|
||||
'%H': 'HH', # Hour (24-hour clock) as a decimal number [00,23].
|
||||
'%I': 'hh', # Hour (12-hour clock) as a decimal number [01,12].
|
||||
'%j': 'DDD', # Day of the year as a zero-padded decimal number.
|
||||
'%m': 'MM', # Month as a zero-padded decimal number.
|
||||
'%M': 'mm', # Minute as a decimal number [00,59].
|
||||
'%p': 'a', # Locale’s equivalent of either AM or PM.
|
||||
'%S': 'ss', # Second as a decimal number.
|
||||
'%U': 'WW', # Week number of the year (Sunday as the first day of the week)
|
||||
# as a zero padded decimal number. All days in a new year preceding
|
||||
# the first Sunday are considered to be in week 0.
|
||||
@@ -143,21 +149,28 @@ date_format_mappings = {
|
||||
# as a decimal number. All days in a new year preceding the first
|
||||
# Monday are considered to be in week 0.
|
||||
'%x': 'medium', # Locale’s appropriate date representation.
|
||||
'%X': 'medium', # Locale’s appropriate time representation.
|
||||
'%y': 'YY', # Year without century as a zero-padded decimal number.
|
||||
'%Y': 'YYYY', # Year with century as a decimal number.
|
||||
'%Z': 'zzzz', # Time zone name (no characters if no time zone exists).
|
||||
'%%': '%',
|
||||
}
|
||||
|
||||
|
||||
def babel_format_date(date, format, locale, warn=None):
|
||||
def babel_format_date(date, format, locale, warn=None, formatter=babel.dates.format_date):
|
||||
if locale is None:
|
||||
locale = 'en'
|
||||
|
||||
# Check if we have the tzinfo attribute. If not we cannot do any time
|
||||
# related formats.
|
||||
if not hasattr(date, 'tzinfo'):
|
||||
formatter = babel.dates.format_date
|
||||
|
||||
try:
|
||||
return babel.dates.format_date(date, format, locale=locale)
|
||||
return formatter(date, format, locale=locale)
|
||||
except (ValueError, babel.core.UnknownLocaleError):
|
||||
# fallback to English
|
||||
return babel.dates.format_date(date, format, locale='en')
|
||||
return formatter(date, format, locale='en')
|
||||
except AttributeError:
|
||||
if warn:
|
||||
warn('Invalid date format. Quote the string by single quote '
|
||||
@@ -184,7 +197,8 @@ def format_date(format, date=None, language=None, warn=None):
|
||||
warnings.warn('LDML format support will be dropped at Sphinx-1.5',
|
||||
DeprecationWarning)
|
||||
|
||||
return babel_format_date(date, format, locale=language, warn=warn)
|
||||
return babel_format_date(date, format, locale=language, warn=warn,
|
||||
formatter=babel.dates.format_datetime)
|
||||
else:
|
||||
# consider the format as ustrftime's and try to convert it to babel's
|
||||
result = []
|
||||
@@ -192,7 +206,19 @@ def format_date(format, date=None, language=None, warn=None):
|
||||
for token in tokens:
|
||||
if token in date_format_mappings:
|
||||
babel_format = date_format_mappings.get(token, '')
|
||||
result.append(babel_format_date(date, babel_format, locale=language))
|
||||
|
||||
# Check if we have to use a different babel formatter then
|
||||
# format_datetime, because we only want to format a date
|
||||
# or a time.
|
||||
if token == '%x':
|
||||
function = babel.dates.format_date
|
||||
elif token == '%X':
|
||||
function = babel.dates.format_time
|
||||
else:
|
||||
function = babel.dates.format_datetime
|
||||
|
||||
result.append(babel_format_date(date, babel_format, locale=language,
|
||||
formatter=function))
|
||||
else:
|
||||
result.append(token)
|
||||
|
||||
|
||||
@@ -200,6 +200,18 @@ def test_format_date():
|
||||
format = 'Mon Mar 28 12:37:08 2016, commit 4367aef'
|
||||
assert i18n.format_date(format, date=date) == format
|
||||
|
||||
format = '%B %d, %Y, %H:%M:%S %I %p'
|
||||
datet = datetime.datetime(2016, 2, 7, 5, 11, 17, 0)
|
||||
assert i18n.format_date(format, date=datet) == 'February 07, 2016, 05:11:17 05 AM'
|
||||
|
||||
format = '%x'
|
||||
assert i18n.format_date(format, date=datet) == 'Feb 7, 2016'
|
||||
format = '%X'
|
||||
assert i18n.format_date(format, date=datet) == '5:11:17 AM'
|
||||
assert i18n.format_date(format, date=date) == 'Feb 7, 2016'
|
||||
format = '%c'
|
||||
assert i18n.format_date(format, date=datet) == 'Feb 7, 2016, 5:11:17 AM'
|
||||
assert i18n.format_date(format, date=date) == 'Feb 7, 2016'
|
||||
|
||||
def test_get_filename_for_language():
|
||||
app = TestApp()
|
||||
|
||||
Reference in New Issue
Block a user