gedcom-x 0.5.6__py3-none-any.whl → 0.5.8__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (64) hide show
  1. {gedcom_x-0.5.6.dist-info → gedcom_x-0.5.8.dist-info}/METADATA +1 -1
  2. gedcom_x-0.5.8.dist-info/RECORD +56 -0
  3. gedcomx/Extensions/__init__.py +1 -0
  4. gedcomx/Extensions/rs10/__init__.py +1 -0
  5. gedcomx/Extensions/rs10/rsLink.py +116 -0
  6. gedcomx/TopLevelTypeCollection.py +1 -1
  7. gedcomx/__init__.py +43 -41
  8. gedcomx/{Address.py → address.py} +13 -13
  9. gedcomx/{Agent.py → agent.py} +52 -24
  10. gedcomx/{Attribution.py → attribution.py} +36 -9
  11. gedcomx/{Conclusion.py → conclusion.py} +49 -21
  12. gedcomx/converter.py +1049 -0
  13. gedcomx/coverage.py +55 -0
  14. gedcomx/{Date.py → date.py} +11 -4
  15. gedcomx/{Document.py → document.py} +27 -8
  16. gedcomx/{Event.py → event.py} +102 -27
  17. gedcomx/{EvidenceReference.py → evidence_reference.py} +2 -2
  18. gedcomx/{Fact.py → fact.py} +45 -34
  19. gedcomx/{Gedcom5x.py → gedcom5x.py} +78 -61
  20. gedcomx/gedcom7/Exceptions.py +9 -0
  21. gedcomx/gedcom7/Gedcom7.py +160 -0
  22. gedcomx/gedcom7/GedcomStructure.py +94 -0
  23. gedcomx/gedcom7/Specification.py +347 -0
  24. gedcomx/gedcom7/__init__.py +26 -0
  25. gedcomx/gedcom7/g7interop.py +205 -0
  26. gedcomx/gedcom7/logger.py +19 -0
  27. gedcomx/gedcomx.py +501 -0
  28. gedcomx/{Gender.py → gender.py} +29 -17
  29. gedcomx/group.py +63 -0
  30. gedcomx/{Identifier.py → identifier.py} +13 -16
  31. gedcomx/{LoggingHub.py → logging_hub.py} +21 -0
  32. gedcomx/{Mutations.py → mutations.py} +50 -26
  33. gedcomx/name.py +396 -0
  34. gedcomx/{Note.py → note.py} +17 -10
  35. gedcomx/{OnlineAccount.py → online_account.py} +1 -1
  36. gedcomx/{Person.py → person.py} +52 -29
  37. gedcomx/place_description.py +123 -0
  38. gedcomx/place_reference.py +62 -0
  39. gedcomx/qualifier.py +54 -0
  40. gedcomx/{Relationship.py → relationship.py} +33 -13
  41. gedcomx/resource.py +85 -0
  42. gedcomx/serialization.py +815 -0
  43. gedcomx/{SourceDescription.py → source_description.py} +144 -85
  44. gedcomx/{SourceReference.py → source_reference.py} +15 -14
  45. gedcomx/{Subject.py → subject.py} +30 -28
  46. gedcomx/{GedcomX.py → translation.py} +283 -446
  47. gedcomx/{URI.py → uri.py} +42 -26
  48. gedcom_x-0.5.6.dist-info/RECORD +0 -45
  49. gedcomx/Coverage.py +0 -36
  50. gedcomx/Group.py +0 -37
  51. gedcomx/Name.py +0 -276
  52. gedcomx/PlaceDescription.py +0 -70
  53. gedcomx/PlaceReference.py +0 -30
  54. gedcomx/Qualifier.py +0 -27
  55. gedcomx/Resource.py +0 -75
  56. gedcomx/Serialization.py +0 -401
  57. gedcomx/Translation.py +0 -219
  58. {gedcom_x-0.5.6.dist-info → gedcom_x-0.5.8.dist-info}/WHEEL +0 -0
  59. {gedcom_x-0.5.6.dist-info → gedcom_x-0.5.8.dist-info}/top_level.txt +0 -0
  60. /gedcomx/{Exceptions.py → exceptions.py} +0 -0
  61. /gedcomx/{ExtensibleEnum.py → extensible_enum.py} +0 -0
  62. /gedcomx/{Gedcom.py → gedcom.py} +0 -0
  63. /gedcomx/{SourceCitation.py → source_citation.py} +0 -0
  64. /gedcomx/{TextValue.py → textvalue.py} +0 -0
@@ -1,384 +1,221 @@
1
- DEBUG = False
2
- import base64
3
- import json
4
- import mimetypes
1
+ from . import *
2
+ from .mutations import GedcomXEventOrFact
5
3
  import re
6
- import uuid
7
- import xml.etree.ElementTree as ET
8
-
9
- from typing import List, Optional
10
- from xml.dom import minidom
11
- from .Address import Address
12
- from .Agent import Agent
13
- from .Attribution import Attribution
14
- from .Conclusion import Conclusion
15
- from .Coverage import Coverage
16
- from .Date import Date, date_to_timestamp
17
- from .Document import Document
18
- from .EvidenceReference import EvidenceReference
19
- from .Exceptions import TagConversionError
20
- from .Event import Event,EventType,EventRole,EventRoleType
21
- from .Fact import Fact, FactType, FactQualifier
22
- from .Gedcom import Gedcom
23
- from .Gedcom5x import Gedcom5x, GedcomRecord
24
- from .Gender import Gender, GenderType
25
- from .Group import Group
26
- from .Identifier import Identifier, IdentifierType, make_uid, IdentifierList
27
- from .Logging import get_logger
28
- from .Name import Name, NameType, NameForm, NamePart, NamePartType, NamePartQualifier
29
- from .Note import Note
30
- from .OnlineAccount import OnlineAccount
31
- from .Person import Person
32
- from .PlaceDescription import PlaceDescription
33
- from .PlaceReference import PlaceReference
34
- from .Qualifier import Qualifier
35
- from .Relationship import Relationship, RelationshipType
36
- from .SourceCitation import SourceCitation
37
- from .SourceDescription import SourceDescription, ResourceType
38
- from .SourceReference import SourceReference, KnownSourceReference
39
- from .Subject import Subject
40
- from .TextValue import TextValue
41
- from .TopLevelTypeCollection import TopLevelTypeCollection
42
- from .Resource import Resource, URI
43
-
44
- import_log = get_logger('import')
45
- convert_log = get_logger('conversion')
46
-
47
- def TypeCollection(item_type):
48
- class Collection:
49
- def __init__(self):
50
- self._items = []
51
- self._id_index = {}
52
- self._name_index = {}
53
- self._uri_index = {}
54
- self.uri = URI(path=f'/{item_type.__name__}s/')
55
-
56
- def __iter__(self):
57
- self._index = 0
58
- return self
59
-
60
- def __next__(self):
61
- if self._index < len(self._items):
62
- result = self._items[self._index]
63
- self._index += 1
64
- return result
65
- else:
66
- raise StopIteration
67
-
68
- @property
69
- def item_type(self):
70
- return item_type
71
-
72
- def _update_indexes(self, item):
73
- # Update the id index
74
- if hasattr(item, 'id'):
75
- self._id_index[item.id] = item
76
-
77
- try:
78
- if hasattr(item, '_uri'):
79
- self._uri_index[item._uri.value] = item
80
- except AttributeError as e:
81
- print(f"type{item}")
82
- assert False
83
-
84
- # Update the name index
85
- ''' #TODO Fix name handling on persons
86
- if hasattr(item, 'names'):
87
- names = getattr(item, 'names')
88
- for name in names:
89
- print(name._as_dict_)
90
- name_value = name.value if isinstance(name, TextValue) else name
91
- if name_value in self._name_index:
92
- self._name_index[name_value].append(item)
93
- else:
94
- self._name_index[name_value] = [item]
95
- '''
96
-
97
- def _remove_from_indexes(self, item):
98
- # Remove from the id index
99
- if hasattr(item, 'id'):
100
- if item.id in self._id_index:
101
- del self._id_index[item.id]
102
-
103
- # Remove from the name index
104
- if hasattr(item, 'names'):
105
- names = getattr(item, 'names')
106
- for name in names:
107
- name_value = name.value if isinstance(name, TextValue) else name
108
- if name_value in self._name_index:
109
- if item in self._name_index[name_value]:
110
- self._name_index[name_value].remove(item)
111
- if not self._name_index[name_value]:
112
- del self._name_index[name_value]
113
-
114
- def byName(self, sname: str):
115
- # Use the name index for fast lookup
116
- if sname:
117
- sname = sname.strip()
118
- return self._name_index.get(sname, [])
119
- return None
120
-
121
- def byId(self, id):
122
- # Use the id index for fast lookup
123
- return self._id_index.get(id, None)
124
-
125
- def byUri(self, uri):
126
- # Use the id index for fast lookup
127
- return self._uri_index.get(uri.value, None)
128
-
129
- def append(self, item):
130
- if not isinstance(item, item_type):
131
- raise TypeError(f"Expected item of type {item_type.__name__}, got {type(item).__name__}")
132
- if item.uri:
133
- item.uri.path = f'{str(item_type.__name__)}s' if (item.uri.path is None or item.uri.path == "") else item.uri.path
134
- else:
135
- item.uri = URI(path=f'/{item_type.__name__}s/')
136
-
137
-
138
- #if isinstance(item,Agent):
139
- # item._uri._path = 'Agents'
140
- # print(item._uri._as_dict_)
141
-
142
- self._items.append(item)
143
- self._update_indexes(item)
144
-
145
- def remove(self, item):
146
- if item not in self._items:
147
- raise ValueError("Item not found in the collection.")
148
- self._items.remove(item)
149
- self._remove_from_indexes(item)
150
-
151
- def __repr__(self):
152
- return f"Collection({self._items!r})"
153
-
154
- def list(self):
155
- for item in self._items:
156
- print(item)
157
-
158
- def __call__(self, **kwargs):
159
- results = []
160
- for item in self._items:
161
- match = True
162
- for key, value in kwargs.items():
163
- if not hasattr(item, key) or getattr(item, key) != value:
164
- match = False
165
- break
166
- if match:
167
- results.append(item)
168
- return results
169
-
170
- def __len__(self):
171
- return len(self._items)
172
-
173
- def __getitem__(self, index):
174
- return self._items[index]
175
-
176
- @property
177
- def _items_as_dict(self) -> dict:
178
- return {f'{str(item_type.__name__)}s': [item._as_dict_ for item in self._items]}
179
-
180
- @property
181
- def _as_dict_(self):
182
- return {f'{str(item_type.__name__).lower()}s': [item._as_dict_ for item in self._items]}
183
-
184
- @property
185
- def json(self) -> str:
186
-
187
- return json.dumps(self._as_dict_, indent=4)
188
-
189
- return Collection()
190
-
191
- class GedcomX:
192
- """
193
- Main GedcomX Object representing a Genealogy. Stores collections of Top Level Gedcom-X Types.
194
- complies with GEDCOM X Conceptual Model V1 (http://gedcomx.org/conceptual-model/v1)
195
-
196
- Parameters
197
- ----------
198
- id : str
199
- Unique identifier for this Genealogy.
200
- attribution : Attribution Object
201
- Attribution information for the Genealogy
202
- filepath : str
203
- Not Implimented.
204
- description : str
205
- Description of the Genealogy: ex. 'My Family Tree'
206
-
207
- Raises
208
- ------
209
- ValueError
210
- If `id` is not a valid UUID.
211
- """
212
- version = 'http://gedcomx.org/conceptual-model/v1'
213
-
214
- def __init__(self, id: Optional[str] = None,
215
- attribution: Optional[Attribution] = None,
216
- filepath: Optional[str] = None,
217
- description: Optional[str] = None) -> None:
218
-
219
- self.id = id
220
- self.attribution = attribution
221
- self._filepath = None
222
-
223
- self.description = description
224
- self.source_descriptions = TypeCollection(SourceDescription)
225
- self.persons = TypeCollection(Person)
226
- self.relationships = TypeCollection(Relationship)
227
- self.agents = TypeCollection(Agent)
228
- self.events = TypeCollection(Event)
229
- self.documents = TypeCollection(Document)
230
- self.places = TypeCollection(PlaceDescription)
231
- self.groups = TypeCollection(Group)
232
-
233
- self.relationship_table = {}
234
-
235
- self.default_id_generator = make_uid
236
-
237
- def add(self,gedcomx_type_object):
238
- if gedcomx_type_object:
239
- if isinstance(gedcomx_type_object,Person):
240
- self.add_person(gedcomx_type_object)
241
- elif isinstance(gedcomx_type_object,SourceDescription):
242
- self.add_source_description(gedcomx_type_object)
243
- elif isinstance(gedcomx_type_object,Agent):
244
- self.add_agent(gedcomx_type_object)
245
- elif isinstance(gedcomx_type_object,PlaceDescription):
246
- self.add_place_description(gedcomx_type_object)
247
- elif isinstance(gedcomx_type_object,Event):
248
- self.add_event(gedcomx_type_object)
249
- elif isinstance(gedcomx_type_object,Relationship):
250
- self.add_relationship(gedcomx_type_object)
251
- else:
252
- raise ValueError(f"I do not know how to add an Object of type {type(gedcomx_type_object)}")
253
- else:
254
- Warning("Tried to add a None type to the Geneology")
255
-
256
- def add_source_description(self,sourceDescription: SourceDescription):
257
- if sourceDescription and isinstance(sourceDescription,SourceDescription):
258
- if sourceDescription.id is None:
259
- sourceDescription.id =self.default_id_generator()
260
- self.source_descriptions.append(item=sourceDescription)
261
- self.lastSourceDescriptionAdded = sourceDescription
262
- else:
263
- raise ValueError(f"When adding a SourceDescription, value must be of type SourceDescription, type {type(sourceDescription)} was provided")
264
-
265
- def add_person(self,person: Person):
266
- """Add a Person object to the Genealogy
267
-
268
- Args:
269
- person: Person Object
270
-
271
- Returns:
272
- None
273
-
274
- Raises:
275
- ValueError: If `person` is not of type Person.
276
- """
277
- if person and isinstance(person,Person):
278
- if person.id is None:
279
- person.id =self.personURIgenerator()
280
- self.persons.append(item=person)
281
- else:
282
- raise ValueError(f'person must be a Person Object not type: {type(person)}')
283
-
284
- def add_relationship(self,relationship: Relationship):
285
- if relationship and isinstance(relationship,Relationship):
286
- if isinstance(relationship.person1,Resource) and isinstance(relationship.person2,Resource):
287
- print("Adding unresolved Relationship")
288
- self.relationships.append(relationship)
289
- return
290
-
291
- if relationship.person1:
292
- if relationship.person1.id is None:
293
- relationship.person1.id = self.personURIgenerator()
294
- if not self.persons.byId(relationship.person1.id):
295
- self.persons.append(relationship.person1)
296
- if relationship.person1.id not in self.relationship_table:
297
- self.relationship_table[relationship.person1.id] = []
298
- self.relationship_table[relationship.person1.id].append(relationship)
299
- relationship.person1._add_relationship(relationship)
300
- else:
301
- pass
302
-
303
- if relationship.person2:
304
- if relationship.person2.id is None:
305
- relationship.person2.id = self.personURIgenerator() #TODO
306
- if not self.persons.byId(relationship.person2.id):
307
- self.persons.append(relationship.person2)
308
- if relationship.person2.id not in self.relationship_table:
309
- self.relationship_table[relationship.person2.id] = []
310
- self.relationship_table[relationship.person2.id].append(relationship)
311
- relationship.person2._add_relationship(relationship)
312
- else:
313
- pass
314
-
315
- self.relationships.append(relationship)
316
- else:
317
- raise ValueError()
318
-
319
- def add_place_description(self,placeDescription: PlaceDescription):
320
- if placeDescription and isinstance(placeDescription,PlaceDescription):
321
- if placeDescription.id is None:
322
- Warning("PlaceDescription has no id")
323
- self.places.append(placeDescription)
324
-
325
- def add_agent(self,agent: Agent):
326
- """Add a Agent object to the Genealogy
327
-
328
- Args:
329
- agent: Agent Object
330
-
331
- Returns:
332
- None
333
-
334
- Raises:
335
- ValueError: If `agent` is not of type Agent.
336
- """
337
- if agent and isinstance(agent,Agent):
338
- if agent in self.agents:
339
- return
340
- if agent.id is None:
341
- agent.id = Agent.default_id_generator()
342
- if self.agents.byId(agent.id):
343
- pass #TODO Deal with duplicates
344
- #raise ValueError
345
- print(f'Added Agent with id: {agent.id}')
346
- self.agents.append(agent)
347
-
348
- def add_event(self,event_to_add: Event):
349
- if event_to_add and isinstance(event_to_add,Event):
350
- for current_event in self.events:
351
- if event_to_add == current_event:
352
- return
353
- self.events.append(event_to_add)
4
+ '''
5
+ {'type': 'Object | Objects | Propertyof',
6
+ 'Object': 'Class',
7
+ 'Objects': ['Class',...],
8
+ 'Propertyof': 'Class',
9
+ 'Args': {'argname':'value|rTextValue|rIntValue|rFloatValue|rBoolValue|id|resource'},
10
+ 'Assign': {'propertyname':'value|rTextValue|rIntValue|rFloatValue|rBoolValue|id|resource'},
11
+ 'Selectoe':callable
12
+ }
354
13
 
355
- def get_person_by_id(self,id: str):
356
- filtered = [person for person in self.persons if getattr(person, 'id') == id]
357
- if filtered: return filtered[0]
358
- return None
359
-
360
- def source(self,id: str):
361
- filtered = [source for source in self.source_descriptions if getattr(source, 'id') == id]
362
- if filtered: return filtered[0]
363
- return None
364
-
365
- def json(self):
366
- """
367
- JSON Representation of the GedcomX Genealogy.
368
-
369
- Returns:
370
- str: JSON Representation of the GedcomX Genealogy in the GEDCOM X JSON Serialization Format
371
- """
372
- gedcomx_json = {
373
- 'persons': [person._as_dict_ for person in self.persons],
374
- 'sourceDescriptions' : [sourceDescription._as_dict_ for sourceDescription in self.source_descriptions],
375
- 'relationships': [relationship._as_dict_ for relationship in self.relationships],
376
- 'agents': [agent._as_dict_ for agent in self.agents],
377
- 'events': [event._as_dict_ for event in self.events],
378
- 'places': [place._as_dict_ for place in self.places],
379
- 'documents': [document._as_dict_ for document in self.documents],
380
- }
381
- return json.dumps(gedcomx_json, indent=4)
14
+ '''
15
+ g7toXtable = {
16
+ "https://gedcom.io/terms/v7/ABBR": {},
17
+ "https://gedcom.io/terms/v7/ADDR": {'type':'Object','Object':Address, 'Args':{'value':'value'},'addmethod':'add_address'},
18
+ "https://gedcom.io/terms/v7/ADOP": {},
19
+ "https://gedcom.io/terms/v7/ADOP-FAMC": {},
20
+ "https://gedcom.io/terms/v7/ADR1": {'type':'Propertyof','propertyof':Address,'assign':{'street':'value'}},
21
+ "https://gedcom.io/terms/v7/ADR2": {'type':'Propertyof','propertyof':Address,'assign':{'street2':'value'}},
22
+ "https://gedcom.io/terms/v7/ADR3": {'type':'Propertyof','propertyof':Address,'assign':{'street3':'value'}},
23
+ "https://gedcom.io/terms/v7/AGE": {},
24
+ "https://gedcom.io/terms/v7/AGNC": {},
25
+ "https://gedcom.io/terms/v7/ALIA": {},
26
+ "https://gedcom.io/terms/v7/ANCI": {},
27
+ "https://gedcom.io/terms/v7/ANUL": {'type':'Mutation','Object':GedcomXEventOrFact,'Args':{'value':'value'},'propertyof':[Relationship],'method':'add_fact'},
28
+ "https://gedcom.io/terms/v7/ASSO": {},
29
+ "https://gedcom.io/terms/v7/AUTH": {},
30
+ "https://gedcom.io/terms/v7/BAPL": {},
31
+ "https://gedcom.io/terms/v7/BAPM": {},
32
+ "https://gedcom.io/terms/v7/BARM": {},
33
+ "https://gedcom.io/terms/v7/BASM": {},
34
+ "https://gedcom.io/terms/v7/BIRT": {},
35
+ "https://gedcom.io/terms/v7/BLES": {},
36
+ "https://gedcom.io/terms/v7/BURI": {},
37
+ "https://gedcom.io/terms/v7/CALN": {},
38
+ "https://gedcom.io/terms/v7/CAST": {},
39
+ "https://gedcom.io/terms/v7/CAUS": {},
40
+ "https://gedcom.io/terms/v7/CENS": {},
41
+ "https://gedcom.io/terms/v7/CHAN": {},
42
+ "https://gedcom.io/terms/v7/CHIL": {},
43
+ "https://gedcom.io/terms/v7/CHR": {},
44
+ "https://gedcom.io/terms/v7/CHRA": {},
45
+ "https://gedcom.io/terms/v7/CITY": {'type':'Propertyof','propertyof':Address,'assign':{'city':'value'}},
46
+ "https://gedcom.io/terms/v7/CONF": {},
47
+ "https://gedcom.io/terms/v7/CONL": {},
48
+ "https://gedcom.io/terms/v7/CONT": {},
49
+ "https://gedcom.io/terms/v7/COPR": {},
50
+ "https://gedcom.io/terms/v7/CORP": {},
51
+ "https://gedcom.io/terms/v7/CREA": {},
52
+ "https://gedcom.io/terms/v7/CREM": {},
53
+ "https://gedcom.io/terms/v7/CROP": {},
54
+ "https://gedcom.io/terms/v7/CTRY": {'type':'Propertyof','propertyof':Address,'assign':{'country':'value'}},
55
+ "https://gedcom.io/terms/v7/DATA": {},
56
+ "https://gedcom.io/terms/v7/DATA-EVEN": {},
57
+ "https://gedcom.io/terms/v7/DATA-EVEN-DATE": {},
58
+ "https://gedcom.io/terms/v7/DATE": {},
59
+ "https://gedcom.io/terms/v7/DATE-exact": {},
60
+ "https://gedcom.io/terms/v7/DEAT": {},
61
+ "https://gedcom.io/terms/v7/DESI": {},
62
+ "https://gedcom.io/terms/v7/DEST": {},
63
+ "https://gedcom.io/terms/v7/DIV": {'type':'Mutation','Object':GedcomXEventOrFact,'Args':{'value':'value'},'propertyof':[Relationship],'method':'add_fact'},
64
+ "https://gedcom.io/terms/v7/DIVF": {'type':'Mutation','Object':GedcomXEventOrFact,'Args':{'value':'value'},'propertyof':[Relationship],'method':'add_fact'},
65
+ "https://gedcom.io/terms/v7/DSCR": {},
66
+ "https://gedcom.io/terms/v7/EDUC": {},
67
+ "https://gedcom.io/terms/v7/EMAIL": {},
68
+ "https://gedcom.io/terms/v7/EMIG": {},
69
+ "https://gedcom.io/terms/v7/ENDL": {},
70
+ "https://gedcom.io/terms/v7/ENGA": {'type':'Mutation','Object':GedcomXEventOrFact,'Args':{'value':'value'},'propertyof':[Relationship],'method':'add_fact'},
71
+ "https://gedcom.io/terms/v7/EVEN": {},
72
+ "https://gedcom.io/terms/v7/EXID": {},
73
+ "https://gedcom.io/terms/v7/EXID-TYPE": {},
74
+ "https://gedcom.io/terms/v7/FACT": {},
75
+ "https://gedcom.io/terms/v7/FAM": {'type':'Object','Object':Relationship,'Args':{'id':'xref'},'stackentry':['lastrelationship','lastrelationshipdata']},
76
+ "https://gedcom.io/terms/v7/FAM-CENS": {'type':'Mutation','Object':GedcomXEventOrFact,'Args':{'value':'value'},'propertyof':[Relationship],'method':'add_fact'},
77
+ "https://gedcom.io/terms/v7/FAM-EVEN": {},
78
+ "https://gedcom.io/terms/v7/FAM-FACT": {},
79
+ "https://gedcom.io/terms/v7/FAM-HUSB": {'type':'Object','Object':Resource,'Args':{'Id':'xref'}},
80
+ "https://gedcom.io/terms/v7/FAM-NCHI": {},
81
+ "https://gedcom.io/terms/v7/FAM-RESI": {'type':'Mutation','Object':GedcomXEventOrFact,'Args':{'value':'value'},'propertyof':[Relationship],'method':'add_fact'},
82
+ "https://gedcom.io/terms/v7/FAM-WIFE": {'type':'Object','Object':Resource,'Args':{'Id':'xref'}},
83
+ "https://gedcom.io/terms/v7/FAMC": {},
84
+ "https://gedcom.io/terms/v7/FAMC-ADOP": {},
85
+ "https://gedcom.io/terms/v7/FAMC-STAT": {},
86
+ "https://gedcom.io/terms/v7/FAMS": {},
87
+ "https://gedcom.io/terms/v7/FAX": {},
88
+ "https://gedcom.io/terms/v7/FCOM": {},
89
+ "https://gedcom.io/terms/v7/FILE": {},
90
+ "https://gedcom.io/terms/v7/FILE-TRAN": {},
91
+ "https://gedcom.io/terms/v7/FORM": {},
92
+ "https://gedcom.io/terms/v7/GEDC": {},
93
+ "https://gedcom.io/terms/v7/GEDC-VERS": {},
94
+ "https://gedcom.io/terms/v7/GIVN": {},
95
+ "https://gedcom.io/terms/v7/GRAD": {},
96
+ "https://gedcom.io/terms/v7/HEAD": {},
97
+ "https://gedcom.io/terms/v7/HEAD-DATE": {},
98
+ "https://gedcom.io/terms/v7/HEAD-LANG": {},
99
+ "https://gedcom.io/terms/v7/HEAD-PLAC": {},
100
+ "https://gedcom.io/terms/v7/HEAD-PLAC-FORM": {},
101
+ "https://gedcom.io/terms/v7/HEAD-SOUR": {},
102
+ "https://gedcom.io/terms/v7/HEAD-SOUR-DATA": {},
103
+ "https://gedcom.io/terms/v7/HEIGHT": {},
104
+ "https://gedcom.io/terms/v7/HUSB": {},
105
+ "https://gedcom.io/terms/v7/IDNO": {},
106
+ "https://gedcom.io/terms/v7/IMMI": {},
107
+ "https://gedcom.io/terms/v7/INDI": {},
108
+ "https://gedcom.io/terms/v7/INDI-CENS": {},
109
+ "https://gedcom.io/terms/v7/INDI-EVEN": {},
110
+ "https://gedcom.io/terms/v7/INDI-FACT": {},
111
+ "https://gedcom.io/terms/v7/INDI-FAMC": {},
112
+ "https://gedcom.io/terms/v7/INDI-NAME": {},
113
+ "https://gedcom.io/terms/v7/INDI-NCHI": {},
114
+ "https://gedcom.io/terms/v7/INDI-RELI": {},
115
+ "https://gedcom.io/terms/v7/INDI-RESI": {},
116
+ "https://gedcom.io/terms/v7/INDI-TITL": {},
117
+ "https://gedcom.io/terms/v7/INIL": {},
118
+ "https://gedcom.io/terms/v7/LANG": {},
119
+ "https://gedcom.io/terms/v7/LATI": {},
120
+ "https://gedcom.io/terms/v7/LEFT": {},
121
+ "https://gedcom.io/terms/v7/LONG": {},
122
+ "https://gedcom.io/terms/v7/MAP": {},
123
+ "https://gedcom.io/terms/v7/MARB": {'type':'Mutation','Object':GedcomXEventOrFact,'Args':{'value':'value'},'propertyof':[Relationship],'method':'add_fact'},
124
+ "https://gedcom.io/terms/v7/MARC": {'type':'Mutation','Object':GedcomXEventOrFact,'Args':{'value':'value'},'propertyof':[Relationship],'method':'add_fact'},
125
+ "https://gedcom.io/terms/v7/MARL": {'type':'Mutation','Object':GedcomXEventOrFact,'Args':{'value':'value'},'propertyof':[Relationship],'method':'add_fact'},
126
+ "https://gedcom.io/terms/v7/MARR": {'type':'Mutation','Object':GedcomXEventOrFact,'Args':{'value':'value'},'propertyof':[Relationship],'method':'add_fact'},
127
+ "https://gedcom.io/terms/v7/MARS": {'type':'Mutation','Object':GedcomXEventOrFact,'Args':{'value':'value'},'propertyof':[Relationship],'method':'add_fact'},
128
+ "https://gedcom.io/terms/v7/MEDI": {},
129
+ "https://gedcom.io/terms/v7/MIME": {},
130
+ "https://gedcom.io/terms/v7/NAME": {},
131
+ "https://gedcom.io/terms/v7/NAME-TRAN": {},
132
+ "https://gedcom.io/terms/v7/NAME-TYPE": {},
133
+ "https://gedcom.io/terms/v7/NATI": {},
134
+ "https://gedcom.io/terms/v7/NATU": {},
135
+ "https://gedcom.io/terms/v7/NCHI": {},
136
+ "https://gedcom.io/terms/v7/NICK": {},
137
+ "https://gedcom.io/terms/v7/NMR": {},
138
+ "https://gedcom.io/terms/v7/NO": {},
139
+ "https://gedcom.io/terms/v7/NO-DATE": {},
140
+ "https://gedcom.io/terms/v7/NOTE": {},
141
+ "https://gedcom.io/terms/v7/NOTE-TRAN": {},
142
+ "https://gedcom.io/terms/v7/NPFX": {},
143
+ "https://gedcom.io/terms/v7/NSFX": {},
144
+ "https://gedcom.io/terms/v7/OBJE": {'type':'Object','Object':SourceReference,'Args':{'Id':'xref'}},
145
+ "https://gedcom.io/terms/v7/OCCU": {},
146
+ "https://gedcom.io/terms/v7/ORDN": {},
147
+ "https://gedcom.io/terms/v7/PAGE": {},
148
+ "https://gedcom.io/terms/v7/PEDI": {},
149
+ "https://gedcom.io/terms/v7/PHON": {},
150
+ "https://gedcom.io/terms/v7/PHRASE": {},
151
+ "https://gedcom.io/terms/v7/PLAC": {},
152
+ "https://gedcom.io/terms/v7/PLAC-FORM": {},
153
+ "https://gedcom.io/terms/v7/PLAC-TRAN": {},
154
+ "https://gedcom.io/terms/v7/POST": {},
155
+ "https://gedcom.io/terms/v7/PROB": {},
156
+ "https://gedcom.io/terms/v7/PROP": {},
157
+ "https://gedcom.io/terms/v7/PUBL": {},
158
+ "https://gedcom.io/terms/v7/QUAY": {},
159
+ "https://gedcom.io/terms/v7/REFN": {},
160
+ "https://gedcom.io/terms/v7/RELI": {},
161
+ "https://gedcom.io/terms/v7/REPO": {'type':'Object','Object':Resource,'Args':{'Id':'xref'}},
162
+ "https://gedcom.io/terms/v7/RESI": {},
163
+ "https://gedcom.io/terms/v7/RESN": {},
164
+ "https://gedcom.io/terms/v7/RETI": {},
165
+ "https://gedcom.io/terms/v7/ROLE": {},
166
+ "https://gedcom.io/terms/v7/SCHMA": {},
167
+ "https://gedcom.io/terms/v7/SDATE": {},
168
+ "https://gedcom.io/terms/v7/SEX": {},
169
+ "https://gedcom.io/terms/v7/SLGC": {},
170
+ "https://gedcom.io/terms/v7/SLGS": {},
171
+ "https://gedcom.io/terms/v7/SNOTE": {},
172
+ "https://gedcom.io/terms/v7/SOUR": {},
173
+ "https://gedcom.io/terms/v7/SOUR-DATA": {},
174
+ "https://gedcom.io/terms/v7/SOUR-EVEN": {},
175
+ "https://gedcom.io/terms/v7/SPFX": {},
176
+ "https://gedcom.io/terms/v7/SSN": {},
177
+ "https://gedcom.io/terms/v7/STAE": {'type':'Propertyof','propertyof':Address,'assign':{'stateOrProvince':'value'}},
178
+ "https://gedcom.io/terms/v7/STAT": {},
179
+ "https://gedcom.io/terms/v7/SUBM": {},
180
+ "https://gedcom.io/terms/v7/SUBM-LANG": {},
181
+ "https://gedcom.io/terms/v7/SURN": {'class':NamePart,
182
+ 'args':{'type':NamePartType.Surname,'value':'rTextValue'}
183
+ },
184
+ "https://gedcom.io/terms/v7/TAG": {},
185
+ "https://gedcom.io/terms/v7/TEMP": {},
186
+ "https://gedcom.io/terms/v7/TEXT": {},
187
+ "https://gedcom.io/terms/v7/TIME": {},
188
+ "https://gedcom.io/terms/v7/TITL": {'type':'PropertyObject','Object':TextValue,'Args':{'value':'value'},'propertyof':[SourceDescription],'method':'add_title'},
189
+ "https://gedcom.io/terms/v7/TOP": {},
190
+ "https://gedcom.io/terms/v7/TRAN": {},
191
+ "https://gedcom.io/terms/v7/TRLR": {},
192
+ "https://gedcom.io/terms/v7/TYPE": {'type':'Object','Object':Note,'Args':{'text':'value'},'propertyof':[Fact],'method':'add_note'},
193
+ "https://gedcom.io/terms/v7/UID": {},
194
+ "https://gedcom.io/terms/v7/VERS": {},
195
+ "https://gedcom.io/terms/v7/WIDTH": {},
196
+ "https://gedcom.io/terms/v7/WIFE": {},
197
+ "https://gedcom.io/terms/v7/WILL": {},
198
+ "https://gedcom.io/terms/v7/WWW": {},
199
+ "https://gedcom.io/terms/v7/enumset-ADOP": {},
200
+ "https://gedcom.io/terms/v7/enumset-EVEN": {},
201
+ "https://gedcom.io/terms/v7/enumset-EVENATTR": {},
202
+ "https://gedcom.io/terms/v7/enumset-FAMC-STAT": {},
203
+ "https://gedcom.io/terms/v7/enumset-MEDI": {},
204
+ "https://gedcom.io/terms/v7/enumset-NAME-TYPE": {},
205
+ "https://gedcom.io/terms/v7/enumset-PEDI": {},
206
+ "https://gedcom.io/terms/v7/enumset-QUAY": {},
207
+ "https://gedcom.io/terms/v7/enumset-RESN": {},
208
+ "https://gedcom.io/terms/v7/enumset-ROLE": {},
209
+ "https://gedcom.io/terms/v7/enumset-SEX": {},
210
+ "https://gedcom.io/terms/v7/ord-STAT": {},
211
+ "https://gedcom.io/terms/v7/record-FAM": {'type':'TopLevelObject','Object':Relationship,'Args':{'id':'xref'}},
212
+ "https://gedcom.io/terms/v7/record-INDI": {'type':'TopLevelObject','Object':Person,'Args':{'id':'xref'}},
213
+ "https://gedcom.io/terms/v7/record-OBJE": {'type':'TopLevelObject','Object':SourceDescription, 'Args':{'id':'xref'}},
214
+ "https://gedcom.io/terms/v7/record-REPO": {'type':'TopLevelObject','Object':Agent,'Args':{'id':'xref'}},
215
+ "https://gedcom.io/terms/v7/record-SNOTE": {},
216
+ "https://gedcom.io/terms/v7/record-SOUR": {'type':'TopLevelObject','Object':SourceDescription,'Args':{'id':'xref'}},
217
+ "https://gedcom.io/terms/v7/record-SUBM": {'type':'Object','Object':Resource,'Args':{'Id':'xref'}},
218
+ }
382
219
 
383
220
  class Translater():
384
221
  def __init__(self,gedcom: Gedcom5x) -> None:
@@ -482,7 +319,7 @@ class Translater():
482
319
  }
483
320
 
484
321
  @staticmethod
485
- def clean_str(text: str) -> str:
322
+ def clean_str(text: str) -> str | None:
486
323
  # Regular expression to match HTML/XML tags
487
324
  if text is None or text.strip() == '':
488
325
  return None
@@ -531,7 +368,7 @@ class Translater():
531
368
  return {'BIRT':EventType.Birth,
532
369
  'OBIT':FactType.Obituary}
533
370
 
534
- def parse_record(self,record: GedcomRecord):
371
+ def parse_record(self,record: Gedcom5xRecord):
535
372
 
536
373
  handler_name = 'handle_' + record.tag.lower()
537
374
 
@@ -549,7 +386,7 @@ class Translater():
549
386
  for sub_record in record.subRecords():
550
387
  self.parse_record(sub_record)
551
388
 
552
- def handle__apid(self, record: GedcomRecord):
389
+ def handle__apid(self, record: Gedcom5xRecord):
553
390
  if isinstance(self.object_map[record.level-1], SourceReference):
554
391
  self.object_map[record.level-1].description.add_identifier(Identifier(value=URI.from_url('APID://' + record.value)))
555
392
  elif isinstance(self.object_map[record.level-1], SourceDescription):
@@ -557,7 +394,7 @@ class Translater():
557
394
  else:
558
395
  raise ValueError(f"Could not handle '_APID' tag in record {record.describe()}, last stack object {type(self.object_map[record.level-1])}")
559
396
 
560
- def handle__meta(self, record: GedcomRecord):
397
+ def handle__meta(self, record: Gedcom5xRecord):
561
398
  if isinstance(self.object_map[record.level-1], SourceDescription):
562
399
  gxobject = Note(text=Translater.clean_str(record.value))
563
400
  self.object_map[record.level-1].add_note(gxobject)
@@ -566,10 +403,10 @@ class Translater():
566
403
  else:
567
404
  raise ValueError(f"Could not handle 'WWW' tag in record {record.describe()}, last stack object {self.object_map[record.level-1]}")
568
405
 
569
- def handle__wlnk(self, record: GedcomRecord):
406
+ def handle__wlnk(self, record: Gedcom5xRecord):
570
407
  return self.handle_sour(record)
571
408
 
572
- def handle_addr(self, record: GedcomRecord):
409
+ def handle_addr(self, record: Gedcom5xRecord):
573
410
  if isinstance(self.object_map[record.level-1], Agent):
574
411
  # TODO CHeck if URL?
575
412
  if Translater.clean_str(record.value):
@@ -582,70 +419,70 @@ class Translater():
582
419
  else:
583
420
  raise ValueError(f"I do not know how to handle an 'ADDR' tag for a {type(self.object_map[record.level-1])}")
584
421
 
585
- def handle_adr1(self, record: GedcomRecord):
422
+ def handle_adr1(self, record: Gedcom5xRecord):
586
423
  if isinstance(self.object_map[record.level-1], Address):
587
424
  if Translater.clean_str(record.value):
588
425
  self.object_map[record.level-1].street = Translater.clean_str(record.value)
589
426
  else:
590
427
  raise ValueError(f"I do not know how to handle an 'ADR1' tag for a {type(self.object_map[record.level-1])}")
591
428
 
592
- def handle_adr2(self, record: GedcomRecord):
429
+ def handle_adr2(self, record: Gedcom5xRecord):
593
430
  if isinstance(self.object_map[record.level-1], Address):
594
431
  if Translater.clean_str(record.value):
595
432
  self.object_map[record.level-1].street2 = Translater.clean_str(record.value)
596
433
  else:
597
434
  raise ValueError(f"I do not know how to handle an 'ADR2' tag for a {type(self.object_map[record.level-1])}")
598
435
 
599
- def handle_adr3(self, record: GedcomRecord):
436
+ def handle_adr3(self, record: Gedcom5xRecord):
600
437
  if isinstance(self.object_map[record.level-1], Address):
601
438
  if Translater.clean_str(record.value):
602
439
  self.object_map[record.level-1].street3 = Translater.clean_str(record.value)
603
440
  else:
604
441
  raise ValueError(f"I do not know how to handle an 'ADR3' tag for a {type(self.object_map[record.level-1])}")
605
442
 
606
- def handle_adr4(self, record: GedcomRecord):
443
+ def handle_adr4(self, record: Gedcom5xRecord):
607
444
  if isinstance(self.object_map[record.level-1], Address):
608
445
  if Translater.clean_str(record.value):
609
446
  self.object_map[record.level-1].street4 = Translater.clean_str(record.value)
610
447
  else:
611
448
  raise ValueError(f"I do not know how to handle an 'ADR4' tag for a {type(self.object_map[record.level-1])}")
612
449
 
613
- def handle_adr5(self, record: GedcomRecord):
450
+ def handle_adr5(self, record: Gedcom5xRecord):
614
451
  if isinstance(self.object_map[record.level-1], Address):
615
452
  if Translater.clean_str(record.value):
616
453
  self.object_map[record.level-1].street5 = Translater.clean_str(record.value)
617
454
  else:
618
455
  raise ValueError(f"I do not know how to handle an 'ADR5' tag for a {type(self.object_map[record.level-1])}")
619
456
 
620
- def handle_adr6(self, record: GedcomRecord):
457
+ def handle_adr6(self, record: Gedcom5xRecord):
621
458
  if isinstance(self.object_map[record.level-1], Address):
622
459
  if Translater.clean_str(record.value):
623
460
  self.object_map[record.level-1].street5 = Translater.clean_str(record.value)
624
461
  else:
625
462
  raise ValueError(f"I do not know how to handle an 'ADR6' tag for a {type(self.object_map[record.level-1])}")
626
463
 
627
- def handle_phon(self, record: GedcomRecord):
464
+ def handle_phon(self, record: Gedcom5xRecord):
628
465
  if isinstance(self.object_map[record.level-1], Agent):
629
466
  if Translater.clean_str(record.value):
630
467
  self.object_map[record.level-1].phones.append(Translater.clean_str(record.value))
631
468
  else:
632
469
  raise ValueError(f"I do not know how to handle an '{record.tag}' tag for a {type(self.object_map[record.level-1])}")
633
470
 
634
- def handle_email(self, record: GedcomRecord):
471
+ def handle_email(self, record: Gedcom5xRecord):
635
472
  if isinstance(self.object_map[record.level-1], Agent):
636
473
  if Translater.clean_str(record.value):
637
474
  self.object_map[record.level-1].emails.append(Translater.clean_str(record.value))
638
475
  else:
639
476
  raise ValueError(f"I do not know how to handle an '{record.tag}' tag for a {type(self.object_map[record.level-1])}")
640
477
 
641
- def handle_fax(self, record: GedcomRecord):
478
+ def handle_fax(self, record: Gedcom5xRecord):
642
479
  if isinstance(self.object_map[record.level-1], Agent):
643
480
  if Translater.clean_str(record.value):
644
481
  self.object_map[record.level-1].emails.append('FAX:' + Translater.clean_str(record.value))
645
482
  else:
646
483
  raise ValueError(f"I do not know how to handle an '{record.tag}' tag for a {type(self.object_map[record.level-1])}")
647
484
 
648
- def handle_adop(self, record: GedcomRecord):
485
+ def handle_adop(self, record: Gedcom5xRecord):
649
486
  if isinstance(self.object_map[record.level-1], Person):
650
487
  gxobject = Fact(type=FactType.Adoption)
651
488
  self.object_map[record.level-1].add_fact(gxobject)
@@ -655,7 +492,7 @@ class Translater():
655
492
  else:
656
493
  raise TagConversionError(record=record,levelstack=self.object_map)
657
494
 
658
- def handle_auth(self, record: GedcomRecord):
495
+ def handle_auth(self, record: Gedcom5xRecord):
659
496
  if isinstance(self.object_map[record.level-1], SourceDescription):
660
497
  if self.gedcomx.agents.byName(record.value):
661
498
  gxobject = self.gedcomx.agents.byName(record.value)[0]
@@ -669,7 +506,7 @@ class Translater():
669
506
  else:
670
507
  raise TagConversionError(record=record,levelstack=self.object_map)
671
508
 
672
- def handle_bapm(self, record: GedcomRecord):
509
+ def handle_bapm(self, record: Gedcom5xRecord):
673
510
  if isinstance(self.object_map[record.level-1], Person):
674
511
  gxobject = Fact(type=FactType.Baptism)
675
512
  self.object_map[record.level-1].add_fact(gxobject)
@@ -679,7 +516,7 @@ class Translater():
679
516
  else:
680
517
  raise TagConversionError(record=record,levelstack=self.object_map)
681
518
 
682
- def handle_birt(self, record: GedcomRecord):
519
+ def handle_birt(self, record: Gedcom5xRecord):
683
520
  if isinstance(self.object_map[record.level-1], Person):
684
521
  #gxobject = Event(type=EventType.BIRTH, roles=[EventRole(person=self.object_map[record.level-1], type=EventRoleType.Principal)])
685
522
  gxobject = Fact(type=FactType.Birth)
@@ -691,7 +528,7 @@ class Translater():
691
528
  else:
692
529
  raise TagConversionError(record=record,levelstack=self.object_map)
693
530
 
694
- def handle_buri(self, record: GedcomRecord):
531
+ def handle_buri(self, record: Gedcom5xRecord):
695
532
  if isinstance(self.object_map[record.level-1], Person):
696
533
  gxobject = Fact(type=FactType.Burial)
697
534
  self.object_map[record.level-1].add_fact(gxobject)
@@ -701,7 +538,7 @@ class Translater():
701
538
  else:
702
539
  raise TagConversionError(record=record,levelstack=self.object_map)
703
540
 
704
- def handle_caln(self, record: GedcomRecord):
541
+ def handle_caln(self, record: Gedcom5xRecord):
705
542
  if isinstance(self.object_map[record.level-1], SourceReference):
706
543
  self.object_map[record.level-1].description.add_identifier(Identifier(value=URI.from_url('Call Number:' + record.value)))
707
544
  elif isinstance(self.object_map[record.level-1], SourceDescription):
@@ -712,7 +549,7 @@ class Translater():
712
549
  else:
713
550
  raise ValueError(f"Could not handle 'CALN' tag in record {record.describe()}, last stack object {type(self.object_map[record.level-1])}")
714
551
 
715
- def handle_chan(self, record: GedcomRecord):
552
+ def handle_chan(self, record: Gedcom5xRecord):
716
553
  if isinstance(self.object_map[record.level-1], SourceDescription):
717
554
  self.object_map[record.level-1].created = Date(record.subRecord('DATE'))
718
555
  elif isinstance(self.object_map[record.level-1], Agent):
@@ -724,7 +561,7 @@ class Translater():
724
561
  else:
725
562
  raise ValueError()
726
563
 
727
- def handle_chr(self, record: GedcomRecord):
564
+ def handle_chr(self, record: Gedcom5xRecord):
728
565
  if isinstance(self.object_map[record.level-1], Person):
729
566
  gxobject = Fact(type=FactType.Christening)
730
567
  self.object_map[record.level-1].add_fact(gxobject)
@@ -734,13 +571,13 @@ class Translater():
734
571
  else:
735
572
  raise TagConversionError(record=record,levelstack=self.object_map)
736
573
 
737
- def handle_city(self, record: GedcomRecord):
574
+ def handle_city(self, record: Gedcom5xRecord):
738
575
  if isinstance(self.object_map[record.level-1], Address):
739
576
  self.object_map[record.level-1].city = Translater.clean_str(record.value)
740
577
  else:
741
578
  raise ValueError(f"I do not know how to handle an 'CITY' tag for a {type(self.object_map[record.level-1])}")
742
579
 
743
- def handle_conc(self, record: GedcomRecord):
580
+ def handle_conc(self, record: Gedcom5xRecord):
744
581
  if isinstance(self.object_map[record.level-1], Note):
745
582
  gxobject = Translater.clean_str(str(record.value))
746
583
  self.object_map[record.level-1].append(gxobject)
@@ -761,7 +598,7 @@ class Translater():
761
598
  else:
762
599
  raise TagConversionError(record=record,levelstack=self.object_map)
763
600
 
764
- def handle_cont(self, record: GedcomRecord):
601
+ def handle_cont(self, record: Gedcom5xRecord):
765
602
  if isinstance(self.object_map[record.level-1], Note):
766
603
  gxobject = str("\n" + record.value if record.value else '')
767
604
  self.object_map[record.level-1].append(gxobject)
@@ -780,7 +617,7 @@ class Translater():
780
617
  else:
781
618
  raise TagConversionError(record=record,levelstack=self.object_map)
782
619
 
783
- def handle_crea(self, record: GedcomRecord):
620
+ def handle_crea(self, record: Gedcom5xRecord):
784
621
  if isinstance(self.object_map[record.level-1], SourceDescription):
785
622
  self.object_map[record.level-1].created = Date(original=record.subRecord('DATE'))
786
623
 
@@ -795,18 +632,18 @@ class Translater():
795
632
  else:
796
633
  raise ValueError(f"Could not handle '{record.tag}' tag in record {record.describe()}, last stack object {self.object_map[record.level-1]}")
797
634
 
798
- def handle_ctry(self, record: GedcomRecord):
635
+ def handle_ctry(self, record: Gedcom5xRecord):
799
636
  if isinstance(self.object_map[record.level-1], Address):
800
637
  self.object_map[record.level-1].country = Translater.clean_str(record.value)
801
638
  else:
802
639
  raise ValueError(f"I do not know how to handle an '{record.tag}' tag for a {type(self.object_map[record.level-1])}")
803
640
 
804
- def handle_data(self, record: GedcomRecord) -> None:
641
+ def handle_data(self, record: Gedcom5xRecord) -> None:
805
642
  if record.value != '' and record.value == 'None':
806
643
  assert False
807
644
  self.object_map[record.level] = self.object_map[record.level-1]
808
645
 
809
- def handle_date(self, record: GedcomRecord):
646
+ def handle_date(self, record: Gedcom5xRecord):
810
647
  if record.parent.tag == 'PUBL':
811
648
  #gxobject = Date(original=record.value) #TODO Make a parser for solid timestamps
812
649
  #self.object_map[0].published = gxobject
@@ -837,7 +674,7 @@ class Translater():
837
674
  else:
838
675
  raise TagConversionError(record=record,levelstack=self.object_map)
839
676
 
840
- def handle_deat(self, record: GedcomRecord):
677
+ def handle_deat(self, record: Gedcom5xRecord):
841
678
  if isinstance(self.object_map[record.level-1], Person):
842
679
  gxobject = Fact(type=FactType.Death)
843
680
  self.object_map[record.level-1].add_fact(gxobject)
@@ -847,7 +684,7 @@ class Translater():
847
684
  else:
848
685
  raise TagConversionError(record=record,levelstack=self.object_map)
849
686
 
850
- def handle_even(self, record: GedcomRecord):
687
+ def handle_even(self, record: Gedcom5xRecord):
851
688
  # TODO If events in a @S, check if only 1 person matches?
852
689
  if record.value and (not record.value.strip() == ''):
853
690
  values = [value.strip() for value in record.value.split(",")]
@@ -905,14 +742,14 @@ class Translater():
905
742
  else:
906
743
  assert False
907
744
 
908
- def handle_exid(self,record: GedcomRecord):
745
+ def handle_exid(self,record: Gedcom5xRecord):
909
746
  gxobject = Identifier(type=IdentifierType.External,value=[record.value])
910
747
  self.object_map[record.level-1].add_identifier(gxobject)
911
748
 
912
749
  self.object_stack.append(gxobject)
913
750
  self.object_map[record.level] = gxobject
914
751
 
915
- def handle_fam(self, record: GedcomRecord) -> None:
752
+ def handle_fam(self, record: Gedcom5xRecord) -> None:
916
753
  if record.tag != 'FAM' or record.level != 0:
917
754
  raise ValueError("Invalid record: Must be a level 0 FAM record")
918
755
 
@@ -945,13 +782,13 @@ class Translater():
945
782
  relationship = Relationship(person1=husband, person2=wife, type=RelationshipType.Couple)
946
783
  self.gedcomx.add_relationship(relationship)
947
784
 
948
- def handle_famc(self, record: GedcomRecord) -> None:
785
+ def handle_famc(self, record: Gedcom5xRecord) -> None:
949
786
  return
950
787
 
951
- def handle_fams(self, record: GedcomRecord) -> None:
788
+ def handle_fams(self, record: Gedcom5xRecord) -> None:
952
789
  return
953
790
 
954
- def handle_file(self, record: GedcomRecord):
791
+ def handle_file(self, record: Gedcom5xRecord):
955
792
  if record.value and record.value.strip() != '':
956
793
  #raise ValueError(f"I did not expect the 'FILE' tag to have a value: {record.value}")
957
794
  #TODO Handle files referenced here
@@ -960,7 +797,7 @@ class Translater():
960
797
  ...
961
798
  self.object_map[record.level-1].resourceType = ResourceType.DigitalArtifact
962
799
 
963
- def handle_form(self, record: GedcomRecord):
800
+ def handle_form(self, record: Gedcom5xRecord):
964
801
  if record.parent.tag == 'FILE' and isinstance(self.object_map[record.level-2], SourceDescription):
965
802
  if record.value and record.value.strip() != '':
966
803
  mime_type, _ = mimetypes.guess_type('placehold.' + record.value)
@@ -975,20 +812,20 @@ class Translater():
975
812
  else:
976
813
  convert_log.error(f"raise TagConversionError(record=record,levelstack=self.object_map")
977
814
 
978
- def handle_givn(self, record: GedcomRecord):
815
+ def handle_givn(self, record: Gedcom5xRecord):
979
816
  if isinstance(self.object_map[record.level-1], Name):
980
817
  given_name = NamePart(value=record.value, type=NamePartType.Given)
981
818
  self.object_map[record.level-1]._add_name_part(given_name)
982
819
  else:
983
820
  raise TagConversionError(record=record,levelstack=self.object_map)
984
821
 
985
- def handle_indi(self, record: GedcomRecord):
822
+ def handle_indi(self, record: Gedcom5xRecord):
986
823
  person = Person(id=record.xref.replace('@',''))
987
824
  self.gedcomx.add_person(person)
988
825
  self.object_stack.append(person)
989
826
  self.object_map[record.level] = person
990
827
 
991
- def handle_immi(self, record: GedcomRecord):
828
+ def handle_immi(self, record: Gedcom5xRecord):
992
829
  if isinstance(self.object_map[record.level-1], Person):
993
830
  gxobject = Fact(type=FactType.Immigration)
994
831
  self.object_map[record.level-1].add_fact(gxobject)
@@ -998,7 +835,7 @@ class Translater():
998
835
  else:
999
836
  raise TagConversionError(record=record,levelstack=self.object_map)
1000
837
 
1001
- def handle_marr(self, record: GedcomRecord):
838
+ def handle_marr(self, record: Gedcom5xRecord):
1002
839
  if isinstance(self.object_map[record.level-1], Person):
1003
840
  gxobject = Fact(type=FactType.Marriage)
1004
841
  self.object_map[record.level-1].add_fact(gxobject)
@@ -1008,7 +845,7 @@ class Translater():
1008
845
  else:
1009
846
  raise TagConversionError(record=record,levelstack=self.object_map)
1010
847
 
1011
- def handle_name(self, record: GedcomRecord):
848
+ def handle_name(self, record: Gedcom5xRecord):
1012
849
  if isinstance(self.object_map[record.level-1], Person):
1013
850
  gxobject = Name.simple(record.value)
1014
851
  #gxobject = Name(nameForms=[NameForm(fullText=record.value)], type=NameType.BirthName)
@@ -1022,7 +859,7 @@ class Translater():
1022
859
  else:
1023
860
  raise TagConversionError(record=record,levelstack=self.object_map)
1024
861
 
1025
- def handle_note(self, record: GedcomRecord):
862
+ def handle_note(self, record: Gedcom5xRecord):
1026
863
  if isinstance(self.object_map[record.level-1], SourceDescription):
1027
864
  gxobject = Note(text=Translater.clean_str(record.value))
1028
865
  self.object_map[record.level-1].add_note(gxobject)
@@ -1063,14 +900,14 @@ class Translater():
1063
900
  raise ValueError(f"Could not handle 'NOTE' tag in record {record.describe()}, last stack object {type(self.object_map[record.level-1])}")
1064
901
  assert False
1065
902
 
1066
- def handle_nsfx(self, record: GedcomRecord):
903
+ def handle_nsfx(self, record: Gedcom5xRecord):
1067
904
  if isinstance(self.object_map[record.level-1], Name):
1068
905
  surname = NamePart(value=record.value, type=NamePartType.Suffix)
1069
906
  self.object_map[record.level-1]._add_name_part(surname)
1070
907
  else:
1071
908
  raise TagConversionError(record=record,levelstack=self.object_map)
1072
909
 
1073
- def handle_occu(self, record: GedcomRecord):
910
+ def handle_occu(self, record: Gedcom5xRecord):
1074
911
  if isinstance(self.object_map[record.level-1], Person):
1075
912
  gxobject = Fact(type=FactType.Occupation)
1076
913
  self.object_map[record.level-1].add_fact(gxobject)
@@ -1080,10 +917,10 @@ class Translater():
1080
917
  else:
1081
918
  raise TagConversionError(record=record,levelstack=self.object_map)
1082
919
 
1083
- def handle_obje(self, record: GedcomRecord):
920
+ def handle_obje(self, record: Gedcom5xRecord):
1084
921
  self.handle_sour(record)
1085
922
 
1086
- def handle_page(self, record: GedcomRecord):
923
+ def handle_page(self, record: Gedcom5xRecord):
1087
924
  if isinstance(self.object_map[record.level-1], SourceReference):
1088
925
  self.object_map[record.level-1].descriptionId = record.value
1089
926
  self.object_map[record.level-1].add_qualifier(KnownSourceReference(name=str(KnownSourceReference.Page),value=record.value))
@@ -1094,7 +931,7 @@ class Translater():
1094
931
  else:
1095
932
  raise ValueError(f"Could not handle 'PAGE' tag in record {record.describe()}, last stack object {self.object_map[record.level-1]}")
1096
933
 
1097
- def handle_plac(self, record: GedcomRecord):
934
+ def handle_plac(self, record: Gedcom5xRecord):
1098
935
  if isinstance(self.object_map[record.level-1], Agent):
1099
936
  gxobject = Address(value=record.value)
1100
937
  self.object_map[record.level-1].add_address(gxobject)
@@ -1126,13 +963,13 @@ class Translater():
1126
963
  else:
1127
964
  raise TagConversionError(record=record,levelstack=self.object_map)
1128
965
 
1129
- def handle_post(self, record: GedcomRecord):
966
+ def handle_post(self, record: Gedcom5xRecord):
1130
967
  if isinstance(self.object_map[record.level-1], Address):
1131
968
  self.object_map[record.level-1].postalCode = Translater.clean_str(record.value)
1132
969
  else:
1133
970
  raise ValueError(f"I do not know how to handle an 'POST' tag for a {type(self.object_map[record.level-1])}")
1134
971
 
1135
- def handle_publ(self, record: GedcomRecord):
972
+ def handle_publ(self, record: Gedcom5xRecord):
1136
973
  if isinstance(self.object_map[record.level-1], SourceDescription):
1137
974
  if record.value and self.gedcomx.agents.byName(record.value):
1138
975
  gxobject = self.gedcomx.agents.byName(record.value)[0]
@@ -1146,7 +983,7 @@ class Translater():
1146
983
  else:
1147
984
  raise TagConversionError(record=record,levelstack=self.object_map)
1148
985
 
1149
- def handle_prob(self, record: GedcomRecord):
986
+ def handle_prob(self, record: Gedcom5xRecord):
1150
987
  if isinstance(self.object_map[record.level-1], Person):
1151
988
  gxobject = Fact(type=FactType.Probate)
1152
989
  self.object_map[record.level-1].add_fact(gxobject)
@@ -1156,14 +993,14 @@ class Translater():
1156
993
  else:
1157
994
  raise TagConversionError(record=record,levelstack=self.object_map)
1158
995
 
1159
- def handle_uid(self, record: GedcomRecord):
996
+ def handle_uid(self, record: Gedcom5xRecord):
1160
997
  if isinstance(self.object_map[record.level-1], Agent):
1161
998
  gxobject = Identifier(value=['UID:' + record.value],type=IdentifierType.Primary)
1162
999
  self.object_map[record.level-1].add_identifier(gxobject) #NOTE GC7
1163
1000
  self.object_stack.append(gxobject)
1164
1001
  self.object_map[record.level] = gxobject
1165
1002
 
1166
- def handle_refn(self, record: GedcomRecord):
1003
+ def handle_refn(self, record: Gedcom5xRecord):
1167
1004
  if isinstance(self.object_map[record.level-1], Person) or isinstance(self.object_map[record.level-1], SourceDescription):
1168
1005
  gxobject = Identifier(value=[URI.from_url('Reference Number:' + record.value)])
1169
1006
  self.object_map[record.level-1].add_identifier(gxobject)
@@ -1177,7 +1014,7 @@ class Translater():
1177
1014
  else:
1178
1015
  raise ValueError(f"Could not handle 'REFN' tag in record {record.describe()}, last stack object {type(self.object_map[record.level-1])}")
1179
1016
 
1180
- def handle_repo(self, record: GedcomRecord):
1017
+ def handle_repo(self, record: Gedcom5xRecord):
1181
1018
 
1182
1019
  if record.level == 0:
1183
1020
 
@@ -1205,7 +1042,7 @@ class Translater():
1205
1042
  self.object_stack.append(gxobject)
1206
1043
  self.object_map[record.level] = gxobject
1207
1044
 
1208
- def handle_resi(self, record: GedcomRecord):
1045
+ def handle_resi(self, record: Gedcom5xRecord):
1209
1046
  if isinstance(self.object_map[record.level-1], Person):
1210
1047
  gxobject = Fact(type=FactType.Residence)
1211
1048
  if record.value and record.value.strip() != '':
@@ -1217,7 +1054,7 @@ class Translater():
1217
1054
  else:
1218
1055
  raise TagConversionError(record=record,levelstack=self.object_map)
1219
1056
 
1220
- def handle_rin(self, record: GedcomRecord):
1057
+ def handle_rin(self, record: Gedcom5xRecord):
1221
1058
  if isinstance(self.object_map[record.level-1], SourceDescription):
1222
1059
  self.object_map[record.level-1].id = record.value
1223
1060
  self.object_map[record.level-1].add_note(Note(text=f"Source had RIN: of {record.value}"))
@@ -1225,7 +1062,7 @@ class Translater():
1225
1062
  else:
1226
1063
  raise ValueError(f"Could not handle 'RIN' tag in record {record.describe()}, last stack object {type(self.object_map[record.level-1])}")
1227
1064
 
1228
- def handle_sex(self, record: GedcomRecord):
1065
+ def handle_sex(self, record: Gedcom5xRecord):
1229
1066
 
1230
1067
  if isinstance(self.object_map[record.level-1], Person):
1231
1068
  if record.value == 'M':
@@ -1241,7 +1078,7 @@ class Translater():
1241
1078
  else:
1242
1079
  assert False
1243
1080
 
1244
- def handle_sour(self, record: GedcomRecord):
1081
+ def handle_sour(self, record: Gedcom5xRecord):
1245
1082
  if record.level == 0 or record.tag == '_WLNK' or (record.level == 0 and record.tag == 'OBJE'):
1246
1083
  source_description = SourceDescription(id=record.xref.replace('@','') if record.xref else None)
1247
1084
  self.gedcomx.add_source_description(source_description)
@@ -1267,20 +1104,20 @@ class Translater():
1267
1104
  self.object_stack.append(gxobject)
1268
1105
  self.object_map[record.level] = gxobject
1269
1106
 
1270
- def handle_stae(self, record: GedcomRecord):
1107
+ def handle_stae(self, record: Gedcom5xRecord):
1271
1108
  if isinstance(self.object_map[record.level-1], Address):
1272
1109
  self.object_map[record.level-1].stateOrProvince = Translater.clean_str(record.value)
1273
1110
  else:
1274
1111
  raise ValueError(f"I do not know how to handle an 'STAE' tag for a {type(self.object_map[record.level-1])}")
1275
1112
 
1276
- def handle_surn(self, record: GedcomRecord):
1113
+ def handle_surn(self, record: Gedcom5xRecord):
1277
1114
  if isinstance(self.object_map[record.level-1], Name):
1278
1115
  surname = NamePart(value=record.value, type=NamePartType.Surname)
1279
1116
  self.object_map[record.level-1]._add_name_part(surname)
1280
1117
  else:
1281
1118
  raise TagConversionError(record=record,levelstack=self.object_map)
1282
1119
 
1283
- def handle_text(self, record: GedcomRecord):
1120
+ def handle_text(self, record: Gedcom5xRecord):
1284
1121
  if record.parent.tag == 'DATA':
1285
1122
  if isinstance(self.object_map[record.level-2], SourceReference):
1286
1123
  gxobject = TextValue(value=record.value)
@@ -1293,7 +1130,7 @@ class Translater():
1293
1130
  else:
1294
1131
  assert False
1295
1132
 
1296
- def handle_titl(self, record: GedcomRecord):
1133
+ def handle_titl(self, record: Gedcom5xRecord):
1297
1134
  if isinstance(self.object_map[record.level-1], SourceDescription):
1298
1135
 
1299
1136
  gxobject = TextValue(value=Translater.clean_str(record.value))
@@ -1315,10 +1152,10 @@ class Translater():
1315
1152
  else:
1316
1153
  convert_log.error(f"raise TagConversionError(record=record,levelstack=self.object_map)")
1317
1154
 
1318
- def handle_tran(self, record: GedcomRecord):
1155
+ def handle_tran(self, record: Gedcom5xRecord):
1319
1156
  pass
1320
1157
 
1321
- def handle_type(self, record: GedcomRecord):
1158
+ def handle_type(self, record: Gedcom5xRecord):
1322
1159
  # peek to see if event or fact
1323
1160
  if isinstance(self.object_map[record.level-1], Event):
1324
1161
  if EventType.guess(record.value):
@@ -1341,13 +1178,13 @@ class Translater():
1341
1178
  else:
1342
1179
  raise ValueError(f"I do not know how to handle 'TYPE' tag for {type(self.object_map[record.level-1])}")
1343
1180
 
1344
- def handle__url(self, record: GedcomRecord):
1181
+ def handle__url(self, record: Gedcom5xRecord):
1345
1182
  if isinstance(self.object_map[record.level-2], SourceDescription):
1346
1183
  self.object_map[record.level-2].about = URI.from_url(record.value)
1347
1184
  else:
1348
1185
  raise ValueError(f"Could not handle '_URL' tag in record {record.describe()}, last stack object {self.object_map[record.level-1]}")
1349
1186
 
1350
- def handle_www(self, record: GedcomRecord):
1187
+ def handle_www(self, record: Gedcom5xRecord):
1351
1188
  if isinstance(self.object_map[record.level-1], Agent):
1352
1189
  self.object_map[record.level-1].homepage = Translater.clean_str(record.value)
1353
1190
  elif isinstance(self.object_map[record.level-2], SourceReference):