6926: merge to trunk p2: gramps/ code changes
svn: r23324
This commit is contained in:
parent
dc4404e555
commit
be84468d3f
@ -24,6 +24,8 @@
|
||||
Class handling language-specific selection for date parser and displayer.
|
||||
"""
|
||||
|
||||
from __future__ import print_function, unicode_literals
|
||||
|
||||
#-------------------------------------------------------------------------
|
||||
#
|
||||
# set up logging
|
||||
@ -36,6 +38,7 @@ _ = glocale.translation.sgettext
|
||||
# import prerequisites for localized handlers
|
||||
from ._datehandler import (LANG, LANG_SHORT, LANG_TO_PARSER, LANG_TO_DISPLAY,
|
||||
register_datehandler)
|
||||
from . import _datestrings
|
||||
|
||||
# Import all the localized handlers
|
||||
from . import _date_ar
|
||||
@ -91,5 +94,16 @@ except:
|
||||
|
||||
# Import utility functions
|
||||
from ._dateutils import *
|
||||
from ._grampslocale import (codeset, month_to_int, long_months, short_months,
|
||||
long_days, short_days, tformat)
|
||||
from ._grampslocale import (codeset, long_days, short_days, tformat)
|
||||
|
||||
if __name__ == "__main__":
|
||||
from ._datedisplay import DateDisplay
|
||||
m = 0
|
||||
for l,d in LANG_TO_DISPLAY.items():
|
||||
if len(l) != 2:
|
||||
continue
|
||||
m = max(m, len(d.formats))
|
||||
print("{}: {} {} own dg: {}".format(
|
||||
l, len(d.formats), d.formats,
|
||||
d._display_gregorian != DateDisplay._display_gregorian))
|
||||
print("MAX: ", m)
|
||||
|
@ -21,7 +21,7 @@
|
||||
# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
#
|
||||
|
||||
# $Id$
|
||||
# $Id: _date_fr.py 22672 2013-07-13 18:01:08Z paul-franklin $
|
||||
|
||||
#-------------------------------------------------------------------------
|
||||
#
|
||||
@ -60,92 +60,15 @@ class DateParserFR(DateParser):
|
||||
|
||||
month_to_int = DateParser.month_to_int
|
||||
|
||||
# Custom short months not the same as long months
|
||||
|
||||
month_to_int["janv"] = 1
|
||||
month_to_int["févr"] = 2
|
||||
month_to_int["juil"] = 7
|
||||
month_to_int["sept"] = 9
|
||||
month_to_int["oct"] = 10
|
||||
month_to_int["déc"] = 12
|
||||
|
||||
# Add common value
|
||||
|
||||
month_to_int["bluviose"] = 5
|
||||
month_to_int["vendose"] = 6
|
||||
month_to_int["7bre"] = 9
|
||||
month_to_int["8bre"] = 10
|
||||
month_to_int["9bre"] = 11
|
||||
month_to_int["10bre"] = 12
|
||||
month_to_int["xbre"] = 12
|
||||
|
||||
# Add common latin
|
||||
|
||||
month_to_int["januaris"] = 1
|
||||
month_to_int["januarii"] = 1
|
||||
month_to_int["januarius"] = 1
|
||||
month_to_int["februaris"] = 2
|
||||
month_to_int["februarii"] = 2
|
||||
month_to_int["februarius"] = 2
|
||||
month_to_int["martii"] = 3
|
||||
month_to_int["martius"] = 3
|
||||
month_to_int["aprilis"] = 4
|
||||
month_to_int["maius"] = 5
|
||||
month_to_int["maii"] = 5
|
||||
month_to_int["junius"] = 6
|
||||
month_to_int["junii"] = 6
|
||||
month_to_int["julius"] = 7
|
||||
month_to_int["julii"] = 7
|
||||
month_to_int["augustus"] = 8
|
||||
month_to_int["augusti"] = 8
|
||||
month_to_int["septembris"] = 9
|
||||
month_to_int["7bris"] = 9
|
||||
month_to_int["september"] = 9
|
||||
month_to_int["october"] = 10
|
||||
month_to_int["octobris"] = 10
|
||||
month_to_int["8bris"] = 10
|
||||
month_to_int["novembris"] = 11
|
||||
month_to_int["9bris"] = 11
|
||||
month_to_int["november"] = 11
|
||||
month_to_int["decembris"] = 12
|
||||
month_to_int["10bris"] = 12
|
||||
month_to_int["xbris"] = 12
|
||||
month_to_int["december"] = 12
|
||||
|
||||
#local and historical variants
|
||||
# Add common on east france
|
||||
|
||||
month_to_int["janer"] = 1
|
||||
month_to_int["jenner"] = 1
|
||||
month_to_int["hartmonat"] = 1
|
||||
month_to_int["hartung"] = 1
|
||||
month_to_int["eismond"] = 1
|
||||
month_to_int["hornung"] = 2
|
||||
month_to_int["wintermonat"] = 2
|
||||
month_to_int["taumond"] = 2
|
||||
month_to_int["narrenmond"] = 2
|
||||
month_to_int["lenzing"] = 3
|
||||
month_to_int["ostermond"] = 4
|
||||
month_to_int["wonnemond"] = 5
|
||||
month_to_int["wiesenmonat"] = 5
|
||||
month_to_int["brachet"] = 6
|
||||
month_to_int["heuet"] = 7
|
||||
month_to_int["ernting"] = 8
|
||||
month_to_int["scheiding"] = 9
|
||||
month_to_int["gilbhard"] = 10
|
||||
month_to_int["nebelmonat"] = 11
|
||||
month_to_int["nebelung"] = 11
|
||||
month_to_int["julmond"] = 12
|
||||
|
||||
modifier_to_int = {
|
||||
'avant': Date.MOD_BEFORE,
|
||||
'av.' : Date.MOD_BEFORE,
|
||||
#u'av' : Date.MOD_BEFORE, # Broke Hebrew "Av" month name
|
||||
#u'<' : Date.MOD_BEFORE, # Worrying about XML/HTML parsing
|
||||
'après': Date.MOD_AFTER,
|
||||
'ap.' : Date.MOD_AFTER,
|
||||
'ap' : Date.MOD_AFTER,
|
||||
#u'>' : Date.MOD_AFTER, # Worrying about XML/HTML parsing
|
||||
'avant' : Date.MOD_BEFORE,
|
||||
'av.' : Date.MOD_BEFORE,
|
||||
#u'av' : Date.MOD_BEFORE, # Broke Hebrew "Av" month name
|
||||
#u'<' : Date.MOD_BEFORE, # Worrying about XML/HTML parsing
|
||||
'après' : Date.MOD_AFTER,
|
||||
'ap.' : Date.MOD_AFTER,
|
||||
'ap' : Date.MOD_AFTER,
|
||||
#u'>' : Date.MOD_AFTER, # Worrying about XML/HTML parsing
|
||||
'environ' : Date.MOD_ABOUT,
|
||||
'env.' : Date.MOD_ABOUT,
|
||||
'env' : Date.MOD_ABOUT,
|
||||
@ -157,23 +80,6 @@ class DateParserFR(DateParser):
|
||||
'~' : Date.MOD_ABOUT,
|
||||
}
|
||||
|
||||
calendar_to_int = {
|
||||
'grégorien': Date.CAL_GREGORIAN,
|
||||
'g' : Date.CAL_GREGORIAN,
|
||||
'julien': Date.CAL_JULIAN,
|
||||
'j' : Date.CAL_JULIAN,
|
||||
'hébreu': Date.CAL_HEBREW,
|
||||
'h' : Date.CAL_HEBREW,
|
||||
'islamique': Date.CAL_ISLAMIC,
|
||||
'i' : Date.CAL_ISLAMIC,
|
||||
'révolutionnaire': Date.CAL_FRENCH,
|
||||
'r' : Date.CAL_FRENCH,
|
||||
'perse': Date.CAL_PERSIAN,
|
||||
'p' : Date.CAL_PERSIAN,
|
||||
'suédois': Date.CAL_SWEDISH,
|
||||
's' : Date.CAL_SWEDISH,
|
||||
}
|
||||
|
||||
quality_to_int = {
|
||||
'estimée': Date.QUAL_ESTIMATED,
|
||||
'est.' : Date.QUAL_ESTIMATED,
|
||||
@ -202,6 +108,83 @@ class DateParserFR(DateParser):
|
||||
"""
|
||||
DateParser.init_strings(self)
|
||||
|
||||
DateParser.calendar_to_int.update({
|
||||
'grégorien' : Date.CAL_GREGORIAN,
|
||||
'g' : Date.CAL_GREGORIAN,
|
||||
'julien' : Date.CAL_JULIAN,
|
||||
'j' : Date.CAL_JULIAN,
|
||||
'hébreu' : Date.CAL_HEBREW,
|
||||
'h' : Date.CAL_HEBREW,
|
||||
'islamique' : Date.CAL_ISLAMIC,
|
||||
'i' : Date.CAL_ISLAMIC,
|
||||
'révolutionnaire' : Date.CAL_FRENCH,
|
||||
'r' : Date.CAL_FRENCH,
|
||||
'perse' : Date.CAL_PERSIAN,
|
||||
'p' : Date.CAL_PERSIAN,
|
||||
'suédois' : Date.CAL_SWEDISH,
|
||||
's' : Date.CAL_SWEDISH,
|
||||
})
|
||||
|
||||
DateParser.month_to_int.update({
|
||||
"januaris" : 1,
|
||||
"januarii" : 1,
|
||||
"januarius" : 1,
|
||||
"janer" : 1,
|
||||
"jenner" : 1,
|
||||
"hartmonat" : 1,
|
||||
"hartung" : 1,
|
||||
"eismond" : 1,
|
||||
"februaris" : 2,
|
||||
"februarii" : 2,
|
||||
"februarius" : 2,
|
||||
"hornung" : 2,
|
||||
"wintermonat" : 2,
|
||||
"taumond" : 2,
|
||||
"narrenmond" : 2,
|
||||
"martii" : 3,
|
||||
"martius" : 3,
|
||||
"lenzing" : 3,
|
||||
"aprilis" : 4,
|
||||
"ostermond" : 4,
|
||||
"maius" : 5,
|
||||
"maii" : 5,
|
||||
"bluviose" : 5,
|
||||
"wonnemond" : 5,
|
||||
"wiesenmonat" : 5,
|
||||
"junius" : 6,
|
||||
"junii" : 6,
|
||||
"vendose" : 6,
|
||||
"brachet" : 6,
|
||||
"julius" : 7,
|
||||
"julii" : 7,
|
||||
"heuet" : 7,
|
||||
"augustus" : 8,
|
||||
"augusti" : 8,
|
||||
"ernting" : 8,
|
||||
"septembris" : 9,
|
||||
"7bre" : 9,
|
||||
"7bris" : 9,
|
||||
"september" : 9,
|
||||
"october" : 10,
|
||||
"octobris" : 10,
|
||||
"8bre" : 10,
|
||||
"8bris" : 10,
|
||||
"gilbhard" : 10,
|
||||
"november" : 11,
|
||||
"novembris" : 11,
|
||||
"9bre" : 11,
|
||||
"9bris" : 11,
|
||||
"nebelmonat" : 11,
|
||||
"nebelung" : 11,
|
||||
"december" : 12,
|
||||
"decembris" : 12,
|
||||
"10bre" : 12,
|
||||
"10bris" : 12,
|
||||
"xbre" : 12,
|
||||
"xbris" : 12,
|
||||
"julmond" : 12,
|
||||
})
|
||||
|
||||
# This self._numeric is different from the base
|
||||
# avoid bug gregorian / french calendar conversion (+/-10 days)
|
||||
|
||||
@ -211,35 +194,35 @@ class DateParserFR(DateParser):
|
||||
self._range = re.compile("(entre|ent\.|ent)\s+(?P<start>.+)\s+(et)\s+(?P<stop>.+)",
|
||||
re.IGNORECASE)
|
||||
|
||||
# This self._text are different from the base
|
||||
# by adding ".?" after the first date and removing "\s*$" at the end
|
||||
# This self._text are different from the base
|
||||
# by adding ".?" after the first date and removing "\s*$" at the end
|
||||
|
||||
#gregorian and julian
|
||||
#gregorian and julian
|
||||
|
||||
self._text2 = re.compile('(\d+)?.?\s+?%s\s*((\d+)(/\d+)?)?' %
|
||||
self._mon_str, re.IGNORECASE)
|
||||
|
||||
#hebrew
|
||||
#hebrew
|
||||
|
||||
self._jtext2 = re.compile('(\d+)?.?\s+?%s\s*((\d+)(/\d+)?)?' %
|
||||
self._jmon_str, re.IGNORECASE)
|
||||
|
||||
#french
|
||||
#french
|
||||
|
||||
self._ftext2 = re.compile('(\d+)?.?\s+?%s\s*((\d+)(/\d+)?)?' %
|
||||
self._fmon_str, re.IGNORECASE)
|
||||
|
||||
#persian
|
||||
#persian
|
||||
|
||||
self._ptext2 = re.compile('(\d+)?.?\s+?%s\s*((\d+)(/\d+)?)?' %
|
||||
self._pmon_str, re.IGNORECASE)
|
||||
|
||||
#islamic
|
||||
#islamic
|
||||
|
||||
self._itext2 = re.compile('(\d+)?.?\s+?%s\s*((\d+)(/\d+)?)?' %
|
||||
self._imon_str, re.IGNORECASE)
|
||||
|
||||
#swedish
|
||||
#swedish
|
||||
|
||||
self._stext2 = re.compile('(\d+)?.?\s+?%s\s*((\d+)(/\d+)?)?' %
|
||||
self._smon_str, re.IGNORECASE)
|
||||
@ -253,19 +236,6 @@ class DateDisplayFR(DateDisplay):
|
||||
"""
|
||||
French language date display class.
|
||||
"""
|
||||
long_months = ( "", "janvier", "février", "mars", "avril", "mai",
|
||||
"juin", "juillet", "août", "septembre", "octobre",
|
||||
"novembre", "décembre" )
|
||||
|
||||
short_months = ( "", "janv", "févr", "mars", "avril", "mai", "juin",
|
||||
"juil", "août", "sept", "oct", "nov", "déc" )
|
||||
|
||||
calendar = ("", "Julien", "Hébreu", "Révolutionnaire",
|
||||
"Perse", "Islamique", "Suédois")
|
||||
|
||||
_mod_str = ("", "avant ", "après ", "vers ", "", "", "")
|
||||
|
||||
_qual_str = ("", "estimée ", "calculée ", "")
|
||||
|
||||
_bce_str = "%s avant le calendrier"
|
||||
|
||||
@ -287,7 +257,7 @@ class DateDisplayFR(DateDisplay):
|
||||
)
|
||||
# this definition must agree with its "_display_gregorian" method
|
||||
|
||||
def _display_gregorian(self, date_val):
|
||||
def _display_gregorian(self, date_val, **kwargs):
|
||||
"""
|
||||
display gregorian calendar date in different format
|
||||
"""
|
||||
@ -409,40 +379,7 @@ class DateDisplayFR(DateDisplay):
|
||||
else:
|
||||
return value
|
||||
|
||||
def display(self, date):
|
||||
"""
|
||||
Return a text string representing the date.
|
||||
"""
|
||||
|
||||
mod = date.get_modifier()
|
||||
cal = date.get_calendar()
|
||||
qual = date.get_quality()
|
||||
start = date.get_start_date()
|
||||
newyear = date.get_new_year()
|
||||
|
||||
qual_str = (self._qual_str)[qual]
|
||||
|
||||
if mod == Date.MOD_TEXTONLY:
|
||||
return date.get_text()
|
||||
elif start == Date.EMPTY:
|
||||
return ""
|
||||
elif mod == Date.MOD_SPAN:
|
||||
date1 = self.display_cal[cal](start)
|
||||
date2 = self.display_cal[cal](date.get_stop_date())
|
||||
scal = self.format_extras(cal, newyear)
|
||||
return "%s%s %s %s %s%s" % (qual_str, 'de', date1, 'à',
|
||||
date2, scal)
|
||||
elif mod == Date.MOD_RANGE:
|
||||
date1 = self.display_cal[cal](start)
|
||||
date2 = self.display_cal[cal](date.get_stop_date())
|
||||
scal = self.format_extras(cal, newyear)
|
||||
return "%s%s %s %s %s%s" % (qual_str, 'entre', date1, 'et',
|
||||
date2, scal)
|
||||
else:
|
||||
text = self.display_cal[date.get_calendar()](start)
|
||||
scal = self.format_extras(cal, newyear)
|
||||
return "%s%s%s%s" % (qual_str, (self._mod_str)[mod], text,
|
||||
scal)
|
||||
display = DateDisplay.display_formatted
|
||||
|
||||
#-------------------------------------------------------------------------
|
||||
#
|
||||
|
@ -18,7 +18,7 @@
|
||||
# along with this program; if not, write to the Free Software
|
||||
# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
#
|
||||
# $Id$
|
||||
# $Id: _date_hr.py 22672 2013-07-13 18:01:08Z paul-franklin $
|
||||
#
|
||||
|
||||
# Croatian version 2008 by Josip
|
||||
@ -50,98 +50,6 @@ from ._datehandler import register_datehandler
|
||||
#
|
||||
#-------------------------------------------------------------------------
|
||||
class DateParserHR(DateParser):
|
||||
"""
|
||||
Converts a text string into a Date object
|
||||
"""
|
||||
month_to_int = DateParser.month_to_int
|
||||
|
||||
month_to_int["siječanj"] = 1
|
||||
month_to_int["siječnja"] = 1
|
||||
month_to_int["sij"] = 1
|
||||
month_to_int["januar"] = 1
|
||||
month_to_int["januara"] = 1
|
||||
month_to_int["i"] = 1
|
||||
|
||||
month_to_int["veljača"] = 2
|
||||
month_to_int["veljače"] = 2
|
||||
month_to_int["velj"] = 2
|
||||
month_to_int["februar"] = 2
|
||||
month_to_int["februara"] = 2
|
||||
month_to_int["ii"] = 2
|
||||
|
||||
month_to_int["ožujak"] = 3
|
||||
month_to_int["ožujka"] = 3
|
||||
month_to_int["ožu"] = 3
|
||||
month_to_int["mart"] = 3
|
||||
month_to_int["marta"] = 3
|
||||
month_to_int["iii"] = 3
|
||||
|
||||
month_to_int["travanj"] = 4
|
||||
month_to_int["travnja"] = 4
|
||||
month_to_int["tra"] = 4
|
||||
month_to_int["april"] = 4
|
||||
month_to_int["aprila"] = 4
|
||||
month_to_int["iv"] = 4
|
||||
|
||||
month_to_int["svibanj"] = 5
|
||||
month_to_int["svibnja"] = 5
|
||||
month_to_int["svi"] = 5
|
||||
month_to_int["maj"] = 5
|
||||
month_to_int["maja"] = 5
|
||||
month_to_int["v"] = 5
|
||||
|
||||
month_to_int["lipanj"] = 6
|
||||
month_to_int["lipnja"] = 6
|
||||
month_to_int["lip"] = 6
|
||||
month_to_int["jun"] = 6
|
||||
month_to_int["juna"] = 6
|
||||
month_to_int["vi"] = 6
|
||||
|
||||
month_to_int["srpanj"] = 7
|
||||
month_to_int["srpnja"] = 7
|
||||
month_to_int["srp"] = 7
|
||||
month_to_int["juli"] = 7
|
||||
month_to_int["jula"] = 7
|
||||
month_to_int["vii"] = 7
|
||||
|
||||
month_to_int["kolovoz"] = 8
|
||||
month_to_int["kolovoza"] = 8
|
||||
month_to_int["kol"] = 8
|
||||
month_to_int["august"] = 8
|
||||
month_to_int["augusta"] = 8
|
||||
month_to_int["viii"] = 8
|
||||
|
||||
month_to_int["rujan"] = 9
|
||||
month_to_int["rujna"] = 9
|
||||
month_to_int["ruj"] = 9
|
||||
month_to_int["septembar"] = 9
|
||||
month_to_int["septembra"] = 9
|
||||
month_to_int["ix"] = 9
|
||||
month_to_int["7ber"] = 9
|
||||
|
||||
month_to_int["listopad"] = 10
|
||||
month_to_int["listopada"] = 10
|
||||
month_to_int["lis"] = 10
|
||||
month_to_int["oktobar"] = 10
|
||||
month_to_int["oktobra"] = 10
|
||||
month_to_int["x"] = 10
|
||||
month_to_int["8ber"] = 10
|
||||
|
||||
month_to_int["studeni"] = 11
|
||||
month_to_int["studenog"] = 11
|
||||
month_to_int["stu"] = 11
|
||||
month_to_int["novembar"] = 11
|
||||
month_to_int["novembra"] = 11
|
||||
month_to_int["xi"] = 11
|
||||
month_to_int["9ber"] = 11
|
||||
|
||||
month_to_int["prosinac"] = 12
|
||||
month_to_int["prosinca"] = 12
|
||||
month_to_int["pro"] = 12
|
||||
month_to_int["decembar"] = 12
|
||||
month_to_int["decembra"] = 12
|
||||
month_to_int["xii"] = 12
|
||||
|
||||
modifier_to_int = {
|
||||
'prije' : Date.MOD_BEFORE,
|
||||
'pr. ' : Date.MOD_BEFORE,
|
||||
@ -152,23 +60,6 @@ class DateParserHR(DateParser):
|
||||
|
||||
}
|
||||
|
||||
calendar_to_int = {
|
||||
'gregorijanski' : Date.CAL_GREGORIAN,
|
||||
'greg.' : Date.CAL_GREGORIAN,
|
||||
'julijanski' : Date.CAL_JULIAN,
|
||||
'jul.' : Date.CAL_JULIAN,
|
||||
'hebrejski' : Date.CAL_HEBREW,
|
||||
'hebr.' : Date.CAL_HEBREW,
|
||||
'islamski' : Date.CAL_ISLAMIC,
|
||||
'isl.' : Date.CAL_ISLAMIC,
|
||||
'francuski republikanski': Date.CAL_FRENCH,
|
||||
'franc.' : Date.CAL_FRENCH,
|
||||
'perzijski' : Date.CAL_PERSIAN,
|
||||
'perz. ' : Date.CAL_PERSIAN,
|
||||
'švedski' : Date.CAL_SWEDISH,
|
||||
's' : Date.CAL_SWEDISH,
|
||||
}
|
||||
|
||||
quality_to_int = {
|
||||
'približno' : Date.QUAL_ESTIMATED,
|
||||
'prb.' : Date.QUAL_ESTIMATED,
|
||||
@ -184,20 +75,20 @@ class DateParserHR(DateParser):
|
||||
compiles regular expression strings for matching dates
|
||||
"""
|
||||
DateParser.init_strings(self)
|
||||
# match 'Day. MONTH year.' format with or without dots
|
||||
self._text2 = re.compile('(\d+)?\.?\s*?%s\.?\s*((\d+)(/\d+)?)?\s*\.?$'
|
||||
% self._mon_str, re.IGNORECASE)
|
||||
# match Day.Month.Year.
|
||||
self._numeric = re.compile(
|
||||
"((\d+)[/\. ])?\s*((\d+)[/\.])?\s*(\d+)\.?$"
|
||||
)
|
||||
self._span = re.compile("(od)\s+(?P<start>.+)\s+(do)\s+(?P<stop>.+)",
|
||||
re.IGNORECASE)
|
||||
self._range = re.compile(
|
||||
"(između)\s+(?P<start>.+)\s+(i)\s+(?P<stop>.+)",
|
||||
re.IGNORECASE)
|
||||
self._jtext2 = re.compile('(\d+)?.?\s+?%s\s*((\d+)(/\d+)?)?'\
|
||||
% self._jmon_str, re.IGNORECASE)
|
||||
#~ DateParser.calendar_to_int.update({
|
||||
#~ 'персидский' : Date.CAL_PERSIAN,
|
||||
#~ 'п' : Date.CAL_PERSIAN,
|
||||
#~ })
|
||||
_span_1 = ['od']
|
||||
_span_2 = ['do']
|
||||
_range_1 = ['između']
|
||||
_range_2 = ['i']
|
||||
self._span = re.compile("(%s)\s+(?P<start>.+)\s+(%s)\s+(?P<stop>.+)" %
|
||||
('|'.join(_span_1), '|'.join(_span_2)),
|
||||
re.IGNORECASE)
|
||||
self._range = re.compile("(%s)\s+(?P<start>.+)\s+(%s)\s+(?P<stop>.+)" %
|
||||
('|'.join(_range_1), '|'.join(_range_2)),
|
||||
re.IGNORECASE)
|
||||
|
||||
#-------------------------------------------------------------------------
|
||||
#
|
||||
@ -208,150 +99,11 @@ class DateDisplayHR(DateDisplay):
|
||||
"""
|
||||
Croatian language date display class.
|
||||
"""
|
||||
long_months = ( "",
|
||||
"siječnja",
|
||||
"veljače",
|
||||
"ožujka",
|
||||
"travnja",
|
||||
"svibnja",
|
||||
"lipnja",
|
||||
"srpnja",
|
||||
"kolovoza",
|
||||
"rujna",
|
||||
"listopada",
|
||||
"studenog",
|
||||
"prosinca"
|
||||
)
|
||||
|
||||
#currently unused
|
||||
short_months = ( "", "sij", "velj", "ožu", "tra", "svi", "lip",
|
||||
"srp", "kol", "ruj", "lis", "stu", "pro"
|
||||
)
|
||||
|
||||
calendar = (
|
||||
"", "julijanski", "hebrejski",
|
||||
"francuski republikanski", "perzijski", "islamski",
|
||||
"swedish"
|
||||
)
|
||||
|
||||
_mod_str = ("", "prije ", "poslije ", "okolo ", "", "", "")
|
||||
|
||||
_qual_str = ("", "približno ", "izračunato ")
|
||||
|
||||
# TODO fix BUG 7064: non-Gregorian calendars wrongly use BCE notation for negative dates
|
||||
# not refactoring _bce_str into base class because it'll be gone under #7064
|
||||
_bce_str = "%s p.n.e."
|
||||
|
||||
formats = (
|
||||
"GGGG-MM-DD (ISO-8601)",
|
||||
"Numerički",
|
||||
"D.M.GGGG.",
|
||||
"D. MMMM GGGG.",
|
||||
"D. Rb GGGG."
|
||||
)
|
||||
# this definition must agree with its "_display_gregorian" method
|
||||
|
||||
roman_months = (
|
||||
"",
|
||||
"I",
|
||||
"II",
|
||||
"III",
|
||||
"IV",
|
||||
"V",
|
||||
"VI",
|
||||
"VII",
|
||||
"VIII",
|
||||
"IX",
|
||||
"X",
|
||||
"XI",
|
||||
"XII"
|
||||
)
|
||||
|
||||
def _display_gregorian(self, date_val):
|
||||
"""
|
||||
display gregorian calendar date in different format
|
||||
"""
|
||||
# this must agree with its locale-specific "formats" definition
|
||||
year = self._slash_year(date_val[2], date_val[3])
|
||||
if self.format == 0:
|
||||
return self.display_iso(date_val)
|
||||
elif self.format == 1:
|
||||
# numerical
|
||||
if date_val[3]:
|
||||
return self.display_iso(date_val)
|
||||
else:
|
||||
if date_val[0] == 0 and date_val[1] == 0:
|
||||
value = str(date_val[2])
|
||||
else:
|
||||
value = self._tformat.replace('%m', str(date_val[1]))
|
||||
value = value.replace('%d', str(date_val[0]))
|
||||
value = value.replace('%Y', str(abs(date_val[2])))
|
||||
value = value.replace('-', '/')
|
||||
elif self.format == 2:
|
||||
# day.month_number.year.
|
||||
if date_val[0] == 0:
|
||||
if date_val[1] == 0:
|
||||
value = year
|
||||
else:
|
||||
value = "%s.%s." % (date_val[1], year)
|
||||
else:
|
||||
value = "%s.%d.%s." % (date_val[0], date_val[1], year)
|
||||
elif self.format == 3:
|
||||
# day. month_name year.
|
||||
if date_val[0] == 0:
|
||||
if date_val[1] == 0:
|
||||
value = "%s." % year
|
||||
else:
|
||||
value = "%s %s." % (self.long_months[date_val[1]], year)
|
||||
else:
|
||||
value = "%d. %s %s." % (date_val[0],
|
||||
self.long_months[date_val[1]], year)
|
||||
else:
|
||||
# day. Roman_number_month year.
|
||||
if date_val[0] == 0:
|
||||
if date_val[1] == 0:
|
||||
value = "%s." % year
|
||||
else:
|
||||
value = "%s %s." % (self.roman_months[date_val[1]], year)
|
||||
else:
|
||||
value = "%d. %s %s." % (date_val[0],
|
||||
self.roman_months[date_val[1]], year)
|
||||
if date_val[2] < 0:
|
||||
return self._bce_str % value
|
||||
else:
|
||||
return value
|
||||
|
||||
def display(self, date):
|
||||
"""
|
||||
Return a text string representing the date.
|
||||
"""
|
||||
mod = date.get_modifier()
|
||||
cal = date.get_calendar()
|
||||
qual = date.get_quality()
|
||||
start = date.get_start_date()
|
||||
newyear = date.get_new_year()
|
||||
|
||||
qual_str = self._qual_str[qual]
|
||||
|
||||
if mod == Date.MOD_TEXTONLY:
|
||||
return date.get_text()
|
||||
elif start == Date.EMPTY:
|
||||
return ""
|
||||
elif mod == Date.MOD_SPAN:
|
||||
d_1 = self.display_cal[cal](start)
|
||||
d_2 = self.display_cal[cal](date.get_stop_date())
|
||||
scal = self.format_extras(cal, newyear)
|
||||
return "%s%s %s %s %s%s" % (qual_str, 'od', d_1, 'do', d_2,
|
||||
scal)
|
||||
elif mod == Date.MOD_RANGE:
|
||||
d_1 = self.display_cal[cal](start)
|
||||
d_2 = self.display_cal[cal](date.get_stop_date())
|
||||
scal = self.format_extras(cal, newyear)
|
||||
return "%s%s %s %s %s%s" % (qual_str, 'između', d_1, 'i', d_2,
|
||||
scal)
|
||||
else:
|
||||
text = self.display_cal[date.get_calendar()](start)
|
||||
scal = self.format_extras(cal, newyear)
|
||||
return "%s%s%s%s" % (qual_str, self._mod_str[mod], text,
|
||||
scal)
|
||||
display = DateDisplay.display_formatted
|
||||
|
||||
#-------------------------------------------------------------------------
|
||||
#
|
||||
|
@ -48,7 +48,6 @@ from ._datehandler import register_datehandler
|
||||
#
|
||||
#-------------------------------------------------------------------------
|
||||
class DateParserRU(DateParser):
|
||||
|
||||
modifier_to_int = {
|
||||
'перед' : Date.MOD_BEFORE,
|
||||
'по' : Date.MOD_BEFORE,
|
||||
@ -70,22 +69,6 @@ class DateParserRU(DateParser):
|
||||
'прибл' : Date.MOD_ABOUT,
|
||||
}
|
||||
|
||||
calendar_to_int = {
|
||||
'григорианский' : Date.CAL_GREGORIAN,
|
||||
'г' : Date.CAL_GREGORIAN,
|
||||
'юлианский' : Date.CAL_JULIAN,
|
||||
'ю' : Date.CAL_JULIAN,
|
||||
'еврейский' : Date.CAL_HEBREW,
|
||||
'е' : Date.CAL_HEBREW,
|
||||
'исламский' : Date.CAL_ISLAMIC,
|
||||
'и' : Date.CAL_ISLAMIC,
|
||||
'республиканский': Date.CAL_FRENCH,
|
||||
'р' : Date.CAL_FRENCH,
|
||||
'персидский' : Date.CAL_PERSIAN,
|
||||
'п' : Date.CAL_PERSIAN,
|
||||
'swedish' : Date.CAL_SWEDISH,
|
||||
's' : Date.CAL_SWEDISH,
|
||||
}
|
||||
|
||||
quality_to_int = {
|
||||
'оценено' : Date.QUAL_ESTIMATED,
|
||||
@ -100,127 +83,19 @@ class DateParserRU(DateParser):
|
||||
'выч' : Date.QUAL_CALCULATED,
|
||||
}
|
||||
|
||||
hebrew_to_int = {
|
||||
"тишрей":1,
|
||||
"тишрея":1,
|
||||
"хешван":2,
|
||||
"хешвана":2,
|
||||
"кислев":3,
|
||||
"кислева":3,
|
||||
"тевет":4,
|
||||
"тевета":4,
|
||||
"шеват":5,
|
||||
"шевата":5,
|
||||
"адар":6,
|
||||
"адара":6,
|
||||
"адара бет":7,
|
||||
"нисан":8,
|
||||
"нисана":8,
|
||||
"ниссан":8,
|
||||
"ниссана":8,
|
||||
"ияр":9,
|
||||
"ияра":9,
|
||||
"сиван":10,
|
||||
"сивана":10,
|
||||
"тамуз":11,
|
||||
"тамуза":11,
|
||||
"таммуз":11,
|
||||
"таммуза":11,
|
||||
"ав":12,
|
||||
"ава":12,
|
||||
"элул":13,
|
||||
"элула":13,
|
||||
"элуль":13,
|
||||
"элуля":13,
|
||||
}
|
||||
|
||||
islamic_to_int = {
|
||||
"мухаррам":1,
|
||||
"мухаррама":1,
|
||||
"сафар":2,
|
||||
"сафара":2,
|
||||
"раби-аль-авваль":3,
|
||||
"раби-аль-авваля":3,
|
||||
"раби-ассани":4,
|
||||
"джумада-аль-уля":5,
|
||||
"джумада-аль-ахира":6,
|
||||
"раджаб":7,
|
||||
"раджаба":7,
|
||||
"шаабан":8,
|
||||
"шаабана":8,
|
||||
"рамадан":9,
|
||||
"рамадана":9,
|
||||
"шавваль":10,
|
||||
"шавваля":10,
|
||||
"зуль-каада":11,
|
||||
"зуль-хиджжа":12,
|
||||
}
|
||||
|
||||
persian_to_int = {
|
||||
"фарвардин":1,
|
||||
"фарвардина":1,
|
||||
"урдбихишт":2,
|
||||
"урдбихишта":2,
|
||||
"хурдад":3,
|
||||
"хурдада":3,
|
||||
"тир":4,
|
||||
"тира":4,
|
||||
"мурдад":5,
|
||||
"мурдада":5,
|
||||
"шахривар":6,
|
||||
"шахривара":6,
|
||||
"михр":7,
|
||||
"михра":7,
|
||||
"абан":8,
|
||||
"абана":8,
|
||||
"азар":9,
|
||||
"азара":9,
|
||||
"дай":10,
|
||||
"дая":10,
|
||||
"бахман":11,
|
||||
"бахмана":11,
|
||||
"исфаидармуз":12,
|
||||
"исфаидармуза":12,
|
||||
}
|
||||
|
||||
french_to_int = {
|
||||
"вандемьер":1,
|
||||
"вандемьера":1,
|
||||
"брюмер":2,
|
||||
"брюмера":2,
|
||||
"фример":3,
|
||||
"фримера":3,
|
||||
"нивоз":4,
|
||||
"нивоза":4,
|
||||
"плювиоз":5,
|
||||
"плювиоза":5,
|
||||
"вантоз":6,
|
||||
"вантоза":6,
|
||||
"жерминаль":7,
|
||||
"жерминаля":7,
|
||||
"флореаль":8,
|
||||
"флореаля":8,
|
||||
"прериаль":9,
|
||||
"прериаля":9,
|
||||
"мессидор":10,
|
||||
"мессидора":10,
|
||||
"термидор":11,
|
||||
"термидора":11,
|
||||
"фрюктидор":12,
|
||||
"фрюктидора":12,
|
||||
"доп.":13,
|
||||
"дополн.":13,
|
||||
"дополнит.":13,
|
||||
}
|
||||
|
||||
bce = [
|
||||
'до нашей эры', 'до н. э.', 'до н.э.',
|
||||
'до н э', 'до нэ'] + DateParser.bce
|
||||
|
||||
def init_strings(self):
|
||||
DateParser.init_strings(self)
|
||||
DateParser.calendar_to_int.update({
|
||||
'персидский' : Date.CAL_PERSIAN,
|
||||
'п' : Date.CAL_PERSIAN,
|
||||
})
|
||||
_span_1 = ['с', 'от']
|
||||
_span_2 = ['по', 'до']
|
||||
#_span_2 = ['по', 'до'] # <-- clashes with bce parsing :-(
|
||||
_span_2 = ['по']
|
||||
_range_1 = ['между', 'меж\.', 'меж']
|
||||
_range_2 = ['и']
|
||||
self._span = re.compile("(%s)\s+(?P<start>.+)\s+(%s)\s+(?P<stop>.+)" %
|
||||
@ -239,136 +114,12 @@ class DateDisplayRU(DateDisplay):
|
||||
"""
|
||||
Russian language date display class.
|
||||
"""
|
||||
long_months = ( "", "января", "февраля", "марта", "апреля", "мая",
|
||||
"июня", "июля", "августа", "сентября", "октября",
|
||||
"ноября", "декабря" )
|
||||
|
||||
short_months = ( "", "янв", "фев", "мар", "апр", "мая", "июн",
|
||||
"июл", "авг", "сен", "окт", "ноя", "дек" )
|
||||
|
||||
calendar = (
|
||||
"",
|
||||
"юлианский",
|
||||
"еврейский",
|
||||
"республиканский",
|
||||
"персидский",
|
||||
"исламский",
|
||||
"шведский"
|
||||
)
|
||||
|
||||
_mod_str = (
|
||||
"",
|
||||
"перед ",
|
||||
"после ",
|
||||
"около ",
|
||||
"", "", "")
|
||||
|
||||
_qual_str = ("", "оцен ", "вычисл ")
|
||||
|
||||
# TODO fix BUG 7064: non-Gregorian calendars wrongly use BCE notation for negative dates
|
||||
# not refactoring _bce_str into base class because it'll be gone under #7064
|
||||
_bce_str = "%s до н.э."
|
||||
|
||||
formats = (
|
||||
"ГГГГ-ММ-ДД (ISO)", "Численный", "Месяц День, Год",
|
||||
"МЕС ДД, ГГГГ", "День Месяц, Год", "ДД МЕС, ГГГГ"
|
||||
)
|
||||
# this must agree with DateDisplayEn's "formats" definition
|
||||
# (since no locale-specific _display_gregorian exists, here)
|
||||
|
||||
hebrew = ( "",
|
||||
"тишрея",
|
||||
"хешвана",
|
||||
"кислева",
|
||||
"тевета",
|
||||
"шевата",
|
||||
"адара",
|
||||
"адара бет",
|
||||
"нисана",
|
||||
"ияра",
|
||||
"сивана",
|
||||
"таммуза",
|
||||
"ава",
|
||||
"элула",
|
||||
)
|
||||
|
||||
islamic = ( "",
|
||||
"мухаррама",
|
||||
"сафара",
|
||||
"раби-аль-авваля",
|
||||
"раби-ассани",
|
||||
"джумада-аль-уля",
|
||||
"джумада-аль-ахира",
|
||||
"раджаба",
|
||||
"шаабана",
|
||||
"рамадана",
|
||||
"шавваля",
|
||||
"зуль-каада",
|
||||
"зуль-хиджжа",
|
||||
)
|
||||
|
||||
persian = ( "",
|
||||
"фарвардина",
|
||||
"урдбихишта",
|
||||
"хурдада",
|
||||
"тира",
|
||||
"мурдада",
|
||||
"шахривара",
|
||||
"михра",
|
||||
"абана",
|
||||
"азара",
|
||||
"дая",
|
||||
"бахмана",
|
||||
"исфаидармуза",
|
||||
)
|
||||
|
||||
french = ( "",
|
||||
"вандемьера",
|
||||
"брюмера",
|
||||
"фримера",
|
||||
"нивоза",
|
||||
"плювиоза",
|
||||
"вантоза",
|
||||
"жерминаля",
|
||||
"флореаля",
|
||||
"прериаля",
|
||||
"мессидора",
|
||||
"термидора",
|
||||
"фрюктидора",
|
||||
"дополнит."
|
||||
)
|
||||
|
||||
def display(self, date):
|
||||
"""
|
||||
Return a text string representing the date.
|
||||
"""
|
||||
mod = date.get_modifier()
|
||||
cal = date.get_calendar()
|
||||
qual = date.get_quality()
|
||||
start = date.get_start_date()
|
||||
newyear = date.get_new_year()
|
||||
|
||||
qual_str = self._qual_str[qual]
|
||||
|
||||
if mod == Date.MOD_TEXTONLY:
|
||||
return date.get_text()
|
||||
elif start == Date.EMPTY:
|
||||
return ""
|
||||
elif mod == Date.MOD_SPAN:
|
||||
d1 = self.display_cal[cal](start)
|
||||
d2 = self.display_cal[cal](date.get_stop_date())
|
||||
scal = self.format_extras(cal, newyear)
|
||||
return "%sс %s %s %s%s" % (qual_str, d1, 'по', d2,
|
||||
scal)
|
||||
elif mod == Date.MOD_RANGE:
|
||||
d1 = self.display_cal[cal](start)
|
||||
d2 = self.display_cal[cal](date.get_stop_date())
|
||||
scal = self.format_extras(cal, newyear)
|
||||
return "%s%s %s %s %s%s" % (qual_str, 'между', d1, 'и',
|
||||
d2, scal)
|
||||
else:
|
||||
text = self.display_cal[date.get_calendar()](start)
|
||||
scal = self.format_extras(cal, newyear)
|
||||
return "%s%s%s%s" % (qual_str, self._mod_str[mod],
|
||||
text, scal)
|
||||
display = DateDisplay.display_formatted
|
||||
|
||||
#-------------------------------------------------------------------------
|
||||
#
|
||||
|
@ -41,6 +41,8 @@ log = logging.getLogger(".DateDisplay")
|
||||
#-------------------------------------------------------------------------
|
||||
from ..lib.date import Date
|
||||
from . import _grampslocale
|
||||
from ..utils.grampslocale import GrampsLocale
|
||||
from ._datestrings import DateStrings
|
||||
|
||||
#-------------------------------------------------------------------------
|
||||
#
|
||||
@ -51,78 +53,63 @@ class DateDisplay(object):
|
||||
"""
|
||||
Base date display class.
|
||||
"""
|
||||
long_months = ( "", "January", "February", "March", "April", "May",
|
||||
"June", "July", "August", "September", "October",
|
||||
"November", "December" )
|
||||
|
||||
short_months = ( "", "Jan", "Feb", "Mar", "Apr", "May", "Jun",
|
||||
"Jul", "Aug", "Sep", "Oct", "Nov", "Dec" )
|
||||
_locale = GrampsLocale(lang='en_US', languages='en')
|
||||
|
||||
_tformat = _grampslocale.tformat
|
||||
|
||||
hebrew = (
|
||||
"", "Tishri", "Heshvan", "Kislev", "Tevet", "Shevat",
|
||||
"AdarI", "AdarII", "Nisan", "Iyyar", "Sivan", "Tammuz",
|
||||
"Av", "Elul"
|
||||
)
|
||||
_ = _grampslocale.glocale.translation.sgettext
|
||||
formats = (
|
||||
# format 0 - must always be ISO
|
||||
_("YYYY-MM-DD (ISO)"),
|
||||
|
||||
french = (
|
||||
'',
|
||||
"Vendémiaire",
|
||||
'Brumaire',
|
||||
'Frimaire',
|
||||
"Nivôse",
|
||||
"Pluviôse",
|
||||
"Ventôse",
|
||||
'Germinal',
|
||||
"Floréal",
|
||||
'Prairial',
|
||||
'Messidor',
|
||||
'Thermidor',
|
||||
'Fructidor',
|
||||
'Extra',
|
||||
)
|
||||
# format # 1 - must always be locale-preferred numerical format
|
||||
# such as YY.MM.DD, MM-DD-YY, or whatever your locale prefers.
|
||||
# This should be the format that is used under the locale by
|
||||
# strftime() for '%x'.
|
||||
# You may translate this string as "Numerical", "System preferred", or similar.
|
||||
_("date format|Numerical"),
|
||||
|
||||
persian = (
|
||||
"", "Farvardin", "Ordibehesht", "Khordad", "Tir",
|
||||
"Mordad", "Shahrivar", "Mehr", "Aban", "Azar",
|
||||
"Dey", "Bahman", "Esfand"
|
||||
)
|
||||
# Full month name, day, year
|
||||
_("Month Day, Year"),
|
||||
|
||||
islamic = (
|
||||
"", "Muharram", "Safar", "Rabi`al-Awwal", "Rabi`ath-Thani",
|
||||
"Jumada l-Ula", "Jumada t-Tania", "Rajab", "Sha`ban",
|
||||
"Ramadan", "Shawwal", "Dhu l-Qa`da", "Dhu l-Hijja"
|
||||
)
|
||||
# Abbreviated month name, day, year
|
||||
_("MON DAY, YEAR"),
|
||||
|
||||
swedish = (
|
||||
"", "Januari", "Februari", "Mars",
|
||||
"April", "Maj", "Juni",
|
||||
"Juli", "Augusti", "September",
|
||||
"Oktober", "November", "December"
|
||||
)
|
||||
# Day, full month name, year
|
||||
_("Day Month Year"),
|
||||
|
||||
formats = ("YYYY-MM-DD (ISO)", )
|
||||
# this will be overridden if a locale-specific date displayer exists
|
||||
|
||||
calendar = (
|
||||
"", "Julian", "Hebrew", "French Republican",
|
||||
"Persian", "Islamic", "Swedish"
|
||||
# Day, abbreviated month name, year
|
||||
_("DAY MON YEAR")
|
||||
)
|
||||
# this will be overridden if a locale-specific date displayer exists
|
||||
"""
|
||||
:Note:
|
||||
Will be overridden if a locale-specific date displayer exists.
|
||||
|
||||
If your localized ``_display_gregorian`` / ``_display_calendar`` are overridden,
|
||||
you should override the whole formats list according to your own formats,
|
||||
and you need not localize the format names here.
|
||||
this ``formats`` must agree with
|
||||
:meth:`~_display_calendar`/:meth:`~_display_gregorian`
|
||||
"""
|
||||
del _
|
||||
|
||||
newyear = ("", "Mar1", "Mar25", "Sep1")
|
||||
|
||||
_mod_str = ("", "before ", "after ", "about ", "", "", "")
|
||||
# this will be overridden if a locale-specific date displayer exists
|
||||
|
||||
_qual_str = ("", "estimated ", "calculated ")
|
||||
# this will be overridden if a locale-specific date displayer exists
|
||||
|
||||
_bce_str = "%s B.C.E."
|
||||
# this will be overridden if a locale-specific date displayer exists
|
||||
|
||||
def __init__(self, format=None):
|
||||
self._ds = DateStrings(self._locale)
|
||||
calendar = list(self._ds.calendar)
|
||||
calendar[Date.CAL_GREGORIAN] = "" # that string only used in parsing,
|
||||
# gregorian cal name shouldn't be output!
|
||||
self.calendar = tuple(calendar)
|
||||
self.short_months = self._ds.short_months
|
||||
self.swedish = self.long_months = self._ds.long_months
|
||||
self.hebrew = self._ds.hebrew
|
||||
self.french = self._ds.french
|
||||
self.persian = self._ds.persian
|
||||
self.islamic = self._ds.islamic
|
||||
self.display_cal = [
|
||||
self._display_gregorian,
|
||||
self._display_julian,
|
||||
@ -131,12 +118,119 @@ class DateDisplay(object):
|
||||
self._display_persian,
|
||||
self._display_islamic,
|
||||
self._display_swedish]
|
||||
self._mod_str = self._ds.modifiers
|
||||
self._qual_str = self._ds.qualifiers
|
||||
|
||||
if format is None:
|
||||
self.format = 0
|
||||
else:
|
||||
self.format = format
|
||||
|
||||
self._ = _ = self._locale.translation.sgettext
|
||||
self.FORMATS_long_month_year = {
|
||||
# Inflection control due to modifier.
|
||||
# Protocol: DateDisplayXX passes a key to the dictionary in the
|
||||
# parameter ``inflect`` to ``_display_calendar``.
|
||||
# The modifier passed is not necessarily the one printed, it's just
|
||||
# a representative that induces the same inflection control.
|
||||
# For example, in Russian "before May", "after May", and "about May"
|
||||
# all require genitive form for May, whereas no modifier (just "May 1234")
|
||||
# require nominative, so DateDisplayRU.display will pass "before"
|
||||
# in all 3 cases, collapsing the 3 modifiers into 1.
|
||||
#
|
||||
# Another example in Russian is that "between April 1234 and June 1235"
|
||||
# requires the same inflection for both April and June, so just "between"
|
||||
# is used by DateDisplayRU.display, collapsing two more modifiers into 1.
|
||||
#
|
||||
# If inflect is not specified, then it means that the modifier doesn't have
|
||||
# grammatical control over the format, and so the format can be
|
||||
# localized in a context-free way.
|
||||
# The translator is responsible for:
|
||||
# 1) proper collapse of modifier classes
|
||||
# 2) translating the formats that are selected in runtime
|
||||
# 3) ignoring the other formats in .po (it does no harm to translate them,
|
||||
# it's just a lot of extra work)
|
||||
#
|
||||
# To prevent POT pollution, not all possibilities are populated here yet.
|
||||
# To be amended as the actual localized handlers use it.
|
||||
#
|
||||
# Not moving to DateStrings, as this is part of display code only,
|
||||
# coupled tightly with the formats used in this file.
|
||||
""
|
||||
: _("{long_month} {year}"),
|
||||
|
||||
"from"
|
||||
# first date in a span
|
||||
# You only need to translate this string if you translate one of the
|
||||
# inflect=_("...") with "from"
|
||||
: _("from|{long_month} {year}"),
|
||||
|
||||
"to"
|
||||
# second date in a span
|
||||
# You only need to translate this string if you translate one of the
|
||||
# inflect=_("...") with "to"
|
||||
: _("to|{long_month} {year}"),
|
||||
|
||||
"between"
|
||||
# first date in a range
|
||||
# You only need to translate this string if you translate one of the
|
||||
# inflect=_("...") with "between"
|
||||
: _("between|{long_month} {year}"),
|
||||
|
||||
"and"
|
||||
# second date in a range
|
||||
# You only need to translate this string if you translate one of the
|
||||
# inflect=_("...") with "and"
|
||||
: _("and|{long_month} {year}"),
|
||||
|
||||
"before"
|
||||
# You only need to translate this string if you translate one of the
|
||||
# inflect=_("...") with "before"
|
||||
: _("before|{long_month} {year}"),
|
||||
|
||||
"after"
|
||||
# You only need to translate this string if you translate one of the
|
||||
# inflect=_("...") with "after"
|
||||
: _("after|{long_month} {year}"),
|
||||
|
||||
"about"
|
||||
# You only need to translate this string if you translate one of the
|
||||
# inflect=_("...") with "about"
|
||||
: _("about|{long_month} {year}"),
|
||||
|
||||
# TODO if no modifier, but with qual, might need to inflect in some lang.
|
||||
}
|
||||
|
||||
self.FORMATS_short_month_year = {
|
||||
""
|
||||
: _("{short_month} {year}"),
|
||||
|
||||
"from"
|
||||
# first date in a span
|
||||
: _("from|{short_month} {year}"),
|
||||
|
||||
"to"
|
||||
# second date in a span
|
||||
: _("to|{short_month} {year}"),
|
||||
|
||||
"between"
|
||||
# first date in a range
|
||||
: _("between|{short_month} {year}"),
|
||||
|
||||
"and"
|
||||
# second date in a range
|
||||
: _("and|{short_month} {year}"),
|
||||
|
||||
"before"
|
||||
: _("before|{short_month} {year}"),
|
||||
|
||||
"after"
|
||||
: _("after|{short_month} {year}"),
|
||||
|
||||
"about"
|
||||
: _("about|{short_month} {year}"),
|
||||
}
|
||||
|
||||
def set_format(self, format):
|
||||
self.format = format
|
||||
|
||||
@ -164,7 +258,9 @@ class DateDisplay(object):
|
||||
def display(self, date):
|
||||
"""
|
||||
Return a text string representing the date.
|
||||
(will be overridden if a locale-specific date displayer exists)
|
||||
|
||||
(Will be overridden if a locale-specific date displayer exists.)
|
||||
Disregard any format settings and use display_iso for each date.
|
||||
"""
|
||||
mod = date.get_modifier()
|
||||
cal = date.get_calendar()
|
||||
@ -218,10 +314,115 @@ class DateDisplay(object):
|
||||
else:
|
||||
return value
|
||||
|
||||
def _display_gregorian(self, date_val):
|
||||
def display_formatted(self, date):
|
||||
"""
|
||||
Return a text string representing the date, according to the format.
|
||||
"""
|
||||
mod = date.get_modifier()
|
||||
cal = date.get_calendar()
|
||||
qual = date.get_quality()
|
||||
start = date.get_start_date()
|
||||
newyear = date.get_new_year()
|
||||
|
||||
qual_str = self._qual_str[qual]
|
||||
_ = self._
|
||||
|
||||
if mod == Date.MOD_TEXTONLY:
|
||||
return date.get_text()
|
||||
elif start == Date.EMPTY:
|
||||
return ""
|
||||
elif mod == Date.MOD_SPAN:
|
||||
d1 = self.display_cal[cal](start,
|
||||
# If there is no special inflection for "from <Month>" in your
|
||||
# language, don't translate this string.
|
||||
# Otherwise, translate it to the ENGLISH!!! ENGLISH!!!
|
||||
# key appearing above in the FORMATS_... dict
|
||||
# that maps to the special inflected format string that you need to localize.
|
||||
inflect=_("from-date|"))
|
||||
d2 = self.display_cal[cal](date.get_stop_date(),
|
||||
# If there is no special inflection for "to <Month>" in your
|
||||
# language, don't translate this string.
|
||||
# Otherwise, translate it to the ENGLISH!!! ENGLISH!!!
|
||||
# key appearing above in the FORMATS_... dict
|
||||
# that maps to the special inflected format string that you need to localize.
|
||||
inflect=_("to-date|"))
|
||||
scal = self.format_extras(cal, newyear)
|
||||
return _("{date_quality}from {date_start} to {date_stop}"
|
||||
"{nonstd_calendar_and_ny}").format(
|
||||
date_quality=qual_str,
|
||||
date_start=d1,
|
||||
date_stop=d2,
|
||||
nonstd_calendar_and_ny=scal)
|
||||
elif mod == Date.MOD_RANGE:
|
||||
d1 = self.display_cal[cal](start,
|
||||
# If there is no special inflection for "between <Month>" in your
|
||||
# language, don't translate this string.
|
||||
# Otherwise, translate it to the ENGLISH!!! ENGLISH!!!
|
||||
# key appearing above in the FORMATS_... dict
|
||||
# that maps to the special inflected format string that you need to localize.
|
||||
inflect=_("between-date|"))
|
||||
d2 = self.display_cal[cal](date.get_stop_date(),
|
||||
# If there is no special inflection for "and <Month>" in your
|
||||
# language, don't translate this string.
|
||||
# Otherwise, translate it to the ENGLISH!!! ENGLISH!!!
|
||||
# key appearing above in the FORMATS_... dict
|
||||
# that maps to the special inflected format string that you need to localize.
|
||||
inflect=_("and-date|"))
|
||||
scal = self.format_extras(cal, newyear)
|
||||
return _("{date_quality}between {date_start} and {date_stop}"
|
||||
"{nonstd_calendar_and_ny}").format(
|
||||
date_quality=qual_str,
|
||||
date_start=d1,
|
||||
date_stop=d2,
|
||||
nonstd_calendar_and_ny=scal)
|
||||
else:
|
||||
text = self.display_cal[date.get_calendar()](start,
|
||||
# If there is no special inflection for "before/after/around <Month>" in your
|
||||
# language, don't translate this string.
|
||||
# Otherwise, translate it to the ENGLISH!!! ENGLISH!!!
|
||||
# key appearing above in the FORMATS_... dict
|
||||
# that maps to the special inflected format string that you need to localize.
|
||||
# TODO are there languages for which the inflections for the different
|
||||
# modifiers are different?!
|
||||
inflect=_("before-date|") if mod != Date.MOD_NONE else "")
|
||||
scal = self.format_extras(cal, newyear)
|
||||
return _("{date_quality}{noncompound_modifier}{date}"
|
||||
"{nonstd_calendar_and_ny}").format(
|
||||
date_quality=qual_str,
|
||||
noncompound_modifier=self._mod_str[mod],
|
||||
date=text,
|
||||
nonstd_calendar_and_ny=scal)
|
||||
|
||||
def _display_gregorian(self, date_val, **kwargs):
|
||||
return self._display_calendar(date_val, self.long_months,
|
||||
self.short_months, **kwargs)
|
||||
|
||||
# Julian and Swedish date display is the same as Gregorian
|
||||
_display_julian = _display_swedish = _display_gregorian
|
||||
|
||||
def _display_calendar(self, date_val, long_months, short_months = None,
|
||||
inflect=""):
|
||||
|
||||
if short_months is None:
|
||||
# Let the short formats work the same as long formats
|
||||
short_months = long_months
|
||||
|
||||
_ = self._locale.translation.sgettext
|
||||
# this one must agree with DateDisplayEn's "formats" definition
|
||||
# (it may be overridden if a locale-specific date displayer exists)
|
||||
year = self._slash_year(date_val[2], date_val[3])
|
||||
|
||||
# For partial dates, several formats reduce to just month + year.
|
||||
def format_long_month_year():
|
||||
return self.FORMATS_long_month_year[inflect].format(
|
||||
long_month = long_months[date_val[1]],
|
||||
year = year)
|
||||
|
||||
def format_short_month_year():
|
||||
return self.FORMATS_short_month_year[inflect].format(
|
||||
short_month = short_months[date_val[1]],
|
||||
year = year)
|
||||
|
||||
if self.format == 0:
|
||||
return self.display_iso(date_val)
|
||||
elif self.format == 1:
|
||||
@ -242,30 +443,45 @@ class DateDisplay(object):
|
||||
if date_val[1] == 0:
|
||||
value = year
|
||||
else:
|
||||
value = "%s %s" % (self.long_months[date_val[1]], year)
|
||||
value = format_long_month_year()
|
||||
else:
|
||||
value = "%s %d, %s" % (self.long_months[date_val[1]],
|
||||
date_val[0], year)
|
||||
# TRANSLATORS: see
|
||||
# http://gramps-project.org/wiki/index.php?title=Translating_Gramps#Translating_dates
|
||||
# to learn how to select proper inflection for your language.
|
||||
value = _("{long_month} {day:d}, {year}").format(
|
||||
long_month = long_months[date_val[1]],
|
||||
day = date_val[0],
|
||||
year = year)
|
||||
elif self.format == 3:
|
||||
# month_abbreviation day, year
|
||||
if date_val[0] == 0:
|
||||
if date_val[1] == 0:
|
||||
value = year
|
||||
else:
|
||||
value = "%s %s" % (self.short_months[date_val[1]], year)
|
||||
value = format_short_month_year()
|
||||
else:
|
||||
value = "%s %d, %s" % (self.short_months[date_val[1]],
|
||||
date_val[0], year)
|
||||
# TRANSLATORS: see
|
||||
# http://gramps-project.org/wiki/index.php?title=Translating_Gramps#Translating_dates
|
||||
# to learn how to select proper inflection for your language.
|
||||
value = _("{short_month} {day:d}, {year}").format(
|
||||
short_month = short_months[date_val[1]],
|
||||
day = date_val[0],
|
||||
year = year)
|
||||
elif self.format == 4:
|
||||
# day month_name year
|
||||
if date_val[0] == 0:
|
||||
if date_val[1] == 0:
|
||||
value = year
|
||||
else:
|
||||
value = "%s %s" % (self.long_months[date_val[1]], year)
|
||||
value = format_long_month_year()
|
||||
else:
|
||||
value = "%d %s %s" % (date_val[0],
|
||||
self.long_months[date_val[1]], year)
|
||||
# TRANSLATORS: see
|
||||
# http://gramps-project.org/wiki/index.php?title=Translating_Gramps#Translating_dates
|
||||
# to learn how to select proper inflection for your language.
|
||||
value = _("{day:d} {long_month} {year}").format(
|
||||
day = date_val[0],
|
||||
long_month = long_months[date_val[1]],
|
||||
year = year)
|
||||
# elif self.format == 5:
|
||||
else:
|
||||
# day month_abbreviation year
|
||||
@ -273,78 +489,39 @@ class DateDisplay(object):
|
||||
if date_val[1] == 0:
|
||||
value = year
|
||||
else:
|
||||
value = "%s %s" % (self.short_months[date_val[1]], year)
|
||||
value = format_short_month_year()
|
||||
else:
|
||||
value = "%d %s %s" % (date_val[0],
|
||||
self.short_months[date_val[1]], year)
|
||||
# TRANSLATORS: see
|
||||
# http://gramps-project.org/wiki/index.php?title=Translating_Gramps#Translating_dates
|
||||
# to learn how to select proper inflection for your language.
|
||||
value = _("{day:d} {short_month} {year}").format(
|
||||
short_month = short_months[date_val[1]],
|
||||
day = date_val[0],
|
||||
year = year)
|
||||
if date_val[2] < 0:
|
||||
# TODO fix BUG 7064: non-Gregorian calendars wrongly use BCE notation for negative dates
|
||||
return self._bce_str % value
|
||||
else:
|
||||
return value
|
||||
|
||||
def _display_julian(self, date_val):
|
||||
# Julian date display is the same as Gregorian
|
||||
return self._display_gregorian(date_val)
|
||||
|
||||
def _display_calendar(self, date_val, month_list):
|
||||
# used to display non-Gregorian calendars (Hebrew, Islamic, etc.)
|
||||
year = abs(date_val[2])
|
||||
if self.format == 0 or self.format == 1:
|
||||
return self.display_iso(date_val)
|
||||
else:
|
||||
if date_val[0] == 0:
|
||||
if date_val[1] == 0:
|
||||
value = year
|
||||
else:
|
||||
value = "%s %d" % (month_list[date_val[1]], year)
|
||||
else:
|
||||
value = "%s %d, %s" % (month_list[date_val[1]], date_val[0],
|
||||
year)
|
||||
if date_val[2] < 0:
|
||||
return self._bce_str % value
|
||||
else:
|
||||
return value
|
||||
def _display_french(self, date_val, **kwargs):
|
||||
return self._display_calendar(date_val, self.french, **kwargs)
|
||||
|
||||
def _display_french(self, date_val):
|
||||
year = abs(date_val[2])
|
||||
if self.format == 0 or self.format == 1:
|
||||
return self.display_iso(date_val)
|
||||
else:
|
||||
if date_val[0] == 0:
|
||||
if date_val[1] == 0:
|
||||
value = year
|
||||
else:
|
||||
value = "%s %d" % (self.french[date_val[1]], year)
|
||||
else:
|
||||
value = "%d %s %s" % (date_val[0], self.french[date_val[1]],
|
||||
year)
|
||||
if date_val[2] < 0:
|
||||
return self._bce_str % value
|
||||
else:
|
||||
return value
|
||||
def _display_hebrew(self, date_val, **kwargs):
|
||||
return self._display_calendar(date_val, self.hebrew, **kwargs)
|
||||
|
||||
def _display_hebrew(self, date_val):
|
||||
return self._display_calendar(date_val, self.hebrew)
|
||||
def _display_persian(self, date_val, **kwargs):
|
||||
return self._display_calendar(date_val, self.persian, **kwargs)
|
||||
|
||||
def _display_persian(self, date_val):
|
||||
return self._display_calendar(date_val, self.persian)
|
||||
|
||||
def _display_islamic(self, date_val):
|
||||
return self._display_calendar(date_val, self.islamic)
|
||||
|
||||
def _display_swedish(self, date_val):
|
||||
return self._display_calendar(date_val, self.swedish)
|
||||
def _display_islamic(self, date_val, **kwargs):
|
||||
return self._display_calendar(date_val, self.islamic, **kwargs)
|
||||
|
||||
class DateDisplayEn(DateDisplay):
|
||||
"""
|
||||
English language date display class.
|
||||
"""
|
||||
|
||||
formats = (
|
||||
"YYYY-MM-DD (ISO)", "Numerical", "Month Day, Year",
|
||||
"MON DAY, YEAR", "Day Month Year", "DAY MON YEAR"
|
||||
)
|
||||
# this (English) "formats" must agree with "_display_gregorian" (above)
|
||||
|
||||
def __init__(self, format=None):
|
||||
"""
|
||||
@ -355,33 +532,5 @@ class DateDisplayEn(DateDisplay):
|
||||
|
||||
DateDisplay.__init__(self, format)
|
||||
|
||||
def display(self, date):
|
||||
"""
|
||||
Return a text string representing the date.
|
||||
"""
|
||||
mod = date.get_modifier()
|
||||
cal = date.get_calendar()
|
||||
qual = date.get_quality()
|
||||
start = date.get_start_date()
|
||||
newyear = date.get_new_year()
|
||||
display = DateDisplay.display_formatted
|
||||
|
||||
qual_str = self._qual_str[qual]
|
||||
|
||||
if mod == Date.MOD_TEXTONLY:
|
||||
return date.get_text()
|
||||
elif start == Date.EMPTY:
|
||||
return ""
|
||||
elif mod == Date.MOD_SPAN:
|
||||
d1 = self.display_cal[cal](start)
|
||||
d2 = self.display_cal[cal](date.get_stop_date())
|
||||
scal = self.format_extras(cal, newyear)
|
||||
return "%sfrom %s to %s%s" % (qual_str, d1, d2, scal)
|
||||
elif mod == Date.MOD_RANGE:
|
||||
d1 = self.display_cal[cal](start)
|
||||
d2 = self.display_cal[cal](date.get_stop_date())
|
||||
scal = self.format_extras(cal, newyear)
|
||||
return "%sbetween %s and %s%s" % (qual_str, d1, d2, scal)
|
||||
else:
|
||||
text = self.display_cal[date.get_calendar()](start)
|
||||
scal = self.format_extras(cal, newyear)
|
||||
return "%s%s%s%s" % (qual_str, self._mod_str[mod], text, scal)
|
||||
|
@ -49,6 +49,7 @@ from ._dateparser import DateParser
|
||||
from ._datedisplay import DateDisplay, DateDisplayEn
|
||||
from ..constfunc import win, cuni
|
||||
from ..const import GRAMPS_LOCALE as glocale
|
||||
from gramps.gen.utils.grampslocale import GrampsLocale
|
||||
|
||||
#-------------------------------------------------------------------------
|
||||
#
|
||||
@ -99,6 +100,9 @@ def register_datehandler(locales,parse_class,display_class):
|
||||
Registers the passed date parser class and date displayer
|
||||
classes with the specified language locales.
|
||||
|
||||
Set the parser_class and display_class ._locale attribute
|
||||
to the corresponding GrampsLocale object.
|
||||
|
||||
@param locales: tuple of strings containing language codes.
|
||||
The character encoding is not included, so the language
|
||||
should be in the form of fr_FR, not fr_FR.utf8
|
||||
@ -111,3 +115,5 @@ def register_datehandler(locales,parse_class,display_class):
|
||||
for lang_str in locales:
|
||||
LANG_TO_PARSER[lang_str] = parse_class
|
||||
LANG_TO_DISPLAY[lang_str] = display_class
|
||||
|
||||
parse_class._locale = display_class._locale = GrampsLocale(lang=locales[0])
|
||||
|
@ -51,6 +51,8 @@ log = logging.getLogger(".DateParser")
|
||||
#-------------------------------------------------------------------------
|
||||
from ..lib.date import Date, DateError
|
||||
from . import _grampslocale
|
||||
from ..utils.grampslocale import GrampsLocale
|
||||
from ._datestrings import DateStrings
|
||||
|
||||
#-------------------------------------------------------------------------
|
||||
#
|
||||
@ -120,6 +122,70 @@ def french_valid(date_tuple):
|
||||
valid = False
|
||||
return valid
|
||||
|
||||
def _build_prefix_table(month_to_int, month_variants):
|
||||
"""
|
||||
Populate a DateParser.month_to_int-like dict
|
||||
with all the prefixes found in month_variants.
|
||||
"""
|
||||
|
||||
month_variants = list(month_variants) # drain the generator, if any
|
||||
month_to_int_new = {}
|
||||
|
||||
# Populate with full names first, w/o prefixes
|
||||
log.debug("Mapping full names...")
|
||||
for i in range(0,len(month_variants)):
|
||||
for month in month_variants[i]:
|
||||
m = month.lower()
|
||||
log.debug("Mapping {} -> {}".format(m, i))
|
||||
month_to_int_new[m] = i
|
||||
month_to_int.update(month_to_int_new)
|
||||
|
||||
log.debug("Mapping new prefixes...")
|
||||
months_sorted = list(month_to_int_new.keys())
|
||||
months_sorted.sort(key=len, reverse=True)
|
||||
for m in months_sorted:
|
||||
for prefixlen in reversed(range(1,len(m))):
|
||||
mp = m[:prefixlen]
|
||||
if mp.strip() != mp:
|
||||
continue
|
||||
if mp in month_to_int:
|
||||
break
|
||||
else:
|
||||
i = month_to_int[m]
|
||||
log.debug("Mapping {} -> {}".format(mp, i))
|
||||
month_to_int[mp] = i
|
||||
|
||||
def _generate_variants(months):
|
||||
"""
|
||||
Generate all month variants for passing to _build_prefix_table
|
||||
@param months an iterable ordered collection,
|
||||
1st item is empty, the rest 1..N, for a
|
||||
calendar with N months overall, contain, each,
|
||||
an iterable of alternative specifications.
|
||||
Each such specification can be:
|
||||
1) a Lexeme, supporting .variants()
|
||||
to return the list of variants underneath
|
||||
2) a literal string
|
||||
3) a |-separated string of alternatives
|
||||
Empty strings are discarded.
|
||||
@return generator of lists per month with all variants listed once only
|
||||
the 1st item will be empty
|
||||
"""
|
||||
|
||||
for month_lexemes_and_alternatives in months:
|
||||
v = []
|
||||
for m in month_lexemes_and_alternatives:
|
||||
try:
|
||||
# Lexeme? ask it to compute the variants it knows
|
||||
mv = list(m.variants())
|
||||
except AttributeError:
|
||||
# plain string, not a lexeme with inflections...
|
||||
# Maybe a '|'-separated list of alternatives, maybe empty,
|
||||
# maybe a single string. Suppress empty strings!
|
||||
mv = (s for s in m.split('|') if s)
|
||||
v.extend(mv)
|
||||
yield(list(set(v)))
|
||||
|
||||
#-------------------------------------------------------------------------
|
||||
#
|
||||
# DateParser class
|
||||
@ -131,6 +197,8 @@ class DateParser(object):
|
||||
converted, the text string is assigned.
|
||||
"""
|
||||
|
||||
_locale = GrampsLocale(lang='en', languages='en')
|
||||
|
||||
_fmt_parse = re.compile(".*%(\S).*%(\S).*%(\S).*")
|
||||
|
||||
# RFC-2822 only uses capitalized English abbreviated names, no locales.
|
||||
@ -141,7 +209,12 @@ class DateParser(object):
|
||||
'Sep' : 9, 'Oct' : 10, 'Nov' : 11, 'Dec' : 12,
|
||||
}
|
||||
|
||||
month_to_int = _grampslocale.month_to_int
|
||||
# seeded with __init_prefix_tables
|
||||
swedish_to_int = month_to_int = {}
|
||||
"""
|
||||
Map Gregorian month names and their prefixes, wherever unambiguous,
|
||||
to the relevant integer index (1..12).
|
||||
"""
|
||||
|
||||
# modifiers before the date
|
||||
# (overridden if a locale-specific date parser exists)
|
||||
@ -172,13 +245,7 @@ class DateParser(object):
|
||||
}
|
||||
|
||||
french_to_int = {
|
||||
'vendémiaire' : 1, 'brumaire' : 2,
|
||||
'frimaire' : 3, 'nivôse': 4,
|
||||
'pluviôse' : 5, 'ventôse' : 6,
|
||||
'germinal' : 7, 'floréal' : 8,
|
||||
'prairial' : 9, 'messidor' : 10,
|
||||
'thermidor' : 11, 'fructidor' : 12,
|
||||
'extra' : 13,
|
||||
# the long ones are seeded with __init_prefix_tables
|
||||
#GEDCOM months
|
||||
'vend' : 1, 'brum' : 2,
|
||||
'frim' : 3, 'nivo' : 4,
|
||||
@ -190,6 +257,8 @@ class DateParser(object):
|
||||
}
|
||||
|
||||
islamic_to_int = {
|
||||
# some are already seeded with __init_prefix_tables,
|
||||
# but it is a pain to separate them out from the variants...
|
||||
"muharram" : 1, "muharram ul haram" : 1,
|
||||
"safar" : 2, "rabi`al-awwal" : 3,
|
||||
"rabi'l" : 3, "rabi`ul-akhir" : 4,
|
||||
@ -207,44 +276,14 @@ class DateParser(object):
|
||||
"dhu hijja" : 12, "thw al-hijjah" : 12,
|
||||
}
|
||||
|
||||
persian_to_int = {
|
||||
"farvardin" : 1, "ordibehesht" : 2,
|
||||
"khordad" : 3, "tir" : 4,
|
||||
"mordad" : 5, "shahrivar" : 6,
|
||||
"mehr" : 7, "aban" : 8,
|
||||
"azar" : 9, "dey" : 10,
|
||||
"bahman" : 11, "esfand" : 12,
|
||||
}
|
||||
|
||||
swedish_to_int = {
|
||||
"januari" : 1, "februari" : 2,
|
||||
"mars" : 3, "april" : 4,
|
||||
"maj" : 5, "juni" : 6,
|
||||
"juli" : 7, "augusti" : 8,
|
||||
"september" : 9, "oktober" : 10,
|
||||
"november" : 11, "december" : 12,
|
||||
}
|
||||
|
||||
# seeded with __init_prefix_tables
|
||||
persian_to_int = { }
|
||||
|
||||
bce = ["B.C.E.", "B.C.E", "BCE", "B.C.", "B.C", "BC" ]
|
||||
# (overridden if a locale-specific date parser exists)
|
||||
|
||||
# seeded with __init_prefix_tables
|
||||
calendar_to_int = {
|
||||
'gregorian' : Date.CAL_GREGORIAN,
|
||||
'g' : Date.CAL_GREGORIAN,
|
||||
'julian' : Date.CAL_JULIAN,
|
||||
'j' : Date.CAL_JULIAN,
|
||||
'hebrew' : Date.CAL_HEBREW,
|
||||
'h' : Date.CAL_HEBREW,
|
||||
'islamic' : Date.CAL_ISLAMIC,
|
||||
'i' : Date.CAL_ISLAMIC,
|
||||
'french' : Date.CAL_FRENCH,
|
||||
'french republican': Date.CAL_FRENCH,
|
||||
'f' : Date.CAL_FRENCH,
|
||||
'persian' : Date.CAL_PERSIAN,
|
||||
'p' : Date.CAL_PERSIAN,
|
||||
'swedish' : Date.CAL_SWEDISH,
|
||||
's' : Date.CAL_SWEDISH,
|
||||
}
|
||||
# (probably overridden if a locale-specific date parser exists)
|
||||
|
||||
@ -265,6 +304,31 @@ class DateParser(object):
|
||||
}
|
||||
# (overridden if a locale-specific date parser exists)
|
||||
|
||||
_langs = set()
|
||||
def __init_prefix_tables(self):
|
||||
lang = self._locale.lang
|
||||
if lang in DateParser._langs:
|
||||
log.debug("Prefix tables for {} already built".format(lang))
|
||||
return
|
||||
else:
|
||||
DateParser._langs.add(lang)
|
||||
ds = DateStrings(self._locale)
|
||||
log.debug("Begin building parser prefix tables for {}".format(lang))
|
||||
_build_prefix_table(DateParser.month_to_int,
|
||||
_generate_variants(
|
||||
zip(ds.long_months, ds.short_months,
|
||||
ds.swedish_SV, ds.alt_long_months)))
|
||||
_build_prefix_table(DateParser.hebrew_to_int,
|
||||
_generate_variants(zip(ds.hebrew)))
|
||||
_build_prefix_table(DateParser.french_to_int,
|
||||
_generate_variants(zip(ds.french)))
|
||||
_build_prefix_table(DateParser.islamic_to_int,
|
||||
_generate_variants(zip(ds.islamic)))
|
||||
_build_prefix_table(DateParser.persian_to_int,
|
||||
_generate_variants(zip(ds.persian)))
|
||||
_build_prefix_table(DateParser.calendar_to_int,
|
||||
_generate_variants(zip(ds.calendar)))
|
||||
|
||||
def __init__(self):
|
||||
self.init_strings()
|
||||
self.parser = {
|
||||
@ -294,8 +358,8 @@ class DateParser(object):
|
||||
sorted so that longest keys match first. Any '.' characters
|
||||
are quoted.
|
||||
"""
|
||||
keys.sort(key=lambda x: len(x), reverse=True)
|
||||
return '(' + '|'.join([key.replace('.', '\.') for key in keys]) + ')'
|
||||
keys.sort(key=len, reverse=True)
|
||||
return '(' + '|'.join([re.escape(key) for key in keys]) + ')'
|
||||
|
||||
def init_strings(self):
|
||||
"""
|
||||
@ -308,6 +372,8 @@ class DateParser(object):
|
||||
can be coded after DateParser.init_strings(self) call, that way they
|
||||
override stuff from this method. See DateParserRU() as an example.
|
||||
"""
|
||||
self.__init_prefix_tables()
|
||||
|
||||
self._rfc_mon_str = '(' + '|'.join(list(self._rfc_mons_to_int.keys())) + ')'
|
||||
self._rfc_day_str = '(' + '|'.join(self._rfc_days) + ')'
|
||||
|
||||
|
346
gramps/gen/datehandler/_datestrings.py
Normal file
346
gramps/gen/datehandler/_datestrings.py
Normal file
@ -0,0 +1,346 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
#
|
||||
# Gramps - a GTK+/GNOME based genealogy program
|
||||
#
|
||||
# Copyright (C) 2013 Vassilii Khachaturov
|
||||
#
|
||||
# This program is free software; you can redistribute it and/or modify
|
||||
# it under the terms of the GNU General Public License as published by
|
||||
# the Free Software Foundation; either version 2 of the License, or
|
||||
# (at your option) any later version.
|
||||
#
|
||||
# This program is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# GNU General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU General Public License
|
||||
# along with this program; if not, write to the Free Software
|
||||
# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
#
|
||||
# $Id$
|
||||
|
||||
"""
|
||||
Date strings to translate per each language for display and parsing.
|
||||
"""
|
||||
from __future__ import print_function, unicode_literals
|
||||
|
||||
#-------------------------------------------------------------------------
|
||||
#
|
||||
# set up logging
|
||||
#
|
||||
#-------------------------------------------------------------------------
|
||||
import logging
|
||||
log = logging.getLogger(".DateStrings")
|
||||
|
||||
#-------------------------------------------------------------------------
|
||||
#
|
||||
# DateStrings
|
||||
#
|
||||
#-------------------------------------------------------------------------
|
||||
class DateStrings(object):
|
||||
"""
|
||||
String tables for :class:`~DateDisplay` and :class:`~DateParser`.
|
||||
"""
|
||||
|
||||
# This table needs not be localized, it's only for parsing
|
||||
# Swedish calendar dates using Swedish month names.
|
||||
# Display of these months uses the regular long_months.
|
||||
# TODO should we pack these into alt_long_months instead?
|
||||
swedish_SV = (
|
||||
"", "Januari", "Februari", "Mars",
|
||||
"April", "Maj", "Juni",
|
||||
"Juli", "Augusti", "September",
|
||||
"Oktober", "November", "December"
|
||||
)
|
||||
|
||||
|
||||
def __init__(self, locale):
|
||||
_ = locale.translation.lexgettext
|
||||
|
||||
self.long_months = ( "",
|
||||
# TRANSLATORS: see
|
||||
# http://gramps-project.org/wiki/index.php?title=Translating_Gramps#Translating_dates
|
||||
# to learn how to select proper inflection to be used in your localized
|
||||
# DateDisplayer code!
|
||||
_("localized lexeme inflections||January"),
|
||||
_("localized lexeme inflections||February"),
|
||||
_("localized lexeme inflections||March"),
|
||||
_("localized lexeme inflections||April"),
|
||||
_("localized lexeme inflections||May"),
|
||||
_("localized lexeme inflections||June"),
|
||||
_("localized lexeme inflections||July"),
|
||||
_("localized lexeme inflections||August"),
|
||||
_("localized lexeme inflections||September"),
|
||||
_("localized lexeme inflections||October"),
|
||||
_("localized lexeme inflections||November"),
|
||||
_("localized lexeme inflections||December") )
|
||||
|
||||
self.short_months = ( "",
|
||||
# TRANSLATORS: see
|
||||
# http://gramps-project.org/wiki/index.php?title=Translating_Gramps#Translating_dates
|
||||
# to learn how to select proper inflection to be used in your localized
|
||||
# DateDisplayer code!
|
||||
_("localized lexeme inflections - short month form||Jan"),
|
||||
_("localized lexeme inflections - short month form||Feb"),
|
||||
_("localized lexeme inflections - short month form||Mar"),
|
||||
_("localized lexeme inflections - short month form||Apr"),
|
||||
_("localized lexeme inflections - short month form||May"),
|
||||
_("localized lexeme inflections - short month form||Jun"),
|
||||
_("localized lexeme inflections - short month form||Jul"),
|
||||
_("localized lexeme inflections - short month form||Aug"),
|
||||
_("localized lexeme inflections - short month form||Sep"),
|
||||
_("localized lexeme inflections - short month form||Oct"),
|
||||
_("localized lexeme inflections - short month form||Nov"),
|
||||
_("localized lexeme inflections - short month form||Dec") )
|
||||
|
||||
_ = locale.translation.sgettext
|
||||
self.alt_long_months = ( "",
|
||||
# TRANSLATORS: see
|
||||
# http://gramps-project.org/wiki/index.php?title=Translating_Gramps#Translating_dates
|
||||
# to learn how to add proper alternatives to be recognized in your localized
|
||||
# DateParser code!
|
||||
_("alternative month names for January||"),
|
||||
_("alternative month names for February||"),
|
||||
_("alternative month names for March||"),
|
||||
_("alternative month names for April||"),
|
||||
_("alternative month names for May||"),
|
||||
_("alternative month names for June||"),
|
||||
_("alternative month names for July||"),
|
||||
_("alternative month names for August||"),
|
||||
_("alternative month names for September||"),
|
||||
_("alternative month names for October||"),
|
||||
_("alternative month names for November||"),
|
||||
_("alternative month names for December||") )
|
||||
|
||||
self.calendar = (
|
||||
# Must appear in the order indexed by Date.CAL_... numeric constants
|
||||
_("calendar|Gregorian"),
|
||||
_("calendar|Julian"),
|
||||
_("calendar|Hebrew"),
|
||||
_("calendar|French Republican"),
|
||||
_("calendar|Persian"),
|
||||
_("calendar|Islamic"),
|
||||
_("calendar|Swedish") )
|
||||
_ = locale.translation.lexgettext
|
||||
|
||||
self.hebrew = (
|
||||
"",
|
||||
# TRANSLATORS: see
|
||||
# http://gramps-project.org/wiki/index.php?title=Translating_Gramps#Translating_dates
|
||||
# to learn how to select proper inflection to be used in your localized
|
||||
# DateDisplayer code!
|
||||
_("Hebrew month lexeme|Tishri"),
|
||||
_("Hebrew month lexeme|Heshvan"),
|
||||
_("Hebrew month lexeme|Kislev"),
|
||||
_("Hebrew month lexeme|Tevet"),
|
||||
_("Hebrew month lexeme|Shevat"),
|
||||
_("Hebrew month lexeme|AdarI"),
|
||||
_("Hebrew month lexeme|AdarII"),
|
||||
_("Hebrew month lexeme|Nisan"),
|
||||
_("Hebrew month lexeme|Iyyar"),
|
||||
_("Hebrew month lexeme|Sivan"),
|
||||
_("Hebrew month lexeme|Tammuz"),
|
||||
_("Hebrew month lexeme|Av"),
|
||||
_("Hebrew month lexeme|Elul")
|
||||
)
|
||||
|
||||
self.french = (
|
||||
"",
|
||||
# TRANSLATORS: see
|
||||
# http://gramps-project.org/wiki/index.php?title=Translating_Gramps#Translating_dates
|
||||
# to learn how to select proper inflection to be used in your localized
|
||||
# DateDisplayer code!
|
||||
_("French month lexeme|Vendémiaire"),
|
||||
_("French month lexeme|Brumaire"),
|
||||
_("French month lexeme|Frimaire"),
|
||||
_("French month lexeme|Nivôse"),
|
||||
_("French month lexeme|Pluviôse"),
|
||||
_("French month lexeme|Ventôse"),
|
||||
_("French month lexeme|Germinal"),
|
||||
_("French month lexeme|Floréal"),
|
||||
_("French month lexeme|Prairial"),
|
||||
_("French month lexeme|Messidor"),
|
||||
_("French month lexeme|Thermidor"),
|
||||
_("French month lexeme|Fructidor"),
|
||||
_("French month lexeme|Extra"),
|
||||
)
|
||||
|
||||
self.islamic = (
|
||||
"",
|
||||
# TRANSLATORS: see
|
||||
# http://gramps-project.org/wiki/index.php?title=Translating_Gramps#Translating_dates
|
||||
# to learn how to select proper inflection to be used in your localized
|
||||
# DateDisplayer code!
|
||||
_("Islamic month lexeme|Muharram"),
|
||||
_("Islamic month lexeme|Safar"),
|
||||
_("Islamic month lexeme|Rabi`al-Awwal"),
|
||||
_("Islamic month lexeme|Rabi`ath-Thani"),
|
||||
_("Islamic month lexeme|Jumada l-Ula"),
|
||||
_("Islamic month lexeme|Jumada t-Tania"),
|
||||
_("Islamic month lexeme|Rajab"),
|
||||
_("Islamic month lexeme|Sha`ban"),
|
||||
_("Islamic month lexeme|Ramadan"),
|
||||
_("Islamic month lexeme|Shawwal"),
|
||||
_("Islamic month lexeme|Dhu l-Qa`da"),
|
||||
_("Islamic month lexeme|Dhu l-Hijja"),
|
||||
)
|
||||
|
||||
self.persian = (
|
||||
"",
|
||||
# TRANSLATORS: see
|
||||
# http://gramps-project.org/wiki/index.php?title=Translating_Gramps#Translating_dates
|
||||
# to learn how to select proper inflection to be used in your localized
|
||||
# DateDisplayer code!
|
||||
_("Persian month lexeme|Farvardin"),
|
||||
_("Persian month lexeme|Ordibehesht"),
|
||||
_("Persian month lexeme|Khordad"),
|
||||
_("Persian month lexeme|Tir"),
|
||||
_("Persian month lexeme|Mordad"),
|
||||
_("Persian month lexeme|Shahrivar"),
|
||||
_("Persian month lexeme|Mehr"),
|
||||
_("Persian month lexeme|Aban"),
|
||||
_("Persian month lexeme|Azar"),
|
||||
_("Persian month lexeme|Dey"),
|
||||
_("Persian month lexeme|Bahman"),
|
||||
_("Persian month lexeme|Esfand"),
|
||||
)
|
||||
|
||||
self.modifiers = ("",
|
||||
_("date modifier|before "),
|
||||
_("date modifier|after "),
|
||||
_("date modifier|about "),
|
||||
"", "", "")
|
||||
|
||||
self.qualifiers = ("",
|
||||
_("date quality|estimated "),
|
||||
_("date quality|calculated "),
|
||||
)
|
||||
|
||||
|
||||
# TODO extend with further strings
|
||||
# along with the date displayer and parser refactoring
|
||||
|
||||
__doc__ += """
|
||||
__main__
|
||||
--------
|
||||
|
||||
Run this code with the appropriate ``LANG`` and ``LC_DATE`` set for your target language,
|
||||
in order to generate the .po snippets initialized with the strings from your locale
|
||||
(from the deprecated data provided in _grampslocale).
|
||||
|
||||
E.g., for French:
|
||||
::
|
||||
LANG=fr_FR.utf8 LC_ALL=fr_FR.utf8 GRAMPS_RESOURCES=$PWD python -m gramps.gen.datehandler._datestrings
|
||||
|
||||
Then merge the output into your language's .po file, and further modify the strings as needed.
|
||||
Then remove the strings from your language's ``DateParserXX`` and ``DateHandlerXX`` classes.
|
||||
"""
|
||||
|
||||
if __name__ == '__main__':
|
||||
import sys
|
||||
from ..utils.grampslocale import GrampsLocale
|
||||
from gramps.gen.const import GRAMPS_LOCALE as glocale
|
||||
from ._grampslocale import (_deprecated_long_months as old_long,
|
||||
_deprecated_short_months as old_short)
|
||||
from ._datedisplay import DateDisplay
|
||||
import gettext
|
||||
lang = glocale.lang
|
||||
lang_short = lang[:2]
|
||||
available_langs = glocale.get_available_translations()
|
||||
if glocale.check_available_translations(lang) is None:
|
||||
print ("Translation for current language {lang} not available.\n"
|
||||
"Available translations: {list}.\n"
|
||||
"Does po/{lang_short}*.po exist in gramps source tree?!\n"
|
||||
"Please set your LANG / LC_ALL environment to something else...\n".format(
|
||||
lang=lang, list=available_langs, lang_short=lang_short),
|
||||
file=sys.stderr)
|
||||
sys.exit(1)
|
||||
|
||||
print ("# Generating snippets for {}*.po\n"
|
||||
"# Available languages: {}".format(
|
||||
lang_short, available_langs))
|
||||
glocale = GrampsLocale(languages=(lang))
|
||||
dd = glocale.date_displayer
|
||||
ds = dd._ds
|
||||
glocale_EN = GrampsLocale(languages=('en'))
|
||||
ds_EN = DateStrings(glocale_EN)
|
||||
|
||||
filename = __file__
|
||||
|
||||
try:
|
||||
localized_months = dd.__class__.long_months
|
||||
except AttributeError:
|
||||
localized_months = old_long
|
||||
|
||||
def print_po_snippet(en_loc_old_lists, context):
|
||||
for m,localized,old in zip(*en_loc_old_lists):
|
||||
if m == "":
|
||||
continue
|
||||
if m == localized:
|
||||
localized = old
|
||||
print ('#: {file}:{line}\n'
|
||||
'msgid "{context}{en_month}"\n'
|
||||
'msgstr "{localized_month}"\n'.format(
|
||||
context = context,
|
||||
file = filename,
|
||||
line = print_po_snippet.line,
|
||||
en_month = m,
|
||||
localized_month = localized))
|
||||
print_po_snippet.line += 1
|
||||
print_po_snippet.line = 10000
|
||||
|
||||
try:
|
||||
localized_months = dd.__class__.long_months
|
||||
except AttributeError:
|
||||
localized_months = old_long
|
||||
print_po_snippet((ds_EN.long_months, localized_months, old_long),
|
||||
"localized lexeme inflections||")
|
||||
try:
|
||||
localized_months = dd.__class__.short_months
|
||||
except AttributeError:
|
||||
localized_months = old_short
|
||||
print_po_snippet((ds_EN.short_months, localized_months, old_short),
|
||||
"localized lexeme inflections - short month form||")
|
||||
|
||||
try:
|
||||
loc = dd.__class__.hebrew
|
||||
print_po_snippet((ds_EN.hebrew, loc, loc),
|
||||
"Hebrew month lexeme|")
|
||||
except AttributeError:
|
||||
pass
|
||||
|
||||
try:
|
||||
loc = dd.__class__.french
|
||||
print_po_snippet((ds_EN.french, loc, loc),
|
||||
"French month lexeme|")
|
||||
except AttributeError:
|
||||
pass
|
||||
|
||||
try:
|
||||
loc = dd.__class__.islamic
|
||||
print_po_snippet((ds_EN.islamic, loc, loc),
|
||||
"Islamic month lexeme|")
|
||||
except AttributeError:
|
||||
pass
|
||||
|
||||
try:
|
||||
loc = dd.__class__.persian
|
||||
print_po_snippet((ds_EN.persian, loc, loc),
|
||||
"Persian month lexeme|")
|
||||
except AttributeError:
|
||||
pass
|
||||
|
||||
try:
|
||||
loc = dd.__class__._mod_str
|
||||
print_po_snippet((ds_EN.modifiers, loc, loc),
|
||||
"date modifier|")
|
||||
except AttributeError:
|
||||
pass
|
||||
|
||||
try:
|
||||
loc = dd.__class__._qual_str
|
||||
print_po_snippet((ds_EN.qualifiers, loc, loc),
|
||||
"date quality|")
|
||||
except AttributeError:
|
||||
pass
|
@ -46,34 +46,8 @@ codeset = glocale.encoding
|
||||
|
||||
try:
|
||||
|
||||
month_to_int = {
|
||||
to_uni(locale.nl_langinfo(locale.MON_1), codeset).lower() : 1,
|
||||
to_uni(locale.nl_langinfo(locale.ABMON_1), codeset).lower() : 1,
|
||||
to_uni(locale.nl_langinfo(locale.MON_2), codeset).lower() : 2,
|
||||
to_uni(locale.nl_langinfo(locale.ABMON_2), codeset).lower() : 2,
|
||||
to_uni(locale.nl_langinfo(locale.MON_3), codeset).lower() : 3,
|
||||
to_uni(locale.nl_langinfo(locale.ABMON_3), codeset).lower() : 3,
|
||||
to_uni(locale.nl_langinfo(locale.MON_4), codeset).lower() : 4,
|
||||
to_uni(locale.nl_langinfo(locale.ABMON_4), codeset).lower() : 4,
|
||||
to_uni(locale.nl_langinfo(locale.MON_5), codeset).lower() : 5,
|
||||
to_uni(locale.nl_langinfo(locale.ABMON_5), codeset).lower() : 5,
|
||||
to_uni(locale.nl_langinfo(locale.MON_6), codeset).lower() : 6,
|
||||
to_uni(locale.nl_langinfo(locale.ABMON_6), codeset).lower() : 6,
|
||||
to_uni(locale.nl_langinfo(locale.MON_7), codeset).lower() : 7,
|
||||
to_uni(locale.nl_langinfo(locale.ABMON_7), codeset).lower() : 7,
|
||||
to_uni(locale.nl_langinfo(locale.MON_8), codeset).lower() : 8,
|
||||
to_uni(locale.nl_langinfo(locale.ABMON_8), codeset).lower() : 8,
|
||||
to_uni(locale.nl_langinfo(locale.MON_9), codeset).lower() : 9,
|
||||
to_uni(locale.nl_langinfo(locale.ABMON_9), codeset).lower() : 9,
|
||||
to_uni(locale.nl_langinfo(locale.MON_10), codeset).lower() : 10,
|
||||
to_uni(locale.nl_langinfo(locale.ABMON_10), codeset).lower(): 10,
|
||||
to_uni(locale.nl_langinfo(locale.MON_11), codeset).lower() : 11,
|
||||
to_uni(locale.nl_langinfo(locale.ABMON_11), codeset).lower(): 11,
|
||||
to_uni(locale.nl_langinfo(locale.MON_12), codeset).lower() : 12,
|
||||
to_uni(locale.nl_langinfo(locale.ABMON_12), codeset).lower(): 12,
|
||||
}
|
||||
|
||||
long_months = (
|
||||
# here only for the upgrade tool, see _datestrings.py __main__
|
||||
_deprecated_long_months = (
|
||||
"",
|
||||
to_uni(locale.nl_langinfo(locale.MON_1), codeset),
|
||||
to_uni(locale.nl_langinfo(locale.MON_2), codeset),
|
||||
@ -89,7 +63,7 @@ try:
|
||||
to_uni(locale.nl_langinfo(locale.MON_12), codeset),
|
||||
)
|
||||
|
||||
short_months = (
|
||||
_deprecated_short_months = (
|
||||
"",
|
||||
to_uni(locale.nl_langinfo(locale.ABMON_1), codeset),
|
||||
to_uni(locale.nl_langinfo(locale.ABMON_2), codeset),
|
||||
@ -141,34 +115,7 @@ try:
|
||||
except:
|
||||
import time
|
||||
|
||||
month_to_int = {
|
||||
to_uni(time.strftime('%B',(1,1,1,1,1,1,1,1,1)), codeset).lower() : 1,
|
||||
to_uni(time.strftime('%b',(1,1,1,1,1,1,1,1,1)), codeset).lower() : 1,
|
||||
to_uni(time.strftime('%B',(1,2,1,1,1,1,1,1,1)), codeset).lower() : 2,
|
||||
to_uni(time.strftime('%b',(1,2,1,1,1,1,1,1,1)), codeset).lower() : 2,
|
||||
to_uni(time.strftime('%B',(1,3,1,1,1,1,1,1,1)), codeset).lower() : 3,
|
||||
to_uni(time.strftime('%b',(1,3,1,1,1,1,1,1,1)), codeset).lower() : 3,
|
||||
to_uni(time.strftime('%B',(1,4,1,1,1,1,1,1,1)), codeset).lower() : 4,
|
||||
to_uni(time.strftime('%b',(1,4,1,1,1,1,1,1,1)), codeset).lower() : 4,
|
||||
to_uni(time.strftime('%B',(1,5,1,1,1,1,1,1,1)), codeset).lower() : 5,
|
||||
to_uni(time.strftime('%b',(1,5,1,1,1,1,1,1,1)), codeset).lower() : 5,
|
||||
to_uni(time.strftime('%B',(1,6,1,1,1,1,1,1,1)), codeset).lower() : 6,
|
||||
to_uni(time.strftime('%b',(1,6,1,1,1,1,1,1,1)), codeset).lower() : 6,
|
||||
to_uni(time.strftime('%B',(1,7,1,1,1,1,1,1,1)), codeset).lower() : 7,
|
||||
to_uni(time.strftime('%b',(1,7,1,1,1,1,1,1,1)), codeset).lower() : 7,
|
||||
to_uni(time.strftime('%B',(1,8,1,1,1,1,1,1,1)), codeset).lower() : 8,
|
||||
to_uni(time.strftime('%b',(1,8,1,1,1,1,1,1,1)), codeset).lower() : 8,
|
||||
to_uni(time.strftime('%B',(1,9,1,1,1,1,1,1,1)), codeset).lower() : 9,
|
||||
to_uni(time.strftime('%b',(1,9,1,1,1,1,1,1,1)), codeset).lower() : 9,
|
||||
to_uni(time.strftime('%B',(1,10,1,1,1,1,1,1,1)), codeset).lower() : 10,
|
||||
to_uni(time.strftime('%b',(1,10,1,1,1,1,1,1,1)), codeset).lower() : 10,
|
||||
to_uni(time.strftime('%B',(1,11,1,1,1,1,1,1,1)), codeset).lower() : 11,
|
||||
to_uni(time.strftime('%b',(1,11,1,1,1,1,1,1,1)), codeset).lower() : 11,
|
||||
to_uni(time.strftime('%B',(1,12,1,1,1,1,1,1,1)), codeset).lower() : 12,
|
||||
to_uni(time.strftime('%b',(1,12,1,1,1,1,1,1,1)), codeset).lower() : 12,
|
||||
}
|
||||
|
||||
long_months = (
|
||||
_deprecated_long_months = (
|
||||
"",
|
||||
to_uni(time.strftime('%B',(1,1,1,1,1,1,1,1,1)), codeset),
|
||||
to_uni(time.strftime('%B',(1,2,1,1,1,1,1,1,1)), codeset),
|
||||
@ -184,7 +131,7 @@ except:
|
||||
to_uni(time.strftime('%B',(1,12,1,1,1,1,1,1,1)), codeset),
|
||||
)
|
||||
|
||||
short_months = (
|
||||
_deprecated_short_months = (
|
||||
"",
|
||||
to_uni(time.strftime('%b',(1,1,1,1,1,1,1,1,1)), codeset),
|
||||
to_uni(time.strftime('%b',(1,2,1,1,1,1,1,1,1)), codeset),
|
||||
|
119
gramps/gen/datehandler/test/datedisplay_test.py
Normal file
119
gramps/gen/datehandler/test/datedisplay_test.py
Normal file
@ -0,0 +1,119 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
#
|
||||
# Gramps - a GTK+/GNOME based genealogy program
|
||||
#
|
||||
# Copyright (C) 2013 Vassilii Khachaturov
|
||||
#
|
||||
# This program is free software; you can redistribute it and/or modify
|
||||
# it under the terms of the GNU General Public License as published by
|
||||
# the Free Software Foundation; either version 2 of the License, or
|
||||
# (at your option) any later version.
|
||||
#
|
||||
# This program is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# GNU General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU General Public License
|
||||
# along with this program; if not, write to the Free Software
|
||||
# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
#
|
||||
|
||||
# $Id$
|
||||
|
||||
"""
|
||||
Deeper testing of some DateParser internals.
|
||||
"""
|
||||
|
||||
from __future__ import print_function, unicode_literals
|
||||
import unittest
|
||||
|
||||
from ...utils.grampslocale import GrampsLocale
|
||||
from ...lib.date import Date
|
||||
|
||||
class DateDisplayTest(unittest.TestCase):
|
||||
def setUp(self):
|
||||
from .._datedisplay import DateDisplay
|
||||
self.display = DateDisplay()
|
||||
self.display_RU = GrampsLocale(lang='ru').date_displayer
|
||||
|
||||
def assert_map_key_val(self, m, k, v):
|
||||
try:
|
||||
self.assertEqual(m[k], v)
|
||||
except KeyError:
|
||||
self.assertTrue(False, list(m.items()))
|
||||
|
||||
class DateDisplayCalendarTest(DateDisplayTest):
|
||||
def test_calendar_gregorian_is_empty(self):
|
||||
self.assert_map_key_val(self.display.calendar, Date.CAL_GREGORIAN, "")
|
||||
|
||||
def test_calendar_julian_RU(self):
|
||||
self.assert_map_key_val(self.display_RU.calendar, Date.CAL_JULIAN, 'юлианский')
|
||||
|
||||
# This class tests common functionality in DateDisplay as applied to RU,
|
||||
# and so it is coupled to translated strings and inflection names
|
||||
# extracted by lexgettext from ru.po
|
||||
class DateDisplayInflectionsTestRU(DateDisplayTest):
|
||||
def setUp(self):
|
||||
DateDisplayTest.setUp(self)
|
||||
self.dd = self.display = self.display_RU
|
||||
self.months = self.dd._ds.long_months
|
||||
# TODO hardwired magic numbers! Bad API smell.
|
||||
self.dd.set_format(4) # day month_name year
|
||||
self.may = self.months[5]
|
||||
|
||||
def assertInflectionInDate(self, inflection, date, month=None):
|
||||
if month is None:
|
||||
month = date.get_month()
|
||||
month_lexeme = self.months[month]
|
||||
self.assertIn(month_lexeme.f[inflection],
|
||||
self.dd.display(date))
|
||||
|
||||
def test_month_only_date_nominative(self):
|
||||
for qual in (Date.QUAL_NONE, Date.QUAL_ESTIMATED, Date.QUAL_CALCULATED):
|
||||
d1945may = Date(1945, 5, 0)
|
||||
d1945may.set_quality(qual)
|
||||
self.assertInflectionInDate('И', d1945may)
|
||||
|
||||
def test_day_month_date_genitive(self):
|
||||
d1945may9 = Date(1945, 5, 9)
|
||||
self.assertInflectionInDate('Р', d1945may9)
|
||||
|
||||
def test_before_month_only_date_genitive(self):
|
||||
d1945may = Date(1945, 5, 0)
|
||||
d1945may.set_modifier(Date.MOD_BEFORE)
|
||||
# TODO hardwired magic numbers! Bad API smell.
|
||||
for inflecting_format in (3,4):
|
||||
self.dd.set_format(inflecting_format)
|
||||
# this depends on the fact that in Russian the short and long forms for May
|
||||
# will be the same!
|
||||
self.assertIn("до мая", self.dd.display(d1945may))
|
||||
|
||||
def test_between_month_only_dates_ablative(self):
|
||||
b1945may_1946may = Date()
|
||||
b1945may_1946may.set(
|
||||
modifier=Date.MOD_RANGE,
|
||||
value=(0, 5, 1945, False, 0, 5, 1946, False))
|
||||
# TODO hardwired magic numbers! Bad API smell.
|
||||
for inflecting_format in (3,4):
|
||||
self.dd.set_format(inflecting_format)
|
||||
# this depends on the fact that in Russian the short and long forms for May
|
||||
# will be the same!
|
||||
self.assertIn("между маем", self.dd.display(b1945may_1946may))
|
||||
self.assertIn("и маем", self.dd.display(b1945may_1946may))
|
||||
|
||||
def test_month_only_date_span_from_genitive_to_accusative(self):
|
||||
f1945may_t1946may = Date()
|
||||
f1945may_t1946may.set(
|
||||
modifier=Date.MOD_SPAN,
|
||||
value=(0, 5, 1945, False, 0, 5, 1946, False))
|
||||
# TODO hardwired magic numbers! Bad API smell.
|
||||
for inflecting_format in (3,4):
|
||||
self.dd.set_format(inflecting_format)
|
||||
# this depends on the fact that in Russian the short and long forms for May
|
||||
# will be the same!
|
||||
self.assertIn("с мая", self.dd.display(f1945may_t1946may))
|
||||
self.assertIn("по май", self.dd.display(f1945may_t1946may))
|
||||
|
||||
if __name__ == "__main__":
|
||||
unittest.main()
|
128
gramps/gen/datehandler/test/dateparser_test.py
Normal file
128
gramps/gen/datehandler/test/dateparser_test.py
Normal file
@ -0,0 +1,128 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
#
|
||||
# Gramps - a GTK+/GNOME based genealogy program
|
||||
#
|
||||
# Copyright (C) 2013 Vassilii Khachaturov
|
||||
#
|
||||
# This program is free software; you can redistribute it and/or modify
|
||||
# it under the terms of the GNU General Public License as published by
|
||||
# the Free Software Foundation; either version 2 of the License, or
|
||||
# (at your option) any later version.
|
||||
#
|
||||
# This program is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# GNU General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU General Public License
|
||||
# along with this program; if not, write to the Free Software
|
||||
# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
#
|
||||
|
||||
# $Id$
|
||||
|
||||
"""
|
||||
Deeper testing of some DateParser internals.
|
||||
"""
|
||||
|
||||
from __future__ import print_function, unicode_literals
|
||||
import unittest
|
||||
|
||||
from ...utils.grampslocale import GrampsLocale
|
||||
from ...lib.date import Date
|
||||
|
||||
class DateParserTest(unittest.TestCase):
|
||||
def setUp(self):
|
||||
from .._dateparser import DateParser
|
||||
self.parser = DateParser()
|
||||
self.parser_RU = GrampsLocale(lang='ru').date_parser
|
||||
|
||||
def assert_map_key_val(self, m, k, v):
|
||||
try:
|
||||
self.assertEqual(m[k], v)
|
||||
except KeyError:
|
||||
self.assertTrue(False, list(m.items()))
|
||||
|
||||
def test_month_to_int_jan_is_1(self):
|
||||
self.assert_map_key_val(self.parser.month_to_int, 'jan', 1)
|
||||
|
||||
def test_prefix_table_for_RU_built(self):
|
||||
self.assertIn('ru_RU', self.parser._langs)
|
||||
|
||||
def test_month_to_int_septem_RU_is_9(self):
|
||||
self.assert_map_key_val(self.parser.month_to_int, 'сентяб', 9)
|
||||
|
||||
def test_hebrew_to_int_av_is_12(self):
|
||||
self.assert_map_key_val(self.parser.hebrew_to_int, 'av', 12)
|
||||
self.assert_map_key_val(self.parser.hebrew_to_int, 'ав', 12) # RU
|
||||
|
||||
def test_french_to_int_thermidor_is_11(self):
|
||||
self.assert_map_key_val(self.parser.french_to_int, 'thermidor', 11)
|
||||
self.assert_map_key_val(self.parser.french_to_int, 'термидор', 11) # RU
|
||||
|
||||
def test_islamic_to_int_ramadan_is_9(self):
|
||||
self.assert_map_key_val(self.parser.islamic_to_int, 'ramadan', 9)
|
||||
self.assert_map_key_val(self.parser.islamic_to_int, 'рамадан', 9) # RU
|
||||
|
||||
def test_persian_to_int_tir_is_4(self):
|
||||
self.assert_map_key_val(self.parser.persian_to_int, 'tir', 4)
|
||||
self.assert_map_key_val(self.parser.persian_to_int, 'тир', 4) # RU
|
||||
|
||||
def test_calendar_to_int_gregorian(self):
|
||||
self.assert_map_key_val(self.parser.calendar_to_int, 'gregorian', Date.CAL_GREGORIAN)
|
||||
self.assert_map_key_val(self.parser.calendar_to_int, 'g', Date.CAL_GREGORIAN)
|
||||
self.assert_map_key_val(self.parser.calendar_to_int, 'григорианский', Date.CAL_GREGORIAN)
|
||||
self.assert_map_key_val(self.parser.calendar_to_int, 'г', Date.CAL_GREGORIAN)
|
||||
|
||||
def test_calendar_to_int_julian(self):
|
||||
self.assert_map_key_val(self.parser.calendar_to_int, 'julian', Date.CAL_JULIAN)
|
||||
self.assert_map_key_val(self.parser.calendar_to_int, 'j', Date.CAL_JULIAN)
|
||||
self.assert_map_key_val(self.parser.calendar_to_int, 'юлианский', Date.CAL_JULIAN)
|
||||
self.assert_map_key_val(self.parser.calendar_to_int, 'ю', Date.CAL_JULIAN)
|
||||
|
||||
class Test_generate_variants(unittest.TestCase):
|
||||
def setUp(self):
|
||||
from .. import _datestrings
|
||||
from .._dateparser import _generate_variants
|
||||
self.ds = ds = _datestrings.DateStrings(GrampsLocale(languages=('ru')))
|
||||
self.month_variants = list(_generate_variants(
|
||||
zip(ds.long_months, ds.short_months,
|
||||
ds.swedish_SV, ds.alt_long_months)))
|
||||
|
||||
def testVariantsSameLengthAsLongMonths(self):
|
||||
self.assertEqual(len(self.ds.long_months),
|
||||
len(self.month_variants))
|
||||
|
||||
def testRussianHasDifferentVariantsForEachMonth(self):
|
||||
for i in range(1, 13):
|
||||
mvi = self.month_variants[i]
|
||||
self.assertTrue(len(mvi) > 1, msg=mvi)
|
||||
|
||||
def testNoEmptyStringInVariants(self):
|
||||
for i in range(1, 13):
|
||||
mvi = self.month_variants[i]
|
||||
self.assertNotIn("", mvi)
|
||||
|
||||
def testLongMonthsAppearInVariants(self):
|
||||
for i in range(1, 13):
|
||||
lmi = self.ds.long_months[i]
|
||||
mvi = self.month_variants[i]
|
||||
self.assertIn("{}".format(lmi), mvi)
|
||||
|
||||
def testShortMonthsAppearInVariants(self):
|
||||
for i in range(1, 13):
|
||||
smi = self.ds.short_months[i]
|
||||
mvi = self.month_variants[i]
|
||||
self.assertIn("{}".format(smi), mvi)
|
||||
|
||||
def testLongMonthVariantsUnique(self):
|
||||
for i in range(1, 13):
|
||||
mvi = self.month_variants[i]
|
||||
self.assertEqual(len(mvi), len(set(mvi)), msg=mvi)
|
||||
|
||||
def testRuMayVariantsContainSvMaj(self):
|
||||
v = self.month_variants[5]
|
||||
self.assertIn("Maj", v)
|
||||
|
||||
if __name__ == "__main__":
|
||||
unittest.main()
|
80
gramps/gen/datehandler/test/datestrings_test.py
Normal file
80
gramps/gen/datehandler/test/datestrings_test.py
Normal file
@ -0,0 +1,80 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
#
|
||||
# Gramps - a GTK+/GNOME based genealogy program
|
||||
#
|
||||
# Copyright (C) 2013 Vassilii Khachaturov
|
||||
#
|
||||
# This program is free software; you can redistribute it and/or modify
|
||||
# it under the terms of the GNU General Public License as published by
|
||||
# the Free Software Foundation; either version 2 of the License, or
|
||||
# (at your option) any later version.
|
||||
#
|
||||
# This program is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# GNU General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU General Public License
|
||||
# along with this program; if not, write to the Free Software
|
||||
# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
#
|
||||
|
||||
# $Id$
|
||||
|
||||
from __future__ import print_function, unicode_literals
|
||||
|
||||
import unittest
|
||||
|
||||
from .. import _datestrings
|
||||
from ...lib.date import Date
|
||||
|
||||
class DateStringsTest(unittest.TestCase):
|
||||
def setUp(self):
|
||||
from ...utils.grampslocale import GrampsLocale
|
||||
self.ds = _datestrings.DateStrings(GrampsLocale()) # whatever the default...
|
||||
self.ds_EN = _datestrings.DateStrings(GrampsLocale(languages='en'))
|
||||
self.ds_RU = _datestrings.DateStrings(GrampsLocale(languages='ru'))
|
||||
|
||||
def testTwelfthMonthIsDecember(self):
|
||||
self.assertEqual(self.ds_EN.long_months[12], 'December')
|
||||
self.assertEqual(self.ds_EN.short_months[12], 'Dec')
|
||||
|
||||
# May is 3-letter in Russian, and so abbreviated form
|
||||
# will be different for inflections!
|
||||
def testRussianHasDifferentInflectionsForShortMay(self):
|
||||
v5 = list(self.ds_RU.short_months[5].variants())
|
||||
self.assertTrue(len(v5) > 1, msg=v5)
|
||||
|
||||
def testEnAdarI_in_AdarII(self):
|
||||
adar1 = self.ds_EN.hebrew[6]
|
||||
adar2 = self.ds_EN.hebrew[7]
|
||||
self.assertIn(str(adar1), str(adar2))
|
||||
|
||||
def testEnLastFrenchIsExtra(self):
|
||||
self.assertEqual(str(self.ds_EN.french[-1]), "Extra")
|
||||
|
||||
def testEnPersianKhordadMordad(self):
|
||||
khordad = self.ds_EN.persian[3].lower()
|
||||
mordad = self.ds_EN.persian[5].lower()
|
||||
self.assertEqual(khordad, "khordad")
|
||||
self.assertEqual(mordad, "mordad")
|
||||
|
||||
def testEnIslamicRamadan9(self):
|
||||
self.assertEqual(str(self.ds_EN.islamic[9]), "Ramadan")
|
||||
|
||||
def testFirstStringEmpty(self):
|
||||
self.assertEqual(self.ds.long_months[0], "")
|
||||
self.assertEqual(self.ds.short_months[0], "")
|
||||
self.assertEqual(self.ds.alt_long_months[0], "")
|
||||
|
||||
def testCalendarIndex(self):
|
||||
self.assertEqual(self.ds_EN.calendar[Date.CAL_GREGORIAN], "Gregorian")
|
||||
self.assertEqual(self.ds_EN.calendar[Date.CAL_JULIAN], "Julian")
|
||||
self.assertEqual(self.ds_EN.calendar[Date.CAL_HEBREW], "Hebrew")
|
||||
self.assertEqual(self.ds_EN.calendar[Date.CAL_FRENCH], "French Republican")
|
||||
self.assertEqual(self.ds_EN.calendar[Date.CAL_PERSIAN], "Persian")
|
||||
self.assertEqual(self.ds_EN.calendar[Date.CAL_ISLAMIC], "Islamic")
|
||||
self.assertEqual(self.ds_EN.calendar[Date.CAL_SWEDISH], "Swedish")
|
||||
|
||||
if __name__ == "__main__":
|
||||
unittest.main()
|
@ -530,7 +530,7 @@ class Date(object):
|
||||
QUAL_NONE = 0 # BITWISE
|
||||
QUAL_ESTIMATED = 1
|
||||
QUAL_CALCULATED = 2
|
||||
QUAL_INTERPRETED = 4
|
||||
#QUAL_INTERPRETED = 4 unused in source!!
|
||||
|
||||
CAL_GREGORIAN = 0 # CODE
|
||||
CAL_JULIAN = 1
|
||||
|
@ -1,3 +1,4 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
#
|
||||
# Gramps - a GTK+/GNOME based genealogy program
|
||||
#
|
||||
@ -26,12 +27,13 @@
|
||||
# python modules
|
||||
#
|
||||
#------------------------------------------------------------------------
|
||||
from __future__ import print_function
|
||||
from __future__ import print_function, unicode_literals
|
||||
import gettext
|
||||
import sys
|
||||
import os
|
||||
import codecs
|
||||
import locale
|
||||
import collections
|
||||
import logging
|
||||
|
||||
LOG = logging.getLogger("." + __name__)
|
||||
@ -155,6 +157,7 @@ class GrampsLocale(object):
|
||||
codes corresponding to subidrectries in the localedir,
|
||||
e.g.: "fr" or "zh_CN".
|
||||
"""
|
||||
|
||||
DEFAULT_TRANSLATION_STR = "default"
|
||||
__first_instance = None
|
||||
encoding = None
|
||||
@ -936,6 +939,128 @@ class GrampsLocale(object):
|
||||
# Translations Classes
|
||||
#
|
||||
#-------------------------------------------------------------------------
|
||||
if sys.version_info < (3,0):
|
||||
_LexemeBaseStr = unicode
|
||||
_isstring = lambda s: isinstance(s, basestring)
|
||||
else:
|
||||
_LexemeBaseStr = str
|
||||
_isstring = lambda s: isinstance(s, str)
|
||||
class Lexeme(_LexemeBaseStr):
|
||||
r"""
|
||||
Created with :meth:`~GrampsTranslations.lexgettext`
|
||||
|
||||
.. rubric:: Example
|
||||
Python code:
|
||||
::
|
||||
_ = lexgettext
|
||||
dec = _("localized lexeme inflections||December")
|
||||
xmas = _("lexeme||Christmas")
|
||||
text = _("{holiday} is celebrated in {month}".format(
|
||||
holiday=xmas, month=dec))
|
||||
greeting = _("Merry {holiday}!").format(holiday=xmas)
|
||||
XMAS = xmas.upper()
|
||||
print ("\n".join([XMAS, text, greeting]))
|
||||
|
||||
Translation database (Russian example):
|
||||
::
|
||||
msgid "lexeme||December"
|
||||
msgstr "NOMINATIVE=декабрь|GENITIVE=декабря|ABLATIVE=декабрём|LOCATIVE=декабре"
|
||||
|
||||
msgid "lexeme||Christmas"
|
||||
msgstr "NOMINATIVE=рождество|GENITIVE=рождества|ABLATIVE=рождеством"
|
||||
|
||||
msgid "{holiday} is celebrated in {month}"
|
||||
msgstr "{holiday} празднуют в {month.f[LOCATIVE]}"
|
||||
|
||||
msgid "Merry {holiday}!"
|
||||
msgstr "Счастливого {holiday.f[GENITIVE]}!"
|
||||
|
||||
Prints out:
|
||||
In English locale:
|
||||
::
|
||||
CHRISTMAS
|
||||
Christmas is celebrated in December
|
||||
Merry Christmas!
|
||||
In Russian locale:
|
||||
::
|
||||
РОЖДЕСТВО
|
||||
рождество празднуют в декабре
|
||||
Счастливого рождества!
|
||||
|
||||
.. rubric:: Description
|
||||
Stores an arbitrary number of forms, e.g., inflections.
|
||||
These forms are accessible under dictionary keys for each form.
|
||||
The names of the forms are language-specific. They are assigned
|
||||
by the human translator of the corresponding language (in XX.po)
|
||||
as in the example above,
|
||||
see :meth:`~GrampsTranslations.lexgettext` docs
|
||||
for more info.
|
||||
|
||||
The translated format string can then refer to a specific form
|
||||
of the lexeme using ``.``:attr:`~Lexeme.f` and square brackets:
|
||||
``{holiday.f[GENITIVE]}``
|
||||
expects holiday to be a Lexeme which has a form ``'GENITIVE'`` in it.
|
||||
|
||||
An instance of Lexeme can also be used as a regular unicode string.
|
||||
In this case, the work will be delegated to the string for the very
|
||||
first form provided in the translated string. In the example above,
|
||||
``{holiday}`` in the translated string will expand to the Russian
|
||||
nominative form for Christmas, and ``xmas.upper()`` will produce
|
||||
the same nominative form in capital letters.
|
||||
|
||||
.. rubric:: Motivation
|
||||
Lexeme is the term used in linguistics for the set of forms taken
|
||||
by a particular word, e.g. cases for a noun or tenses for a verb.
|
||||
|
||||
Gramps often needs to compose sentences from several blocks of
|
||||
text and single words, often by using python string formatting.
|
||||
|
||||
For instance, formatting a date range is done similarly to this:
|
||||
::
|
||||
_("Between {startdate_month} {startdate_year}"
|
||||
"and {enddate_month} {enddate_year}").format(
|
||||
startdate_month = m1,
|
||||
startdate_year = y1,
|
||||
enddate_month = m2,
|
||||
enddate_year = y2)
|
||||
|
||||
To make such text translatable, the arguments injected into
|
||||
format string need to bear all the linguistical information
|
||||
on how to plug them into a sentence, i.e., the forms, depending
|
||||
on the linguistic context of where the argument appears.
|
||||
The format string needs to select the relevant linguistic form.
|
||||
This is why ``m1`` and ``m2`` are instances of :class:`~Lexeme`.
|
||||
|
||||
On the other hand, for languages where there is no linguistic
|
||||
variation in such sentences, the code needs not to be aware of
|
||||
the underlying :class:`~Lexeme` complexity;
|
||||
and so they can be processed just like simple strings
|
||||
both when passed around in the code and when formatted.
|
||||
"""
|
||||
|
||||
def __new__(cls, iterable, *args, **kwargs):
|
||||
if _isstring(iterable):
|
||||
newobj = _LexemeBaseStr.__new__(cls, iterable, *args, **kwargs)
|
||||
else:
|
||||
od = collections.OrderedDict(iterable)
|
||||
l = list(od.values()) or [""]
|
||||
newobj = _LexemeBaseStr.__new__(cls, l[0], *args, **kwargs)
|
||||
newobj._forms = od
|
||||
return newobj
|
||||
|
||||
def variants(self):
|
||||
"""All lexeme forms, in the same order as given upon construction.
|
||||
The first one returned is the default form, which is used when the
|
||||
Lexeme instance is used in lieu of a string object.
|
||||
|
||||
Same as ``f.values()``"""
|
||||
return self._forms.values()
|
||||
|
||||
@property
|
||||
def f(self):
|
||||
"""Dictionary of the lexeme forms"""
|
||||
return self._forms
|
||||
|
||||
class GrampsTranslations(gettext.GNUTranslations):
|
||||
"""
|
||||
Overrides and extends gettext.GNUTranslations. See the Python gettext
|
||||
@ -950,6 +1075,7 @@ class GrampsTranslations(gettext.GNUTranslations):
|
||||
def gettext(self, msgid):
|
||||
"""
|
||||
Obtain translation of gettext, return a unicode object
|
||||
|
||||
:param msgid: The string to translated.
|
||||
:type msgid: unicode
|
||||
:returns: Translation or the original.
|
||||
@ -1009,6 +1135,32 @@ class GrampsTranslations(gettext.GNUTranslations):
|
||||
msgval = msgid[sep_idx+1:]
|
||||
return msgval
|
||||
|
||||
def lexgettext(self, msgid):
|
||||
"""
|
||||
Extract all inflections of the same lexeme,
|
||||
stripping the '|'-separated context using :meth:`~sgettext`
|
||||
|
||||
The *resulting* message provided by the translator
|
||||
is supposed to be '|'-separated as well.
|
||||
The possible formats are either (1) a single string
|
||||
for a language with no inflections, or (2) a list of
|
||||
<inflection name>=<inflected form>, separated with '|'.
|
||||
For example:
|
||||
|
||||
(1) "Uninflectable"
|
||||
(2) "n=Inflected-nominative|g=Inflected-genitive|d=Inflected-dative"
|
||||
|
||||
See :class:`~Lexeme` documentation for detailed explanation and example.
|
||||
|
||||
:param msgid: The string to translated.
|
||||
:type msgid: unicode
|
||||
:returns: Translation or the original with context stripped.
|
||||
:rtype: unicode (for option (1)) / Lexeme (option (2))
|
||||
"""
|
||||
variants = self.sgettext(msgid).split('|')
|
||||
return Lexeme([v.split('=') for v in variants]
|
||||
) if len(variants) > 1 else variants[0]
|
||||
|
||||
class GrampsNullTranslations(gettext.NullTranslations):
|
||||
"""
|
||||
Extends gettext.NullTranslations to provide the sgettext method.
|
||||
@ -1023,6 +1175,8 @@ class GrampsNullTranslations(gettext.NullTranslations):
|
||||
msgval = msgid[sep_idx+1:]
|
||||
return msgval
|
||||
|
||||
lexgettext = sgettext
|
||||
|
||||
def language(self):
|
||||
"""
|
||||
The null translation returns the raw msgids, which are in English
|
||||
|
126
gramps/gen/utils/test/grampslocale_test.py
Normal file
126
gramps/gen/utils/test/grampslocale_test.py
Normal file
@ -0,0 +1,126 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
#
|
||||
# Gramps - a GTK+/GNOME based genealogy program
|
||||
#
|
||||
# Copyright (C) 2013 Vassilii Khachaturov
|
||||
#
|
||||
# This program is free software; you can redistribute it and/or modify
|
||||
# it under the terms of the GNU General Public License as published by
|
||||
# the Free Software Foundation; either version 2 of the License, or
|
||||
# (at your option) any later version.
|
||||
#
|
||||
# This program is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# GNU General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU General Public License
|
||||
# along with this program; if not, write to the Free Software
|
||||
# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
#
|
||||
|
||||
# $Id$
|
||||
|
||||
from __future__ import print_function, unicode_literals
|
||||
|
||||
import unittest
|
||||
import sys
|
||||
|
||||
try:
|
||||
if sys.version_info < (3,3):
|
||||
from mock import Mock
|
||||
else:
|
||||
from unittest.mock import Mock
|
||||
|
||||
MOCKING = True
|
||||
|
||||
except:
|
||||
MOCKING = False
|
||||
print ("Mocking disabled, some testing skipped", sys.exc_info()[0:2])
|
||||
|
||||
class LexGettextTest(unittest.TestCase):
|
||||
SRC_WORD = "Inflect-me"
|
||||
MSGID = "how-to-use-lexgettext||" + SRC_WORD
|
||||
|
||||
def setUp(self):
|
||||
from ..grampslocale import GrampsTranslations
|
||||
from ..grampslocale import GrampsLocale as Loc
|
||||
self.trans = GrampsTranslations()
|
||||
|
||||
def setup_sgettext_mock(self, msgval_expected):
|
||||
if MOCKING:
|
||||
mock = Mock(return_value=msgval_expected)
|
||||
else:
|
||||
mock = lambda msgid: msgval_expected
|
||||
self.trans.sgettext = mock
|
||||
|
||||
def tearDown(self):
|
||||
if MOCKING:
|
||||
try:
|
||||
self.trans.sgettext.assert_called_once_with(
|
||||
self.MSGID)
|
||||
except AttributeError as e:
|
||||
print ("Apparently the test has never set up the mock: ", e)
|
||||
|
||||
def testSrcWordOnlyIfNoTranslation(self):
|
||||
self.setup_sgettext_mock(self.SRC_WORD)
|
||||
result = self.trans.lexgettext(self.MSGID)
|
||||
self.assertEqual(result, self.SRC_WORD)
|
||||
|
||||
def test3InflectionsExtractableByNameThroughForm(self):
|
||||
translated = "n=TargetNom|g=TargetGen|d=TargetDat"
|
||||
self.setup_sgettext_mock(translated)
|
||||
lex = self.trans.lexgettext(self.MSGID)
|
||||
formatted = "{lex.f[n]},{lex.f[g]},{lex.f[d]}".format(lex=lex)
|
||||
self.assertEqual(formatted, "TargetNom,TargetGen,TargetDat")
|
||||
|
||||
def testFirstLexemeFormExtractableAsDefaultString(self):
|
||||
translated = "def=Default|v1=Option1|a=AnotherOption"
|
||||
self.setup_sgettext_mock(translated)
|
||||
lex = self.trans.lexgettext(self.MSGID)
|
||||
formatted = "{}".format(lex)
|
||||
self.assertEqual(formatted, "Default")
|
||||
|
||||
class LexemeTest(unittest.TestCase):
|
||||
def setUp(self):
|
||||
from ..grampslocale import Lexeme
|
||||
self.lex = Lexeme((('a', 'aaa'), ('b', 'bbb'), ('c', 'ccc')))
|
||||
self.zlex = Lexeme({'z' : 'zzz'})
|
||||
self.elex = Lexeme({})
|
||||
|
||||
def testIsHashable(self):
|
||||
hash(self.lex) # throws if not hashable
|
||||
|
||||
# test delegation to an arbitrary string method pulled in from unicode
|
||||
def testDefaultStringStartsWithAA(self):
|
||||
self.assertTrue(self.lex.startswith('aa'),
|
||||
msg="default string: {} dict: {}".format(
|
||||
self.lex, self.lex.__dict__))
|
||||
|
||||
def testCanConcatenateStringAndLexeme(self):
|
||||
moo = "moo"
|
||||
self.assertEqual(moo + self.lex, "mooaaa")
|
||||
|
||||
def testCanConcatenateStringAndLexemeInPlace(self):
|
||||
moo = "moo"
|
||||
moo += self.lex
|
||||
self.assertEqual(moo, "mooaaa")
|
||||
|
||||
def testCanConcatenateLexemeAndStringInPlace(self):
|
||||
moo = "moo"
|
||||
self.lex += moo
|
||||
self.assertEqual(self.lex, "aaamoo")
|
||||
|
||||
def testCanConcatenateTwoLexemes(self):
|
||||
aaazzz = self.lex + self.zlex
|
||||
self.assertEqual(aaazzz, "aaazzz")
|
||||
|
||||
def testCanJoinTwoLexemes(self):
|
||||
aaa_zzz = "_".join([self.lex,self.zlex])
|
||||
self.assertEqual(aaa_zzz, "aaa_zzz")
|
||||
|
||||
def testEmptyIterableLikeEmptyString(self):
|
||||
self.assertEqual(self.elex, "")
|
||||
|
||||
if __name__ == "__main__":
|
||||
unittest.main()
|
@ -194,7 +194,13 @@ class Calendar(Report):
|
||||
self.doc.draw_box("CAL-Title", "", 0, 0, width, header, mark)
|
||||
self.doc.draw_line("CAL-Border", 0, header, width, header)
|
||||
year = self.year
|
||||
title = "%s %d" % (_dd.long_months[month].capitalize(), year)
|
||||
# TRANSLATORS: see
|
||||
# http://gramps-project.org/wiki/index.php?title=Translating_Gramps#Translating_dates
|
||||
# to learn how to select proper inflection for your language.
|
||||
title = _("{long_month} {year}").format(
|
||||
long_month = _dd.long_months[month],
|
||||
year = year
|
||||
).capitalize()
|
||||
mark = IndexMark(title, INDEX_TYPE_TOC, 2)
|
||||
font_height = pt2cm(ptitle.get_font().get_size())
|
||||
self.doc.center_text("CAL-Title", title,
|
||||
|
@ -41,7 +41,7 @@ import copy
|
||||
#
|
||||
#------------------------------------------------------------------------
|
||||
from gramps.gen.const import GRAMPS_LOCALE as glocale
|
||||
_ = glocale.translation.gettext
|
||||
_ = glocale.translation.sgettext
|
||||
from gramps.gen.plug.menu import (PersonOption, FilterOption,
|
||||
EnumeratedListOption)
|
||||
from gramps.gen.plug.report import Report
|
||||
@ -71,8 +71,8 @@ cal = config.get('preferences.calendar-format-report')
|
||||
#------------------------------------------------------------------------
|
||||
def _get_sort_functions(sort):
|
||||
return [
|
||||
(_("Birth Date"),sort.by_birthdate_key),
|
||||
(_("Name"),sort.by_last_name_key),
|
||||
(_("sorted by|Birth Date"),sort.by_birthdate_key),
|
||||
(_("sorted by|Name"),sort.by_last_name_key),
|
||||
]
|
||||
|
||||
#------------------------------------------------------------------------
|
||||
|
@ -1703,7 +1703,10 @@ def get_day_list(event_date, holiday_list, bday_anniv_list):
|
||||
if event == 'Birthday':
|
||||
|
||||
txt_str = (text + ', <em>'
|
||||
+ (_('%s old') % str(age_str) if nyears else _('birth'))
|
||||
# TRANSLATORS: expands to smth like "12 years old",
|
||||
# where "12 years" is already localized to your language
|
||||
+ (_('%s old') % str(age_str)
|
||||
if nyears else _('birth'))
|
||||
+ '</em>')
|
||||
|
||||
# an anniversary
|
||||
|
Loading…
Reference in New Issue
Block a user