0005620: Export name types to GEDCOM. Patch extended following testing against various GEDCOM files from the internet.
svn: r19054
This commit is contained in:
parent
44667f7f13
commit
73be67b3f8
@ -1257,6 +1257,14 @@ class GedcomWriter(UpdateCallback):
|
||||
nick = attr_nick
|
||||
|
||||
self.__writeln(1, 'NAME', gedcom_name)
|
||||
if int(name.get_type()) == gen.lib.NameType.BIRTH:
|
||||
pass
|
||||
elif int(name.get_type()) == gen.lib.NameType.MARRIED:
|
||||
self.__writeln(2, 'TYPE', 'married')
|
||||
elif int(name.get_type()) == gen.lib.NameType.AKA:
|
||||
self.__writeln(2, 'TYPE', 'aka')
|
||||
else:
|
||||
self.__writeln(2, 'TYPE', name.get_type().xml_str())
|
||||
|
||||
if firstname:
|
||||
self.__writeln(2, 'GIVN', firstname)
|
||||
|
@ -255,6 +255,8 @@ TOKEN_WWW = 125
|
||||
TOKEN_URL = 126
|
||||
TOKEN_ROLE = 127
|
||||
TOKEN__MAR = 128
|
||||
TOKEN__MARN = 129
|
||||
TOKEN__ADPN = 130
|
||||
|
||||
TOKENS = {
|
||||
"HEAD" : TOKEN_HEAD, "MEDI" : TOKEN_MEDI,
|
||||
@ -268,6 +270,7 @@ TOKENS = {
|
||||
"ADDRESS2" : TOKEN_ADR2, "AFN" : TOKEN_AFN,
|
||||
"AGE" : TOKEN_AGE, "AGNC" : TOKEN_AGNC,
|
||||
"AGENCY" : TOKEN_IGNORE, "_AKA" : TOKEN__AKA,
|
||||
"_AKAN" : TOKEN__AKA, "AKA" : TOKEN__AKA,
|
||||
"_ALIA" : TOKEN_ALIA, "ALIA" : TOKEN_ALIA,
|
||||
"ALIAS" : TOKEN_ALIA, "ANCI" : TOKEN_ANCI,
|
||||
"ASSO" : TOKEN_ASSO, "ASSOCIATES" : TOKEN_ASSO,
|
||||
@ -358,7 +361,8 @@ TOKENS = {
|
||||
"FACT" : TOKEN_FACT, "EMAIL" : TOKEN_EMAIL,
|
||||
"EMAI" : TOKEN_EMAIL, "WWW" : TOKEN_WWW,
|
||||
"_URL" : TOKEN_URL, "URL" : TOKEN_URL,
|
||||
"_MAR" : TOKEN__MAR,
|
||||
"_MAR" : TOKEN__MAR, "_MARN" : TOKEN__MARN,
|
||||
"_ADPN" : TOKEN__ADPN
|
||||
}
|
||||
|
||||
ADOPT_NONE = 0
|
||||
@ -1928,7 +1932,7 @@ class GedcomParser(UpdateCallback):
|
||||
# +1 REFN <USER_REFERENCE_NUMBER> {0:M}
|
||||
# +2 TYPE <USER_REFERENCE_TYPE> {0:1}
|
||||
TOKEN_REFN : self.__person_attr,
|
||||
# TYPE should be eblow REFN, but will work here anyway
|
||||
# TYPE should be below REFN, but will work here anyway
|
||||
TOKEN_TYPE : self.__person_attr,
|
||||
# +1 RIN <AUTOMATED_RECORD_ID> {0:1}
|
||||
TOKEN_RIN : self.__person_attr,
|
||||
@ -1964,10 +1968,18 @@ class GedcomParser(UpdateCallback):
|
||||
# Extensions
|
||||
TOKEN_ALIA : self.__name_alia,
|
||||
TOKEN__MARNM : self.__name_marnm,
|
||||
TOKEN__MAR : self.__name_marnm, # Generated by gni.com
|
||||
TOKEN__AKA : self.__name_aka,
|
||||
TOKEN_TYPE : self.__name_type,
|
||||
TOKEN__MAR : self.__name_marnm, # Generated by geni.com
|
||||
TOKEN__MARN : self.__name_marnm, # Gen'd by BROSKEEP 6.1.31 WIN
|
||||
TOKEN__AKA : self.__name_aka, # PAF and AncestQuest
|
||||
TOKEN_TYPE : self.__name_type, # This is legal GEDCOM 5.5.1
|
||||
TOKEN_BIRT : self.__ignore,
|
||||
TOKEN_DATE : self.__name_date,
|
||||
# This handles date as a subsidiary of "1 ALIA" which might be used
|
||||
# by Family Tree Maker and Reunion, and by cheating (handling a
|
||||
# lower level from the current parse table) handles date as
|
||||
# subsidiary to "2 _MARN", "2 _AKAN" and "2 _ADPN" which has been
|
||||
# found in Brother's keeper.
|
||||
TOKEN__ADPN : self.__name_adpn,
|
||||
}
|
||||
|
||||
#
|
||||
@ -3143,8 +3155,13 @@ class GedcomParser(UpdateCallback):
|
||||
@param state: The current state
|
||||
@type state: CurrentState
|
||||
"""
|
||||
# We can get here when a tag that is not valid in the indi_parse_tbl
|
||||
# parse table is encountered. It is remotely possible that this is
|
||||
# actally a DATE tag, in which case line.data will be a date object, so
|
||||
# we need to convert it back to a string here.
|
||||
event_ref = self.__build_event_pair(state, gen.lib.EventType.CUSTOM,
|
||||
self.event_parse_tbl, line.data)
|
||||
self.event_parse_tbl,
|
||||
str(line.data))
|
||||
state.person.add_event_ref(event_ref)
|
||||
|
||||
def __fam_even(self, line, state):
|
||||
@ -3184,14 +3201,41 @@ class GedcomParser(UpdateCallback):
|
||||
|
||||
def __person_alt_name(self, line, state):
|
||||
"""
|
||||
This parses the standard GEDCOM structure:
|
||||
|
||||
n @XREF:INDI@ INDI {1:1}
|
||||
+1 ALIA @<XREF:INDI>@ {0:M}
|
||||
|
||||
The ALIA tag is supposed to cross reference another person. We will
|
||||
store this in the Association record.
|
||||
|
||||
ALIA {ALIAS}: = An indicator to link different record descriptions of a
|
||||
person who may be the same person.
|
||||
|
||||
Some systems use the ALIA tag as an alternate NAME tag, which
|
||||
is not legal in GEDCOM, but oddly enough, is easy to support.
|
||||
|
||||
Some systems use the ALIA tag as an alternate NAME tag, which is not
|
||||
legal in GEDCOM, but oddly enough, is easy to support. This parses the
|
||||
illegal (ALIA or ALIAS) or non-standard (_ALIA) GEDCOM. "1 ALIA" is used
|
||||
by Family Tree Maker and Reunion. "1 ALIAS" and "1 _ALIA" do not appear
|
||||
to be used.
|
||||
|
||||
n @XREF:INDI@ INDI {1:1}
|
||||
+1 <ALIA> <NAME_PERSONAL> {1:1}
|
||||
+2 NPFX <NAME_PIECE_PREFIX> {0:1}
|
||||
+2 GIVN <NAME_PIECE_GIVEN> {0:1}
|
||||
+2 NICK <NAME_PIECE_NICKNAME> {0:1}
|
||||
+2 SPFX <NAME_PIECE_SURNAME_PREFIX> {0:1}
|
||||
+2 SURN <NAME_PIECE_SURNAME> {0:1}
|
||||
+2 NSFX <NAME_PIECE_SUFFIX> {0:1}
|
||||
+2 <<SOURCE_CITATION>> {0:M}
|
||||
+3 <<NOTE_STRUCTURE>> {0:M}
|
||||
+3 <<MULTIMEDIA_LINK>> {0:M}
|
||||
+2 <<NOTE_STRUCTURE>> {0:M}
|
||||
where <ALIA> == ALIA | _ALIA | ALIAS
|
||||
|
||||
@param line: The current line in GedLine format
|
||||
@type line: GedLine
|
||||
@param state: The current state
|
||||
@type state: CurrentState
|
||||
"""
|
||||
if line.data[0] == '@':
|
||||
handle = self.__find_person_handle(self.pid_map[line.data])
|
||||
@ -3204,11 +3248,23 @@ class GedcomParser(UpdateCallback):
|
||||
|
||||
def __parse_alias_name(self, line, state):
|
||||
"""
|
||||
Parse a altername name, usually indicated by a AKA or _AKA
|
||||
tag. This is not valid GEDCOM, but several programs will add
|
||||
this just to make life interesting. Odd, since GEDCOM supports
|
||||
multiple NAME indicators, which is the correct way of handling
|
||||
multiple names.
|
||||
Parse a level 1 alias name and subsidiary levels when called from
|
||||
__person_alt_name (when the <NAME_PERSONAL> does not start with @). Also
|
||||
parses a level 2 alias name and subsidiary levels when called from
|
||||
__name_alias.
|
||||
|
||||
+1 <ALIA> <NAME_PERSONAL> {1:1}
|
||||
+2 NPFX <NAME_PIECE_PREFIX> {0:1}
|
||||
+2 GIVN <NAME_PIECE_GIVEN> {0:1}
|
||||
+2 NICK <NAME_PIECE_NICKNAME> {0:1}
|
||||
+2 SPFX <NAME_PIECE_SURNAME_PREFIX> {0:1}
|
||||
+2 SURN <NAME_PIECE_SURNAME> {0:1}
|
||||
+2 NSFX <NAME_PIECE_SUFFIX> {0:1}
|
||||
+2 <<SOURCE_CITATION>> {0:M}
|
||||
+3 <<NOTE_STRUCTURE>> {0:M}
|
||||
+3 <<MULTIMEDIA_LINK>> {0:M}
|
||||
+2 <<NOTE_STRUCTURE>> {0:M}
|
||||
where <ALIA> == ALIA | _ALIA | ALIAS
|
||||
|
||||
@param line: The current line in GedLine format
|
||||
@type line: GedLine
|
||||
@ -3595,11 +3651,23 @@ class GedcomParser(UpdateCallback):
|
||||
@param state: The current state
|
||||
@type state: CurrentState
|
||||
"""
|
||||
if line.data == "_OTHN":
|
||||
if line.data.upper() in ("_OTHN", "_AKA", "AKA", "AKAN"):
|
||||
state.name.set_type(gen.lib.NameType.AKA)
|
||||
elif line.data.upper() in ("_MAR", "_MARN", "_MARNM", "MARRIED"):
|
||||
state.name.set_type(gen.lib.NameType.MARRIED)
|
||||
else:
|
||||
state.name.set_type((gen.lib.NameType.CUSTOM, line.data))
|
||||
|
||||
def __name_date(self, line, state):
|
||||
"""
|
||||
@param line: The current line in GedLine format
|
||||
@type line: GedLine
|
||||
@param state: The current state
|
||||
@type state: CurrentState
|
||||
"""
|
||||
if state.name:
|
||||
state.name.set_date_object(line.data)
|
||||
|
||||
def __name_note(self, line, state):
|
||||
"""
|
||||
@param line: The current line in GedLine format
|
||||
@ -3611,27 +3679,46 @@ class GedcomParser(UpdateCallback):
|
||||
|
||||
def __name_alia(self, line, state):
|
||||
"""
|
||||
This handles the ALIA (or _ALIA or ALIAS) tag as a subsidiary of the
|
||||
NAME tag. For example:
|
||||
This parses the illegal (ALIA or ALIAS) or non-standard (_ALIA) GEDCOM
|
||||
tag as a subsidiary of the NAME tag.
|
||||
|
||||
0 @PERSON1@ INDI
|
||||
1 NAME John /Doe/
|
||||
2 GIVN John
|
||||
2 SURN Doe
|
||||
2 ALIA Richard /Roe/
|
||||
2 NPFX Dr.
|
||||
2 GIVN Richard
|
||||
2 NICK Rich
|
||||
2 SPFX Le
|
||||
|
||||
n @XREF:INDI@ INDI {1:1}
|
||||
+1 NAME <NAME_PERSONAL> {1:1}
|
||||
+2 NPFX <NAME_PIECE_PREFIX> {0:1}
|
||||
+2 GIVN <NAME_PIECE_GIVEN> {0:1}
|
||||
+2 NICK <NAME_PIECE_NICKNAME> {0:1}
|
||||
+2 SPFX <NAME_PIECE_SURNAME_PREFIX> {0:1}
|
||||
+2 SURN <NAME_PIECE_SURNAME> {0:1}
|
||||
+2 NSFX <NAME_PIECE_SUFFIX> {0:1}
|
||||
+2 <ALIA> <NAME_PERSONAL> {1:1}
|
||||
+3 NPFX <NAME_PIECE_PREFIX> {0:1}
|
||||
+3 GIVN <NAME_PIECE_GIVEN> {0:1}
|
||||
+3 NICK <NAME_PIECE_NICKNAME> {0:1}
|
||||
+3 SPFX <NAME_PIECE_SURNAME_PREFIX> {0:1}
|
||||
+3 SURN <NAME_PIECE_SURNAME> {0:1}
|
||||
+3 NSFX <NAME_PIECE_SUFFIX> {0:1}
|
||||
+3 <<SOURCE_CITATION>> {0:M}
|
||||
+4 <<NOTE_STRUCTURE>> {0:M}
|
||||
+4 <<MULTIMEDIA_LINK>> {0:M}
|
||||
+3 <<NOTE_STRUCTURE>> {0:M}
|
||||
+2 <<SOURCE_CITATION>> {0:M}
|
||||
+3 <<NOTE_STRUCTURE>> {0:M}
|
||||
+3 <<MULTIMEDIA_LINK>> {0:M}
|
||||
+2 <<NOTE_STRUCTURE>> {0:M}
|
||||
|
||||
Note that the subsidiary name structure detail will overwrite the ALIA
|
||||
name (if the same elements are provided in both), so the names should
|
||||
match.
|
||||
|
||||
There does not appear to be any evidence that this usage exists, but as
|
||||
it was supported (though probably incorrectly coded as it would only
|
||||
work if the name started with'@'), in previous versions of Gramps, we
|
||||
had better support it here.
|
||||
"2 _ALIA" is used for example, by PRO-GEN v 3.0a and "2 ALIA" is used
|
||||
by GTEdit and Brother's keeper 5.2 for windows. It had been supported in
|
||||
previous versions of Gramps but as it was probably incorrectly coded as
|
||||
it would only work if the name started with '@'.
|
||||
|
||||
@param line: The current line in GedLine format
|
||||
@type line: GedLine
|
||||
@param state: The current state
|
||||
@type state: CurrentState
|
||||
"""
|
||||
self.__parse_alias_name(line, state)
|
||||
|
||||
@ -3689,6 +3776,16 @@ class GedcomParser(UpdateCallback):
|
||||
|
||||
def __name_marnm(self, line, state):
|
||||
"""
|
||||
This is non-standard GEDCOM. _MARNM is reported to be used in Ancestral
|
||||
Quest and Personal Ancestral File 5. This will also handle a usage which
|
||||
has been found in Brother's Keeper (BROSKEEP VERS 6.1.31 WINDOWS) as
|
||||
follows:
|
||||
|
||||
0 @I203@ INDI
|
||||
1 NAME John Richard/Doe/
|
||||
2 _MARN Some Other Name
|
||||
3 DATE 27 JUN 1817
|
||||
|
||||
@param line: The current line in GedLine format
|
||||
@type line: GedLine
|
||||
@param state: The current state
|
||||
@ -3737,6 +3834,22 @@ class GedcomParser(UpdateCallback):
|
||||
|
||||
def __name_aka(self, line, state):
|
||||
"""
|
||||
This parses the non-standard GEDCOM tags _AKA or _AKAN as a subsidiary
|
||||
to the NAME tag, which is reported to have been found in Ancestral Quest
|
||||
and Personal Ancestral File 4 and 5. Note: example AQ and PAF files have
|
||||
separate 2 NICK and 2 _AKA lines for the same person. The NICK will be
|
||||
stored by Gramps in the nick_name field of the name structure, while the
|
||||
_AKA, if it is a single word, will be stored in the NICKNAME attribute.
|
||||
If more than one word it is stored as an AKA alternate name.
|
||||
|
||||
This will also handle a usage which has been found in in Brother's
|
||||
Keeper (BROSKEEP VERS 6.1.31 WINDOWS) as follows:
|
||||
|
||||
0 @I203@ INDI
|
||||
1 NAME John Richard/Doe/
|
||||
2 _AKAN Some Other Name
|
||||
3 DATE 27 JUN 1817
|
||||
|
||||
@param line: The current line in GedLine format
|
||||
@type line: GedLine
|
||||
@param state: The current state
|
||||
@ -3756,8 +3869,33 @@ class GedcomParser(UpdateCallback):
|
||||
surname.set_primary()
|
||||
name.set_surname_list([surname])
|
||||
name.set_first_name(' '.join(lname[0:name_len-1]))
|
||||
# name = self.__parse_name_personal(line.data)
|
||||
name.set_type(gen.lib.NameType.AKA)
|
||||
state.person.add_alternate_name(name)
|
||||
|
||||
def __name_adpn(self, line, state):
|
||||
"""
|
||||
@param line: The current line in GedLine format
|
||||
@type line: GedLine
|
||||
@param state: The current state
|
||||
@type state: CurrentState
|
||||
"""
|
||||
text = line.data.strip()
|
||||
data = text.split()
|
||||
if len(data) == 1:
|
||||
name = gen.lib.Name(state.person.primary_name)
|
||||
surn = gen.lib.Surname()
|
||||
surn.set_surname(data[0].strip())
|
||||
surn.set_primary()
|
||||
name.set_surname_list([surn])
|
||||
name.set_type((gen.lib.NameType.CUSTOM, "Adopted"))
|
||||
state.person.add_alternate_name(name)
|
||||
elif len(data) > 1:
|
||||
name = self.__parse_name_personal(text)
|
||||
name.set_type((gen.lib.NameType.CUSTOM, "Adopted"))
|
||||
state.person.add_alternate_name(name)
|
||||
|
||||
|
||||
def __name_sour(self, line, state):
|
||||
"""
|
||||
@param line: The current line in GedLine format
|
||||
|
Loading…
Reference in New Issue
Block a user