summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDan Korostelev <nadako@gmail.com>2009-02-24 21:12:51 +0000
committerDan Korostelev <nadako@gmail.com>2009-02-24 21:12:51 +0000
commit144cd0ee6cd70301feec219e29ff604061fd316b (patch)
treecdfbf0235408779d260f2f6c9f04572fe1b66114
parent6c34b8a04801de54671efc89fcd2878c26de5763 (diff)
downloadzope-i18n-144cd0ee6cd70301feec219e29ff604061fd316b.tar.gz
Add support for month and day contexts and widths.
-rw-r--r--BRANCH-TODO.txt8
-rw-r--r--src/zope/i18n/interfaces/locales.py79
-rw-r--r--src/zope/i18n/locales/__init__.py21
-rw-r--r--src/zope/i18n/locales/xmlfactory.py154
4 files changed, 226 insertions, 36 deletions
diff --git a/BRANCH-TODO.txt b/BRANCH-TODO.txt
index 967923e..7704814 100644
--- a/BRANCH-TODO.txt
+++ b/BRANCH-TODO.txt
@@ -15,12 +15,10 @@ maintain full backward compatibility with earlier locale interfaces.
CLDR 1.1 (LDML 1.1)
-------------------
-Updated the XML files and fixed incompatibilities.
+- Updated the XML files and fixed incompatibilities.
+- Added support day and month contexts and widths.
-Still need to add interface/implementation for day/month context
-and day/month width system.
-
-Review other non-critical changes and implement them.
+Still need to review other not so critical changes and implement them.
CLDR 1.2 (LDML 1.2)
-------------------
diff --git a/src/zope/i18n/interfaces/locales.py b/src/zope/i18n/interfaces/locales.py
index bafcfe5..a4505b7 100644
--- a/src/zope/i18n/interfaces/locales.py
+++ b/src/zope/i18n/interfaces/locales.py
@@ -247,6 +247,59 @@ class ILocaleFormatLength(Interface):
readonly = True)
+class ILocaleMonthContext(Interface):
+ """Specifices a usage context for month names"""
+
+ type = TextLine(
+ title=u'Month context type',
+ description=u"Name of the month context, format or stand-alone.")
+
+ defaultWidth = TextLine(
+ title=u'Default month name width',
+ default=u'wide')
+
+ months = Dict(
+ title=u'Month Names',
+ description=u'A mapping of month name widths to a mapping of'
+ u'corresponding month names.',
+ key_type=Choice(
+ title=u'Width type',
+ values=(u'wide', u'abbreviated', u'narrow')),
+ value_type=Dict(
+ title=u'Month name',
+ key_type=Int(title=u'Type', min=1, max=12),
+ value_type=TextLine(title=u'Month Name'))
+ )
+
+
+class ILocaleDayContext(Interface):
+ """Specifices a usage context for days names"""
+
+ type = TextLine(
+ title=u'Day context type',
+ description=u"Name of the day context, format or stand-alone.")
+
+ defaultWidth = TextLine(
+ title=u'Default day name width',
+ default=u'wide')
+
+ days = Dict(
+ title=u'Day Names',
+ description=u'A mapping of day name widths to a mapping of'
+ u'corresponding day names.',
+ key_type=Choice(
+ title=u'Width type',
+ values=(u'wide', u'abbreviated', u'narrow')),
+ value_type=Dict(
+ title=u'Day name',
+ key_type=Choice(
+ title=u"Type",
+ values=(u'sun', u'mon', u'tue', u'wed',
+ u'thu', u'fri', u'sat')),
+ value_type=TextLine(title=u'Day Name'))
+ )
+
+
class ILocaleCalendar(Interface):
"""There is a massive amount of information contained in the calendar,
which made it attractive to be added."""
@@ -255,6 +308,19 @@ class ILocaleCalendar(Interface):
title=u"Calendar Type",
description=u"Name of the calendar, for example 'gregorian'.")
+ defaultMonthContext = TextLine(
+ title=u'Default month context',
+ default=u'format')
+
+ monthContexts = Dict(
+ title=u'Month Contexts',
+ description=u'A mapping of month context types to '
+ u'ILocaleMonthContext objects',
+ key_type=Choice(title=u'Type',
+ values=(u'format', u'stand-alone')),
+ value_type=Field(title=u'ILocaleMonthContext object'))
+
+ # BBB: leftover from CLDR 1.0
months = Dict(
title = u"Month Names",
description = u"A mapping of all month names and abbreviations",
@@ -262,6 +328,19 @@ class ILocaleCalendar(Interface):
value_type = Tuple(title=u"Month Name and Abbreviation",
min_length=2, max_length=2))
+ defaultDayContext = TextLine(
+ title=u'Default day context',
+ default=u'format')
+
+ dayContexts = Dict(
+ title=u'Day Contexts',
+ description=u'A mapping of day context types to '
+ u'ILocaleDayContext objects',
+ key_type=Choice(title=u'Type',
+ values=(u'format', u'stand-alone')),
+ value_type=Field(title=u'ILocaleDayContext object'))
+
+ # BBB: leftover from CLDR 1.0
days = Dict(
title=u"Weekdays Names",
description = u"A mapping of all month names and abbreviations",
diff --git a/src/zope/i18n/locales/__init__.py b/src/zope/i18n/locales/__init__.py
index d7ea842..907424d 100644
--- a/src/zope/i18n/locales/__init__.py
+++ b/src/zope/i18n/locales/__init__.py
@@ -29,6 +29,7 @@ from zope.i18n.interfaces.locales import ILocaleTimeZone, ILocaleCalendar
from zope.i18n.interfaces.locales import ILocaleCurrency, ILocaleNumbers
from zope.i18n.interfaces.locales import ILocaleFormat, ILocaleFormatLength
from zope.i18n.interfaces.locales import ILocaleOrientation
+from zope.i18n.interfaces.locales import ILocaleDayContext, ILocaleMonthContext
from zope.i18n.format import NumberFormat, DateTimeFormat
from zope.i18n.locales.inheritance import \
AttributeInheritance, InheritingDictionary, NoParentException
@@ -234,6 +235,26 @@ class LocaleFormatLength(AttributeInheritance):
self.default = None
+class LocaleMonthContext(AttributeInheritance):
+
+ implements(ILocaleMonthContext)
+
+ def __init__(self, type=None):
+ """Initialize the object."""
+ self.type = type
+ self.default = u'wide'
+
+
+class LocaleDayContext(AttributeInheritance):
+
+ implements(ILocaleDayContext)
+
+ def __init__(self, type=None):
+ """Initialize the object."""
+ self.type = type
+ self.default = u'wide'
+
+
class LocaleCalendar(AttributeInheritance):
"""Represents locale data for a calendar, like 'gregorian'.
diff --git a/src/zope/i18n/locales/xmlfactory.py b/src/zope/i18n/locales/xmlfactory.py
index 53d44d6..8b16930 100644
--- a/src/zope/i18n/locales/xmlfactory.py
+++ b/src/zope/i18n/locales/xmlfactory.py
@@ -21,7 +21,8 @@ from zope.i18n.locales import Locale, LocaleDisplayNames, LocaleDates
from zope.i18n.locales import LocaleVersion, LocaleIdentity, LocaleTimeZone
from zope.i18n.locales import LocaleCalendar, LocaleCurrency, LocaleNumbers
from zope.i18n.locales import LocaleFormat, LocaleFormatLength, dayMapping
-from zope.i18n.locales import LocaleOrientation
+from zope.i18n.locales import LocaleOrientation, LocaleDayContext
+from zope.i18n.locales import LocaleMonthContext
from zope.i18n.locales.inheritance import InheritingDictionary
class LocaleFactory(object):
@@ -298,7 +299,9 @@ class LocaleFactory(object):
>>> from xml.dom.minidom import parseString
>>> xml = u'''
... <months>
+ ... <default type="format" />
... <monthContext type="format">
+ ... <default type="wide" />
... <monthWidth type="wide">
... <month type="1">Januar</month>
... <month type="2">Februar</month>
@@ -332,6 +335,30 @@ class LocaleFactory(object):
>>> dom = parseString(xml)
>>> factory._extractMonths(dom.documentElement, calendar)
+ The contexts and widths were introduced in CLDR 1.1, the way
+ of getting month names is like this::
+
+ >>> calendar.defaultMonthContext
+ u'format'
+
+ >>> ctx = calendar.monthContexts[u'format']
+ >>> ctx.defaultWidth
+ u'wide'
+
+ >>> names = [ctx.months[u'wide'][type] for type in xrange(1,13)]
+ >>> names[:7]
+ [u'Januar', u'Februar', u'Maerz', u'April', u'Mai', u'Juni', u'Juli']
+ >>> names[7:]
+ [u'August', u'September', u'Oktober', u'November', u'Dezember']
+
+ >>> abbrs = [ctx.months[u'abbreviated'][type] for type in xrange(1,13)]
+ >>> abbrs[:6]
+ [u'Jan', u'Feb', u'Mrz', u'Apr', u'Mai', u'Jun']
+ >>> abbrs[6:]
+ [u'Jul', u'Aug', u'Sep', u'Okt', u'Nov', u'Dez']
+
+ The old, CLDR 1.0 way of getting month names and abbreviations::
+
>>> names = [calendar.months.get(type, (None, None))[0]
... for type in range(1, 13)]
>>> names[:7]
@@ -345,25 +372,46 @@ class LocaleFactory(object):
[u'Jan', u'Feb', u'Mrz', u'Apr', u'Mai', u'Jun']
>>> abbrs[6:]
[u'Jul', u'Aug', u'Sep', u'Okt', u'Nov', u'Dez']
+
+
"""
+
+ defaultMonthContext_node = months_node.getElementsByTagName('default')
+ if defaultMonthContext_node:
+ calendar.defaultMonthContext = defaultMonthContext_node[0].getAttribute('type')
+
monthContext_nodes = months_node.getElementsByTagName('monthContext')
if not monthContext_nodes:
return
- format_node = None
- for node in monthContext_nodes:
- if node.getAttribute('type') == 'format':
- format_node = node
- break
- if not format_node:
- return
- names_node = abbrs_node = None
- for node in format_node.getElementsByTagName('monthWidth'):
- type = node.getAttribute('type')
- if type == 'abbreviated':
- abbrs_node = node
- elif type == 'wide':
- names_node = node
+ calendar.monthContexts = InheritingDictionary()
+ names_node = abbrs_node = None # BBB
+
+ for node in monthContext_nodes:
+ context_type = node.getAttribute('type')
+ mctx = LocaleMonthContext(context_type)
+ calendar.monthContexts[context_type] = mctx
+
+ defaultWidth_node = node.getElementsByTagName('default')
+ if defaultWidth_node:
+ mctx.defaultWidth = defaultWidth_node[0].getAttribute('type')
+
+ widths = InheritingDictionary()
+ mctx.months = widths
+ for width_node in node.getElementsByTagName('monthWidth'):
+ width_type = width_node.getAttribute('type')
+ width = InheritingDictionary()
+ widths[width_type] = width
+
+ for month_node in width_node.getElementsByTagName('month'):
+ mtype = int(month_node.getAttribute('type'))
+ width[mtype] = self._getText(month_node.childNodes)
+
+ if context_type == 'format':
+ if width_type == 'abbreviated':
+ abbrs_node = width_node
+ elif width_type == 'wide':
+ names_node = width_node
if not (names_node and abbrs_node):
return
@@ -400,7 +448,9 @@ class LocaleFactory(object):
>>> from xml.dom.minidom import parseString
>>> xml = u'''
... <days>
+ ... <default type="format" />
... <dayContext type="format">
+ ... <default type="wide" />
... <dayWidth type="wide">
... <day type="sun">Sonntag</day>
... <day type="mon">Montag</day>
@@ -424,37 +474,79 @@ class LocaleFactory(object):
>>> dom = parseString(xml)
>>> factory._extractDays(dom.documentElement, calendar)
+ Day contexts and widths were introduced in CLDR 1.1, here's
+ how to use them::
+
+ >>> calendar.defaultDayContext
+ u'format'
+
+ >>> ctx = calendar.dayContexts[u'format']
+ >>> ctx.defaultWidth
+ u'wide'
+
+ >>> names = [ctx.days[u'wide'][type] for type in xrange(1,8)]
+ >>> names[:4]
+ [u'Montag', u'Dienstag', u'Mittwoch', u'Donnerstag']
+ >>> names[4:]
+ [u'Freitag', u'Samstag', u'Sonntag']
+
+ >>> abbrs = [ctx.days[u'abbreviated'][type] for type in xrange(1,8)]
+ >>> abbrs
+ [u'Mo', u'Di', u'Mi', u'Do', u'Fr', u'Sa', u'So']
+
+ And here's the old CLDR 1.0 way of getting day names and
+ abbreviations::
+
>>> names = [calendar.days.get(type, (None, None))[0]
- ... for type in range(1, 8)]
+ ... for type in xrange(1, 8)]
>>> names[:4]
[u'Montag', u'Dienstag', u'Mittwoch', u'Donnerstag']
>>> names[4:]
[u'Freitag', u'Samstag', u'Sonntag']
>>> abbrs = [calendar.days.get(type, (None, None))[1]
- ... for type in range(1, 8)]
+ ... for type in xrange(1, 8)]
>>> abbrs
[u'Mo', u'Di', u'Mi', u'Do', u'Fr', u'Sa', u'So']
"""
+
+ defaultDayContext_node = days_node.getElementsByTagName('default')
+ if defaultDayContext_node:
+ calendar.defaultDayContext = defaultDayContext_node[0].getAttribute('type')
+
dayContext_nodes = days_node.getElementsByTagName('dayContext')
if not dayContext_nodes:
return
- format_node = None
- for node in dayContext_nodes:
- if node.getAttribute('type') == 'format':
- format_node = node
- break
- if not format_node:
- return
- names_node = abbrs_node = None
- for node in format_node.getElementsByTagName('dayWidth'):
- type = node.getAttribute('type')
- if type == 'abbreviated':
- abbrs_node = node
- elif type == 'wide':
- names_node = node
+ calendar.dayContexts = InheritingDictionary()
+ names_node = abbrs_node = None # BBB
+ for node in dayContext_nodes:
+ context_type = node.getAttribute('type')
+ dctx = LocaleDayContext(context_type)
+ calendar.dayContexts[context_type] = dctx
+
+ defaultWidth_node = node.getElementsByTagName('default')
+ if defaultWidth_node:
+ dctx.defaultWidth = defaultWidth_node[0].getAttribute('type')
+
+ widths = InheritingDictionary()
+ dctx.days = widths
+ for width_node in node.getElementsByTagName('dayWidth'):
+ width_type = width_node.getAttribute('type')
+ width = InheritingDictionary()
+ widths[width_type] = width
+
+ for day_node in width_node.getElementsByTagName('day'):
+ dtype = dayMapping[day_node.getAttribute('type')]
+ width[dtype] = self._getText(day_node.childNodes)
+
+ if context_type == 'format':
+ if width_type == 'abbreviated':
+ abbrs_node = width_node
+ elif width_type == 'wide':
+ names_node = width_node
+
if not (names_node and abbrs_node):
return