0005620: Export name types to GEDCOM. Patch extended following testing against various GEDCOM files from the internet.
svn: r19053
This commit is contained in:
parent
88df9c000f
commit
9c4f7b7e0a
@ -1257,6 +1257,14 @@ class GedcomWriter(UpdateCallback):
|
|||||||
nick = attr_nick
|
nick = attr_nick
|
||||||
|
|
||||||
self.__writeln(1, 'NAME', gedcom_name)
|
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:
|
if firstname:
|
||||||
self.__writeln(2, 'GIVN', firstname)
|
self.__writeln(2, 'GIVN', firstname)
|
||||||
|
@ -255,6 +255,8 @@ TOKEN_WWW = 125
|
|||||||
TOKEN_URL = 126
|
TOKEN_URL = 126
|
||||||
TOKEN_ROLE = 127
|
TOKEN_ROLE = 127
|
||||||
TOKEN__MAR = 128
|
TOKEN__MAR = 128
|
||||||
|
TOKEN__MARN = 129
|
||||||
|
TOKEN__ADPN = 130
|
||||||
|
|
||||||
TOKENS = {
|
TOKENS = {
|
||||||
"HEAD" : TOKEN_HEAD, "MEDI" : TOKEN_MEDI,
|
"HEAD" : TOKEN_HEAD, "MEDI" : TOKEN_MEDI,
|
||||||
@ -268,6 +270,7 @@ TOKENS = {
|
|||||||
"ADDRESS2" : TOKEN_ADR2, "AFN" : TOKEN_AFN,
|
"ADDRESS2" : TOKEN_ADR2, "AFN" : TOKEN_AFN,
|
||||||
"AGE" : TOKEN_AGE, "AGNC" : TOKEN_AGNC,
|
"AGE" : TOKEN_AGE, "AGNC" : TOKEN_AGNC,
|
||||||
"AGENCY" : TOKEN_IGNORE, "_AKA" : TOKEN__AKA,
|
"AGENCY" : TOKEN_IGNORE, "_AKA" : TOKEN__AKA,
|
||||||
|
"_AKAN" : TOKEN__AKA, "AKA" : TOKEN__AKA,
|
||||||
"_ALIA" : TOKEN_ALIA, "ALIA" : TOKEN_ALIA,
|
"_ALIA" : TOKEN_ALIA, "ALIA" : TOKEN_ALIA,
|
||||||
"ALIAS" : TOKEN_ALIA, "ANCI" : TOKEN_ANCI,
|
"ALIAS" : TOKEN_ALIA, "ANCI" : TOKEN_ANCI,
|
||||||
"ASSO" : TOKEN_ASSO, "ASSOCIATES" : TOKEN_ASSO,
|
"ASSO" : TOKEN_ASSO, "ASSOCIATES" : TOKEN_ASSO,
|
||||||
@ -358,7 +361,8 @@ TOKENS = {
|
|||||||
"FACT" : TOKEN_FACT, "EMAIL" : TOKEN_EMAIL,
|
"FACT" : TOKEN_FACT, "EMAIL" : TOKEN_EMAIL,
|
||||||
"EMAI" : TOKEN_EMAIL, "WWW" : TOKEN_WWW,
|
"EMAI" : TOKEN_EMAIL, "WWW" : TOKEN_WWW,
|
||||||
"_URL" : TOKEN_URL, "URL" : TOKEN_URL,
|
"_URL" : TOKEN_URL, "URL" : TOKEN_URL,
|
||||||
"_MAR" : TOKEN__MAR,
|
"_MAR" : TOKEN__MAR, "_MARN" : TOKEN__MARN,
|
||||||
|
"_ADPN" : TOKEN__ADPN
|
||||||
}
|
}
|
||||||
|
|
||||||
ADOPT_NONE = 0
|
ADOPT_NONE = 0
|
||||||
@ -1928,7 +1932,7 @@ class GedcomParser(UpdateCallback):
|
|||||||
# +1 REFN <USER_REFERENCE_NUMBER> {0:M}
|
# +1 REFN <USER_REFERENCE_NUMBER> {0:M}
|
||||||
# +2 TYPE <USER_REFERENCE_TYPE> {0:1}
|
# +2 TYPE <USER_REFERENCE_TYPE> {0:1}
|
||||||
TOKEN_REFN : self.__person_attr,
|
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,
|
TOKEN_TYPE : self.__person_attr,
|
||||||
# +1 RIN <AUTOMATED_RECORD_ID> {0:1}
|
# +1 RIN <AUTOMATED_RECORD_ID> {0:1}
|
||||||
TOKEN_RIN : self.__person_attr,
|
TOKEN_RIN : self.__person_attr,
|
||||||
@ -1964,10 +1968,18 @@ class GedcomParser(UpdateCallback):
|
|||||||
# Extensions
|
# Extensions
|
||||||
TOKEN_ALIA : self.__name_alia,
|
TOKEN_ALIA : self.__name_alia,
|
||||||
TOKEN__MARNM : self.__name_marnm,
|
TOKEN__MARNM : self.__name_marnm,
|
||||||
TOKEN__MAR : self.__name_marnm, # Generated by gni.com
|
TOKEN__MAR : self.__name_marnm, # Generated by geni.com
|
||||||
TOKEN__AKA : self.__name_aka,
|
TOKEN__MARN : self.__name_marnm, # Gen'd by BROSKEEP 6.1.31 WIN
|
||||||
TOKEN_TYPE : self.__name_type,
|
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_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
|
@param state: The current state
|
||||||
@type state: CurrentState
|
@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,
|
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)
|
state.person.add_event_ref(event_ref)
|
||||||
|
|
||||||
def __fam_even(self, line, state):
|
def __fam_even(self, line, state):
|
||||||
@ -3184,14 +3201,41 @@ class GedcomParser(UpdateCallback):
|
|||||||
|
|
||||||
def __person_alt_name(self, line, state):
|
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
|
The ALIA tag is supposed to cross reference another person. We will
|
||||||
store this in the Association record.
|
store this in the Association record.
|
||||||
|
|
||||||
ALIA {ALIAS}: = An indicator to link different record descriptions of a
|
ALIA {ALIAS}: = An indicator to link different record descriptions of a
|
||||||
person who may be the same person.
|
person who may be the same person.
|
||||||
|
|
||||||
Some systems use the ALIA tag as an alternate NAME tag, which
|
Some systems use the ALIA tag as an alternate NAME tag, which is not
|
||||||
is not legal in GEDCOM, but oddly enough, is easy to support.
|
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] == '@':
|
if line.data[0] == '@':
|
||||||
handle = self.__find_person_handle(self.pid_map[line.data])
|
handle = self.__find_person_handle(self.pid_map[line.data])
|
||||||
@ -3204,11 +3248,23 @@ class GedcomParser(UpdateCallback):
|
|||||||
|
|
||||||
def __parse_alias_name(self, line, state):
|
def __parse_alias_name(self, line, state):
|
||||||
"""
|
"""
|
||||||
Parse a altername name, usually indicated by a AKA or _AKA
|
Parse a level 1 alias name and subsidiary levels when called from
|
||||||
tag. This is not valid GEDCOM, but several programs will add
|
__person_alt_name (when the <NAME_PERSONAL> does not start with @). Also
|
||||||
this just to make life interesting. Odd, since GEDCOM supports
|
parses a level 2 alias name and subsidiary levels when called from
|
||||||
multiple NAME indicators, which is the correct way of handling
|
__name_alias.
|
||||||
multiple names.
|
|
||||||
|
+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
|
@param line: The current line in GedLine format
|
||||||
@type line: GedLine
|
@type line: GedLine
|
||||||
@ -3595,11 +3651,23 @@ class GedcomParser(UpdateCallback):
|
|||||||
@param state: The current state
|
@param state: The current state
|
||||||
@type state: CurrentState
|
@type state: CurrentState
|
||||||
"""
|
"""
|
||||||
if line.data == "_OTHN":
|
if line.data.upper() in ("_OTHN", "_AKA", "AKA", "AKAN"):
|
||||||
state.name.set_type(gen.lib.NameType.AKA)
|
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:
|
else:
|
||||||
state.name.set_type((gen.lib.NameType.CUSTOM, line.data))
|
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):
|
def __name_note(self, line, state):
|
||||||
"""
|
"""
|
||||||
@param line: The current line in GedLine format
|
@param line: The current line in GedLine format
|
||||||
@ -3611,27 +3679,46 @@ class GedcomParser(UpdateCallback):
|
|||||||
|
|
||||||
def __name_alia(self, line, state):
|
def __name_alia(self, line, state):
|
||||||
"""
|
"""
|
||||||
This handles the ALIA (or _ALIA or ALIAS) tag as a subsidiary of the
|
This parses the illegal (ALIA or ALIAS) or non-standard (_ALIA) GEDCOM
|
||||||
NAME tag. For example:
|
tag as a subsidiary of the NAME tag.
|
||||||
|
|
||||||
0 @PERSON1@ INDI
|
n @XREF:INDI@ INDI {1:1}
|
||||||
1 NAME John /Doe/
|
+1 NAME <NAME_PERSONAL> {1:1}
|
||||||
2 GIVN John
|
+2 NPFX <NAME_PIECE_PREFIX> {0:1}
|
||||||
2 SURN Doe
|
+2 GIVN <NAME_PIECE_GIVEN> {0:1}
|
||||||
2 ALIA Richard /Roe/
|
+2 NICK <NAME_PIECE_NICKNAME> {0:1}
|
||||||
2 NPFX Dr.
|
+2 SPFX <NAME_PIECE_SURNAME_PREFIX> {0:1}
|
||||||
2 GIVN Richard
|
+2 SURN <NAME_PIECE_SURNAME> {0:1}
|
||||||
2 NICK Rich
|
+2 NSFX <NAME_PIECE_SUFFIX> {0:1}
|
||||||
2 SPFX Le
|
+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
|
Note that the subsidiary name structure detail will overwrite the ALIA
|
||||||
name (if the same elements are provided in both), so the names should
|
name (if the same elements are provided in both), so the names should
|
||||||
match.
|
match.
|
||||||
|
|
||||||
There does not appear to be any evidence that this usage exists, but as
|
"2 _ALIA" is used for example, by PRO-GEN v 3.0a and "2 ALIA" is used
|
||||||
it was supported (though probably incorrectly coded as it would only
|
by GTEdit and Brother's keeper 5.2 for windows. It had been supported in
|
||||||
work if the name started with'@'), in previous versions of Gramps, we
|
previous versions of Gramps but as it was probably incorrectly coded as
|
||||||
had better support it here.
|
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)
|
self.__parse_alias_name(line, state)
|
||||||
|
|
||||||
@ -3689,6 +3776,16 @@ class GedcomParser(UpdateCallback):
|
|||||||
|
|
||||||
def __name_marnm(self, line, state):
|
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
|
@param line: The current line in GedLine format
|
||||||
@type line: GedLine
|
@type line: GedLine
|
||||||
@param state: The current state
|
@param state: The current state
|
||||||
@ -3737,6 +3834,22 @@ class GedcomParser(UpdateCallback):
|
|||||||
|
|
||||||
def __name_aka(self, line, state):
|
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
|
@param line: The current line in GedLine format
|
||||||
@type line: GedLine
|
@type line: GedLine
|
||||||
@param state: The current state
|
@param state: The current state
|
||||||
@ -3756,8 +3869,33 @@ class GedcomParser(UpdateCallback):
|
|||||||
surname.set_primary()
|
surname.set_primary()
|
||||||
name.set_surname_list([surname])
|
name.set_surname_list([surname])
|
||||||
name.set_first_name(' '.join(lname[0:name_len-1]))
|
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)
|
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):
|
def __name_sour(self, line, state):
|
||||||
"""
|
"""
|
||||||
@param line: The current line in GedLine format
|
@param line: The current line in GedLine format
|
||||||
|
Loading…
Reference in New Issue
Block a user