From cfd2c3f5a8e1b4ac65e50998da7f0b8d6df83966 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sveinn=20=C3=AD=20Felli?= Date: Sun, 21 Feb 2016 14:29:07 +0100 Subject: [PATCH] Add dates and relationships handlers for Icelandic --- gramps/gen/datehandler/__init__.py | 1 + gramps/gen/datehandler/_date_is.py | 180 +++++++++++++++++ gramps/gen/datehandler/_datehandler.py | 2 + gramps/plugins/rel/rel_is.py | 267 +++++++++++++++++++++++++ gramps/plugins/rel/relplugins.gpr.py | 13 ++ 5 files changed, 463 insertions(+) create mode 100644 gramps/gen/datehandler/_date_is.py create mode 100644 gramps/plugins/rel/rel_is.py diff --git a/gramps/gen/datehandler/__init__.py b/gramps/gen/datehandler/__init__.py index f565455b0..ca0ca473a 100644 --- a/gramps/gen/datehandler/__init__.py +++ b/gramps/gen/datehandler/__init__.py @@ -49,6 +49,7 @@ from . import _date_fi from . import _date_fr from . import _date_hr from . import _date_hu +from . import _date_is from . import _date_it from . import _date_ja from . import _date_lt diff --git a/gramps/gen/datehandler/_date_is.py b/gramps/gen/datehandler/_date_is.py new file mode 100644 index 000000000..5bdd8b854 --- /dev/null +++ b/gramps/gen/datehandler/_date_is.py @@ -0,0 +1,180 @@ +# -*- coding: utf-8 -*- +# +# Gramps - a GTK+/GNOME based genealogy program +# +# Copyright (C) 2004-2006 Donald N. Allingham +# +# 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. +# +# Attempt to parse dates for Icelandic, Sveinn í Felli 2016 + +""" +Icelandic-specific classes for parsing and displaying dates. +""" + +#------------------------------------------------------------------------- +# +# Python modules +# +#------------------------------------------------------------------------- +import re + +#------------------------------------------------------------------------- +# +# GRAMPS modules +# +#------------------------------------------------------------------------- +from ..lib.date import Date +from ._dateparser import DateParser +from ._datedisplay import DateDisplay +from ._datehandler import register_datehandler + +#------------------------------------------------------------------------- +# +# Icelandic parser class +# +#------------------------------------------------------------------------- +class DateParserIs(DateParser): + """ + Convert a text string into a Date object, expecting a date + notation in the Icelandic language. If the date cannot be converted, + the text string is assigned. + """ + + # modifiers before the date + modifier_to_int = { + 'fyrir' : Date.MOD_BEFORE, + 'á undan' : Date.MOD_BEFORE, + 'eftir' : Date.MOD_AFTER, + 'í kringum' : Date.MOD_ABOUT, + 'uþb' : Date.MOD_ABOUT + } + + bce = ["f Kr"] + + calendar_to_int = { + 'gregoríanskt ' : Date.CAL_GREGORIAN, + 'g' : Date.CAL_GREGORIAN, + 'júlíanskt' : Date.CAL_JULIAN, + 'j' : Date.CAL_JULIAN, + 'hebreskt' : Date.CAL_HEBREW, + 'h' : Date.CAL_HEBREW, + 'íslamskt' : Date.CAL_ISLAMIC, + 'múslimskt' : Date.CAL_ISLAMIC, + 'i' : Date.CAL_ISLAMIC, + 'franskt' : Date.CAL_FRENCH, + 'franska lýðveldisins' : Date.CAL_FRENCH, + 'f' : Date.CAL_FRENCH, + 'persneskt' : Date.CAL_PERSIAN, + 'p' : Date.CAL_PERSIAN, + 'sænskt' : Date.CAL_SWEDISH, + 's' : Date.CAL_SWEDISH, + } + + quality_to_int = { + 'áætlað' : Date.QUAL_ESTIMATED, + 'reiknað' : Date.QUAL_CALCULATED, + } + + def init_strings(self): + DateParser.init_strings(self) + self._span = re.compile("(frá)?\s*(?P.+)\s*(til|--|–)\s*(?P.+)", + re.IGNORECASE) + self._range = re.compile("(milli)\s+(?P.+)\s+og\s+(?P.+)", + re.IGNORECASE) + +#------------------------------------------------------------------------- +# +# Icelandic display class +# +#------------------------------------------------------------------------- +class DateDisplayIs(DateDisplay): + """ + Icelandic language date display class. + """ + + long_months = ( "", "janúar", "febrúar", "mars", "apríl", "maí", + "júní", "júlí", "ágúst", "september", "október", + "nóvember", "desember" ) + + short_months = ( "", "jan", "feb", "mar", "apr", "maí", "jún", + "júl", "ágú", "sep", "okt", "nóv", "des" ) + + formats = ( + "ÁÁÁÁ-MM-DD (ISO)", + "Tölulegt", + "Mánuður dagur, ár", + "Mán Dag Ár", + "Dagur mánuður ár", + "Dag Mán Ár", + ) + # this must agree with DateDisplayEn's "formats" definition + # (since no locale-specific _display_gregorian exists, here) + + calendar = ( + "", + "júlíanskt", + "hebreskt", + "franska lýðveldisins", + "persneskt", + "íslamskt", + "sænskt" + ) + + _mod_str = ("", "fyrir ", "eftir ", "uþb ", "", "", "") + + _qual_str = ("", "reiknað ", "reiknað ") + + _bce_str = "%s f. Kr" + + 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 "%sfrá %s til %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 "%smilli %s og %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) + +#------------------------------------------------------------------------- +# +# Register classes +# +#------------------------------------------------------------------------- +register_datehandler(('is_IS', 'is', 'íslenskt', 'Icelandic'), DateParserIs, DateDisplayIs) diff --git a/gramps/gen/datehandler/_datehandler.py b/gramps/gen/datehandler/_datehandler.py index 558251e14..d6ccb257d 100644 --- a/gramps/gen/datehandler/_datehandler.py +++ b/gramps/gen/datehandler/_datehandler.py @@ -85,6 +85,8 @@ LANG_TO_DISPLAY = { 'English_United States' : DateDisplayEn, 'ko_KR' : DateDisplay, 'nb_NO' : DateDisplay, + 'is' : DateDisplay, + 'is_IS' : DateDisplay, } def register_datehandler(locales,parse_class,display_class): diff --git a/gramps/plugins/rel/rel_is.py b/gramps/plugins/rel/rel_is.py new file mode 100644 index 000000000..a5bfd3101 --- /dev/null +++ b/gramps/plugins/rel/rel_is.py @@ -0,0 +1,267 @@ +# -*- coding: utf-8 -*- +# +# Gramps - a GTK+/GNOME based genealogy program +# +# Copyright (C) 2003-2005 Donald N. Allingham +# Copyright (C) 2008 Brian G. Matherly +# Copyright (C) 2010 Andrew I Baznikin +# +# 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. +# + +# Written by Alex Roitman, largely based on relationship.py by Don Allingham +# and on valuable input from Frode Jemtland +# Tilraun til aðlögunar: Sveinn í Felli, 02/2016 +""" +Icelandic-Specific classes for relationships. +""" + +#------------------------------------------------------------------------- +# +# GRAMPS modules +# +#------------------------------------------------------------------------- + +from gramps.gen.lib import Person +import gramps.gen.relationship + +#------------------------------------------------------------------------- + +_cousin_level = [ "", "", #brother/sister, frændi/frænka -- these are taken care of separately +"þremenningur", "fjórmenningur", "fimmmenningur", +"sexmenningur", "sjömenningur", "áttmenningur", +"nímenningur", "tímenningur", "ellefumenningur", +"tólfmenningur", "þrettánmenningur", "fjórtánmenningur", +"fimtánmenningur", "sekstenmenning", "syttenmenning", +"attenmenning", "nittenmenning", "tyvemenning" ] + +_cousin_terms = _cousin_level + ["frændi", "frænka"] +#------------------------------------------------------------------------- +# +# +# +#------------------------------------------------------------------------- +class RelationshipCalculator(gramps.gen.relationship.RelationshipCalculator): + """ + RelationshipCalculator Class + """ + + def __init__(self): + gramps.gen.relationship.RelationshipCalculator.__init__(self) + + def get_parents(self, level): + if level == 0: + return "foreldri" + else: + return "forfaðir í %d-tu kynslóð" % (level+1) + + def get_cousin(self, level): + if level > len(_cousin_level)-1: + # FIXME: use Norwegian term term here, + # UPDATED by Frode: unsure about the expretion "en fjern slektning", should it be just "fjern slektning". + # Need to see it used in the program to get the understanding. + return "fjarskyldur ættingi" + else: + return _cousin_level[level] + + def pair_up(self, rel_list): + result = [] + item = "" + for word in rel_list[:]: + if not word: + continue + if word in _cousin_terms: + if item: + result.append(item) + item = "" + result.append(word) + continue + if item: + if word == 'synir': + word = 'sonur' + result.append(item + word) + item = "" + else: + item = word + if item: + result.append(item) + gen_result = [ item + 's' for item in result[0:-1] ] + return ' '.join(gen_result+result[-1:]) + + def get_direct_ancestor(self, person, rel_string): + result = [] + for ix in range(len(rel_string)): + if rel_string[ix] == 'f': + result.append('faðir') + else: + result.append('móðir') + return self.pair_up(result) + + def get_direct_descendant(self, person, rel_string): + result = [] + for ix in range(len(rel_string)-2, -1, -1): + if rel_string[ix] == 'f': + result.append('synir') + else: + result.append('dætur') + if person == Person.MALE: + result.append('sonur') + else: + result.append('dóttir') + return self.pair_up(result) + + def get_ancestors_cousin(self, person, rel_string_long, rel_string_short): + result = [] + removed = len(rel_string_long)-len(rel_string_short) + level = len(rel_string_short)-1 + for ix in range(removed): + if rel_string_long[ix] == 'f': + result.append('faðir') + else: + result.append('móðir') + if level > 1: + result.append(self.get_cousin(level)) + elif person == Person.MALE: + result.append('frændi') + else: + result.append('frænka') + main_string = self.get_two_way_rel(person, rel_string_short, rel_string_long) + aux_string = self.pair_up(result) + return "%s (%s)" % (main_string, aux_string) + + def get_cousins_descendant(self, person, rel_string_long, rel_string_short): + result = [] + aux_string = "" + removed = len(rel_string_long)-len(rel_string_short)-1 + level = len(rel_string_short)-1 + if level > 1: # Cousin terms without gender + result.append(self.get_cousin(level)) + elif level == 1: # gender-dependent fetter/kusine + if rel_string_long[removed] == 'f': + result.append('fændi') + else: + result.append('frænka') + elif rel_string_long[removed] == 'f': + result.append('bróðir') + else: + result.append('systir') + for ix in range(removed-1, -1, -1): + if rel_string_long[ix] == 'f': + result.append('sonur') + else: + result.append('dóttir') + if person == Person.MALE: + result.append('sonur') + else: + result.append('dóttir') + main_string = self.get_two_way_rel(person, rel_string_long, rel_string_short) + if level: + aux_string = " (%s)" % self.pair_up(result) + return "%s%s" % (main_string, aux_string) + + def get_ancestors_brother(self, rel_string): + result = [] + for ix in range(len(rel_string)-1): + if rel_string[ix] == 'f': + result.append('föður') + else: + result.append('móður') + result.append('bróðir') + return self.pair_up(result) + + def get_ancestors_sister(self, rel_string): + result = [] + for ix in range(len(rel_string)-1): + if rel_string[ix] == 'f': + result.append('föður') + else: + result.append('móður') + result.append('systir') + return self.pair_up(result) + + def get_two_way_rel(self, person, first_rel_string, second_rel_string): + result = [] + for ix in range(len(second_rel_string)-1): + if second_rel_string[ix] == 'f': + result.append('föður') + else: + result.append('móður') + if len(first_rel_string)>1: + if first_rel_string[-2] == 'f': + result.append('bróðir') + else: + result.append('systir') + for ix in range(len(first_rel_string)-3, -1, -1): + if first_rel_string[ix] == 'f': + result.append('sønne') + else: + result.append('datter') + if person == Person.MALE: + result.append('sonur') + else: + result.append('dóttir') + else: + if person == Person.MALE: + result.append('bróðir') + else: + result.append('systir') + return self.pair_up(result) + + def get_relationship(self, + secondRel, firstRel, orig_person, other_person): + + common = "" + if not firstRel: + if not secondRel: + return ('', common) + else: + return (self.get_direct_ancestor(other_person, secondRel), common) + elif not secondRel: + return (self.get_direct_descendant(other_person, firstRel), common) + elif len(firstRel) == 1: + if other_person == Person.MALE: + return (self.get_ancestors_brother(secondRel), common) + else: + return (self.get_ancestors_sister(secondRel), common) + elif len(secondRel) >= len(firstRel): + return (self.get_ancestors_cousin(other_person, secondRel, firstRel), common) + else: + return (self.get_cousins_descendant(other_person, firstRel, secondRel), common) + + def get_single_relationship_string(self, Ga, Gb, gender_a, gender_b, + reltocommon_a, reltocommon_b, + only_birth=True, + in_law_a=False, in_law_b=False): + return self.get_relationship(reltocommon_a, reltocommon_b, gender_a, gender_b)[0]; + + def get_sibling_relationship_string(self, sib_type, gender_a, gender_b, + in_law_a=False, in_law_b=False): + return self.get_two_way_rel(gender_b, "", "") + +if __name__ == "__main__": + + # Test function. Call it as follows from the command line (so as to find + # imported modules): + # export PYTHONPATH=/path/to/gramps/src + # python src/plugins/rel/rel_no.py + # (Above not needed here) + + """TRANSLATORS, copy this if statement at the bottom of your + rel_xx.py module, and test your work with: + python src/plugins/rel/rel_xx.py + """ + from gramps.gen.relationship import test + RC = RelationshipCalculator() + test(RC, True) diff --git a/gramps/plugins/rel/relplugins.gpr.py b/gramps/plugins/rel/relplugins.gpr.py index 836963d1b..2d58236d2 100644 --- a/gramps/plugins/rel/relplugins.gpr.py +++ b/gramps/plugins/rel/relplugins.gpr.py @@ -158,6 +158,19 @@ plg.ptype = RELCALC plg.relcalcclass = 'RelationshipCalculator' plg.lang_list = ["hu", "HU", "hu_HU", "hu_HU.utf8", "hu_HU.UTF8"] +# is +plg = newplugin() +plg.id = 'relcalc_is' +plg.name = _("Icelandic Relationship Calculator") +plg.description = _("Calculates relationships between people") +plg.version = '1.0' +plg.gramps_target_version = MODULE_VERSION +plg.status = STABLE +plg.fname = 'rel_is.py' +plg.ptype = RELCALC +plg.relcalcclass = 'RelationshipCalculator' +plg.lang_list = ["is", "IS", "is_IS", "is_IS@euro", "is_IS.utf8"] + # it plg = newplugin() plg.id = 'relcalc_it'