diff --git a/MANIFEST.in b/MANIFEST.in index b2e106f..4f4a654 100644 --- a/MANIFEST.in +++ b/MANIFEST.in @@ -15,9 +15,7 @@ exclude logo.png exclude docs recursive-exclude docs * recursive-exclude gedcom *.md - -# Include GEDCOM test files -include tests/files/*.ged +recursive-exclude tests * # Exclude Node related files exclude .nvmrc diff --git a/Pipfile b/Pipfile index 59b90df..642e6a1 100644 --- a/Pipfile +++ b/Pipfile @@ -11,6 +11,8 @@ tox = "*" pdoc3 = "*" [packages] +chardet = "*" +ansel = "*" [requires] python_version = "3.5" diff --git a/Pipfile.lock b/Pipfile.lock index 6e99c0c..3e13e07 100644 --- a/Pipfile.lock +++ b/Pipfile.lock @@ -1,7 +1,7 @@ { "_meta": { "hash": { - "sha256": "ff4ffecf922d35b96c175b7a2a6e76ba732f698d575beb753c2742046c2da00d" + "sha256": "25eda2701127ac3899d81381bca449f6bcc14ee7afe4ae9c5b2f683afd95dd03" }, "pipfile-spec": 6, "requires": { @@ -15,34 +15,59 @@ } ] }, - "default": {}, + "default": { + "ansel": { + "hashes": [ + "sha256:27c1a849b1a683a2b3befd50e9156bda3527e8026f6bc6f04c3d0a2b9cadeed9", + "sha256:3cb2c6a726dcf674bcd1cbd1fc4f35b80167b1c090ea94f6bc60c70f4e615eab" + ], + "index": "pypi", + "version": "==0.1.1" + }, + "chardet": { + "hashes": [ + "sha256:84ab92ed1c4d4f16916e05906b6b75a6c0fb5db821cc65e70cbd64a3e2a5eaae", + "sha256:fc323ffcaeaed0e0a02bf4d117757b98aed530d9ed4531e3e15460124c106691" + ], + "index": "pypi", + "version": "==3.0.4" + }, + "six": { + "hashes": [ + "sha256:30639c035cdb23534cd4aa2dd52c3bf48f06e5f4a941509c8bafd8ce11080259", + "sha256:8b74bedcbbbaca38ff6d7491d76f2b06b3592611af620f8426e82dddb04a5ced" + ], + "version": "==1.15.0" + } + }, "develop": { "appdirs": { "hashes": [ - "sha256:9e5896d1372858f8dd3344faf4e5014d21849c756c8d5701f78f8a103b372d92", - "sha256:d8b24664561d0d34ddfaec54636d502d7cea6e29c3eaf68f3df6180863e2166e" + "sha256:7d5d0167b2b1ba821647616af46a749d1c653740dd0d2415100fe26e27afdf41", + "sha256:a841dacd6b99318a741b166adb07e19ee71a274450e68237b4650ca1055ab128" ], - "version": "==1.4.3" + "version": "==1.4.4" }, "bleach": { "hashes": [ - "sha256:53165a6596e7899c4338d847315fec508110a53bd6fd15c127c2e0d0860264e3", - "sha256:f8dfd8a7e26443e986c4e44df31870da8e906ea61096af06ba5d5cc2d519842a" + "sha256:2bce3d8fab545a6528c8fa5d9f9ae8ebc85a56da365c7f85180bfe96a35ef22f", + "sha256:3c4c520fdb9db59ef139915a5db79f8b51bc2a7257ea0389f30c846883430a4b" ], - "version": "==3.1.3" + "version": "==3.1.5" }, "certifi": { "hashes": [ - "sha256:017c25db2a153ce562900032d5bc68e9f191e44e9a0f762f373977de9df1fbb3", - "sha256:25b64c7da4cd7479594d035c08c2d809eb4aab3a26e5a990ea98cc450c320f1f" + "sha256:1d987a998c75633c40847cc966fcf5904906c920a7f17ef374f5aa4282abd304", + "sha256:51fcb31174be6e6664c5f69e3e1691a2d72a1a12e90f872cbdb1567eb47b6519" ], - "version": "==2019.11.28" + "version": "==2020.4.5.1" }, "chardet": { "hashes": [ "sha256:84ab92ed1c4d4f16916e05906b6b75a6c0fb5db821cc65e70cbd64a3e2a5eaae", "sha256:fc323ffcaeaed0e0a02bf4d117757b98aed530d9ed4531e3e15460124c106691" ], + "index": "pypi", "version": "==3.0.4" }, "distlib": { @@ -74,19 +99,19 @@ }, "importlib-metadata": { "hashes": [ - "sha256:06f5b3a99029c7134207dd882428a66992a9de2bef7c2b699b5641f9886c3302", - "sha256:b97607a1a18a5100839aec1dc26a1ea17ee0d93b20b0f008d80a5a050afb200b" + "sha256:2a688cbaa90e0cc587f1df48bdc97a6eadccdcd9c35fb3f976a09e3b5016d90f", + "sha256:34513a8a0c4962bc66d35b359558fd8a5e10cd472d37aec5f66858addef32c1e" ], "markers": "python_version < '3.8'", - "version": "==1.5.0" + "version": "==1.6.0" }, "importlib-resources": { "hashes": [ - "sha256:4019b6a9082d8ada9def02bece4a76b131518866790d58fdda0b5f8c603b36c2", - "sha256:dd98ceeef3f5ad2ef4cc287b8586da4ebad15877f351e9688987ad663a0a29b8" + "sha256:6f87df66833e1942667108628ec48900e02a4ab4ad850e25fbf07cb17cf734ca", + "sha256:85dc0b9b325ff78c8bef2e4ff42616094e16b98ebd5e3b50fe7e2f0bbcdcde49" ], "markers": "python_version < '3.7'", - "version": "==1.4.0" + "version": "==1.5.0" }, "mako": { "hashes": [ @@ -97,10 +122,10 @@ }, "markdown": { "hashes": [ - "sha256:90fee683eeabe1a92e149f7ba74e5ccdc81cd397bd6c516d93a8da0ef90b6902", - "sha256:e4795399163109457d4c5af2183fbe6b60326c17cfdf25ce6e7474c6624f725d" + "sha256:1fafe3f1ecabfb514a5285fca634a53c1b32a81cb0feb154264d55bf2ff22c17", + "sha256:c467cd6233885534bf0fe96e62e3cf46cfc1605112356c4f9981512b8174de59" ], - "version": "==3.2.1" + "version": "==3.2.2" }, "markupsafe": { "hashes": [ @@ -142,17 +167,17 @@ }, "packaging": { "hashes": [ - "sha256:3c292b474fda1671ec57d46d739d072bfd495a4f51ad01a055121d81e952b7a3", - "sha256:82f77b9bee21c1bafbf35a84905d604d5d1223801d639cf3ed140bd651c08752" + "sha256:4357f74f47b9c12db93624a82154e9b120fa8293699949152b22065d556079f8", + "sha256:998416ba6962ae7fbd6596850b80e17859a5753ba17c32284f67bfff33784181" ], - "version": "==20.3" + "version": "==20.4" }, "pdoc3": { "hashes": [ - "sha256:ebca75b7fcf23f3b4320abe23339834d3f08c28517718e9d29e555fc38eeb33c" + "sha256:d7b56e67b5e049d53dcde94245a28040b640b2e06c344fc58ab2bdf2d91dc00f" ], "index": "pypi", - "version": "==0.7.5" + "version": "==0.8.1" }, "pkginfo": { "hashes": [ @@ -184,17 +209,17 @@ }, "pyparsing": { "hashes": [ - "sha256:4c830582a84fb022400b85429791bc551f1f4871c33f23e44f353119e92f969f", - "sha256:c342dccb5250c08d45fd6f8b4a559613ca603b57498511740e65cd11a2e7dcec" + "sha256:c203ec8783bf771a155b207279b9bccb8dea02d8f0c9e5f8ead507bc3246ecc1", + "sha256:ef9d7589ef3c200abe66653d3f1ab1033c3c419ae9b9bdb1240a85b024efc88b" ], - "version": "==2.4.6" + "version": "==2.4.7" }, "readme-renderer": { "hashes": [ - "sha256:1b6d8dd1673a0b293766b4106af766b6eff3654605f9c4f239e65de6076bc222", - "sha256:e67d64242f0174a63c3b727801a2fff4c1f38ebe5d71d95ff7ece081945a6cd4" + "sha256:cbe9db71defedd2428a1589cdc545f9bd98e59297449f69d721ef8f1cfced68d", + "sha256:cc4957a803106e820d05d14f71033092537a22daa4f406dfbdd61177e0936376" ], - "version": "==25.0" + "version": "==26.0" }, "requests": { "hashes": [ @@ -212,32 +237,32 @@ }, "six": { "hashes": [ - "sha256:236bdbdce46e6e6a3d61a337c0f8b763ca1e8717c03b369e87a7ec7ce1319c0a", - "sha256:8f3cd2e254d8f793e7f3d6d9df77b92252b52637291d0f0da013c76ea2724b6c" + "sha256:30639c035cdb23534cd4aa2dd52c3bf48f06e5f4a941509c8bafd8ce11080259", + "sha256:8b74bedcbbbaca38ff6d7491d76f2b06b3592611af620f8426e82dddb04a5ced" ], - "version": "==1.14.0" + "version": "==1.15.0" }, "toml": { "hashes": [ - "sha256:229f81c57791a41d65e399fc06bf0848bab550a9dfd5ed66df18ce5f05e73d5c", - "sha256:235682dd292d5899d361a811df37e04a8828a5b1da3115886b73cf81ebc9100e" + "sha256:926b612be1e5ce0634a2ca03470f95169cf16f939018233a670519cb4ac58b0f", + "sha256:bda89d5935c2eac546d648028b9901107a595863cb36bae0c73ac804a9b4ce88" ], - "version": "==0.10.0" + "version": "==0.10.1" }, "tox": { "hashes": [ - "sha256:0cbe98369081fa16bd6f1163d3d0b2a62afa29d402ccfad2bd09fb2668be0956", - "sha256:676f1e3e7de245ad870f956436b84ea226210587d1f72c8dfb8cd5ac7b6f0e70" + "sha256:322dfdf007d7d53323f767badcb068a5cfa7c44d8aabb698d131b28cf44e62c4", + "sha256:8c9ad9b48659d291c5bc78bcabaa4d680d627687154b812fa52baedaa94f9f83" ], "index": "pypi", - "version": "==3.14.5" + "version": "==3.15.1" }, "tqdm": { "hashes": [ - "sha256:0d8b5afb66e23d80433102e9bd8b5c8b65d34c2a2255b2de58d97bd2ea8170fd", - "sha256:f35fb121bafa030bd94e74fcfd44f3c2830039a2ddef7fc87ef1c2d205237b24" + "sha256:4733c4a10d0f2a4d098d801464bdaf5240c7dadd2a7fde4ee93b0a0efd9fb25e", + "sha256:acdafb20f51637ca3954150d0405ff1a7edde0ff19e38fb99a80a66210d2a28f" ], - "version": "==4.43.0" + "version": "==4.46.0" }, "twine": { "hashes": [ @@ -249,17 +274,17 @@ }, "urllib3": { "hashes": [ - "sha256:2f3db8b19923a873b3e5256dc9c2dedfa883e33d87c690d9c7913e1f40673cdc", - "sha256:87716c2d2a7121198ebcb7ce7cccf6ce5e9ba539041cfbaeecfb641dc0bf6acc" + "sha256:3018294ebefce6572a474f0604c2021e33b3fd8006ecd11d62107a5d2a963527", + "sha256:88206b0eb87e6d677d424843ac5209e3fb9d0190d0ee169599165ec25e9d9115" ], - "version": "==1.25.8" + "version": "==1.25.9" }, "virtualenv": { "hashes": [ - "sha256:87831f1070534b636fea2241dd66f3afe37ac9041bcca6d0af3215cdcfbf7d82", - "sha256:f3128d882383c503003130389bf892856341c1da12c881ae24d6358c82561b55" + "sha256:a116629d4e7f4d03433b8afa27f43deba09d48bc48f5ecefa4f015a178efb6cf", + "sha256:a730548b27366c5e6cbdf6f97406d861cccece2e22275e8e1a757aeff5e00c70" ], - "version": "==20.0.13" + "version": "==20.0.21" }, "webencodings": { "hashes": [ diff --git a/README.md b/README.md index 4be15cb..e18505a 100644 --- a/README.md +++ b/README.md @@ -72,11 +72,15 @@ was licensed under the GPL v2 and then continued by The project was taken over by [Nicklas Reincke](https://github.com/nickreynke) in 2018. Together with [Damon Brodie](https://github.com/nomadyow) a lot of changes were made and the parser was optimized. +Ansel support, additional tags, and extensive record and substructure level parsing support were added by +[Christopher Horn](https://github.com/cdhorn) in 2020. + ## License Licensed under the [GNU General Public License v2](http://www.gnu.org/licenses/gpl-2.0.html) **Python GEDCOM Parser** +
Copyright (C) 2020 Christopher Horn (cdhorn at embarqmail dot com)
Copyright (C) 2018 Damon Brodie (damon.brodie at gmail.com)
Copyright (C) 2018-2019 Nicklas Reincke (contact at reynke.com)
Copyright (C) 2016 Andreas Oberritter diff --git a/docs/gedcom/detect.html b/docs/gedcom/detect.html new file mode 100644 index 0000000..60b9b94 --- /dev/null +++ b/docs/gedcom/detect.html @@ -0,0 +1,298 @@ + + + + + + +gedcom.detect API documentation + + + + + + + + + +
+
+
+

Module gedcom.detect

+
+
+

Module containing functions for detecting GEDCOM file encoding and version.

+
+ +Expand source code + +
# -*- coding: utf-8 -*-
+
+# Python GEDCOM Parser
+#
+# Copyright (C) 2020 Christopher Horn (cdhorn at embarqmail dot com)
+# Copyright (C) 2018 Damon Brodie (damon.brodie at gmail.com)
+# Copyright (C) 2018-2019 Nicklas Reincke (contact at reynke.com)
+# Copyright (C) 2016 Andreas Oberritter
+# Copyright (C) 2012 Madeleine Price Ball
+# Copyright (C) 2005 Daniel Zappala (zappala at cs.byu.edu)
+# Copyright (C) 2005 Brigham Young University
+#
+# 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.
+#
+# Further information about the license: http://www.gnu.org/licenses/gpl-2.0.html
+
+"""
+Module containing functions for detecting GEDCOM file encoding and version.
+"""
+
+from typing import Tuple
+import chardet
+import ansel
+
+import gedcom.tags as tags
+import gedcom.standards as standards
+from gedcom.errors import GedcomFormatViolationError
+from gedcom.errors import GedcomCharacterSetUnsupportedError
+
+ansel.register()
+
+
+def __validate_encoding(file_path, codec):
+    """Check the encoding is compatible with the encoding as reported by the
+    `gedcom.tags.GEDCOM_TAG_CHARACTER` header tag.
+    """
+    with open(file_path, 'r', encoding=codec) as gedcom_data:
+        for line in gedcom_data:
+            if tags.GEDCOM_TAG_CHARACTER in line:
+                character_set = line.split(' ')[2].lower().strip()
+                break
+
+    if character_set == 'ansel' and codec == 'gedcom':
+        return
+
+    if character_set == 'ascii' and codec == 'utf-8':
+        return
+
+    if character_set not in codec:
+        errmsg = "A " + codec + " encoding was detected but the GEDCOM reports using " + \
+            "a " + character_set + " encoding.\n" + \
+            "Processing aborted as unsure how to properly proceed.\n" + \
+            "See: {0}".format(standards.GEDCOM_5_5_1)
+        raise GedcomCharacterSetUnsupportedError(errmsg)
+
+
+def get_encoding(file_path: str) -> str:
+    """Probe a GEDCOM file to determine the encoding and validate it against the encoding
+    as reported in the `HEADER` record by the `gedcom.tags.GEDCOM_TAG_CHARACTER` tag.
+
+    Returns: codec
+    """
+    with open(file_path, 'rb') as gedcom_data:
+        sample_data = gedcom_data.read(262144)
+
+    # Note chardet reports Ansel as ISO-8859-1 or ISO-8859-2 at this time
+    # depending on sample size, and could be making a faulty assumption here
+    # by treating it as Ansel. The ansel module supports both ansel and a
+    # gedcom codec with some gedcom specific extensions so we use that.
+    codec = 'unknown'
+    probe = chardet.detect(sample_data)
+    if probe['encoding'] in ['UTF-8', 'UTF-8-SIG']:
+        codec = 'utf-8-sig'
+    elif probe['encoding'] == 'UTF-16':
+        codec = 'utf-16'
+    elif probe['encoding'] == 'ASCII':
+        codec = 'ascii'
+    elif probe['encoding'] == 'ANSEL':
+        codec = 'ansel'
+    elif 'ISO-8859' in probe['encoding']:
+        codec = 'gedcom'
+
+    if codec == 'unknown':
+        errmsg = "Unable to properly identify a supported GEDCOM character encoding for" + \
+            "the file.\nSee: {0}".format(standards.GEDCOM_5_5_1)
+        raise GedcomCharacterSetUnsupportedError(errmsg)
+
+    __validate_encoding(file_path, codec)
+    return codec
+
+
+def get_version(file_path: str, codec: str) -> Tuple[str, str, str]:
+    """Probe a GEDCOM file to identify the version of the standard used as some reported 5.5
+    files are really 5.5.1.
+
+    Returns: probed version, reported version, reported format
+    """
+    in_gedc_tag = False
+    gedcom_version = None
+    gedcom_format = None
+    with open(file_path, 'r', encoding=codec) as gedcom_data:
+        for line in gedcom_data:
+            if '1 GEDC' in line:
+                in_gedc_tag = True
+                continue
+            if in_gedc_tag:
+                if '2 VERS' in line:
+                    gedcom_version = line.split(' ')[2].strip()
+                    continue
+                if '2 FORM' in line:
+                    gedcom_format = line.split(' ')[2].strip()
+                    break
+
+    if gedcom_version is None or gedcom_format is None:
+        errmsg = "Malformed GEDCOM file, the required version number or format were" + \
+            " not found as expected.\nSee: {0}".format(standards.GEDCOM_5_5_1)
+        raise GedcomFormatViolationError(errmsg)
+
+    probed_version = gedcom_version
+
+    # UTF was added in the 5.5.1 specification
+    if gedcom_version == '5.5' and 'utf' in codec:
+        probed_version = gedcom_version
+
+    return probed_version, gedcom_version, gedcom_format
+
+
+
+
+
+
+
+

Functions

+
+
+def get_encoding(file_path: str) -> str +
+
+

Probe a GEDCOM file to determine the encoding and validate it against the encoding +as reported in the HEADER record by the GEDCOM_TAG_CHARACTER tag.

+

Returns: codec

+
+ +Expand source code + +
def get_encoding(file_path: str) -> str:
+    """Probe a GEDCOM file to determine the encoding and validate it against the encoding
+    as reported in the `HEADER` record by the `gedcom.tags.GEDCOM_TAG_CHARACTER` tag.
+
+    Returns: codec
+    """
+    with open(file_path, 'rb') as gedcom_data:
+        sample_data = gedcom_data.read(262144)
+
+    # Note chardet reports Ansel as ISO-8859-1 or ISO-8859-2 at this time
+    # depending on sample size, and could be making a faulty assumption here
+    # by treating it as Ansel. The ansel module supports both ansel and a
+    # gedcom codec with some gedcom specific extensions so we use that.
+    codec = 'unknown'
+    probe = chardet.detect(sample_data)
+    if probe['encoding'] in ['UTF-8', 'UTF-8-SIG']:
+        codec = 'utf-8-sig'
+    elif probe['encoding'] == 'UTF-16':
+        codec = 'utf-16'
+    elif probe['encoding'] == 'ASCII':
+        codec = 'ascii'
+    elif probe['encoding'] == 'ANSEL':
+        codec = 'ansel'
+    elif 'ISO-8859' in probe['encoding']:
+        codec = 'gedcom'
+
+    if codec == 'unknown':
+        errmsg = "Unable to properly identify a supported GEDCOM character encoding for" + \
+            "the file.\nSee: {0}".format(standards.GEDCOM_5_5_1)
+        raise GedcomCharacterSetUnsupportedError(errmsg)
+
+    __validate_encoding(file_path, codec)
+    return codec
+
+
+
+def get_version(file_path: str, codec: str) -> Tuple[str, str, str] +
+
+

Probe a GEDCOM file to identify the version of the standard used as some reported 5.5 +files are really 5.5.1.

+

Returns: probed version, reported version, reported format

+
+ +Expand source code + +
def get_version(file_path: str, codec: str) -> Tuple[str, str, str]:
+    """Probe a GEDCOM file to identify the version of the standard used as some reported 5.5
+    files are really 5.5.1.
+
+    Returns: probed version, reported version, reported format
+    """
+    in_gedc_tag = False
+    gedcom_version = None
+    gedcom_format = None
+    with open(file_path, 'r', encoding=codec) as gedcom_data:
+        for line in gedcom_data:
+            if '1 GEDC' in line:
+                in_gedc_tag = True
+                continue
+            if in_gedc_tag:
+                if '2 VERS' in line:
+                    gedcom_version = line.split(' ')[2].strip()
+                    continue
+                if '2 FORM' in line:
+                    gedcom_format = line.split(' ')[2].strip()
+                    break
+
+    if gedcom_version is None or gedcom_format is None:
+        errmsg = "Malformed GEDCOM file, the required version number or format were" + \
+            " not found as expected.\nSee: {0}".format(standards.GEDCOM_5_5_1)
+        raise GedcomFormatViolationError(errmsg)
+
+    probed_version = gedcom_version
+
+    # UTF was added in the 5.5.1 specification
+    if gedcom_version == '5.5' and 'utf' in codec:
+        probed_version = gedcom_version
+
+    return probed_version, gedcom_version, gedcom_format
+
+
+
+
+
+
+
+ +
+ + + + + \ No newline at end of file diff --git a/docs/gedcom/element/element.html b/docs/gedcom/element/element.html index 7d9c271..5e91e48 100644 --- a/docs/gedcom/element/element.html +++ b/docs/gedcom/element/element.html @@ -3,14 +3,14 @@ - + gedcom.element.element API documentation - + - - + + @@ -20,7 +20,7 @@

Module gedcom.element.element

-

Base GEDCOM element

+

Base GEDCOM element.

Expand source code @@ -53,18 +53,20 @@

Module gedcom.element.element

# Further information about the license: http://www.gnu.org/licenses/gpl-2.0.html """ -Base GEDCOM element +Base GEDCOM element. """ from sys import version_info +from typing import List + from gedcom.helpers import deprecated import gedcom.tags class Element(object): - """GEDCOM element + """GEDCOM element. - Each line in a GEDCOM file is an element with the format + Each line in a GEDCOM file is an element with the format: `level [pointer] tag [value]` @@ -89,7 +91,8 @@

Module gedcom.element.element

Tags available to an element are seen here: `gedcom.tags` """ - def __init__(self, level, pointer, tag, value, crlf="\n", multi_line=True): + def __init__(self, level: int, pointer: str, tag: str, value: str, + crlf: str = "\n", multi_line: bool = True): # basic element info self.__level = level self.__pointer = pointer @@ -104,39 +107,33 @@

Module gedcom.element.element

if multi_line: self.set_multi_line_value(value) - def get_level(self): - """Returns the level of this element from within the GEDCOM file - :rtype: int + def get_level(self) -> int: + """Returns the level of this element from within the GEDCOM file. """ return self.__level - def get_pointer(self): - """Returns the pointer of this element from within the GEDCOM file - :rtype: str + def get_pointer(self) -> str: + """Returns the pointer of this element from within the GEDCOM file. """ return self.__pointer - def get_tag(self): - """Returns the tag of this element from within the GEDCOM file - :rtype: str + def get_tag(self) -> str: + """Returns the tag of this element from within the GEDCOM file. """ return self.__tag - def get_value(self): - """Return the value of this element from within the GEDCOM file - :rtype: str + def get_value(self) -> str: + """Return the value of this element from within the GEDCOM file. """ return self.__value - def set_value(self, value): - """Sets the value of this element - :type value: str + def set_value(self, value: str): + """Sets the value of this element. """ self.__value = value - def get_multi_line_value(self): - """Returns the value of this element including concatenations or continuations - :rtype: str + def get_multi_line_value(self) -> str: + """Returns the value of this element including concatenations or continuations. """ result = self.get_value() last_crlf = self.__crlf @@ -150,17 +147,14 @@

Module gedcom.element.element

last_crlf = element.__crlf return result - def __available_characters(self): + def __available_characters(self) -> int: """Get the number of available characters of the elements original string - :rtype: int """ element_characters = len(self.to_gedcom_string()) return 0 if element_characters > 255 else 255 - element_characters - def __line_length(self, line): - """@TODO Write docs. - :type line: str - :rtype: int + def __line_length(self, line: str) -> int: + """Return line length. """ total_characters = len(line) available_characters = self.__available_characters() @@ -173,40 +167,36 @@

Module gedcom.element.element

return available_characters return available_characters - spaces - def __set_bounded_value(self, value): + def __set_bounded_value(self, value: str) -> int: """@TODO Write docs. - :type value: str - :rtype: int """ line_length = self.__line_length(value) self.set_value(value[:line_length]) return line_length - def __add_bounded_child(self, tag, value): + def __add_bounded_child(self, tag: str, value: str) -> int: """@TODO Write docs. - :type tag: str - :type value: str - :rtype: int """ child = self.new_child_element(tag) return child.__set_bounded_value(value) - def __add_concatenation(self, string): + def __add_concatenation(self, string: str): """@TODO Write docs. - :rtype: str """ index = 0 size = len(string) while index < size: index += self.__add_bounded_child(gedcom.tags.GEDCOM_TAG_CONCATENATION, string[index:]) - def set_multi_line_value(self, value): - """Sets the value of this element, adding concatenation and continuation lines when necessary - :type value: str + def set_multi_line_value(self, value: str): + """Sets the value of this element, adding concatenation and continuation lines + when necessary. """ self.set_value('') self.get_child_elements()[:] = [child for child in self.get_child_elements() if - child.get_tag() not in (gedcom.tags.GEDCOM_TAG_CONCATENATION, gedcom.tags.GEDCOM_TAG_CONTINUED)] + child.get_tag() not in + (gedcom.tags.GEDCOM_TAG_CONCATENATION, + gedcom.tags.GEDCOM_TAG_CONTINUED)] lines = value.splitlines() if lines: @@ -218,79 +208,91 @@

Module gedcom.element.element

n = self.__add_bounded_child(gedcom.tags.GEDCOM_TAG_CONTINUED, line) self.__add_concatenation(line[n:]) - def get_child_elements(self): - """Returns the direct child elements of this element - :rtype: list of Element + def get_child_elements(self) -> List['Element']: + """Returns the direct child elements of this element. """ return self.__children - def new_child_element(self, tag, pointer="", value=""): - """Creates and returns a new child element of this element - - :type tag: str - :type pointer: str - :type value: str - :rtype: Element + def new_child_element(self, tag: str, pointer: str = "", + value: str = "") -> 'Element': + """Creates and returns a new child element of this element. """ from gedcom.element.family import FamilyElement - from gedcom.element.file import FileElement from gedcom.element.individual import IndividualElement + from gedcom.element.note import NoteElement from gedcom.element.object import ObjectElement + from gedcom.element.repository import RepositoryElement + from gedcom.element.source import SourceElement + from gedcom.element.submitter import SubmitterElement + from gedcom.element.submission import SubmissionElement + from gedcom.element.header import HeaderElement # Differentiate between the type of the new child element if tag == gedcom.tags.GEDCOM_TAG_FAMILY: - child_element = FamilyElement(self.get_level() + 1, pointer, tag, value, self.__crlf) - elif tag == gedcom.tags.GEDCOM_TAG_FILE: - child_element = FileElement(self.get_level() + 1, pointer, tag, value, self.__crlf) + child_element = FamilyElement(self.get_level() + 1, pointer, tag, + value, self.__crlf) elif tag == gedcom.tags.GEDCOM_TAG_INDIVIDUAL: - child_element = IndividualElement(self.get_level() + 1, pointer, tag, value, self.__crlf) + child_element = IndividualElement(self.get_level() + 1, pointer, tag, + value, self.__crlf) + elif tag == gedcom.tags.GEDCOM_TAG_NOTE: + child_element = NoteElement(self.get_level() + 1, pointer, tag, + value, self.__crlf) elif tag == gedcom.tags.GEDCOM_TAG_OBJECT: - child_element = ObjectElement(self.get_level() + 1, pointer, tag, value, self.__crlf) + child_element = ObjectElement(self.get_level() + 1, pointer, tag, + value, self.__crlf) + elif tag == gedcom.tags.GEDCOM_TAG_REPOSITORY: + child_element = RepositoryElement(self.get_level() + 1, pointer, tag, + value, self.__crlf) + elif tag == gedcom.tags.GEDCOM_TAG_SOURCE: + child_element = SourceElement(self.get_level() + 1, pointer, tag, + value, self.__crlf) + elif tag == gedcom.tags.GEDCOM_TAG_SUBMITTER: + child_element = SubmitterElement(self.get_level() + 1, pointer, tag, + value, self.__crlf) + elif tag == gedcom.tags.GEDCOM_TAG_SUBMISSION: + child_element = SubmissionElement(self.get_level() + 1, pointer, tag, + value, self.__crlf) + elif tag == gedcom.tags.GEDCOM_TAG_HEADER: + child_element = HeaderElement(self.get_level() + 1, pointer, tag, + value, self.__crlf) else: - child_element = Element(self.get_level() + 1, pointer, tag, value, self.__crlf) + child_element = Element(self.get_level() + 1, pointer, tag, + value, self.__crlf) self.add_child_element(child_element) return child_element - def add_child_element(self, element): - """Adds a child element to this element - - :type element: Element + def add_child_element(self, element: 'Element'): + """Adds a child element to this element. """ self.get_child_elements().append(element) element.set_parent_element(self) return element - def get_parent_element(self): - """Returns the parent element of this element - :rtype: Element + def get_parent_element(self) -> 'Element': + """Returns the parent element of this element. """ return self.__parent - def set_parent_element(self, element): - """Adds a parent element to this element + def set_parent_element(self, element: 'Element'): + """Adds a parent element to this element. There's usually no need to call this method manually, `add_child_element()` calls it automatically. - - :type element: Element """ self.__parent = element @deprecated - def get_individual(self): - """Returns this element and all of its sub-elements represented as a GEDCOM string + def get_individual(self) -> str: + """Returns this element and all of its sub-elements represented as a GEDCOM string. ::deprecated:: As of version 1.0.0 use `to_gedcom_string()` method instead - :rtype: str """ return self.to_gedcom_string(True) - def to_gedcom_string(self, recursive=False): - """Formats this element and optionally all of its sub-elements into a GEDCOM string - :type recursive: bool - :rtype: str + def to_gedcom_string(self, recursive: bool = False) -> str: + """Formats this element and optionally all of its sub-elements into a GEDCOM string. """ result = str(self.get_level()) @@ -314,7 +316,7 @@

Module gedcom.element.element

return result - def __str__(self): + def __str__(self) -> str: """:rtype: str""" if version_info[0] >= 3: return self.to_gedcom_string() @@ -333,11 +335,11 @@

Classes

class Element -(level, pointer, tag, value, crlf='\n', multi_line=True) +(level: int, pointer: str, tag: str, value: str, crlf: str = '\n', multi_line: bool = True)
-

GEDCOM element

-

Each line in a GEDCOM file is an element with the format

+

GEDCOM element.

+

Each line in a GEDCOM file is an element with the format:

level [pointer] tag [value]

where level and tag are required, and pointer and value are optional. @@ -356,15 +358,15 @@

Classes

that points to a family record in which the associated person is a child.

See a GEDCOM file for examples of tags and their values.

-

Tags available to an element are seen here: gedcom.tags

+

Tags available to an element are seen here: gedcom.tags

Expand source code
class Element(object):
-    """GEDCOM element
+    """GEDCOM element.
 
-    Each line in a GEDCOM file is an element with the format
+    Each line in a GEDCOM file is an element with the format:
 
     `level [pointer] tag [value]`
 
@@ -389,7 +391,8 @@ 

Classes

Tags available to an element are seen here: `gedcom.tags` """ - def __init__(self, level, pointer, tag, value, crlf="\n", multi_line=True): + def __init__(self, level: int, pointer: str, tag: str, value: str, + crlf: str = "\n", multi_line: bool = True): # basic element info self.__level = level self.__pointer = pointer @@ -404,39 +407,33 @@

Classes

if multi_line: self.set_multi_line_value(value) - def get_level(self): - """Returns the level of this element from within the GEDCOM file - :rtype: int + def get_level(self) -> int: + """Returns the level of this element from within the GEDCOM file. """ return self.__level - def get_pointer(self): - """Returns the pointer of this element from within the GEDCOM file - :rtype: str + def get_pointer(self) -> str: + """Returns the pointer of this element from within the GEDCOM file. """ return self.__pointer - def get_tag(self): - """Returns the tag of this element from within the GEDCOM file - :rtype: str + def get_tag(self) -> str: + """Returns the tag of this element from within the GEDCOM file. """ return self.__tag - def get_value(self): - """Return the value of this element from within the GEDCOM file - :rtype: str + def get_value(self) -> str: + """Return the value of this element from within the GEDCOM file. """ return self.__value - def set_value(self, value): - """Sets the value of this element - :type value: str + def set_value(self, value: str): + """Sets the value of this element. """ self.__value = value - def get_multi_line_value(self): - """Returns the value of this element including concatenations or continuations - :rtype: str + def get_multi_line_value(self) -> str: + """Returns the value of this element including concatenations or continuations. """ result = self.get_value() last_crlf = self.__crlf @@ -450,17 +447,14 @@

Classes

last_crlf = element.__crlf return result - def __available_characters(self): + def __available_characters(self) -> int: """Get the number of available characters of the elements original string - :rtype: int """ element_characters = len(self.to_gedcom_string()) return 0 if element_characters > 255 else 255 - element_characters - def __line_length(self, line): - """@TODO Write docs. - :type line: str - :rtype: int + def __line_length(self, line: str) -> int: + """Return line length. """ total_characters = len(line) available_characters = self.__available_characters() @@ -473,40 +467,36 @@

Classes

return available_characters return available_characters - spaces - def __set_bounded_value(self, value): + def __set_bounded_value(self, value: str) -> int: """@TODO Write docs. - :type value: str - :rtype: int """ line_length = self.__line_length(value) self.set_value(value[:line_length]) return line_length - def __add_bounded_child(self, tag, value): + def __add_bounded_child(self, tag: str, value: str) -> int: """@TODO Write docs. - :type tag: str - :type value: str - :rtype: int """ child = self.new_child_element(tag) return child.__set_bounded_value(value) - def __add_concatenation(self, string): + def __add_concatenation(self, string: str): """@TODO Write docs. - :rtype: str """ index = 0 size = len(string) while index < size: index += self.__add_bounded_child(gedcom.tags.GEDCOM_TAG_CONCATENATION, string[index:]) - def set_multi_line_value(self, value): - """Sets the value of this element, adding concatenation and continuation lines when necessary - :type value: str + def set_multi_line_value(self, value: str): + """Sets the value of this element, adding concatenation and continuation lines + when necessary. """ self.set_value('') self.get_child_elements()[:] = [child for child in self.get_child_elements() if - child.get_tag() not in (gedcom.tags.GEDCOM_TAG_CONCATENATION, gedcom.tags.GEDCOM_TAG_CONTINUED)] + child.get_tag() not in + (gedcom.tags.GEDCOM_TAG_CONCATENATION, + gedcom.tags.GEDCOM_TAG_CONTINUED)] lines = value.splitlines() if lines: @@ -518,79 +508,91 @@

Classes

n = self.__add_bounded_child(gedcom.tags.GEDCOM_TAG_CONTINUED, line) self.__add_concatenation(line[n:]) - def get_child_elements(self): - """Returns the direct child elements of this element - :rtype: list of Element + def get_child_elements(self) -> List['Element']: + """Returns the direct child elements of this element. """ return self.__children - def new_child_element(self, tag, pointer="", value=""): - """Creates and returns a new child element of this element - - :type tag: str - :type pointer: str - :type value: str - :rtype: Element + def new_child_element(self, tag: str, pointer: str = "", + value: str = "") -> 'Element': + """Creates and returns a new child element of this element. """ from gedcom.element.family import FamilyElement - from gedcom.element.file import FileElement from gedcom.element.individual import IndividualElement + from gedcom.element.note import NoteElement from gedcom.element.object import ObjectElement + from gedcom.element.repository import RepositoryElement + from gedcom.element.source import SourceElement + from gedcom.element.submitter import SubmitterElement + from gedcom.element.submission import SubmissionElement + from gedcom.element.header import HeaderElement # Differentiate between the type of the new child element if tag == gedcom.tags.GEDCOM_TAG_FAMILY: - child_element = FamilyElement(self.get_level() + 1, pointer, tag, value, self.__crlf) - elif tag == gedcom.tags.GEDCOM_TAG_FILE: - child_element = FileElement(self.get_level() + 1, pointer, tag, value, self.__crlf) + child_element = FamilyElement(self.get_level() + 1, pointer, tag, + value, self.__crlf) elif tag == gedcom.tags.GEDCOM_TAG_INDIVIDUAL: - child_element = IndividualElement(self.get_level() + 1, pointer, tag, value, self.__crlf) + child_element = IndividualElement(self.get_level() + 1, pointer, tag, + value, self.__crlf) + elif tag == gedcom.tags.GEDCOM_TAG_NOTE: + child_element = NoteElement(self.get_level() + 1, pointer, tag, + value, self.__crlf) elif tag == gedcom.tags.GEDCOM_TAG_OBJECT: - child_element = ObjectElement(self.get_level() + 1, pointer, tag, value, self.__crlf) + child_element = ObjectElement(self.get_level() + 1, pointer, tag, + value, self.__crlf) + elif tag == gedcom.tags.GEDCOM_TAG_REPOSITORY: + child_element = RepositoryElement(self.get_level() + 1, pointer, tag, + value, self.__crlf) + elif tag == gedcom.tags.GEDCOM_TAG_SOURCE: + child_element = SourceElement(self.get_level() + 1, pointer, tag, + value, self.__crlf) + elif tag == gedcom.tags.GEDCOM_TAG_SUBMITTER: + child_element = SubmitterElement(self.get_level() + 1, pointer, tag, + value, self.__crlf) + elif tag == gedcom.tags.GEDCOM_TAG_SUBMISSION: + child_element = SubmissionElement(self.get_level() + 1, pointer, tag, + value, self.__crlf) + elif tag == gedcom.tags.GEDCOM_TAG_HEADER: + child_element = HeaderElement(self.get_level() + 1, pointer, tag, + value, self.__crlf) else: - child_element = Element(self.get_level() + 1, pointer, tag, value, self.__crlf) + child_element = Element(self.get_level() + 1, pointer, tag, + value, self.__crlf) self.add_child_element(child_element) return child_element - def add_child_element(self, element): - """Adds a child element to this element - - :type element: Element + def add_child_element(self, element: 'Element'): + """Adds a child element to this element. """ self.get_child_elements().append(element) element.set_parent_element(self) return element - def get_parent_element(self): - """Returns the parent element of this element - :rtype: Element + def get_parent_element(self) -> 'Element': + """Returns the parent element of this element. """ return self.__parent - def set_parent_element(self, element): - """Adds a parent element to this element + def set_parent_element(self, element: 'Element'): + """Adds a parent element to this element. There's usually no need to call this method manually, `add_child_element()` calls it automatically. - - :type element: Element """ self.__parent = element @deprecated - def get_individual(self): - """Returns this element and all of its sub-elements represented as a GEDCOM string + def get_individual(self) -> str: + """Returns this element and all of its sub-elements represented as a GEDCOM string. ::deprecated:: As of version 1.0.0 use `to_gedcom_string()` method instead - :rtype: str """ return self.to_gedcom_string(True) - def to_gedcom_string(self, recursive=False): - """Formats this element and optionally all of its sub-elements into a GEDCOM string - :type recursive: bool - :rtype: str + def to_gedcom_string(self, recursive: bool = False) -> str: + """Formats this element and optionally all of its sub-elements into a GEDCOM string. """ result = str(self.get_level()) @@ -614,7 +616,7 @@

Classes

return result - def __str__(self): + def __str__(self) -> str: """:rtype: str""" if version_info[0] >= 3: return self.to_gedcom_string() @@ -624,27 +626,29 @@

Classes

Subclasses

Methods

-def add_child_element(self, element) +def add_child_element(self, element: Element)
-

Adds a child element to this element

-

:type element: Element

+

Adds a child element to this element.

Expand source code -
def add_child_element(self, element):
-    """Adds a child element to this element
-
-    :type element: Element
+
def add_child_element(self, element: 'Element'):
+    """Adds a child element to this element.
     """
     self.get_child_elements().append(element)
     element.set_parent_element(self)
@@ -653,72 +657,64 @@ 

Methods

-def get_child_elements(self) +def get_child_elements(self) -> List[Element]
-

Returns the direct child elements of this element -:rtype: list of Element

+

Returns the direct child elements of this element.

Expand source code -
def get_child_elements(self):
-    """Returns the direct child elements of this element
-    :rtype: list of Element
+
def get_child_elements(self) -> List['Element']:
+    """Returns the direct child elements of this element.
     """
     return self.__children
-def get_individual(self) +def get_individual(self) -> str
-

Returns this element and all of its sub-elements represented as a GEDCOM string -::deprecated:: As of version 1.0.0 use to_gedcom_string() method instead -:rtype: str

+

Returns this element and all of its sub-elements represented as a GEDCOM string. +::deprecated:: As of version 1.0.0 use to_gedcom_string() method instead

Expand source code
@deprecated
-def get_individual(self):
-    """Returns this element and all of its sub-elements represented as a GEDCOM string
+def get_individual(self) -> str:
+    """Returns this element and all of its sub-elements represented as a GEDCOM string.
     ::deprecated:: As of version 1.0.0 use `to_gedcom_string()` method instead
-    :rtype: str
     """
     return self.to_gedcom_string(True)
-def get_level(self) +def get_level(self) -> int
-

Returns the level of this element from within the GEDCOM file -:rtype: int

+

Returns the level of this element from within the GEDCOM file.

Expand source code -
def get_level(self):
-    """Returns the level of this element from within the GEDCOM file
-    :rtype: int
+
def get_level(self) -> int:
+    """Returns the level of this element from within the GEDCOM file.
     """
     return self.__level
-def get_multi_line_value(self) +def get_multi_line_value(self) -> str
-

Returns the value of this element including concatenations or continuations -:rtype: str

+

Returns the value of this element including concatenations or continuations.

Expand source code -
def get_multi_line_value(self):
-    """Returns the value of this element including concatenations or continuations
-    :rtype: str
+
def get_multi_line_value(self) -> str:
+    """Returns the value of this element including concatenations or continuations.
     """
     result = self.get_value()
     last_crlf = self.__crlf
@@ -734,110 +730,119 @@ 

Methods

-def get_parent_element(self) +def get_parent_element(self) -> Element
-

Returns the parent element of this element -:rtype: Element

+

Returns the parent element of this element.

Expand source code -
def get_parent_element(self):
-    """Returns the parent element of this element
-    :rtype: Element
+
def get_parent_element(self) -> 'Element':
+    """Returns the parent element of this element.
     """
     return self.__parent
-def get_pointer(self) +def get_pointer(self) -> str
-

Returns the pointer of this element from within the GEDCOM file -:rtype: str

+

Returns the pointer of this element from within the GEDCOM file.

Expand source code -
def get_pointer(self):
-    """Returns the pointer of this element from within the GEDCOM file
-    :rtype: str
+
def get_pointer(self) -> str:
+    """Returns the pointer of this element from within the GEDCOM file.
     """
     return self.__pointer
-def get_tag(self) +def get_tag(self) -> str
-

Returns the tag of this element from within the GEDCOM file -:rtype: str

+

Returns the tag of this element from within the GEDCOM file.

Expand source code -
def get_tag(self):
-    """Returns the tag of this element from within the GEDCOM file
-    :rtype: str
+
def get_tag(self) -> str:
+    """Returns the tag of this element from within the GEDCOM file.
     """
     return self.__tag
-def get_value(self) +def get_value(self) -> str
-

Return the value of this element from within the GEDCOM file -:rtype: str

+

Return the value of this element from within the GEDCOM file.

Expand source code -
def get_value(self):
-    """Return the value of this element from within the GEDCOM file
-    :rtype: str
+
def get_value(self) -> str:
+    """Return the value of this element from within the GEDCOM file.
     """
     return self.__value
-def new_child_element(self, tag, pointer='', value='') +def new_child_element(self, tag: str, pointer: str = '', value: str = '') -> Element
-

Creates and returns a new child element of this element

-

:type tag: str -:type pointer: str -:type value: str -:rtype: Element

+

Creates and returns a new child element of this element.

Expand source code -
def new_child_element(self, tag, pointer="", value=""):
-    """Creates and returns a new child element of this element
-
-    :type tag: str
-    :type pointer: str
-    :type value: str
-    :rtype: Element
+
def new_child_element(self, tag: str, pointer: str = "",
+                      value: str = "") -> 'Element':
+    """Creates and returns a new child element of this element.
     """
     from gedcom.element.family import FamilyElement
-    from gedcom.element.file import FileElement
     from gedcom.element.individual import IndividualElement
+    from gedcom.element.note import NoteElement
     from gedcom.element.object import ObjectElement
+    from gedcom.element.repository import RepositoryElement
+    from gedcom.element.source import SourceElement
+    from gedcom.element.submitter import SubmitterElement
+    from gedcom.element.submission import SubmissionElement
+    from gedcom.element.header import HeaderElement
 
     # Differentiate between the type of the new child element
     if tag == gedcom.tags.GEDCOM_TAG_FAMILY:
-        child_element = FamilyElement(self.get_level() + 1, pointer, tag, value, self.__crlf)
-    elif tag == gedcom.tags.GEDCOM_TAG_FILE:
-        child_element = FileElement(self.get_level() + 1, pointer, tag, value, self.__crlf)
+        child_element = FamilyElement(self.get_level() + 1, pointer, tag,
+                                      value, self.__crlf)
     elif tag == gedcom.tags.GEDCOM_TAG_INDIVIDUAL:
-        child_element = IndividualElement(self.get_level() + 1, pointer, tag, value, self.__crlf)
+        child_element = IndividualElement(self.get_level() + 1, pointer, tag,
+                                          value, self.__crlf)
+    elif tag == gedcom.tags.GEDCOM_TAG_NOTE:
+        child_element = NoteElement(self.get_level() + 1, pointer, tag,
+                                    value, self.__crlf)
     elif tag == gedcom.tags.GEDCOM_TAG_OBJECT:
-        child_element = ObjectElement(self.get_level() + 1, pointer, tag, value, self.__crlf)
+        child_element = ObjectElement(self.get_level() + 1, pointer, tag,
+                                      value, self.__crlf)
+    elif tag == gedcom.tags.GEDCOM_TAG_REPOSITORY:
+        child_element = RepositoryElement(self.get_level() + 1, pointer, tag,
+                                          value, self.__crlf)
+    elif tag == gedcom.tags.GEDCOM_TAG_SOURCE:
+        child_element = SourceElement(self.get_level() + 1, pointer, tag,
+                                      value, self.__crlf)
+    elif tag == gedcom.tags.GEDCOM_TAG_SUBMITTER:
+        child_element = SubmitterElement(self.get_level() + 1, pointer, tag,
+                                         value, self.__crlf)
+    elif tag == gedcom.tags.GEDCOM_TAG_SUBMISSION:
+        child_element = SubmissionElement(self.get_level() + 1, pointer, tag,
+                                          value, self.__crlf)
+    elif tag == gedcom.tags.GEDCOM_TAG_HEADER:
+        child_element = HeaderElement(self.get_level() + 1, pointer, tag,
+                                      value, self.__crlf)
     else:
-        child_element = Element(self.get_level() + 1, pointer, tag, value, self.__crlf)
+        child_element = Element(self.get_level() + 1, pointer, tag,
+                                value, self.__crlf)
 
     self.add_child_element(child_element)
 
@@ -845,22 +850,24 @@ 

Methods

-def set_multi_line_value(self, value) +def set_multi_line_value(self, value: str)
-

Sets the value of this element, adding concatenation and continuation lines when necessary -:type value: str

+

Sets the value of this element, adding concatenation and continuation lines +when necessary.

Expand source code -
def set_multi_line_value(self, value):
-    """Sets the value of this element, adding concatenation and continuation lines when necessary
-    :type value: str
+
def set_multi_line_value(self, value: str):
+    """Sets the value of this element, adding concatenation and continuation lines
+    when necessary.
     """
     self.set_value('')
     self.get_child_elements()[:] = [child for child in self.get_child_elements() if
-                                    child.get_tag() not in (gedcom.tags.GEDCOM_TAG_CONCATENATION, gedcom.tags.GEDCOM_TAG_CONTINUED)]
+                                    child.get_tag() not in
+                                    (gedcom.tags.GEDCOM_TAG_CONCATENATION,
+                                     gedcom.tags.GEDCOM_TAG_CONTINUED)]
 
     lines = value.splitlines()
     if lines:
@@ -874,60 +881,51 @@ 

Methods

-def set_parent_element(self, element) +def set_parent_element(self, element: Element)
-

Adds a parent element to this element

+

Adds a parent element to this element.

There's usually no need to call this method manually, -add_child_element() calls it automatically.

-

:type element: Element

+add_child_element() calls it automatically.

Expand source code -
def set_parent_element(self, element):
-    """Adds a parent element to this element
+
def set_parent_element(self, element: 'Element'):
+    """Adds a parent element to this element.
 
     There's usually no need to call this method manually,
     `add_child_element()` calls it automatically.
-
-    :type element: Element
     """
     self.__parent = element
-def set_value(self, value) +def set_value(self, value: str)
-

Sets the value of this element -:type value: str

+

Sets the value of this element.

Expand source code -
def set_value(self, value):
-    """Sets the value of this element
-    :type value: str
+
def set_value(self, value: str):
+    """Sets the value of this element.
     """
     self.__value = value
-def to_gedcom_string(self, recursive=False) +def to_gedcom_string(self, recursive: bool = False) -> str
-

Formats this element and optionally all of its sub-elements into a GEDCOM string -:type recursive: bool -:rtype: str

+

Formats this element and optionally all of its sub-elements into a GEDCOM string.

Expand source code -
def to_gedcom_string(self, recursive=False):
-    """Formats this element and optionally all of its sub-elements into a GEDCOM string
-    :type recursive: bool
-    :rtype: str
+
def to_gedcom_string(self, recursive: bool = False) -> str:
+    """Formats this element and optionally all of its sub-elements into a GEDCOM string.
     """
 
     result = str(self.get_level())
@@ -995,7 +993,7 @@ 

-

Generated by pdoc 0.7.5.

+

Generated by pdoc 0.8.1.

diff --git a/docs/gedcom/element/family.html b/docs/gedcom/element/family.html index ec7d2c6..4c91975 100644 --- a/docs/gedcom/element/family.html +++ b/docs/gedcom/element/family.html @@ -3,14 +3,15 @@ - + gedcom.element.family API documentation - + - - + + @@ -20,7 +21,8 @@

Module gedcom.element.family

-

GEDCOM element consisting of tag GEDCOM_TAG_FAMILY

+

GEDCOM element for a FAM_RECORD family record identified by the +GEDCOM_TAG_FAMILY tag.

Expand source code @@ -29,6 +31,7 @@

Module gedcom.element.family

# Python GEDCOM Parser # +# Copyright (C) 2020 Christopher Horn (cdhorn at embarqmail dot com) # Copyright (C) 2018 Damon Brodie (damon.brodie at gmail.com) # Copyright (C) 2018-2019 Nicklas Reincke (contact at reynke.com) # Copyright (C) 2016 Andreas Oberritter @@ -52,20 +55,107 @@

Module gedcom.element.family

# # Further information about the license: http://www.gnu.org/licenses/gpl-2.0.html -"""GEDCOM element consisting of tag `gedcom.tags.GEDCOM_TAG_FAMILY`""" +""" +GEDCOM element for a `FAM_RECORD` family record identified by the +`gedcom.tags.GEDCOM_TAG_FAMILY` tag. +""" +import gedcom.tags as tags from gedcom.element.element import Element -import gedcom.tags +from gedcom.subparsers.family_event_structure import family_event_structure +from gedcom.subparsers.change_date import change_date +from gedcom.subparsers.lds_spouse_sealing import lds_spouse_sealing +from gedcom.subparsers.note_structure import note_structure +from gedcom.subparsers.source_citation import source_citation +from gedcom.subparsers.multimedia_link import multimedia_link +from gedcom.subparsers.user_reference_number import user_reference_number - -class NotAnActualFamilyError(Exception): - pass +FAMILY_SINGLE_TAGS = { + tags.GEDCOM_TAG_WIFE: 'key_to_wife', + tags.GEDCOM_TAG_HUSBAND: 'key_to_husband', + tags.GEDCOM_TAG_CHILDREN_COUNT: 'number_of_children', + tags.GEDCOM_TAG_RESTRICTION: 'restriction', + tags.GEDCOM_TAG_REC_ID_NUMBER: 'record_id' +} class FamilyElement(Element): + """Element associated with a `FAM_RECORD`""" + + def get_tag(self) -> str: + return tags.GEDCOM_TAG_FAMILY + + def get_record(self) -> dict: + """Parse and return the full record in dictionary format. + """ + record = { + 'key_to_family': self.get_pointer(), + 'restriction': '', + 'events': family_event_structure(self), + 'key_to_husband': '', + 'key_to_wife': '', + 'children': [], + 'number_of_children': '', + 'submitters': [], + 'references': [], + 'record_id': '', + 'change_date': {}, + 'notes': [], + 'citations': [], + 'media': [] + } + lds_events = lds_spouse_sealing(self) + if len(lds_events) > 0: + for event in lds_events: + record['events'].append(event) + + for child in self.get_child_elements(): + if child.get_tag() in FAMILY_SINGLE_TAGS: + record[FAMILY_SINGLE_TAGS[child.get_tag()]] = child.get_value() + continue + + if child.get_tag() == tags.GEDCOM_TAG_CHILD: + entry = { + 'key_to_child': child.get_value(), + 'relationship_to_father': '', + 'relationship_to_mother': '' + } + for gchild in child.get_child_elements(): + if gchild.get_tag() == tags.GEDCOM_PROGRAM_DEFINED_TAG_FREL: + entry['relationship_to_father'] = gchild.get_value() + continue + + if gchild.get_tag() == tags.GEDCOM_PROGRAM_DEFINED_TAG_MREL: + entry['relationship_to_mother'] = gchild.get_value() + + record['children'].append(entry) + continue + + if child.get_tag() == tags.GEDCOM_TAG_NOTE: + record['notes'].append(note_structure(child)) + continue - def get_tag(self): - return gedcom.tags.GEDCOM_TAG_FAMILY

+ if child.get_tag() == tags.GEDCOM_TAG_SOURCE: + record['citations'].append(source_citation(child)) + continue + + if child.get_tag() == tags.GEDCOM_TAG_OBJECT: + record['media'].append(multimedia_link(child)) + continue + + if child.get_tag() == tags.GEDCOM_TAG_REFERENCE: + record['references'].append(user_reference_number(child)) + continue + + if child.get_tag() == tags.GEDCOM_TAG_CHANGE: + record['change_date'] = change_date(child) + continue + + if child.get_tag() == tags.GEDCOM_TAG_SUBMITTER: + record['submitters'].append(child.get_value()) + continue + + return record
@@ -79,43 +169,181 @@

Classes

class FamilyElement -(level, pointer, tag, value, crlf='\n', multi_line=True) +(level: int, pointer: str, tag: str, value: str, crlf: str = '\n', multi_line: bool = True)
-

GEDCOM element

-

Each line in a GEDCOM file is an element with the format

-

level [pointer] tag [value]

-

where level and tag are required, and pointer and value are -optional. -Elements are arranged hierarchically according to their -level, and elements with a level of zero are at the top level. -Elements with a level greater than zero are children of their -parent.

-

A pointer has the format @pname@, where pname is any sequence of -characters and numbers. The pointer identifies the object being -pointed to, so that any pointer included as the value of any -element points back to the original object. -For example, an -element may have a FAMS tag whose value is @F1@, meaning that this -element points to the family record in which the associated person -is a spouse. Likewise, an element with a tag of FAMC has a value -that points to a family record in which the associated person is a -child.

-

See a GEDCOM file for examples of tags and their values.

-

Tags available to an element are seen here: gedcom.tags

+

Element associated with a FAM_RECORD

Expand source code
class FamilyElement(Element):
+    """Element associated with a `FAM_RECORD`"""
+
+    def get_tag(self) -> str:
+        return tags.GEDCOM_TAG_FAMILY
+
+    def get_record(self) -> dict:
+        """Parse and return the full record in dictionary format.
+        """
+        record = {
+            'key_to_family': self.get_pointer(),
+            'restriction': '',
+            'events': family_event_structure(self),
+            'key_to_husband': '',
+            'key_to_wife': '',
+            'children': [],
+            'number_of_children': '',
+            'submitters': [],
+            'references': [],
+            'record_id': '',
+            'change_date': {},
+            'notes': [],
+            'citations': [],
+            'media': []
+        }
+        lds_events = lds_spouse_sealing(self)
+        if len(lds_events) > 0:
+            for event in lds_events:
+                record['events'].append(event)
 
-    def get_tag(self):
-        return gedcom.tags.GEDCOM_TAG_FAMILY
+ for child in self.get_child_elements(): + if child.get_tag() in FAMILY_SINGLE_TAGS: + record[FAMILY_SINGLE_TAGS[child.get_tag()]] = child.get_value() + continue + + if child.get_tag() == tags.GEDCOM_TAG_CHILD: + entry = { + 'key_to_child': child.get_value(), + 'relationship_to_father': '', + 'relationship_to_mother': '' + } + for gchild in child.get_child_elements(): + if gchild.get_tag() == tags.GEDCOM_PROGRAM_DEFINED_TAG_FREL: + entry['relationship_to_father'] = gchild.get_value() + continue + + if gchild.get_tag() == tags.GEDCOM_PROGRAM_DEFINED_TAG_MREL: + entry['relationship_to_mother'] = gchild.get_value() + + record['children'].append(entry) + continue + + if child.get_tag() == tags.GEDCOM_TAG_NOTE: + record['notes'].append(note_structure(child)) + continue + + if child.get_tag() == tags.GEDCOM_TAG_SOURCE: + record['citations'].append(source_citation(child)) + continue + + if child.get_tag() == tags.GEDCOM_TAG_OBJECT: + record['media'].append(multimedia_link(child)) + continue + + if child.get_tag() == tags.GEDCOM_TAG_REFERENCE: + record['references'].append(user_reference_number(child)) + continue + + if child.get_tag() == tags.GEDCOM_TAG_CHANGE: + record['change_date'] = change_date(child) + continue + + if child.get_tag() == tags.GEDCOM_TAG_SUBMITTER: + record['submitters'].append(child.get_value()) + continue + + return record

Ancestors

+

Methods

+
+
+def get_record(self) -> dict +
+
+

Parse and return the full record in dictionary format.

+
+ +Expand source code + +
def get_record(self) -> dict:
+    """Parse and return the full record in dictionary format.
+    """
+    record = {
+        'key_to_family': self.get_pointer(),
+        'restriction': '',
+        'events': family_event_structure(self),
+        'key_to_husband': '',
+        'key_to_wife': '',
+        'children': [],
+        'number_of_children': '',
+        'submitters': [],
+        'references': [],
+        'record_id': '',
+        'change_date': {},
+        'notes': [],
+        'citations': [],
+        'media': []
+    }
+    lds_events = lds_spouse_sealing(self)
+    if len(lds_events) > 0:
+        for event in lds_events:
+            record['events'].append(event)
+
+    for child in self.get_child_elements():
+        if child.get_tag() in FAMILY_SINGLE_TAGS:
+            record[FAMILY_SINGLE_TAGS[child.get_tag()]] = child.get_value()
+            continue
+
+        if child.get_tag() == tags.GEDCOM_TAG_CHILD:
+            entry = {
+                'key_to_child': child.get_value(),
+                'relationship_to_father': '',
+                'relationship_to_mother': ''
+            }
+            for gchild in child.get_child_elements():
+                if gchild.get_tag() == tags.GEDCOM_PROGRAM_DEFINED_TAG_FREL:
+                    entry['relationship_to_father'] = gchild.get_value()
+                    continue
+
+                if gchild.get_tag() == tags.GEDCOM_PROGRAM_DEFINED_TAG_MREL:
+                    entry['relationship_to_mother'] = gchild.get_value()
+
+            record['children'].append(entry)
+            continue
+
+        if child.get_tag() == tags.GEDCOM_TAG_NOTE:
+            record['notes'].append(note_structure(child))
+            continue
+
+        if child.get_tag() == tags.GEDCOM_TAG_SOURCE:
+            record['citations'].append(source_citation(child))
+            continue
+
+        if child.get_tag() == tags.GEDCOM_TAG_OBJECT:
+            record['media'].append(multimedia_link(child))
+            continue
+
+        if child.get_tag() == tags.GEDCOM_TAG_REFERENCE:
+            record['references'].append(user_reference_number(child))
+            continue
+
+        if child.get_tag() == tags.GEDCOM_TAG_CHANGE:
+            record['change_date'] = change_date(child)
+            continue
+
+        if child.get_tag() == tags.GEDCOM_TAG_SUBMITTER:
+            record['submitters'].append(child.get_value())
+            continue
+
+    return record
+
+
+

Inherited members

  • Element: @@ -138,25 +366,6 @@

    Inherited members

-
-class NotAnActualFamilyError -(...) -
-
-

Common base class for all non-exit exceptions.

-
- -Expand source code - -
class NotAnActualFamilyError(Exception):
-    pass
-
-

Ancestors

-
    -
  • builtins.Exception
  • -
  • builtins.BaseException
  • -
-
@@ -175,9 +384,9 @@

Index

@@ -185,7 +394,7 @@

-

Generated by pdoc 0.7.5.

+

Generated by pdoc 0.8.1.

diff --git a/docs/gedcom/element/header.html b/docs/gedcom/element/header.html new file mode 100644 index 0000000..b3d0a70 --- /dev/null +++ b/docs/gedcom/element/header.html @@ -0,0 +1,498 @@ + + + + + + +gedcom.element.header API documentation + + + + + + + + + +
+
+
+

Module gedcom.element.header

+
+
+

GEDCOM element for a HEADER header record identified by the +GEDCOM_TAG_HEADER tag.

+
+ +Expand source code + +
# -*- coding: utf-8 -*-
+
+# Python GEDCOM Parser
+#
+# Copyright (C) 2020 Christopher Horn (cdhorn at embarqmail dot com)
+# Copyright (C) 2018 Damon Brodie (damon.brodie at gmail.com)
+# Copyright (C) 2018-2019 Nicklas Reincke (contact at reynke.com)
+# Copyright (C) 2016 Andreas Oberritter
+# Copyright (C) 2012 Madeleine Price Ball
+# Copyright (C) 2005 Daniel Zappala (zappala at cs.byu.edu)
+# Copyright (C) 2005 Brigham Young University
+#
+# 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.
+#
+# Further information about the license: http://www.gnu.org/licenses/gpl-2.0.html
+
+"""
+GEDCOM element for a `HEADER` header record identified by the
+`gedcom.tags.GEDCOM_TAG_HEADER` tag.
+"""
+
+import gedcom.tags as tags
+from gedcom.element.element import Element
+from gedcom.subparsers.address_structure import address_structure
+from gedcom.subparsers.note_structure import note_structure
+
+HEADER_TAGS = {
+    tags.GEDCOM_TAG_DESTINATION: 'destination',
+    tags.GEDCOM_TAG_SUBMITTER: 'key_to_submitter',
+    tags.GEDCOM_TAG_SUBMISSION: 'key_to_submission',
+    tags.GEDCOM_TAG_FILE: 'file',
+    tags.GEDCOM_TAG_COPYRIGHT: 'copyright',
+    tags.GEDCOM_TAG_LANGUAGE: 'language',
+    tags.GEDCOM_PROGRAM_DEFINED_TAG_HOME_PERSON: 'key_to_home_person'
+}
+
+
+class HeaderElement(Element):
+    """Element associated with a `HEADER`"""
+
+    def get_tag(self) -> str:
+        return tags.GEDCOM_TAG_HEADER
+
+    def get_record(self) -> dict:
+        """Parse and return the full record in dictionary format.
+        """
+        record = {
+            'source': '',
+            'product': {
+                'version': '',
+                'name': '',
+                'corporation': '',
+                'address': {}
+            },
+            'data': {
+                'source_data': '',
+                'published': '',
+                'copyright': ''
+            },
+            'destination': '',
+            'transmission_date': '',
+            'transmission_time': '',
+            'key_to_submitter': '',
+            'key_to_submission': '',
+            'file': '',
+            'copyright': '',
+            'gedcom': {
+                'version': '',
+                'format': '',
+            },
+            'character_set': '',
+            'character_set_version': '',
+            'language': '',
+            'place_hierarchy': '',
+            'key_to_home_person': '',
+            'notes': []
+        }
+        for child in self.get_child_elements():
+            if child.get_tag() == tags.GEDCOM_TAG_SOURCE:
+                record['source'] = child.get_value()
+                for gchild in child.get_child_elements():
+                    if gchild.get_tag() == tags.GEDCOM_TAG_VERSION:
+                        record['product']['version'] = gchild.get_value()
+                        continue
+
+                    if gchild.get_tag() == tags.GEDCOM_TAG_NAME:
+                        record['product']['name'] = gchild.get_value()
+                        continue
+
+                    if gchild.get_tag() == tags.GEDCOM_TAG_CORPORATE:
+                        record['product']['corporation'] = gchild.get_value()
+
+                        for ggchild in gchild.get_child_elements():
+                            if ggchild.get_tag() == tags.GEDCOM_TAG_ADDRESS:
+                                record['product']['address'] = address_structure(gchild)
+                        continue
+
+                    if gchild.get_tag() == tags.GEDCOM_TAG_DATA:
+                        record['data']['source_data'] = gchild.get_value()
+                        for ggchild in gchild.get_child_elements():
+                            if ggchild.get_tag() == tags.GEDCOM_TAG_DATE:
+                                record['data']['published'] = ggchild.get_value()
+                                continue
+
+                            if ggchild.get_tag() == tags.GEDCOM_TAG_COPYRIGHT:
+                                record['data']['copyright'] = ggchild.get_multi_line_value()
+                        continue
+                continue
+
+            if child.get_tag() in HEADER_TAGS:
+                record[HEADER_TAGS[child.get_tag()]] = child.get_value()
+                continue
+
+            if child.get_tag() == tags.GEDCOM_TAG_DATE:
+                record['transmission_date'] = child.get_value()
+                for gchild in child.get_child_elements():
+                    if gchild.get_tag() == tags.GEDCOM_TAG_TIME:
+                        record['transmission_time'] = gchild.get_value()
+                continue
+
+            if child.get_tag() == tags.GEDCOM_TAG_GEDCOM:
+                for gchild in child.get_child_elements():
+                    if gchild.get_tag() == tags.GEDCOM_TAG_VERSION:
+                        record['gedcom']['version'] = gchild.get_value()
+                        continue
+
+                    if gchild.get_tag() == tags.GEDCOM_TAG_FORMAT:
+                        record['gedcom']['format'] = gchild.get_value()
+                continue
+
+            if child.get_tag() == tags.GEDCOM_TAG_CHARACTER:
+                record['character_set'] = child.get_value()
+                for gchild in child.get_child_elements():
+                    if gchild.get_tag() == tags.GEDCOM_TAG_VERSION:
+                        record['character_set_version'] = gchild.get_value()
+                continue
+
+            if child.get_tag() == tags.GEDCOM_TAG_PLACE:
+                for gchild in child.get_child_elements():
+                    if gchild.get_tag() == tags.GEDCOM_TAG_FORMAT:
+                        record['place_hierarchy'] = gchild.get_value()
+                continue
+
+            if child.get_tag() == tags.GEDCOM_TAG_NOTE:
+                record['notes'].append(note_structure(child))
+
+        return record
+
+
+
+
+
+
+
+
+
+

Classes

+
+
+class HeaderElement +(level: int, pointer: str, tag: str, value: str, crlf: str = '\n', multi_line: bool = True) +
+
+

Element associated with a HEADER

+
+ +Expand source code + +
class HeaderElement(Element):
+    """Element associated with a `HEADER`"""
+
+    def get_tag(self) -> str:
+        return tags.GEDCOM_TAG_HEADER
+
+    def get_record(self) -> dict:
+        """Parse and return the full record in dictionary format.
+        """
+        record = {
+            'source': '',
+            'product': {
+                'version': '',
+                'name': '',
+                'corporation': '',
+                'address': {}
+            },
+            'data': {
+                'source_data': '',
+                'published': '',
+                'copyright': ''
+            },
+            'destination': '',
+            'transmission_date': '',
+            'transmission_time': '',
+            'key_to_submitter': '',
+            'key_to_submission': '',
+            'file': '',
+            'copyright': '',
+            'gedcom': {
+                'version': '',
+                'format': '',
+            },
+            'character_set': '',
+            'character_set_version': '',
+            'language': '',
+            'place_hierarchy': '',
+            'key_to_home_person': '',
+            'notes': []
+        }
+        for child in self.get_child_elements():
+            if child.get_tag() == tags.GEDCOM_TAG_SOURCE:
+                record['source'] = child.get_value()
+                for gchild in child.get_child_elements():
+                    if gchild.get_tag() == tags.GEDCOM_TAG_VERSION:
+                        record['product']['version'] = gchild.get_value()
+                        continue
+
+                    if gchild.get_tag() == tags.GEDCOM_TAG_NAME:
+                        record['product']['name'] = gchild.get_value()
+                        continue
+
+                    if gchild.get_tag() == tags.GEDCOM_TAG_CORPORATE:
+                        record['product']['corporation'] = gchild.get_value()
+
+                        for ggchild in gchild.get_child_elements():
+                            if ggchild.get_tag() == tags.GEDCOM_TAG_ADDRESS:
+                                record['product']['address'] = address_structure(gchild)
+                        continue
+
+                    if gchild.get_tag() == tags.GEDCOM_TAG_DATA:
+                        record['data']['source_data'] = gchild.get_value()
+                        for ggchild in gchild.get_child_elements():
+                            if ggchild.get_tag() == tags.GEDCOM_TAG_DATE:
+                                record['data']['published'] = ggchild.get_value()
+                                continue
+
+                            if ggchild.get_tag() == tags.GEDCOM_TAG_COPYRIGHT:
+                                record['data']['copyright'] = ggchild.get_multi_line_value()
+                        continue
+                continue
+
+            if child.get_tag() in HEADER_TAGS:
+                record[HEADER_TAGS[child.get_tag()]] = child.get_value()
+                continue
+
+            if child.get_tag() == tags.GEDCOM_TAG_DATE:
+                record['transmission_date'] = child.get_value()
+                for gchild in child.get_child_elements():
+                    if gchild.get_tag() == tags.GEDCOM_TAG_TIME:
+                        record['transmission_time'] = gchild.get_value()
+                continue
+
+            if child.get_tag() == tags.GEDCOM_TAG_GEDCOM:
+                for gchild in child.get_child_elements():
+                    if gchild.get_tag() == tags.GEDCOM_TAG_VERSION:
+                        record['gedcom']['version'] = gchild.get_value()
+                        continue
+
+                    if gchild.get_tag() == tags.GEDCOM_TAG_FORMAT:
+                        record['gedcom']['format'] = gchild.get_value()
+                continue
+
+            if child.get_tag() == tags.GEDCOM_TAG_CHARACTER:
+                record['character_set'] = child.get_value()
+                for gchild in child.get_child_elements():
+                    if gchild.get_tag() == tags.GEDCOM_TAG_VERSION:
+                        record['character_set_version'] = gchild.get_value()
+                continue
+
+            if child.get_tag() == tags.GEDCOM_TAG_PLACE:
+                for gchild in child.get_child_elements():
+                    if gchild.get_tag() == tags.GEDCOM_TAG_FORMAT:
+                        record['place_hierarchy'] = gchild.get_value()
+                continue
+
+            if child.get_tag() == tags.GEDCOM_TAG_NOTE:
+                record['notes'].append(note_structure(child))
+
+        return record
+
+

Ancestors

+ +

Methods

+
+
+def get_record(self) -> dict +
+
+

Parse and return the full record in dictionary format.

+
+ +Expand source code + +
def get_record(self) -> dict:
+    """Parse and return the full record in dictionary format.
+    """
+    record = {
+        'source': '',
+        'product': {
+            'version': '',
+            'name': '',
+            'corporation': '',
+            'address': {}
+        },
+        'data': {
+            'source_data': '',
+            'published': '',
+            'copyright': ''
+        },
+        'destination': '',
+        'transmission_date': '',
+        'transmission_time': '',
+        'key_to_submitter': '',
+        'key_to_submission': '',
+        'file': '',
+        'copyright': '',
+        'gedcom': {
+            'version': '',
+            'format': '',
+        },
+        'character_set': '',
+        'character_set_version': '',
+        'language': '',
+        'place_hierarchy': '',
+        'key_to_home_person': '',
+        'notes': []
+    }
+    for child in self.get_child_elements():
+        if child.get_tag() == tags.GEDCOM_TAG_SOURCE:
+            record['source'] = child.get_value()
+            for gchild in child.get_child_elements():
+                if gchild.get_tag() == tags.GEDCOM_TAG_VERSION:
+                    record['product']['version'] = gchild.get_value()
+                    continue
+
+                if gchild.get_tag() == tags.GEDCOM_TAG_NAME:
+                    record['product']['name'] = gchild.get_value()
+                    continue
+
+                if gchild.get_tag() == tags.GEDCOM_TAG_CORPORATE:
+                    record['product']['corporation'] = gchild.get_value()
+
+                    for ggchild in gchild.get_child_elements():
+                        if ggchild.get_tag() == tags.GEDCOM_TAG_ADDRESS:
+                            record['product']['address'] = address_structure(gchild)
+                    continue
+
+                if gchild.get_tag() == tags.GEDCOM_TAG_DATA:
+                    record['data']['source_data'] = gchild.get_value()
+                    for ggchild in gchild.get_child_elements():
+                        if ggchild.get_tag() == tags.GEDCOM_TAG_DATE:
+                            record['data']['published'] = ggchild.get_value()
+                            continue
+
+                        if ggchild.get_tag() == tags.GEDCOM_TAG_COPYRIGHT:
+                            record['data']['copyright'] = ggchild.get_multi_line_value()
+                    continue
+            continue
+
+        if child.get_tag() in HEADER_TAGS:
+            record[HEADER_TAGS[child.get_tag()]] = child.get_value()
+            continue
+
+        if child.get_tag() == tags.GEDCOM_TAG_DATE:
+            record['transmission_date'] = child.get_value()
+            for gchild in child.get_child_elements():
+                if gchild.get_tag() == tags.GEDCOM_TAG_TIME:
+                    record['transmission_time'] = gchild.get_value()
+            continue
+
+        if child.get_tag() == tags.GEDCOM_TAG_GEDCOM:
+            for gchild in child.get_child_elements():
+                if gchild.get_tag() == tags.GEDCOM_TAG_VERSION:
+                    record['gedcom']['version'] = gchild.get_value()
+                    continue
+
+                if gchild.get_tag() == tags.GEDCOM_TAG_FORMAT:
+                    record['gedcom']['format'] = gchild.get_value()
+            continue
+
+        if child.get_tag() == tags.GEDCOM_TAG_CHARACTER:
+            record['character_set'] = child.get_value()
+            for gchild in child.get_child_elements():
+                if gchild.get_tag() == tags.GEDCOM_TAG_VERSION:
+                    record['character_set_version'] = gchild.get_value()
+            continue
+
+        if child.get_tag() == tags.GEDCOM_TAG_PLACE:
+            for gchild in child.get_child_elements():
+                if gchild.get_tag() == tags.GEDCOM_TAG_FORMAT:
+                    record['place_hierarchy'] = gchild.get_value()
+            continue
+
+        if child.get_tag() == tags.GEDCOM_TAG_NOTE:
+            record['notes'].append(note_structure(child))
+
+    return record
+
+
+
+

Inherited members

+ +
+
+
+
+ +
+ + + + + \ No newline at end of file diff --git a/docs/gedcom/element/index.html b/docs/gedcom/element/index.html index dc608ef..22738d6 100644 --- a/docs/gedcom/element/index.html +++ b/docs/gedcom/element/index.html @@ -3,15 +3,15 @@ - + gedcom.element API documentation - - + + @@ -21,7 +21,7 @@

Module gedcom.element

-

Module containing all relevant elements generated by a Parser. +

Module containing all relevant elements generated by a Parser. An element represents a line within GEDCOM data.

@@ -62,10 +62,15 @@

Module gedcom.element

__all__ = [ "element", "family", - "file", + "header", "individual", + "note", "object", - "root" + "repository", + "root", + "source", + "submission", + "submitter" ]
@@ -74,27 +79,56 @@

Sub-modules

gedcom.element.element
-

Base GEDCOM element

+

Base GEDCOM element.

gedcom.element.family
-

GEDCOM element consisting of tag GEDCOM_TAG_FAMILY

+

GEDCOM element for a FAM_RECORD family record identified by the +GEDCOM_TAG_FAMILY tag.

-
gedcom.element.file
+
gedcom.element.header
-

GEDCOM element consisting of tag GEDCOM_TAG_FILE

+

GEDCOM element for a HEADER header record identified by the +GEDCOM_TAG_HEADER tag.

gedcom.element.individual
-

GEDCOM element consisting of tag GEDCOM_TAG_INDIVIDUAL

+

GEDCOM element for a INDIVIDUAL_RECORD individual record identified by the +GEDCOM_TAG_INDIVIDUAL tag.

+
+
gedcom.element.note
+
+

GEDCOM element for a NOTE_RECORD note record identified by the +GEDCOM_TAG_NOTE tag.

gedcom.element.object
-

GEDCOM element consisting of tag GEDCOM_TAG_OBJECT

+

GEDCOM element for a MULTIMEDIA_RECORD media record identified by the +GEDCOM_TAG_OBJECT tag.

+
+
gedcom.element.repository
+
+

GEDCOM element for a REPOSITORY_RECORD repository record identified by the +GEDCOM_TAG_REPOSITORY tag.

gedcom.element.root
-

Virtual GEDCOM root element containing all logical records as children

+

Virtual GEDCOM root element containing all logical records as children

+
+
gedcom.element.source
+
+

GEDCOM element for a SOURCE_RECORD source record identified by the +GEDCOM_TAG_SOURCE tag.

+
+
gedcom.element.submission
+
+

GEDCOM element for a SUBMISSION_RECORD submission record identified by the +GEDCOM_TAG_SUBMISSION tag.

+
+
gedcom.element.submitter
+
+

GEDCOM element for a SUBMITTER_RECORD submitter record identified by the +GEDCOM_TAG_SUBMITTER tag.

@@ -120,17 +154,22 @@

Index

diff --git a/docs/gedcom/element/individual.html b/docs/gedcom/element/individual.html index 34421c0..83f897b 100644 --- a/docs/gedcom/element/individual.html +++ b/docs/gedcom/element/individual.html @@ -3,14 +3,15 @@ - + gedcom.element.individual API documentation - + - - + + @@ -20,7 +21,8 @@

Module gedcom.element.individual

-

GEDCOM element consisting of tag GEDCOM_TAG_INDIVIDUAL

+

GEDCOM element for a INDIVIDUAL_RECORD individual record identified by the +GEDCOM_TAG_INDIVIDUAL tag.

Expand source code @@ -29,6 +31,7 @@

Module gedcom.element.individual

# Python GEDCOM Parser # +# Copyright (C) 2020 Christopher Horn (cdhorn at embarqmail dot com) # Copyright (C) 2018 Damon Brodie (damon.brodie at gmail.com) # Copyright (C) 2018-2019 Nicklas Reincke (contact at reynke.com) # Copyright (C) 2016 Andreas Oberritter @@ -52,71 +55,179 @@

Module gedcom.element.individual

# # Further information about the license: http://www.gnu.org/licenses/gpl-2.0.html -"""GEDCOM element consisting of tag `gedcom.tags.GEDCOM_TAG_INDIVIDUAL`""" +""" +GEDCOM element for a `INDIVIDUAL_RECORD` individual record identified by the +`gedcom.tags.GEDCOM_TAG_INDIVIDUAL` tag. +""" +from typing import Tuple, List import re as regex + +import gedcom.tags as tags from gedcom.element.element import Element +from gedcom.subparsers.personal_name_structure import personal_name_structure +from gedcom.subparsers.individual_event_structure import individual_event_structure +from gedcom.subparsers.individual_attribute_structure import individual_attribute_structure +from gedcom.subparsers.lds_individual_ordinance import lds_individual_ordinance +from gedcom.subparsers.child_to_family_link import child_to_family_link +from gedcom.subparsers.spouse_to_family_link import spouse_to_family_link +from gedcom.subparsers.association_structure import association_structure +from gedcom.subparsers.user_reference_number import user_reference_number +from gedcom.subparsers.change_date import change_date +from gedcom.subparsers.note_structure import note_structure +from gedcom.subparsers.source_citation import source_citation +from gedcom.subparsers.multimedia_link import multimedia_link from gedcom.helpers import deprecated -import gedcom.tags - -class NotAnActualIndividualError(Exception): - pass +INDIVIDUAL_SINGLE_TAGS = { + tags.GEDCOM_TAG_RESTRICTION: 'restriction', + tags.GEDCOM_TAG_SEX: 'sex', + tags.GEDCOM_TAG_REC_ID_NUMBER: 'record_id', + tags.GEDCOM_TAG_REC_FILE_NUMBER: 'permanent_file_number', + tags.GEDCOM_TAG_AFN: 'ancestral_file_number' +} class IndividualElement(Element): + """Element associated with an `INDIVIDUAL_RECORD`""" + + def get_tag(self) -> str: + return tags.GEDCOM_TAG_INDIVIDUAL + + def get_record(self) -> dict: + """Parse and return the full record in dictionary format. + """ + record = { + 'key_to_individual': self.get_pointer(), + 'restriction': '', + 'names': [], + 'sex': 'U', + 'events': individual_event_structure(self), + 'attributes': individual_attribute_structure(self), + 'child_to_family': [], + 'spouse_to_family': [], + 'submitters': [], + 'associates': [], + 'aliases': [], + 'ancestors_interest': [], + 'descendants_interest': [], + 'permanent_file_number': '', + 'ancestral_file_number': '', + 'references': [], + 'record_id': '', + 'change_date': {}, + 'notes': [], + 'citations': [], + 'media': [] + } + lds_events = lds_individual_ordinance(self) + if len(lds_events) > 0: + for event in lds_events: + record['events'].append(event) + + for child in self.get_child_elements(): + if child.get_tag() in INDIVIDUAL_SINGLE_TAGS: + record[INDIVIDUAL_SINGLE_TAGS[child.get_tag()]] = child.get_value() + continue + + if child.get_tag() == tags.GEDCOM_TAG_NAME: + record['names'].append(personal_name_structure(child)) + continue + + if child.get_tag() == tags.GEDCOM_TAG_FAMILY_CHILD: + record['child_to_family'].append(child_to_family_link(child)) + continue + + if child.get_tag() == tags.GEDCOM_TAG_FAMILY_SPOUSE: + record['spouse_to_family'].append(spouse_to_family_link(child)) + continue + + if child.get_tag() == tags.GEDCOM_TAG_NOTE: + record['notes'].append(note_structure(child)) + continue + + if child.get_tag() == tags.GEDCOM_TAG_SOURCE: + record['citations'].append(source_citation(child)) + continue + + if child.get_tag() == tags.GEDCOM_TAG_MEDIA: + record['media'].append(multimedia_link(child)) + continue + + if child.get_tag() == tags.GEDCOM_TAG_SUBMITTER: + record['submitters'].append(child.get_value()) + continue + + if child.get_tag() == tags.GEDCOM_TAG_ASSOCIATES: + record['associates'].append(association_structure(child)) + continue + + if child.get_tag() == tags.GEDCOM_TAG_ALIAS: + record['aliases'].append(child.get_value()) + continue + + if child.get_tag() == tags.GEDCOM_TAG_ANCES_INTEREST: + record['ancestors_interest'].append(child.get_value()) + continue + + if child.get_tag() == tags.GEDCOM_TAG_DESCENDANTS_INT: + record['descendants_interest'].append(child.get_value()) + continue + + if child.get_tag() == tags.GEDCOM_TAG_REFERENCE: + record['references'].append(user_reference_number(child)) + continue + + if child.get_tag() == tags.GEDCOM_TAG_CHANGE: + record['changed'] = change_date(child) - def get_tag(self): - return gedcom.tags.GEDCOM_TAG_INDIVIDUAL + return record - def is_deceased(self): - """Checks if this individual is deceased - :rtype: bool + def is_deceased(self) -> bool: + """Checks if this individual is deceased. """ for child in self.get_child_elements(): - if child.get_tag() == gedcom.tags.GEDCOM_TAG_DEATH: + if child.get_tag() == tags.GEDCOM_TAG_DEATH: return True return False - def is_child(self): - """Checks if this element is a child of a family - :rtype: bool + def is_child(self) -> bool: + """Checks if this element is a child of a family. """ found_child = False for child in self.get_child_elements(): - if child.get_tag() == gedcom.tags.GEDCOM_TAG_FAMILY_CHILD: + if child.get_tag() == tags.GEDCOM_TAG_FAMILY_CHILD: found_child = True return found_child - def is_private(self): - """Checks if this individual is marked private - :rtype: bool + def is_private(self) -> bool: + """Checks if this individual is marked private. """ for child in self.get_child_elements(): - if child.get_tag() == gedcom.tags.GEDCOM_TAG_PRIVATE: + if child.get_tag() == tags.GEDCOM_TAG_PRIVATE: private = child.get_value() if private == 'Y': return True return False - def get_name(self): + def get_name(self) -> Tuple[str, str]: """Returns an individual's names as a tuple: (`str` given_name, `str` surname) - :rtype: tuple """ given_name = "" surname = "" - # Return the first gedcom.tags.GEDCOM_TAG_NAME that is found. - # Alternatively as soon as we have both the gedcom.tags.GEDCOM_TAG_GIVEN_NAME and _SURNAME return those. + # Return the first tags.GEDCOM_TAG_NAME that is found. + # Alternatively as soon as we have both the tags.GEDCOM_TAG_GIVEN_NAME + # and _SURNAME return those. found_given_name = False found_surname_name = False for child in self.get_child_elements(): - if child.get_tag() == gedcom.tags.GEDCOM_TAG_NAME: + if child.get_tag() == tags.GEDCOM_TAG_NAME: # Some GEDCOM files don't use child tags but instead # place the name in the value of the NAME tag. if child.get_value() != "": @@ -129,14 +240,14 @@

Module gedcom.element.individual

return given_name, surname - for childOfChild in child.get_child_elements(): + for gchild in child.get_child_elements(): - if childOfChild.get_tag() == gedcom.tags.GEDCOM_TAG_GIVEN_NAME: - given_name = childOfChild.get_value() + if gchild.get_tag() == tags.GEDCOM_TAG_GIVEN_NAME: + given_name = gchild.get_value() found_given_name = True - if childOfChild.get_tag() == gedcom.tags.GEDCOM_TAG_SURNAME: - surname = childOfChild.get_value() + if gchild.get_tag() == tags.GEDCOM_TAG_SURNAME: + surname = gchild.get_value() found_surname_name = True if found_given_name and found_surname_name: @@ -145,80 +256,74 @@

Module gedcom.element.individual

# If we reach here we are probably returning empty strings return given_name, surname - def get_all_names(self): - return [a.get_value() for a in self.get_child_elements() if a.get_tag() == gedcom.tags.GEDCOM_TAG_NAME] + def get_all_names(self) -> List[str]: + """Return all names.""" + return [a.get_value() for a in self.get_child_elements() + if a.get_tag() == tags.GEDCOM_TAG_NAME] - def surname_match(self, surname_to_match): - """Matches a string with the surname of an individual - :type surname_to_match: str - :rtype: bool + def surname_match(self, surname_to_match: str) -> bool: + """Matches a string with the surname of an individual. """ (given_name, surname) = self.get_name() return regex.search(surname_to_match, surname, regex.IGNORECASE) @deprecated - def given_match(self, name): - """Matches a string with the given name of an individual + def given_match(self, name: str) -> bool: + """Matches a string with the given name of an individual. ::deprecated:: As of version 1.0.0 use `given_name_match()` method instead - :type name: str - :rtype: bool """ return self.given_name_match(name) - def given_name_match(self, given_name_to_match): - """Matches a string with the given name of an individual - :type given_name_to_match: str - :rtype: bool + def given_name_match(self, given_name_to_match: str) -> bool: + """Matches a string with the given name of an individual. """ (given_name, surname) = self.get_name() return regex.search(given_name_to_match, given_name, regex.IGNORECASE) - def get_gender(self): - """Returns the gender of a person in string format - :rtype: str + def get_gender(self) -> str: + """Returns the gender of a person in string format. """ gender = "" for child in self.get_child_elements(): - if child.get_tag() == gedcom.tags.GEDCOM_TAG_SEX: + if child.get_tag() == tags.GEDCOM_TAG_SEX: gender = child.get_value() return gender - def get_birth_data(self): - """Returns the birth data of a person formatted as a tuple: (`str` date, `str` place, `list` sources) - :rtype: tuple + def get_birth_data(self) -> Tuple[str, str, List[str]]: + """Returns the birth data of a person formatted as a tuple: + (`str` date, `str` place, `list` sources) """ date = "" place = "" sources = [] for child in self.get_child_elements(): - if child.get_tag() == gedcom.tags.GEDCOM_TAG_BIRTH: - for childOfChild in child.get_child_elements(): + if child.get_tag() == tags.GEDCOM_TAG_BIRTH: + for gchild in child.get_child_elements(): - if childOfChild.get_tag() == gedcom.tags.GEDCOM_TAG_DATE: - date = childOfChild.get_value() + if gchild.get_tag() == tags.GEDCOM_TAG_DATE: + date = gchild.get_value() - if childOfChild.get_tag() == gedcom.tags.GEDCOM_TAG_PLACE: - place = childOfChild.get_value() + if gchild.get_tag() == tags.GEDCOM_TAG_PLACE: + place = gchild.get_value() - if childOfChild.get_tag() == gedcom.tags.GEDCOM_TAG_SOURCE: - sources.append(childOfChild.get_value()) + if gchild.get_tag() == tags.GEDCOM_TAG_SOURCE: + sources.append(gchild.get_value()) return date, place, sources - def get_birth_year(self): - """Returns the birth year of a person in integer format - :rtype: int + def get_birth_year(self) -> int: + """Returns the birth year of a person in integer format. """ date = "" for child in self.get_child_elements(): - if child.get_tag() == gedcom.tags.GEDCOM_TAG_BIRTH: - for childOfChild in child.get_child_elements(): - if childOfChild.get_tag() == gedcom.tags.GEDCOM_TAG_DATE: - date_split = childOfChild.get_value().split() + if child.get_tag() == tags.GEDCOM_TAG_BIRTH: + for gchild in child.get_child_elements(): + if gchild.get_tag() == tags.GEDCOM_TAG_DATE: + date_split = gchild.get_value().split() date = date_split[len(date_split) - 1] if date == "": @@ -228,37 +333,36 @@

Module gedcom.element.individual

except ValueError: return -1 - def get_death_data(self): - """Returns the death data of a person formatted as a tuple: (`str` date, `str` place, `list` sources) - :rtype: tuple + def get_death_data(self) -> Tuple[str, str, List[str]]: + """Returns the death data of a person formatted as a tuple: + (`str` date, `str` place, `list` sources) """ date = "" place = "" sources = [] for child in self.get_child_elements(): - if child.get_tag() == gedcom.tags.GEDCOM_TAG_DEATH: - for childOfChild in child.get_child_elements(): - if childOfChild.get_tag() == gedcom.tags.GEDCOM_TAG_DATE: - date = childOfChild.get_value() - if childOfChild.get_tag() == gedcom.tags.GEDCOM_TAG_PLACE: - place = childOfChild.get_value() - if childOfChild.get_tag() == gedcom.tags.GEDCOM_TAG_SOURCE: - sources.append(childOfChild.get_value()) + if child.get_tag() == tags.GEDCOM_TAG_DEATH: + for gchild in child.get_child_elements(): + if gchild.get_tag() == tags.GEDCOM_TAG_DATE: + date = gchild.get_value() + if gchild.get_tag() == tags.GEDCOM_TAG_PLACE: + place = gchild.get_value() + if gchild.get_tag() == tags.GEDCOM_TAG_SOURCE: + sources.append(gchild.get_value()) return date, place, sources - def get_death_year(self): - """Returns the death year of a person in integer format - :rtype: int + def get_death_year(self) -> int: + """Returns the death year of a person in integer format. """ date = "" for child in self.get_child_elements(): - if child.get_tag() == gedcom.tags.GEDCOM_TAG_DEATH: - for childOfChild in child.get_child_elements(): - if childOfChild.get_tag() == gedcom.tags.GEDCOM_TAG_DATE: - date_split = childOfChild.get_value().split() + if child.get_tag() == tags.GEDCOM_TAG_DEATH: + for gchild in child.get_child_elements(): + if gchild.get_tag() == tags.GEDCOM_TAG_DATE: + date_split = gchild.get_value().split() date = date_split[len(date_split) - 1] if date == "": @@ -269,110 +373,103 @@

Module gedcom.element.individual

return -1 @deprecated - def get_burial(self): - """Returns the burial data of a person formatted as a tuple: (`str` date, `str´ place, `list` sources) + def get_burial(self) -> Tuple[str, str, List[str]]: + """Returns the burial data of a person formatted as a tuple: + (`str` date, `str´ place, `list` sources) ::deprecated:: As of version 1.0.0 use `get_burial_data()` method instead - :rtype: tuple """ self.get_burial_data() - def get_burial_data(self): - """Returns the burial data of a person formatted as a tuple: (`str` date, `str´ place, `list` sources) - :rtype: tuple + def get_burial_data(self) -> Tuple[str, str, List[str]]: + """Returns the burial data of a person formatted as a tuple: + (`str` date, `str´ place, `list` sources) """ date = "" place = "" sources = [] for child in self.get_child_elements(): - if child.get_tag() == gedcom.tags.GEDCOM_TAG_BURIAL: - for childOfChild in child.get_child_elements(): + if child.get_tag() == tags.GEDCOM_TAG_BURIAL: + for gchild in child.get_child_elements(): - if childOfChild.get_tag() == gedcom.tags.GEDCOM_TAG_DATE: - date = childOfChild.get_value() + if gchild.get_tag() == tags.GEDCOM_TAG_DATE: + date = gchild.get_value() - if childOfChild.get_tag() == gedcom.tags.GEDCOM_TAG_PLACE: - place = childOfChild.get_value() + if gchild.get_tag() == tags.GEDCOM_TAG_PLACE: + place = gchild.get_value() - if childOfChild.get_tag() == gedcom.tags.GEDCOM_TAG_SOURCE: - sources.append(childOfChild.get_value()) + if gchild.get_tag() == tags.GEDCOM_TAG_SOURCE: + sources.append(gchild.get_value()) return date, place, sources @deprecated - def get_census(self): - """Returns a list of censuses of an individual formatted as tuples: (`str` date, `str´ place, `list` sources) + def get_census(self) -> List[Tuple[str, str, List[str]]]: + """Returns a list of censuses of an individual formatted as tuples: + (`str` date, `str´ place, `list` sources) ::deprecated:: As of version 1.0.0 use `get_census_data()` method instead - :rtype: list of tuple """ self.get_census_data() - def get_census_data(self): - """Returns a list of censuses of an individual formatted as tuples: (`str` date, `str´ place, `list` sources) - :rtype: list of tuple + def get_census_data(self) -> List[Tuple[str, str, List[str]]]: + """Returns a list of censuses of an individual formatted as tuples: + (`str` date, `str´ place, `list` sources) """ census = [] for child in self.get_child_elements(): - if child.get_tag() == gedcom.tags.GEDCOM_TAG_CENSUS: + if child.get_tag() == tags.GEDCOM_TAG_CENSUS: date = '' place = '' sources = [] - for childOfChild in child.get_child_elements(): + for gchild in child.get_child_elements(): - if childOfChild.get_tag() == gedcom.tags.GEDCOM_TAG_DATE: - date = childOfChild.get_value() + if gchild.get_tag() == tags.GEDCOM_TAG_DATE: + date = gchild.get_value() - if childOfChild.get_tag() == gedcom.tags.GEDCOM_TAG_PLACE: - place = childOfChild.get_value() + if gchild.get_tag() == tags.GEDCOM_TAG_PLACE: + place = gchild.get_value() - if childOfChild.get_tag() == gedcom.tags.GEDCOM_TAG_SOURCE: - sources.append(childOfChild.get_value()) + if gchild.get_tag() == tags.GEDCOM_TAG_SOURCE: + sources.append(gchild.get_value()) census.append((date, place, sources)) return census - def get_last_change_date(self): - """Returns the date of when the person data was last changed formatted as a string - :rtype: str + def get_last_change_date(self) -> str: + """Returns the date of when the person data was last changed formatted as a string. """ date = "" for child in self.get_child_elements(): - if child.get_tag() == gedcom.tags.GEDCOM_TAG_CHANGE: - for childOfChild in child.get_child_elements(): - if childOfChild.get_tag() == gedcom.tags.GEDCOM_TAG_DATE: - date = childOfChild.get_value() + if child.get_tag() == tags.GEDCOM_TAG_CHANGE: + for gchild in child.get_child_elements(): + if gchild.get_tag() == tags.GEDCOM_TAG_DATE: + date = gchild.get_value() return date - def get_occupation(self): - """Returns the occupation of a person - :rtype: str + def get_occupation(self) -> str: + """Returns the occupation of a person. """ occupation = "" for child in self.get_child_elements(): - if child.get_tag() == gedcom.tags.GEDCOM_TAG_OCCUPATION: + if child.get_tag() == tags.GEDCOM_TAG_OCCUPATION: occupation = child.get_value() return occupation - def birth_year_match(self, year): - """Returns `True` if the given year matches the birth year of this person - :type year: int - :rtype: bool + def birth_year_match(self, year: int) -> bool: + """Returns `True` if the given year matches the birth year of this person. """ return self.get_birth_year() == year - def birth_range_match(self, from_year, to_year): - """Checks if the birth year of a person lies within the given range - :type from_year: int - :type to_year: int - :rtype: bool + def birth_range_match(self, from_year: int, to_year: int) -> bool: + """Checks if the birth year of a person lies within the given range. """ birth_year = self.get_birth_year() @@ -381,18 +478,13 @@

Module gedcom.element.individual

return False - def death_year_match(self, year): - """Returns `True` if the given year matches the death year of this person - :type year: int - :rtype: bool + def death_year_match(self, year: int) -> bool: + """Returns `True` if the given year matches the death year of this person. """ return self.get_death_year() == year - def death_range_match(self, from_year, to_year): - """Checks if the death year of a person lies within the given range - :type from_year: int - :type to_year: int - :rtype: bool + def death_range_match(self, from_year: int, to_year: int) -> bool: + """Checks if the death year of a person lies within the given range. """ death_year = self.get_death_year() @@ -401,8 +493,8 @@

Module gedcom.element.individual

return False - def criteria_match(self, criteria): - """Checks if this individual matches all of the given criteria + def criteria_match(self, criteria: str) -> bool: + """Checks if this individual matches all of the given criteria. `criteria` is a colon-separated list, where each item in the list has the form [name]=[value]. The following criteria are supported: @@ -416,9 +508,6 @@

Module gedcom.element.individual

birth_range=[from_year-to_year] Match a person whose birth year is in the range of years from [from_year] to [to_year], including both [from_year] and [to_year]. - - :type criteria: str - :rtype: bool """ # Check if criteria is a valid criteria and can be split by `:` and `=` characters @@ -491,87 +580,154 @@

Classes

class IndividualElement -(level, pointer, tag, value, crlf='\n', multi_line=True) +(level: int, pointer: str, tag: str, value: str, crlf: str = '\n', multi_line: bool = True)
-

GEDCOM element

-

Each line in a GEDCOM file is an element with the format

-

level [pointer] tag [value]

-

where level and tag are required, and pointer and value are -optional. -Elements are arranged hierarchically according to their -level, and elements with a level of zero are at the top level. -Elements with a level greater than zero are children of their -parent.

-

A pointer has the format @pname@, where pname is any sequence of -characters and numbers. The pointer identifies the object being -pointed to, so that any pointer included as the value of any -element points back to the original object. -For example, an -element may have a FAMS tag whose value is @F1@, meaning that this -element points to the family record in which the associated person -is a spouse. Likewise, an element with a tag of FAMC has a value -that points to a family record in which the associated person is a -child.

-

See a GEDCOM file for examples of tags and their values.

-

Tags available to an element are seen here: gedcom.tags

+

Element associated with an INDIVIDUAL_RECORD

Expand source code
class IndividualElement(Element):
+    """Element associated with an `INDIVIDUAL_RECORD`"""
+
+    def get_tag(self) -> str:
+        return tags.GEDCOM_TAG_INDIVIDUAL
+
+    def get_record(self) -> dict:
+        """Parse and return the full record in dictionary format.
+        """
+        record = {
+            'key_to_individual': self.get_pointer(),
+            'restriction': '',
+            'names': [],
+            'sex': 'U',
+            'events': individual_event_structure(self),
+            'attributes': individual_attribute_structure(self),
+            'child_to_family': [],
+            'spouse_to_family': [],
+            'submitters': [],
+            'associates': [],
+            'aliases': [],
+            'ancestors_interest': [],
+            'descendants_interest': [],
+            'permanent_file_number': '',
+            'ancestral_file_number': '',
+            'references': [],
+            'record_id': '',
+            'change_date': {},
+            'notes': [],
+            'citations': [],
+            'media': []
+        }
+        lds_events = lds_individual_ordinance(self)
+        if len(lds_events) > 0:
+            for event in lds_events:
+                record['events'].append(event)
+
+        for child in self.get_child_elements():
+            if child.get_tag() in INDIVIDUAL_SINGLE_TAGS:
+                record[INDIVIDUAL_SINGLE_TAGS[child.get_tag()]] = child.get_value()
+                continue
+
+            if child.get_tag() == tags.GEDCOM_TAG_NAME:
+                record['names'].append(personal_name_structure(child))
+                continue
+
+            if child.get_tag() == tags.GEDCOM_TAG_FAMILY_CHILD:
+                record['child_to_family'].append(child_to_family_link(child))
+                continue
+
+            if child.get_tag() == tags.GEDCOM_TAG_FAMILY_SPOUSE:
+                record['spouse_to_family'].append(spouse_to_family_link(child))
+                continue
+
+            if child.get_tag() == tags.GEDCOM_TAG_NOTE:
+                record['notes'].append(note_structure(child))
+                continue
 
-    def get_tag(self):
-        return gedcom.tags.GEDCOM_TAG_INDIVIDUAL
+            if child.get_tag() == tags.GEDCOM_TAG_SOURCE:
+                record['citations'].append(source_citation(child))
+                continue
 
-    def is_deceased(self):
-        """Checks if this individual is deceased
-        :rtype: bool
+            if child.get_tag() == tags.GEDCOM_TAG_MEDIA:
+                record['media'].append(multimedia_link(child))
+                continue
+
+            if child.get_tag() == tags.GEDCOM_TAG_SUBMITTER:
+                record['submitters'].append(child.get_value())
+                continue
+
+            if child.get_tag() == tags.GEDCOM_TAG_ASSOCIATES:
+                record['associates'].append(association_structure(child))
+                continue
+
+            if child.get_tag() == tags.GEDCOM_TAG_ALIAS:
+                record['aliases'].append(child.get_value())
+                continue
+
+            if child.get_tag() == tags.GEDCOM_TAG_ANCES_INTEREST:
+                record['ancestors_interest'].append(child.get_value())
+                continue
+
+            if child.get_tag() == tags.GEDCOM_TAG_DESCENDANTS_INT:
+                record['descendants_interest'].append(child.get_value())
+                continue
+
+            if child.get_tag() == tags.GEDCOM_TAG_REFERENCE:
+                record['references'].append(user_reference_number(child))
+                continue
+
+            if child.get_tag() == tags.GEDCOM_TAG_CHANGE:
+                record['changed'] = change_date(child)
+
+        return record
+
+    def is_deceased(self) -> bool:
+        """Checks if this individual is deceased.
         """
         for child in self.get_child_elements():
-            if child.get_tag() == gedcom.tags.GEDCOM_TAG_DEATH:
+            if child.get_tag() == tags.GEDCOM_TAG_DEATH:
                 return True
 
         return False
 
-    def is_child(self):
-        """Checks if this element is a child of a family
-        :rtype: bool
+    def is_child(self) -> bool:
+        """Checks if this element is a child of a family.
         """
         found_child = False
 
         for child in self.get_child_elements():
-            if child.get_tag() == gedcom.tags.GEDCOM_TAG_FAMILY_CHILD:
+            if child.get_tag() == tags.GEDCOM_TAG_FAMILY_CHILD:
                 found_child = True
 
         return found_child
 
-    def is_private(self):
-        """Checks if this individual is marked private
-        :rtype: bool
+    def is_private(self) -> bool:
+        """Checks if this individual is marked private.
         """
         for child in self.get_child_elements():
-            if child.get_tag() == gedcom.tags.GEDCOM_TAG_PRIVATE:
+            if child.get_tag() == tags.GEDCOM_TAG_PRIVATE:
                 private = child.get_value()
                 if private == 'Y':
                     return True
 
         return False
 
-    def get_name(self):
+    def get_name(self) -> Tuple[str, str]:
         """Returns an individual's names as a tuple: (`str` given_name, `str` surname)
-        :rtype: tuple
         """
         given_name = ""
         surname = ""
 
-        # Return the first gedcom.tags.GEDCOM_TAG_NAME that is found.
-        # Alternatively as soon as we have both the gedcom.tags.GEDCOM_TAG_GIVEN_NAME and _SURNAME return those.
+        # Return the first tags.GEDCOM_TAG_NAME that is found.
+        # Alternatively as soon as we have both the tags.GEDCOM_TAG_GIVEN_NAME
+        # and _SURNAME return those.
         found_given_name = False
         found_surname_name = False
 
         for child in self.get_child_elements():
-            if child.get_tag() == gedcom.tags.GEDCOM_TAG_NAME:
+            if child.get_tag() == tags.GEDCOM_TAG_NAME:
                 # Some GEDCOM files don't use child tags but instead
                 # place the name in the value of the NAME tag.
                 if child.get_value() != "":
@@ -584,14 +740,14 @@ 

Classes

return given_name, surname - for childOfChild in child.get_child_elements(): + for gchild in child.get_child_elements(): - if childOfChild.get_tag() == gedcom.tags.GEDCOM_TAG_GIVEN_NAME: - given_name = childOfChild.get_value() + if gchild.get_tag() == tags.GEDCOM_TAG_GIVEN_NAME: + given_name = gchild.get_value() found_given_name = True - if childOfChild.get_tag() == gedcom.tags.GEDCOM_TAG_SURNAME: - surname = childOfChild.get_value() + if gchild.get_tag() == tags.GEDCOM_TAG_SURNAME: + surname = gchild.get_value() found_surname_name = True if found_given_name and found_surname_name: @@ -600,80 +756,74 @@

Classes

# If we reach here we are probably returning empty strings return given_name, surname - def get_all_names(self): - return [a.get_value() for a in self.get_child_elements() if a.get_tag() == gedcom.tags.GEDCOM_TAG_NAME] + def get_all_names(self) -> List[str]: + """Return all names.""" + return [a.get_value() for a in self.get_child_elements() + if a.get_tag() == tags.GEDCOM_TAG_NAME] - def surname_match(self, surname_to_match): - """Matches a string with the surname of an individual - :type surname_to_match: str - :rtype: bool + def surname_match(self, surname_to_match: str) -> bool: + """Matches a string with the surname of an individual. """ (given_name, surname) = self.get_name() return regex.search(surname_to_match, surname, regex.IGNORECASE) @deprecated - def given_match(self, name): - """Matches a string with the given name of an individual + def given_match(self, name: str) -> bool: + """Matches a string with the given name of an individual. ::deprecated:: As of version 1.0.0 use `given_name_match()` method instead - :type name: str - :rtype: bool """ return self.given_name_match(name) - def given_name_match(self, given_name_to_match): - """Matches a string with the given name of an individual - :type given_name_to_match: str - :rtype: bool + def given_name_match(self, given_name_to_match: str) -> bool: + """Matches a string with the given name of an individual. """ (given_name, surname) = self.get_name() return regex.search(given_name_to_match, given_name, regex.IGNORECASE) - def get_gender(self): - """Returns the gender of a person in string format - :rtype: str + def get_gender(self) -> str: + """Returns the gender of a person in string format. """ gender = "" for child in self.get_child_elements(): - if child.get_tag() == gedcom.tags.GEDCOM_TAG_SEX: + if child.get_tag() == tags.GEDCOM_TAG_SEX: gender = child.get_value() return gender - def get_birth_data(self): - """Returns the birth data of a person formatted as a tuple: (`str` date, `str` place, `list` sources) - :rtype: tuple + def get_birth_data(self) -> Tuple[str, str, List[str]]: + """Returns the birth data of a person formatted as a tuple: + (`str` date, `str` place, `list` sources) """ date = "" place = "" sources = [] for child in self.get_child_elements(): - if child.get_tag() == gedcom.tags.GEDCOM_TAG_BIRTH: - for childOfChild in child.get_child_elements(): + if child.get_tag() == tags.GEDCOM_TAG_BIRTH: + for gchild in child.get_child_elements(): - if childOfChild.get_tag() == gedcom.tags.GEDCOM_TAG_DATE: - date = childOfChild.get_value() + if gchild.get_tag() == tags.GEDCOM_TAG_DATE: + date = gchild.get_value() - if childOfChild.get_tag() == gedcom.tags.GEDCOM_TAG_PLACE: - place = childOfChild.get_value() + if gchild.get_tag() == tags.GEDCOM_TAG_PLACE: + place = gchild.get_value() - if childOfChild.get_tag() == gedcom.tags.GEDCOM_TAG_SOURCE: - sources.append(childOfChild.get_value()) + if gchild.get_tag() == tags.GEDCOM_TAG_SOURCE: + sources.append(gchild.get_value()) return date, place, sources - def get_birth_year(self): - """Returns the birth year of a person in integer format - :rtype: int + def get_birth_year(self) -> int: + """Returns the birth year of a person in integer format. """ date = "" for child in self.get_child_elements(): - if child.get_tag() == gedcom.tags.GEDCOM_TAG_BIRTH: - for childOfChild in child.get_child_elements(): - if childOfChild.get_tag() == gedcom.tags.GEDCOM_TAG_DATE: - date_split = childOfChild.get_value().split() + if child.get_tag() == tags.GEDCOM_TAG_BIRTH: + for gchild in child.get_child_elements(): + if gchild.get_tag() == tags.GEDCOM_TAG_DATE: + date_split = gchild.get_value().split() date = date_split[len(date_split) - 1] if date == "": @@ -683,37 +833,36 @@

Classes

except ValueError: return -1 - def get_death_data(self): - """Returns the death data of a person formatted as a tuple: (`str` date, `str` place, `list` sources) - :rtype: tuple + def get_death_data(self) -> Tuple[str, str, List[str]]: + """Returns the death data of a person formatted as a tuple: + (`str` date, `str` place, `list` sources) """ date = "" place = "" sources = [] for child in self.get_child_elements(): - if child.get_tag() == gedcom.tags.GEDCOM_TAG_DEATH: - for childOfChild in child.get_child_elements(): - if childOfChild.get_tag() == gedcom.tags.GEDCOM_TAG_DATE: - date = childOfChild.get_value() - if childOfChild.get_tag() == gedcom.tags.GEDCOM_TAG_PLACE: - place = childOfChild.get_value() - if childOfChild.get_tag() == gedcom.tags.GEDCOM_TAG_SOURCE: - sources.append(childOfChild.get_value()) + if child.get_tag() == tags.GEDCOM_TAG_DEATH: + for gchild in child.get_child_elements(): + if gchild.get_tag() == tags.GEDCOM_TAG_DATE: + date = gchild.get_value() + if gchild.get_tag() == tags.GEDCOM_TAG_PLACE: + place = gchild.get_value() + if gchild.get_tag() == tags.GEDCOM_TAG_SOURCE: + sources.append(gchild.get_value()) return date, place, sources - def get_death_year(self): - """Returns the death year of a person in integer format - :rtype: int + def get_death_year(self) -> int: + """Returns the death year of a person in integer format. """ date = "" for child in self.get_child_elements(): - if child.get_tag() == gedcom.tags.GEDCOM_TAG_DEATH: - for childOfChild in child.get_child_elements(): - if childOfChild.get_tag() == gedcom.tags.GEDCOM_TAG_DATE: - date_split = childOfChild.get_value().split() + if child.get_tag() == tags.GEDCOM_TAG_DEATH: + for gchild in child.get_child_elements(): + if gchild.get_tag() == tags.GEDCOM_TAG_DATE: + date_split = gchild.get_value().split() date = date_split[len(date_split) - 1] if date == "": @@ -724,110 +873,103 @@

Classes

return -1 @deprecated - def get_burial(self): - """Returns the burial data of a person formatted as a tuple: (`str` date, `str´ place, `list` sources) + def get_burial(self) -> Tuple[str, str, List[str]]: + """Returns the burial data of a person formatted as a tuple: + (`str` date, `str´ place, `list` sources) ::deprecated:: As of version 1.0.0 use `get_burial_data()` method instead - :rtype: tuple """ self.get_burial_data() - def get_burial_data(self): - """Returns the burial data of a person formatted as a tuple: (`str` date, `str´ place, `list` sources) - :rtype: tuple + def get_burial_data(self) -> Tuple[str, str, List[str]]: + """Returns the burial data of a person formatted as a tuple: + (`str` date, `str´ place, `list` sources) """ date = "" place = "" sources = [] for child in self.get_child_elements(): - if child.get_tag() == gedcom.tags.GEDCOM_TAG_BURIAL: - for childOfChild in child.get_child_elements(): + if child.get_tag() == tags.GEDCOM_TAG_BURIAL: + for gchild in child.get_child_elements(): - if childOfChild.get_tag() == gedcom.tags.GEDCOM_TAG_DATE: - date = childOfChild.get_value() + if gchild.get_tag() == tags.GEDCOM_TAG_DATE: + date = gchild.get_value() - if childOfChild.get_tag() == gedcom.tags.GEDCOM_TAG_PLACE: - place = childOfChild.get_value() + if gchild.get_tag() == tags.GEDCOM_TAG_PLACE: + place = gchild.get_value() - if childOfChild.get_tag() == gedcom.tags.GEDCOM_TAG_SOURCE: - sources.append(childOfChild.get_value()) + if gchild.get_tag() == tags.GEDCOM_TAG_SOURCE: + sources.append(gchild.get_value()) return date, place, sources @deprecated - def get_census(self): - """Returns a list of censuses of an individual formatted as tuples: (`str` date, `str´ place, `list` sources) + def get_census(self) -> List[Tuple[str, str, List[str]]]: + """Returns a list of censuses of an individual formatted as tuples: + (`str` date, `str´ place, `list` sources) ::deprecated:: As of version 1.0.0 use `get_census_data()` method instead - :rtype: list of tuple """ self.get_census_data() - def get_census_data(self): - """Returns a list of censuses of an individual formatted as tuples: (`str` date, `str´ place, `list` sources) - :rtype: list of tuple + def get_census_data(self) -> List[Tuple[str, str, List[str]]]: + """Returns a list of censuses of an individual formatted as tuples: + (`str` date, `str´ place, `list` sources) """ census = [] for child in self.get_child_elements(): - if child.get_tag() == gedcom.tags.GEDCOM_TAG_CENSUS: + if child.get_tag() == tags.GEDCOM_TAG_CENSUS: date = '' place = '' sources = [] - for childOfChild in child.get_child_elements(): + for gchild in child.get_child_elements(): - if childOfChild.get_tag() == gedcom.tags.GEDCOM_TAG_DATE: - date = childOfChild.get_value() + if gchild.get_tag() == tags.GEDCOM_TAG_DATE: + date = gchild.get_value() - if childOfChild.get_tag() == gedcom.tags.GEDCOM_TAG_PLACE: - place = childOfChild.get_value() + if gchild.get_tag() == tags.GEDCOM_TAG_PLACE: + place = gchild.get_value() - if childOfChild.get_tag() == gedcom.tags.GEDCOM_TAG_SOURCE: - sources.append(childOfChild.get_value()) + if gchild.get_tag() == tags.GEDCOM_TAG_SOURCE: + sources.append(gchild.get_value()) census.append((date, place, sources)) return census - def get_last_change_date(self): - """Returns the date of when the person data was last changed formatted as a string - :rtype: str + def get_last_change_date(self) -> str: + """Returns the date of when the person data was last changed formatted as a string. """ date = "" for child in self.get_child_elements(): - if child.get_tag() == gedcom.tags.GEDCOM_TAG_CHANGE: - for childOfChild in child.get_child_elements(): - if childOfChild.get_tag() == gedcom.tags.GEDCOM_TAG_DATE: - date = childOfChild.get_value() + if child.get_tag() == tags.GEDCOM_TAG_CHANGE: + for gchild in child.get_child_elements(): + if gchild.get_tag() == tags.GEDCOM_TAG_DATE: + date = gchild.get_value() return date - def get_occupation(self): - """Returns the occupation of a person - :rtype: str + def get_occupation(self) -> str: + """Returns the occupation of a person. """ occupation = "" for child in self.get_child_elements(): - if child.get_tag() == gedcom.tags.GEDCOM_TAG_OCCUPATION: + if child.get_tag() == tags.GEDCOM_TAG_OCCUPATION: occupation = child.get_value() return occupation - def birth_year_match(self, year): - """Returns `True` if the given year matches the birth year of this person - :type year: int - :rtype: bool + def birth_year_match(self, year: int) -> bool: + """Returns `True` if the given year matches the birth year of this person. """ return self.get_birth_year() == year - def birth_range_match(self, from_year, to_year): - """Checks if the birth year of a person lies within the given range - :type from_year: int - :type to_year: int - :rtype: bool + def birth_range_match(self, from_year: int, to_year: int) -> bool: + """Checks if the birth year of a person lies within the given range. """ birth_year = self.get_birth_year() @@ -836,18 +978,13 @@

Classes

return False - def death_year_match(self, year): - """Returns `True` if the given year matches the death year of this person - :type year: int - :rtype: bool + def death_year_match(self, year: int) -> bool: + """Returns `True` if the given year matches the death year of this person. """ return self.get_death_year() == year - def death_range_match(self, from_year, to_year): - """Checks if the death year of a person lies within the given range - :type from_year: int - :type to_year: int - :rtype: bool + def death_range_match(self, from_year: int, to_year: int) -> bool: + """Checks if the death year of a person lies within the given range. """ death_year = self.get_death_year() @@ -856,8 +993,8 @@

Classes

return False - def criteria_match(self, criteria): - """Checks if this individual matches all of the given criteria + def criteria_match(self, criteria: str) -> bool: + """Checks if this individual matches all of the given criteria. `criteria` is a colon-separated list, where each item in the list has the form [name]=[value]. The following criteria are supported: @@ -871,9 +1008,6 @@

Classes

birth_range=[from_year-to_year] Match a person whose birth year is in the range of years from [from_year] to [to_year], including both [from_year] and [to_year]. - - :type criteria: str - :rtype: bool """ # Check if criteria is a valid criteria and can be split by `:` and `=` characters @@ -941,22 +1075,16 @@

Ancestors

Methods

-def birth_range_match(self, from_year, to_year) +def birth_range_match(self, from_year: int, to_year: int) -> bool
-

Checks if the birth year of a person lies within the given range -:type from_year: int -:type to_year: int -:rtype: bool

+

Checks if the birth year of a person lies within the given range.

Expand source code -
def birth_range_match(self, from_year, to_year):
-    """Checks if the birth year of a person lies within the given range
-    :type from_year: int
-    :type to_year: int
-    :rtype: bool
+
def birth_range_match(self, from_year: int, to_year: int) -> bool:
+    """Checks if the birth year of a person lies within the given range.
     """
     birth_year = self.get_birth_year()
 
@@ -967,29 +1095,25 @@ 

Methods

-def birth_year_match(self, year) +def birth_year_match(self, year: int) -> bool
-

Returns True if the given year matches the birth year of this person -:type year: int -:rtype: bool

+

Returns True if the given year matches the birth year of this person.

Expand source code -
def birth_year_match(self, year):
-    """Returns `True` if the given year matches the birth year of this person
-    :type year: int
-    :rtype: bool
+
def birth_year_match(self, year: int) -> bool:
+    """Returns `True` if the given year matches the birth year of this person.
     """
     return self.get_birth_year() == year
-def criteria_match(self, criteria) +def criteria_match(self, criteria: str) -> bool
-

Checks if this individual matches all of the given criteria

+

Checks if this individual matches all of the given criteria.

criteria is a colon-separated list, where each item in the list has the form [name]=[value]. The following criteria are supported:

surname=[name] @@ -1000,15 +1124,13 @@

Methods

Match a person whose birth year is a four-digit [year]. birth_range=[from_year-to_year] Match a person whose birth year is in the range of years from -[from_year] to [to_year], including both [from_year] and [to_year].

-

:type criteria: str -:rtype: bool

+[from_year] to [to_year], including both [from_year] and [to_year].

Expand source code -
def criteria_match(self, criteria):
-    """Checks if this individual matches all of the given criteria
+
def criteria_match(self, criteria: str) -> bool:
+    """Checks if this individual matches all of the given criteria.
 
     `criteria` is a colon-separated list, where each item in the
     list has the form [name]=[value]. The following criteria are supported:
@@ -1022,9 +1144,6 @@ 

Methods

birth_range=[from_year-to_year] Match a person whose birth year is in the range of years from [from_year] to [to_year], including both [from_year] and [to_year]. - - :type criteria: str - :rtype: bool """ # Check if criteria is a valid criteria and can be split by `:` and `=` characters @@ -1087,22 +1206,16 @@

Methods

-def death_range_match(self, from_year, to_year) +def death_range_match(self, from_year: int, to_year: int) -> bool
-

Checks if the death year of a person lies within the given range -:type from_year: int -:type to_year: int -:rtype: bool

+

Checks if the death year of a person lies within the given range.

Expand source code -
def death_range_match(self, from_year, to_year):
-    """Checks if the death year of a person lies within the given range
-    :type from_year: int
-    :type to_year: int
-    :rtype: bool
+
def death_range_match(self, from_year: int, to_year: int) -> bool:
+    """Checks if the death year of a person lies within the given range.
     """
     death_year = self.get_death_year()
 
@@ -1113,92 +1226,88 @@ 

Methods

-def death_year_match(self, year) +def death_year_match(self, year: int) -> bool
-

Returns True if the given year matches the death year of this person -:type year: int -:rtype: bool

+

Returns True if the given year matches the death year of this person.

Expand source code -
def death_year_match(self, year):
-    """Returns `True` if the given year matches the death year of this person
-    :type year: int
-    :rtype: bool
+
def death_year_match(self, year: int) -> bool:
+    """Returns `True` if the given year matches the death year of this person.
     """
     return self.get_death_year() == year
-def get_all_names(self) +def get_all_names(self) -> List[str]
-
+

Return all names.

Expand source code -
def get_all_names(self):
-    return [a.get_value() for a in self.get_child_elements() if a.get_tag() == gedcom.tags.GEDCOM_TAG_NAME]
+
def get_all_names(self) -> List[str]:
+    """Return all names."""
+    return [a.get_value() for a in self.get_child_elements()
+            if a.get_tag() == tags.GEDCOM_TAG_NAME]
-def get_birth_data(self) +def get_birth_data(self) -> Tuple[str, str, List[str]]
-

Returns the birth data of a person formatted as a tuple: (str date, str place, list sources) -:rtype: tuple

+

Returns the birth data of a person formatted as a tuple: +(str date, str place, list sources)

Expand source code -
def get_birth_data(self):
-    """Returns the birth data of a person formatted as a tuple: (`str` date, `str` place, `list` sources)
-    :rtype: tuple
+
def get_birth_data(self) -> Tuple[str, str, List[str]]:
+    """Returns the birth data of a person formatted as a tuple:
+    (`str` date, `str` place, `list` sources)
     """
     date = ""
     place = ""
     sources = []
 
     for child in self.get_child_elements():
-        if child.get_tag() == gedcom.tags.GEDCOM_TAG_BIRTH:
-            for childOfChild in child.get_child_elements():
+        if child.get_tag() == tags.GEDCOM_TAG_BIRTH:
+            for gchild in child.get_child_elements():
 
-                if childOfChild.get_tag() == gedcom.tags.GEDCOM_TAG_DATE:
-                    date = childOfChild.get_value()
+                if gchild.get_tag() == tags.GEDCOM_TAG_DATE:
+                    date = gchild.get_value()
 
-                if childOfChild.get_tag() == gedcom.tags.GEDCOM_TAG_PLACE:
-                    place = childOfChild.get_value()
+                if gchild.get_tag() == tags.GEDCOM_TAG_PLACE:
+                    place = gchild.get_value()
 
-                if childOfChild.get_tag() == gedcom.tags.GEDCOM_TAG_SOURCE:
-                    sources.append(childOfChild.get_value())
+                if gchild.get_tag() == tags.GEDCOM_TAG_SOURCE:
+                    sources.append(gchild.get_value())
 
     return date, place, sources
-def get_birth_year(self) +def get_birth_year(self) -> int
-

Returns the birth year of a person in integer format -:rtype: int

+

Returns the birth year of a person in integer format.

Expand source code -
def get_birth_year(self):
-    """Returns the birth year of a person in integer format
-    :rtype: int
+
def get_birth_year(self) -> int:
+    """Returns the birth year of a person in integer format.
     """
     date = ""
 
     for child in self.get_child_elements():
-        if child.get_tag() == gedcom.tags.GEDCOM_TAG_BIRTH:
-            for childOfChild in child.get_child_elements():
-                if childOfChild.get_tag() == gedcom.tags.GEDCOM_TAG_DATE:
-                    date_split = childOfChild.get_value().split()
+        if child.get_tag() == tags.GEDCOM_TAG_BIRTH:
+            for gchild in child.get_child_elements():
+                if gchild.get_tag() == tags.GEDCOM_TAG_DATE:
+                    date_split = gchild.get_value().split()
                     date = date_split[len(date_split) - 1]
 
     if date == "":
@@ -1210,112 +1319,112 @@ 

Methods

-def get_burial(self) +def get_burial(self) -> Tuple[str, str, List[str]]
-

Returns the burial data of a person formatted as a tuple: (str date, str´ place,listsources) -::deprecated:: As of version 1.0.0 useget_burial_data()` method instead -:rtype: tuple

+

Returns the burial data of a person formatted as a tuple: +(str date, str´ place,list` sources) +::deprecated:: As of version 1.0.0 use get_burial_data() method instead

Expand source code
@deprecated
-def get_burial(self):
-    """Returns the burial data of a person formatted as a tuple: (`str` date, `str´ place, `list` sources)
+def get_burial(self) -> Tuple[str, str, List[str]]:
+    """Returns the burial data of a person formatted as a tuple:
+    (`str` date, `str´ place, `list` sources)
     ::deprecated:: As of version 1.0.0 use `get_burial_data()` method instead
-    :rtype: tuple
     """
     self.get_burial_data()
-def get_burial_data(self) +def get_burial_data(self) -> Tuple[str, str, List[str]]
-

Returns the burial data of a person formatted as a tuple: (str date, str´ place,list` sources) -:rtype: tuple

+

Returns the burial data of a person formatted as a tuple: +(str date, str´ place,list` sources)

Expand source code -
def get_burial_data(self):
-    """Returns the burial data of a person formatted as a tuple: (`str` date, `str´ place, `list` sources)
-    :rtype: tuple
+
def get_burial_data(self) -> Tuple[str, str, List[str]]:
+    """Returns the burial data of a person formatted as a tuple:
+    (`str` date, `str´ place, `list` sources)
     """
     date = ""
     place = ""
     sources = []
 
     for child in self.get_child_elements():
-        if child.get_tag() == gedcom.tags.GEDCOM_TAG_BURIAL:
-            for childOfChild in child.get_child_elements():
+        if child.get_tag() == tags.GEDCOM_TAG_BURIAL:
+            for gchild in child.get_child_elements():
 
-                if childOfChild.get_tag() == gedcom.tags.GEDCOM_TAG_DATE:
-                    date = childOfChild.get_value()
+                if gchild.get_tag() == tags.GEDCOM_TAG_DATE:
+                    date = gchild.get_value()
 
-                if childOfChild.get_tag() == gedcom.tags.GEDCOM_TAG_PLACE:
-                    place = childOfChild.get_value()
+                if gchild.get_tag() == tags.GEDCOM_TAG_PLACE:
+                    place = gchild.get_value()
 
-                if childOfChild.get_tag() == gedcom.tags.GEDCOM_TAG_SOURCE:
-                    sources.append(childOfChild.get_value())
+                if gchild.get_tag() == tags.GEDCOM_TAG_SOURCE:
+                    sources.append(gchild.get_value())
 
     return date, place, sources
-def get_census(self) +def get_census(self) -> List[Tuple[str, str, List[str]]]
-

Returns a list of censuses of an individual formatted as tuples: (str date, str´ place,listsources) -::deprecated:: As of version 1.0.0 useget_census_data()` method instead -:rtype: list of tuple

+

Returns a list of censuses of an individual formatted as tuples: +(str date, str´ place,list` sources) +::deprecated:: As of version 1.0.0 use get_census_data() method instead

Expand source code
@deprecated
-def get_census(self):
-    """Returns a list of censuses of an individual formatted as tuples: (`str` date, `str´ place, `list` sources)
+def get_census(self) -> List[Tuple[str, str, List[str]]]:
+    """Returns a list of censuses of an individual formatted as tuples:
+    (`str` date, `str´ place, `list` sources)
     ::deprecated:: As of version 1.0.0 use `get_census_data()` method instead
-    :rtype: list of tuple
     """
     self.get_census_data()
-def get_census_data(self) +def get_census_data(self) -> List[Tuple[str, str, List[str]]]
-

Returns a list of censuses of an individual formatted as tuples: (str date, str´ place,list` sources) -:rtype: list of tuple

+

Returns a list of censuses of an individual formatted as tuples: +(str date, str´ place,list` sources)

Expand source code -
def get_census_data(self):
-    """Returns a list of censuses of an individual formatted as tuples: (`str` date, `str´ place, `list` sources)
-    :rtype: list of tuple
+
def get_census_data(self) -> List[Tuple[str, str, List[str]]]:
+    """Returns a list of censuses of an individual formatted as tuples:
+    (`str` date, `str´ place, `list` sources)
     """
     census = []
 
     for child in self.get_child_elements():
-        if child.get_tag() == gedcom.tags.GEDCOM_TAG_CENSUS:
+        if child.get_tag() == tags.GEDCOM_TAG_CENSUS:
 
             date = ''
             place = ''
             sources = []
 
-            for childOfChild in child.get_child_elements():
+            for gchild in child.get_child_elements():
 
-                if childOfChild.get_tag() == gedcom.tags.GEDCOM_TAG_DATE:
-                    date = childOfChild.get_value()
+                if gchild.get_tag() == tags.GEDCOM_TAG_DATE:
+                    date = gchild.get_value()
 
-                if childOfChild.get_tag() == gedcom.tags.GEDCOM_TAG_PLACE:
-                    place = childOfChild.get_value()
+                if gchild.get_tag() == tags.GEDCOM_TAG_PLACE:
+                    place = gchild.get_value()
 
-                if childOfChild.get_tag() == gedcom.tags.GEDCOM_TAG_SOURCE:
-                    sources.append(childOfChild.get_value())
+                if gchild.get_tag() == tags.GEDCOM_TAG_SOURCE:
+                    sources.append(gchild.get_value())
 
             census.append((date, place, sources))
 
@@ -1323,57 +1432,55 @@ 

Methods

-def get_death_data(self) +def get_death_data(self) -> Tuple[str, str, List[str]]
-

Returns the death data of a person formatted as a tuple: (str date, str place, list sources) -:rtype: tuple

+

Returns the death data of a person formatted as a tuple: +(str date, str place, list sources)

Expand source code -
def get_death_data(self):
-    """Returns the death data of a person formatted as a tuple: (`str` date, `str` place, `list` sources)
-    :rtype: tuple
+
def get_death_data(self) -> Tuple[str, str, List[str]]:
+    """Returns the death data of a person formatted as a tuple:
+    (`str` date, `str` place, `list` sources)
     """
     date = ""
     place = ""
     sources = []
 
     for child in self.get_child_elements():
-        if child.get_tag() == gedcom.tags.GEDCOM_TAG_DEATH:
-            for childOfChild in child.get_child_elements():
-                if childOfChild.get_tag() == gedcom.tags.GEDCOM_TAG_DATE:
-                    date = childOfChild.get_value()
-                if childOfChild.get_tag() == gedcom.tags.GEDCOM_TAG_PLACE:
-                    place = childOfChild.get_value()
-                if childOfChild.get_tag() == gedcom.tags.GEDCOM_TAG_SOURCE:
-                    sources.append(childOfChild.get_value())
+        if child.get_tag() == tags.GEDCOM_TAG_DEATH:
+            for gchild in child.get_child_elements():
+                if gchild.get_tag() == tags.GEDCOM_TAG_DATE:
+                    date = gchild.get_value()
+                if gchild.get_tag() == tags.GEDCOM_TAG_PLACE:
+                    place = gchild.get_value()
+                if gchild.get_tag() == tags.GEDCOM_TAG_SOURCE:
+                    sources.append(gchild.get_value())
 
     return date, place, sources
-def get_death_year(self) +def get_death_year(self) -> int
-

Returns the death year of a person in integer format -:rtype: int

+

Returns the death year of a person in integer format.

Expand source code -
def get_death_year(self):
-    """Returns the death year of a person in integer format
-    :rtype: int
+
def get_death_year(self) -> int:
+    """Returns the death year of a person in integer format.
     """
     date = ""
 
     for child in self.get_child_elements():
-        if child.get_tag() == gedcom.tags.GEDCOM_TAG_DEATH:
-            for childOfChild in child.get_child_elements():
-                if childOfChild.get_tag() == gedcom.tags.GEDCOM_TAG_DATE:
-                    date_split = childOfChild.get_value().split()
+        if child.get_tag() == tags.GEDCOM_TAG_DEATH:
+            for gchild in child.get_child_elements():
+                if gchild.get_tag() == tags.GEDCOM_TAG_DATE:
+                    date_split = gchild.get_value().split()
                     date = date_split[len(date_split) - 1]
 
     if date == "":
@@ -1385,77 +1492,72 @@ 

Methods

-def get_gender(self) +def get_gender(self) -> str
-

Returns the gender of a person in string format -:rtype: str

+

Returns the gender of a person in string format.

Expand source code -
def get_gender(self):
-    """Returns the gender of a person in string format
-    :rtype: str
+
def get_gender(self) -> str:
+    """Returns the gender of a person in string format.
     """
     gender = ""
 
     for child in self.get_child_elements():
-        if child.get_tag() == gedcom.tags.GEDCOM_TAG_SEX:
+        if child.get_tag() == tags.GEDCOM_TAG_SEX:
             gender = child.get_value()
 
     return gender
-def get_last_change_date(self) +def get_last_change_date(self) -> str
-

Returns the date of when the person data was last changed formatted as a string -:rtype: str

+

Returns the date of when the person data was last changed formatted as a string.

Expand source code -
def get_last_change_date(self):
-    """Returns the date of when the person data was last changed formatted as a string
-    :rtype: str
+
def get_last_change_date(self) -> str:
+    """Returns the date of when the person data was last changed formatted as a string.
     """
     date = ""
 
     for child in self.get_child_elements():
-        if child.get_tag() == gedcom.tags.GEDCOM_TAG_CHANGE:
-            for childOfChild in child.get_child_elements():
-                if childOfChild.get_tag() == gedcom.tags.GEDCOM_TAG_DATE:
-                    date = childOfChild.get_value()
+        if child.get_tag() == tags.GEDCOM_TAG_CHANGE:
+            for gchild in child.get_child_elements():
+                if gchild.get_tag() == tags.GEDCOM_TAG_DATE:
+                    date = gchild.get_value()
 
     return date
-def get_name(self) +def get_name(self) -> Tuple[str, str]
-

Returns an individual's names as a tuple: (str given_name, str surname) -:rtype: tuple

+

Returns an individual's names as a tuple: (str given_name, str surname)

Expand source code -
def get_name(self):
+
def get_name(self) -> Tuple[str, str]:
     """Returns an individual's names as a tuple: (`str` given_name, `str` surname)
-    :rtype: tuple
     """
     given_name = ""
     surname = ""
 
-    # Return the first gedcom.tags.GEDCOM_TAG_NAME that is found.
-    # Alternatively as soon as we have both the gedcom.tags.GEDCOM_TAG_GIVEN_NAME and _SURNAME return those.
+    # Return the first tags.GEDCOM_TAG_NAME that is found.
+    # Alternatively as soon as we have both the tags.GEDCOM_TAG_GIVEN_NAME
+    # and _SURNAME return those.
     found_given_name = False
     found_surname_name = False
 
     for child in self.get_child_elements():
-        if child.get_tag() == gedcom.tags.GEDCOM_TAG_NAME:
+        if child.get_tag() == tags.GEDCOM_TAG_NAME:
             # Some GEDCOM files don't use child tags but instead
             # place the name in the value of the NAME tag.
             if child.get_value() != "":
@@ -1468,14 +1570,14 @@ 

Methods

return given_name, surname - for childOfChild in child.get_child_elements(): + for gchild in child.get_child_elements(): - if childOfChild.get_tag() == gedcom.tags.GEDCOM_TAG_GIVEN_NAME: - given_name = childOfChild.get_value() + if gchild.get_tag() == tags.GEDCOM_TAG_GIVEN_NAME: + given_name = gchild.get_value() found_given_name = True - if childOfChild.get_tag() == gedcom.tags.GEDCOM_TAG_SURNAME: - surname = childOfChild.get_value() + if gchild.get_tag() == tags.GEDCOM_TAG_SURNAME: + surname = gchild.get_value() found_surname_name = True if found_given_name and found_surname_name: @@ -1486,130 +1588,213 @@

Methods

-def get_occupation(self) +def get_occupation(self) -> str
-

Returns the occupation of a person -:rtype: str

+

Returns the occupation of a person.

Expand source code -
def get_occupation(self):
-    """Returns the occupation of a person
-    :rtype: str
+
def get_occupation(self) -> str:
+    """Returns the occupation of a person.
     """
     occupation = ""
 
     for child in self.get_child_elements():
-        if child.get_tag() == gedcom.tags.GEDCOM_TAG_OCCUPATION:
+        if child.get_tag() == tags.GEDCOM_TAG_OCCUPATION:
             occupation = child.get_value()
 
     return occupation
+
+def get_record(self) -> dict +
+
+

Parse and return the full record in dictionary format.

+
+ +Expand source code + +
def get_record(self) -> dict:
+    """Parse and return the full record in dictionary format.
+    """
+    record = {
+        'key_to_individual': self.get_pointer(),
+        'restriction': '',
+        'names': [],
+        'sex': 'U',
+        'events': individual_event_structure(self),
+        'attributes': individual_attribute_structure(self),
+        'child_to_family': [],
+        'spouse_to_family': [],
+        'submitters': [],
+        'associates': [],
+        'aliases': [],
+        'ancestors_interest': [],
+        'descendants_interest': [],
+        'permanent_file_number': '',
+        'ancestral_file_number': '',
+        'references': [],
+        'record_id': '',
+        'change_date': {},
+        'notes': [],
+        'citations': [],
+        'media': []
+    }
+    lds_events = lds_individual_ordinance(self)
+    if len(lds_events) > 0:
+        for event in lds_events:
+            record['events'].append(event)
+
+    for child in self.get_child_elements():
+        if child.get_tag() in INDIVIDUAL_SINGLE_TAGS:
+            record[INDIVIDUAL_SINGLE_TAGS[child.get_tag()]] = child.get_value()
+            continue
+
+        if child.get_tag() == tags.GEDCOM_TAG_NAME:
+            record['names'].append(personal_name_structure(child))
+            continue
+
+        if child.get_tag() == tags.GEDCOM_TAG_FAMILY_CHILD:
+            record['child_to_family'].append(child_to_family_link(child))
+            continue
+
+        if child.get_tag() == tags.GEDCOM_TAG_FAMILY_SPOUSE:
+            record['spouse_to_family'].append(spouse_to_family_link(child))
+            continue
+
+        if child.get_tag() == tags.GEDCOM_TAG_NOTE:
+            record['notes'].append(note_structure(child))
+            continue
+
+        if child.get_tag() == tags.GEDCOM_TAG_SOURCE:
+            record['citations'].append(source_citation(child))
+            continue
+
+        if child.get_tag() == tags.GEDCOM_TAG_MEDIA:
+            record['media'].append(multimedia_link(child))
+            continue
+
+        if child.get_tag() == tags.GEDCOM_TAG_SUBMITTER:
+            record['submitters'].append(child.get_value())
+            continue
+
+        if child.get_tag() == tags.GEDCOM_TAG_ASSOCIATES:
+            record['associates'].append(association_structure(child))
+            continue
+
+        if child.get_tag() == tags.GEDCOM_TAG_ALIAS:
+            record['aliases'].append(child.get_value())
+            continue
+
+        if child.get_tag() == tags.GEDCOM_TAG_ANCES_INTEREST:
+            record['ancestors_interest'].append(child.get_value())
+            continue
+
+        if child.get_tag() == tags.GEDCOM_TAG_DESCENDANTS_INT:
+            record['descendants_interest'].append(child.get_value())
+            continue
+
+        if child.get_tag() == tags.GEDCOM_TAG_REFERENCE:
+            record['references'].append(user_reference_number(child))
+            continue
+
+        if child.get_tag() == tags.GEDCOM_TAG_CHANGE:
+            record['changed'] = change_date(child)
+
+    return record
+
+
-def given_match(self, name) +def given_match(self, name: str) -> bool
-

Matches a string with the given name of an individual -::deprecated:: As of version 1.0.0 use given_name_match() method instead -:type name: str -:rtype: bool

+

Matches a string with the given name of an individual. +::deprecated:: As of version 1.0.0 use given_name_match() method instead

Expand source code
@deprecated
-def given_match(self, name):
-    """Matches a string with the given name of an individual
+def given_match(self, name: str) -> bool:
+    """Matches a string with the given name of an individual.
     ::deprecated:: As of version 1.0.0 use `given_name_match()` method instead
-    :type name: str
-    :rtype: bool
     """
     return self.given_name_match(name)
-def given_name_match(self, given_name_to_match) +def given_name_match(self, given_name_to_match: str) -> bool
-

Matches a string with the given name of an individual -:type given_name_to_match: str -:rtype: bool

+

Matches a string with the given name of an individual.

Expand source code -
def given_name_match(self, given_name_to_match):
-    """Matches a string with the given name of an individual
-    :type given_name_to_match: str
-    :rtype: bool
+
def given_name_match(self, given_name_to_match: str) -> bool:
+    """Matches a string with the given name of an individual.
     """
     (given_name, surname) = self.get_name()
     return regex.search(given_name_to_match, given_name, regex.IGNORECASE)
-def is_child(self) +def is_child(self) -> bool
-

Checks if this element is a child of a family -:rtype: bool

+

Checks if this element is a child of a family.

Expand source code -
def is_child(self):
-    """Checks if this element is a child of a family
-    :rtype: bool
+
def is_child(self) -> bool:
+    """Checks if this element is a child of a family.
     """
     found_child = False
 
     for child in self.get_child_elements():
-        if child.get_tag() == gedcom.tags.GEDCOM_TAG_FAMILY_CHILD:
+        if child.get_tag() == tags.GEDCOM_TAG_FAMILY_CHILD:
             found_child = True
 
     return found_child
-def is_deceased(self) +def is_deceased(self) -> bool
-

Checks if this individual is deceased -:rtype: bool

+

Checks if this individual is deceased.

Expand source code -
def is_deceased(self):
-    """Checks if this individual is deceased
-    :rtype: bool
+
def is_deceased(self) -> bool:
+    """Checks if this individual is deceased.
     """
     for child in self.get_child_elements():
-        if child.get_tag() == gedcom.tags.GEDCOM_TAG_DEATH:
+        if child.get_tag() == tags.GEDCOM_TAG_DEATH:
             return True
 
     return False
-def is_private(self) +def is_private(self) -> bool
-

Checks if this individual is marked private -:rtype: bool

+

Checks if this individual is marked private.

Expand source code -
def is_private(self):
-    """Checks if this individual is marked private
-    :rtype: bool
+
def is_private(self) -> bool:
+    """Checks if this individual is marked private.
     """
     for child in self.get_child_elements():
-        if child.get_tag() == gedcom.tags.GEDCOM_TAG_PRIVATE:
+        if child.get_tag() == tags.GEDCOM_TAG_PRIVATE:
             private = child.get_value()
             if private == 'Y':
                 return True
@@ -1618,20 +1803,16 @@ 

Methods

-def surname_match(self, surname_to_match) +def surname_match(self, surname_to_match: str) -> bool
-

Matches a string with the surname of an individual -:type surname_to_match: str -:rtype: bool

+

Matches a string with the surname of an individual.

Expand source code -
def surname_match(self, surname_to_match):
-    """Matches a string with the surname of an individual
-    :type surname_to_match: str
-    :rtype: bool
+
def surname_match(self, surname_to_match: str) -> bool:
+    """Matches a string with the surname of an individual.
     """
     (given_name, surname) = self.get_name()
     return regex.search(surname_to_match, surname, regex.IGNORECASE)
@@ -1660,25 +1841,6 @@

Inherited members

-
-class NotAnActualIndividualError -(...) -
-
-

Common base class for all non-exit exceptions.

-
- -Expand source code - -
class NotAnActualIndividualError(Exception):
-    pass
-
-

Ancestors

-
    -
  • builtins.Exception
  • -
  • builtins.BaseException
  • -
-
@@ -1716,6 +1878,7 @@

get_last_change_date
  • get_name
  • get_occupation
  • +
  • get_record
  • given_match
  • given_name_match
  • is_child
  • @@ -1724,16 +1887,13 @@

    surname_match -
  • -

    NotAnActualIndividualError

    -
  • diff --git a/docs/gedcom/element/note.html b/docs/gedcom/element/note.html new file mode 100644 index 0000000..10c75a7 --- /dev/null +++ b/docs/gedcom/element/note.html @@ -0,0 +1,261 @@ + + + + + + +gedcom.element.note API documentation + + + + + + + + + +
    +
    +
    +

    Module gedcom.element.note

    +
    +
    +

    GEDCOM element for a NOTE_RECORD note record identified by the +GEDCOM_TAG_NOTE tag.

    +
    + +Expand source code + +
    # -*- coding: utf-8 -*-
    +
    +# Python GEDCOM Parser
    +#
    +# Copyright (C) 2020 Christopher Horn (cdhorn at embarqmail dot com)
    +# Copyright (C) 2018 Damon Brodie (damon.brodie at gmail.com)
    +# Copyright (C) 2018-2019 Nicklas Reincke (contact at reynke.com)
    +# Copyright (C) 2016 Andreas Oberritter
    +# Copyright (C) 2012 Madeleine Price Ball
    +# Copyright (C) 2005 Daniel Zappala (zappala at cs.byu.edu)
    +# Copyright (C) 2005 Brigham Young University
    +#
    +# 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.
    +#
    +# Further information about the license: http://www.gnu.org/licenses/gpl-2.0.html
    +
    +"""
    +GEDCOM element for a `NOTE_RECORD` note record identified by the
    +`gedcom.tags.GEDCOM_TAG_NOTE` tag.
    +"""
    +
    +import gedcom.tags as tags
    +from gedcom.element.element import Element
    +from gedcom.subparsers.source_citation import source_citation
    +from gedcom.subparsers.change_date import change_date
    +from gedcom.subparsers.user_reference_number import user_reference_number
    +
    +
    +class NoteElement(Element):
    +    """Element associated with a `NOTE_RECORD`"""
    +
    +    def get_tag(self) -> str:
    +        return tags.GEDCOM_TAG_NOTE
    +
    +    def get_record(self) -> dict:
    +        """Parse and return the full record in dictionary format.
    +        """
    +        record = {
    +            'key_to_note': self.get_pointer(),
    +            'note': self.get_multi_line_value(),
    +            'references': [],
    +            'record_id': '',
    +            'citations': [],
    +            'change_date': {}
    +        }
    +        for child in self.get_child_elements():
    +            if child.get_tag() == tags.GEDCOM_TAG_REFERENCE:
    +                record['references'].append(user_reference_number(child))
    +                continue
    +
    +            if child.get_tag() == tags.GEDCOM_TAG_REC_ID_NUMBER:
    +                record['record_id'] = child.get_value()
    +                continue
    +
    +            if child.get_tag() == tags.GEDCOM_TAG_SOURCE:
    +                record['citations'].append(source_citation(child))
    +                continue
    +
    +            if child.get_tag() == tags.GEDCOM_TAG_CHANGE:
    +                record['change_date'] = change_date(child)
    +
    +        return record
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +

    Classes

    +
    +
    +class NoteElement +(level: int, pointer: str, tag: str, value: str, crlf: str = '\n', multi_line: bool = True) +
    +
    +

    Element associated with a NOTE_RECORD

    +
    + +Expand source code + +
    class NoteElement(Element):
    +    """Element associated with a `NOTE_RECORD`"""
    +
    +    def get_tag(self) -> str:
    +        return tags.GEDCOM_TAG_NOTE
    +
    +    def get_record(self) -> dict:
    +        """Parse and return the full record in dictionary format.
    +        """
    +        record = {
    +            'key_to_note': self.get_pointer(),
    +            'note': self.get_multi_line_value(),
    +            'references': [],
    +            'record_id': '',
    +            'citations': [],
    +            'change_date': {}
    +        }
    +        for child in self.get_child_elements():
    +            if child.get_tag() == tags.GEDCOM_TAG_REFERENCE:
    +                record['references'].append(user_reference_number(child))
    +                continue
    +
    +            if child.get_tag() == tags.GEDCOM_TAG_REC_ID_NUMBER:
    +                record['record_id'] = child.get_value()
    +                continue
    +
    +            if child.get_tag() == tags.GEDCOM_TAG_SOURCE:
    +                record['citations'].append(source_citation(child))
    +                continue
    +
    +            if child.get_tag() == tags.GEDCOM_TAG_CHANGE:
    +                record['change_date'] = change_date(child)
    +
    +        return record
    +
    +

    Ancestors

    + +

    Methods

    +
    +
    +def get_record(self) -> dict +
    +
    +

    Parse and return the full record in dictionary format.

    +
    + +Expand source code + +
    def get_record(self) -> dict:
    +    """Parse and return the full record in dictionary format.
    +    """
    +    record = {
    +        'key_to_note': self.get_pointer(),
    +        'note': self.get_multi_line_value(),
    +        'references': [],
    +        'record_id': '',
    +        'citations': [],
    +        'change_date': {}
    +    }
    +    for child in self.get_child_elements():
    +        if child.get_tag() == tags.GEDCOM_TAG_REFERENCE:
    +            record['references'].append(user_reference_number(child))
    +            continue
    +
    +        if child.get_tag() == tags.GEDCOM_TAG_REC_ID_NUMBER:
    +            record['record_id'] = child.get_value()
    +            continue
    +
    +        if child.get_tag() == tags.GEDCOM_TAG_SOURCE:
    +            record['citations'].append(source_citation(child))
    +            continue
    +
    +        if child.get_tag() == tags.GEDCOM_TAG_CHANGE:
    +            record['change_date'] = change_date(child)
    +
    +    return record
    +
    +
    +
    +

    Inherited members

    + +
    +
    +
    +
    + +
    + + + + + \ No newline at end of file diff --git a/docs/gedcom/element/object.html b/docs/gedcom/element/object.html index 6897dfc..9f89ec5 100644 --- a/docs/gedcom/element/object.html +++ b/docs/gedcom/element/object.html @@ -3,14 +3,15 @@ - + gedcom.element.object API documentation - + - - + + @@ -20,7 +21,8 @@

    Module gedcom.element.object

    -

    GEDCOM element consisting of tag GEDCOM_TAG_OBJECT

    +

    GEDCOM element for a MULTIMEDIA_RECORD media record identified by the +GEDCOM_TAG_OBJECT tag.

    Expand source code @@ -29,6 +31,7 @@

    Module gedcom.element.object

    # Python GEDCOM Parser # +# Copyright (C) 2020 Christopher Horn (cdhorn at embarqmail dot com) # Copyright (C) 2018 Damon Brodie (damon.brodie at gmail.com) # Copyright (C) 2018-2019 Nicklas Reincke (contact at reynke.com) # Copyright (C) 2016 Andreas Oberritter @@ -52,23 +55,86 @@

    Module gedcom.element.object

    # # Further information about the license: http://www.gnu.org/licenses/gpl-2.0.html -"""GEDCOM element consisting of tag `gedcom.tags.GEDCOM_TAG_OBJECT`""" +""" +GEDCOM element for a `MULTIMEDIA_RECORD` media record identified by the +`gedcom.tags.GEDCOM_TAG_OBJECT` tag. +""" +import gedcom.tags as tags from gedcom.element.element import Element -import gedcom.tags - - -class NotAnActualObjectError(Exception): - pass +from gedcom.subparsers.note_structure import note_structure +from gedcom.subparsers.source_citation import source_citation +from gedcom.subparsers.change_date import change_date +from gedcom.subparsers.user_reference_number import user_reference_number class ObjectElement(Element): + """Element associated with a `MULTIMEDIA_RECORD`""" - def is_object(self): - """Checks if this element is an actual object - :rtype: bool + def get_tag(self) -> str: + return tags.GEDCOM_TAG_OBJECT + + def get_record(self) -> dict: + """Parse and return the full record in dictionary format. """ - return self.get_tag() == gedcom.tags.GEDCOM_TAG_OBJECT
    + record = { + 'key_to_object': self.get_pointer(), + 'file': '', + 'format': '', + 'type': '', + 'title': '', + 'references': [], + 'record_id': '', + 'citations': [], + 'notes': [], + 'change_date': {} + } + for child in self.get_child_elements(): + if child.get_tag() == tags.GEDCOM_TAG_FILE: + record['file'] = child.get_value() + + for gchild in child.get_child_elements(): + if gchild.get_tag() == tags.GEDCOM_TAG_FORMAT: + record['format'] = gchild.get_value() + + for ggchild in gchild.get_child_elements(): + if ggchild.get_tag() == tags.GEDCOM_TAG_TYPE: + record['type'] = ggchild.get_value() + continue + + if gchild.get_tag() == tags.GEDCOM_TAG_TITLE: + record['title'] = gchild.get_value() + continue + continue + + if child.get_tag() == tags.GEDCOM_TAG_FORMAT: + record['format'] = child.get_value() + continue + + if child.get_tag() == tags.GEDCOM_TAG_TYPE: + record['type'] = child.get_value() + continue + + if child.get_tag() == tags.GEDCOM_TAG_NOTE: + record['notes'].append(note_structure(child)) + continue + + if child.get_tag() == tags.GEDCOM_TAG_SOURCE: + record['citations'].append(source_citation(child)) + continue + + if child.get_tag() == tags.GEDCOM_TAG_REFERENCE: + record['references'].append(user_reference_number(child)) + continue + + if child.get_tag() == tags.GEDCOM_TAG_REC_ID_NUMBER: + record['record_id'] = child.get_value() + continue + + if child.get_tag() == tags.GEDCOM_TAG_CHANGE: + record['change_date'] = change_date(child) + + return record
    @@ -80,62 +146,83 @@

    Module gedcom.element.object

    Classes

    -
    -class NotAnActualObjectError -(...) -
    -
    -

    Common base class for all non-exit exceptions.

    -
    - -Expand source code - -
    class NotAnActualObjectError(Exception):
    -    pass
    -
    -

    Ancestors

    -
      -
    • builtins.Exception
    • -
    • builtins.BaseException
    • -
    -
    class ObjectElement -(level, pointer, tag, value, crlf='\n', multi_line=True) +(level: int, pointer: str, tag: str, value: str, crlf: str = '\n', multi_line: bool = True)
    -

    GEDCOM element

    -

    Each line in a GEDCOM file is an element with the format

    -

    level [pointer] tag [value]

    -

    where level and tag are required, and pointer and value are -optional. -Elements are arranged hierarchically according to their -level, and elements with a level of zero are at the top level. -Elements with a level greater than zero are children of their -parent.

    -

    A pointer has the format @pname@, where pname is any sequence of -characters and numbers. The pointer identifies the object being -pointed to, so that any pointer included as the value of any -element points back to the original object. -For example, an -element may have a FAMS tag whose value is @F1@, meaning that this -element points to the family record in which the associated person -is a spouse. Likewise, an element with a tag of FAMC has a value -that points to a family record in which the associated person is a -child.

    -

    See a GEDCOM file for examples of tags and their values.

    -

    Tags available to an element are seen here: gedcom.tags

    +

    Element associated with a MULTIMEDIA_RECORD

    Expand source code
    class ObjectElement(Element):
    +    """Element associated with a `MULTIMEDIA_RECORD`"""
     
    -    def is_object(self):
    -        """Checks if this element is an actual object
    -        :rtype: bool
    +    def get_tag(self) -> str:
    +        return tags.GEDCOM_TAG_OBJECT
    +
    +    def get_record(self) -> dict:
    +        """Parse and return the full record in dictionary format.
             """
    -        return self.get_tag() == gedcom.tags.GEDCOM_TAG_OBJECT
    + record = { + 'key_to_object': self.get_pointer(), + 'file': '', + 'format': '', + 'type': '', + 'title': '', + 'references': [], + 'record_id': '', + 'citations': [], + 'notes': [], + 'change_date': {} + } + for child in self.get_child_elements(): + if child.get_tag() == tags.GEDCOM_TAG_FILE: + record['file'] = child.get_value() + + for gchild in child.get_child_elements(): + if gchild.get_tag() == tags.GEDCOM_TAG_FORMAT: + record['format'] = gchild.get_value() + + for ggchild in gchild.get_child_elements(): + if ggchild.get_tag() == tags.GEDCOM_TAG_TYPE: + record['type'] = ggchild.get_value() + continue + + if gchild.get_tag() == tags.GEDCOM_TAG_TITLE: + record['title'] = gchild.get_value() + continue + continue + + if child.get_tag() == tags.GEDCOM_TAG_FORMAT: + record['format'] = child.get_value() + continue + + if child.get_tag() == tags.GEDCOM_TAG_TYPE: + record['type'] = child.get_value() + continue + + if child.get_tag() == tags.GEDCOM_TAG_NOTE: + record['notes'].append(note_structure(child)) + continue + + if child.get_tag() == tags.GEDCOM_TAG_SOURCE: + record['citations'].append(source_citation(child)) + continue + + if child.get_tag() == tags.GEDCOM_TAG_REFERENCE: + record['references'].append(user_reference_number(child)) + continue + + if child.get_tag() == tags.GEDCOM_TAG_REC_ID_NUMBER: + record['record_id'] = child.get_value() + continue + + if child.get_tag() == tags.GEDCOM_TAG_CHANGE: + record['change_date'] = change_date(child) + + return record

    Ancestors

      @@ -143,21 +230,76 @@

      Ancestors

    Methods

    -
    -def is_object(self) +
    +def get_record(self) -> dict
    -

    Checks if this element is an actual object -:rtype: bool

    +

    Parse and return the full record in dictionary format.

    Expand source code -
    def is_object(self):
    -    """Checks if this element is an actual object
    -    :rtype: bool
    +
    def get_record(self) -> dict:
    +    """Parse and return the full record in dictionary format.
         """
    -    return self.get_tag() == gedcom.tags.GEDCOM_TAG_OBJECT
    + record = { + 'key_to_object': self.get_pointer(), + 'file': '', + 'format': '', + 'type': '', + 'title': '', + 'references': [], + 'record_id': '', + 'citations': [], + 'notes': [], + 'change_date': {} + } + for child in self.get_child_elements(): + if child.get_tag() == tags.GEDCOM_TAG_FILE: + record['file'] = child.get_value() + + for gchild in child.get_child_elements(): + if gchild.get_tag() == tags.GEDCOM_TAG_FORMAT: + record['format'] = gchild.get_value() + + for ggchild in gchild.get_child_elements(): + if ggchild.get_tag() == tags.GEDCOM_TAG_TYPE: + record['type'] = ggchild.get_value() + continue + + if gchild.get_tag() == tags.GEDCOM_TAG_TITLE: + record['title'] = gchild.get_value() + continue + continue + + if child.get_tag() == tags.GEDCOM_TAG_FORMAT: + record['format'] = child.get_value() + continue + + if child.get_tag() == tags.GEDCOM_TAG_TYPE: + record['type'] = child.get_value() + continue + + if child.get_tag() == tags.GEDCOM_TAG_NOTE: + record['notes'].append(note_structure(child)) + continue + + if child.get_tag() == tags.GEDCOM_TAG_SOURCE: + record['citations'].append(source_citation(child)) + continue + + if child.get_tag() == tags.GEDCOM_TAG_REFERENCE: + record['references'].append(user_reference_number(child)) + continue + + if child.get_tag() == tags.GEDCOM_TAG_REC_ID_NUMBER: + record['record_id'] = child.get_value() + continue + + if child.get_tag() == tags.GEDCOM_TAG_CHANGE: + record['change_date'] = change_date(child) + + return record
    @@ -200,12 +342,9 @@

    Index

  • Classes

    @@ -214,7 +353,7 @@

    -

    Generated by pdoc 0.7.5.

    +

    Generated by pdoc 0.8.1.

    diff --git a/docs/gedcom/element/repository.html b/docs/gedcom/element/repository.html new file mode 100644 index 0000000..2369196 --- /dev/null +++ b/docs/gedcom/element/repository.html @@ -0,0 +1,289 @@ + + + + + + +gedcom.element.repository API documentation + + + + + + + + + +
    +
    +
    +

    Module gedcom.element.repository

    +
    +
    +

    GEDCOM element for a REPOSITORY_RECORD repository record identified by the +GEDCOM_TAG_REPOSITORY tag.

    +
    + +Expand source code + +
    # -*- coding: utf-8 -*-
    +
    +# Python GEDCOM Parser
    +#
    +# Copyright (C) 2020 Christopher Horn (cdhorn at embarqmail dot com)
    +# Copyright (C) 2018 Damon Brodie (damon.brodie at gmail.com)
    +# Copyright (C) 2018-2019 Nicklas Reincke (contact at reynke.com)
    +# Copyright (C) 2016 Andreas Oberritter
    +# Copyright (C) 2012 Madeleine Price Ball
    +# Copyright (C) 2005 Daniel Zappala (zappala at cs.byu.edu)
    +# Copyright (C) 2005 Brigham Young University
    +#
    +# 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.
    +#
    +# Further information about the license: http://www.gnu.org/licenses/gpl-2.0.html
    +
    +"""
    +GEDCOM element for a `REPOSITORY_RECORD` repository record identified by the
    +`gedcom.tags.GEDCOM_TAG_REPOSITORY` tag.
    +"""
    +
    +import gedcom.tags as tags
    +from gedcom.element.element import Element
    +from gedcom.subparsers.address_structure import address_structure
    +from gedcom.subparsers.note_structure import note_structure
    +from gedcom.subparsers.change_date import change_date
    +from gedcom.subparsers.user_reference_number import user_reference_number
    +
    +
    +class RepositoryElement(Element):
    +    """Element associated with a `REPOSITORY_RECORD`"""
    +
    +    def get_tag(self) -> str:
    +        return tags.GEDCOM_TAG_REPOSITORY
    +
    +    def get_record(self) -> dict:
    +        """Parse and return the full record in dictionary format.
    +        """
    +        record = {
    +            'key_to_repository': self.get_pointer(),
    +            'name': '',
    +            'address': {},
    +            'references': [],
    +            'record_id': '',
    +            'change_date': {},
    +            'notes': []
    +        }
    +        for child in self.get_child_elements():
    +            if child.get_tag() == tags.GEDCOM_TAG_NAME:
    +                record['name'] = child.get_value()
    +                continue
    +
    +            if child.get_tag() == tags.GEDCOM_TAG_ADDRESS:
    +                record['address'] = address_structure(self)
    +                continue
    +
    +            if child.get_tag() == tags.GEDCOM_TAG_NOTE:
    +                record['notes'].append(note_structure(child))
    +                continue
    +
    +            if child.get_tag() == tags.GEDCOM_TAG_REFERENCE:
    +                record['references'].append(user_reference_number(child))
    +                continue
    +
    +            if child.get_tag() == tags.GEDCOM_TAG_REC_ID_NUMBER:
    +                record['record_id'] = child.get_value()
    +                continue
    +
    +            if child.get_tag() == tags.GEDCOM_TAG_CHANGE:
    +                record['change_date'] = change_date(child)
    +
    +        return record
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +

    Classes

    +
    +
    +class RepositoryElement +(level: int, pointer: str, tag: str, value: str, crlf: str = '\n', multi_line: bool = True) +
    +
    +

    Element associated with a REPOSITORY_RECORD

    +
    + +Expand source code + +
    class RepositoryElement(Element):
    +    """Element associated with a `REPOSITORY_RECORD`"""
    +
    +    def get_tag(self) -> str:
    +        return tags.GEDCOM_TAG_REPOSITORY
    +
    +    def get_record(self) -> dict:
    +        """Parse and return the full record in dictionary format.
    +        """
    +        record = {
    +            'key_to_repository': self.get_pointer(),
    +            'name': '',
    +            'address': {},
    +            'references': [],
    +            'record_id': '',
    +            'change_date': {},
    +            'notes': []
    +        }
    +        for child in self.get_child_elements():
    +            if child.get_tag() == tags.GEDCOM_TAG_NAME:
    +                record['name'] = child.get_value()
    +                continue
    +
    +            if child.get_tag() == tags.GEDCOM_TAG_ADDRESS:
    +                record['address'] = address_structure(self)
    +                continue
    +
    +            if child.get_tag() == tags.GEDCOM_TAG_NOTE:
    +                record['notes'].append(note_structure(child))
    +                continue
    +
    +            if child.get_tag() == tags.GEDCOM_TAG_REFERENCE:
    +                record['references'].append(user_reference_number(child))
    +                continue
    +
    +            if child.get_tag() == tags.GEDCOM_TAG_REC_ID_NUMBER:
    +                record['record_id'] = child.get_value()
    +                continue
    +
    +            if child.get_tag() == tags.GEDCOM_TAG_CHANGE:
    +                record['change_date'] = change_date(child)
    +
    +        return record
    +
    +

    Ancestors

    + +

    Methods

    +
    +
    +def get_record(self) -> dict +
    +
    +

    Parse and return the full record in dictionary format.

    +
    + +Expand source code + +
    def get_record(self) -> dict:
    +    """Parse and return the full record in dictionary format.
    +    """
    +    record = {
    +        'key_to_repository': self.get_pointer(),
    +        'name': '',
    +        'address': {},
    +        'references': [],
    +        'record_id': '',
    +        'change_date': {},
    +        'notes': []
    +    }
    +    for child in self.get_child_elements():
    +        if child.get_tag() == tags.GEDCOM_TAG_NAME:
    +            record['name'] = child.get_value()
    +            continue
    +
    +        if child.get_tag() == tags.GEDCOM_TAG_ADDRESS:
    +            record['address'] = address_structure(self)
    +            continue
    +
    +        if child.get_tag() == tags.GEDCOM_TAG_NOTE:
    +            record['notes'].append(note_structure(child))
    +            continue
    +
    +        if child.get_tag() == tags.GEDCOM_TAG_REFERENCE:
    +            record['references'].append(user_reference_number(child))
    +            continue
    +
    +        if child.get_tag() == tags.GEDCOM_TAG_REC_ID_NUMBER:
    +            record['record_id'] = child.get_value()
    +            continue
    +
    +        if child.get_tag() == tags.GEDCOM_TAG_CHANGE:
    +            record['change_date'] = change_date(child)
    +
    +    return record
    +
    +
    +
    +

    Inherited members

    + +
    +
    +
    +
    + +
    + + + + + \ No newline at end of file diff --git a/docs/gedcom/element/root.html b/docs/gedcom/element/root.html index 11b2efd..2609f10 100644 --- a/docs/gedcom/element/root.html +++ b/docs/gedcom/element/root.html @@ -3,14 +3,14 @@ - + gedcom.element.root API documentation - - + + @@ -58,9 +58,10 @@

    Module gedcom.element.root

    class RootElement(Element): - """Virtual GEDCOM root element containing all logical records as children""" + """Virtual GEDCOM root element containing all logical records as children.""" - def __init__(self, level=-1, pointer="", tag="ROOT", value="", crlf="\n", multi_line=True): + def __init__(self, level: int = -1, pointer: str = "", tag: str = "ROOT", value: str = "", + crlf: str = "\n", multi_line: bool = True): super(RootElement, self).__init__(level, pointer, tag, value, crlf, multi_line)

  • @@ -75,18 +76,19 @@

    Classes

    class RootElement -(level=-1, pointer='', tag='ROOT', value='', crlf='\n', multi_line=True) +(level: int = -1, pointer: str = '', tag: str = 'ROOT', value: str = '', crlf: str = '\n', multi_line: bool = True)
    -

    Virtual GEDCOM root element containing all logical records as children

    +

    Virtual GEDCOM root element containing all logical records as children.

    Expand source code
    class RootElement(Element):
    -    """Virtual GEDCOM root element containing all logical records as children"""
    +    """Virtual GEDCOM root element containing all logical records as children."""
     
    -    def __init__(self, level=-1, pointer="", tag="ROOT", value="", crlf="\n", multi_line=True):
    +    def __init__(self, level: int = -1, pointer: str = "", tag: str = "ROOT", value: str = "",
    +                 crlf: str = "\n", multi_line: bool = True):
             super(RootElement, self).__init__(level, pointer, tag, value, crlf, multi_line)

    Ancestors

    @@ -140,7 +142,7 @@

    -

    Generated by pdoc 0.7.5.

    +

    Generated by pdoc 0.8.1.

    diff --git a/docs/gedcom/element/source.html b/docs/gedcom/element/source.html new file mode 100644 index 0000000..0a60467 --- /dev/null +++ b/docs/gedcom/element/source.html @@ -0,0 +1,420 @@ + + + + + + +gedcom.element.source API documentation + + + + + + + + + +
    +
    +
    +

    Module gedcom.element.source

    +
    +
    +

    GEDCOM element for a SOURCE_RECORD source record identified by the +GEDCOM_TAG_SOURCE tag.

    +
    + +Expand source code + +
    # -*- coding: utf-8 -*-
    +
    +# Python GEDCOM Parser
    +#
    +# Copyright (C) 2020 Christopher Horn (cdhorn at embarqmail dot com)
    +# Copyright (C) 2018 Damon Brodie (damon.brodie at gmail.com)
    +# Copyright (C) 2018-2019 Nicklas Reincke (contact at reynke.com)
    +# Copyright (C) 2016 Andreas Oberritter
    +# Copyright (C) 2012 Madeleine Price Ball
    +# Copyright (C) 2005 Daniel Zappala (zappala at cs.byu.edu)
    +# Copyright (C) 2005 Brigham Young University
    +#
    +# 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.
    +#
    +# Further information about the license: http://www.gnu.org/licenses/gpl-2.0.html
    +
    +"""
    +GEDCOM element for a `SOURCE_RECORD` source record identified by the
    +`gedcom.tags.GEDCOM_TAG_SOURCE` tag.
    +"""
    +
    +import gedcom.tags as tags
    +from gedcom.element.element import Element
    +from gedcom.subparsers.change_date import change_date
    +from gedcom.subparsers.note_structure import note_structure
    +from gedcom.subparsers.multimedia_link import multimedia_link
    +from gedcom.subparsers.user_reference_number import user_reference_number
    +from gedcom.subparsers.source_repository_citation import source_repository_citation
    +
    +SOURCE_PLURAL_TAGS = {
    +    tags.GEDCOM_TAG_AUTHOR: 'author',
    +    tags.GEDCOM_TAG_TITLE: 'title',
    +    tags.GEDCOM_TAG_PUBLICATION: 'publication',
    +    tags.GEDCOM_TAG_TEXT: 'text'
    +}
    +
    +SOURCE_SINGLE_TAGS = {
    +    tags.GEDCOM_TAG_ABBREVIATION: 'abbreviation',
    +    tags.GEDCOM_TAG_REC_ID_NUMBER: 'record_id',
    +    tags.GEDCOM_PROGRAM_DEFINED_TAG_APID: 'apid'
    +}
    +
    +
    +class SourceElement(Element):
    +    """Element associated with a SOURCE_RECORD"""
    +
    +    def get_tag(self) -> str:
    +        return tags.GEDCOM_TAG_SOURCE
    +
    +    def get_record(self) -> dict:
    +        """Parse and return the full record in dictionary format.
    +        """
    +        record = {
    +            'key_to_source': self.get_pointer(),
    +            'data': {
    +                'events': '',
    +                'date': '',
    +                'place': '',
    +                'agency': '',
    +                'notes': []
    +            },
    +            'author': '',
    +            'title': '',
    +            'abbreviation': '',
    +            'publication': '',
    +            'text': '',
    +            'repository': {},
    +            'references': [],
    +            'record_id': '',
    +            'change_date': {},
    +            'notes': [],
    +            'media': [],
    +            'apid': ''
    +        }
    +        for child in self.get_child_elements():
    +            if child.get_tag() in SOURCE_PLURAL_TAGS:
    +                record[SOURCE_PLURAL_TAGS[child.get_tag()]] = child.get_multi_line_value()
    +                continue
    +
    +            if child.get_tag() in SOURCE_SINGLE_TAGS:
    +                record[SOURCE_SINGLE_TAGS[child.get_tag()]] = child.get_value()
    +                continue
    +
    +            if child.get_tag() == tags.GEDCOM_TAG_NOTE:
    +                record['notes'].append(note_structure(child))
    +                continue
    +
    +            if child.get_tag() == tags.GEDCOM_TAG_OBJECT:
    +                record['media'].append(multimedia_link(child))
    +                continue
    +
    +            if child.get_tag() == tags.GEDCOM_TAG_REPOSITORY:
    +                record['repository'] = source_repository_citation(child)
    +                continue
    +
    +            if child.get_tag() == tags.GEDCOM_TAG_DATA:
    +                for gchild in child.get_child_elements():
    +                    if gchild.get_tag() == tags.GEDCOM_TAG_EVENT:
    +                        record['data']['events'] = gchild.get_value()
    +                        for ggchild in gchild.get_child_elements():
    +                            if ggchild.get_tag() == tags.GEDCOM_TAG_DATE:
    +                                record['data']['date'] = ggchild.get_value()
    +                                continue
    +
    +                            if ggchild.get_tag() == tags.GEDCOM_TAG_PLACE:
    +                                record['data']['place'] = ggchild.get_value()
    +                        continue
    +
    +                    if gchild.get_tag() == tags.GEDCOM_TAG_AGENCY:
    +                        record['data']['agency'] = gchild.get_value()
    +                        continue
    +
    +                    if gchild.get_tag() == tags.GEDCOM_TAG_NOTE:
    +                        record['data']['notes'].append(note_structure(gchild))
    +                        continue
    +
    +            if child.get_tag() == tags.GEDCOM_TAG_REFERENCE:
    +                record['references'].append(user_reference_number(child))
    +                continue
    +
    +            if child.get_tag() == tags.GEDCOM_TAG_CHANGE:
    +                record['change_date'] = change_date(child)
    +                continue
    +
    +        return record
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +

    Classes

    +
    +
    +class SourceElement +(level: int, pointer: str, tag: str, value: str, crlf: str = '\n', multi_line: bool = True) +
    +
    +

    Element associated with a SOURCE_RECORD

    +
    + +Expand source code + +
    class SourceElement(Element):
    +    """Element associated with a SOURCE_RECORD"""
    +
    +    def get_tag(self) -> str:
    +        return tags.GEDCOM_TAG_SOURCE
    +
    +    def get_record(self) -> dict:
    +        """Parse and return the full record in dictionary format.
    +        """
    +        record = {
    +            'key_to_source': self.get_pointer(),
    +            'data': {
    +                'events': '',
    +                'date': '',
    +                'place': '',
    +                'agency': '',
    +                'notes': []
    +            },
    +            'author': '',
    +            'title': '',
    +            'abbreviation': '',
    +            'publication': '',
    +            'text': '',
    +            'repository': {},
    +            'references': [],
    +            'record_id': '',
    +            'change_date': {},
    +            'notes': [],
    +            'media': [],
    +            'apid': ''
    +        }
    +        for child in self.get_child_elements():
    +            if child.get_tag() in SOURCE_PLURAL_TAGS:
    +                record[SOURCE_PLURAL_TAGS[child.get_tag()]] = child.get_multi_line_value()
    +                continue
    +
    +            if child.get_tag() in SOURCE_SINGLE_TAGS:
    +                record[SOURCE_SINGLE_TAGS[child.get_tag()]] = child.get_value()
    +                continue
    +
    +            if child.get_tag() == tags.GEDCOM_TAG_NOTE:
    +                record['notes'].append(note_structure(child))
    +                continue
    +
    +            if child.get_tag() == tags.GEDCOM_TAG_OBJECT:
    +                record['media'].append(multimedia_link(child))
    +                continue
    +
    +            if child.get_tag() == tags.GEDCOM_TAG_REPOSITORY:
    +                record['repository'] = source_repository_citation(child)
    +                continue
    +
    +            if child.get_tag() == tags.GEDCOM_TAG_DATA:
    +                for gchild in child.get_child_elements():
    +                    if gchild.get_tag() == tags.GEDCOM_TAG_EVENT:
    +                        record['data']['events'] = gchild.get_value()
    +                        for ggchild in gchild.get_child_elements():
    +                            if ggchild.get_tag() == tags.GEDCOM_TAG_DATE:
    +                                record['data']['date'] = ggchild.get_value()
    +                                continue
    +
    +                            if ggchild.get_tag() == tags.GEDCOM_TAG_PLACE:
    +                                record['data']['place'] = ggchild.get_value()
    +                        continue
    +
    +                    if gchild.get_tag() == tags.GEDCOM_TAG_AGENCY:
    +                        record['data']['agency'] = gchild.get_value()
    +                        continue
    +
    +                    if gchild.get_tag() == tags.GEDCOM_TAG_NOTE:
    +                        record['data']['notes'].append(note_structure(gchild))
    +                        continue
    +
    +            if child.get_tag() == tags.GEDCOM_TAG_REFERENCE:
    +                record['references'].append(user_reference_number(child))
    +                continue
    +
    +            if child.get_tag() == tags.GEDCOM_TAG_CHANGE:
    +                record['change_date'] = change_date(child)
    +                continue
    +
    +        return record
    +
    +

    Ancestors

    + +

    Methods

    +
    +
    +def get_record(self) -> dict +
    +
    +

    Parse and return the full record in dictionary format.

    +
    + +Expand source code + +
    def get_record(self) -> dict:
    +    """Parse and return the full record in dictionary format.
    +    """
    +    record = {
    +        'key_to_source': self.get_pointer(),
    +        'data': {
    +            'events': '',
    +            'date': '',
    +            'place': '',
    +            'agency': '',
    +            'notes': []
    +        },
    +        'author': '',
    +        'title': '',
    +        'abbreviation': '',
    +        'publication': '',
    +        'text': '',
    +        'repository': {},
    +        'references': [],
    +        'record_id': '',
    +        'change_date': {},
    +        'notes': [],
    +        'media': [],
    +        'apid': ''
    +    }
    +    for child in self.get_child_elements():
    +        if child.get_tag() in SOURCE_PLURAL_TAGS:
    +            record[SOURCE_PLURAL_TAGS[child.get_tag()]] = child.get_multi_line_value()
    +            continue
    +
    +        if child.get_tag() in SOURCE_SINGLE_TAGS:
    +            record[SOURCE_SINGLE_TAGS[child.get_tag()]] = child.get_value()
    +            continue
    +
    +        if child.get_tag() == tags.GEDCOM_TAG_NOTE:
    +            record['notes'].append(note_structure(child))
    +            continue
    +
    +        if child.get_tag() == tags.GEDCOM_TAG_OBJECT:
    +            record['media'].append(multimedia_link(child))
    +            continue
    +
    +        if child.get_tag() == tags.GEDCOM_TAG_REPOSITORY:
    +            record['repository'] = source_repository_citation(child)
    +            continue
    +
    +        if child.get_tag() == tags.GEDCOM_TAG_DATA:
    +            for gchild in child.get_child_elements():
    +                if gchild.get_tag() == tags.GEDCOM_TAG_EVENT:
    +                    record['data']['events'] = gchild.get_value()
    +                    for ggchild in gchild.get_child_elements():
    +                        if ggchild.get_tag() == tags.GEDCOM_TAG_DATE:
    +                            record['data']['date'] = ggchild.get_value()
    +                            continue
    +
    +                        if ggchild.get_tag() == tags.GEDCOM_TAG_PLACE:
    +                            record['data']['place'] = ggchild.get_value()
    +                    continue
    +
    +                if gchild.get_tag() == tags.GEDCOM_TAG_AGENCY:
    +                    record['data']['agency'] = gchild.get_value()
    +                    continue
    +
    +                if gchild.get_tag() == tags.GEDCOM_TAG_NOTE:
    +                    record['data']['notes'].append(note_structure(gchild))
    +                    continue
    +
    +        if child.get_tag() == tags.GEDCOM_TAG_REFERENCE:
    +            record['references'].append(user_reference_number(child))
    +            continue
    +
    +        if child.get_tag() == tags.GEDCOM_TAG_CHANGE:
    +            record['change_date'] = change_date(child)
    +            continue
    +
    +    return record
    +
    +
    +
    +

    Inherited members

    + +
    +
    +
    +
    + +
    + + + + + \ No newline at end of file diff --git a/docs/gedcom/element/submission.html b/docs/gedcom/element/submission.html new file mode 100644 index 0000000..c4bdb9e --- /dev/null +++ b/docs/gedcom/element/submission.html @@ -0,0 +1,270 @@ + + + + + + +gedcom.element.submission API documentation + + + + + + + + + +
    +
    +
    +

    Module gedcom.element.submission

    +
    +
    +

    GEDCOM element for a SUBMISSION_RECORD submission record identified by the +GEDCOM_TAG_SUBMISSION tag.

    +
    + +Expand source code + +
    # -*- coding: utf-8 -*-
    +
    +# Python GEDCOM Parser
    +#
    +# Copyright (C) 2020 Christopher Horn (cdhorn at embarqmail dot com)
    +# Copyright (C) 2018 Damon Brodie (damon.brodie at gmail.com)
    +# Copyright (C) 2018-2019 Nicklas Reincke (contact at reynke.com)
    +# Copyright (C) 2016 Andreas Oberritter
    +# Copyright (C) 2012 Madeleine Price Ball
    +# Copyright (C) 2005 Daniel Zappala (zappala at cs.byu.edu)
    +# Copyright (C) 2005 Brigham Young University
    +#
    +# 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.
    +#
    +# Further information about the license: http://www.gnu.org/licenses/gpl-2.0.html
    +
    +"""
    +GEDCOM element for a `SUBMISSION_RECORD` submission record identified by the
    +`gedcom.tags.GEDCOM_TAG_SUBMISSION` tag.
    +"""
    +
    +import gedcom.tags as tags
    +from gedcom.element.element import Element
    +from gedcom.subparsers.note_structure import note_structure
    +from gedcom.subparsers.change_date import change_date
    +
    +SUBMISSION_TAGS = {
    +    tags.GEDCOM_TAG_SUBMITTER: 'key_to_submitter',
    +    tags.GEDCOM_TAG_FAMILY_FILE: 'family_file',
    +    tags.GEDCOM_TAG_TEMPLE: 'temple',
    +    tags.GEDCOM_TAG_ANCESTORS: 'generations_of_ancestors',
    +    tags.GEDCOM_TAG_DESCENDANTS: 'generations_of_decendants',
    +    tags.GEDCOM_TAG_ORDINANCE: 'ordinance_process_flag',
    +    tags.GEDCOM_TAG_REC_ID_NUMBER: 'record_id'
    +}
    +
    +
    +class SubmissionElement(Element):
    +    """Element associated with a `SUBMISSION_RECORD`"""
    +
    +    def get_tag(self) -> str:
    +        return tags.GEDCOM_TAG_SUBMISSION
    +
    +    def get_record(self) -> dict:
    +        """Parse and return the record in dictionary format
    +        """
    +        record = {
    +            'key_to_submission': self.get_pointer(),
    +            'key_to_submitter': '',
    +            'family_file': '',
    +            'temple': '',
    +            'generations_of_ancestors': '',
    +            'generations_of_descendants': '',
    +            'ordinance_process_flag': '',
    +            'record_id': '',
    +            'notes': [],
    +            'change_date': {}
    +        }
    +        for child in self.get_child_elements():
    +            if child.get_tag() in SUBMISSION_TAGS:
    +                record[SUBMISSION_TAGS[child.get_tag()]] = child.get_value()
    +                continue
    +
    +            if child.get_tag() == tags.GEDCOM_TAG_NOTE:
    +                record['notes'].append(note_structure(child))
    +                continue
    +
    +            if child.get_tag() == tags.GEDCOM_TAG_CHANGE:
    +                record['change_date'] = change_date(child)
    +
    +        return record
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +

    Classes

    +
    +
    +class SubmissionElement +(level: int, pointer: str, tag: str, value: str, crlf: str = '\n', multi_line: bool = True) +
    +
    +

    Element associated with a SUBMISSION_RECORD

    +
    + +Expand source code + +
    class SubmissionElement(Element):
    +    """Element associated with a `SUBMISSION_RECORD`"""
    +
    +    def get_tag(self) -> str:
    +        return tags.GEDCOM_TAG_SUBMISSION
    +
    +    def get_record(self) -> dict:
    +        """Parse and return the record in dictionary format
    +        """
    +        record = {
    +            'key_to_submission': self.get_pointer(),
    +            'key_to_submitter': '',
    +            'family_file': '',
    +            'temple': '',
    +            'generations_of_ancestors': '',
    +            'generations_of_descendants': '',
    +            'ordinance_process_flag': '',
    +            'record_id': '',
    +            'notes': [],
    +            'change_date': {}
    +        }
    +        for child in self.get_child_elements():
    +            if child.get_tag() in SUBMISSION_TAGS:
    +                record[SUBMISSION_TAGS[child.get_tag()]] = child.get_value()
    +                continue
    +
    +            if child.get_tag() == tags.GEDCOM_TAG_NOTE:
    +                record['notes'].append(note_structure(child))
    +                continue
    +
    +            if child.get_tag() == tags.GEDCOM_TAG_CHANGE:
    +                record['change_date'] = change_date(child)
    +
    +        return record
    +
    +

    Ancestors

    + +

    Methods

    +
    +
    +def get_record(self) -> dict +
    +
    +

    Parse and return the record in dictionary format

    +
    + +Expand source code + +
    def get_record(self) -> dict:
    +    """Parse and return the record in dictionary format
    +    """
    +    record = {
    +        'key_to_submission': self.get_pointer(),
    +        'key_to_submitter': '',
    +        'family_file': '',
    +        'temple': '',
    +        'generations_of_ancestors': '',
    +        'generations_of_descendants': '',
    +        'ordinance_process_flag': '',
    +        'record_id': '',
    +        'notes': [],
    +        'change_date': {}
    +    }
    +    for child in self.get_child_elements():
    +        if child.get_tag() in SUBMISSION_TAGS:
    +            record[SUBMISSION_TAGS[child.get_tag()]] = child.get_value()
    +            continue
    +
    +        if child.get_tag() == tags.GEDCOM_TAG_NOTE:
    +            record['notes'].append(note_structure(child))
    +            continue
    +
    +        if child.get_tag() == tags.GEDCOM_TAG_CHANGE:
    +            record['change_date'] = change_date(child)
    +
    +    return record
    +
    +
    +
    +

    Inherited members

    + +
    +
    +
    +
    + +
    + + + + + \ No newline at end of file diff --git a/docs/gedcom/element/submitter.html b/docs/gedcom/element/submitter.html new file mode 100644 index 0000000..899e7ec --- /dev/null +++ b/docs/gedcom/element/submitter.html @@ -0,0 +1,319 @@ + + + + + + +gedcom.element.submitter API documentation + + + + + + + + + +
    +
    +
    +

    Module gedcom.element.submitter

    +
    +
    +

    GEDCOM element for a SUBMITTER_RECORD submitter record identified by the +GEDCOM_TAG_SUBMITTER tag.

    +
    + +Expand source code + +
    # -*- coding: utf-8 -*-
    +
    +# Python GEDCOM Parser
    +#
    +# Copyright (C) 2020 Christopher Horn (cdhorn at embarqmail dot com)
    +# Copyright (C) 2018 Damon Brodie (damon.brodie at gmail.com)
    +# Copyright (C) 2018-2019 Nicklas Reincke (contact at reynke.com)
    +# Copyright (C) 2016 Andreas Oberritter
    +# Copyright (C) 2012 Madeleine Price Ball
    +# Copyright (C) 2005 Daniel Zappala (zappala at cs.byu.edu)
    +# Copyright (C) 2005 Brigham Young University
    +#
    +# 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.
    +#
    +# Further information about the license: http://www.gnu.org/licenses/gpl-2.0.html
    +
    +"""
    +GEDCOM element for a `SUBMITTER_RECORD` submitter record identified by the
    +`gedcom.tags.GEDCOM_TAG_SUBMITTER` tag.
    +"""
    +
    +import gedcom.tags as tags
    +from gedcom.element.element import Element
    +from gedcom.subparsers.address_structure import address_structure
    +from gedcom.subparsers.note_structure import note_structure
    +from gedcom.subparsers.change_date import change_date
    +from gedcom.subparsers.multimedia_link import multimedia_link
    +
    +
    +class SubmitterElement(Element):
    +    """Element associated with a `SUBMITTER_RECORD`"""
    +
    +    def get_tag(self) -> str:
    +        return tags.GEDCOM_TAG_SUBMITTER
    +
    +    def get_record(self) -> dict:
    +        """Parse and return the record in dictionary format
    +        """
    +        record = {
    +            'key_to_submitter': self.get_pointer(),
    +            'name': '',
    +            'address': {},
    +            'media': [],
    +            'language': '',
    +            'registered_file_number': '',
    +            'record_id': '',
    +            'notes': [],
    +            'change_date': {}
    +        }
    +        for child in self.get_child_elements():
    +            if child.get_tag() == tags.GEDCOM_TAG_NAME:
    +                record['name'] = child.get_value()
    +                continue
    +
    +            if child.get_tag() == tags.GEDCOM_TAG_ADDRESS:
    +                record['address'] = address_structure(self)
    +                continue
    +
    +            if child.get_tag() == tags.GEDCOM_TAG_NOTE:
    +                record['notes'].append(note_structure(child))
    +                continue
    +
    +            if child.get_tag() == tags.GEDCOM_TAG_OBJECT:
    +                record['media'].append(multimedia_link(child))
    +                continue
    +
    +            if child.get_tag() == tags.GEDCOM_TAG_LANGUAGE:
    +                record['language'] = child.get_value()
    +                continue
    +
    +            if child.get_tag() == tags.GEDCOM_TAG_REC_FILE_NUMBER:
    +                record['registered_file_number'] = child.get_value()
    +                continue
    +
    +            if child.get_tag() == tags.GEDCOM_TAG_REC_ID_NUMBER:
    +                record['record_id'] = child.get_value()
    +                continue
    +
    +            if child.get_tag() == tags.GEDCOM_TAG_CHANGE:
    +                record['change_date'] = change_date(child)
    +
    +        return record
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +

    Classes

    +
    +
    +class SubmitterElement +(level: int, pointer: str, tag: str, value: str, crlf: str = '\n', multi_line: bool = True) +
    +
    +

    Element associated with a SUBMITTER_RECORD

    +
    + +Expand source code + +
    class SubmitterElement(Element):
    +    """Element associated with a `SUBMITTER_RECORD`"""
    +
    +    def get_tag(self) -> str:
    +        return tags.GEDCOM_TAG_SUBMITTER
    +
    +    def get_record(self) -> dict:
    +        """Parse and return the record in dictionary format
    +        """
    +        record = {
    +            'key_to_submitter': self.get_pointer(),
    +            'name': '',
    +            'address': {},
    +            'media': [],
    +            'language': '',
    +            'registered_file_number': '',
    +            'record_id': '',
    +            'notes': [],
    +            'change_date': {}
    +        }
    +        for child in self.get_child_elements():
    +            if child.get_tag() == tags.GEDCOM_TAG_NAME:
    +                record['name'] = child.get_value()
    +                continue
    +
    +            if child.get_tag() == tags.GEDCOM_TAG_ADDRESS:
    +                record['address'] = address_structure(self)
    +                continue
    +
    +            if child.get_tag() == tags.GEDCOM_TAG_NOTE:
    +                record['notes'].append(note_structure(child))
    +                continue
    +
    +            if child.get_tag() == tags.GEDCOM_TAG_OBJECT:
    +                record['media'].append(multimedia_link(child))
    +                continue
    +
    +            if child.get_tag() == tags.GEDCOM_TAG_LANGUAGE:
    +                record['language'] = child.get_value()
    +                continue
    +
    +            if child.get_tag() == tags.GEDCOM_TAG_REC_FILE_NUMBER:
    +                record['registered_file_number'] = child.get_value()
    +                continue
    +
    +            if child.get_tag() == tags.GEDCOM_TAG_REC_ID_NUMBER:
    +                record['record_id'] = child.get_value()
    +                continue
    +
    +            if child.get_tag() == tags.GEDCOM_TAG_CHANGE:
    +                record['change_date'] = change_date(child)
    +
    +        return record
    +
    +

    Ancestors

    + +

    Methods

    +
    +
    +def get_record(self) -> dict +
    +
    +

    Parse and return the record in dictionary format

    +
    + +Expand source code + +
    def get_record(self) -> dict:
    +    """Parse and return the record in dictionary format
    +    """
    +    record = {
    +        'key_to_submitter': self.get_pointer(),
    +        'name': '',
    +        'address': {},
    +        'media': [],
    +        'language': '',
    +        'registered_file_number': '',
    +        'record_id': '',
    +        'notes': [],
    +        'change_date': {}
    +    }
    +    for child in self.get_child_elements():
    +        if child.get_tag() == tags.GEDCOM_TAG_NAME:
    +            record['name'] = child.get_value()
    +            continue
    +
    +        if child.get_tag() == tags.GEDCOM_TAG_ADDRESS:
    +            record['address'] = address_structure(self)
    +            continue
    +
    +        if child.get_tag() == tags.GEDCOM_TAG_NOTE:
    +            record['notes'].append(note_structure(child))
    +            continue
    +
    +        if child.get_tag() == tags.GEDCOM_TAG_OBJECT:
    +            record['media'].append(multimedia_link(child))
    +            continue
    +
    +        if child.get_tag() == tags.GEDCOM_TAG_LANGUAGE:
    +            record['language'] = child.get_value()
    +            continue
    +
    +        if child.get_tag() == tags.GEDCOM_TAG_REC_FILE_NUMBER:
    +            record['registered_file_number'] = child.get_value()
    +            continue
    +
    +        if child.get_tag() == tags.GEDCOM_TAG_REC_ID_NUMBER:
    +            record['record_id'] = child.get_value()
    +            continue
    +
    +        if child.get_tag() == tags.GEDCOM_TAG_CHANGE:
    +            record['change_date'] = change_date(child)
    +
    +    return record
    +
    +
    +
    +

    Inherited members

    + +
    +
    +
    +
    + +
    + + + + + \ No newline at end of file diff --git a/docs/gedcom/errors.html b/docs/gedcom/errors.html new file mode 100644 index 0000000..bc3b49f --- /dev/null +++ b/docs/gedcom/errors.html @@ -0,0 +1,495 @@ + + + + + + +gedcom.errors API documentation + + + + + + + + + +
    +
    +
    +

    Module gedcom.errors

    +
    +
    +

    Module containing the exception handling classes.

    +
    + +Expand source code + +
    # -*- coding: utf-8 -*-
    +
    +# Python GEDCOM Parser
    +#
    +# Copyright (C) 2020 Christopher Horn (cdhorn at embarqmail dot com)
    +# Copyright (C) 2018 Damon Brodie (damon.brodie at gmail.com)
    +# Copyright (C) 2018-2019 Nicklas Reincke (contact at reynke.com)
    +# Copyright (C) 2016 Andreas Oberritter
    +# Copyright (C) 2012 Madeleine Price Ball
    +# Copyright (C) 2005 Daniel Zappala (zappala at cs.byu.edu)
    +# Copyright (C) 2005 Brigham Young University
    +#
    +# 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.
    +#
    +# Further information about the license: http://www.gnu.org/licenses/gpl-2.0.html
    +
    +"""
    +Module containing the exception handling classes.
    +"""
    +
    +
    +class GedcomFormatViolationError(Exception):
    +    """Raised when the document format does not appear to conform
    +    to the GEDCOM standard and strict parsing required.
    +    """
    +
    +
    +class GedcomStructureViolationError(Exception):
    +    """Raised when the structure of a record does not conform to
    +    the GEDCOM standard.
    +    """
    +
    +
    +class GedcomCharacterSetUnsupportedError(Exception):
    +    """Raised when a GEDCOM appears to contain a character set
    +    the standard or the parser does not support.
    +    """
    +
    +
    +class GedcomVersionUnsupportedError(Exception):
    +    """Raised when a particular GEDCOM version is not supported
    +    by the parser and the standard for that version requires the
    +    parser to reject it.
    +    """
    +
    +
    +class GedcomFormatUnsupportedError(Exception):
    +    """Raised if the GEDCOM format is not recognized by the
    +    parser. Note some common misspellings as documented on page 148
    +    in the 5.5.5 GEDCOM standard are treated as `LINEAGE-LINKED`
    +    and allowed when parsing older GEDCOM data.
    +    """
    +
    +
    +class NotAnActualIndividualError(Exception):
    +    """Raised if record does not appear to be an `INDIVIDUAL_RECORD`"""
    +
    +
    +class NotAnActualFamilyError(Exception):
    +    """Raised if record does not appear to be a `FAM_RECORD`"""
    +
    +
    +class NotAnActualSourceError(Exception):
    +    """Raised if record does not appear to be a `SOURCE_RECORD`"""
    +
    +
    +class NotAnActualRepositoryError(Exception):
    +    """Raised if record does not appear to be a `REPOSITORY_RECORD`"""
    +
    +
    +class NotAnActualNoteError(Exception):
    +    """Raised if record does not appear to be a `NOTE_RECORD`"""
    +
    +
    +class NotAnActualObjectError(Exception):
    +    """Raised if record does not appear to be a `MULTIMEDIA_RECORD`"""
    +
    +
    +class NotAnActualHeaderError(Exception):
    +    """Raised if record does not appear to be a `HEADER`"""
    +
    +
    +class NotAnActualSubmitterError(Exception):
    +    """Raised if record does not appear to be a `SUBMITTER_RECORD`"""
    +
    +
    +class NotAnActualSubmissionError(Exception):
    +    """Raised if record does not appear to be a `SUBMISSION_RECORD`"""
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +

    Classes

    +
    +
    +class GedcomCharacterSetUnsupportedError +(...) +
    +
    +

    Raised when a GEDCOM appears to contain a character set +the standard or the parser does not support.

    +
    + +Expand source code + +
    class GedcomCharacterSetUnsupportedError(Exception):
    +    """Raised when a GEDCOM appears to contain a character set
    +    the standard or the parser does not support.
    +    """
    +
    +

    Ancestors

    +
      +
    • builtins.Exception
    • +
    • builtins.BaseException
    • +
    +
    +
    +class GedcomFormatUnsupportedError +(...) +
    +
    +

    Raised if the GEDCOM format is not recognized by the +parser. Note some common misspellings as documented on page 148 +in the 5.5.5 GEDCOM standard are treated as LINEAGE-LINKED +and allowed when parsing older GEDCOM data.

    +
    + +Expand source code + +
    class GedcomFormatUnsupportedError(Exception):
    +    """Raised if the GEDCOM format is not recognized by the
    +    parser. Note some common misspellings as documented on page 148
    +    in the 5.5.5 GEDCOM standard are treated as `LINEAGE-LINKED`
    +    and allowed when parsing older GEDCOM data.
    +    """
    +
    +

    Ancestors

    +
      +
    • builtins.Exception
    • +
    • builtins.BaseException
    • +
    +
    +
    +class GedcomFormatViolationError +(...) +
    +
    +

    Raised when the document format does not appear to conform +to the GEDCOM standard and strict parsing required.

    +
    + +Expand source code + +
    class GedcomFormatViolationError(Exception):
    +    """Raised when the document format does not appear to conform
    +    to the GEDCOM standard and strict parsing required.
    +    """
    +
    +

    Ancestors

    +
      +
    • builtins.Exception
    • +
    • builtins.BaseException
    • +
    +
    +
    +class GedcomStructureViolationError +(...) +
    +
    +

    Raised when the structure of a record does not conform to +the GEDCOM standard.

    +
    + +Expand source code + +
    class GedcomStructureViolationError(Exception):
    +    """Raised when the structure of a record does not conform to
    +    the GEDCOM standard.
    +    """
    +
    +

    Ancestors

    +
      +
    • builtins.Exception
    • +
    • builtins.BaseException
    • +
    +
    +
    +class GedcomVersionUnsupportedError +(...) +
    +
    +

    Raised when a particular GEDCOM version is not supported +by the parser and the standard for that version requires the +parser to reject it.

    +
    + +Expand source code + +
    class GedcomVersionUnsupportedError(Exception):
    +    """Raised when a particular GEDCOM version is not supported
    +    by the parser and the standard for that version requires the
    +    parser to reject it.
    +    """
    +
    +

    Ancestors

    +
      +
    • builtins.Exception
    • +
    • builtins.BaseException
    • +
    +
    +
    +class NotAnActualFamilyError +(...) +
    +
    +

    Raised if record does not appear to be a FAM_RECORD

    +
    + +Expand source code + +
    class NotAnActualFamilyError(Exception):
    +    """Raised if record does not appear to be a `FAM_RECORD`"""
    +
    +

    Ancestors

    +
      +
    • builtins.Exception
    • +
    • builtins.BaseException
    • +
    +
    +
    +class NotAnActualHeaderError +(...) +
    +
    +

    Raised if record does not appear to be a HEADER

    +
    + +Expand source code + +
    class NotAnActualHeaderError(Exception):
    +    """Raised if record does not appear to be a `HEADER`"""
    +
    +

    Ancestors

    +
      +
    • builtins.Exception
    • +
    • builtins.BaseException
    • +
    +
    +
    +class NotAnActualIndividualError +(...) +
    +
    +

    Raised if record does not appear to be an INDIVIDUAL_RECORD

    +
    + +Expand source code + +
    class NotAnActualIndividualError(Exception):
    +    """Raised if record does not appear to be an `INDIVIDUAL_RECORD`"""
    +
    +

    Ancestors

    +
      +
    • builtins.Exception
    • +
    • builtins.BaseException
    • +
    +
    +
    +class NotAnActualNoteError +(...) +
    +
    +

    Raised if record does not appear to be a NOTE_RECORD

    +
    + +Expand source code + +
    class NotAnActualNoteError(Exception):
    +    """Raised if record does not appear to be a `NOTE_RECORD`"""
    +
    +

    Ancestors

    +
      +
    • builtins.Exception
    • +
    • builtins.BaseException
    • +
    +
    +
    +class NotAnActualObjectError +(...) +
    +
    +

    Raised if record does not appear to be a MULTIMEDIA_RECORD

    +
    + +Expand source code + +
    class NotAnActualObjectError(Exception):
    +    """Raised if record does not appear to be a `MULTIMEDIA_RECORD`"""
    +
    +

    Ancestors

    +
      +
    • builtins.Exception
    • +
    • builtins.BaseException
    • +
    +
    +
    +class NotAnActualRepositoryError +(...) +
    +
    +

    Raised if record does not appear to be a REPOSITORY_RECORD

    +
    + +Expand source code + +
    class NotAnActualRepositoryError(Exception):
    +    """Raised if record does not appear to be a `REPOSITORY_RECORD`"""
    +
    +

    Ancestors

    +
      +
    • builtins.Exception
    • +
    • builtins.BaseException
    • +
    +
    +
    +class NotAnActualSourceError +(...) +
    +
    +

    Raised if record does not appear to be a SOURCE_RECORD

    +
    + +Expand source code + +
    class NotAnActualSourceError(Exception):
    +    """Raised if record does not appear to be a `SOURCE_RECORD`"""
    +
    +

    Ancestors

    +
      +
    • builtins.Exception
    • +
    • builtins.BaseException
    • +
    +
    +
    +class NotAnActualSubmissionError +(...) +
    +
    +

    Raised if record does not appear to be a SUBMISSION_RECORD

    +
    + +Expand source code + +
    class NotAnActualSubmissionError(Exception):
    +    """Raised if record does not appear to be a `SUBMISSION_RECORD`"""
    +
    +

    Ancestors

    +
      +
    • builtins.Exception
    • +
    • builtins.BaseException
    • +
    +
    +
    +class NotAnActualSubmitterError +(...) +
    +
    +

    Raised if record does not appear to be a SUBMITTER_RECORD

    +
    + +Expand source code + +
    class NotAnActualSubmitterError(Exception):
    +    """Raised if record does not appear to be a `SUBMITTER_RECORD`"""
    +
    +

    Ancestors

    +
      +
    • builtins.Exception
    • +
    • builtins.BaseException
    • +
    +
    +
    +
    +
    + +
    + + + + + \ No newline at end of file diff --git a/docs/gedcom/helpers.html b/docs/gedcom/helpers.html index 783b4cd..8543391 100644 --- a/docs/gedcom/helpers.html +++ b/docs/gedcom/helpers.html @@ -3,14 +3,14 @@ - + gedcom.helpers API documentation - - + + @@ -90,9 +90,9 @@

    Functions

    def deprecated(func)
    -

    This is a decorator which can be used to mark functions +

    This is a decorator which can be used to mark functions as deprecated. It will result in a warning being emitted -when the function is used.

    +when the function is used.

    Expand source code @@ -141,7 +141,7 @@

    Index

    diff --git a/docs/gedcom/index.html b/docs/gedcom/index.html index 389005e..33be1ff 100644 --- a/docs/gedcom/index.html +++ b/docs/gedcom/index.html @@ -3,21 +3,21 @@ - + gedcom API documentation - - + +
    -

    Module gedcom

    +

    Package gedcom

    A Python module for parsing, analyzing, and manipulating GEDCOM files.

    @@ -34,12 +34,12 @@

    Pre-releases

    simply append the --pre option to pip3: pip3 install python-gedcom --pre

    Important classes and modules

    Example usage

    -

    When successfully installed you may import the gedcom package and use it like so:

    +

    When successfully installed you may import the gedcom package and use it like so:

    from gedcom.element.individual import IndividualElement
     from gedcom.parser import Parser
     
    @@ -79,7 +79,7 @@ 

    Strict parsing

    If you encounter errors in parsing, you might consider disabling strict parsing which is enabled by default:

    from gedcom.parser import Parser
     
    -file_path = '' # Path to your `.ged` file
    +file_path = '' # Path to your <code>.ged</code> file
     
     gedcom_parser = Parser()
     gedcom_parser.parse_file(file_path, False) # Disable strict parsing
    @@ -92,6 +92,7 @@ 

    Strict parsing

    License

    Licensed under the GNU General Public License v2

    Python GEDCOM Parser +
    Copyright (C) 2020 Christopher Horn (cdhorn at embarqmail dot com)
    Copyright (C) 2018 Damon Brodie (damon.brodie at gmail.com)
    Copyright (C) 2018-2019 Nicklas Reincke (contact at reynke.com)
    Copyright (C) 2016 Andreas Oberritter @@ -150,9 +151,15 @@

    License

    __all__ = [ # Subpackages "element", + "subparsers", # Modules + "errors", "helpers", + "detect", "parser", + "reader", + "records", + "standards", "tags" ]
    @@ -160,23 +167,50 @@

    License

    Sub-modules

    +
    gedcom.detect
    +
    +

    Module containing functions for detecting GEDCOM file encoding and version.

    +
    gedcom.element
    -

    Module containing all relevant elements generated by a Parser. -An element represents a line within GEDCOM data.

    +

    Module containing all relevant elements generated by a Parser. +An element represents a line within GEDCOM data.

    +
    +
    gedcom.errors
    +
    +

    Module containing the exception handling classes.

    gedcom.helpers
    -

    Helper methods.

    +

    Helper methods.

    gedcom.parser
    -

    Module containing the actual Parser used to generate elements - out of each line - -which can in return be manipulated.

    +

    Module containing the actual Parser used to generate elements +out of each line - which can in return be manipulated.

    +
    +
    gedcom.reader
    +
    +

    Module containing a Reader with higher order methods than the +base Parser for extracting records as structured data.

    +
    +
    gedcom.records
    +
    +

    Module containing the standard GEDCOM record types recognized by the +GEDCOM Reader.

    +
    +
    gedcom.standards
    +
    +

    Module containing links to the documentation for the various GEDCOM standards.

    +
    +
    gedcom.subparsers
    +
    +

    Module containing parsers for extracting various substructures from the +different record types as defined in the GEDCOM standard.

    gedcom.tags
    -

    GEDCOM tags.

    +

    Module containing the standard GEDCOM tags and some of the most common program defined extensions.

    @@ -204,9 +238,15 @@

    Index

    • Sub-modules

    • @@ -214,7 +254,7 @@

      Index

      diff --git a/docs/gedcom/parser.html b/docs/gedcom/parser.html index 1e6d4aa..36faeaa 100644 --- a/docs/gedcom/parser.html +++ b/docs/gedcom/parser.html @@ -3,15 +3,15 @@ - + gedcom.parser API documentation - + - - + + @@ -21,8 +21,8 @@

      Module gedcom.parser

      -

      Module containing the actual Parser used to generate elements - out of each line - -which can in return be manipulated.

      +

      Module containing the actual Parser used to generate elements +out of each line - which can in return be manipulated.

      Expand source code @@ -31,6 +31,7 @@

      Module gedcom.parser

      # Python GEDCOM Parser # +# Copyright (C) 2020 Christopher Horn (cdhorn at embarqmail dot com) # Copyright (C) 2018 Damon Brodie (damon.brodie at gmail.com) # Copyright (C) 2018-2019 Nicklas Reincke (contact at reynke.com) # Copyright (C) 2016 Andreas Oberritter @@ -55,35 +56,63 @@

      Module gedcom.parser

      # Further information about the license: http://www.gnu.org/licenses/gpl-2.0.html """ -Module containing the actual `gedcom.parser.Parser` used to generate elements - out of each line - -which can in return be manipulated. +Module containing the actual `gedcom.parser.Parser` used to generate elements +out of each line - which can in return be manipulated. """ import re as regex +from sys import stdout from sys import version_info +from typing import Tuple, List, IO + +import gedcom.tags as tags +import gedcom.standards as standards + +from gedcom.detect import get_encoding, get_version from gedcom.element.element import Element -from gedcom.element.family import FamilyElement, NotAnActualFamilyError -from gedcom.element.file import FileElement -from gedcom.element.individual import IndividualElement, NotAnActualIndividualError +from gedcom.element.header import HeaderElement +from gedcom.element.family import FamilyElement +from gedcom.element.individual import IndividualElement +from gedcom.element.note import NoteElement from gedcom.element.object import ObjectElement +from gedcom.element.source import SourceElement +from gedcom.element.submission import SubmissionElement +from gedcom.element.submitter import SubmitterElement +from gedcom.element.repository import RepositoryElement from gedcom.element.root import RootElement -import gedcom.tags + +from gedcom.errors import GedcomVersionUnsupportedError +from gedcom.errors import GedcomFormatUnsupportedError +from gedcom.errors import GedcomFormatViolationError +from gedcom.errors import NotAnActualIndividualError +from gedcom.errors import NotAnActualFamilyError + +ERROR_TEMPLATE = "Line <{0}:{1}> of document violates GEDCOM format {2}\nSee: {3}" + +RECORD_ELEMENTS = { + tags.GEDCOM_TAG_HEADER: HeaderElement, + tags.GEDCOM_TAG_INDIVIDUAL: IndividualElement, + tags.GEDCOM_TAG_FAMILY: FamilyElement, + tags.GEDCOM_TAG_NOTE: NoteElement, + tags.GEDCOM_TAG_OBJECT: ObjectElement, + tags.GEDCOM_TAG_SOURCE: SourceElement, + tags.GEDCOM_TAG_SUBMISSION: SubmissionElement, + tags.GEDCOM_TAG_SUBMITTER: SubmitterElement, + tags.GEDCOM_TAG_REPOSITORY: RepositoryElement +} FAMILY_MEMBERS_TYPE_ALL = "ALL" -FAMILY_MEMBERS_TYPE_CHILDREN = gedcom.tags.GEDCOM_TAG_CHILD -FAMILY_MEMBERS_TYPE_HUSBAND = gedcom.tags.GEDCOM_TAG_HUSBAND +FAMILY_MEMBERS_TYPE_CHILDREN = tags.GEDCOM_TAG_CHILD +FAMILY_MEMBERS_TYPE_HUSBAND = tags.GEDCOM_TAG_HUSBAND FAMILY_MEMBERS_TYPE_PARENTS = "PARENTS" -FAMILY_MEMBERS_TYPE_WIFE = gedcom.tags.GEDCOM_TAG_WIFE +FAMILY_MEMBERS_TYPE_WIFE = tags.GEDCOM_TAG_WIFE -class GedcomFormatViolationError(Exception): - pass +class Parser(): + """Parses and manipulates GEDCOM formatted data. - -class Parser(object): - """Parses and manipulates GEDCOM 5.5 format data - - For documentation of the GEDCOM 5.5 format, see: http://homepages.rootsweb.ancestry.com/~pmcbride/gedcom/55gctoc.htm + For documentation of the different GEDCOM standards see the + links defined in `gedcom.standards` This parser reads and parses a GEDCOM file. @@ -99,35 +128,36 @@

      Module gedcom.parser

      self.__root_element = RootElement() def invalidate_cache(self): - """Empties the element list and dictionary to cause `gedcom.parser.Parser.get_element_list()` - and `gedcom.parser.Parser.get_element_dictionary()` to return updated data. + """Empties the element list and dictionary to cause + `gedcom.parser.Parser.get_element_list()` and + `gedcom.parser.Parser.get_element_dictionary()` to return updated data. The update gets deferred until each of the methods actually gets called. """ self.__element_list = [] self.__element_dictionary = {} - def get_element_list(self): - """Returns a list containing all elements from within the GEDCOM file + def get_element_list(self) -> List[Element]: + """Returns a list containing all elements from within the GEDCOM file. By default elements are in the same order as they appeared in the file. This list gets generated on-the-fly, but gets cached. If the database - was modified, you should call `gedcom.parser.Parser.invalidate_cache()` once to let this - method return updated data. + was modified, you should call `gedcom.parser.Parser.invalidate_cache()` once + to let this method return updated data. - Consider using `gedcom.parser.Parser.get_root_element()` or `gedcom.parser.Parser.get_root_child_elements()` to access + Consider using `gedcom.parser.Parser.get_root_element()` or + `gedcom.parser.Parser.get_root_child_elements()` to access the hierarchical GEDCOM tree, unless you rarely modify the database. - - :rtype: list of Element """ if not self.__element_list: for element in self.get_root_child_elements(): self.__build_list(element, self.__element_list) return self.__element_list - def get_element_dictionary(self): - """Returns a dictionary containing all elements, identified by a pointer, from within the GEDCOM file + def get_element_dictionary(self) -> dict: + """Returns a dictionary containing all elements, identified by a pointer, + from within the GEDCOM file. Only elements identified by a pointer are listed in the dictionary. The keys for the dictionary are the pointers. @@ -135,46 +165,51 @@

      Module gedcom.parser

      This dictionary gets generated on-the-fly, but gets cached. If the database was modified, you should call `invalidate_cache()` once to let this method return updated data. - - :rtype: dict of Element """ if not self.__element_dictionary: self.__element_dictionary = { - element.get_pointer(): element for element in self.get_root_child_elements() if element.get_pointer() + element.get_pointer(): + element for element in self.get_root_child_elements() if element.get_pointer() } return self.__element_dictionary - def get_root_element(self): - """Returns a virtual root element containing all logical records as children + def get_root_element(self) -> RootElement: + """Returns a virtual root element containing all logical records as children. When printed, this element converts to an empty string. - - :rtype: RootElement """ return self.__root_element - def get_root_child_elements(self): - """Returns a list of logical records in the GEDCOM file + def get_root_child_elements(self) -> List[Element]: + """Returns a list of logical records in the GEDCOM file. By default, elements are in the same order as they appeared in the file. - - :rtype: list of Element """ return self.get_root_element().get_child_elements() - def parse_file(self, file_path, strict=True): - """Opens and parses a file, from the given file path, as GEDCOM 5.5 formatted data - :type file_path: str - :type strict: bool + def parse_file(self, file_path: str, strict: bool = True): + """Opens and parses a file, from the given file path, as GEDCOM formatted data. """ - with open(file_path, 'rb') as gedcom_stream: + codec = get_encoding(file_path) + real_version, reported_version, reported_format = get_version(file_path, codec) + + if reported_version == '5.5.5': + errmsg = "This parser does not properly support the GEDCOM " + reported_version + \ + " standard at this time\nSee: {0}".format(standards.GEDCOM_5_5_5) + raise GedcomVersionUnsupportedError(errmsg) + + if reported_format not in ['LINEAGE-LINKED', 'LINEAGE_LINKED', + 'LINAGE-LINKED', 'Lineage - Linked']: + errmsg = "This parser does not recognize the GEDCOM format " + reported_format + \ + " at this time\nSee: {0}".format(standards.GEDCOM_5_5_5) + raise GedcomFormatUnsupportedError(errmsg) + + with open(file_path, 'r', encoding=codec) as gedcom_stream: self.parse(gedcom_stream, strict) - def parse(self, gedcom_stream, strict=True): - """Parses a stream, or an array of lines, as GEDCOM 5.5 formatted data - :type gedcom_stream: a file stream, or str array of lines with new line at the end - :type strict: bool + def parse(self, gedcom_stream: IO, strict: bool = True): + """Parses a stream, or an array of lines, as GEDCOM formatted data. """ self.invalidate_cache() self.__root_element = RootElement() @@ -183,24 +218,18 @@

      Module gedcom.parser

      last_element = self.get_root_element() for line in gedcom_stream: - last_element = self.__parse_line(line_number, line.decode('utf-8-sig'), last_element, strict) + last_element = self.__parse_line(line_number, line, last_element, strict) line_number += 1 # Private methods @staticmethod - def __parse_line(line_number, line, last_element, strict=True): - """Parse a line from a GEDCOM 5.5 formatted document + def __parse_line(line_number: int, line: str, last_element: Element, + strict: bool = True) -> Element: + """Parse a line from a GEDCOM formatted document. Each line should have the following (bracketed items optional): level + ' ' + [pointer + ' ' +] tag + [' ' + line_value] - - :type line_number: int - :type line: str - :type last_element: Element - :type strict: bool - - :rtype: Element """ # Level must start with non-negative int, no leading zeros. @@ -219,43 +248,43 @@

      Module gedcom.parser

      end_of_line_regex = '([\r\n]{1,2})' # Complete regex - gedcom_line_regex = level_regex + pointer_regex + tag_regex + value_regex + end_of_line_regex + gedcom_line_regex = level_regex + pointer_regex + tag_regex + \ + value_regex + end_of_line_regex regex_match = regex.match(gedcom_line_regex, line) if regex_match is None: if strict: - error_message = ("Line <%d:%s> of document violates GEDCOM format 5.5" % (line_number, line) - + "\nSee: https://chronoplexsoftware.com/gedcomvalidator/gedcom/gedcom-5.5.pdf") - raise GedcomFormatViolationError(error_message) + errmsg = ERROR_TEMPLATE.format(line_number, line, '5.5.1', standards.GEDCOM_5_5_1) + raise GedcomFormatViolationError(errmsg) + + # Quirk check - see if this is a line without a CRLF (which could be the last line) + last_line_regex = level_regex + pointer_regex + tag_regex + value_regex + regex_match = regex.match(last_line_regex, line) + if regex_match is not None: + line_parts = regex_match.groups() + + level = int(line_parts[0]) + pointer = line_parts[1].rstrip(' ') + tag = line_parts[2] + value = line_parts[3][1:] + crlf = '\n' else: - # Quirk check - see if this is a line without a CRLF (which could be the last line) - last_line_regex = level_regex + pointer_regex + tag_regex + value_regex - regex_match = regex.match(last_line_regex, line) - if regex_match is not None: - line_parts = regex_match.groups() - - level = int(line_parts[0]) - pointer = line_parts[1].rstrip(' ') - tag = line_parts[2] - value = line_parts[3][1:] - crlf = '\n' - else: - # Quirk check - Sometimes a gedcom has a text field with a CR. - # This creates a line without the standard level and pointer. - # If this is detected then turn it into a CONC or CONT. - line_regex = '([^\n\r]*|)' - cont_line_regex = line_regex + end_of_line_regex - regex_match = regex.match(cont_line_regex, line) - line_parts = regex_match.groups() - level = last_element.get_level() - tag = last_element.get_tag() - pointer = None - value = line_parts[0][1:] - crlf = line_parts[1] - if tag != gedcom.tags.GEDCOM_TAG_CONTINUED and tag != gedcom.tags.GEDCOM_TAG_CONCATENATION: - # Increment level and change this line to a CONC - level += 1 - tag = gedcom.tags.GEDCOM_TAG_CONCATENATION + # Quirk check - Sometimes a gedcom has a text field with a CR. + # This creates a line without the standard level and pointer. + # If this is detected then turn it into a CONC or CONT. + line_regex = '([^\n\r]*|)' + cont_line_regex = line_regex + end_of_line_regex + regex_match = regex.match(cont_line_regex, line) + line_parts = regex_match.groups() + level = last_element.get_level() + tag = last_element.get_tag() + pointer = None + value = line_parts[0][1:] + crlf = line_parts[1] + if tag not in [tags.GEDCOM_TAG_CONTINUED, tags.GEDCOM_TAG_CONCATENATION]: + # Increment level and change this line to a CONC + level += 1 + tag = tags.GEDCOM_TAG_CONCATENATION else: line_parts = regex_match.groups() @@ -267,20 +296,14 @@

      Module gedcom.parser

      # Check level: should never be more than one higher than previous line. if level > last_element.get_level() + 1: - error_message = ("Line %d of document violates GEDCOM format 5.5" % line_number - + "\nLines must be no more than one level higher than previous line." - + "\nSee: https://chronoplexsoftware.com/gedcomvalidator/gedcom/gedcom-5.5.pdf") - raise GedcomFormatViolationError(error_message) + errmsg = "Line {0} of document violates GEDCOM format 5.5.1\n".format(line_number) + \ + "Lines must be no more than one level higher than previous line.\n" + \ + "See: {0}".format(standards.GEDCOM_5_5_1) + raise GedcomFormatViolationError(errmsg) # Create element. Store in list and dict, create children and parents. - if tag == gedcom.tags.GEDCOM_TAG_INDIVIDUAL: - element = IndividualElement(level, pointer, tag, value, crlf, multi_line=False) - elif tag == gedcom.tags.GEDCOM_TAG_FAMILY: - element = FamilyElement(level, pointer, tag, value, crlf, multi_line=False) - elif tag == gedcom.tags.GEDCOM_TAG_FILE: - element = FileElement(level, pointer, tag, value, crlf, multi_line=False) - elif tag == gedcom.tags.GEDCOM_TAG_OBJECT: - element = ObjectElement(level, pointer, tag, value, crlf, multi_line=False) + if tag in RECORD_ELEMENTS: + element = RECORD_ELEMENTS[tag](level, pointer, tag, value, crlf, multi_line=False) else: element = Element(level, pointer, tag, value, crlf, multi_line=False) @@ -295,10 +318,8 @@

      Module gedcom.parser

      return element - def __build_list(self, element, element_list): - """Recursively add elements to a list containing elements - :type element: Element - :type element_list: list of Element + def __build_list(self, element: Element, element_list: List[Element]): + """Recursively add elements to a list containing elements. """ element_list.append(element) for child in element.get_child_elements(): @@ -306,81 +327,74 @@

      Module gedcom.parser

      # Methods for analyzing individuals and relationships between individuals - def get_marriages(self, individual): - """Returns a list of marriages of an individual formatted as a tuple (`str` date, `str` place) - :type individual: IndividualElement - :rtype: tuple + def get_marriages(self, individual: IndividualElement) -> Tuple[str, str]: + """Returns a list of marriages of an individual formatted as a tuple: + (`str` date, `str` place) """ marriages = [] if not isinstance(individual, IndividualElement): raise NotAnActualIndividualError( - "Operation only valid for elements with %s tag" % gedcom.tags.GEDCOM_TAG_INDIVIDUAL + "Operation only valid for elements with %s tag" % tags.GEDCOM_TAG_INDIVIDUAL ) # Get and analyze families where individual is spouse. - families = self.get_families(individual, gedcom.tags.GEDCOM_TAG_FAMILY_SPOUSE) + families = self.get_families(individual, tags.GEDCOM_TAG_FAMILY_SPOUSE) for family in families: for family_data in family.get_child_elements(): - if family_data.get_tag() == gedcom.tags.GEDCOM_TAG_MARRIAGE: + if family_data.get_tag() == tags.GEDCOM_TAG_MARRIAGE: date = '' place = '' for marriage_data in family_data.get_child_elements(): - if marriage_data.get_tag() == gedcom.tags.GEDCOM_TAG_DATE: + if marriage_data.get_tag() == tags.GEDCOM_TAG_DATE: date = marriage_data.get_value() - if marriage_data.get_tag() == gedcom.tags.GEDCOM_TAG_PLACE: + if marriage_data.get_tag() == tags.GEDCOM_TAG_PLACE: place = marriage_data.get_value() marriages.append((date, place)) return marriages - def get_marriage_years(self, individual): - """Returns a list of marriage years (as integers) for an individual - :type individual: IndividualElement - :rtype: list of int + def get_marriage_years(self, individual: IndividualElement) -> List[int]: + """Returns a list of marriage years for an individual. """ dates = [] if not isinstance(individual, IndividualElement): raise NotAnActualIndividualError( - "Operation only valid for elements with %s tag" % gedcom.tags.GEDCOM_TAG_INDIVIDUAL + "Operation only valid for elements with %s tag" % tags.GEDCOM_TAG_INDIVIDUAL ) # Get and analyze families where individual is spouse. - families = self.get_families(individual, gedcom.tags.GEDCOM_TAG_FAMILY_SPOUSE) + families = self.get_families(individual, tags.GEDCOM_TAG_FAMILY_SPOUSE) for family in families: for child in family.get_child_elements(): - if child.get_tag() == gedcom.tags.GEDCOM_TAG_MARRIAGE: - for childOfChild in child.get_child_elements(): - if childOfChild.get_tag() == gedcom.tags.GEDCOM_TAG_DATE: - date = childOfChild.get_value().split()[-1] + if child.get_tag() == tags.GEDCOM_TAG_MARRIAGE: + for gchild in child.get_child_elements(): + if gchild.get_tag() == tags.GEDCOM_TAG_DATE: + date = gchild.get_value().split()[-1] try: dates.append(int(date)) except ValueError: pass return dates - def marriage_year_match(self, individual, year): - """Checks if one of the marriage years of an individual matches the supplied year. Year is an integer. - :type individual: IndividualElement - :type year: int - :rtype: bool + def marriage_year_match(self, individual: IndividualElement, year: int) -> bool: + """Checks if one of the marriage years of an individual matches the supplied year. + Year is an integer. """ if not isinstance(individual, IndividualElement): raise NotAnActualIndividualError( - "Operation only valid for elements with %s tag" % gedcom.tags.GEDCOM_TAG_INDIVIDUAL + "Operation only valid for elements with %s tag" % tags.GEDCOM_TAG_INDIVIDUAL ) years = self.get_marriage_years(individual) return year in years - def marriage_range_match(self, individual, from_year, to_year): - """Check if one of the marriage years of an individual is in a given range. Years are integers. - :type individual: IndividualElement - :type from_year: int - :type to_year: int - :rtype: bool + def marriage_range_match(self, individual: IndividualElement, + from_year: int, to_year: int) -> bool: + """Check if one of the marriage years of an individual is in a given range. + Years are integers. """ if not isinstance(individual, IndividualElement): raise NotAnActualIndividualError( - "Operation only valid for elements with %s tag" % gedcom.tags.GEDCOM_TAG_INDIVIDUAL + "Operation only valid for elements with %s tag" % tags.GEDCOM_TAG_INDIVIDUAL ) years = self.get_marriage_years(individual) @@ -389,20 +403,19 @@

      Module gedcom.parser

      return True return False - def get_families(self, individual, family_type=gedcom.tags.GEDCOM_TAG_FAMILY_SPOUSE): - """Return family elements listed for an individual + def get_families(self, individual: IndividualElement, + family_type: str = tags.GEDCOM_TAG_FAMILY_SPOUSE) -> List[FamilyElement]: + """Return family elements listed for an individual. + + Optional argument `family_type` can be used to return specific subsets: - family_type can be `gedcom.tags.GEDCOM_TAG_FAMILY_SPOUSE` (families where the individual is a spouse) or - `gedcom.tags.GEDCOM_TAG_FAMILY_CHILD` (families where the individual is a child). If a value is not - provided, `gedcom.tags.GEDCOM_TAG_FAMILY_SPOUSE` is default value. + `tags.GEDCOM_TAG_FAMILY_SPOUSE`: Default, families where the individual is a spouse. - :type individual: IndividualElement - :type family_type: str - :rtype: list of FamilyElement + `tags.GEDCOM_TAG_FAMILY_CHILD`: Families where the individual is a child. """ if not isinstance(individual, IndividualElement): raise NotAnActualIndividualError( - "Operation only valid for elements with %s tag" % gedcom.tags.GEDCOM_TAG_INDIVIDUAL + "Operation only valid for elements with %s tag" % tags.GEDCOM_TAG_INDIVIDUAL ) families = [] @@ -417,19 +430,19 @@

      Module gedcom.parser

      return families - def get_ancestors(self, individual, ancestor_type="ALL"): - """Return elements corresponding to ancestors of an individual + def get_ancestors(self, individual: IndividualElement, + ancestor_type: str = "ALL") -> List[Element]: + """Return elements corresponding to ancestors of an individual. - Optional `ancestor_type`. Default "ALL" returns all ancestors, "NAT" can be - used to specify only natural (genetic) ancestors. + Optional argument `ancestor_type` can be used to return specific subsets: - :type individual: IndividualElement - :type ancestor_type: str - :rtype: list of Element + "ALL": Default, returns all ancestors. + + "NAT": Return only natural (genetic) ancestors. """ if not isinstance(individual, IndividualElement): raise NotAnActualIndividualError( - "Operation only valid for elements with %s tag" % gedcom.tags.GEDCOM_TAG_INDIVIDUAL + "Operation only valid for elements with %s tag" % tags.GEDCOM_TAG_INDIVIDUAL ) parents = self.get_parents(individual, ancestor_type) @@ -441,49 +454,53 @@

      Module gedcom.parser

      return ancestors - def get_parents(self, individual, parent_type="ALL"): - """Return elements corresponding to parents of an individual + def get_parents(self, individual: IndividualElement, + parent_type: str = "ALL") -> List[IndividualElement]: + """Return elements corresponding to parents of an individual. + + Optional argument `parent_type` can be used to return specific subsets: - Optional parent_type. Default "ALL" returns all parents. "NAT" can be - used to specify only natural (genetic) parents. + "ALL": Default, returns all parents. - :type individual: IndividualElement - :type parent_type: str - :rtype: list of IndividualElement + "NAT": Return only natural (genetic) parents. """ if not isinstance(individual, IndividualElement): raise NotAnActualIndividualError( - "Operation only valid for elements with %s tag" % gedcom.tags.GEDCOM_TAG_INDIVIDUAL + "Operation only valid for elements with %s tag" % tags.GEDCOM_TAG_INDIVIDUAL ) parents = [] - families = self.get_families(individual, gedcom.tags.GEDCOM_TAG_FAMILY_CHILD) + families = self.get_families(individual, tags.GEDCOM_TAG_FAMILY_CHILD) for family in families: if parent_type == "NAT": for family_member in family.get_child_elements(): - if family_member.get_tag() == gedcom.tags.GEDCOM_TAG_CHILD \ + if family_member.get_tag() == tags.GEDCOM_TAG_CHILD \ and family_member.get_value() == individual.get_pointer(): for child in family_member.get_child_elements(): if child.get_value() == "Natural": - if child.get_tag() == gedcom.tags.GEDCOM_PROGRAM_DEFINED_TAG_MREL: - parents += self.get_family_members(family, gedcom.tags.GEDCOM_TAG_WIFE) - elif child.get_tag() == gedcom.tags.GEDCOM_PROGRAM_DEFINED_TAG_FREL: - parents += self.get_family_members(family, gedcom.tags.GEDCOM_TAG_HUSBAND) + if child.get_tag() == tags.GEDCOM_PROGRAM_DEFINED_TAG_MREL: + parents += self.get_family_members(family, + tags.GEDCOM_TAG_WIFE) + elif child.get_tag() == tags.GEDCOM_PROGRAM_DEFINED_TAG_FREL: + parents += self.get_family_members(family, + tags.GEDCOM_TAG_HUSBAND) else: parents += self.get_family_members(family, "PARENTS") return parents - def find_path_to_ancestor(self, descendant, ancestor, path=None): - """Return path from descendant to ancestor + def find_path_to_ancestor(self, descendant: IndividualElement, + ancestor: IndividualElement, path: str = None): + """Return path from descendant to ancestor. :rtype: object """ - if not isinstance(descendant, IndividualElement) and isinstance(ancestor, IndividualElement): + if not isinstance(descendant, IndividualElement) and isinstance(ancestor, + IndividualElement): raise NotAnActualIndividualError( - "Operation only valid for elements with %s tag." % gedcom.tags.GEDCOM_TAG_INDIVIDUAL + "Operation only valid for elements with %s tag." % tags.GEDCOM_TAG_INDIVIDUAL ) if not path: @@ -491,33 +508,34 @@

      Module gedcom.parser

      if path[-1].get_pointer() == ancestor.get_pointer(): return path - else: - parents = self.get_parents(descendant, "NAT") - for parent in parents: - potential_path = self.find_path_to_ancestor(parent, ancestor, path + [parent]) - if potential_path is not None: - return potential_path + + parents = self.get_parents(descendant, "NAT") + for parent in parents: + potential_path = self.find_path_to_ancestor(parent, ancestor, path + [parent]) + if potential_path is not None: + return potential_path return None - def get_family_members(self, family, members_type=FAMILY_MEMBERS_TYPE_ALL): - """Return array of family members: individual, spouse, and children + def get_family_members(self, family: FamilyElement, + members_type: str = FAMILY_MEMBERS_TYPE_ALL) -> List[IndividualElement]: + """Return array of family members: individual, spouse, and children. Optional argument `members_type` can be used to return specific subsets: "FAMILY_MEMBERS_TYPE_ALL": Default, return all members of the family + "FAMILY_MEMBERS_TYPE_PARENTS": Return individuals with "HUSB" and "WIFE" tags (parents) + "FAMILY_MEMBERS_TYPE_HUSBAND": Return individuals with "HUSB" tags (father) + "FAMILY_MEMBERS_TYPE_WIFE": Return individuals with "WIFE" tags (mother) - "FAMILY_MEMBERS_TYPE_CHILDREN": Return individuals with "CHIL" tags (children) - :type family: FamilyElement - :type members_type: str - :rtype: list of IndividualElement + "FAMILY_MEMBERS_TYPE_CHILDREN": Return individuals with "CHIL" tags (children) """ if not isinstance(family, FamilyElement): raise NotAnActualFamilyError( - "Operation only valid for element with %s tag." % gedcom.tags.GEDCOM_TAG_FAMILY + "Operation only valid for element with %s tag." % tags.GEDCOM_TAG_FAMILY ) family_members = [] @@ -525,19 +543,19 @@

      Module gedcom.parser

      for child_element in family.get_child_elements(): # Default is ALL - is_family = (child_element.get_tag() == gedcom.tags.GEDCOM_TAG_HUSBAND - or child_element.get_tag() == gedcom.tags.GEDCOM_TAG_WIFE - or child_element.get_tag() == gedcom.tags.GEDCOM_TAG_CHILD) + is_family = (child_element.get_tag() == tags.GEDCOM_TAG_HUSBAND + or child_element.get_tag() == tags.GEDCOM_TAG_WIFE + or child_element.get_tag() == tags.GEDCOM_TAG_CHILD) if members_type == FAMILY_MEMBERS_TYPE_PARENTS: - is_family = (child_element.get_tag() == gedcom.tags.GEDCOM_TAG_HUSBAND - or child_element.get_tag() == gedcom.tags.GEDCOM_TAG_WIFE) + is_family = (child_element.get_tag() == tags.GEDCOM_TAG_HUSBAND + or child_element.get_tag() == tags.GEDCOM_TAG_WIFE) elif members_type == FAMILY_MEMBERS_TYPE_HUSBAND: - is_family = child_element.get_tag() == gedcom.tags.GEDCOM_TAG_HUSBAND + is_family = child_element.get_tag() == tags.GEDCOM_TAG_HUSBAND elif members_type == FAMILY_MEMBERS_TYPE_WIFE: - is_family = child_element.get_tag() == gedcom.tags.GEDCOM_TAG_WIFE + is_family = child_element.get_tag() == tags.GEDCOM_TAG_WIFE elif members_type == FAMILY_MEMBERS_TYPE_CHILDREN: - is_family = child_element.get_tag() == gedcom.tags.GEDCOM_TAG_CHILD + is_family = child_element.get_tag() == tags.GEDCOM_TAG_CHILD if is_family and child_element.get_value() in element_dictionary: family_members.append(element_dictionary[child_element.get_value()]) @@ -546,9 +564,9 @@

      Module gedcom.parser

      # Other methods - def to_gedcom_string(self, recursive=False): - """Formats all elements and optionally all of the sub-elements into a GEDCOM string - :type recursive: bool + def to_gedcom_string(self, recursive: bool = False) -> str: + """Formats all elements and optionally all of the sub-elements into a + GEDCOM string. """ is_gte_python_3 = version_info[0] >= 3 output = '' if is_gte_python_3 else b'' @@ -562,14 +580,11 @@

      Module gedcom.parser

      return output def print_gedcom(self): - """Write GEDCOM data to stdout""" - from sys import stdout + """Write GEDCOM data to stdout.""" self.save_gedcom(stdout) - def save_gedcom(self, open_file, recursive=True): - """Save GEDCOM data to a file - :type open_file: file - :type recursive: bool + def save_gedcom(self, open_file: IO, recursive: bool = True): + """Save GEDCOM data to a file. """ open_file.write(self.to_gedcom_string(recursive))
      @@ -583,45 +598,28 @@

      Module gedcom.parser

      Classes

      -
      -class GedcomFormatViolationError -(...) -
      -
      -

      Common base class for all non-exit exceptions.

      -
      - -Expand source code - -
      class GedcomFormatViolationError(Exception):
      -    pass
      -
      -

      Ancestors

      -
        -
      • builtins.Exception
      • -
      • builtins.BaseException
      • -
      -
      class Parser
      -

      Parses and manipulates GEDCOM 5.5 format data

      -

      For documentation of the GEDCOM 5.5 format, see: http://homepages.rootsweb.ancestry.com/~pmcbride/gedcom/55gctoc.htm

      +

      Parses and manipulates GEDCOM formatted data.

      +

      For documentation of the different GEDCOM standards see the +links defined in gedcom.standards

      This parser reads and parses a GEDCOM file.

      Elements may be accessed via:

      +
    • a list through Parser.get_element_list()
    • +
    • a dict through Parser.get_element_dictionary()
    • +
    Expand source code -
    class Parser(object):
    -    """Parses and manipulates GEDCOM 5.5 format data
    +
    class Parser():
    +    """Parses and manipulates GEDCOM formatted data.
     
    -    For documentation of the GEDCOM 5.5 format, see: http://homepages.rootsweb.ancestry.com/~pmcbride/gedcom/55gctoc.htm
    +    For documentation of the different GEDCOM standards see the
    +    links defined in `gedcom.standards`
     
         This parser reads and parses a GEDCOM file.
     
    @@ -637,35 +635,36 @@ 

    Ancestors

    self.__root_element = RootElement() def invalidate_cache(self): - """Empties the element list and dictionary to cause `gedcom.parser.Parser.get_element_list()` - and `gedcom.parser.Parser.get_element_dictionary()` to return updated data. + """Empties the element list and dictionary to cause + `gedcom.parser.Parser.get_element_list()` and + `gedcom.parser.Parser.get_element_dictionary()` to return updated data. The update gets deferred until each of the methods actually gets called. """ self.__element_list = [] self.__element_dictionary = {} - def get_element_list(self): - """Returns a list containing all elements from within the GEDCOM file + def get_element_list(self) -> List[Element]: + """Returns a list containing all elements from within the GEDCOM file. By default elements are in the same order as they appeared in the file. This list gets generated on-the-fly, but gets cached. If the database - was modified, you should call `gedcom.parser.Parser.invalidate_cache()` once to let this - method return updated data. + was modified, you should call `gedcom.parser.Parser.invalidate_cache()` once + to let this method return updated data. - Consider using `gedcom.parser.Parser.get_root_element()` or `gedcom.parser.Parser.get_root_child_elements()` to access + Consider using `gedcom.parser.Parser.get_root_element()` or + `gedcom.parser.Parser.get_root_child_elements()` to access the hierarchical GEDCOM tree, unless you rarely modify the database. - - :rtype: list of Element """ if not self.__element_list: for element in self.get_root_child_elements(): self.__build_list(element, self.__element_list) return self.__element_list - def get_element_dictionary(self): - """Returns a dictionary containing all elements, identified by a pointer, from within the GEDCOM file + def get_element_dictionary(self) -> dict: + """Returns a dictionary containing all elements, identified by a pointer, + from within the GEDCOM file. Only elements identified by a pointer are listed in the dictionary. The keys for the dictionary are the pointers. @@ -673,46 +672,51 @@

    Ancestors

    This dictionary gets generated on-the-fly, but gets cached. If the database was modified, you should call `invalidate_cache()` once to let this method return updated data. - - :rtype: dict of Element """ if not self.__element_dictionary: self.__element_dictionary = { - element.get_pointer(): element for element in self.get_root_child_elements() if element.get_pointer() + element.get_pointer(): + element for element in self.get_root_child_elements() if element.get_pointer() } return self.__element_dictionary - def get_root_element(self): - """Returns a virtual root element containing all logical records as children + def get_root_element(self) -> RootElement: + """Returns a virtual root element containing all logical records as children. When printed, this element converts to an empty string. - - :rtype: RootElement """ return self.__root_element - def get_root_child_elements(self): - """Returns a list of logical records in the GEDCOM file + def get_root_child_elements(self) -> List[Element]: + """Returns a list of logical records in the GEDCOM file. By default, elements are in the same order as they appeared in the file. - - :rtype: list of Element """ return self.get_root_element().get_child_elements() - def parse_file(self, file_path, strict=True): - """Opens and parses a file, from the given file path, as GEDCOM 5.5 formatted data - :type file_path: str - :type strict: bool + def parse_file(self, file_path: str, strict: bool = True): + """Opens and parses a file, from the given file path, as GEDCOM formatted data. """ - with open(file_path, 'rb') as gedcom_stream: + codec = get_encoding(file_path) + real_version, reported_version, reported_format = get_version(file_path, codec) + + if reported_version == '5.5.5': + errmsg = "This parser does not properly support the GEDCOM " + reported_version + \ + " standard at this time\nSee: {0}".format(standards.GEDCOM_5_5_5) + raise GedcomVersionUnsupportedError(errmsg) + + if reported_format not in ['LINEAGE-LINKED', 'LINEAGE_LINKED', + 'LINAGE-LINKED', 'Lineage - Linked']: + errmsg = "This parser does not recognize the GEDCOM format " + reported_format + \ + " at this time\nSee: {0}".format(standards.GEDCOM_5_5_5) + raise GedcomFormatUnsupportedError(errmsg) + + with open(file_path, 'r', encoding=codec) as gedcom_stream: self.parse(gedcom_stream, strict) - def parse(self, gedcom_stream, strict=True): - """Parses a stream, or an array of lines, as GEDCOM 5.5 formatted data - :type gedcom_stream: a file stream, or str array of lines with new line at the end - :type strict: bool + def parse(self, gedcom_stream: IO, strict: bool = True): + """Parses a stream, or an array of lines, as GEDCOM formatted data. """ self.invalidate_cache() self.__root_element = RootElement() @@ -721,24 +725,18 @@

    Ancestors

    last_element = self.get_root_element() for line in gedcom_stream: - last_element = self.__parse_line(line_number, line.decode('utf-8-sig'), last_element, strict) + last_element = self.__parse_line(line_number, line, last_element, strict) line_number += 1 # Private methods @staticmethod - def __parse_line(line_number, line, last_element, strict=True): - """Parse a line from a GEDCOM 5.5 formatted document + def __parse_line(line_number: int, line: str, last_element: Element, + strict: bool = True) -> Element: + """Parse a line from a GEDCOM formatted document. Each line should have the following (bracketed items optional): level + ' ' + [pointer + ' ' +] tag + [' ' + line_value] - - :type line_number: int - :type line: str - :type last_element: Element - :type strict: bool - - :rtype: Element """ # Level must start with non-negative int, no leading zeros. @@ -757,43 +755,43 @@

    Ancestors

    end_of_line_regex = '([\r\n]{1,2})' # Complete regex - gedcom_line_regex = level_regex + pointer_regex + tag_regex + value_regex + end_of_line_regex + gedcom_line_regex = level_regex + pointer_regex + tag_regex + \ + value_regex + end_of_line_regex regex_match = regex.match(gedcom_line_regex, line) if regex_match is None: if strict: - error_message = ("Line <%d:%s> of document violates GEDCOM format 5.5" % (line_number, line) - + "\nSee: https://chronoplexsoftware.com/gedcomvalidator/gedcom/gedcom-5.5.pdf") - raise GedcomFormatViolationError(error_message) + errmsg = ERROR_TEMPLATE.format(line_number, line, '5.5.1', standards.GEDCOM_5_5_1) + raise GedcomFormatViolationError(errmsg) + + # Quirk check - see if this is a line without a CRLF (which could be the last line) + last_line_regex = level_regex + pointer_regex + tag_regex + value_regex + regex_match = regex.match(last_line_regex, line) + if regex_match is not None: + line_parts = regex_match.groups() + + level = int(line_parts[0]) + pointer = line_parts[1].rstrip(' ') + tag = line_parts[2] + value = line_parts[3][1:] + crlf = '\n' else: - # Quirk check - see if this is a line without a CRLF (which could be the last line) - last_line_regex = level_regex + pointer_regex + tag_regex + value_regex - regex_match = regex.match(last_line_regex, line) - if regex_match is not None: - line_parts = regex_match.groups() - - level = int(line_parts[0]) - pointer = line_parts[1].rstrip(' ') - tag = line_parts[2] - value = line_parts[3][1:] - crlf = '\n' - else: - # Quirk check - Sometimes a gedcom has a text field with a CR. - # This creates a line without the standard level and pointer. - # If this is detected then turn it into a CONC or CONT. - line_regex = '([^\n\r]*|)' - cont_line_regex = line_regex + end_of_line_regex - regex_match = regex.match(cont_line_regex, line) - line_parts = regex_match.groups() - level = last_element.get_level() - tag = last_element.get_tag() - pointer = None - value = line_parts[0][1:] - crlf = line_parts[1] - if tag != gedcom.tags.GEDCOM_TAG_CONTINUED and tag != gedcom.tags.GEDCOM_TAG_CONCATENATION: - # Increment level and change this line to a CONC - level += 1 - tag = gedcom.tags.GEDCOM_TAG_CONCATENATION + # Quirk check - Sometimes a gedcom has a text field with a CR. + # This creates a line without the standard level and pointer. + # If this is detected then turn it into a CONC or CONT. + line_regex = '([^\n\r]*|)' + cont_line_regex = line_regex + end_of_line_regex + regex_match = regex.match(cont_line_regex, line) + line_parts = regex_match.groups() + level = last_element.get_level() + tag = last_element.get_tag() + pointer = None + value = line_parts[0][1:] + crlf = line_parts[1] + if tag not in [tags.GEDCOM_TAG_CONTINUED, tags.GEDCOM_TAG_CONCATENATION]: + # Increment level and change this line to a CONC + level += 1 + tag = tags.GEDCOM_TAG_CONCATENATION else: line_parts = regex_match.groups() @@ -805,20 +803,14 @@

    Ancestors

    # Check level: should never be more than one higher than previous line. if level > last_element.get_level() + 1: - error_message = ("Line %d of document violates GEDCOM format 5.5" % line_number - + "\nLines must be no more than one level higher than previous line." - + "\nSee: https://chronoplexsoftware.com/gedcomvalidator/gedcom/gedcom-5.5.pdf") - raise GedcomFormatViolationError(error_message) + errmsg = "Line {0} of document violates GEDCOM format 5.5.1\n".format(line_number) + \ + "Lines must be no more than one level higher than previous line.\n" + \ + "See: {0}".format(standards.GEDCOM_5_5_1) + raise GedcomFormatViolationError(errmsg) # Create element. Store in list and dict, create children and parents. - if tag == gedcom.tags.GEDCOM_TAG_INDIVIDUAL: - element = IndividualElement(level, pointer, tag, value, crlf, multi_line=False) - elif tag == gedcom.tags.GEDCOM_TAG_FAMILY: - element = FamilyElement(level, pointer, tag, value, crlf, multi_line=False) - elif tag == gedcom.tags.GEDCOM_TAG_FILE: - element = FileElement(level, pointer, tag, value, crlf, multi_line=False) - elif tag == gedcom.tags.GEDCOM_TAG_OBJECT: - element = ObjectElement(level, pointer, tag, value, crlf, multi_line=False) + if tag in RECORD_ELEMENTS: + element = RECORD_ELEMENTS[tag](level, pointer, tag, value, crlf, multi_line=False) else: element = Element(level, pointer, tag, value, crlf, multi_line=False) @@ -833,10 +825,8 @@

    Ancestors

    return element - def __build_list(self, element, element_list): - """Recursively add elements to a list containing elements - :type element: Element - :type element_list: list of Element + def __build_list(self, element: Element, element_list: List[Element]): + """Recursively add elements to a list containing elements. """ element_list.append(element) for child in element.get_child_elements(): @@ -844,81 +834,74 @@

    Ancestors

    # Methods for analyzing individuals and relationships between individuals - def get_marriages(self, individual): - """Returns a list of marriages of an individual formatted as a tuple (`str` date, `str` place) - :type individual: IndividualElement - :rtype: tuple + def get_marriages(self, individual: IndividualElement) -> Tuple[str, str]: + """Returns a list of marriages of an individual formatted as a tuple: + (`str` date, `str` place) """ marriages = [] if not isinstance(individual, IndividualElement): raise NotAnActualIndividualError( - "Operation only valid for elements with %s tag" % gedcom.tags.GEDCOM_TAG_INDIVIDUAL + "Operation only valid for elements with %s tag" % tags.GEDCOM_TAG_INDIVIDUAL ) # Get and analyze families where individual is spouse. - families = self.get_families(individual, gedcom.tags.GEDCOM_TAG_FAMILY_SPOUSE) + families = self.get_families(individual, tags.GEDCOM_TAG_FAMILY_SPOUSE) for family in families: for family_data in family.get_child_elements(): - if family_data.get_tag() == gedcom.tags.GEDCOM_TAG_MARRIAGE: + if family_data.get_tag() == tags.GEDCOM_TAG_MARRIAGE: date = '' place = '' for marriage_data in family_data.get_child_elements(): - if marriage_data.get_tag() == gedcom.tags.GEDCOM_TAG_DATE: + if marriage_data.get_tag() == tags.GEDCOM_TAG_DATE: date = marriage_data.get_value() - if marriage_data.get_tag() == gedcom.tags.GEDCOM_TAG_PLACE: + if marriage_data.get_tag() == tags.GEDCOM_TAG_PLACE: place = marriage_data.get_value() marriages.append((date, place)) return marriages - def get_marriage_years(self, individual): - """Returns a list of marriage years (as integers) for an individual - :type individual: IndividualElement - :rtype: list of int + def get_marriage_years(self, individual: IndividualElement) -> List[int]: + """Returns a list of marriage years for an individual. """ dates = [] if not isinstance(individual, IndividualElement): raise NotAnActualIndividualError( - "Operation only valid for elements with %s tag" % gedcom.tags.GEDCOM_TAG_INDIVIDUAL + "Operation only valid for elements with %s tag" % tags.GEDCOM_TAG_INDIVIDUAL ) # Get and analyze families where individual is spouse. - families = self.get_families(individual, gedcom.tags.GEDCOM_TAG_FAMILY_SPOUSE) + families = self.get_families(individual, tags.GEDCOM_TAG_FAMILY_SPOUSE) for family in families: for child in family.get_child_elements(): - if child.get_tag() == gedcom.tags.GEDCOM_TAG_MARRIAGE: - for childOfChild in child.get_child_elements(): - if childOfChild.get_tag() == gedcom.tags.GEDCOM_TAG_DATE: - date = childOfChild.get_value().split()[-1] + if child.get_tag() == tags.GEDCOM_TAG_MARRIAGE: + for gchild in child.get_child_elements(): + if gchild.get_tag() == tags.GEDCOM_TAG_DATE: + date = gchild.get_value().split()[-1] try: dates.append(int(date)) except ValueError: pass return dates - def marriage_year_match(self, individual, year): - """Checks if one of the marriage years of an individual matches the supplied year. Year is an integer. - :type individual: IndividualElement - :type year: int - :rtype: bool + def marriage_year_match(self, individual: IndividualElement, year: int) -> bool: + """Checks if one of the marriage years of an individual matches the supplied year. + Year is an integer. """ if not isinstance(individual, IndividualElement): raise NotAnActualIndividualError( - "Operation only valid for elements with %s tag" % gedcom.tags.GEDCOM_TAG_INDIVIDUAL + "Operation only valid for elements with %s tag" % tags.GEDCOM_TAG_INDIVIDUAL ) years = self.get_marriage_years(individual) return year in years - def marriage_range_match(self, individual, from_year, to_year): - """Check if one of the marriage years of an individual is in a given range. Years are integers. - :type individual: IndividualElement - :type from_year: int - :type to_year: int - :rtype: bool + def marriage_range_match(self, individual: IndividualElement, + from_year: int, to_year: int) -> bool: + """Check if one of the marriage years of an individual is in a given range. + Years are integers. """ if not isinstance(individual, IndividualElement): raise NotAnActualIndividualError( - "Operation only valid for elements with %s tag" % gedcom.tags.GEDCOM_TAG_INDIVIDUAL + "Operation only valid for elements with %s tag" % tags.GEDCOM_TAG_INDIVIDUAL ) years = self.get_marriage_years(individual) @@ -927,20 +910,19 @@

    Ancestors

    return True return False - def get_families(self, individual, family_type=gedcom.tags.GEDCOM_TAG_FAMILY_SPOUSE): - """Return family elements listed for an individual + def get_families(self, individual: IndividualElement, + family_type: str = tags.GEDCOM_TAG_FAMILY_SPOUSE) -> List[FamilyElement]: + """Return family elements listed for an individual. - family_type can be `gedcom.tags.GEDCOM_TAG_FAMILY_SPOUSE` (families where the individual is a spouse) or - `gedcom.tags.GEDCOM_TAG_FAMILY_CHILD` (families where the individual is a child). If a value is not - provided, `gedcom.tags.GEDCOM_TAG_FAMILY_SPOUSE` is default value. + Optional argument `family_type` can be used to return specific subsets: - :type individual: IndividualElement - :type family_type: str - :rtype: list of FamilyElement + `tags.GEDCOM_TAG_FAMILY_SPOUSE`: Default, families where the individual is a spouse. + + `tags.GEDCOM_TAG_FAMILY_CHILD`: Families where the individual is a child. """ if not isinstance(individual, IndividualElement): raise NotAnActualIndividualError( - "Operation only valid for elements with %s tag" % gedcom.tags.GEDCOM_TAG_INDIVIDUAL + "Operation only valid for elements with %s tag" % tags.GEDCOM_TAG_INDIVIDUAL ) families = [] @@ -955,19 +937,19 @@

    Ancestors

    return families - def get_ancestors(self, individual, ancestor_type="ALL"): - """Return elements corresponding to ancestors of an individual + def get_ancestors(self, individual: IndividualElement, + ancestor_type: str = "ALL") -> List[Element]: + """Return elements corresponding to ancestors of an individual. + + Optional argument `ancestor_type` can be used to return specific subsets: - Optional `ancestor_type`. Default "ALL" returns all ancestors, "NAT" can be - used to specify only natural (genetic) ancestors. + "ALL": Default, returns all ancestors. - :type individual: IndividualElement - :type ancestor_type: str - :rtype: list of Element + "NAT": Return only natural (genetic) ancestors. """ if not isinstance(individual, IndividualElement): raise NotAnActualIndividualError( - "Operation only valid for elements with %s tag" % gedcom.tags.GEDCOM_TAG_INDIVIDUAL + "Operation only valid for elements with %s tag" % tags.GEDCOM_TAG_INDIVIDUAL ) parents = self.get_parents(individual, ancestor_type) @@ -979,49 +961,53 @@

    Ancestors

    return ancestors - def get_parents(self, individual, parent_type="ALL"): - """Return elements corresponding to parents of an individual + def get_parents(self, individual: IndividualElement, + parent_type: str = "ALL") -> List[IndividualElement]: + """Return elements corresponding to parents of an individual. + + Optional argument `parent_type` can be used to return specific subsets: - Optional parent_type. Default "ALL" returns all parents. "NAT" can be - used to specify only natural (genetic) parents. + "ALL": Default, returns all parents. - :type individual: IndividualElement - :type parent_type: str - :rtype: list of IndividualElement + "NAT": Return only natural (genetic) parents. """ if not isinstance(individual, IndividualElement): raise NotAnActualIndividualError( - "Operation only valid for elements with %s tag" % gedcom.tags.GEDCOM_TAG_INDIVIDUAL + "Operation only valid for elements with %s tag" % tags.GEDCOM_TAG_INDIVIDUAL ) parents = [] - families = self.get_families(individual, gedcom.tags.GEDCOM_TAG_FAMILY_CHILD) + families = self.get_families(individual, tags.GEDCOM_TAG_FAMILY_CHILD) for family in families: if parent_type == "NAT": for family_member in family.get_child_elements(): - if family_member.get_tag() == gedcom.tags.GEDCOM_TAG_CHILD \ + if family_member.get_tag() == tags.GEDCOM_TAG_CHILD \ and family_member.get_value() == individual.get_pointer(): for child in family_member.get_child_elements(): if child.get_value() == "Natural": - if child.get_tag() == gedcom.tags.GEDCOM_PROGRAM_DEFINED_TAG_MREL: - parents += self.get_family_members(family, gedcom.tags.GEDCOM_TAG_WIFE) - elif child.get_tag() == gedcom.tags.GEDCOM_PROGRAM_DEFINED_TAG_FREL: - parents += self.get_family_members(family, gedcom.tags.GEDCOM_TAG_HUSBAND) + if child.get_tag() == tags.GEDCOM_PROGRAM_DEFINED_TAG_MREL: + parents += self.get_family_members(family, + tags.GEDCOM_TAG_WIFE) + elif child.get_tag() == tags.GEDCOM_PROGRAM_DEFINED_TAG_FREL: + parents += self.get_family_members(family, + tags.GEDCOM_TAG_HUSBAND) else: parents += self.get_family_members(family, "PARENTS") return parents - def find_path_to_ancestor(self, descendant, ancestor, path=None): - """Return path from descendant to ancestor + def find_path_to_ancestor(self, descendant: IndividualElement, + ancestor: IndividualElement, path: str = None): + """Return path from descendant to ancestor. :rtype: object """ - if not isinstance(descendant, IndividualElement) and isinstance(ancestor, IndividualElement): + if not isinstance(descendant, IndividualElement) and isinstance(ancestor, + IndividualElement): raise NotAnActualIndividualError( - "Operation only valid for elements with %s tag." % gedcom.tags.GEDCOM_TAG_INDIVIDUAL + "Operation only valid for elements with %s tag." % tags.GEDCOM_TAG_INDIVIDUAL ) if not path: @@ -1029,33 +1015,34 @@

    Ancestors

    if path[-1].get_pointer() == ancestor.get_pointer(): return path - else: - parents = self.get_parents(descendant, "NAT") - for parent in parents: - potential_path = self.find_path_to_ancestor(parent, ancestor, path + [parent]) - if potential_path is not None: - return potential_path + + parents = self.get_parents(descendant, "NAT") + for parent in parents: + potential_path = self.find_path_to_ancestor(parent, ancestor, path + [parent]) + if potential_path is not None: + return potential_path return None - def get_family_members(self, family, members_type=FAMILY_MEMBERS_TYPE_ALL): - """Return array of family members: individual, spouse, and children + def get_family_members(self, family: FamilyElement, + members_type: str = FAMILY_MEMBERS_TYPE_ALL) -> List[IndividualElement]: + """Return array of family members: individual, spouse, and children. Optional argument `members_type` can be used to return specific subsets: "FAMILY_MEMBERS_TYPE_ALL": Default, return all members of the family + "FAMILY_MEMBERS_TYPE_PARENTS": Return individuals with "HUSB" and "WIFE" tags (parents) + "FAMILY_MEMBERS_TYPE_HUSBAND": Return individuals with "HUSB" tags (father) + "FAMILY_MEMBERS_TYPE_WIFE": Return individuals with "WIFE" tags (mother) - "FAMILY_MEMBERS_TYPE_CHILDREN": Return individuals with "CHIL" tags (children) - :type family: FamilyElement - :type members_type: str - :rtype: list of IndividualElement + "FAMILY_MEMBERS_TYPE_CHILDREN": Return individuals with "CHIL" tags (children) """ if not isinstance(family, FamilyElement): raise NotAnActualFamilyError( - "Operation only valid for element with %s tag." % gedcom.tags.GEDCOM_TAG_FAMILY + "Operation only valid for element with %s tag." % tags.GEDCOM_TAG_FAMILY ) family_members = [] @@ -1063,19 +1050,19 @@

    Ancestors

    for child_element in family.get_child_elements(): # Default is ALL - is_family = (child_element.get_tag() == gedcom.tags.GEDCOM_TAG_HUSBAND - or child_element.get_tag() == gedcom.tags.GEDCOM_TAG_WIFE - or child_element.get_tag() == gedcom.tags.GEDCOM_TAG_CHILD) + is_family = (child_element.get_tag() == tags.GEDCOM_TAG_HUSBAND + or child_element.get_tag() == tags.GEDCOM_TAG_WIFE + or child_element.get_tag() == tags.GEDCOM_TAG_CHILD) if members_type == FAMILY_MEMBERS_TYPE_PARENTS: - is_family = (child_element.get_tag() == gedcom.tags.GEDCOM_TAG_HUSBAND - or child_element.get_tag() == gedcom.tags.GEDCOM_TAG_WIFE) + is_family = (child_element.get_tag() == tags.GEDCOM_TAG_HUSBAND + or child_element.get_tag() == tags.GEDCOM_TAG_WIFE) elif members_type == FAMILY_MEMBERS_TYPE_HUSBAND: - is_family = child_element.get_tag() == gedcom.tags.GEDCOM_TAG_HUSBAND + is_family = child_element.get_tag() == tags.GEDCOM_TAG_HUSBAND elif members_type == FAMILY_MEMBERS_TYPE_WIFE: - is_family = child_element.get_tag() == gedcom.tags.GEDCOM_TAG_WIFE + is_family = child_element.get_tag() == tags.GEDCOM_TAG_WIFE elif members_type == FAMILY_MEMBERS_TYPE_CHILDREN: - is_family = child_element.get_tag() == gedcom.tags.GEDCOM_TAG_CHILD + is_family = child_element.get_tag() == tags.GEDCOM_TAG_CHILD if is_family and child_element.get_value() in element_dictionary: family_members.append(element_dictionary[child_element.get_value()]) @@ -1084,9 +1071,9 @@

    Ancestors

    # Other methods - def to_gedcom_string(self, recursive=False): - """Formats all elements and optionally all of the sub-elements into a GEDCOM string - :type recursive: bool + def to_gedcom_string(self, recursive: bool = False) -> str: + """Formats all elements and optionally all of the sub-elements into a + GEDCOM string. """ is_gte_python_3 = version_info[0] >= 3 output = '' if is_gte_python_3 else b'' @@ -1100,36 +1087,39 @@

    Ancestors

    return output def print_gedcom(self): - """Write GEDCOM data to stdout""" - from sys import stdout + """Write GEDCOM data to stdout.""" self.save_gedcom(stdout) - def save_gedcom(self, open_file, recursive=True): - """Save GEDCOM data to a file - :type open_file: file - :type recursive: bool + def save_gedcom(self, open_file: IO, recursive: bool = True): + """Save GEDCOM data to a file. """ open_file.write(self.to_gedcom_string(recursive))
    +

    Subclasses

    +

    Methods

    -def find_path_to_ancestor(self, descendant, ancestor, path=None) +def find_path_to_ancestor(self, descendant: IndividualElement, ancestor: IndividualElement, path: str = None)
    -

    Return path from descendant to ancestor -:rtype: object

    +

    Return path from descendant to ancestor. +:rtype: object

    Expand source code -
    def find_path_to_ancestor(self, descendant, ancestor, path=None):
    -    """Return path from descendant to ancestor
    +
    def find_path_to_ancestor(self, descendant: IndividualElement,
    +                          ancestor: IndividualElement, path: str = None):
    +    """Return path from descendant to ancestor.
         :rtype: object
         """
    -    if not isinstance(descendant, IndividualElement) and isinstance(ancestor, IndividualElement):
    +    if not isinstance(descendant, IndividualElement) and isinstance(ancestor,
    +                                                                    IndividualElement):
             raise NotAnActualIndividualError(
    -            "Operation only valid for elements with %s tag." % gedcom.tags.GEDCOM_TAG_INDIVIDUAL
    +            "Operation only valid for elements with %s tag." % tags.GEDCOM_TAG_INDIVIDUAL
             )
     
         if not path:
    @@ -1137,43 +1127,41 @@ 

    Methods

    if path[-1].get_pointer() == ancestor.get_pointer(): return path - else: - parents = self.get_parents(descendant, "NAT") - for parent in parents: - potential_path = self.find_path_to_ancestor(parent, ancestor, path + [parent]) - if potential_path is not None: - return potential_path + + parents = self.get_parents(descendant, "NAT") + for parent in parents: + potential_path = self.find_path_to_ancestor(parent, ancestor, path + [parent]) + if potential_path is not None: + return potential_path return None
    -def get_ancestors(self, individual, ancestor_type='ALL') +def get_ancestors(self, individual: IndividualElement, ancestor_type: str = 'ALL') -> List[Element]
    -

    Return elements corresponding to ancestors of an individual

    -

    Optional ancestor_type. Default "ALL" returns all ancestors, "NAT" can be -used to specify only natural (genetic) ancestors.

    -

    :type individual: IndividualElement -:type ancestor_type: str -:rtype: list of Element

    +

    Return elements corresponding to ancestors of an individual.

    +

    Optional argument ancestor_type can be used to return specific subsets:

    +

    "ALL": Default, returns all ancestors.

    +

    "NAT": Return only natural (genetic) ancestors.

    Expand source code -
    def get_ancestors(self, individual, ancestor_type="ALL"):
    -    """Return elements corresponding to ancestors of an individual
    +
    def get_ancestors(self, individual: IndividualElement,
    +                  ancestor_type: str = "ALL") -> List[Element]:
    +    """Return elements corresponding to ancestors of an individual.
    +
    +    Optional argument `ancestor_type` can be used to return specific subsets:
     
    -    Optional `ancestor_type`. Default "ALL" returns all ancestors, "NAT" can be
    -    used to specify only natural (genetic) ancestors.
    +    "ALL": Default, returns all ancestors.
     
    -    :type individual: IndividualElement
    -    :type ancestor_type: str
    -    :rtype: list of Element
    +    "NAT": Return only natural (genetic) ancestors.
         """
         if not isinstance(individual, IndividualElement):
             raise NotAnActualIndividualError(
    -            "Operation only valid for elements with %s tag" % gedcom.tags.GEDCOM_TAG_INDIVIDUAL
    +            "Operation only valid for elements with %s tag" % tags.GEDCOM_TAG_INDIVIDUAL
             )
     
         parents = self.get_parents(individual, ancestor_type)
    @@ -1187,22 +1175,23 @@ 

    Methods

    -def get_element_dictionary(self) +def get_element_dictionary(self) -> dict
    -

    Returns a dictionary containing all elements, identified by a pointer, from within the GEDCOM file

    +

    Returns a dictionary containing all elements, identified by a pointer, +from within the GEDCOM file.

    Only elements identified by a pointer are listed in the dictionary. The keys for the dictionary are the pointers.

    This dictionary gets generated on-the-fly, but gets cached. If the database was modified, you should call invalidate_cache() once to let -this method return updated data.

    -

    :rtype: dict of Element

    +this method return updated data.

    Expand source code -
    def get_element_dictionary(self):
    -    """Returns a dictionary containing all elements, identified by a pointer, from within the GEDCOM file
    +
    def get_element_dictionary(self) -> dict:
    +    """Returns a dictionary containing all elements, identified by a pointer,
    +    from within the GEDCOM file.
     
         Only elements identified by a pointer are listed in the dictionary.
         The keys for the dictionary are the pointers.
    @@ -1210,46 +1199,44 @@ 

    Methods

    This dictionary gets generated on-the-fly, but gets cached. If the database was modified, you should call `invalidate_cache()` once to let this method return updated data. - - :rtype: dict of Element """ if not self.__element_dictionary: self.__element_dictionary = { - element.get_pointer(): element for element in self.get_root_child_elements() if element.get_pointer() + element.get_pointer(): + element for element in self.get_root_child_elements() if element.get_pointer() } return self.__element_dictionary
    -def get_element_list(self) +def get_element_list(self) -> List[Element]
    -

    Returns a list containing all elements from within the GEDCOM file

    +

    Returns a list containing all elements from within the GEDCOM file.

    By default elements are in the same order as they appeared in the file.

    This list gets generated on-the-fly, but gets cached. If the database -was modified, you should call Parser.invalidate_cache() once to let this -method return updated data.

    -

    Consider using Parser.get_root_element() or Parser.get_root_child_elements() to access -the hierarchical GEDCOM tree, unless you rarely modify the database.

    -

    :rtype: list of Element

    +was modified, you should call Parser.invalidate_cache() once +to let this method return updated data.

    +

    Consider using Parser.get_root_element() or +Parser.get_root_child_elements() to access +the hierarchical GEDCOM tree, unless you rarely modify the database.

    Expand source code -
    def get_element_list(self):
    -    """Returns a list containing all elements from within the GEDCOM file
    +
    def get_element_list(self) -> List[Element]:
    +    """Returns a list containing all elements from within the GEDCOM file.
     
         By default elements are in the same order as they appeared in the file.
     
         This list gets generated on-the-fly, but gets cached. If the database
    -    was modified, you should call `gedcom.parser.Parser.invalidate_cache()` once to let this
    -    method return updated data.
    +    was modified, you should call `gedcom.parser.Parser.invalidate_cache()` once
    +    to let this method return updated data.
     
    -    Consider using `gedcom.parser.Parser.get_root_element()` or `gedcom.parser.Parser.get_root_child_elements()` to access
    +    Consider using `gedcom.parser.Parser.get_root_element()` or
    +    `gedcom.parser.Parser.get_root_child_elements()` to access
         the hierarchical GEDCOM tree, unless you rarely modify the database.
    -
    -    :rtype: list of Element
         """
         if not self.__element_list:
             for element in self.get_root_child_elements():
    @@ -1258,34 +1245,30 @@ 

    Methods

    -def get_families(self, individual, family_type='FAMS') +def get_families(self, individual: IndividualElement, family_type: str = 'FAMS') -> List[FamilyElement]
    -

    Return family elements listed for an individual

    -

    family_type can be GEDCOM_TAG_FAMILY_SPOUSE (families where the individual is a spouse) or -GEDCOM_TAG_FAMILY_CHILD (families where the individual is a child). If a value is not -provided, GEDCOM_TAG_FAMILY_SPOUSE is default value.

    -

    :type individual: IndividualElement -:type family_type: str -:rtype: list of FamilyElement

    +

    Return family elements listed for an individual.

    +

    Optional argument family_type can be used to return specific subsets:

    +

    tags.GEDCOM_TAG_FAMILY_SPOUSE: Default, families where the individual is a spouse.

    +

    tags.GEDCOM_TAG_FAMILY_CHILD: Families where the individual is a child.

    Expand source code -
    def get_families(self, individual, family_type=gedcom.tags.GEDCOM_TAG_FAMILY_SPOUSE):
    -    """Return family elements listed for an individual
    +
    def get_families(self, individual: IndividualElement,
    +                 family_type: str = tags.GEDCOM_TAG_FAMILY_SPOUSE) -> List[FamilyElement]:
    +    """Return family elements listed for an individual.
    +
    +    Optional argument `family_type` can be used to return specific subsets:
     
    -    family_type can be `gedcom.tags.GEDCOM_TAG_FAMILY_SPOUSE` (families where the individual is a spouse) or
    -    `gedcom.tags.GEDCOM_TAG_FAMILY_CHILD` (families where the individual is a child). If a value is not
    -    provided, `gedcom.tags.GEDCOM_TAG_FAMILY_SPOUSE` is default value.
    +    `tags.GEDCOM_TAG_FAMILY_SPOUSE`: Default, families where the individual is a spouse.
     
    -    :type individual: IndividualElement
    -    :type family_type: str
    -    :rtype: list of FamilyElement
    +    `tags.GEDCOM_TAG_FAMILY_CHILD`: Families where the individual is a child.
         """
         if not isinstance(individual, IndividualElement):
             raise NotAnActualIndividualError(
    -            "Operation only valid for elements with %s tag" % gedcom.tags.GEDCOM_TAG_INDIVIDUAL
    +            "Operation only valid for elements with %s tag" % tags.GEDCOM_TAG_INDIVIDUAL
             )
     
         families = []
    @@ -1302,41 +1285,39 @@ 

    Methods

    -def get_family_members(self, family, members_type='ALL') +def get_family_members(self, family: FamilyElement, members_type: str = 'ALL') -> List[IndividualElement]
    -

    Return array of family members: individual, spouse, and children

    +

    Return array of family members: individual, spouse, and children.

    Optional argument members_type can be used to return specific subsets:

    -

    "FAMILY_MEMBERS_TYPE_ALL": Default, return all members of the family -"FAMILY_MEMBERS_TYPE_PARENTS": Return individuals with "HUSB" and "WIFE" tags (parents) -"FAMILY_MEMBERS_TYPE_HUSBAND": Return individuals with "HUSB" tags (father) -"FAMILY_MEMBERS_TYPE_WIFE": Return individuals with "WIFE" tags (mother) -"FAMILY_MEMBERS_TYPE_CHILDREN": Return individuals with "CHIL" tags (children)

    -

    :type family: FamilyElement -:type members_type: str -:rtype: list of IndividualElement

    +

    "FAMILY_MEMBERS_TYPE_ALL": Default, return all members of the family

    +

    "FAMILY_MEMBERS_TYPE_PARENTS": Return individuals with "HUSB" and "WIFE" tags (parents)

    +

    "FAMILY_MEMBERS_TYPE_HUSBAND": Return individuals with "HUSB" tags (father)

    +

    "FAMILY_MEMBERS_TYPE_WIFE": Return individuals with "WIFE" tags (mother)

    +

    "FAMILY_MEMBERS_TYPE_CHILDREN": Return individuals with "CHIL" tags (children)

    Expand source code -
    def get_family_members(self, family, members_type=FAMILY_MEMBERS_TYPE_ALL):
    -    """Return array of family members: individual, spouse, and children
    +
    def get_family_members(self, family: FamilyElement,
    +                       members_type: str = FAMILY_MEMBERS_TYPE_ALL) -> List[IndividualElement]:
    +    """Return array of family members: individual, spouse, and children.
     
         Optional argument `members_type` can be used to return specific subsets:
     
         "FAMILY_MEMBERS_TYPE_ALL": Default, return all members of the family
    +
         "FAMILY_MEMBERS_TYPE_PARENTS": Return individuals with "HUSB" and "WIFE" tags (parents)
    +
         "FAMILY_MEMBERS_TYPE_HUSBAND": Return individuals with "HUSB" tags (father)
    +
         "FAMILY_MEMBERS_TYPE_WIFE": Return individuals with "WIFE" tags (mother)
    -    "FAMILY_MEMBERS_TYPE_CHILDREN": Return individuals with "CHIL" tags (children)
     
    -    :type family: FamilyElement
    -    :type members_type: str
    -    :rtype: list of IndividualElement
    +    "FAMILY_MEMBERS_TYPE_CHILDREN": Return individuals with "CHIL" tags (children)
         """
         if not isinstance(family, FamilyElement):
             raise NotAnActualFamilyError(
    -            "Operation only valid for element with %s tag." % gedcom.tags.GEDCOM_TAG_FAMILY
    +            "Operation only valid for element with %s tag." % tags.GEDCOM_TAG_FAMILY
             )
     
         family_members = []
    @@ -1344,19 +1325,19 @@ 

    Methods

    for child_element in family.get_child_elements(): # Default is ALL - is_family = (child_element.get_tag() == gedcom.tags.GEDCOM_TAG_HUSBAND - or child_element.get_tag() == gedcom.tags.GEDCOM_TAG_WIFE - or child_element.get_tag() == gedcom.tags.GEDCOM_TAG_CHILD) + is_family = (child_element.get_tag() == tags.GEDCOM_TAG_HUSBAND + or child_element.get_tag() == tags.GEDCOM_TAG_WIFE + or child_element.get_tag() == tags.GEDCOM_TAG_CHILD) if members_type == FAMILY_MEMBERS_TYPE_PARENTS: - is_family = (child_element.get_tag() == gedcom.tags.GEDCOM_TAG_HUSBAND - or child_element.get_tag() == gedcom.tags.GEDCOM_TAG_WIFE) + is_family = (child_element.get_tag() == tags.GEDCOM_TAG_HUSBAND + or child_element.get_tag() == tags.GEDCOM_TAG_WIFE) elif members_type == FAMILY_MEMBERS_TYPE_HUSBAND: - is_family = child_element.get_tag() == gedcom.tags.GEDCOM_TAG_HUSBAND + is_family = child_element.get_tag() == tags.GEDCOM_TAG_HUSBAND elif members_type == FAMILY_MEMBERS_TYPE_WIFE: - is_family = child_element.get_tag() == gedcom.tags.GEDCOM_TAG_WIFE + is_family = child_element.get_tag() == tags.GEDCOM_TAG_WIFE elif members_type == FAMILY_MEMBERS_TYPE_CHILDREN: - is_family = child_element.get_tag() == gedcom.tags.GEDCOM_TAG_CHILD + is_family = child_element.get_tag() == tags.GEDCOM_TAG_CHILD if is_family and child_element.get_value() in element_dictionary: family_members.append(element_dictionary[child_element.get_value()]) @@ -1365,36 +1346,32 @@

    Methods

    -def get_marriage_years(self, individual) +def get_marriage_years(self, individual: IndividualElement) -> List[int]
    -

    Returns a list of marriage years (as integers) for an individual -:type individual: IndividualElement -:rtype: list of int

    +

    Returns a list of marriage years for an individual.

    Expand source code -
    def get_marriage_years(self, individual):
    -    """Returns a list of marriage years (as integers) for an individual
    -    :type individual: IndividualElement
    -    :rtype: list of int
    +
    def get_marriage_years(self, individual: IndividualElement) -> List[int]:
    +    """Returns a list of marriage years for an individual.
         """
         dates = []
     
         if not isinstance(individual, IndividualElement):
             raise NotAnActualIndividualError(
    -            "Operation only valid for elements with %s tag" % gedcom.tags.GEDCOM_TAG_INDIVIDUAL
    +            "Operation only valid for elements with %s tag" % tags.GEDCOM_TAG_INDIVIDUAL
             )
     
         # Get and analyze families where individual is spouse.
    -    families = self.get_families(individual, gedcom.tags.GEDCOM_TAG_FAMILY_SPOUSE)
    +    families = self.get_families(individual, tags.GEDCOM_TAG_FAMILY_SPOUSE)
         for family in families:
             for child in family.get_child_elements():
    -            if child.get_tag() == gedcom.tags.GEDCOM_TAG_MARRIAGE:
    -                for childOfChild in child.get_child_elements():
    -                    if childOfChild.get_tag() == gedcom.tags.GEDCOM_TAG_DATE:
    -                        date = childOfChild.get_value().split()[-1]
    +            if child.get_tag() == tags.GEDCOM_TAG_MARRIAGE:
    +                for gchild in child.get_child_elements():
    +                    if gchild.get_tag() == tags.GEDCOM_TAG_DATE:
    +                        date = gchild.get_value().split()[-1]
                             try:
                                 dates.append(int(date))
                             except ValueError:
    @@ -1403,87 +1380,85 @@ 

    Methods

    -def get_marriages(self, individual) +def get_marriages(self, individual: IndividualElement) -> Tuple[str, str]
    -

    Returns a list of marriages of an individual formatted as a tuple (str date, str place) -:type individual: IndividualElement -:rtype: tuple

    +

    Returns a list of marriages of an individual formatted as a tuple: +(str date, str place)

    Expand source code -
    def get_marriages(self, individual):
    -    """Returns a list of marriages of an individual formatted as a tuple (`str` date, `str` place)
    -    :type individual: IndividualElement
    -    :rtype: tuple
    +
    def get_marriages(self, individual: IndividualElement) -> Tuple[str, str]:
    +    """Returns a list of marriages of an individual formatted as a tuple:
    +    (`str` date, `str` place)
         """
         marriages = []
         if not isinstance(individual, IndividualElement):
             raise NotAnActualIndividualError(
    -            "Operation only valid for elements with %s tag" % gedcom.tags.GEDCOM_TAG_INDIVIDUAL
    +            "Operation only valid for elements with %s tag" % tags.GEDCOM_TAG_INDIVIDUAL
             )
         # Get and analyze families where individual is spouse.
    -    families = self.get_families(individual, gedcom.tags.GEDCOM_TAG_FAMILY_SPOUSE)
    +    families = self.get_families(individual, tags.GEDCOM_TAG_FAMILY_SPOUSE)
         for family in families:
             for family_data in family.get_child_elements():
    -            if family_data.get_tag() == gedcom.tags.GEDCOM_TAG_MARRIAGE:
    +            if family_data.get_tag() == tags.GEDCOM_TAG_MARRIAGE:
                     date = ''
                     place = ''
                     for marriage_data in family_data.get_child_elements():
    -                    if marriage_data.get_tag() == gedcom.tags.GEDCOM_TAG_DATE:
    +                    if marriage_data.get_tag() == tags.GEDCOM_TAG_DATE:
                             date = marriage_data.get_value()
    -                    if marriage_data.get_tag() == gedcom.tags.GEDCOM_TAG_PLACE:
    +                    if marriage_data.get_tag() == tags.GEDCOM_TAG_PLACE:
                             place = marriage_data.get_value()
                     marriages.append((date, place))
         return marriages
    -def get_parents(self, individual, parent_type='ALL') +def get_parents(self, individual: IndividualElement, parent_type: str = 'ALL') -> List[IndividualElement]
    -

    Return elements corresponding to parents of an individual

    -

    Optional parent_type. Default "ALL" returns all parents. "NAT" can be -used to specify only natural (genetic) parents.

    -

    :type individual: IndividualElement -:type parent_type: str -:rtype: list of IndividualElement

    +

    Return elements corresponding to parents of an individual.

    +

    Optional argument parent_type can be used to return specific subsets:

    +

    "ALL": Default, returns all parents.

    +

    "NAT": Return only natural (genetic) parents.

    Expand source code -
    def get_parents(self, individual, parent_type="ALL"):
    -    """Return elements corresponding to parents of an individual
    +
    def get_parents(self, individual: IndividualElement,
    +                parent_type: str = "ALL") -> List[IndividualElement]:
    +    """Return elements corresponding to parents of an individual.
     
    -    Optional parent_type. Default "ALL" returns all parents. "NAT" can be
    -    used to specify only natural (genetic) parents.
    +    Optional argument `parent_type` can be used to return specific subsets:
     
    -    :type individual: IndividualElement
    -    :type parent_type: str
    -    :rtype: list of IndividualElement
    +    "ALL": Default, returns all parents.
    +
    +    "NAT": Return only natural (genetic) parents.
         """
         if not isinstance(individual, IndividualElement):
             raise NotAnActualIndividualError(
    -            "Operation only valid for elements with %s tag" % gedcom.tags.GEDCOM_TAG_INDIVIDUAL
    +            "Operation only valid for elements with %s tag" % tags.GEDCOM_TAG_INDIVIDUAL
             )
     
         parents = []
    -    families = self.get_families(individual, gedcom.tags.GEDCOM_TAG_FAMILY_CHILD)
    +    families = self.get_families(individual, tags.GEDCOM_TAG_FAMILY_CHILD)
     
         for family in families:
             if parent_type == "NAT":
                 for family_member in family.get_child_elements():
     
    -                if family_member.get_tag() == gedcom.tags.GEDCOM_TAG_CHILD \
    +                if family_member.get_tag() == tags.GEDCOM_TAG_CHILD \
                             and family_member.get_value() == individual.get_pointer():
     
                         for child in family_member.get_child_elements():
                             if child.get_value() == "Natural":
    -                            if child.get_tag() == gedcom.tags.GEDCOM_PROGRAM_DEFINED_TAG_MREL:
    -                                parents += self.get_family_members(family, gedcom.tags.GEDCOM_TAG_WIFE)
    -                            elif child.get_tag() == gedcom.tags.GEDCOM_PROGRAM_DEFINED_TAG_FREL:
    -                                parents += self.get_family_members(family, gedcom.tags.GEDCOM_TAG_HUSBAND)
    +                            if child.get_tag() == tags.GEDCOM_PROGRAM_DEFINED_TAG_MREL:
    +                                parents += self.get_family_members(family,
    +                                                                   tags.GEDCOM_TAG_WIFE)
    +                            elif child.get_tag() == tags.GEDCOM_PROGRAM_DEFINED_TAG_FREL:
    +                                parents += self.get_family_members(family,
    +                                                                   tags.GEDCOM_TAG_HUSBAND)
             else:
                 parents += self.get_family_members(family, "PARENTS")
     
    @@ -1491,43 +1466,37 @@ 

    Methods

    -def get_root_child_elements(self) +def get_root_child_elements(self) -> List[Element]
    -

    Returns a list of logical records in the GEDCOM file

    -

    By default, elements are in the same order as they appeared in the file.

    -

    :rtype: list of Element

    +

    Returns a list of logical records in the GEDCOM file.

    +

    By default, elements are in the same order as they appeared in the file.

    Expand source code -
    def get_root_child_elements(self):
    -    """Returns a list of logical records in the GEDCOM file
    +
    def get_root_child_elements(self) -> List[Element]:
    +    """Returns a list of logical records in the GEDCOM file.
     
         By default, elements are in the same order as they appeared in the file.
    -
    -    :rtype: list of Element
         """
         return self.get_root_element().get_child_elements()
    -def get_root_element(self) +def get_root_element(self) -> RootElement
    -

    Returns a virtual root element containing all logical records as children

    -

    When printed, this element converts to an empty string.

    -

    :rtype: RootElement

    +

    Returns a virtual root element containing all logical records as children.

    +

    When printed, this element converts to an empty string.

    Expand source code -
    def get_root_element(self):
    -    """Returns a virtual root element containing all logical records as children
    +
    def get_root_element(self) -> RootElement:
    +    """Returns a virtual root element containing all logical records as children.
     
         When printed, this element converts to an empty string.
    -
    -    :rtype: RootElement
         """
         return self.__root_element
    @@ -1536,16 +1505,18 @@

    Methods

    def invalidate_cache(self)
    -

    Empties the element list and dictionary to cause Parser.get_element_list() -and Parser.get_element_dictionary() to return updated data.

    -

    The update gets deferred until each of the methods actually gets called.

    +

    Empties the element list and dictionary to cause +Parser.get_element_list() and +Parser.get_element_dictionary() to return updated data.

    +

    The update gets deferred until each of the methods actually gets called.

    Expand source code
    def invalidate_cache(self):
    -    """Empties the element list and dictionary to cause `gedcom.parser.Parser.get_element_list()`
    -    and `gedcom.parser.Parser.get_element_dictionary()` to return updated data.
    +    """Empties the element list and dictionary to cause
    +    `gedcom.parser.Parser.get_element_list()` and
    +    `gedcom.parser.Parser.get_element_dictionary()` to return updated data.
     
         The update gets deferred until each of the methods actually gets called.
         """
    @@ -1554,28 +1525,23 @@ 

    Methods

    -def marriage_range_match(self, individual, from_year, to_year) +def marriage_range_match(self, individual: IndividualElement, from_year: int, to_year: int) -> bool
    -

    Check if one of the marriage years of an individual is in a given range. Years are integers. -:type individual: IndividualElement -:type from_year: int -:type to_year: int -:rtype: bool

    +

    Check if one of the marriage years of an individual is in a given range. +Years are integers.

    Expand source code -
    def marriage_range_match(self, individual, from_year, to_year):
    -    """Check if one of the marriage years of an individual is in a given range. Years are integers.
    -    :type individual: IndividualElement
    -    :type from_year: int
    -    :type to_year: int
    -    :rtype: bool
    +
    def marriage_range_match(self, individual: IndividualElement,
    +                         from_year: int, to_year: int) -> bool:
    +    """Check if one of the marriage years of an individual is in a given range.
    +    Years are integers.
         """
         if not isinstance(individual, IndividualElement):
             raise NotAnActualIndividualError(
    -            "Operation only valid for elements with %s tag" % gedcom.tags.GEDCOM_TAG_INDIVIDUAL
    +            "Operation only valid for elements with %s tag" % tags.GEDCOM_TAG_INDIVIDUAL
             )
     
         years = self.get_marriage_years(individual)
    @@ -1586,26 +1552,22 @@ 

    Methods

    -def marriage_year_match(self, individual, year) +def marriage_year_match(self, individual: IndividualElement, year: int) -> bool
    -

    Checks if one of the marriage years of an individual matches the supplied year. Year is an integer. -:type individual: IndividualElement -:type year: int -:rtype: bool

    +

    Checks if one of the marriage years of an individual matches the supplied year. +Year is an integer.

    Expand source code -
    def marriage_year_match(self, individual, year):
    -    """Checks if one of the marriage years of an individual matches the supplied year. Year is an integer.
    -    :type individual: IndividualElement
    -    :type year: int
    -    :rtype: bool
    +
    def marriage_year_match(self, individual: IndividualElement, year: int) -> bool:
    +    """Checks if one of the marriage years of an individual matches the supplied year.
    +    Year is an integer.
         """
         if not isinstance(individual, IndividualElement):
             raise NotAnActualIndividualError(
    -            "Operation only valid for elements with %s tag" % gedcom.tags.GEDCOM_TAG_INDIVIDUAL
    +            "Operation only valid for elements with %s tag" % tags.GEDCOM_TAG_INDIVIDUAL
             )
     
         years = self.get_marriage_years(individual)
    @@ -1613,20 +1575,16 @@ 

    Methods

    -def parse(self, gedcom_stream, strict=True) +def parse(self, gedcom_stream: IO, strict: bool = True)
    -

    Parses a stream, or an array of lines, as GEDCOM 5.5 formatted data -:type gedcom_stream: a file stream, or str array of lines with new line at the end -:type strict: bool

    +

    Parses a stream, or an array of lines, as GEDCOM formatted data.

    Expand source code -
    def parse(self, gedcom_stream, strict=True):
    -    """Parses a stream, or an array of lines, as GEDCOM 5.5 formatted data
    -    :type gedcom_stream: a file stream, or str array of lines with new line at the end
    -    :type strict: bool
    +
    def parse(self, gedcom_stream: IO, strict: bool = True):
    +    """Parses a stream, or an array of lines, as GEDCOM formatted data.
         """
         self.invalidate_cache()
         self.__root_element = RootElement()
    @@ -1635,27 +1593,37 @@ 

    Methods

    last_element = self.get_root_element() for line in gedcom_stream: - last_element = self.__parse_line(line_number, line.decode('utf-8-sig'), last_element, strict) + last_element = self.__parse_line(line_number, line, last_element, strict) line_number += 1
    -def parse_file(self, file_path, strict=True) +def parse_file(self, file_path: str, strict: bool = True)
    -

    Opens and parses a file, from the given file path, as GEDCOM 5.5 formatted data -:type file_path: str -:type strict: bool

    +

    Opens and parses a file, from the given file path, as GEDCOM formatted data.

    Expand source code -
    def parse_file(self, file_path, strict=True):
    -    """Opens and parses a file, from the given file path, as GEDCOM 5.5 formatted data
    -    :type file_path: str
    -    :type strict: bool
    +
    def parse_file(self, file_path: str, strict: bool = True):
    +    """Opens and parses a file, from the given file path, as GEDCOM formatted data.
         """
    -    with open(file_path, 'rb') as gedcom_stream:
    +    codec = get_encoding(file_path)
    +    real_version, reported_version, reported_format = get_version(file_path, codec)
    +
    +    if reported_version == '5.5.5':
    +        errmsg = "This parser does not properly support the GEDCOM " + reported_version + \
    +            " standard at this time\nSee: {0}".format(standards.GEDCOM_5_5_5)
    +        raise GedcomVersionUnsupportedError(errmsg)
    +
    +    if reported_format not in ['LINEAGE-LINKED', 'LINEAGE_LINKED',
    +                               'LINAGE-LINKED', 'Lineage - Linked']:
    +        errmsg = "This parser does not recognize the GEDCOM format " + reported_format + \
    +            " at this time\nSee: {0}".format(standards.GEDCOM_5_5_5)
    +        raise GedcomFormatUnsupportedError(errmsg)
    +
    +    with open(file_path, 'r', encoding=codec) as gedcom_stream:
             self.parse(gedcom_stream, strict)
    @@ -1663,49 +1631,44 @@

    Methods

    def print_gedcom(self)
    -

    Write GEDCOM data to stdout

    +

    Write GEDCOM data to stdout.

    Expand source code
    def print_gedcom(self):
    -    """Write GEDCOM data to stdout"""
    -    from sys import stdout
    +    """Write GEDCOM data to stdout."""
         self.save_gedcom(stdout)
    -def save_gedcom(self, open_file, recursive=True) +def save_gedcom(self, open_file: IO, recursive: bool = True)
    -

    Save GEDCOM data to a file -:type open_file: file -:type recursive: bool

    +

    Save GEDCOM data to a file.

    Expand source code -
    def save_gedcom(self, open_file, recursive=True):
    -    """Save GEDCOM data to a file
    -    :type open_file: file
    -    :type recursive: bool
    +
    def save_gedcom(self, open_file: IO, recursive: bool = True):
    +    """Save GEDCOM data to a file.
         """
         open_file.write(self.to_gedcom_string(recursive))
    -def to_gedcom_string(self, recursive=False) +def to_gedcom_string(self, recursive: bool = False) -> str
    -

    Formats all elements and optionally all of the sub-elements into a GEDCOM string -:type recursive: bool

    +

    Formats all elements and optionally all of the sub-elements into a +GEDCOM string.

    Expand source code -
    def to_gedcom_string(self, recursive=False):
    -    """Formats all elements and optionally all of the sub-elements into a GEDCOM string
    -    :type recursive: bool
    +
    def to_gedcom_string(self, recursive: bool = False) -> str:
    +    """Formats all elements and optionally all of the sub-elements into a
    +    GEDCOM string.
         """
         is_gte_python_3 = version_info[0] >= 3
         output = '' if is_gte_python_3 else b''
    @@ -1738,9 +1701,6 @@ 

    Index

  • Classes

    • -

      GedcomFormatViolationError

      -
    • -
    • Parser

      • find_path_to_ancestor
      • @@ -1770,7 +1730,7 @@

        Parser diff --git a/docs/gedcom/reader.html b/docs/gedcom/reader.html new file mode 100644 index 0000000..51b5dee --- /dev/null +++ b/docs/gedcom/reader.html @@ -0,0 +1,368 @@ + + + + + + +gedcom.reader API documentation + + + + + + + + + +
        +
        +
        +

        Module gedcom.reader

        +
        +
        +

        Module containing a Reader with higher order methods than the +base Parser for extracting records as structured data.

        +
        + +Expand source code + +
        # -*- coding: utf-8 -*-
        +
        +# Python GEDCOM Parser
        +#
        +# Copyright (C) 2020 Christopher Horn (cdhorn at embarqmail dot com)
        +# Copyright (C) 2018 Damon Brodie (damon.brodie at gmail.com)
        +# Copyright (C) 2018-2019 Nicklas Reincke (contact at reynke.com)
        +# Copyright (C) 2016 Andreas Oberritter
        +# Copyright (C) 2012 Madeleine Price Ball
        +# Copyright (C) 2005 Daniel Zappala (zappala at cs.byu.edu)
        +# Copyright (C) 2005 Brigham Young University
        +#
        +# 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.
        +#
        +# Further information about the license: http://www.gnu.org/licenses/gpl-2.0.html
        +
        +"""
        +Module containing a `gedcom.reader.Reader` with higher order methods than the
        +base `gedcom.parser.Parser` for extracting records as structured data.
        +"""
        +
        +from typing import Union
        +
        +from gedcom.parser import Parser
        +from gedcom.element.header import HeaderElement
        +from gedcom.element.individual import IndividualElement
        +from gedcom.element.family import FamilyElement
        +from gedcom.element.note import NoteElement
        +from gedcom.element.object import ObjectElement
        +from gedcom.element.source import SourceElement
        +from gedcom.element.submission import SubmissionElement
        +from gedcom.element.submitter import SubmitterElement
        +from gedcom.element.repository import RepositoryElement
        +
        +ELEMENT_TYPES = {
        +    'header': HeaderElement,
        +    'individual': IndividualElement,
        +    'family': FamilyElement,
        +    'note': NoteElement,
        +    'media': ObjectElement,
        +    'source': SourceElement,
        +    'submission': SubmissionElement,
        +    'submitter': SubmitterElement,
        +    'repository': RepositoryElement
        +}
        +
        +RECORD_KEYS = {
        +    'header': None,
        +    'individual': 'key_to_individual',
        +    'family': 'key_to_family',
        +    'media': 'key_to_object',
        +    'note': 'key_to_note',
        +    'source': 'key_to_source',
        +    'submission': 'key_to_submission',
        +    'submitter': 'key_to_submitter',
        +    'repository': 'key_to_repository'
        +}
        +
        +
        +class Reader(Parser):
        +    """Simple wrapper around the core `gedcom.parser.Parser` with methods for
        +    extracting parsed records as structured data.
        +    """
        +
        +    def get_records_by_type(self, record_type: str,
        +                            return_output_as_list: bool = True) -> Union[list, dict]:
        +        """Return either a list or dictionary with all of the requested records for the
        +        given `gedcom.records` record type.
        +        """
        +        record_list = []
        +        record_dict = {}
        +
        +        for element in self.get_root_child_elements():
        +            if isinstance(element, ELEMENT_TYPES[record_type]):
        +                record = element.get_record()
        +                if return_output_as_list:
        +                    record_list.append(record)
        +                else:
        +                    if RECORD_KEYS[record_type] is not None:
        +                        record_dict.update({record[RECORD_KEYS[record_type]]: record})
        +                    else:
        +                        record_dict.update({'@HEAD@': record})
        +
        +        if return_output_as_list:
        +            return record_list
        +
        +        return record_dict
        +
        +    def get_all_records(self, return_entries_as_list: bool = True) -> dict:
        +        """Return a dictionary with all of the available records in the GEDCOM broken
        +        down by record type."""
        +        record_dict = {}
        +
        +        for key in RECORD_KEYS:
        +            if return_entries_as_list:
        +                record_dict.update({key: []})
        +            else:
        +                record_dict.update({key: {}})
        +
        +        for element in self.get_root_child_elements():
        +            for key in ELEMENT_TYPES:
        +                if isinstance(element, ELEMENT_TYPES[key]):
        +                    record = element.get_record()
        +                    if return_entries_as_list:
        +                        record_dict[key].append(record)
        +                    else:
        +                        if key != 'header':
        +                            record_dict[key].update({record[RECORD_KEYS[key]]: record})
        +                        else:
        +                            record_dict['header'].update({'@HEAD@': record})
        +
        +        return record_dict
        +
        +
        +
        +
        +
        +
        +
        +
        +
        +

        Classes

        +
        +
        +class Reader +
        +
        +

        Simple wrapper around the core Parser with methods for +extracting parsed records as structured data.

        +
        + +Expand source code + +
        class Reader(Parser):
        +    """Simple wrapper around the core `gedcom.parser.Parser` with methods for
        +    extracting parsed records as structured data.
        +    """
        +
        +    def get_records_by_type(self, record_type: str,
        +                            return_output_as_list: bool = True) -> Union[list, dict]:
        +        """Return either a list or dictionary with all of the requested records for the
        +        given `gedcom.records` record type.
        +        """
        +        record_list = []
        +        record_dict = {}
        +
        +        for element in self.get_root_child_elements():
        +            if isinstance(element, ELEMENT_TYPES[record_type]):
        +                record = element.get_record()
        +                if return_output_as_list:
        +                    record_list.append(record)
        +                else:
        +                    if RECORD_KEYS[record_type] is not None:
        +                        record_dict.update({record[RECORD_KEYS[record_type]]: record})
        +                    else:
        +                        record_dict.update({'@HEAD@': record})
        +
        +        if return_output_as_list:
        +            return record_list
        +
        +        return record_dict
        +
        +    def get_all_records(self, return_entries_as_list: bool = True) -> dict:
        +        """Return a dictionary with all of the available records in the GEDCOM broken
        +        down by record type."""
        +        record_dict = {}
        +
        +        for key in RECORD_KEYS:
        +            if return_entries_as_list:
        +                record_dict.update({key: []})
        +            else:
        +                record_dict.update({key: {}})
        +
        +        for element in self.get_root_child_elements():
        +            for key in ELEMENT_TYPES:
        +                if isinstance(element, ELEMENT_TYPES[key]):
        +                    record = element.get_record()
        +                    if return_entries_as_list:
        +                        record_dict[key].append(record)
        +                    else:
        +                        if key != 'header':
        +                            record_dict[key].update({record[RECORD_KEYS[key]]: record})
        +                        else:
        +                            record_dict['header'].update({'@HEAD@': record})
        +
        +        return record_dict
        +
        +

        Ancestors

        + +

        Methods

        +
        +
        +def get_all_records(self, return_entries_as_list: bool = True) -> dict +
        +
        +

        Return a dictionary with all of the available records in the GEDCOM broken +down by record type.

        +
        + +Expand source code + +
        def get_all_records(self, return_entries_as_list: bool = True) -> dict:
        +    """Return a dictionary with all of the available records in the GEDCOM broken
        +    down by record type."""
        +    record_dict = {}
        +
        +    for key in RECORD_KEYS:
        +        if return_entries_as_list:
        +            record_dict.update({key: []})
        +        else:
        +            record_dict.update({key: {}})
        +
        +    for element in self.get_root_child_elements():
        +        for key in ELEMENT_TYPES:
        +            if isinstance(element, ELEMENT_TYPES[key]):
        +                record = element.get_record()
        +                if return_entries_as_list:
        +                    record_dict[key].append(record)
        +                else:
        +                    if key != 'header':
        +                        record_dict[key].update({record[RECORD_KEYS[key]]: record})
        +                    else:
        +                        record_dict['header'].update({'@HEAD@': record})
        +
        +    return record_dict
        +
        +
        +
        +def get_records_by_type(self, record_type: str, return_output_as_list: bool = True) -> Union[list, dict] +
        +
        +

        Return either a list or dictionary with all of the requested records for the +given gedcom.records record type.

        +
        + +Expand source code + +
        def get_records_by_type(self, record_type: str,
        +                        return_output_as_list: bool = True) -> Union[list, dict]:
        +    """Return either a list or dictionary with all of the requested records for the
        +    given `gedcom.records` record type.
        +    """
        +    record_list = []
        +    record_dict = {}
        +
        +    for element in self.get_root_child_elements():
        +        if isinstance(element, ELEMENT_TYPES[record_type]):
        +            record = element.get_record()
        +            if return_output_as_list:
        +                record_list.append(record)
        +            else:
        +                if RECORD_KEYS[record_type] is not None:
        +                    record_dict.update({record[RECORD_KEYS[record_type]]: record})
        +                else:
        +                    record_dict.update({'@HEAD@': record})
        +
        +    if return_output_as_list:
        +        return record_list
        +
        +    return record_dict
        +
        +
        +
        +

        Inherited members

        + +
        +
        +
        +
        + +
        + + + + + \ No newline at end of file diff --git a/docs/gedcom/records.html b/docs/gedcom/records.html new file mode 100644 index 0000000..b4abd1f --- /dev/null +++ b/docs/gedcom/records.html @@ -0,0 +1,163 @@ + + + + + + +gedcom.records API documentation + + + + + + + + + +
        +
        +
        +

        Module gedcom.records

        +
        +
        +

        Module containing the standard GEDCOM record types recognized by the +GEDCOM Reader.

        +
        + +Expand source code + +
        # -*- coding: utf-8 -*-
        +
        +# Python GEDCOM Parser
        +#
        +# Copyright (C) 2020 Christopher Horn (cdhorn at embarqmail dot com)
        +# Copyright (C) 2018 Damon Brodie (damon.brodie at gmail.com)
        +# Copyright (C) 2018-2019 Nicklas Reincke (contact at reynke.com)
        +# Copyright (C) 2016 Andreas Oberritter
        +# Copyright (C) 2012 Madeleine Price Ball
        +# Copyright (C) 2005 Daniel Zappala (zappala at cs.byu.edu)
        +# Copyright (C) 2005 Brigham Young University
        +#
        +# 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.
        +#
        +# Further information about the license: http://www.gnu.org/licenses/gpl-2.0.html
        +
        +"""Module containing the standard GEDCOM record types recognized by the
        +GEDCOM `gedcom.reader.Reader`."""
        +
        +
        +GEDCOM_RECORD_FAMILY = 'family'
        +"""Identifies the `FAM_RECORD` record type."""
        +
        +GEDCOM_RECORD_HEADER = 'header'
        +"""Identifies the `HEADER` record type."""
        +
        +GEDCOM_RECORD_INDIVIDUAL = 'individual'
        +"""Identifies the `INDIVIDUAL_RECORD` record type."""
        +
        +GEDCOM_RECORD_NOTE = 'note'
        +"""Identifies the `NOTE_RECORD` record type."""
        +
        +GEDCOM_RECORD_SOURCE = 'source'
        +"""Identifies the `SOURCE_RECORD` record type."""
        +
        +GEDCOM_RECORD_REPOSITORY = 'repository'
        +"""Identifies the `REPOSITORY_RECORD` record type."""
        +
        +GEDCOM_RECORD_SUBMISSION = 'submission'
        +"""Identifies the `SUBMISSION_RECORD` record type."""
        +
        +GEDCOM_RECORD_SUBMITTER = 'submitter'
        +"""Identifies the `SUBMITTER_RECORD` record type."""
        +
        +
        +
        +
        +
        +

        Global variables

        +
        +
        var GEDCOM_RECORD_FAMILY
        +
        +

        Identifies the FAM_RECORD record type.

        +
        +
        var GEDCOM_RECORD_HEADER
        +
        +

        Identifies the HEADER record type.

        +
        +
        var GEDCOM_RECORD_INDIVIDUAL
        +
        +

        Identifies the INDIVIDUAL_RECORD record type.

        +
        +
        var GEDCOM_RECORD_NOTE
        +
        +

        Identifies the NOTE_RECORD record type.

        +
        +
        var GEDCOM_RECORD_REPOSITORY
        +
        +

        Identifies the REPOSITORY_RECORD record type.

        +
        +
        var GEDCOM_RECORD_SOURCE
        +
        +

        Identifies the SOURCE_RECORD record type.

        +
        +
        var GEDCOM_RECORD_SUBMISSION
        +
        +

        Identifies the SUBMISSION_RECORD record type.

        +
        +
        var GEDCOM_RECORD_SUBMITTER
        +
        +

        Identifies the SUBMITTER_RECORD record type.

        +
        +
        +
        +
        +
        +
        +
        +
        + +
        + + + + + \ No newline at end of file diff --git a/docs/gedcom/standards.html b/docs/gedcom/standards.html new file mode 100644 index 0000000..59fa416 --- /dev/null +++ b/docs/gedcom/standards.html @@ -0,0 +1,130 @@ + + + + + + +gedcom.standards API documentation + + + + + + + + + +
        +
        +
        +

        Module gedcom.standards

        +
        +
        +

        Module containing links to the documentation for the various GEDCOM standards.

        +
        + +Expand source code + +
        # -*- coding: utf-8 -*-
        +
        +# Python GEDCOM Parser
        +#
        +# Copyright (C) 2020 Christopher Horn (cdhorn at embarqmail dot com)
        +# Copyright (C) 2018 Damon Brodie (damon.brodie at gmail.com)
        +# Copyright (C) 2018-2019 Nicklas Reincke (contact at reynke.com)
        +# Copyright (C) 2016 Andreas Oberritter
        +# Copyright (C) 2012 Madeleine Price Ball
        +# Copyright (C) 2005 Daniel Zappala (zappala at cs.byu.edu)
        +# Copyright (C) 2005 Brigham Young University
        +#
        +# 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.
        +#
        +# Further information about the license: http://www.gnu.org/licenses/gpl-2.0.html
        +
        +"""Module containing links to the documentation for the various GEDCOM standards."""
        +
        +GEDCOM_5_5 = "https://edge.fscdn.org/assets/img/documents/" + \
        +    "gedcom55-82e1509bd8dbe7477e3b500e4f62c240.pdf"
        +"""The official FamilySearch GEDCOM 5.5 Standard."""
        +
        +GEDCOM_5_5_1 = "https://edge.fscdn.org/assets/img/documents/" + \
        +    "ged551-5bac5e57fe88dd37df0e153d9c515335.pdf"
        +"""The official FamilySearch GEDCOM 5.5.1 Standard."""
        +
        +GEDCOM_5_5_1_GEDCOM_L_ADDENDUM = "https://genealogy.net/GEDCOM/" + \
        +    "GEDCOM551%20GEDCOM-L%20Addendum-R1.pdf"
        +"""The GEDCOM-L working group GEDCOM 5.5.1 Addendum."""
        +
        +GEDCOM_5_5_5 = "https://www.gedcom.org/specs/GEDCOM555.zip"
        +"""The gedcom.org GEDCOM 5.5.5 Specification With Annotations."""
        +
        +
        +
        +
        +
        +

        Global variables

        +
        +
        var GEDCOM_5_5
        +
        +

        The official FamilySearch GEDCOM 5.5 Standard.

        +
        +
        var GEDCOM_5_5_1
        +
        +

        The official FamilySearch GEDCOM 5.5.1 Standard.

        +
        +
        var GEDCOM_5_5_1_GEDCOM_L_ADDENDUM
        +
        +

        The GEDCOM-L working group GEDCOM 5.5.1 Addendum.

        +
        +
        var GEDCOM_5_5_5
        +
        +

        The gedcom.org GEDCOM 5.5.5 Specification With Annotations.

        +
        +
        +
        +
        +
        +
        +
        +
        + +
        + + + + + \ No newline at end of file diff --git a/docs/gedcom/subparsers/address_structure.html b/docs/gedcom/subparsers/address_structure.html new file mode 100644 index 0000000..ac9c495 --- /dev/null +++ b/docs/gedcom/subparsers/address_structure.html @@ -0,0 +1,198 @@ + + + + + + +gedcom.subparsers.address_structure API documentation + + + + + + + + + +
        +
        +
        +

        Module gedcom.subparsers.address_structure

        +
        +
        +

        Substructure parser for a ADDRESS_STRUCTURE embedded record.

        +

        This is referenced as part of a larger structure so there is no anchor tag. +The GEDCOM_TAG_ADDRESS tag is at the same level as some of +the other parts of this structure.

        +
        + +Expand source code + +
        # -*- coding: utf-8 -*-
        +
        +# Python GEDCOM Parser
        +#
        +# Copyright (C) 2020 Christopher Horn (cdhorn at embarqmail dot com)
        +#
        +# 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.
        +#
        +# Further information about the license: http://www.gnu.org/licenses/gpl-2.0.html
        +
        +"""
        +Substructure parser for a `ADDRESS_STRUCTURE` embedded record.
        +
        +This is referenced as part of a larger structure so there is no anchor tag.
        +The `gedcom.tags.GEDCOM_TAG_ADDRESS` tag is at the same level as some of
        +the other parts of this structure.
        +"""
        +
        +import gedcom.tags as tags
        +from gedcom.element.element import Element
        +
        +ADDRESS_TAGS = {
        +    tags.GEDCOM_PROGRAM_DEFINED_TAG_ADDRESSE: 'addresse',
        +    tags.GEDCOM_TAG_ADDRESS1: 'address1',
        +    tags.GEDCOM_TAG_ADDRESS2: 'address2',
        +    tags.GEDCOM_TAG_ADDRESS3: 'address3',
        +    tags.GEDCOM_TAG_CITY: 'city',
        +    tags.GEDCOM_TAG_STATE: 'state',
        +    tags.GEDCOM_TAG_POSTAL_CODE: 'postal_code',
        +    tags.GEDCOM_TAG_COUNTRY: 'country'
        +}
        +
        +CONTACT_TAGS = {
        +    tags.GEDCOM_TAG_PHONE: 'phone',
        +    tags.GEDCOM_TAG_EMAIL: 'email',
        +    tags.GEDCOM_TAG_FAX: 'fax',
        +    tags.GEDCOM_TAG_WWW: 'www'
        +}
        +
        +
        +def address_structure(element: Element) -> dict:
        +    """Parses and extracts a `ADDRESS_STRUCTURE` structure.
        +
        +    The `element` should be the parent that contains it.
        +    """
        +    record = {
        +        'address': '',
        +        'addresse': '',
        +        'address1': '',
        +        'address2': '',
        +        'address3': '',
        +        'city': '',
        +        'state': '',
        +        'postal_code': '',
        +        'country': '',
        +        'phone': [],
        +        'email': [],
        +        'fax': [],
        +        'www': []
        +    }
        +    for child in element.get_child_elements():
        +        if child.get_tag() == tags.GEDCOM_TAG_ADDRESS:
        +            record['address'] = child.get_multi_line_value()
        +            for gchild in child.get_child_elements():
        +                if gchild.get_tag() in ADDRESS_TAGS:
        +                    record[ADDRESS_TAGS[gchild.get_tag()]] = gchild.get_value()
        +            continue
        +
        +        if child.get_tag() in CONTACT_TAGS:
        +            record[CONTACT_TAGS[child.get_tag()]].append(child.get_value())
        +
        +    return record
        +
        +
        +
        +
        +
        +
        +
        +

        Functions

        +
        +
        +def address_structure(element: Element) -> dict +
        +
        +

        Parses and extracts a ADDRESS_STRUCTURE structure.

        +

        The element should be the parent that contains it.

        +
        + +Expand source code + +
        def address_structure(element: Element) -> dict:
        +    """Parses and extracts a `ADDRESS_STRUCTURE` structure.
        +
        +    The `element` should be the parent that contains it.
        +    """
        +    record = {
        +        'address': '',
        +        'addresse': '',
        +        'address1': '',
        +        'address2': '',
        +        'address3': '',
        +        'city': '',
        +        'state': '',
        +        'postal_code': '',
        +        'country': '',
        +        'phone': [],
        +        'email': [],
        +        'fax': [],
        +        'www': []
        +    }
        +    for child in element.get_child_elements():
        +        if child.get_tag() == tags.GEDCOM_TAG_ADDRESS:
        +            record['address'] = child.get_multi_line_value()
        +            for gchild in child.get_child_elements():
        +                if gchild.get_tag() in ADDRESS_TAGS:
        +                    record[ADDRESS_TAGS[gchild.get_tag()]] = gchild.get_value()
        +            continue
        +
        +        if child.get_tag() in CONTACT_TAGS:
        +            record[CONTACT_TAGS[child.get_tag()]].append(child.get_value())
        +
        +    return record
        +
        +
        +
        +
        +
        +
        +
        + +
        + + + + + \ No newline at end of file diff --git a/docs/gedcom/subparsers/association_structure.html b/docs/gedcom/subparsers/association_structure.html new file mode 100644 index 0000000..b5ccdcd --- /dev/null +++ b/docs/gedcom/subparsers/association_structure.html @@ -0,0 +1,162 @@ + + + + + + +gedcom.subparsers.association_structure API documentation + + + + + + + + + +
        +
        +
        +

        Module gedcom.subparsers.association_structure

        +
        +
        +

        Substructure parser for the ASSOCIATION_STRUCTURE record.

        +

        This is anchored by the GEDCOM_TAG_ASSOCIATES tag.

        +
        + +Expand source code + +
        # -*- coding: utf-8 -*-
        +
        +# Python GEDCOM Parser
        +#
        +# Copyright (C) 2020 Christopher Horn (cdhorn at embarqmail dot com)
        +#
        +# 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.
        +#
        +# Further information about the license: http://www.gnu.org/licenses/gpl-2.0.html
        +
        +"""
        +Substructure parser for the `ASSOCIATION_STRUCTURE` record.
        +
        +This is anchored by the `gedcom.tags.GEDCOM_TAG_ASSOCIATES` tag.
        +"""
        +
        +import gedcom.tags as tags
        +from gedcom.element.element import Element
        +from gedcom.subparsers.note_structure import note_structure
        +from gedcom.subparsers.source_citation import source_citation
        +
        +
        +def association_structure(element: Element) -> dict:
        +    """Parses and extracts the `ASSOCIATION_STRUCTURE` structure.
        +
        +    The `element` should contain the `gedcom.tags.GEDCOM_TAG_ASSOCIATES` tag.
        +    """
        +    record = {
        +        'key_to_individual': element.get_value(),
        +        'relationship': '',
        +        'citations': [],
        +        'notes': []
        +    }
        +    for child in element.get_child_elements():
        +        if child.get_tag() == tags.GEDCOM_TAG_RELATIONSHIP:
        +            record['relationship'] = child.get_value()
        +            continue
        +
        +        if child.get_tag() == tags.GEDCOM_TAG_NOTE:
        +            record['notes'].append(note_structure(child))
        +            continue
        +
        +        if child.get_tag() == tags.GEDCOM_TAG_SOURCE:
        +            record['citations'].append(source_citation(child))
        +
        +    return record
        +
        +
        +
        +
        +
        +
        +
        +

        Functions

        +
        +
        +def association_structure(element: Element) -> dict +
        +
        +

        Parses and extracts the ASSOCIATION_STRUCTURE structure.

        +

        The element should contain the GEDCOM_TAG_ASSOCIATES tag.

        +
        + +Expand source code + +
        def association_structure(element: Element) -> dict:
        +    """Parses and extracts the `ASSOCIATION_STRUCTURE` structure.
        +
        +    The `element` should contain the `gedcom.tags.GEDCOM_TAG_ASSOCIATES` tag.
        +    """
        +    record = {
        +        'key_to_individual': element.get_value(),
        +        'relationship': '',
        +        'citations': [],
        +        'notes': []
        +    }
        +    for child in element.get_child_elements():
        +        if child.get_tag() == tags.GEDCOM_TAG_RELATIONSHIP:
        +            record['relationship'] = child.get_value()
        +            continue
        +
        +        if child.get_tag() == tags.GEDCOM_TAG_NOTE:
        +            record['notes'].append(note_structure(child))
        +            continue
        +
        +        if child.get_tag() == tags.GEDCOM_TAG_SOURCE:
        +            record['citations'].append(source_citation(child))
        +
        +    return record
        +
        +
        +
        +
        +
        +
        +
        + +
        + + + + + \ No newline at end of file diff --git a/docs/gedcom/subparsers/change_date.html b/docs/gedcom/subparsers/change_date.html new file mode 100644 index 0000000..50e2473 --- /dev/null +++ b/docs/gedcom/subparsers/change_date.html @@ -0,0 +1,159 @@ + + + + + + +gedcom.subparsers.change_date API documentation + + + + + + + + + +
        +
        +
        +

        Module gedcom.subparsers.change_date

        +
        +
        +

        Substructure parser for a CHANGE_DATE record.

        +

        This is anchored by the GEDCOM_TAG_CHANGE tag.

        +
        + +Expand source code + +
        # -*- coding: utf-8 -*-
        +
        +# Python GEDCOM Parser
        +#
        +# Copyright (C) 2020 Christopher Horn (cdhorn at embarqmail dot com)
        +#
        +# 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.
        +#
        +# Further information about the license: http://www.gnu.org/licenses/gpl-2.0.html
        +
        +"""
        +Substructure parser for a `CHANGE_DATE` record.
        +
        +This is anchored by the `gedcom.tags.GEDCOM_TAG_CHANGE` tag.
        +"""
        +
        +import gedcom.tags as tags
        +from gedcom.element.element import Element
        +from gedcom.subparsers.note_structure import note_structure
        +
        +
        +def change_date(element: Element) -> dict:
        +    """Parses and extracts a `CHANGE_DATE` structure.
        +
        +    The `element` should contain the `gedcom.tags.GEDCOM_TAG_CHANGE` tag.
        +    """
        +    record = {
        +        'date': '',
        +        'time': '',
        +        'notes': []
        +    }
        +    for child in element.get_child_elements():
        +        if child.get_tag() == tags.GEDCOM_TAG_DATE:
        +            record['date'] = child.get_value()
        +            for gchild in child.get_child_elements():
        +                if gchild.get_tag() == tags.GEDCOM_TAG_TIME:
        +                    record['time'] = gchild.get_value()
        +                    continue
        +            continue
        +
        +        if child.get_tag() == tags.GEDCOM_TAG_NOTE:
        +            record['notes'].append(note_structure(child))
        +
        +    return record
        +
        +
        +
        +
        +
        +
        +
        +

        Functions

        +
        +
        +def change_date(element: Element) -> dict +
        +
        +

        Parses and extracts a CHANGE_DATE structure.

        +

        The element should contain the GEDCOM_TAG_CHANGE tag.

        +
        + +Expand source code + +
        def change_date(element: Element) -> dict:
        +    """Parses and extracts a `CHANGE_DATE` structure.
        +
        +    The `element` should contain the `gedcom.tags.GEDCOM_TAG_CHANGE` tag.
        +    """
        +    record = {
        +        'date': '',
        +        'time': '',
        +        'notes': []
        +    }
        +    for child in element.get_child_elements():
        +        if child.get_tag() == tags.GEDCOM_TAG_DATE:
        +            record['date'] = child.get_value()
        +            for gchild in child.get_child_elements():
        +                if gchild.get_tag() == tags.GEDCOM_TAG_TIME:
        +                    record['time'] = gchild.get_value()
        +                    continue
        +            continue
        +
        +        if child.get_tag() == tags.GEDCOM_TAG_NOTE:
        +            record['notes'].append(note_structure(child))
        +
        +    return record
        +
        +
        +
        +
        +
        +
        +
        + +
        + + + + + \ No newline at end of file diff --git a/docs/gedcom/subparsers/child_to_family_link.html b/docs/gedcom/subparsers/child_to_family_link.html new file mode 100644 index 0000000..74ad45d --- /dev/null +++ b/docs/gedcom/subparsers/child_to_family_link.html @@ -0,0 +1,161 @@ + + + + + + +gedcom.subparsers.child_to_family_link API documentation + + + + + + + + + +
        +
        +
        +

        Module gedcom.subparsers.child_to_family_link

        +
        +
        +

        Substructure parser for a CHILD_TO_FAMILY_LINK record.

        +

        This is anchored by the GEDCOM_TAG_FAMILY_CHILD tag.

        +
        + +Expand source code + +
        # -*- coding: utf-8 -*-
        +
        +# Python GEDCOM Parser
        +#
        +# Copyright (C) 2020 Christopher Horn (cdhorn at embarqmail dot com)
        +#
        +# 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.
        +#
        +# Further information about the license: http://www.gnu.org/licenses/gpl-2.0.html
        +
        +"""
        +Substructure parser for a `CHILD_TO_FAMILY_LINK` record.
        +
        +This is anchored by the `gedcom.tags.GEDCOM_TAG_FAMILY_CHILD` tag.
        +"""
        +
        +import gedcom.tags as tags
        +from gedcom.element.element import Element
        +from gedcom.subparsers.note_structure import note_structure
        +
        +
        +def child_to_family_link(element: Element) -> dict:
        +    """Parses and extracts a `CHILD_TO_FAMILY_LINK` structure.
        +
        +    The `element` should contain the `gedcom.tags.GEDCOM_TAG_FAMILY_CHILD` tag.
        +    """
        +    record = {
        +        'key_to_family': element.get_value(),
        +        'pedigree': '',
        +        'status': '',
        +        'notes': []
        +    }
        +    for child in element.get_child_elements():
        +        if child.get_tag() == tags.GEDCOM_TAG_PEDIGREE:
        +            record['pedigree'] = child.get_value()
        +            continue
        +
        +        if child.get_tag() == tags.GEDCOM_TAG_STATUS:
        +            record['status'] = child.get_value()
        +            continue
        +
        +        if child.get_tag() == tags.GEDCOM_TAG_NOTE:
        +            record['notes'].append(note_structure(child))
        +
        +    return record
        +
        +
        +
        +
        +
        +
        +
        +

        Functions

        +
        + +
        +

        Parses and extracts a CHILD_TO_FAMILY_LINK structure.

        +

        The element should contain the GEDCOM_TAG_FAMILY_CHILD tag.

        +
        + +Expand source code + +
        def child_to_family_link(element: Element) -> dict:
        +    """Parses and extracts a `CHILD_TO_FAMILY_LINK` structure.
        +
        +    The `element` should contain the `gedcom.tags.GEDCOM_TAG_FAMILY_CHILD` tag.
        +    """
        +    record = {
        +        'key_to_family': element.get_value(),
        +        'pedigree': '',
        +        'status': '',
        +        'notes': []
        +    }
        +    for child in element.get_child_elements():
        +        if child.get_tag() == tags.GEDCOM_TAG_PEDIGREE:
        +            record['pedigree'] = child.get_value()
        +            continue
        +
        +        if child.get_tag() == tags.GEDCOM_TAG_STATUS:
        +            record['status'] = child.get_value()
        +            continue
        +
        +        if child.get_tag() == tags.GEDCOM_TAG_NOTE:
        +            record['notes'].append(note_structure(child))
        +
        +    return record
        +
        +
        +
        +
        +
        +
        +
        + +
        + + + + + \ No newline at end of file diff --git a/docs/gedcom/subparsers/event_detail.html b/docs/gedcom/subparsers/event_detail.html new file mode 100644 index 0000000..6e6e876 --- /dev/null +++ b/docs/gedcom/subparsers/event_detail.html @@ -0,0 +1,212 @@ + + + + + + +gedcom.subparsers.event_detail API documentation + + + + + + + + + +
        +
        +
        +

        Module gedcom.subparsers.event_detail

        +
        +
        +

        Substructure parser for a EVENT_DETAIL embedded record.

        +

        This is referenced as part of a larger structure so there is no anchor tag.

        +
        + +Expand source code + +
        # -*- coding: utf-8 -*-
        +
        +# Python GEDCOM Parser
        +#
        +# Copyright (C) 2020 Christopher Horn (cdhorn at embarqmail dot com)
        +#
        +# 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.
        +#
        +# Further information about the license: http://www.gnu.org/licenses/gpl-2.0.html
        +
        +"""
        +Substructure parser for a `EVENT_DETAIL` embedded record.
        +
        +This is referenced as part of a larger structure so there is no anchor tag.
        +"""
        +
        +import gedcom.tags as tags
        +from gedcom.element.element import Element
        +from gedcom.subparsers.place_structure import place_structure
        +from gedcom.subparsers.address_structure import address_structure
        +from gedcom.subparsers.note_structure import note_structure
        +from gedcom.subparsers.source_citation import source_citation
        +from gedcom.subparsers.multimedia_link import multimedia_link
        +
        +EVENT_TAGS = {
        +    tags.GEDCOM_TAG_TYPE: 'type',
        +    tags.GEDCOM_TAG_DATE: 'date',
        +    tags.GEDCOM_TAG_AGENCY: 'responsible_agency',
        +    tags.GEDCOM_TAG_RELIGION: 'religious_affiliation',
        +    tags.GEDCOM_TAG_CAUSE: 'cause_of_event',
        +    tags.GEDCOM_TAG_RESTRICTION: 'restriction'
        +}
        +
        +
        +def event_detail(element: Element) -> dict:
        +    """Parses and extracts a `EVENT_DETAIL` structure.
        +
        +    The `element` should be the parent that contains it.
        +    """
        +    record = {
        +        'type': '',
        +        'date': '',
        +        'place': {},
        +        'address': {},
        +        'responsible_agency': '',
        +        'religious_affiliation': '',
        +        'cause_of_event': '',
        +        'restriction_notice': '',
        +        'notes': [],
        +        'citations': [],
        +        'media': []
        +    }
        +    for child in element.get_child_elements():
        +        if child.get_tag() in EVENT_TAGS:
        +            record[EVENT_TAGS[child.get_tag()]] = child.get_value()
        +            continue
        +
        +        if child.get_tag() == tags.GEDCOM_TAG_PLACE:
        +            record['place'] = place_structure(child)
        +            continue
        +
        +        if child.get_tag() == tags.GEDCOM_TAG_ADDRESS:
        +            record['address'] = address_structure(element)
        +            continue
        +
        +        if child.get_tag() == tags.GEDCOM_TAG_NOTE:
        +            record['notes'].append(note_structure(child))
        +            continue
        +
        +        if child.get_tag() == tags.GEDCOM_TAG_SOURCE:
        +            record['citations'].append(source_citation(child))
        +            continue
        +
        +        if child.get_tag() == tags.GEDCOM_TAG_OBJECT:
        +            record['media'].append(multimedia_link(child))
        +
        +    return record
        +
        +
        +
        +
        +
        +
        +
        +

        Functions

        +
        +
        +def event_detail(element: Element) -> dict +
        +
        +

        Parses and extracts a EVENT_DETAIL structure.

        +

        The element should be the parent that contains it.

        +
        + +Expand source code + +
        def event_detail(element: Element) -> dict:
        +    """Parses and extracts a `EVENT_DETAIL` structure.
        +
        +    The `element` should be the parent that contains it.
        +    """
        +    record = {
        +        'type': '',
        +        'date': '',
        +        'place': {},
        +        'address': {},
        +        'responsible_agency': '',
        +        'religious_affiliation': '',
        +        'cause_of_event': '',
        +        'restriction_notice': '',
        +        'notes': [],
        +        'citations': [],
        +        'media': []
        +    }
        +    for child in element.get_child_elements():
        +        if child.get_tag() in EVENT_TAGS:
        +            record[EVENT_TAGS[child.get_tag()]] = child.get_value()
        +            continue
        +
        +        if child.get_tag() == tags.GEDCOM_TAG_PLACE:
        +            record['place'] = place_structure(child)
        +            continue
        +
        +        if child.get_tag() == tags.GEDCOM_TAG_ADDRESS:
        +            record['address'] = address_structure(element)
        +            continue
        +
        +        if child.get_tag() == tags.GEDCOM_TAG_NOTE:
        +            record['notes'].append(note_structure(child))
        +            continue
        +
        +        if child.get_tag() == tags.GEDCOM_TAG_SOURCE:
        +            record['citations'].append(source_citation(child))
        +            continue
        +
        +        if child.get_tag() == tags.GEDCOM_TAG_OBJECT:
        +            record['media'].append(multimedia_link(child))
        +
        +    return record
        +
        +
        +
        +
        +
        +
        +
        + +
        + + + + + \ No newline at end of file diff --git a/docs/gedcom/subparsers/family_event_detail.html b/docs/gedcom/subparsers/family_event_detail.html new file mode 100644 index 0000000..51972b5 --- /dev/null +++ b/docs/gedcom/subparsers/family_event_detail.html @@ -0,0 +1,155 @@ + + + + + + +gedcom.subparsers.family_event_detail API documentation + + + + + + + + + +
        +
        +
        +

        Module gedcom.subparsers.family_event_detail

        +
        +
        +

        Substructure parser for a FAMILY_EVENT_DETAIL emdedded record.

        +

        This is referenced as part of a larger structure so there is no anchor tag.

        +
        + +Expand source code + +
        # -*- coding: utf-8 -*-
        +
        +# Python GEDCOM Parser
        +#
        +# Copyright (C) 2020 Christopher Horn (cdhorn at embarqmail dot com)
        +#
        +# 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.
        +#
        +# Further information about the license: http://www.gnu.org/licenses/gpl-2.0.html
        +
        +"""
        +Substructure parser for a `FAMILY_EVENT_DETAIL` emdedded record.
        +
        +This is referenced as part of a larger structure so there is no anchor tag.
        +"""
        +
        +import gedcom.tags as tags
        +from gedcom.element.element import Element
        +from gedcom.subparsers.event_detail import event_detail
        +
        +
        +def family_event_detail(element: Element) -> dict:
        +    """Parses and extracts a `FAMILY_EVENT_DETAIL` structure.
        +
        +    The `element` shouldbe the parent that contains it.
        +    """
        +    record = event_detail(element)
        +    record['husband_age'] = ''
        +    record['wife_age'] = ''
        +    for child in element.get_child_elements():
        +        if child.get_tag() == tags.GEDCOM_TAG_HUSBAND:
        +            for gchild in child.get_child_elements():
        +                if gchild.get_tag() == tags.GEDCOM_TAG_AGE:
        +                    record['husband_age'] = gchild.get_value()
        +            continue
        +
        +        if child.get_tag() == tags.GEDCOM_TAG_WIFE:
        +            for gchild in child.get_child_elements():
        +                if gchild.get_tag() == tags.GEDCOM_TAG_AGE:
        +                    record['wife_age'] = gchild.get_value()
        +
        +    return record
        +
        +
        +
        +
        +
        +
        +
        +

        Functions

        +
        +
        +def family_event_detail(element: Element) -> dict +
        +
        +

        Parses and extracts a FAMILY_EVENT_DETAIL structure.

        +

        The element shouldbe the parent that contains it.

        +
        + +Expand source code + +
        def family_event_detail(element: Element) -> dict:
        +    """Parses and extracts a `FAMILY_EVENT_DETAIL` structure.
        +
        +    The `element` shouldbe the parent that contains it.
        +    """
        +    record = event_detail(element)
        +    record['husband_age'] = ''
        +    record['wife_age'] = ''
        +    for child in element.get_child_elements():
        +        if child.get_tag() == tags.GEDCOM_TAG_HUSBAND:
        +            for gchild in child.get_child_elements():
        +                if gchild.get_tag() == tags.GEDCOM_TAG_AGE:
        +                    record['husband_age'] = gchild.get_value()
        +            continue
        +
        +        if child.get_tag() == tags.GEDCOM_TAG_WIFE:
        +            for gchild in child.get_child_elements():
        +                if gchild.get_tag() == tags.GEDCOM_TAG_AGE:
        +                    record['wife_age'] = gchild.get_value()
        +
        +    return record
        +
        +
        +
        +
        +
        +
        +
        + +
        + + + + + \ No newline at end of file diff --git a/docs/gedcom/subparsers/family_event_structure.html b/docs/gedcom/subparsers/family_event_structure.html new file mode 100644 index 0000000..972cff6 --- /dev/null +++ b/docs/gedcom/subparsers/family_event_structure.html @@ -0,0 +1,160 @@ + + + + + + +gedcom.subparsers.family_event_structure API documentation + + + + + + + + + +
        +
        +
        +

        Module gedcom.subparsers.family_event_structure

        +
        +
        +

        Substructure parser for a FAMILY_EVENT_STRUCTURE embedded record.

        +

        This is referenced as part of a larger structure so there is no anchor tag.

        +
        + +Expand source code + +
        # -*- coding: utf-8 -*-
        +
        +# Python GEDCOM Parser
        +#
        +# Copyright (C) 2020 Christopher Horn (cdhorn at embarqmail dot com)
        +#
        +# 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.
        +#
        +# Further information about the license: http://www.gnu.org/licenses/gpl-2.0.html
        +
        +"""
        +Substructure parser for a `FAMILY_EVENT_STRUCTURE` embedded record.
        +
        +This is referenced as part of a larger structure so there is no anchor tag.
        +"""
        +
        +from typing import List
        +
        +import gedcom.tags as tags
        +from gedcom.element.element import Element
        +from gedcom.subparsers.family_event_detail import family_event_detail
        +
        +EVENT_TAGS = {
        +    tags.GEDCOM_TAG_ANNULMENT: 'annulment',
        +    tags.GEDCOM_TAG_CENSUS: 'census',
        +    tags.GEDCOM_TAG_DIVORCE: 'divorce',
        +    tags.GEDCOM_TAG_DIVORCE_FILED: 'divorce_filed',
        +    tags.GEDCOM_TAG_ENGAGEMENT: 'engagement',
        +    tags.GEDCOM_TAG_MARRIAGE: 'marriage',
        +    tags.GEDCOM_TAG_MARRIAGE_BANN: 'marriage_bann',
        +    tags.GEDCOM_TAG_MARR_CONTRACT: 'marriage_contract',
        +    tags.GEDCOM_TAG_MARR_LICENSE: 'marriage_license',
        +    tags.GEDCOM_TAG_MARR_SETTLEMENT: 'marriage_settlement',
        +    tags.GEDCOM_TAG_RESIDENCE: 'residence',
        +    tags.GEDCOM_TAG_EVENT: 'event'
        +}
        +
        +
        +def family_event_structure(element: Element) -> List[dict]:
        +    """Parses and extracts a `FAMILY_EVENT_STRUCTURE` structure.
        +
        +    The `element` should be the parent that contains it.
        +    """
        +    records = []
        +    for child in element.get_child_elements():
        +        if child.get_tag() in EVENT_TAGS:
        +            record = family_event_detail(child)
        +            record['description'] = child.get_multi_line_value()
        +            record['tag'] = child.get_tag()
        +            record['event'] = EVENT_TAGS[child.get_tag()]
        +            records.append(record)
        +
        +    return records
        +
        +
        +
        +
        +
        +
        +
        +

        Functions

        +
        +
        +def family_event_structure(element: Element) -> List[dict] +
        +
        +

        Parses and extracts a FAMILY_EVENT_STRUCTURE structure.

        +

        The element should be the parent that contains it.

        +
        + +Expand source code + +
        def family_event_structure(element: Element) -> List[dict]:
        +    """Parses and extracts a `FAMILY_EVENT_STRUCTURE` structure.
        +
        +    The `element` should be the parent that contains it.
        +    """
        +    records = []
        +    for child in element.get_child_elements():
        +        if child.get_tag() in EVENT_TAGS:
        +            record = family_event_detail(child)
        +            record['description'] = child.get_multi_line_value()
        +            record['tag'] = child.get_tag()
        +            record['event'] = EVENT_TAGS[child.get_tag()]
        +            records.append(record)
        +
        +    return records
        +
        +
        +
        +
        +
        +
        +
        + +
        + + + + + \ No newline at end of file diff --git a/docs/gedcom/subparsers/index.html b/docs/gedcom/subparsers/index.html new file mode 100644 index 0000000..6add805 --- /dev/null +++ b/docs/gedcom/subparsers/index.html @@ -0,0 +1,221 @@ + + + + + + +gedcom.subparsers API documentation + + + + + + + + + +
        +
        +
        +

        Module gedcom.subparsers

        +
        +
        +

        Module containing parsers for extracting various substructures from the +different record types as defined in the GEDCOM standard.

        +
        + +Expand source code + +
        # -*- coding: utf-8 -*-
        +
        +# Python GEDCOM Parser
        +#
        +# Copyright (C) 2020 Christopher Horn (cdhorn at embarqmail dot com)
        +#
        +# 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.
        +#
        +# Further information about the license: http://www.gnu.org/licenses/gpl-2.0.html
        +
        +"""Module containing parsers for extracting various substructures from the
        +different record types as defined in the GEDCOM standard."""
        +
        +__all__ = [
        +    "address_structure",
        +    "association_structure",
        +    "change_date",
        +    "child_to_family_link",
        +    "event_detail",
        +    "family_event_detail",
        +    "family_event_structure",
        +    "individual_attribute_structure",
        +    "individual_event_detail",
        +    "individual_event_structure",
        +    "lds_individual_ordinance",
        +    "lds_spouse_sealing",
        +    "multimedia_link",
        +    "note_structure",
        +    "personal_name_pieces",
        +    "personal_name_structure",
        +    "place_structure",
        +    "source_citation",
        +    "source_repository_citation",
        +    "spouse_to_family_link",
        +    "user_reference_number"
        +]
        +
        +
        +
        +

        Sub-modules

        +
        +
        gedcom.subparsers.address_structure
        +
        +

        Substructure parser for a ADDRESS_STRUCTURE embedded record …

        +
        +
        gedcom.subparsers.association_structure
        +
        +

        Substructure parser for the ASSOCIATION_STRUCTURE record …

        +
        +
        gedcom.subparsers.change_date
        +
        +

        Substructure parser for a CHANGE_DATE record …

        +
        +
        gedcom.subparsers.child_to_family_link
        +
        +

        Substructure parser for a CHILD_TO_FAMILY_LINK record …

        +
        +
        gedcom.subparsers.event_detail
        +
        +

        Substructure parser for a EVENT_DETAIL embedded record …

        +
        +
        gedcom.subparsers.family_event_detail
        +
        +

        Substructure parser for a FAMILY_EVENT_DETAIL emdedded record …

        +
        +
        gedcom.subparsers.family_event_structure
        +
        +

        Substructure parser for a FAMILY_EVENT_STRUCTURE embedded record …

        +
        +
        gedcom.subparsers.individual_attribute_structure
        +
        +

        Substructure parser for the INDIVIDUAL_ATTRIBUTE_STRUCTURE embedded record …

        +
        +
        gedcom.subparsers.individual_event_detail
        +
        +

        Substructure parser for a INDIVIDUAL_EVENT_DETAIL emdedded record …

        +
        +
        gedcom.subparsers.individual_event_structure
        +
        +

        Substructure parser for a INDIVIDUAL_EVENT_STRUCTURE embedded record …

        +
        +
        gedcom.subparsers.lds_individual_ordinance
        +
        +

        Substructure parser for a LDS_INDIVIDUAL_ORDINANCE embedded record …

        +
        +
        gedcom.subparsers.lds_spouse_sealing
        +
        +

        Substructure parser for a LDS_SPOUSE_SEALING embedded record …

        +
        +
        gedcom.subparsers.multimedia_link
        +
        +

        Substructure parser for a MULTIMEDIA_LINK record …

        +
        +
        gedcom.subparsers.note_structure
        +
        +

        Substructure parser for a NOTE_STRUCTURE record …

        +
        +
        gedcom.subparsers.personal_name_pieces
        +
        +

        Substructure parser for a PERSONAL_NAME_PIECES embedded record …

        +
        +
        gedcom.subparsers.personal_name_structure
        +
        +

        Substructure parser for a PERSONAL_NAME_STRUCTURE record …

        +
        +
        gedcom.subparsers.place_structure
        +
        +

        Substructure parser for a PLACE_STRUCTURE record …

        +
        +
        gedcom.subparsers.source_citation
        +
        +

        Substructure parser for a SOURCE_CITATION record …

        +
        +
        gedcom.subparsers.source_repository_citation
        +
        +

        Substructure parser for a SOURCE_REPOSITORY_CITATION record …

        +
        +
        gedcom.subparsers.spouse_to_family_link
        +
        +

        Substructure parser for a SPOUSE_TO_FAMILY_LINK record …

        +
        +
        gedcom.subparsers.user_reference_number
        +
        +

        Parser for a USER_REFERENCE_NUMBER structure …

        +
        +
        +
        +
        +
        +
        +
        +
        +
        +
        + +
        + + + + + \ No newline at end of file diff --git a/docs/gedcom/subparsers/individual_attribute_structure.html b/docs/gedcom/subparsers/individual_attribute_structure.html new file mode 100644 index 0000000..6289792 --- /dev/null +++ b/docs/gedcom/subparsers/individual_attribute_structure.html @@ -0,0 +1,165 @@ + + + + + + +gedcom.subparsers.individual_attribute_structure API documentation + + + + + + + + + +
        +
        +
        +

        Module gedcom.subparsers.individual_attribute_structure

        +
        +
        +

        Substructure parser for the INDIVIDUAL_ATTRIBUTE_STRUCTURE embedded record.

        +

        This is referenced as part of a larger structure so there is no anchor tag.

        +
        + +Expand source code + +
        # -*- coding: utf-8 -*-
        +
        +# Python GEDCOM Parser
        +#
        +# Copyright (C) 2020 Christopher Horn (cdhorn at embarqmail dot com)
        +#
        +# 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.
        +#
        +# Further information about the license: http://www.gnu.org/licenses/gpl-2.0.html
        +
        +"""
        +Substructure parser for the `INDIVIDUAL_ATTRIBUTE_STRUCTURE` embedded record.
        +
        +This is referenced as part of a larger structure so there is no anchor tag.
        +"""
        +
        +from typing import List
        +
        +import gedcom.tags as tags
        +from gedcom.element.element import Element
        +from gedcom.subparsers.individual_event_detail import individual_event_detail
        +
        +ATTRIBUTE_TAGS = {
        +    tags.GEDCOM_TAG_CASTE: 'caste',
        +    tags.GEDCOM_TAG_PHY_DESCRIPTION: 'physical_description',
        +    tags.GEDCOM_TAG_EDUCATION: 'eduction',
        +    tags.GEDCOM_TAG_IDENT_NUMBER: 'identity_number',
        +    tags.GEDCOM_TAG_NATIONALITY: 'nationality',
        +    tags.GEDCOM_TAG_CHILDREN_COUNT: 'number_of_children',
        +    tags.GEDCOM_TAG_MARRIAGE_COUNT: 'number_of_marriages',
        +    tags.GEDCOM_TAG_OCCUPATION: 'occupation',
        +    tags.GEDCOM_TAG_PROPERTY: 'property',
        +    tags.GEDCOM_TAG_RELIGION: 'religion',
        +    tags.GEDCOM_TAG_RESIDENCE: 'residence',
        +    tags.GEDCOM_TAG_SOC_SEC_NUMBER: 'social_security_number',
        +    tags.GEDCOM_TAG_TITLE: 'title',
        +    tags.GEDCOM_TAG_FACT: 'fact',
        +    tags.GEDCOM_PROGRAM_DEFINED_TAG_DCAUSE: 'cause_of_death'
        +}
        +
        +
        +def individual_attribute_structure(element: Element) -> List[dict]:
        +    """Parses and extracts the `INDIVIDUAL_ATTRIBUTE_STRUCTURE` structures.
        +
        +    The `element` should be the parent that contains them.
        +    """
        +    records = []
        +    for child in element.get_child_elements():
        +        if child.get_tag() in ATTRIBUTE_TAGS:
        +            record = individual_event_detail(child)
        +            record['description'] = child.get_multi_line_value()
        +            record['tag'] = child.get_tag()
        +            record['attribute'] = ATTRIBUTE_TAGS[child.get_tag()]
        +            records.append(record)
        +            continue
        +
        +    return records
        +
        +
        +
        +
        +
        +
        +
        +

        Functions

        +
        +
        +def individual_attribute_structure(element: Element) -> List[dict] +
        +
        +

        Parses and extracts the INDIVIDUAL_ATTRIBUTE_STRUCTURE structures.

        +

        The element should be the parent that contains them.

        +
        + +Expand source code + +
        def individual_attribute_structure(element: Element) -> List[dict]:
        +    """Parses and extracts the `INDIVIDUAL_ATTRIBUTE_STRUCTURE` structures.
        +
        +    The `element` should be the parent that contains them.
        +    """
        +    records = []
        +    for child in element.get_child_elements():
        +        if child.get_tag() in ATTRIBUTE_TAGS:
        +            record = individual_event_detail(child)
        +            record['description'] = child.get_multi_line_value()
        +            record['tag'] = child.get_tag()
        +            record['attribute'] = ATTRIBUTE_TAGS[child.get_tag()]
        +            records.append(record)
        +            continue
        +
        +    return records
        +
        +
        +
        +
        +
        +
        +
        + +
        + + + + + \ No newline at end of file diff --git a/docs/gedcom/subparsers/individual_event_detail.html b/docs/gedcom/subparsers/individual_event_detail.html new file mode 100644 index 0000000..0706915 --- /dev/null +++ b/docs/gedcom/subparsers/individual_event_detail.html @@ -0,0 +1,137 @@ + + + + + + +gedcom.subparsers.individual_event_detail API documentation + + + + + + + + + +
        +
        +
        +

        Module gedcom.subparsers.individual_event_detail

        +
        +
        +

        Substructure parser for a INDIVIDUAL_EVENT_DETAIL emdedded record.

        +

        This is referenced as part of a larger structure so there is no anchor tag.

        +
        + +Expand source code + +
        # -*- coding: utf-8 -*-
        +
        +# Python GEDCOM Parser
        +#
        +# Copyright (C) 2020 Christopher Horn (cdhorn at embarqmail dot com)
        +#
        +# 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.
        +#
        +# Further information about the license: http://www.gnu.org/licenses/gpl-2.0.html
        +
        +"""
        +Substructure parser for a `INDIVIDUAL_EVENT_DETAIL` emdedded record.
        +
        +This is referenced as part of a larger structure so there is no anchor tag.
        +"""
        +
        +import gedcom.tags as tags
        +from gedcom.element.element import Element
        +from gedcom.subparsers.event_detail import event_detail
        +
        +
        +def individual_event_detail(element: Element) -> dict:
        +    """Parses and extracts a `INDIVIDUAL_EVENT_DETAIL` structure.
        +
        +    The `element` should be the parent that contains it.
        +    """
        +    record = event_detail(element)
        +    record['age'] = ''
        +    for child in element.get_child_elements():
        +        if child.get_tag() == tags.GEDCOM_TAG_AGE:
        +            record['age'] = child.get_value()
        +
        +    return record
        +
        +
        +
        +
        +
        +
        +
        +

        Functions

        +
        +
        +def individual_event_detail(element: Element) -> dict +
        +
        +

        Parses and extracts a INDIVIDUAL_EVENT_DETAIL structure.

        +

        The element should be the parent that contains it.

        +
        + +Expand source code + +
        def individual_event_detail(element: Element) -> dict:
        +    """Parses and extracts a `INDIVIDUAL_EVENT_DETAIL` structure.
        +
        +    The `element` should be the parent that contains it.
        +    """
        +    record = event_detail(element)
        +    record['age'] = ''
        +    for child in element.get_child_elements():
        +        if child.get_tag() == tags.GEDCOM_TAG_AGE:
        +            record['age'] = child.get_value()
        +
        +    return record
        +
        +
        +
        +
        +
        +
        +
        + +
        + + + + + \ No newline at end of file diff --git a/docs/gedcom/subparsers/individual_event_structure.html b/docs/gedcom/subparsers/individual_event_structure.html new file mode 100644 index 0000000..dd8eef8 --- /dev/null +++ b/docs/gedcom/subparsers/individual_event_structure.html @@ -0,0 +1,233 @@ + + + + + + +gedcom.subparsers.individual_event_structure API documentation + + + + + + + + + +
        +
        +
        +

        Module gedcom.subparsers.individual_event_structure

        +
        +
        +

        Substructure parser for a INDIVIDUAL_EVENT_STRUCTURE embedded record.

        +

        This is referenced as part of a larger structure so there is no anchor tag.

        +
        + +Expand source code + +
        # -*- coding: utf-8 -*-
        +
        +# Python GEDCOM Parser
        +#
        +# Copyright (C) 2020 Christopher Horn (cdhorn at embarqmail dot com)
        +#
        +# 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.
        +#
        +# Further information about the license: http://www.gnu.org/licenses/gpl-2.0.html
        +
        +"""
        +Substructure parser for a `INDIVIDUAL_EVENT_STRUCTURE` embedded record.
        +
        +This is referenced as part of a larger structure so there is no anchor tag.
        +"""
        +
        +from typing import List
        +
        +import gedcom.tags as tags
        +from gedcom.element.element import Element
        +from gedcom.subparsers.individual_event_detail import individual_event_detail
        +
        +EVENT_TAGS = {
        +    tags.GEDCOM_TAG_DEATH: 'death',
        +    tags.GEDCOM_TAG_BURIAL: 'burial',
        +    tags.GEDCOM_TAG_CREMATION: 'cremation',
        +    tags.GEDCOM_TAG_BAPTISM: 'baptism',
        +    tags.GEDCOM_TAG_BAR_MITZVAH: 'bar_mitzvah',
        +    tags.GEDCOM_TAG_BAS_MITZVAH: 'bas_mitzvah',
        +    tags.GEDCOM_TAG_BLESSING: 'blessing',
        +    tags.GEDCOM_TAG_ADULT_CHRISTENING: 'adult_christening',
        +    tags.GEDCOM_TAG_CONFIRMATION: 'confirmation',
        +    tags.GEDCOM_TAG_FIRST_COMMUNION: 'first_communion',
        +    tags.GEDCOM_TAG_ORDINATION: 'ordination',
        +    tags.GEDCOM_TAG_NATURALIZATION: 'naturalization',
        +    tags.GEDCOM_TAG_EMIGRATION: 'emmigration',
        +    tags.GEDCOM_TAG_IMMIGRATION: 'immigration',
        +    tags.GEDCOM_TAG_CENSUS: 'census',
        +    tags.GEDCOM_TAG_PROBATE: 'probate',
        +    tags.GEDCOM_TAG_WILL: 'will',
        +    tags.GEDCOM_TAG_GRADUATION: 'graduation',
        +    tags.GEDCOM_TAG_RETIREMENT: 'retirement',
        +    tags.GEDCOM_TAG_EVENT: 'event',
        +    tags.GEDCOM_PROGRAM_DEFINED_TAG_DEGREE: 'degree',
        +    tags.GEDCOM_PROGRAM_DEFINED_TAG_FUNERAL: 'funeral',
        +    tags.GEDCOM_PROGRAM_DEFINED_TAG_MEDICAL: 'medical',
        +    tags.GEDCOM_PROGRAM_DEFINED_TAG_MILITARY: 'military'
        +}
        +
        +BIRTH_EVENT_TAGS = {
        +    tags.GEDCOM_TAG_BIRTH: 'birth',
        +    tags.GEDCOM_TAG_CHRISTENING: 'christening'
        +}
        +
        +
        +def individual_event_structure(element: Element) -> List[dict]:
        +    """Parses and extracts a `INDIVIDUAL_EVENT_STRUCTURE` structure.
        +
        +    The `element` should be the parent that contains it.
        +    """
        +    records = []
        +    for child in element.get_child_elements():
        +        if child.get_tag() in BIRTH_EVENT_TAGS:
        +            record = individual_event_detail(child)
        +            record['tag'] = child.get_tag()
        +            record['event'] = BIRTH_EVENT_TAGS[child.get_tag()]
        +            record['description'] = child.get_multi_line_value()
        +            record['family'] = ''
        +            for gchild in child.get_child_elements():
        +                if gchild.get_tag() == tags.GEDCOM_TAG_FAMILY_CHILD:
        +                    record['family'] = gchild.get_value()
        +            records.append(record)
        +            continue
        +
        +        if child.get_tag() in EVENT_TAGS:
        +            record = individual_event_detail(child)
        +            record['tag'] = child.get_tag()
        +            record['event'] = EVENT_TAGS[child.get_tag()]
        +            record['description'] = child.get_multi_line_value()
        +            records.append(record)
        +            continue
        +
        +        if child.get_tag() == tags.GEDCOM_TAG_ADOPTION:
        +            record = individual_event_detail(child)
        +            record['tag'] = child.get_tag()
        +            record['event'] = 'adoption'
        +            record['description'] = child.get_multi_line_value()
        +            record['family'] = ''
        +            record['parent'] = ''
        +            for gchild in child.get_child_elements():
        +                if gchild.get_tag() == tags.GEDCOM_TAG_FAMILY_CHILD:
        +                    record['family'] = gchild.get_value()
        +                    for ggchild in gchild.get_child_elements():
        +                        if ggchild.get_tag() == tags.GEDCOM_TAG_ADOPTION:
        +                            record['parent'] = ggchild.get_value()
        +            records.append(record)
        +
        +    return records
        +
        +
        +
        +
        +
        +
        +
        +

        Functions

        +
        +
        +def individual_event_structure(element: Element) -> List[dict] +
        +
        +

        Parses and extracts a INDIVIDUAL_EVENT_STRUCTURE structure.

        +

        The element should be the parent that contains it.

        +
        + +Expand source code + +
        def individual_event_structure(element: Element) -> List[dict]:
        +    """Parses and extracts a `INDIVIDUAL_EVENT_STRUCTURE` structure.
        +
        +    The `element` should be the parent that contains it.
        +    """
        +    records = []
        +    for child in element.get_child_elements():
        +        if child.get_tag() in BIRTH_EVENT_TAGS:
        +            record = individual_event_detail(child)
        +            record['tag'] = child.get_tag()
        +            record['event'] = BIRTH_EVENT_TAGS[child.get_tag()]
        +            record['description'] = child.get_multi_line_value()
        +            record['family'] = ''
        +            for gchild in child.get_child_elements():
        +                if gchild.get_tag() == tags.GEDCOM_TAG_FAMILY_CHILD:
        +                    record['family'] = gchild.get_value()
        +            records.append(record)
        +            continue
        +
        +        if child.get_tag() in EVENT_TAGS:
        +            record = individual_event_detail(child)
        +            record['tag'] = child.get_tag()
        +            record['event'] = EVENT_TAGS[child.get_tag()]
        +            record['description'] = child.get_multi_line_value()
        +            records.append(record)
        +            continue
        +
        +        if child.get_tag() == tags.GEDCOM_TAG_ADOPTION:
        +            record = individual_event_detail(child)
        +            record['tag'] = child.get_tag()
        +            record['event'] = 'adoption'
        +            record['description'] = child.get_multi_line_value()
        +            record['family'] = ''
        +            record['parent'] = ''
        +            for gchild in child.get_child_elements():
        +                if gchild.get_tag() == tags.GEDCOM_TAG_FAMILY_CHILD:
        +                    record['family'] = gchild.get_value()
        +                    for ggchild in gchild.get_child_elements():
        +                        if ggchild.get_tag() == tags.GEDCOM_TAG_ADOPTION:
        +                            record['parent'] = ggchild.get_value()
        +            records.append(record)
        +
        +    return records
        +
        +
        +
        +
        +
        +
        +
        + +
        + + + + + \ No newline at end of file diff --git a/docs/gedcom/subparsers/lds_individual_ordinance.html b/docs/gedcom/subparsers/lds_individual_ordinance.html new file mode 100644 index 0000000..cdc657d --- /dev/null +++ b/docs/gedcom/subparsers/lds_individual_ordinance.html @@ -0,0 +1,220 @@ + + + + + + +gedcom.subparsers.lds_individual_ordinance API documentation + + + + + + + + + +
        +
        +
        +

        Module gedcom.subparsers.lds_individual_ordinance

        +
        +
        +

        Substructure parser for a LDS_INDIVIDUAL_ORDINANCE embedded record.

        +

        This is referenced as part of a larger structure so there is no anchor tag.

        +
        + +Expand source code + +
        # -*- coding: utf-8 -*-
        +
        +# Python GEDCOM Parser
        +#
        +# Copyright (C) 2020 Christopher Horn (cdhorn at embarqmail dot com)
        +#
        +# 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.
        +#
        +# Further information about the license: http://www.gnu.org/licenses/gpl-2.0.html
        +
        +"""
        +Substructure parser for a `LDS_INDIVIDUAL_ORDINANCE` embedded record.
        +
        +This is referenced as part of a larger structure so there is no anchor tag.
        +"""
        +
        +from typing import List
        +
        +import gedcom.tags as tags
        +from gedcom.element.element import Element
        +from gedcom.subparsers.note_structure import note_structure
        +from gedcom.subparsers.source_citation import source_citation
        +
        +ORDINANCE_TAGS = {
        +    tags.GEDCOM_TAG_BAPTISM_LDS: 'lds_baptism',
        +    tags.GEDCOM_TAG_CONFIRMATION_L: 'lds_confirmation',
        +    tags.GEDCOM_TAG_ENDOWMENT: 'lds_endowment',
        +    tags.GEDCOM_TAG_SEALING_CHILD: 'lds_sealing_child'
        +}
        +
        +ORDINANCE_ATTRIBUTE_TAGS = {
        +    tags.GEDCOM_TAG_DATE: 'date',
        +    tags.GEDCOM_TAG_TEMPLE: 'temple',
        +    tags.GEDCOM_TAG_PLACE: 'place',
        +    tags.GEDCOM_TAG_FAMILY_CHILD: 'key_to_family'
        +}
        +
        +
        +def lds_individual_ordinance(element: Element) -> List[dict]:
        +    """Parses and extracts a `LDS_INDIVIDUAL_ORDINANCE` structure.
        +
        +    The `element` should be the parent that contains it.
        +    """
        +    records = []
        +    for child in element.get_child_elements():
        +        if child.get_tag() in ORDINANCE_TAGS:
        +            record = {
        +                'date': '',
        +                'temple': '',
        +                'place': '',
        +                'status': '',
        +                'status_change': '',
        +                'notes': [],
        +                'citations': [],
        +                'tag': child.get_tag(),
        +                'event': ORDINANCE_TAGS[child.get_tag()]
        +            }
        +            if child.get_tag() == tags.GEDCOM_TAG_SEALING_CHILD:
        +                record.update({'key_to_family': ''})
        +            for gchild in child.get_child_elements():
        +                if gchild.get_tag() in ORDINANCE_ATTRIBUTE_TAGS:
        +                    record[ORDINANCE_ATTRIBUTE_TAGS[gchild.get_tag()]] = gchild.get_value()
        +                    continue
        +
        +                if gchild.get_tag() == tags.GEDCOM_TAG_STATUS:
        +                    record['status'] = gchild.get_value()
        +                    for ggchild in gchild.get_child_elements():
        +                        if ggchild.get_tag() == tags.GEDCOM_TAG_DATE:
        +                            record['status_change'] = ggchild.get_value()
        +                    continue
        +
        +                if gchild.get_tag() == tags.GEDCOM_TAG_NOTE:
        +                    record['notes'].append(note_structure(child))
        +                    continue
        +
        +                if gchild.get_tag() == tags.GEDCOM_TAG_SOURCE:
        +                    record['citations'].append(source_citation(child))
        +                    continue
        +
        +            records.append(record)
        +            continue
        +
        +    return records
        +
        +
        +
        +
        +
        +
        +
        +

        Functions

        +
        +
        +def lds_individual_ordinance(element: Element) -> List[dict] +
        +
        +

        Parses and extracts a LDS_INDIVIDUAL_ORDINANCE structure.

        +

        The element should be the parent that contains it.

        +
        + +Expand source code + +
        def lds_individual_ordinance(element: Element) -> List[dict]:
        +    """Parses and extracts a `LDS_INDIVIDUAL_ORDINANCE` structure.
        +
        +    The `element` should be the parent that contains it.
        +    """
        +    records = []
        +    for child in element.get_child_elements():
        +        if child.get_tag() in ORDINANCE_TAGS:
        +            record = {
        +                'date': '',
        +                'temple': '',
        +                'place': '',
        +                'status': '',
        +                'status_change': '',
        +                'notes': [],
        +                'citations': [],
        +                'tag': child.get_tag(),
        +                'event': ORDINANCE_TAGS[child.get_tag()]
        +            }
        +            if child.get_tag() == tags.GEDCOM_TAG_SEALING_CHILD:
        +                record.update({'key_to_family': ''})
        +            for gchild in child.get_child_elements():
        +                if gchild.get_tag() in ORDINANCE_ATTRIBUTE_TAGS:
        +                    record[ORDINANCE_ATTRIBUTE_TAGS[gchild.get_tag()]] = gchild.get_value()
        +                    continue
        +
        +                if gchild.get_tag() == tags.GEDCOM_TAG_STATUS:
        +                    record['status'] = gchild.get_value()
        +                    for ggchild in gchild.get_child_elements():
        +                        if ggchild.get_tag() == tags.GEDCOM_TAG_DATE:
        +                            record['status_change'] = ggchild.get_value()
        +                    continue
        +
        +                if gchild.get_tag() == tags.GEDCOM_TAG_NOTE:
        +                    record['notes'].append(note_structure(child))
        +                    continue
        +
        +                if gchild.get_tag() == tags.GEDCOM_TAG_SOURCE:
        +                    record['citations'].append(source_citation(child))
        +                    continue
        +
        +            records.append(record)
        +            continue
        +
        +    return records
        +
        +
        +
        +
        +
        +
        +
        + +
        + + + + + \ No newline at end of file diff --git a/docs/gedcom/subparsers/lds_spouse_sealing.html b/docs/gedcom/subparsers/lds_spouse_sealing.html new file mode 100644 index 0000000..8d5d0a1 --- /dev/null +++ b/docs/gedcom/subparsers/lds_spouse_sealing.html @@ -0,0 +1,209 @@ + + + + + + +gedcom.subparsers.lds_spouse_sealing API documentation + + + + + + + + + +
        +
        +
        +

        Module gedcom.subparsers.lds_spouse_sealing

        +
        +
        +

        Substructure parser for a LDS_SPOUSE_SEALING embedded record.

        +

        This is referenced as part of a larger structure so there is no anchor tag.

        +
        + +Expand source code + +
        # -*- coding: utf-8 -*-
        +
        +# Python GEDCOM Parser
        +#
        +# Copyright (C) 2020 Christopher Horn (cdhorn at embarqmail dot com)
        +#
        +# 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.
        +#
        +# Further information about the license: http://www.gnu.org/licenses/gpl-2.0.html
        +
        +"""
        +Substructure parser for a `LDS_SPOUSE_SEALING` embedded record.
        +
        +This is referenced as part of a larger structure so there is no anchor tag.
        +"""
        +
        +from typing import List
        +
        +import gedcom.tags as tags
        +from gedcom.element.element import Element
        +from gedcom.subparsers.note_structure import note_structure
        +from gedcom.subparsers.source_citation import source_citation
        +
        +SEALING_TAGS = {
        +    tags.GEDCOM_TAG_DATE: 'date',
        +    tags.GEDCOM_TAG_TEMPLE: 'temple',
        +    tags.GEDCOM_TAG_PLACE: 'place',
        +    tags.GEDCOM_TAG_FAMILY_CHILD: 'key_to_family'
        +}
        +
        +
        +def lds_spouse_sealing(element: Element) -> List[dict]:
        +    """Parses and extracts a `LDS_SPOUSE_SEALING` structure.
        +
        +    The `element` should be the parent that contains it.
        +    """
        +    records = []
        +    for child in element.get_child_elements():
        +        if child.get_tag() == tags.GEDCOM_TAG_SEALING_SPOUSE:
        +            record = {
        +                'date': '',
        +                'temple': '',
        +                'place': '',
        +                'status': '',
        +                'status_change': '',
        +                'notes': [],
        +                'citations': [],
        +                'tag': tags.GEDCOM_TAG_SEALING_SPOUSE,
        +                'event': 'lds_spouse_sealing'
        +            }
        +            for gchild in child.get_child_elements():
        +                if gchild.get_tag() in SEALING_TAGS:
        +                    record[SEALING_TAGS[gchild.get_tag()]] = gchild.get_value()
        +                    continue
        +
        +                if gchild.get_tag() == tags.GEDCOM_TAG_STATUS:
        +                    record['status'] = gchild.get_value()
        +                    for ggchild in gchild.get_child_elements():
        +                        if ggchild.get_tag() == tags.GEDCOM_TAG_DATE:
        +                            record['status_change'] = ggchild.get_value()
        +                    continue
        +
        +                if gchild.get_tag() == tags.GEDCOM_TAG_NOTE:
        +                    record['notes'].append(note_structure(child))
        +                    continue
        +
        +                if gchild.get_tag() == tags.GEDCOM_TAG_SOURCE:
        +                    record['citations'].append(source_citation(child))
        +                    continue
        +
        +            records.append(record)
        +            continue
        +
        +    return records
        +
        +
        +
        +
        +
        +
        +
        +

        Functions

        +
        +
        +def lds_spouse_sealing(element: Element) -> List[dict] +
        +
        +

        Parses and extracts a LDS_SPOUSE_SEALING structure.

        +

        The element should be the parent that contains it.

        +
        + +Expand source code + +
        def lds_spouse_sealing(element: Element) -> List[dict]:
        +    """Parses and extracts a `LDS_SPOUSE_SEALING` structure.
        +
        +    The `element` should be the parent that contains it.
        +    """
        +    records = []
        +    for child in element.get_child_elements():
        +        if child.get_tag() == tags.GEDCOM_TAG_SEALING_SPOUSE:
        +            record = {
        +                'date': '',
        +                'temple': '',
        +                'place': '',
        +                'status': '',
        +                'status_change': '',
        +                'notes': [],
        +                'citations': [],
        +                'tag': tags.GEDCOM_TAG_SEALING_SPOUSE,
        +                'event': 'lds_spouse_sealing'
        +            }
        +            for gchild in child.get_child_elements():
        +                if gchild.get_tag() in SEALING_TAGS:
        +                    record[SEALING_TAGS[gchild.get_tag()]] = gchild.get_value()
        +                    continue
        +
        +                if gchild.get_tag() == tags.GEDCOM_TAG_STATUS:
        +                    record['status'] = gchild.get_value()
        +                    for ggchild in gchild.get_child_elements():
        +                        if ggchild.get_tag() == tags.GEDCOM_TAG_DATE:
        +                            record['status_change'] = ggchild.get_value()
        +                    continue
        +
        +                if gchild.get_tag() == tags.GEDCOM_TAG_NOTE:
        +                    record['notes'].append(note_structure(child))
        +                    continue
        +
        +                if gchild.get_tag() == tags.GEDCOM_TAG_SOURCE:
        +                    record['citations'].append(source_citation(child))
        +                    continue
        +
        +            records.append(record)
        +            continue
        +
        +    return records
        +
        +
        +
        +
        +
        +
        +
        + +
        + + + + + \ No newline at end of file diff --git a/docs/gedcom/subparsers/multimedia_link.html b/docs/gedcom/subparsers/multimedia_link.html new file mode 100644 index 0000000..fe4d7ab --- /dev/null +++ b/docs/gedcom/subparsers/multimedia_link.html @@ -0,0 +1,189 @@ + + + + + + +gedcom.subparsers.multimedia_link API documentation + + + + + + + + + +
        +
        +
        +

        Module gedcom.subparsers.multimedia_link

        +
        +
        +

        Substructure parser for a MULTIMEDIA_LINK record.

        +

        This is anchored by the GEDCOM_TAG_OBJECT tag.

        +
        + +Expand source code + +
        # -*- coding: utf-8 -*-
        +
        +# Python GEDCOM Parser
        +#
        +# Copyright (C) 2020 Christopher Horn (cdhorn at embarqmail dot com)
        +#
        +# 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.
        +#
        +# Further information about the license: http://www.gnu.org/licenses/gpl-2.0.html
        +
        +"""
        +Substructure parser for a `MULTIMEDIA_LINK` record.
        +
        +This is anchored by the `gedcom.tags.GEDCOM_TAG_OBJECT` tag.
        +"""
        +
        +import gedcom.tags as tags
        +from gedcom.element.element import Element
        +
        +MEDIA_TAGS = {
        +    tags.GEDCOM_TAG_FILE: 'file',
        +    tags.GEDCOM_TAG_FORMAT: 'format',
        +    tags.GEDCOM_TAG_MEDIA: 'type',
        +    tags.GEDCOM_TAG_TITLE: 'title',
        +    tags.GEDCOM_PROGRAM_DEFINED_TAG_PHOTO: 'preferred',
        +    tags.GEDCOM_PROGRAM_DEFINED_TAG_PRIMARY: 'preferred'
        +}
        +
        +
        +def multimedia_link(element: Element) -> dict:
        +    """Parse and extract a `MULTIMEDIA_LINK` structure.
        +
        +    The `element` should contain the `gedcom.tags.GEDCOM_TAG_OBJECT` tag.
        +    """
        +    record = {
        +        'key_to_object': element.get_value(),
        +        'file': '',
        +        'format': '',
        +        'type': '',
        +        'title': '',
        +        'preferred': ''
        +    }
        +    if record['key_to_object'] not in [None, '']:
        +        if '@' in record['key_to_object']:
        +            return record
        +
        +    record['key_to_object'] = ''
        +    for child in element.get_child_elements():
        +        if child.get_tag() == tags.GEDCOM_TAG_FILE:
        +            record['file'] = child.get_value()
        +            for gchild in child.get_child_elements():
        +                if gchild.get_tag() == tags.GEDCOM_TAG_FORMAT:
        +                    record['format'] = gchild.get_value()
        +                    for ggchild in gchild.get_child_elements():
        +                        if ggchild.get_tag() == tags.GEDCOM_TAG_MEDIA:
        +                            record['type'] = ggchild.get_value()
        +                    continue
        +            continue
        +
        +        if child.get_tag() in MEDIA_TAGS:
        +            record[MEDIA_TAGS[child.get_tag()]] = child.get_value()
        +
        +    return record
        +
        +
        +
        +
        +
        +
        +
        +

        Functions

        +
        + +
        +

        Parse and extract a MULTIMEDIA_LINK structure.

        +

        The element should contain the GEDCOM_TAG_OBJECT tag.

        +
        + +Expand source code + +
        def multimedia_link(element: Element) -> dict:
        +    """Parse and extract a `MULTIMEDIA_LINK` structure.
        +
        +    The `element` should contain the `gedcom.tags.GEDCOM_TAG_OBJECT` tag.
        +    """
        +    record = {
        +        'key_to_object': element.get_value(),
        +        'file': '',
        +        'format': '',
        +        'type': '',
        +        'title': '',
        +        'preferred': ''
        +    }
        +    if record['key_to_object'] not in [None, '']:
        +        if '@' in record['key_to_object']:
        +            return record
        +
        +    record['key_to_object'] = ''
        +    for child in element.get_child_elements():
        +        if child.get_tag() == tags.GEDCOM_TAG_FILE:
        +            record['file'] = child.get_value()
        +            for gchild in child.get_child_elements():
        +                if gchild.get_tag() == tags.GEDCOM_TAG_FORMAT:
        +                    record['format'] = gchild.get_value()
        +                    for ggchild in gchild.get_child_elements():
        +                        if ggchild.get_tag() == tags.GEDCOM_TAG_MEDIA:
        +                            record['type'] = ggchild.get_value()
        +                    continue
        +            continue
        +
        +        if child.get_tag() in MEDIA_TAGS:
        +            record[MEDIA_TAGS[child.get_tag()]] = child.get_value()
        +
        +    return record
        +
        +
        +
        +
        +
        +
        +
        + +
        + + + + + \ No newline at end of file diff --git a/docs/gedcom/subparsers/note_structure.html b/docs/gedcom/subparsers/note_structure.html new file mode 100644 index 0000000..2bcddb5 --- /dev/null +++ b/docs/gedcom/subparsers/note_structure.html @@ -0,0 +1,143 @@ + + + + + + +gedcom.subparsers.note_structure API documentation + + + + + + + + + +
        +
        +
        +

        Module gedcom.subparsers.note_structure

        +
        +
        +

        Substructure parser for a NOTE_STRUCTURE record.

        +

        This is anchored by the GEDCOM_TAG_NOTE tag.

        +
        + +Expand source code + +
        # -*- coding: utf-8 -*-
        +
        +# Python GEDCOM Parser
        +#
        +# Copyright (C) 2020 Christopher Horn (cdhorn at embarqmail dot com)
        +#
        +# 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.
        +#
        +# Further information about the license: http://www.gnu.org/licenses/gpl-2.0.html
        +
        +"""
        +Substructure parser for a `NOTE_STRUCTURE` record.
        +
        +This is anchored by the `gedcom.tags.GEDCOM_TAG_NOTE` tag.
        +"""
        +
        +from gedcom.element.element import Element
        +
        +
        +def note_structure(element: Element) -> dict:
        +    """Parse and extract a `NOTE_STRUCTURE` structure.
        +
        +    The `element` should contain the `gedcom.tags.GEDCOM_TAG_NOTE` tag.
        +    """
        +    record = {
        +        'key_to_note': element.get_value(),
        +        'note': ''
        +    }
        +    if record['key_to_note'] not in [None, '']:
        +        if '@' in record['key_to_note']:
        +            return record
        +    record['key_to_note'] = ''
        +    record['note'] = element.get_multi_line_value()
        +
        +    return record
        +
        +
        +
        +
        +
        +
        +
        +

        Functions

        +
        +
        +def note_structure(element: Element) -> dict +
        +
        +

        Parse and extract a NOTE_STRUCTURE structure.

        +

        The element should contain the GEDCOM_TAG_NOTE tag.

        +
        + +Expand source code + +
        def note_structure(element: Element) -> dict:
        +    """Parse and extract a `NOTE_STRUCTURE` structure.
        +
        +    The `element` should contain the `gedcom.tags.GEDCOM_TAG_NOTE` tag.
        +    """
        +    record = {
        +        'key_to_note': element.get_value(),
        +        'note': ''
        +    }
        +    if record['key_to_note'] not in [None, '']:
        +        if '@' in record['key_to_note']:
        +            return record
        +    record['key_to_note'] = ''
        +    record['note'] = element.get_multi_line_value()
        +
        +    return record
        +
        +
        +
        +
        +
        +
        +
        + +
        + + + + + \ No newline at end of file diff --git a/docs/gedcom/subparsers/personal_name_pieces.html b/docs/gedcom/subparsers/personal_name_pieces.html new file mode 100644 index 0000000..69e94a5 --- /dev/null +++ b/docs/gedcom/subparsers/personal_name_pieces.html @@ -0,0 +1,184 @@ + + + + + + +gedcom.subparsers.personal_name_pieces API documentation + + + + + + + + + +
        +
        +
        +

        Module gedcom.subparsers.personal_name_pieces

        +
        +
        +

        Substructure parser for a PERSONAL_NAME_PIECES embedded record.

        +

        This is referenced as part of a larger structure so there is no anchor tag.

        +
        + +Expand source code + +
        # -*- coding: utf-8 -*-
        +
        +# Python GEDCOM Parser
        +#
        +# Copyright (C) 2020 Christopher Horn (cdhorn at embarqmail dot com)
        +#
        +# 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.
        +#
        +# Further information about the license: http://www.gnu.org/licenses/gpl-2.0.html
        +
        +"""
        +Substructure parser for a `PERSONAL_NAME_PIECES` embedded record.
        +
        +This is referenced as part of a larger structure so there is no anchor tag.
        +"""
        +
        +import gedcom.tags as tags
        +from gedcom.element.element import Element
        +from gedcom.subparsers.note_structure import note_structure
        +from gedcom.subparsers.source_citation import source_citation
        +
        +NAME_TAGS = {
        +    tags.GEDCOM_TAG_NAME_PREFIX: 'prefix',
        +    tags.GEDCOM_TAG_GIVEN_NAME: 'given',
        +    tags.GEDCOM_TAG_NICKNAME: 'nick',
        +    tags.GEDCOM_TAG_SURN_PREFIX: 'surname_prefix',
        +    tags.GEDCOM_TAG_SURNAME: 'surname',
        +    tags.GEDCOM_TAG_NAME_SUFFIX: 'suffix',
        +    tags.GEDCOM_PROGRAM_DEFINED_TAG_RUFNAME: 'rufname'
        +}
        +
        +
        +def personal_name_pieces(element: Element) -> dict:
        +    """Parse and extract a `PERSONAL_NAME_PIECES` structure.
        +
        +    The `element` should be the parent that contains it.
        +    """
        +    record = {
        +        'prefix': '',
        +        'given': '',
        +        'nick': '',
        +        'surname_prefix': '',
        +        'surname': '',
        +        'suffix': '',
        +        'rufname': '',
        +        'notes': [],
        +        'citations': []
        +    }
        +    for child in element.get_child_elements():
        +        if child.get_tag() in NAME_TAGS:
        +            record[NAME_TAGS[child.get_tag()]] = child.get_value()
        +            continue
        +
        +        if child.get_tag() == tags.GEDCOM_TAG_NOTE:
        +            record['notes'].append(note_structure(child))
        +            continue
        +
        +        if child.get_tag() == tags.GEDCOM_TAG_SOURCE:
        +            record['citations'].append(source_citation(child))
        +            continue
        +
        +    return record
        +
        +
        +
        +
        +
        +
        +
        +

        Functions

        +
        +
        +def personal_name_pieces(element: Element) -> dict +
        +
        +

        Parse and extract a PERSONAL_NAME_PIECES structure.

        +

        The element should be the parent that contains it.

        +
        + +Expand source code + +
        def personal_name_pieces(element: Element) -> dict:
        +    """Parse and extract a `PERSONAL_NAME_PIECES` structure.
        +
        +    The `element` should be the parent that contains it.
        +    """
        +    record = {
        +        'prefix': '',
        +        'given': '',
        +        'nick': '',
        +        'surname_prefix': '',
        +        'surname': '',
        +        'suffix': '',
        +        'rufname': '',
        +        'notes': [],
        +        'citations': []
        +    }
        +    for child in element.get_child_elements():
        +        if child.get_tag() in NAME_TAGS:
        +            record[NAME_TAGS[child.get_tag()]] = child.get_value()
        +            continue
        +
        +        if child.get_tag() == tags.GEDCOM_TAG_NOTE:
        +            record['notes'].append(note_structure(child))
        +            continue
        +
        +        if child.get_tag() == tags.GEDCOM_TAG_SOURCE:
        +            record['citations'].append(source_citation(child))
        +            continue
        +
        +    return record
        +
        +
        +
        +
        +
        +
        +
        + +
        + + + + + \ No newline at end of file diff --git a/docs/gedcom/subparsers/personal_name_structure.html b/docs/gedcom/subparsers/personal_name_structure.html new file mode 100644 index 0000000..ebc7a80 --- /dev/null +++ b/docs/gedcom/subparsers/personal_name_structure.html @@ -0,0 +1,211 @@ + + + + + + +gedcom.subparsers.personal_name_structure API documentation + + + + + + + + + +
        +
        +
        +

        Module gedcom.subparsers.personal_name_structure

        +
        +
        +

        Substructure parser for a PERSONAL_NAME_STRUCTURE record.

        +

        This is anchored by the GEDCOM_TAG_NAME tag.

        +
        + +Expand source code + +
        # -*- coding: utf-8 -*-
        +
        +# Python GEDCOM Parser
        +#
        +# Copyright (C) 2020 Christopher Horn (cdhorn at embarqmail dot com)
        +#
        +# 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.
        +#
        +# Further information about the license: http://www.gnu.org/licenses/gpl-2.0.html
        +
        +"""
        +Substructure parser for a `PERSONAL_NAME_STRUCTURE` record.
        +
        +This is anchored by the `gedcom.tags.GEDCOM_TAG_NAME` tag.
        +"""
        +
        +import gedcom.tags as tags
        +from gedcom.element.element import Element
        +from gedcom.subparsers.personal_name_pieces import personal_name_pieces
        +
        +
        +def extract_name(element: Element) -> dict:
        +    """Parse and extract a `NAME` for a `PERSONAL_NAME_STRUCTURE` structure.
        +
        +    The `element` should contain one of the name tags:
        +
        +    `gedcom.tags.GEDCOM_TAG_NAME`
        +
        +    `gedcom.tags.GEDCOM_TAG_PHONETIC`
        +
        +    `gedcom.tags.GEDCOM_TAG_ROMANIZED`
        +    """
        +    record = {
        +        'name': '',
        +        'type': '',
        +        'pieces': {}
        +    }
        +    record['name'] = element.get_value()
        +    record['pieces'] = personal_name_pieces(element)
        +    for child in element.get_child_elements():
        +        if child.get_tag() == tags.GEDCOM_TAG_TYPE:
        +            record['type'] = child.get_value()
        +    return record
        +
        +
        +def personal_name_structure(element: Element) -> dict:
        +    """Parse and extract a `PERSONAL_NAME_STRUCTURE` structure.
        +
        +    The `element` should contain the `gedcom.tags.GEDCOM_TAG_NAME` tag.
        +    """
        +    record = extract_name(element)
        +    record['phonetic'] = []
        +    record['romanized'] = []
        +    for child in element.get_child_elements():
        +        if child.get_tag() == tags.GEDCOM_TAG_PHONETIC:
        +            record['phonetic'].append(extract_name(child))
        +            continue
        +
        +        if child.get_tag() == tags.GEDCOM_TAG_ROMANIZED:
        +            record['romanized'].append(extract_name(child))
        +            continue
        +
        +    return record
        +
        +
        +
        +
        +
        +
        +
        +

        Functions

        +
        +
        +def extract_name(element: Element) -> dict +
        +
        +

        Parse and extract a NAME for a PERSONAL_NAME_STRUCTURE structure.

        +

        The element should contain one of the name tags:

        +

        GEDCOM_TAG_NAME

        +

        GEDCOM_TAG_PHONETIC

        +

        GEDCOM_TAG_ROMANIZED

        +
        + +Expand source code + +
        def extract_name(element: Element) -> dict:
        +    """Parse and extract a `NAME` for a `PERSONAL_NAME_STRUCTURE` structure.
        +
        +    The `element` should contain one of the name tags:
        +
        +    `gedcom.tags.GEDCOM_TAG_NAME`
        +
        +    `gedcom.tags.GEDCOM_TAG_PHONETIC`
        +
        +    `gedcom.tags.GEDCOM_TAG_ROMANIZED`
        +    """
        +    record = {
        +        'name': '',
        +        'type': '',
        +        'pieces': {}
        +    }
        +    record['name'] = element.get_value()
        +    record['pieces'] = personal_name_pieces(element)
        +    for child in element.get_child_elements():
        +        if child.get_tag() == tags.GEDCOM_TAG_TYPE:
        +            record['type'] = child.get_value()
        +    return record
        +
        +
        +
        +def personal_name_structure(element: Element) -> dict +
        +
        +

        Parse and extract a PERSONAL_NAME_STRUCTURE structure.

        +

        The element should contain the GEDCOM_TAG_NAME tag.

        +
        + +Expand source code + +
        def personal_name_structure(element: Element) -> dict:
        +    """Parse and extract a `PERSONAL_NAME_STRUCTURE` structure.
        +
        +    The `element` should contain the `gedcom.tags.GEDCOM_TAG_NAME` tag.
        +    """
        +    record = extract_name(element)
        +    record['phonetic'] = []
        +    record['romanized'] = []
        +    for child in element.get_child_elements():
        +        if child.get_tag() == tags.GEDCOM_TAG_PHONETIC:
        +            record['phonetic'].append(extract_name(child))
        +            continue
        +
        +        if child.get_tag() == tags.GEDCOM_TAG_ROMANIZED:
        +            record['romanized'].append(extract_name(child))
        +            continue
        +
        +    return record
        +
        +
        +
        +
        +
        +
        +
        + +
        + + + + + \ No newline at end of file diff --git a/docs/gedcom/subparsers/place_structure.html b/docs/gedcom/subparsers/place_structure.html new file mode 100644 index 0000000..2de7d94 --- /dev/null +++ b/docs/gedcom/subparsers/place_structure.html @@ -0,0 +1,223 @@ + + + + + + +gedcom.subparsers.place_structure API documentation + + + + + + + + + +
        +
        +
        +

        Module gedcom.subparsers.place_structure

        +
        +
        +

        Substructure parser for a PLACE_STRUCTURE record.

        +

        This is anchored by the GEDCOM_TAG_PLACE tag.

        +
        + +Expand source code + +
        # -*- coding: utf-8 -*-
        +
        +# Python GEDCOM Parser
        +#
        +# Copyright (C) 2020 Christopher Horn (cdhorn at embarqmail dot com)
        +#
        +# 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.
        +#
        +# Further information about the license: http://www.gnu.org/licenses/gpl-2.0.html
        +
        +"""
        +Substructure parser for a `PLACE_STRUCTURE` record.
        +
        +This is anchored by the `gedcom.tags.GEDCOM_TAG_PLACE` tag.
        +"""
        +
        +import gedcom.tags as tags
        +from gedcom.element.element import Element
        +from gedcom.subparsers.note_structure import note_structure
        +
        +
        +def place_structure(element: Element) -> dict:
        +    """Parse and extract a `PLACE_STRUCTURE` structure.
        +
        +    The `element` should contain the `gedcom.tags.GEDCOM_TAG_PLACE` tag.
        +    """
        +    record = {
        +        'name': element.get_value(),
        +        'hierarchy': '',
        +        'phonetic': [],
        +        'romanized': [],
        +        'latitude': '',
        +        'longitude': '',
        +        'notes': []
        +    }
        +    for child in element.get_child_elements():
        +        if child.get_tag() == tags.GEDCOM_TAG_FORMAT:
        +            record['hierarchy'] = child.get_value()
        +            continue
        +
        +        if child.get_tag() == tags.GEDCOM_TAG_NOTE:
        +            record['notes'].append(note_structure(child))
        +            continue
        +
        +        if child.get_tag() == tags.GEDCOM_TAG_PHONETIC:
        +            subrecord = {
        +                'name': child.get_value(),
        +                'type': ''
        +            }
        +            for gchild in child.get_child_elements():
        +                if gchild.get_tag() == tags.GEDCOM_TAG_TYPE:
        +                    subrecord['type'] = gchild.get_value()
        +            record['phonetic'].append(subrecord)
        +            continue
        +
        +        if child.get_tag() == tags.GEDCOM_TAG_ROMANIZED:
        +            subrecord = {
        +                'name': child.get_value(),
        +                'type': ''
        +            }
        +            for gchild in child.get_child_elements():
        +                if gchild.get_tag() == tags.GEDCOM_TAG_TYPE:
        +                    subrecord['type'] = gchild.get_value()
        +            record['romanized'].append(subrecord)
        +            continue
        +
        +        if child.get_tag() == tags.GEDCOM_TAG_MAP:
        +            for gchild in child.get_child_elements():
        +                if gchild.get_tag() == tags.GEDCOM_TAG_LATITUDE:
        +                    record['latitude'] = gchild.get_value()
        +                    continue
        +
        +                if gchild.get_tag() == tags.GEDCOM_TAG_LONGITUDE:
        +                    record['longitude'] = gchild.get_value()
        +
        +    return record
        +
        +
        +
        +
        +
        +
        +
        +

        Functions

        +
        +
        +def place_structure(element: Element) -> dict +
        +
        +

        Parse and extract a PLACE_STRUCTURE structure.

        +

        The element should contain the GEDCOM_TAG_PLACE tag.

        +
        + +Expand source code + +
        def place_structure(element: Element) -> dict:
        +    """Parse and extract a `PLACE_STRUCTURE` structure.
        +
        +    The `element` should contain the `gedcom.tags.GEDCOM_TAG_PLACE` tag.
        +    """
        +    record = {
        +        'name': element.get_value(),
        +        'hierarchy': '',
        +        'phonetic': [],
        +        'romanized': [],
        +        'latitude': '',
        +        'longitude': '',
        +        'notes': []
        +    }
        +    for child in element.get_child_elements():
        +        if child.get_tag() == tags.GEDCOM_TAG_FORMAT:
        +            record['hierarchy'] = child.get_value()
        +            continue
        +
        +        if child.get_tag() == tags.GEDCOM_TAG_NOTE:
        +            record['notes'].append(note_structure(child))
        +            continue
        +
        +        if child.get_tag() == tags.GEDCOM_TAG_PHONETIC:
        +            subrecord = {
        +                'name': child.get_value(),
        +                'type': ''
        +            }
        +            for gchild in child.get_child_elements():
        +                if gchild.get_tag() == tags.GEDCOM_TAG_TYPE:
        +                    subrecord['type'] = gchild.get_value()
        +            record['phonetic'].append(subrecord)
        +            continue
        +
        +        if child.get_tag() == tags.GEDCOM_TAG_ROMANIZED:
        +            subrecord = {
        +                'name': child.get_value(),
        +                'type': ''
        +            }
        +            for gchild in child.get_child_elements():
        +                if gchild.get_tag() == tags.GEDCOM_TAG_TYPE:
        +                    subrecord['type'] = gchild.get_value()
        +            record['romanized'].append(subrecord)
        +            continue
        +
        +        if child.get_tag() == tags.GEDCOM_TAG_MAP:
        +            for gchild in child.get_child_elements():
        +                if gchild.get_tag() == tags.GEDCOM_TAG_LATITUDE:
        +                    record['latitude'] = gchild.get_value()
        +                    continue
        +
        +                if gchild.get_tag() == tags.GEDCOM_TAG_LONGITUDE:
        +                    record['longitude'] = gchild.get_value()
        +
        +    return record
        +
        +
        +
        +
        +
        +
        +
        + +
        + + + + + \ No newline at end of file diff --git a/docs/gedcom/subparsers/source_citation.html b/docs/gedcom/subparsers/source_citation.html new file mode 100644 index 0000000..f867a30 --- /dev/null +++ b/docs/gedcom/subparsers/source_citation.html @@ -0,0 +1,233 @@ + + + + + + +gedcom.subparsers.source_citation API documentation + + + + + + + + + +
        +
        +
        +

        Module gedcom.subparsers.source_citation

        +
        +
        +

        Substructure parser for a SOURCE_CITATION record.

        +

        This is anchored by the GEDCOM_TAG_SOURCE tag.

        +
        + +Expand source code + +
        # -*- coding: utf-8 -*-
        +
        +# Python GEDCOM Parser
        +#
        +# Copyright (C) 2020 Christopher Horn (cdhorn at embarqmail dot com)
        +#
        +# 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.
        +#
        +# Further information about the license: http://www.gnu.org/licenses/gpl-2.0.html
        +
        +"""
        +Substructure parser for a `SOURCE_CITATION` record.
        +
        +This is anchored by the `gedcom.tags.GEDCOM_TAG_SOURCE` tag.
        +"""
        +
        +import gedcom.tags as tags
        +from gedcom.element.element import Element
        +from gedcom.subparsers.multimedia_link import multimedia_link
        +from gedcom.subparsers.note_structure import note_structure
        +
        +CITATION_TAGS = {
        +    tags.GEDCOM_TAG_PAGE: 'page',
        +    tags.GEDCOM_TAG_DATE: 'date',
        +    tags.GEDCOM_TAG_QUALITY_OF_DATA: 'quality',
        +    tags.GEDCOM_PROGRAM_DEFINED_TAG_APID: 'apid'
        +}
        +
        +
        +def source_citation(element: Element) -> dict:
        +    """Parse and extract a `SOURCE_CITATION` structure.
        +
        +    The `element` should contain the `gedcom.tags.GEDCOM_TAG_SOURCE` tag.
        +    """
        +    record = {
        +        'key_to_source': element.get_value(),
        +        'source': '',
        +        'page': '',
        +        'event': '',
        +        'role': '',
        +        'date': '',
        +        'text': '',
        +        'media': [],
        +        'notes': [],
        +        'quality': '',
        +        'apid': ''
        +    }
        +    if record['key_to_source'] not in [None, '']:
        +        if '@' not in record['key_to_source']:
        +            record['key_to_source'] = ''
        +            record['source'] = element.get_multi_line_value()
        +
        +    for child in element.get_child_elements():
        +        if child.get_tag() in CITATION_TAGS:
        +            record[CITATION_TAGS[child.get_tag()]] = child.get_value()
        +            continue
        +
        +        if child.get_tag() == tags.GEDCOM_TAG_EVENT:
        +            record['event'] = child.get_value()
        +            for gchild in child.get_child_elements():
        +                if gchild.get_tag() == tags.GEDCOM_TAG_ROLE:
        +                    record['role'] = gchild.get_value()
        +            continue
        +
        +        if child.get_tag() == tags.GEDCOM_TAG_DATA:
        +            for gchild in child.get_child_elements():
        +                if gchild.get_tag() == tags.GEDCOM_TAG_DATE:
        +                    record['date'] = gchild.get_value()
        +                    continue
        +                if gchild.get_tag() == tags.GEDCOM_TAG_TEXT:
        +                    record['text'] = gchild.get_multi_line_value()
        +            continue
        +
        +        if child.get_tag() == tags.GEDCOM_TAG_OBJECT:
        +            record['media'].append(multimedia_link(child))
        +            continue
        +
        +        if child.get_tag() == tags.GEDCOM_TAG_NOTE:
        +            record['notes'].append(note_structure(child))
        +            continue
        +
        +        if child.get_tag() == tags.GEDCOM_TAG_TEXT:
        +            record['text'] = child.get_multi_line_value()
        +
        +    return record
        +
        +
        +
        +
        +
        +
        +
        +

        Functions

        +
        +
        +def source_citation(element: Element) -> dict +
        +
        +

        Parse and extract a SOURCE_CITATION structure.

        +

        The element should contain the GEDCOM_TAG_SOURCE tag.

        +
        + +Expand source code + +
        def source_citation(element: Element) -> dict:
        +    """Parse and extract a `SOURCE_CITATION` structure.
        +
        +    The `element` should contain the `gedcom.tags.GEDCOM_TAG_SOURCE` tag.
        +    """
        +    record = {
        +        'key_to_source': element.get_value(),
        +        'source': '',
        +        'page': '',
        +        'event': '',
        +        'role': '',
        +        'date': '',
        +        'text': '',
        +        'media': [],
        +        'notes': [],
        +        'quality': '',
        +        'apid': ''
        +    }
        +    if record['key_to_source'] not in [None, '']:
        +        if '@' not in record['key_to_source']:
        +            record['key_to_source'] = ''
        +            record['source'] = element.get_multi_line_value()
        +
        +    for child in element.get_child_elements():
        +        if child.get_tag() in CITATION_TAGS:
        +            record[CITATION_TAGS[child.get_tag()]] = child.get_value()
        +            continue
        +
        +        if child.get_tag() == tags.GEDCOM_TAG_EVENT:
        +            record['event'] = child.get_value()
        +            for gchild in child.get_child_elements():
        +                if gchild.get_tag() == tags.GEDCOM_TAG_ROLE:
        +                    record['role'] = gchild.get_value()
        +            continue
        +
        +        if child.get_tag() == tags.GEDCOM_TAG_DATA:
        +            for gchild in child.get_child_elements():
        +                if gchild.get_tag() == tags.GEDCOM_TAG_DATE:
        +                    record['date'] = gchild.get_value()
        +                    continue
        +                if gchild.get_tag() == tags.GEDCOM_TAG_TEXT:
        +                    record['text'] = gchild.get_multi_line_value()
        +            continue
        +
        +        if child.get_tag() == tags.GEDCOM_TAG_OBJECT:
        +            record['media'].append(multimedia_link(child))
        +            continue
        +
        +        if child.get_tag() == tags.GEDCOM_TAG_NOTE:
        +            record['notes'].append(note_structure(child))
        +            continue
        +
        +        if child.get_tag() == tags.GEDCOM_TAG_TEXT:
        +            record['text'] = child.get_multi_line_value()
        +
        +    return record
        +
        +
        +
        +
        +
        +
        +
        + +
        + + + + + \ No newline at end of file diff --git a/docs/gedcom/subparsers/source_repository_citation.html b/docs/gedcom/subparsers/source_repository_citation.html new file mode 100644 index 0000000..f711032 --- /dev/null +++ b/docs/gedcom/subparsers/source_repository_citation.html @@ -0,0 +1,167 @@ + + + + + + +gedcom.subparsers.source_repository_citation API documentation + + + + + + + + + +
        +
        +
        +

        Module gedcom.subparsers.source_repository_citation

        +
        +
        +

        Substructure parser for a SOURCE_REPOSITORY_CITATION record.

        +

        This is anchored by the GEDCOM_TAG_REPOSITORY tag.

        +
        + +Expand source code + +
        # -*- coding: utf-8 -*-
        +
        +# Python GEDCOM Parser
        +#
        +# Copyright (C) 2020 Christopher Horn (cdhorn at embarqmail dot com)
        +#
        +# 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.
        +#
        +# Further information about the license: http://www.gnu.org/licenses/gpl-2.0.html
        +
        +"""
        +Substructure parser for a `SOURCE_REPOSITORY_CITATION` record.
        +
        +This is anchored by the `gedcom.tags.GEDCOM_TAG_REPOSITORY` tag.
        +"""
        +
        +import gedcom.tags as tags
        +from gedcom.element.element import Element
        +from gedcom.subparsers.note_structure import note_structure
        +
        +
        +def source_repository_citation(element: Element) -> dict:
        +    """Parse and extract a `SOURCE_REPOSITORY_CITATION` structure.
        +
        +    The `element` should contain the `gedcom.tags.GEDCOM_TAG_REPOSITORY` tag.
        +    """
        +    record = {
        +        'key_to_repository': element.get_value(),
        +        'call_number': '',
        +        'media_type': '',
        +        'notes': []
        +    }
        +    if record['key_to_repository'] not in [None, '']:
        +        if '@' not in record['key_to_repository']:
        +            record['key_to_repository'] = ''
        +
        +    for child in element.get_child_elements():
        +        if child.get_tag() == tags.GEDCOM_TAG_NOTE:
        +            record['notes'].append(note_structure(child))
        +            continue
        +
        +        if child.get_tag() == tags.GEDCOM_TAG_CALL_NUMBER:
        +            record['call_number'] = child.get_value()
        +            for gchild in child.get_child_elements():
        +                if gchild.get_tag() == tags.GEDCOM_TAG_MEDIA:
        +                    record['media_type'] = gchild.get_value()
        +
        +    return record
        +
        +
        +
        +
        +
        +
        +
        +

        Functions

        +
        +
        +def source_repository_citation(element: Element) -> dict +
        +
        +

        Parse and extract a SOURCE_REPOSITORY_CITATION structure.

        +

        The element should contain the GEDCOM_TAG_REPOSITORY tag.

        +
        + +Expand source code + +
        def source_repository_citation(element: Element) -> dict:
        +    """Parse and extract a `SOURCE_REPOSITORY_CITATION` structure.
        +
        +    The `element` should contain the `gedcom.tags.GEDCOM_TAG_REPOSITORY` tag.
        +    """
        +    record = {
        +        'key_to_repository': element.get_value(),
        +        'call_number': '',
        +        'media_type': '',
        +        'notes': []
        +    }
        +    if record['key_to_repository'] not in [None, '']:
        +        if '@' not in record['key_to_repository']:
        +            record['key_to_repository'] = ''
        +
        +    for child in element.get_child_elements():
        +        if child.get_tag() == tags.GEDCOM_TAG_NOTE:
        +            record['notes'].append(note_structure(child))
        +            continue
        +
        +        if child.get_tag() == tags.GEDCOM_TAG_CALL_NUMBER:
        +            record['call_number'] = child.get_value()
        +            for gchild in child.get_child_elements():
        +                if gchild.get_tag() == tags.GEDCOM_TAG_MEDIA:
        +                    record['media_type'] = gchild.get_value()
        +
        +    return record
        +
        +
        +
        +
        +
        +
        +
        + +
        + + + + + \ No newline at end of file diff --git a/docs/gedcom/subparsers/spouse_to_family_link.html b/docs/gedcom/subparsers/spouse_to_family_link.html new file mode 100644 index 0000000..6a77ff3 --- /dev/null +++ b/docs/gedcom/subparsers/spouse_to_family_link.html @@ -0,0 +1,141 @@ + + + + + + +gedcom.subparsers.spouse_to_family_link API documentation + + + + + + + + + +
        +
        +
        +

        Module gedcom.subparsers.spouse_to_family_link

        +
        +
        +

        Substructure parser for a SPOUSE_TO_FAMILY_LINK record.

        +

        This is anchored by the GEDCOM_TAG_FAMILY_SPOUSE tag.

        +
        + +Expand source code + +
        # -*- coding: utf-8 -*-
        +
        +# Python GEDCOM Parser
        +#
        +# Copyright (C) 2020 Christopher Horn (cdhorn at embarqmail dot com)
        +#
        +# 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.
        +#
        +# Further information about the license: http://www.gnu.org/licenses/gpl-2.0.html
        +
        +"""
        +Substructure parser for a `SPOUSE_TO_FAMILY_LINK` record.
        +
        +This is anchored by the `gedcom.tags.GEDCOM_TAG_FAMILY_SPOUSE` tag.
        +"""
        +
        +import gedcom.tags as tags
        +from gedcom.element.element import Element
        +from gedcom.subparsers.note_structure import note_structure
        +
        +
        +def spouse_to_family_link(element: Element) -> dict:
        +    """Parse and extract a `SPOUSE_TO_FAMILY_LINK` structure.
        +
        +    The `element` should contain the `gedcom.tags.GEDCOM_TAG_FAMILY_SPOUSE` tag.
        +    """
        +    record = {
        +        'key_to_family': element.get_value(),
        +        'notes': []
        +    }
        +    for child in element.get_child_elements():
        +        if child.get_tag() == tags.GEDCOM_TAG_NOTE:
        +            record['notes'].append(note_structure(child))
        +
        +    return record
        +
        +
        +
        +
        +
        +
        +
        +

        Functions

        +
        + +
        +

        Parse and extract a SPOUSE_TO_FAMILY_LINK structure.

        +

        The element should contain the GEDCOM_TAG_FAMILY_SPOUSE tag.

        +
        + +Expand source code + +
        def spouse_to_family_link(element: Element) -> dict:
        +    """Parse and extract a `SPOUSE_TO_FAMILY_LINK` structure.
        +
        +    The `element` should contain the `gedcom.tags.GEDCOM_TAG_FAMILY_SPOUSE` tag.
        +    """
        +    record = {
        +        'key_to_family': element.get_value(),
        +        'notes': []
        +    }
        +    for child in element.get_child_elements():
        +        if child.get_tag() == tags.GEDCOM_TAG_NOTE:
        +            record['notes'].append(note_structure(child))
        +
        +    return record
        +
        +
        +
        +
        +
        +
        +
        + +
        + + + + + \ No newline at end of file diff --git a/docs/gedcom/subparsers/user_reference_number.html b/docs/gedcom/subparsers/user_reference_number.html new file mode 100644 index 0000000..252d224 --- /dev/null +++ b/docs/gedcom/subparsers/user_reference_number.html @@ -0,0 +1,145 @@ + + + + + + +gedcom.subparsers.user_reference_number API documentation + + + + + + + + + +
        +
        +
        +

        Module gedcom.subparsers.user_reference_number

        +
        +
        +

        Parser for a USER_REFERENCE_NUMBER structure.

        +

        This is anchored by the GEDCOM_TAG_REFERENCE tag.

        +

        This is not a formally documented structure in the standard but it is +a substructure that repeats itself in a number of record types.

        +
        + +Expand source code + +
        # -*- coding: utf-8 -*-
        +
        +# Python GEDCOM Parser
        +#
        +# Copyright (C) 2020 Christopher Horn (cdhorn at embarqmail dot com)
        +#
        +# 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.
        +#
        +# Further information about the license: http://www.gnu.org/licenses/gpl-2.0.html
        +
        +"""
        +Parser for a `USER_REFERENCE_NUMBER` structure.
        +
        +This is anchored by the `gedcom.tags.GEDCOM_TAG_REFERENCE` tag.
        +
        +This is not a formally documented structure in the standard but it is
        +a substructure that repeats itself in a number of record types.
        +"""
        +
        +import gedcom.tags as tags
        +from gedcom.element.element import Element
        +
        +
        +def user_reference_number(element: Element) -> dict:
        +    """Parse and extract a `USER_REFERENCE_NUMBER` structure.
        +
        +    The `element` should contain the `gedcom.tags.GEDCOM_TAG_REFERENCE` tag.
        +    """
        +    record = {
        +        'reference': element.get_value(),
        +        'type': ''
        +    }
        +    for child in element.get_child_elements():
        +        if child.get_tag() == tags.GEDCOM_TAG_TYPE:
        +            record['type'] = child.get_value()
        +
        +    return record
        +
        +
        +
        +
        +
        +
        +
        +

        Functions

        +
        +
        +def user_reference_number(element: Element) -> dict +
        +
        +

        Parse and extract a USER_REFERENCE_NUMBER structure.

        +

        The element should contain the GEDCOM_TAG_REFERENCE tag.

        +
        + +Expand source code + +
        def user_reference_number(element: Element) -> dict:
        +    """Parse and extract a `USER_REFERENCE_NUMBER` structure.
        +
        +    The `element` should contain the `gedcom.tags.GEDCOM_TAG_REFERENCE` tag.
        +    """
        +    record = {
        +        'reference': element.get_value(),
        +        'type': ''
        +    }
        +    for child in element.get_child_elements():
        +        if child.get_tag() == tags.GEDCOM_TAG_TYPE:
        +            record['type'] = child.get_value()
        +
        +    return record
        +
        +
        +
        +
        +
        +
        +
        + +
        + + + + + \ No newline at end of file diff --git a/docs/gedcom/tags.html b/docs/gedcom/tags.html index f1c5491..ae9d7c5 100644 --- a/docs/gedcom/tags.html +++ b/docs/gedcom/tags.html @@ -3,14 +3,14 @@ - + gedcom.tags API documentation - + - - + + @@ -20,7 +20,7 @@

        Module gedcom.tags

        -

        GEDCOM tags.

        +

        Module containing the standard GEDCOM tags and some of the most common program defined extensions.

        Expand source code @@ -29,6 +29,7 @@

        Module gedcom.tags

        # Python GEDCOM Parser # +# Copyright (C) 2020 Christopher Horn (cdhorn at embarqmail dot com) # Copyright (C) 2018 Damon Brodie (damon.brodie at gmail.com) # Copyright (C) 2018-2019 Nicklas Reincke (contact at reynke.com) # Copyright (C) 2016 Andreas Oberritter @@ -53,63 +54,392 @@

        Module gedcom.tags

        # Further information about the license: http://www.gnu.org/licenses/gpl-2.0.html """ -GEDCOM tags. +Module containing the standard GEDCOM tags and some of the most common program defined extensions. """ -GEDCOM_PROGRAM_DEFINED_TAG_MREL = "_MREL" -"""Value: `_MREL` +GEDCOM_PROGRAM_DEFINED_TAG_ADDRESSE = "_NAME" +"""Value: `_NAME` + +Name of addresse in a `gedcom.tags.GEDCOM_TAG_ADDRESS` structure. + +5.5.1 GEDCOM-L Addendum.""" + +GEDCOM_PROGRAM_DEFINED_TAG_ADMINISTRATIVE_ID = "_AIDN" +"""Value: `_AIDN` + +Identifier for a location with the intention of an administrative authority, +e.g. community identifier. + +5.5.1 GEDCOM-L Addendum.""" + +GEDCOM_PROGRAM_DEFINED_TAG_APID = "_APID" +"""Value: `_APID` + +Ancestry page identifier. For a citation, points to the page in a Ancestry +database for the record supporting the citation. For a source record it +points to the database as a whole. + +Ancestry.com Extension.""" + +GEDCOM_PROGRAM_DEFINED_TAG_DCAUSE = "_DCAUSE" +"""Value: `_DCAUSE` + +Cause of death.""" + +GEDCOM_PROGRAM_DEFINED_TAG_DEGREE = "_DEG" +"""Value: `_DEG` + +Degree or recognition of accomplishment received by an individual.""" + +GEDCOM_PROGRAM_DEFINED_TAG_DEMOGRAPHIC_DATA = "_DMGD" +"""Value: `_DMGD` + +A number of ojects, during an ascertainment, e.g. the count of households. -Relationship to a mother.""" +5.5.1 GEDCOM-L Addendum.""" GEDCOM_PROGRAM_DEFINED_TAG_FREL = "_FREL" """Value: `_FREL` -Relationship to a father.""" +Type of relationship between child and the father in a family.""" + +GEDCOM_PROGRAM_DEFINED_TAG_FUNERAL = "_FUN" +"""Value: `_FUN` + +Funeral for an individual.""" + +GEDCOM_PROGRAM_DEFINED_TAG_GOVERNMENT = "_GOV" +"""Value: `_GOV` + +The official government id of the object in the Historical Place Register / +Historic Gazeteer. + +5.5.1 GEDCOM-L Addendum.""" + +GEDCOM_PROGRAM_DEFINED_TAG_GOVERNMENT_TYPE = "_GOVTYPE" +"""Value: `_GOVTYPE` + +An integer positive number as defined in the GOV system. +See http://gov.genealogy.net.net/type/list. + +5.5.1 GEDCOM-L Addendum.""" + +GEDCOM_PROGRAM_DEFINED_TAG_HOME_PERSON = "_HME" +"""Value: `_HME` + +Home person in the tree.""" + +GEDCOM_PROGRAM_DEFINED_TAG_LOCATION = "_LOC" +"""Value: `_LOC` + +Location data record. + +5.5.1 GEDCOM-L Addendum.""" + +GEDCOM_PROGRAM_DEFINED_TAG_MAIDENHEAD = "_MAIDENHEAD" +"""Value: `_MAIDENHEAD` + +The maidenhead code. + +5.5.1 GEDCOM-L Addendum.""" + +GEDCOM_PROGRAM_DEFINED_TAG_MEDICAL = "_MDCL" +"""Value: `_MDCL` + +Medical information about an individual.""" + +GEDCOM_PROGRAM_DEFINED_TAG_MILITARY = "_MILT" +"""Value: `_MILT` + +A military related event in the individuals life.""" + +GEDCOM_PROGRAM_DEFINED_TAG_MREL = "_MREL" +"""Value: `_MREL` + +Type of relationship between child and the mother in a family.""" + +GEDCOM_PROGRAM_DEFINED_TAG_PHOTO = "_PHOTO" +"""Value: `_PHOTO` + +Used by some programs to identify the primary multimedia object for an +individual, the same as `gedcom.tags.GEDCOM_PROGRAM_DEFINED_TAG_PRIMARY`.""" + +GEDCOM_PROGRAM_DEFINED_TAG_POSTAL_CODE = "_POST" +"""Value: `_POST` + +The official zip code, called ADDRESS_POSTAL_CODE in the standard. + +5.5.1 GEDCOM-L Addendum.""" + +GEDCOM_PROGRAM_DEFINED_TAG_PREFERRED = "_PREF" +"""Value: `_PREF` + +Indicates a preferred spouse, child or parents.""" + +GEDCOM_PROGRAM_DEFINED_TAG_PRIMARY = "_PRIM" +"""Value: `_PRIM` + +Primary multimedia object for an individual.""" + +GEDCOM_PROGRAM_DEFINED_TAG_SCHEMA = "_SCHEMA" +"""Value: `_SCHEMA` + +Schema substructure extension to describe user defined tags. + +5.5.1 GEDCOM-L Addendum.""" + +GEDCOM_PROGRAM_DEFINED_TAG_RUFNAME = "_RUFNAME" +"""Value: `_RUFNAME` + +An official given name of a German individual used in legal documents. + +5.5.1 GEDCOM-L Addendum.""" + +GEDCOM_PROGRAM_DEFINED_TAG_UUID = "_UID" +"""Value: `_UID` + +Universal identification number. + +5.5.1 GEDCOM-L Addendum.""" + +GEDCOM_TAG_ABBREVIATION = "ABBR" +"""Value: `ABBR` + +A short name of a title, description, or name.""" + +GEDCOM_TAG_ADDRESS = "ADDR" +"""Value: `ADDR` + +The contemporary place, usually required for postal purposes, of an individual, +a submitter of information, a repository, a business, a school, or a company.""" + +GEDCOM_TAG_ADDRESS1 = "ADR1" +"""Value: `ADR1` + +The first line of an address.""" + +GEDCOM_TAG_ADDRESS2 = "ADR2" +"""Value: `ADR2` + +The second line of an address.""" + +GEDCOM_TAG_ADDRESS3 = "ADR3" +"""Value: `ADR3` + +The third line of an address.""" + +GEDCOM_TAG_ADOPTION = "ADOP" +"""Value: `ADOP` + +Pertaining to creation of a child-parent relationship that does not exist +biologically.""" + +GEDCOM_TAG_AFN = "AFN" +"""Value: `AFN` + +Ancestral File Number, a unique permanent record file number of an individual +record stored in Ancestral File.""" + +GEDCOM_TAG_AGE = "AGE" +"""Value: `AGE` + +The age of the individual at the time an event occurred, or the age listed in +the document.""" + +GEDCOM_TAG_AGENCY = "AGNC" +"""Value: `AGNC` + +The institution or individual having authority and/or responsibility to manage +or govern.""" + +GEDCOM_TAG_ALIAS = "ALIA" +"""Value: `ALIA` + +An indicator to link different record descriptions of a person who may be the +same person.""" + +GEDCOM_TAG_ANCESTORS = "ANCE" +"""Value: `ANCE` + +Pertaining to forbearers of an individual.""" + +GEDCOM_TAG_ANCES_INTEREST = "ANCI" +"""Value: `ANCI` + +Indicates an interest in additional research for ancestors of this individual. +(See also `gedcom.tags.GEDCOM_TAG_DESCENDANTS_INT`)""" + +GEDCOM_TAG_ANNULMENT = "ANUL" +"""Value: `ANUL` + +Declaring a marriage void from the beginning (never existed).""" + +GEDCOM_TAG_ASSOCIATES = "ASSO" +"""Value: `ASSO` + +An indicator to link friends, neighbors, relatives, or associates of an +individual.""" + +GEDCOM_TAG_AUTHOR = "AUTH" +"""Value: `AUTH` + +The name of the individual who created or compiled information.""" + +GEDCOM_TAG_BAPTISM_LDS = "BAPL" +"""Value: `BAPL` + +The event of baptism performed at age eight or later by priesthood authority +of the LDS Church. (See also `gedcom.tags.GEDCOM_TAG_BAPTISM`)""" + +GEDCOM_TAG_BAPTISM = "BAPM" +"""Value: `BAPM` + +The event of baptism (not LDS), performed in infancy or later.""" + +GEDCOM_TAG_BAR_MITZVAH = "BARM" +"""Value: `BARM` + +The ceremonial event held when a Jewish boy reaches age 13.""" + +GEDCOM_TAG_BAS_MITZVAH = "BASM" +"""Value: `BASM` + +The ceremonial event held when a Jewish girl reaches age 13, also known as +Bat Mitzvah.""" GEDCOM_TAG_BIRTH = "BIRT" """Value: `BIRT` The event of entering into life.""" +GEDCOM_TAG_BLESSING = "BLES" +"""Value: `BLES` + +A religious event of bestowing divine care or intercession. Sometimes given +in connection with a naming ceremony.""" + GEDCOM_TAG_BURIAL = "BURI" """Value: `BURI` The event of the proper disposing of the mortal remains of a deceased person.""" +GEDCOM_TAG_CALL_NUMBER = "CALN" +"""Value: `CALN` + +The number used by a repository to identify the specific items in its +collections.""" + +GEDCOM_TAG_CASTE = "CAST" +"""Value: `CAST` + +The name of an individual's rank or status in society, based on racial or +religious differences, or differences in wealth, inherited rank, profession, +occupation, etc.""" + +GEDCOM_TAG_CAUSE = "CAUSE" +"""Value: `CAUS` + +A description of the cause of the associated event or fact, such as the cause +of death.""" + GEDCOM_TAG_CENSUS = "CENS" """Value: `CENS`. -The event of the periodic count of the population for a designated locality, such as a national or state Census.""" +The event of the periodic count of the population for a designated locality, +such as a national or state Census.""" GEDCOM_TAG_CHANGE = "CHAN" """Value: `CHAN` Indicates a change, correction, or modification. Typically used in connection -with a `gedcom.tags.GEDCOM_TAG_DATE` to specify when a change in information occurred.""" +with a `gedcom.tags.GEDCOM_TAG_DATE` to specify when a change in information +occurred.""" + +GEDCOM_TAG_CHARACTER = "CHAR" +"""Value: `CHAR` + +An indicator of the character set used in writing this automated information.""" GEDCOM_TAG_CHILD = "CHIL" """Value: `CHIL` The natural, adopted, or sealed (LDS) child of a father and a mother.""" +GEDCOM_TAG_CHRISTENING = "CHR" +"""Value: `CHR` + +The religious event (not LDS) of baptizing and/or naming a child.""" + +GEDCOM_TAG_ADULT_CHRISTENING = "CHRA" +"""Value: `CHRA` + +The religious event (not LDS) of baptizing and/or naming an adult person.""" + +GEDCOM_TAG_CITY = "CITY" +"""Value: `CITY` + +A lower level jurisdictional unit. Normally an incorporated municipal unit.""" + GEDCOM_TAG_CONCATENATION = "CONC" """Value: `CONC` -An indicator that additional data belongs to the superior value. The information from the `CONC` value is to -be connected to the value of the superior preceding line without a space and without a carriage return and/or -new line character. Values that are split for a `CONC` tag must always be split at a non-space. If the value is -split on a space the space will be lost when concatenation takes place. This is because of the treatment that -spaces get as a GEDCOM delimiter, many GEDCOM values are trimmed of trailing spaces and some systems look for -the first non-space starting after the tag to determine the beginning of the value.""" +An indicator that additional data belongs to the superior value. The information +from the `CONC` value is to be connected to the value of the superior preceding +line without a space and without a carriage return and/or new line character. +Values that are split for a `CONC` tag must always be split at a non-space. If +the value is split on a space the space will be lost when concatenation takes +place. This is because of the treatment that spaces get as a GEDCOM delimiter, +many GEDCOM values are trimmed of trailing spaces and some systems look for +the first non-space starting after the tag to determine the beginning of the +value.""" + +GEDCOM_TAG_CONFIRMATION = "CONF" +"""Value: `CONF` + +The religious event (not LDS) of conferring the gift of the Holy Ghost and, +among protestants, full church membership.""" + +GEDCOM_TAG_CONFIRMATION_L = "CONL" +"""Value: `CONL` + +The religious event by which a person receives membership in the LDS Church.""" GEDCOM_TAG_CONTINUED = "CONT" """Value: `CONT` -An indicator that additional data belongs to the superior value. The information from the `CONT` value is to be -connected to the value of the superior preceding line with a carriage return and/or new line character. -Leading spaces could be important to the formatting of the resultant text. When importing values from `CONT` lines -the reader should assume only one delimiter character following the `CONT` tag. Assume that the rest of the leading -spaces are to be a part of the value.""" +An indicator that additional data belongs to the superior value. The information +from the `CONT` value is to be connected to the value of the superior preceding +line with a carriage return and/or new line character. Leading spaces could be +important to the formatting of the resultant text. When importing values from +`CONT` lines the reader should assume only one delimiter character following +the `CONT` tag. Assume that the rest of the leading spaces are to be a part +of the value.""" + +GEDCOM_TAG_COPYRIGHT = "COPR" +"""Value: `COPR` + +A statement that accompanies data to protect it from unlawful duplication +and distribution.""" + +GEDCOM_TAG_CORPORATE = "CORP" +"""Value: `CORP` + +A name of an institution, agency, corporation, or company.""" + +GEDCOM_TAG_CREMATION = "CREM" +"""Value: `CREM` + +Disposal of the remains of a person's body by fire.""" + +GEDCOM_TAG_COUNTRY = "CTRY" +"""Value: `CTRY` + +The name or code of a country.""" + +GEDCOM_TAG_DATA = "DATA" +"""Value: `DATA` + +Pertaining to stored automation information.""" GEDCOM_TAG_DATE = "DATE" """Value: `DATE` @@ -121,93 +451,542 @@

        Module gedcom.tags

        The event when mortal life terminates.""" +GEDCOM_TAG_DESCENDANTS = "DESC" +"""Value: `DESC` + +Pertaining to offspring of an individual.""" + +GEDCOM_TAG_DESCENDANTS_INT = "DESI" +"""Value: `DESI` + +Indicates an interest in research to identify additional descendants of this +individual. (See also `gedcom.tags.GEDCOM_TAG_ANCES_INTEREST`)""" + +GEDCOM_TAG_DESTINATION = "DEST" +"""Value: `DEST` + +A system receiving data.""" + +GEDCOM_TAG_DIVORCE = "DIV" +"""Value: `DIV` + +The event of disolving a marriage through civil action.""" + +GEDCOM_TAG_DIVORCE_FILED = "DIVF" +"""Value: `DIVF` + +An event of filing for a divorce by a spouse.""" + +GEDCOM_TAG_PHY_DESCRIPTION = "DSCR" +"""Value: `DSCR` + +The physical characteristics of a person, place, or thing.""" + +GEDCOM_TAG_EDUCATION = "EDUC" +"""Value: `EDUC` + +Indicator of a level of education attained.""" + +GEDCOM_TAG_EMAIL = "EMAIL" +"""Value: `EMAIL` + +An electronic address that can be used for contact such as an email address.""" + +GEDCOM_TAG_EMIGRATION = "EMIG" +"""Value: `EMIG` + +An event of leaving one's homeland with the intent of residing elsewhere.""" + +GEDCOM_TAG_ENDOWMENT = "ENDL" +"""Value: `ENDL` + +A religious event where an endowment ordinance for an individual was performed +by priesthood authority in an LDS temple.""" + +GEDCOM_TAG_ENGAGEMENT = "ENGA" +"""Value: `ENGA` + +An event of recording or announcing an agreement between two people to become +married.""" + +GEDCOM_TAG_EVENT = "EVEN" +"""Value: `EVEN` + +A noteworthy happening related to an individual, a group, or an organization.""" + +GEDCOM_TAG_FACT = "FACT" +"""Value: `FACT` + +Pertaining to a noteworthy attribute or fact concerning an individual, a group, +or an organization. A `FACT` structure is usually qualified or classified by a +subordinate use of the `gedcom.tags.GEDCOM_TAG_TYPE` tag.""" + GEDCOM_TAG_FAMILY = "FAM" """Value: `FAM`. -Identifies a legal, common law, or other customary relationship of man and woman and their children, -if any, or a family created by virtue of the birth of a child to its biological father and mother.""" +Identifies a legal, common law, or other customary relationship of man and woman +and their children, if any, or a family created by virtue of the birth of a +child to its biological father and mother.""" GEDCOM_TAG_FAMILY_CHILD = "FAMC" """Value: `FAMC` Identifies the family in which an individual appears as a child.""" +GEDCOM_TAG_FAMILY_FILE = "FAMF" +"""Value: `FAMF` + +Pertaining to, or the name of, a family file. Names stored in a file that are +assigned to a family for doing temple ordinance work.""" + GEDCOM_TAG_FAMILY_SPOUSE = "FAMS" """Value: `FAMS` Identifies the family in which an individual appears as a spouse.""" +GEDCOM_TAG_FAX = "FAX" +"""Value: `FAX` + +A FAX telephone number appropriate for sending data facsimiles.""" + +GEDCOM_TAG_FIRST_COMMUNION = "FCOM" +"""Value: `FCOM` + +A religious rite, the first act of sharing in the Lord's supper as part of +church worship.""" + GEDCOM_TAG_FILE = "FILE" """Value: `FILE` -An information storage place that is ordered and arranged for preservation and reference.""" +An information storage place that is ordered and arranged for preservation and +reference.""" + +GEDCOM_TAG_PHONETIC = "FONE" +"""Value: `FONE` + +A phonetic variation of a superior text string.""" + +GEDCOM_TAG_FORMAT = "FORM" +"""Value: `FORM` + +An assigned name given to a consistent format in which information can be +conveyed.""" + +GEDCOM_TAG_GEDCOM = "GEDC" +"""Value: `GEDC` + +Information about the use of GEDCOM in a transmission.""" GEDCOM_TAG_GIVEN_NAME = "GIVN" """Value: `GIVN` A given or earned name used for official identification of a person.""" +GEDCOM_TAG_GRADUATION = "GRAD" +"""Value: `GRAD` + +An event of awarding educational diplomas or degrees to individuals.""" + +GEDCOM_TAG_HEADER = "HEAD" +"""Value: `HEAD` + +Identifies information pertaining to an entire GEDCOM transmission.""" + GEDCOM_TAG_HUSBAND = "HUSB" """Value: `HUSB` An individual in the family role of a married man or father.""" +GEDCOM_TAG_IDENT_NUMBER = "IDNO" +"""Value: `IDNO` + +A number assigned to identify a person within some significant external system.""" + +GEDCOM_TAG_IMMIGRATION = "IMMI" +"""Value: `IMMI` + +An event of entering into a new locality witht he intent of residing there.""" + GEDCOM_TAG_INDIVIDUAL = "INDI" """Value: `INDI` A person.""" +GEDCOM_TAG_LANGUAGE = "LANG" +"""Value: `LANG` + +The name of the language used in a communication or transmission of information.""" + +GEDCOM_TAG_LATITUDE = "LATI" +"""Value: `LATI` + +A value indicating a coordinate position on a line, plane, or space.""" + +GEDCOM_TAG_LEGATEE = "LEGA" +"""Value: `LEGA` + +A role of an individual acting as a person receiving a bequest or legal devise.""" + +GEDCOM_TAG_LONGITUDE = "LONG" +"""Value: `LONG` + +A value indicating a coordinate position on a line, plane, or space.""" + +GEDCOM_TAG_MAP = "MAP" +"""Value: `MAP` + +Pertains to a representation of measurements usually presented in a graphical +form.""" + +GEDCOM_TAG_MARRIAGE_BANN = "MARB" +"""Value: `MARB`. + +An event of an official public notice given that two people intend to marry.""" + +GEDCOM_TAG_MARR_CONTRACT = "MARC" +"""Value: `MARC`. + +An event of recording a formal agreement of marriage, including the prenuptial +agreement in which marriage partners reach agreement about the property rights +of one or both, securing property to their children.""" + +GEDCOM_TAG_MARR_LICENSE = "MARL" +"""Value: `MARL`. + +An event of obtaining a legal license to marry.""" + GEDCOM_TAG_MARRIAGE = "MARR" """Value: `MARR`. -A legal, common-law, or customary event of creating a family unit of a man and a woman as husband and wife.""" +A legal, common-law, or customary event of creating a family unit of a man and +a woman as husband and wife.""" + +GEDCOM_TAG_MARR_SETTLEMENT = "MARS" +"""Value: `MARS`. + +An event of creating an agreement between two people contemplating marriage, +at which time they agree to release or modify property rights that would +otherwise arise from the marriage.""" + +GEDCOM_TAG_MEDIA = "MEDI" +"""Value: `MEDI`. + +Identifies information about the media or having to do with the medium in which +information is stored.""" GEDCOM_TAG_NAME = "NAME" """Value: `NAME`. -A word or combination of words used to help identify an individual, title, or other item. -More than one NAME line should be used for people who were known by multiple names.""" +A word or combination of words used to help identify an individual, title, or +other item. More than one `NAME` line should be used for people who were known +by multiple names.""" + +GEDCOM_TAG_NATIONALITY = "NATI" +"""Value: `NATI` + +The national heritage of an individual.""" + +GEDCOM_TAG_NATURALIZATION = "NATU" +"""Value: `NATU` + +The event of obtaining citizenship.""" + +GEDCOM_TAG_CHILDREN_COUNT = "NCHI" +"""Value: `NCHI` + +The number of children that this person is known to be the parent of (all +marriages) when subordinate to an individual, or that belong to this family +when subordinate to a `gedcom.tags.GEDCOM_TAG_FAMILY` record.""" + +GEDCOM_TAG_NICKNAME = "NICK" +"""Value: `NICK` + +A descriptive or familiar that is used instead of, or in addition to, one's +proper name.""" + +GEDCOM_TAG_MARRIAGE_COUNT = "NMR" +"""Value: `NMR` + +The number of times this person has participated in a family as a spouse or +parent.""" + +GEDCOM_TAG_NOTE = "NOTE" +"""Value: `NOTE` + +Additional information provided by the submitter for understanding the +enclosing data.""" + +GEDCOM_TAG_NAME_PREFIX = "NPFX" +"""Value: `NPFX` + +Text which appears on a name line before the given and surname parts of a name. +i.e. ( Lt. Cmndr. ) Joseph /Allen/ jr. In this example Lt. Cmndr. is considered +as the name prefix portion.""" + +GEDCOM_TAG_NAME_SUFFIX = "NSFX" +"""Value: `NSFX` + +Text which appears on a name line after or behind the given and surname parts +of a name. i.e. Lt. Cmndr. Joseph /Allen/ ( jr. ) In this example jr. is +considered as the name suffix portion.""" GEDCOM_TAG_OBJECT = "OBJE" """Value: `OBJE` -Pertaining to a grouping of attributes used in describing something. Usually referring to the data required -to represent a multimedia object, such an audio recording, a photograph of a person, or an image of a document.""" +Pertaining to a grouping of attributes used in describing something. Usually +referring to the data required to represent a multimedia object, such an audio +recording, a photograph of a person, or an image of a document.""" GEDCOM_TAG_OCCUPATION = "OCCU" """Value: `OCCU` The type of work or profession of an individual.""" +GEDCOM_TAG_ORDINANCE = "ORDI" +"""Value: `ORDI` + +Pertaining to a religious ordinance in general.""" + +GEDCOM_TAG_ORDINATION = "ORDN" +"""Value: `ORDN` + +A religious event of receiving authority to act in religious matters.""" + +GEDCOM_TAG_PAGE = "PAGE" +"""Value: `PAGE` + +A number or description to identify where information can be found in a +referenced work.""" + +GEDCOM_TAG_PEDIGREE = "PEDI" +"""Value: `PEDI` + +Information pertaining to an individual to parent lineage chart.""" + +GEDCOM_TAG_PHONE = "PHON" +"""Value: `PHON` + +A unique number assigned to access a specific telephone.""" + GEDCOM_TAG_PLACE = "PLAC" """Value: `PLAC` A jurisdictional name to identify the place or location of an event.""" +GEDCOM_TAG_POSTAL_CODE = "POST" +"""Value: `POST` + +A code used by a postal service to identify an area to facilitate mail handling.""" + GEDCOM_TAG_PRIVATE = "PRIV" """Value: `PRIV` Flag for private address or event.""" +GEDCOM_TAG_PROBATE = "PROB" +"""Value: `PROB` + +An event of judicial determination of the validity of a will. May indicate +several related court activities over several dates.""" + +GEDCOM_TAG_PROPERTY = "PROP" +"""Value: `PROP` + +Pertaining to possessions such as real estate or other property of interest.""" + +GEDCOM_TAG_PUBLICATION = "PUBL" +"""Value: `PUBL` + +Refers to when and/or were a work was published or created.""" + +GEDCOM_TAG_QUALITY_OF_DATA = "QUAY" +"""Value: `QUAY` + +An assessment of the certainty of the evidence to support the conclusion drawn +from evidence.""" + +GEDCOM_TAG_REFERENCE = "REFN" +"""Value: `REFN` + +A description or number used to identify an item for filing, storage, or other +reference purposes.""" + +GEDCOM_TAG_RELATIONSHIP = "RELA" +"""Value: `RELA` + +A relationship value between the indicated contexts.""" + +GEDCOM_TAG_RELIGION = "RELI" +"""Value: `RELI` + +A religious denomination to which a person is affiliated or for which a record +applies.""" + +GEDCOM_TAG_REPOSITORY = "REPO" +"""Value: `REPO` + +An institution or person that has the specified item as part of their +collection(s).""" + +GEDCOM_TAG_RESIDENCE = "RESI" +"""Value: `RESI` + +The act of dwelling at a place for a period of time.""" + +GEDCOM_TAG_RESTRICTION = "RESN" +"""Value: `RESN` + +A processing indicator signifying access to information has been denied or +otherwise restricted.""" + +GEDCOM_TAG_RETIREMENT = "RETI" +"""Value: `RETI` + +An event of exiting an occupational relationship with an employer after a +qualifying time period.""" + +GEDCOM_TAG_REC_FILE_NUMBER = "RFN" +"""Value: `RFN` + +A permanent number assigned to a record that uniquely identifies it within a +known file.""" + +GEDCOM_TAG_REC_ID_NUMBER = "RIN" +"""Value: `RIN` + +A number assigned to a record by an originating automated system that can be +used by a receiving system to report results pertaining to that record.""" + +GEDCOM_TAG_ROLE = "ROLE" +"""Value: `ROLE` + +A name given to a role played by an individual in connection with an event.""" + +GEDCOM_TAG_ROMANIZED = "ROMN" +"""Value: `ROMN` + +A romanized variation of a superior text string.""" + GEDCOM_TAG_SEX = "SEX" """Value: `SEX` Indicates the sex of an individual--male or female.""" +GEDCOM_TAG_SEALING_CHILD = "SLGC" +"""Value: `SLGC` + +A religious event pertaining to the sealing of a child to his or her parents in +an LDS temple ceremony.""" + +GEDCOM_TAG_SEALING_SPOUSE = "SLGS" +"""Value: `SLGS` + +A religious event pertaining to the sealing of a husband and wife in an LDS +temple ceremony.""" + GEDCOM_TAG_SOURCE = "SOUR" """Value: `SOUR` The initial or original material from which information was obtained.""" -GEDCOM_TAG_SURNAME = "SURN" -"""Value: `SURN` +GEDCOM_TAG_SURN_PREFIX = "SPFX" +"""Value: `SPFX` + +A name piece used as a non-indexing pre-part of a surname.""" + +GEDCOM_TAG_SOC_SEC_NUMBER = "SSN" +"""Value: `SSN` + +A number assigned by the United States Social Security Administration. Used for +tax identification purposes.""" + +GEDCOM_TAG_STATE = "STAE" +"""Value: `STAE` + +A geographical division of a larger jurisdictional area, such as a State within +the United States of America.""" + +GEDCOM_TAG_STATUS = "STAT" +"""Value: `STAT` + +An assessment of the state or condition of something.""" + +GEDCOM_TAG_SUBMITTER = "SUBM" +"""Value: `SUBM` + +An individual or organization who contributes genealogical data to a file or +transfers it to someone else.""" + +GEDCOM_TAG_SUBMISSION = "SUBN" +"""Value: `SUBN` + +Pertains to a collection of data issued for processing.""" + +GEDCOM_TAG_SURNAME = "SURN" +"""Value: `SURN` A family name passed on or used by members of a family.""" +GEDCOM_TAG_TEMPLE = "TEMP" +"""Value: `TEMP` + +The name or code that represents the name a temple of the LDS Church.""" + +GEDCOM_TAG_TEXT = "TEXT" +"""Value: `TEXT` + +The exact wording found in an original source document.""" + +GEDCOM_TAG_TIME = "TIME" +"""Value: `TIME` + +A time value in a 24-hour clock format, including hours, minutes, and optional +seconds, separated by a colon (:). Fractions of seconds are shown in decimal +notation.""" + +GEDCOM_TAG_TITLE = "TITL" +"""Value: `TITL` + +A description of a specific writing or other work, such as the title of a book +when used in a source context, or a formal designation used by an individual +in connection with positions of royalty or other social status, such as Grand +Duke.""" + +GEDCOM_TAG_TRAILER = "TRLR" +"""Value: `TRLR` + +At level 0, specifies the end of a GEDCOM transmission.""" + +GEDCOM_TAG_TYPE = "TYPE" +"""Value: `TYPE` + +A further qualification to the meaning of the associated superior tag. The value +does not have any computer processing reliability. It is more in the form of a +short one or two word note that should be displayed any time the associated data +is displayed.""" + +GEDCOM_TAG_VERSION = "VERS" +"""Value: `VERS` + +Indicates which version of a product, item, or publication is being used or +referenced.""" + GEDCOM_TAG_WIFE = "WIFE" """Value: `WIFE` -An individual in the role as a mother and/or married woman."""

  • +An individual in the role as a mother and/or married woman.""" + +GEDCOM_TAG_WWW = "WWW" +"""Value: `WWW` + +World Wide Web home page.""" + +GEDCOM_TAG_WILL = "WILL" +"""Value: `WILL` + +A legal document treated as an event, by which a person disposes of his or her +estate, to take effect after death. The event date is the date the will was +signed while the person was alive. (See also `gedcom.tags.GEDCOM_TAG_PROBATE`)"""

    @@ -215,158 +994,924 @@

    Module gedcom.tags

    Global variables

    +
    var GEDCOM_PROGRAM_DEFINED_TAG_ADDRESSE
    +
    +

    Value: _NAME

    +

    Name of addresse in a GEDCOM_TAG_ADDRESS structure.

    +

    5.5.1 GEDCOM-L Addendum.

    +
    +
    var GEDCOM_PROGRAM_DEFINED_TAG_ADMINISTRATIVE_ID
    +
    +

    Value: _AIDN

    +

    Identifier for a location with the intention of an administrative authority, +e.g. community identifier.

    +

    5.5.1 GEDCOM-L Addendum.

    +
    +
    var GEDCOM_PROGRAM_DEFINED_TAG_APID
    +
    +

    Value: _APID

    +

    Ancestry page identifier. For a citation, points to the page in a Ancestry +database for the record supporting the citation. For a source record it +points to the database as a whole.

    +

    Ancestry.com Extension.

    +
    +
    var GEDCOM_PROGRAM_DEFINED_TAG_DCAUSE
    +
    +

    Value: _DCAUSE

    +

    Cause of death.

    +
    +
    var GEDCOM_PROGRAM_DEFINED_TAG_DEGREE
    +
    +

    Value: _DEG

    +

    Degree or recognition of accomplishment received by an individual.

    +
    +
    var GEDCOM_PROGRAM_DEFINED_TAG_DEMOGRAPHIC_DATA
    +
    +

    Value: _DMGD

    +

    A number of ojects, during an ascertainment, e.g. the count of households.

    +

    5.5.1 GEDCOM-L Addendum.

    +
    var GEDCOM_PROGRAM_DEFINED_TAG_FREL
    -

    Value: _FREL

    -

    Relationship to a father.

    +

    Value: _FREL

    +

    Type of relationship between child and the father in a family.

    +
    +
    var GEDCOM_PROGRAM_DEFINED_TAG_FUNERAL
    +
    +

    Value: _FUN

    +

    Funeral for an individual.

    +
    +
    var GEDCOM_PROGRAM_DEFINED_TAG_GOVERNMENT
    +
    +

    Value: _GOV

    +

    The official government id of the object in the Historical Place Register / +Historic Gazeteer.

    +

    5.5.1 GEDCOM-L Addendum.

    +
    +
    var GEDCOM_PROGRAM_DEFINED_TAG_GOVERNMENT_TYPE
    +
    +

    Value: _GOVTYPE

    +

    An integer positive number as defined in the GOV system. +See http://gov.genealogy.net.net/type/list.

    +

    5.5.1 GEDCOM-L Addendum.

    +
    +
    var GEDCOM_PROGRAM_DEFINED_TAG_HOME_PERSON
    +
    +

    Value: _HME

    +

    Home person in the tree.

    +
    +
    var GEDCOM_PROGRAM_DEFINED_TAG_LOCATION
    +
    +

    Value: _LOC

    +

    Location data record.

    +

    5.5.1 GEDCOM-L Addendum.

    +
    +
    var GEDCOM_PROGRAM_DEFINED_TAG_MAIDENHEAD
    +
    +

    Value: _MAIDENHEAD

    +

    The maidenhead code.

    +

    5.5.1 GEDCOM-L Addendum.

    +
    +
    var GEDCOM_PROGRAM_DEFINED_TAG_MEDICAL
    +
    +

    Value: _MDCL

    +

    Medical information about an individual.

    +
    +
    var GEDCOM_PROGRAM_DEFINED_TAG_MILITARY
    +
    +

    Value: _MILT

    +

    A military related event in the individuals life.

    var GEDCOM_PROGRAM_DEFINED_TAG_MREL
    -

    Value: _MREL

    -

    Relationship to a mother.

    +

    Value: _MREL

    +

    Type of relationship between child and the mother in a family.

    +
    +
    var GEDCOM_PROGRAM_DEFINED_TAG_PHOTO
    +
    +

    Value: _PHOTO

    +

    Used by some programs to identify the primary multimedia object for an +individual, the same as GEDCOM_PROGRAM_DEFINED_TAG_PRIMARY.

    +
    +
    var GEDCOM_PROGRAM_DEFINED_TAG_POSTAL_CODE
    +
    +

    Value: _POST

    +

    The official zip code, called ADDRESS_POSTAL_CODE in the standard.

    +

    5.5.1 GEDCOM-L Addendum.

    +
    +
    var GEDCOM_PROGRAM_DEFINED_TAG_PREFERRED
    +
    +

    Value: _PREF

    +

    Indicates a preferred spouse, child or parents.

    +
    +
    var GEDCOM_PROGRAM_DEFINED_TAG_PRIMARY
    +
    +

    Value: _PRIM

    +

    Primary multimedia object for an individual.

    +
    +
    var GEDCOM_PROGRAM_DEFINED_TAG_RUFNAME
    +
    +

    Value: _RUFNAME

    +

    An official given name of a German individual used in legal documents.

    +

    5.5.1 GEDCOM-L Addendum.

    +
    +
    var GEDCOM_PROGRAM_DEFINED_TAG_SCHEMA
    +
    +

    Value: _SCHEMA

    +

    Schema substructure extension to describe user defined tags.

    +

    5.5.1 GEDCOM-L Addendum.

    +
    +
    var GEDCOM_PROGRAM_DEFINED_TAG_UUID
    +
    +

    Value: _UID

    +

    Universal identification number.

    +

    5.5.1 GEDCOM-L Addendum.

    +
    +
    var GEDCOM_TAG_ABBREVIATION
    +
    +

    Value: ABBR

    +

    A short name of a title, description, or name.

    +
    +
    var GEDCOM_TAG_ADDRESS
    +
    +

    Value: ADDR

    +

    The contemporary place, usually required for postal purposes, of an individual, +a submitter of information, a repository, a business, a school, or a company.

    +
    +
    var GEDCOM_TAG_ADDRESS1
    +
    +

    Value: ADR1

    +

    The first line of an address.

    +
    +
    var GEDCOM_TAG_ADDRESS2
    +
    +

    Value: ADR2

    +

    The second line of an address.

    +
    +
    var GEDCOM_TAG_ADDRESS3
    +
    +

    Value: ADR3

    +

    The third line of an address.

    +
    +
    var GEDCOM_TAG_ADOPTION
    +
    +

    Value: ADOP

    +

    Pertaining to creation of a child-parent relationship that does not exist +biologically.

    +
    +
    var GEDCOM_TAG_ADULT_CHRISTENING
    +
    +

    Value: CHRA

    +

    The religious event (not LDS) of baptizing and/or naming an adult person.

    +
    +
    var GEDCOM_TAG_AFN
    +
    +

    Value: AFN

    +

    Ancestral File Number, a unique permanent record file number of an individual +record stored in Ancestral File.

    +
    +
    var GEDCOM_TAG_AGE
    +
    +

    Value: AGE

    +

    The age of the individual at the time an event occurred, or the age listed in +the document.

    +
    +
    var GEDCOM_TAG_AGENCY
    +
    +

    Value: AGNC

    +

    The institution or individual having authority and/or responsibility to manage +or govern.

    +
    +
    var GEDCOM_TAG_ALIAS
    +
    +

    Value: ALIA

    +

    An indicator to link different record descriptions of a person who may be the +same person.

    +
    +
    var GEDCOM_TAG_ANCESTORS
    +
    +

    Value: ANCE

    +

    Pertaining to forbearers of an individual.

    +
    +
    var GEDCOM_TAG_ANCES_INTEREST
    +
    +

    Value: ANCI

    +

    Indicates an interest in additional research for ancestors of this individual. +(See also GEDCOM_TAG_DESCENDANTS_INT)

    +
    +
    var GEDCOM_TAG_ANNULMENT
    +
    +

    Value: ANUL

    +

    Declaring a marriage void from the beginning (never existed).

    +
    +
    var GEDCOM_TAG_ASSOCIATES
    +
    +

    Value: ASSO

    +

    An indicator to link friends, neighbors, relatives, or associates of an +individual.

    +
    +
    var GEDCOM_TAG_AUTHOR
    +
    +

    Value: AUTH

    +

    The name of the individual who created or compiled information.

    +
    +
    var GEDCOM_TAG_BAPTISM
    +
    +

    Value: BAPM

    +

    The event of baptism (not LDS), performed in infancy or later.

    +
    +
    var GEDCOM_TAG_BAPTISM_LDS
    +
    +

    Value: BAPL

    +

    The event of baptism performed at age eight or later by priesthood authority +of the LDS Church. (See also GEDCOM_TAG_BAPTISM)

    +
    +
    var GEDCOM_TAG_BAR_MITZVAH
    +
    +

    Value: BARM

    +

    The ceremonial event held when a Jewish boy reaches age 13.

    +
    +
    var GEDCOM_TAG_BAS_MITZVAH
    +
    +

    Value: BASM

    +

    The ceremonial event held when a Jewish girl reaches age 13, also known as +Bat Mitzvah.

    var GEDCOM_TAG_BIRTH
    -

    Value: BIRT

    -

    The event of entering into life.

    +

    Value: BIRT

    +

    The event of entering into life.

    +
    +
    var GEDCOM_TAG_BLESSING
    +
    +

    Value: BLES

    +

    A religious event of bestowing divine care or intercession. Sometimes given +in connection with a naming ceremony.

    var GEDCOM_TAG_BURIAL
    -

    Value: BURI

    -

    The event of the proper disposing of the mortal remains of a deceased person.

    +

    Value: BURI

    +

    The event of the proper disposing of the mortal remains of a deceased person.

    +
    +
    var GEDCOM_TAG_CALL_NUMBER
    +
    +

    Value: CALN

    +

    The number used by a repository to identify the specific items in its +collections.

    +
    +
    var GEDCOM_TAG_CASTE
    +
    +

    Value: CAST

    +

    The name of an individual's rank or status in society, based on racial or +religious differences, or differences in wealth, inherited rank, profession, +occupation, etc.

    +
    +
    var GEDCOM_TAG_CAUSE
    +
    +

    Value: CAUS

    +

    A description of the cause of the associated event or fact, such as the cause +of death.

    var GEDCOM_TAG_CENSUS
    -

    Value: CENS.

    -

    The event of the periodic count of the population for a designated locality, such as a national or state Census.

    +

    Value: CENS.

    +

    The event of the periodic count of the population for a designated locality, +such as a national or state Census.

    var GEDCOM_TAG_CHANGE
    -

    Value: CHAN

    +

    Value: CHAN

    Indicates a change, correction, or modification. Typically used in connection -with a GEDCOM_TAG_DATE to specify when a change in information occurred.

    +with a GEDCOM_TAG_DATE to specify when a change in information +occurred.

    +
    +
    var GEDCOM_TAG_CHARACTER
    +
    +

    Value: CHAR

    +

    An indicator of the character set used in writing this automated information.

    var GEDCOM_TAG_CHILD
    -

    Value: CHIL

    -

    The natural, adopted, or sealed (LDS) child of a father and a mother.

    +

    Value: CHIL

    +

    The natural, adopted, or sealed (LDS) child of a father and a mother.

    +
    +
    var GEDCOM_TAG_CHILDREN_COUNT
    +
    +

    Value: NCHI

    +

    The number of children that this person is known to be the parent of (all +marriages) when subordinate to an individual, or that belong to this family +when subordinate to a GEDCOM_TAG_FAMILY record.

    +
    +
    var GEDCOM_TAG_CHRISTENING
    +
    +

    Value: CHR

    +

    The religious event (not LDS) of baptizing and/or naming a child.

    +
    +
    var GEDCOM_TAG_CITY
    +
    +

    Value: CITY

    +

    A lower level jurisdictional unit. Normally an incorporated municipal unit.

    var GEDCOM_TAG_CONCATENATION
    -

    Value: CONC

    -

    An indicator that additional data belongs to the superior value. The information from the CONC value is to -be connected to the value of the superior preceding line without a space and without a carriage return and/or -new line character. Values that are split for a CONC tag must always be split at a non-space. If the value is -split on a space the space will be lost when concatenation takes place. This is because of the treatment that -spaces get as a GEDCOM delimiter, many GEDCOM values are trimmed of trailing spaces and some systems look for -the first non-space starting after the tag to determine the beginning of the value.

    +

    Value: CONC

    +

    An indicator that additional data belongs to the superior value. The information +from the CONC value is to be connected to the value of the superior preceding +line without a space and without a carriage return and/or new line character. +Values that are split for a CONC tag must always be split at a non-space. If +the value is split on a space the space will be lost when concatenation takes +place. This is because of the treatment that spaces get as a GEDCOM delimiter, +many GEDCOM values are trimmed of trailing spaces and some systems look for +the first non-space starting after the tag to determine the beginning of the +value.

    +
    +
    var GEDCOM_TAG_CONFIRMATION
    +
    +

    Value: CONF

    +

    The religious event (not LDS) of conferring the gift of the Holy Ghost and, +among protestants, full church membership.

    +
    +
    var GEDCOM_TAG_CONFIRMATION_L
    +
    +

    Value: CONL

    +

    The religious event by which a person receives membership in the LDS Church.

    var GEDCOM_TAG_CONTINUED
    -

    Value: CONT

    -

    An indicator that additional data belongs to the superior value. The information from the CONT value is to be -connected to the value of the superior preceding line with a carriage return and/or new line character. -Leading spaces could be important to the formatting of the resultant text. When importing values from CONT lines -the reader should assume only one delimiter character following the CONT tag. Assume that the rest of the leading -spaces are to be a part of the value.

    +

    Value: CONT

    +

    An indicator that additional data belongs to the superior value. The information +from the CONT value is to be connected to the value of the superior preceding +line with a carriage return and/or new line character. Leading spaces could be +important to the formatting of the resultant text. When importing values from +CONT lines the reader should assume only one delimiter character following +the CONT tag. Assume that the rest of the leading spaces are to be a part +of the value.

    +
    + +
    +

    Value: COPR

    +

    A statement that accompanies data to protect it from unlawful duplication +and distribution.

    +
    +
    var GEDCOM_TAG_CORPORATE
    +
    +

    Value: CORP

    +

    A name of an institution, agency, corporation, or company.

    +
    +
    var GEDCOM_TAG_COUNTRY
    +
    +

    Value: CTRY

    +

    The name or code of a country.

    +
    +
    var GEDCOM_TAG_CREMATION
    +
    +

    Value: CREM

    +

    Disposal of the remains of a person's body by fire.

    +
    +
    var GEDCOM_TAG_DATA
    +
    +

    Value: DATA

    +

    Pertaining to stored automation information.

    var GEDCOM_TAG_DATE
    -

    Value: DATE

    -

    The time of an event in a calendar format.

    +

    Value: DATE

    +

    The time of an event in a calendar format.

    var GEDCOM_TAG_DEATH
    -

    Value: DEAT

    -

    The event when mortal life terminates.

    +

    Value: DEAT

    +

    The event when mortal life terminates.

    +
    +
    var GEDCOM_TAG_DESCENDANTS
    +
    +

    Value: DESC

    +

    Pertaining to offspring of an individual.

    +
    +
    var GEDCOM_TAG_DESCENDANTS_INT
    +
    +

    Value: DESI

    +

    Indicates an interest in research to identify additional descendants of this +individual. (See also GEDCOM_TAG_ANCES_INTEREST)

    +
    +
    var GEDCOM_TAG_DESTINATION
    +
    +

    Value: DEST

    +

    A system receiving data.

    +
    +
    var GEDCOM_TAG_DIVORCE
    +
    +

    Value: DIV

    +

    The event of disolving a marriage through civil action.

    +
    +
    var GEDCOM_TAG_DIVORCE_FILED
    +
    +

    Value: DIVF

    +

    An event of filing for a divorce by a spouse.

    +
    +
    var GEDCOM_TAG_EDUCATION
    +
    +

    Value: EDUC

    +

    Indicator of a level of education attained.

    +
    +
    var GEDCOM_TAG_EMAIL
    +
    +

    Value: EMAIL

    +

    An electronic address that can be used for contact such as an email address.

    +
    +
    var GEDCOM_TAG_EMIGRATION
    +
    +

    Value: EMIG

    +

    An event of leaving one's homeland with the intent of residing elsewhere.

    +
    +
    var GEDCOM_TAG_ENDOWMENT
    +
    +

    Value: ENDL

    +

    A religious event where an endowment ordinance for an individual was performed +by priesthood authority in an LDS temple.

    +
    +
    var GEDCOM_TAG_ENGAGEMENT
    +
    +

    Value: ENGA

    +

    An event of recording or announcing an agreement between two people to become +married.

    +
    +
    var GEDCOM_TAG_EVENT
    +
    +

    Value: EVEN

    +

    A noteworthy happening related to an individual, a group, or an organization.

    +
    +
    var GEDCOM_TAG_FACT
    +
    +

    Value: FACT

    +

    Pertaining to a noteworthy attribute or fact concerning an individual, a group, +or an organization. A FACT structure is usually qualified or classified by a +subordinate use of the GEDCOM_TAG_TYPE tag.

    var GEDCOM_TAG_FAMILY
    -

    Value: FAM.

    -

    Identifies a legal, common law, or other customary relationship of man and woman and their children, -if any, or a family created by virtue of the birth of a child to its biological father and mother.

    +

    Value: FAM.

    +

    Identifies a legal, common law, or other customary relationship of man and woman +and their children, if any, or a family created by virtue of the birth of a +child to its biological father and mother.

    var GEDCOM_TAG_FAMILY_CHILD
    -

    Value: FAMC

    -

    Identifies the family in which an individual appears as a child.

    +

    Value: FAMC

    +

    Identifies the family in which an individual appears as a child.

    +
    +
    var GEDCOM_TAG_FAMILY_FILE
    +
    +

    Value: FAMF

    +

    Pertaining to, or the name of, a family file. Names stored in a file that are +assigned to a family for doing temple ordinance work.

    var GEDCOM_TAG_FAMILY_SPOUSE
    -

    Value: FAMS

    -

    Identifies the family in which an individual appears as a spouse.

    +

    Value: FAMS

    +

    Identifies the family in which an individual appears as a spouse.

    +
    +
    var GEDCOM_TAG_FAX
    +
    +

    Value: FAX

    +

    A FAX telephone number appropriate for sending data facsimiles.

    var GEDCOM_TAG_FILE
    -

    Value: FILE

    -

    An information storage place that is ordered and arranged for preservation and reference.

    +

    Value: FILE

    +

    An information storage place that is ordered and arranged for preservation and +reference.

    +
    +
    var GEDCOM_TAG_FIRST_COMMUNION
    +
    +

    Value: FCOM

    +

    A religious rite, the first act of sharing in the Lord's supper as part of +church worship.

    +
    +
    var GEDCOM_TAG_FORMAT
    +
    +

    Value: FORM

    +

    An assigned name given to a consistent format in which information can be +conveyed.

    +
    +
    var GEDCOM_TAG_GEDCOM
    +
    +

    Value: GEDC

    +

    Information about the use of GEDCOM in a transmission.

    var GEDCOM_TAG_GIVEN_NAME
    -

    Value: GIVN

    -

    A given or earned name used for official identification of a person.

    +

    Value: GIVN

    +

    A given or earned name used for official identification of a person.

    +
    +
    var GEDCOM_TAG_GRADUATION
    +
    +

    Value: GRAD

    +

    An event of awarding educational diplomas or degrees to individuals.

    +
    +
    var GEDCOM_TAG_HEADER
    +
    +

    Value: HEAD

    +

    Identifies information pertaining to an entire GEDCOM transmission.

    var GEDCOM_TAG_HUSBAND
    -

    Value: HUSB

    -

    An individual in the family role of a married man or father.

    +

    Value: HUSB

    +

    An individual in the family role of a married man or father.

    +
    +
    var GEDCOM_TAG_IDENT_NUMBER
    +
    +

    Value: IDNO

    +

    A number assigned to identify a person within some significant external system.

    +
    +
    var GEDCOM_TAG_IMMIGRATION
    +
    +

    Value: IMMI

    +

    An event of entering into a new locality witht he intent of residing there.

    var GEDCOM_TAG_INDIVIDUAL
    -

    Value: INDI

    -

    A person.

    +

    Value: INDI

    +

    A person.

    +
    +
    var GEDCOM_TAG_LANGUAGE
    +
    +

    Value: LANG

    +

    The name of the language used in a communication or transmission of information.

    +
    +
    var GEDCOM_TAG_LATITUDE
    +
    +

    Value: LATI

    +

    A value indicating a coordinate position on a line, plane, or space.

    +
    +
    var GEDCOM_TAG_LEGATEE
    +
    +

    Value: LEGA

    +

    A role of an individual acting as a person receiving a bequest or legal devise.

    +
    +
    var GEDCOM_TAG_LONGITUDE
    +
    +

    Value: LONG

    +

    A value indicating a coordinate position on a line, plane, or space.

    +
    +
    var GEDCOM_TAG_MAP
    +
    +

    Value: MAP

    +

    Pertains to a representation of measurements usually presented in a graphical +form.

    var GEDCOM_TAG_MARRIAGE
    -

    Value: MARR.

    -

    A legal, common-law, or customary event of creating a family unit of a man and a woman as husband and wife.

    +

    Value: MARR.

    +

    A legal, common-law, or customary event of creating a family unit of a man and +a woman as husband and wife.

    +
    +
    var GEDCOM_TAG_MARRIAGE_BANN
    +
    +

    Value: MARB.

    +

    An event of an official public notice given that two people intend to marry.

    +
    +
    var GEDCOM_TAG_MARRIAGE_COUNT
    +
    +

    Value: NMR

    +

    The number of times this person has participated in a family as a spouse or +parent.

    +
    +
    var GEDCOM_TAG_MARR_CONTRACT
    +
    +

    Value: MARC.

    +

    An event of recording a formal agreement of marriage, including the prenuptial +agreement in which marriage partners reach agreement about the property rights +of one or both, securing property to their children.

    +
    +
    var GEDCOM_TAG_MARR_LICENSE
    +
    +

    Value: MARL.

    +

    An event of obtaining a legal license to marry.

    +
    +
    var GEDCOM_TAG_MARR_SETTLEMENT
    +
    +

    Value: MARS.

    +

    An event of creating an agreement between two people contemplating marriage, +at which time they agree to release or modify property rights that would +otherwise arise from the marriage.

    +
    +
    var GEDCOM_TAG_MEDIA
    +
    +

    Value: MEDI.

    +

    Identifies information about the media or having to do with the medium in which +information is stored.

    var GEDCOM_TAG_NAME
    -

    Value: NAME.

    -

    A word or combination of words used to help identify an individual, title, or other item. -More than one NAME line should be used for people who were known by multiple names.

    +

    Value: NAME.

    +

    A word or combination of words used to help identify an individual, title, or +other item. More than one NAME line should be used for people who were known +by multiple names.

    +
    +
    var GEDCOM_TAG_NAME_PREFIX
    +
    +

    Value: NPFX

    +

    Text which appears on a name line before the given and surname parts of a name. +i.e. ( Lt. Cmndr. ) Joseph /Allen/ jr. In this example Lt. Cmndr. is considered +as the name prefix portion.

    +
    +
    var GEDCOM_TAG_NAME_SUFFIX
    +
    +

    Value: NSFX

    +

    Text which appears on a name line after or behind the given and surname parts +of a name. i.e. Lt. Cmndr. Joseph /Allen/ ( jr. ) In this example jr. is +considered as the name suffix portion.

    +
    +
    var GEDCOM_TAG_NATIONALITY
    +
    +

    Value: NATI

    +

    The national heritage of an individual.

    +
    +
    var GEDCOM_TAG_NATURALIZATION
    +
    +

    Value: NATU

    +

    The event of obtaining citizenship.

    +
    +
    var GEDCOM_TAG_NICKNAME
    +
    +

    Value: NICK

    +

    A descriptive or familiar that is used instead of, or in addition to, one's +proper name.

    +
    +
    var GEDCOM_TAG_NOTE
    +
    +

    Value: NOTE

    +

    Additional information provided by the submitter for understanding the +enclosing data.

    var GEDCOM_TAG_OBJECT
    -

    Value: OBJE

    -

    Pertaining to a grouping of attributes used in describing something. Usually referring to the data required -to represent a multimedia object, such an audio recording, a photograph of a person, or an image of a document.

    +

    Value: OBJE

    +

    Pertaining to a grouping of attributes used in describing something. Usually +referring to the data required to represent a multimedia object, such an audio +recording, a photograph of a person, or an image of a document.

    var GEDCOM_TAG_OCCUPATION
    -

    Value: OCCU

    -

    The type of work or profession of an individual.

    +

    Value: OCCU

    +

    The type of work or profession of an individual.

    +
    +
    var GEDCOM_TAG_ORDINANCE
    +
    +

    Value: ORDI

    +

    Pertaining to a religious ordinance in general.

    +
    +
    var GEDCOM_TAG_ORDINATION
    +
    +

    Value: ORDN

    +

    A religious event of receiving authority to act in religious matters.

    +
    +
    var GEDCOM_TAG_PAGE
    +
    +

    Value: PAGE

    +

    A number or description to identify where information can be found in a +referenced work.

    +
    +
    var GEDCOM_TAG_PEDIGREE
    +
    +

    Value: PEDI

    +

    Information pertaining to an individual to parent lineage chart.

    +
    +
    var GEDCOM_TAG_PHONE
    +
    +

    Value: PHON

    +

    A unique number assigned to access a specific telephone.

    +
    +
    var GEDCOM_TAG_PHONETIC
    +
    +

    Value: FONE

    +

    A phonetic variation of a superior text string.

    +
    +
    var GEDCOM_TAG_PHY_DESCRIPTION
    +
    +

    Value: DSCR

    +

    The physical characteristics of a person, place, or thing.

    var GEDCOM_TAG_PLACE
    -

    Value: PLAC

    -

    A jurisdictional name to identify the place or location of an event.

    +

    Value: PLAC

    +

    A jurisdictional name to identify the place or location of an event.

    +
    +
    var GEDCOM_TAG_POSTAL_CODE
    +
    +

    Value: POST

    +

    A code used by a postal service to identify an area to facilitate mail handling.

    var GEDCOM_TAG_PRIVATE
    -

    Value: PRIV

    -

    Flag for private address or event.

    +

    Value: PRIV

    +

    Flag for private address or event.

    +
    +
    var GEDCOM_TAG_PROBATE
    +
    +

    Value: PROB

    +

    An event of judicial determination of the validity of a will. May indicate +several related court activities over several dates.

    +
    +
    var GEDCOM_TAG_PROPERTY
    +
    +

    Value: PROP

    +

    Pertaining to possessions such as real estate or other property of interest.

    +
    +
    var GEDCOM_TAG_PUBLICATION
    +
    +

    Value: PUBL

    +

    Refers to when and/or were a work was published or created.

    +
    +
    var GEDCOM_TAG_QUALITY_OF_DATA
    +
    +

    Value: QUAY

    +

    An assessment of the certainty of the evidence to support the conclusion drawn +from evidence.

    +
    +
    var GEDCOM_TAG_REC_FILE_NUMBER
    +
    +

    Value: RFN

    +

    A permanent number assigned to a record that uniquely identifies it within a +known file.

    +
    +
    var GEDCOM_TAG_REC_ID_NUMBER
    +
    +

    Value: RIN

    +

    A number assigned to a record by an originating automated system that can be +used by a receiving system to report results pertaining to that record.

    +
    +
    var GEDCOM_TAG_REFERENCE
    +
    +

    Value: REFN

    +

    A description or number used to identify an item for filing, storage, or other +reference purposes.

    +
    +
    var GEDCOM_TAG_RELATIONSHIP
    +
    +

    Value: RELA

    +

    A relationship value between the indicated contexts.

    +
    +
    var GEDCOM_TAG_RELIGION
    +
    +

    Value: RELI

    +

    A religious denomination to which a person is affiliated or for which a record +applies.

    +
    +
    var GEDCOM_TAG_REPOSITORY
    +
    +

    Value: REPO

    +

    An institution or person that has the specified item as part of their +collection(s).

    +
    +
    var GEDCOM_TAG_RESIDENCE
    +
    +

    Value: RESI

    +

    The act of dwelling at a place for a period of time.

    +
    +
    var GEDCOM_TAG_RESTRICTION
    +
    +

    Value: RESN

    +

    A processing indicator signifying access to information has been denied or +otherwise restricted.

    +
    +
    var GEDCOM_TAG_RETIREMENT
    +
    +

    Value: RETI

    +

    An event of exiting an occupational relationship with an employer after a +qualifying time period.

    +
    +
    var GEDCOM_TAG_ROLE
    +
    +

    Value: ROLE

    +

    A name given to a role played by an individual in connection with an event.

    +
    +
    var GEDCOM_TAG_ROMANIZED
    +
    +

    Value: ROMN

    +

    A romanized variation of a superior text string.

    +
    +
    var GEDCOM_TAG_SEALING_CHILD
    +
    +

    Value: SLGC

    +

    A religious event pertaining to the sealing of a child to his or her parents in +an LDS temple ceremony.

    +
    +
    var GEDCOM_TAG_SEALING_SPOUSE
    +
    +

    Value: SLGS

    +

    A religious event pertaining to the sealing of a husband and wife in an LDS +temple ceremony.

    var GEDCOM_TAG_SEX
    -

    Value: SEX

    -

    Indicates the sex of an individual–male or female.

    +

    Value: SEX

    +

    Indicates the sex of an individual–male or female.

    +
    +
    var GEDCOM_TAG_SOC_SEC_NUMBER
    +
    +

    Value: SSN

    +

    A number assigned by the United States Social Security Administration. Used for +tax identification purposes.

    var GEDCOM_TAG_SOURCE
    -

    Value: SOUR

    -

    The initial or original material from which information was obtained.

    +

    Value: SOUR

    +

    The initial or original material from which information was obtained.

    +
    +
    var GEDCOM_TAG_STATE
    +
    +

    Value: STAE

    +

    A geographical division of a larger jurisdictional area, such as a State within +the United States of America.

    +
    +
    var GEDCOM_TAG_STATUS
    +
    +

    Value: STAT

    +

    An assessment of the state or condition of something.

    +
    +
    var GEDCOM_TAG_SUBMISSION
    +
    +

    Value: SUBN

    +

    Pertains to a collection of data issued for processing.

    +
    +
    var GEDCOM_TAG_SUBMITTER
    +
    +

    Value: SUBM

    +

    An individual or organization who contributes genealogical data to a file or +transfers it to someone else.

    var GEDCOM_TAG_SURNAME
    -

    Value: SURN

    -

    A family name passed on or used by members of a family.

    +

    Value: SURN

    +

    A family name passed on or used by members of a family.

    +
    +
    var GEDCOM_TAG_SURN_PREFIX
    +
    +

    Value: SPFX

    +

    A name piece used as a non-indexing pre-part of a surname.

    +
    +
    var GEDCOM_TAG_TEMPLE
    +
    +

    Value: TEMP

    +

    The name or code that represents the name a temple of the LDS Church.

    +
    +
    var GEDCOM_TAG_TEXT
    +
    +

    Value: TEXT

    +

    The exact wording found in an original source document.

    +
    +
    var GEDCOM_TAG_TIME
    +
    +

    Value: TIME

    +

    A time value in a 24-hour clock format, including hours, minutes, and optional +seconds, separated by a colon (:). Fractions of seconds are shown in decimal +notation.

    +
    +
    var GEDCOM_TAG_TITLE
    +
    +

    Value: TITL

    +

    A description of a specific writing or other work, such as the title of a book +when used in a source context, or a formal designation used by an individual +in connection with positions of royalty or other social status, such as Grand +Duke.

    +
    +
    var GEDCOM_TAG_TRAILER
    +
    +

    Value: TRLR

    +

    At level 0, specifies the end of a GEDCOM transmission.

    +
    +
    var GEDCOM_TAG_TYPE
    +
    +

    Value: TYPE

    +

    A further qualification to the meaning of the associated superior tag. The value +does not have any computer processing reliability. It is more in the form of a +short one or two word note that should be displayed any time the associated data +is displayed.

    +
    +
    var GEDCOM_TAG_VERSION
    +
    +

    Value: VERS

    +

    Indicates which version of a product, item, or publication is being used or +referenced.

    var GEDCOM_TAG_WIFE
    -

    Value: WIFE

    -

    An individual in the role as a mother and/or married woman.

    +

    Value: WIFE

    +

    An individual in the role as a mother and/or married woman.

    +
    +
    var GEDCOM_TAG_WILL
    +
    +

    Value: WILL

    +

    A legal document treated as an event, by which a person disposes of his or her +estate, to take effect after death. The event date is the date the will was +signed while the person was alive. (See also GEDCOM_TAG_PROBATE)

    +
    +
    var GEDCOM_TAG_WWW
    +
    +

    Value: WWW

    +

    World Wide Web home page.

    @@ -388,41 +1933,175 @@

    Index

  • Global variables

  • diff --git a/gedcom/__init__.py b/gedcom/__init__.py index 386a74b..65ea462 100644 --- a/gedcom/__init__.py +++ b/gedcom/__init__.py @@ -34,8 +34,14 @@ __all__ = [ # Subpackages "element", + "subparsers", # Modules + "errors", "helpers", + "detect", "parser", + "reader", + "records", + "standards", "tags" ] diff --git a/gedcom/detect.py b/gedcom/detect.py new file mode 100644 index 0000000..d79116c --- /dev/null +++ b/gedcom/detect.py @@ -0,0 +1,137 @@ +# -*- coding: utf-8 -*- + +# Python GEDCOM Parser +# +# Copyright (C) 2020 Christopher Horn (cdhorn at embarqmail dot com) +# Copyright (C) 2018 Damon Brodie (damon.brodie at gmail.com) +# Copyright (C) 2018-2019 Nicklas Reincke (contact at reynke.com) +# Copyright (C) 2016 Andreas Oberritter +# Copyright (C) 2012 Madeleine Price Ball +# Copyright (C) 2005 Daniel Zappala (zappala at cs.byu.edu) +# Copyright (C) 2005 Brigham Young University +# +# 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. +# +# Further information about the license: http://www.gnu.org/licenses/gpl-2.0.html + +""" +Module containing functions for detecting GEDCOM file encoding and version. +""" + +from typing import Tuple +import chardet +import ansel + +import gedcom.tags as tags +import gedcom.standards as standards +from gedcom.errors import GedcomFormatViolationError +from gedcom.errors import GedcomCharacterSetUnsupportedError + +ansel.register() + + +def __validate_encoding(file_path, codec): + """Check the encoding is compatible with the encoding as reported by the + `gedcom.tags.GEDCOM_TAG_CHARACTER` header tag. + """ + with open(file_path, 'r', encoding=codec) as gedcom_data: + for line in gedcom_data: + if tags.GEDCOM_TAG_CHARACTER in line: + character_set = line.split(' ')[2].lower().strip() + break + + if character_set == 'ansel' and codec == 'gedcom': + return + + if character_set == 'ascii' and codec == 'utf-8': + return + + if character_set not in codec: + errmsg = "A " + codec + " encoding was detected but the GEDCOM reports using " + \ + "a " + character_set + " encoding.\n" + \ + "Processing aborted as unsure how to properly proceed.\n" + \ + "See: {0}".format(standards.GEDCOM_5_5_1) + raise GedcomCharacterSetUnsupportedError(errmsg) + + +def get_encoding(file_path: str) -> str: + """Probe a GEDCOM file to determine the encoding and validate it against the encoding + as reported in the `HEADER` record by the `gedcom.tags.GEDCOM_TAG_CHARACTER` tag. + + Returns: codec + """ + with open(file_path, 'rb') as gedcom_data: + sample_data = gedcom_data.read(262144) + + # Note chardet reports Ansel as ISO-8859-1 or ISO-8859-2 at this time + # depending on sample size, and could be making a faulty assumption here + # by treating it as Ansel. The ansel module supports both ansel and a + # gedcom codec with some gedcom specific extensions so we use that. + codec = 'unknown' + probe = chardet.detect(sample_data) + if probe['encoding'] in ['UTF-8', 'UTF-8-SIG']: + codec = 'utf-8-sig' + elif probe['encoding'] == 'UTF-16': + codec = 'utf-16' + elif probe['encoding'] == 'ASCII': + codec = 'ascii' + elif probe['encoding'] == 'ANSEL': + codec = 'ansel' + elif 'ISO-8859' in probe['encoding']: + codec = 'gedcom' + + if codec == 'unknown': + errmsg = "Unable to properly identify a supported GEDCOM character encoding for" + \ + "the file.\nSee: {0}".format(standards.GEDCOM_5_5_1) + raise GedcomCharacterSetUnsupportedError(errmsg) + + __validate_encoding(file_path, codec) + return codec + + +def get_version(file_path: str, codec: str) -> Tuple[str, str, str]: + """Probe a GEDCOM file to identify the version of the standard used as some reported 5.5 + files are really 5.5.1. + + Returns: probed version, reported version, reported format + """ + in_gedc_tag = False + gedcom_version = None + gedcom_format = None + with open(file_path, 'r', encoding=codec) as gedcom_data: + for line in gedcom_data: + if '1 GEDC' in line: + in_gedc_tag = True + continue + if in_gedc_tag: + if '2 VERS' in line: + gedcom_version = line.split(' ')[2].strip() + continue + if '2 FORM' in line: + gedcom_format = line.split(' ')[2].strip() + break + + if gedcom_version is None or gedcom_format is None: + errmsg = "Malformed GEDCOM file, the required version number or format were" + \ + " not found as expected.\nSee: {0}".format(standards.GEDCOM_5_5_1) + raise GedcomFormatViolationError(errmsg) + + probed_version = gedcom_version + + # UTF was added in the 5.5.1 specification + if gedcom_version == '5.5' and 'utf' in codec: + probed_version = gedcom_version + + return probed_version, gedcom_version, gedcom_format diff --git a/gedcom/element/__init__.py b/gedcom/element/__init__.py index 34eaac5..4360a26 100644 --- a/gedcom/element/__init__.py +++ b/gedcom/element/__init__.py @@ -33,8 +33,13 @@ __all__ = [ "element", "family", - "file", + "header", "individual", + "note", "object", - "root" + "repository", + "root", + "source", + "submission", + "submitter" ] diff --git a/gedcom/element/element.py b/gedcom/element/element.py index 3428e3c..c62b1af 100644 --- a/gedcom/element/element.py +++ b/gedcom/element/element.py @@ -26,18 +26,20 @@ # Further information about the license: http://www.gnu.org/licenses/gpl-2.0.html """ -Base GEDCOM element +Base GEDCOM element. """ from sys import version_info +from typing import List + from gedcom.helpers import deprecated import gedcom.tags class Element(object): - """GEDCOM element + """GEDCOM element. - Each line in a GEDCOM file is an element with the format + Each line in a GEDCOM file is an element with the format: `level [pointer] tag [value]` @@ -62,7 +64,8 @@ class Element(object): Tags available to an element are seen here: `gedcom.tags` """ - def __init__(self, level, pointer, tag, value, crlf="\n", multi_line=True): + def __init__(self, level: int, pointer: str, tag: str, value: str, + crlf: str = "\n", multi_line: bool = True): # basic element info self.__level = level self.__pointer = pointer @@ -77,39 +80,33 @@ def __init__(self, level, pointer, tag, value, crlf="\n", multi_line=True): if multi_line: self.set_multi_line_value(value) - def get_level(self): - """Returns the level of this element from within the GEDCOM file - :rtype: int + def get_level(self) -> int: + """Returns the level of this element from within the GEDCOM file. """ return self.__level - def get_pointer(self): - """Returns the pointer of this element from within the GEDCOM file - :rtype: str + def get_pointer(self) -> str: + """Returns the pointer of this element from within the GEDCOM file. """ return self.__pointer - def get_tag(self): - """Returns the tag of this element from within the GEDCOM file - :rtype: str + def get_tag(self) -> str: + """Returns the tag of this element from within the GEDCOM file. """ return self.__tag - def get_value(self): - """Return the value of this element from within the GEDCOM file - :rtype: str + def get_value(self) -> str: + """Return the value of this element from within the GEDCOM file. """ return self.__value - def set_value(self, value): - """Sets the value of this element - :type value: str + def set_value(self, value: str): + """Sets the value of this element. """ self.__value = value - def get_multi_line_value(self): - """Returns the value of this element including concatenations or continuations - :rtype: str + def get_multi_line_value(self) -> str: + """Returns the value of this element including concatenations or continuations. """ result = self.get_value() last_crlf = self.__crlf @@ -123,17 +120,14 @@ def get_multi_line_value(self): last_crlf = element.__crlf return result - def __available_characters(self): + def __available_characters(self) -> int: """Get the number of available characters of the elements original string - :rtype: int """ element_characters = len(self.to_gedcom_string()) return 0 if element_characters > 255 else 255 - element_characters - def __line_length(self, line): - """@TODO Write docs. - :type line: str - :rtype: int + def __line_length(self, line: str) -> int: + """Return line length. """ total_characters = len(line) available_characters = self.__available_characters() @@ -146,40 +140,36 @@ def __line_length(self, line): return available_characters return available_characters - spaces - def __set_bounded_value(self, value): + def __set_bounded_value(self, value: str) -> int: """@TODO Write docs. - :type value: str - :rtype: int """ line_length = self.__line_length(value) self.set_value(value[:line_length]) return line_length - def __add_bounded_child(self, tag, value): + def __add_bounded_child(self, tag: str, value: str) -> int: """@TODO Write docs. - :type tag: str - :type value: str - :rtype: int """ child = self.new_child_element(tag) return child.__set_bounded_value(value) - def __add_concatenation(self, string): + def __add_concatenation(self, string: str): """@TODO Write docs. - :rtype: str """ index = 0 size = len(string) while index < size: index += self.__add_bounded_child(gedcom.tags.GEDCOM_TAG_CONCATENATION, string[index:]) - def set_multi_line_value(self, value): - """Sets the value of this element, adding concatenation and continuation lines when necessary - :type value: str + def set_multi_line_value(self, value: str): + """Sets the value of this element, adding concatenation and continuation lines + when necessary. """ self.set_value('') self.get_child_elements()[:] = [child for child in self.get_child_elements() if - child.get_tag() not in (gedcom.tags.GEDCOM_TAG_CONCATENATION, gedcom.tags.GEDCOM_TAG_CONTINUED)] + child.get_tag() not in + (gedcom.tags.GEDCOM_TAG_CONCATENATION, + gedcom.tags.GEDCOM_TAG_CONTINUED)] lines = value.splitlines() if lines: @@ -191,79 +181,91 @@ def set_multi_line_value(self, value): n = self.__add_bounded_child(gedcom.tags.GEDCOM_TAG_CONTINUED, line) self.__add_concatenation(line[n:]) - def get_child_elements(self): - """Returns the direct child elements of this element - :rtype: list of Element + def get_child_elements(self) -> List['Element']: + """Returns the direct child elements of this element. """ return self.__children - def new_child_element(self, tag, pointer="", value=""): - """Creates and returns a new child element of this element - - :type tag: str - :type pointer: str - :type value: str - :rtype: Element + def new_child_element(self, tag: str, pointer: str = "", + value: str = "") -> 'Element': + """Creates and returns a new child element of this element. """ from gedcom.element.family import FamilyElement - from gedcom.element.file import FileElement from gedcom.element.individual import IndividualElement + from gedcom.element.note import NoteElement from gedcom.element.object import ObjectElement + from gedcom.element.repository import RepositoryElement + from gedcom.element.source import SourceElement + from gedcom.element.submitter import SubmitterElement + from gedcom.element.submission import SubmissionElement + from gedcom.element.header import HeaderElement # Differentiate between the type of the new child element if tag == gedcom.tags.GEDCOM_TAG_FAMILY: - child_element = FamilyElement(self.get_level() + 1, pointer, tag, value, self.__crlf) - elif tag == gedcom.tags.GEDCOM_TAG_FILE: - child_element = FileElement(self.get_level() + 1, pointer, tag, value, self.__crlf) + child_element = FamilyElement(self.get_level() + 1, pointer, tag, + value, self.__crlf) elif tag == gedcom.tags.GEDCOM_TAG_INDIVIDUAL: - child_element = IndividualElement(self.get_level() + 1, pointer, tag, value, self.__crlf) + child_element = IndividualElement(self.get_level() + 1, pointer, tag, + value, self.__crlf) + elif tag == gedcom.tags.GEDCOM_TAG_NOTE: + child_element = NoteElement(self.get_level() + 1, pointer, tag, + value, self.__crlf) elif tag == gedcom.tags.GEDCOM_TAG_OBJECT: - child_element = ObjectElement(self.get_level() + 1, pointer, tag, value, self.__crlf) + child_element = ObjectElement(self.get_level() + 1, pointer, tag, + value, self.__crlf) + elif tag == gedcom.tags.GEDCOM_TAG_REPOSITORY: + child_element = RepositoryElement(self.get_level() + 1, pointer, tag, + value, self.__crlf) + elif tag == gedcom.tags.GEDCOM_TAG_SOURCE: + child_element = SourceElement(self.get_level() + 1, pointer, tag, + value, self.__crlf) + elif tag == gedcom.tags.GEDCOM_TAG_SUBMITTER: + child_element = SubmitterElement(self.get_level() + 1, pointer, tag, + value, self.__crlf) + elif tag == gedcom.tags.GEDCOM_TAG_SUBMISSION: + child_element = SubmissionElement(self.get_level() + 1, pointer, tag, + value, self.__crlf) + elif tag == gedcom.tags.GEDCOM_TAG_HEADER: + child_element = HeaderElement(self.get_level() + 1, pointer, tag, + value, self.__crlf) else: - child_element = Element(self.get_level() + 1, pointer, tag, value, self.__crlf) + child_element = Element(self.get_level() + 1, pointer, tag, + value, self.__crlf) self.add_child_element(child_element) return child_element - def add_child_element(self, element): - """Adds a child element to this element - - :type element: Element + def add_child_element(self, element: 'Element'): + """Adds a child element to this element. """ self.get_child_elements().append(element) element.set_parent_element(self) return element - def get_parent_element(self): - """Returns the parent element of this element - :rtype: Element + def get_parent_element(self) -> 'Element': + """Returns the parent element of this element. """ return self.__parent - def set_parent_element(self, element): - """Adds a parent element to this element + def set_parent_element(self, element: 'Element'): + """Adds a parent element to this element. There's usually no need to call this method manually, `add_child_element()` calls it automatically. - - :type element: Element """ self.__parent = element @deprecated - def get_individual(self): - """Returns this element and all of its sub-elements represented as a GEDCOM string + def get_individual(self) -> str: + """Returns this element and all of its sub-elements represented as a GEDCOM string. ::deprecated:: As of version 1.0.0 use `to_gedcom_string()` method instead - :rtype: str """ return self.to_gedcom_string(True) - def to_gedcom_string(self, recursive=False): - """Formats this element and optionally all of its sub-elements into a GEDCOM string - :type recursive: bool - :rtype: str + def to_gedcom_string(self, recursive: bool = False) -> str: + """Formats this element and optionally all of its sub-elements into a GEDCOM string. """ result = str(self.get_level()) @@ -287,7 +289,7 @@ def to_gedcom_string(self, recursive=False): return result - def __str__(self): + def __str__(self) -> str: """:rtype: str""" if version_info[0] >= 3: return self.to_gedcom_string() diff --git a/gedcom/element/family.py b/gedcom/element/family.py index c91b5a9..ff735bb 100644 --- a/gedcom/element/family.py +++ b/gedcom/element/family.py @@ -2,6 +2,7 @@ # Python GEDCOM Parser # +# Copyright (C) 2020 Christopher Horn (cdhorn at embarqmail dot com) # Copyright (C) 2018 Damon Brodie (damon.brodie at gmail.com) # Copyright (C) 2018-2019 Nicklas Reincke (contact at reynke.com) # Copyright (C) 2016 Andreas Oberritter @@ -25,17 +26,104 @@ # # Further information about the license: http://www.gnu.org/licenses/gpl-2.0.html -"""GEDCOM element consisting of tag `gedcom.tags.GEDCOM_TAG_FAMILY`""" +""" +GEDCOM element for a `FAM_RECORD` family record identified by the +`gedcom.tags.GEDCOM_TAG_FAMILY` tag. +""" +import gedcom.tags as tags from gedcom.element.element import Element -import gedcom.tags +from gedcom.subparsers.family_event_structure import family_event_structure +from gedcom.subparsers.change_date import change_date +from gedcom.subparsers.lds_spouse_sealing import lds_spouse_sealing +from gedcom.subparsers.note_structure import note_structure +from gedcom.subparsers.source_citation import source_citation +from gedcom.subparsers.multimedia_link import multimedia_link +from gedcom.subparsers.user_reference_number import user_reference_number - -class NotAnActualFamilyError(Exception): - pass +FAMILY_SINGLE_TAGS = { + tags.GEDCOM_TAG_WIFE: 'key_to_wife', + tags.GEDCOM_TAG_HUSBAND: 'key_to_husband', + tags.GEDCOM_TAG_CHILDREN_COUNT: 'number_of_children', + tags.GEDCOM_TAG_RESTRICTION: 'restriction', + tags.GEDCOM_TAG_REC_ID_NUMBER: 'record_id' +} class FamilyElement(Element): + """Element associated with a `FAM_RECORD`""" + + def get_tag(self) -> str: + return tags.GEDCOM_TAG_FAMILY + + def get_record(self) -> dict: + """Parse and return the full record in dictionary format. + """ + record = { + 'key_to_family': self.get_pointer(), + 'restriction': '', + 'events': family_event_structure(self), + 'key_to_husband': '', + 'key_to_wife': '', + 'children': [], + 'number_of_children': '', + 'submitters': [], + 'references': [], + 'record_id': '', + 'change_date': {}, + 'notes': [], + 'citations': [], + 'media': [] + } + lds_events = lds_spouse_sealing(self) + if len(lds_events) > 0: + for event in lds_events: + record['events'].append(event) + + for child in self.get_child_elements(): + if child.get_tag() in FAMILY_SINGLE_TAGS: + record[FAMILY_SINGLE_TAGS[child.get_tag()]] = child.get_value() + continue + + if child.get_tag() == tags.GEDCOM_TAG_CHILD: + entry = { + 'key_to_child': child.get_value(), + 'relationship_to_father': '', + 'relationship_to_mother': '' + } + for gchild in child.get_child_elements(): + if gchild.get_tag() == tags.GEDCOM_PROGRAM_DEFINED_TAG_FREL: + entry['relationship_to_father'] = gchild.get_value() + continue + + if gchild.get_tag() == tags.GEDCOM_PROGRAM_DEFINED_TAG_MREL: + entry['relationship_to_mother'] = gchild.get_value() + + record['children'].append(entry) + continue + + if child.get_tag() == tags.GEDCOM_TAG_NOTE: + record['notes'].append(note_structure(child)) + continue + + if child.get_tag() == tags.GEDCOM_TAG_SOURCE: + record['citations'].append(source_citation(child)) + continue + + if child.get_tag() == tags.GEDCOM_TAG_OBJECT: + record['media'].append(multimedia_link(child)) + continue + + if child.get_tag() == tags.GEDCOM_TAG_REFERENCE: + record['references'].append(user_reference_number(child)) + continue + + if child.get_tag() == tags.GEDCOM_TAG_CHANGE: + record['change_date'] = change_date(child) + continue + + if child.get_tag() == tags.GEDCOM_TAG_SUBMITTER: + record['submitters'].append(child.get_value()) + continue - def get_tag(self): - return gedcom.tags.GEDCOM_TAG_FAMILY + return record diff --git a/gedcom/element/header.py b/gedcom/element/header.py new file mode 100644 index 0000000..55399d9 --- /dev/null +++ b/gedcom/element/header.py @@ -0,0 +1,159 @@ +# -*- coding: utf-8 -*- + +# Python GEDCOM Parser +# +# Copyright (C) 2020 Christopher Horn (cdhorn at embarqmail dot com) +# Copyright (C) 2018 Damon Brodie (damon.brodie at gmail.com) +# Copyright (C) 2018-2019 Nicklas Reincke (contact at reynke.com) +# Copyright (C) 2016 Andreas Oberritter +# Copyright (C) 2012 Madeleine Price Ball +# Copyright (C) 2005 Daniel Zappala (zappala at cs.byu.edu) +# Copyright (C) 2005 Brigham Young University +# +# 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. +# +# Further information about the license: http://www.gnu.org/licenses/gpl-2.0.html + +""" +GEDCOM element for a `HEADER` header record identified by the +`gedcom.tags.GEDCOM_TAG_HEADER` tag. +""" + +import gedcom.tags as tags +from gedcom.element.element import Element +from gedcom.subparsers.address_structure import address_structure +from gedcom.subparsers.note_structure import note_structure + +HEADER_TAGS = { + tags.GEDCOM_TAG_DESTINATION: 'destination', + tags.GEDCOM_TAG_SUBMITTER: 'key_to_submitter', + tags.GEDCOM_TAG_SUBMISSION: 'key_to_submission', + tags.GEDCOM_TAG_FILE: 'file', + tags.GEDCOM_TAG_COPYRIGHT: 'copyright', + tags.GEDCOM_TAG_LANGUAGE: 'language', + tags.GEDCOM_PROGRAM_DEFINED_TAG_HOME_PERSON: 'key_to_home_person' +} + + +class HeaderElement(Element): + """Element associated with a `HEADER`""" + + def get_tag(self) -> str: + return tags.GEDCOM_TAG_HEADER + + def get_record(self) -> dict: + """Parse and return the full record in dictionary format. + """ + record = { + 'source': '', + 'product': { + 'version': '', + 'name': '', + 'corporation': '', + 'address': {} + }, + 'data': { + 'source_data': '', + 'published': '', + 'copyright': '' + }, + 'destination': '', + 'transmission_date': '', + 'transmission_time': '', + 'key_to_submitter': '', + 'key_to_submission': '', + 'file': '', + 'copyright': '', + 'gedcom': { + 'version': '', + 'format': '', + }, + 'character_set': '', + 'character_set_version': '', + 'language': '', + 'place_hierarchy': '', + 'key_to_home_person': '', + 'notes': [] + } + for child in self.get_child_elements(): + if child.get_tag() == tags.GEDCOM_TAG_SOURCE: + record['source'] = child.get_value() + for gchild in child.get_child_elements(): + if gchild.get_tag() == tags.GEDCOM_TAG_VERSION: + record['product']['version'] = gchild.get_value() + continue + + if gchild.get_tag() == tags.GEDCOM_TAG_NAME: + record['product']['name'] = gchild.get_value() + continue + + if gchild.get_tag() == tags.GEDCOM_TAG_CORPORATE: + record['product']['corporation'] = gchild.get_value() + + for ggchild in gchild.get_child_elements(): + if ggchild.get_tag() == tags.GEDCOM_TAG_ADDRESS: + record['product']['address'] = address_structure(gchild) + continue + + if gchild.get_tag() == tags.GEDCOM_TAG_DATA: + record['data']['source_data'] = gchild.get_value() + for ggchild in gchild.get_child_elements(): + if ggchild.get_tag() == tags.GEDCOM_TAG_DATE: + record['data']['published'] = ggchild.get_value() + continue + + if ggchild.get_tag() == tags.GEDCOM_TAG_COPYRIGHT: + record['data']['copyright'] = ggchild.get_multi_line_value() + continue + continue + + if child.get_tag() in HEADER_TAGS: + record[HEADER_TAGS[child.get_tag()]] = child.get_value() + continue + + if child.get_tag() == tags.GEDCOM_TAG_DATE: + record['transmission_date'] = child.get_value() + for gchild in child.get_child_elements(): + if gchild.get_tag() == tags.GEDCOM_TAG_TIME: + record['transmission_time'] = gchild.get_value() + continue + + if child.get_tag() == tags.GEDCOM_TAG_GEDCOM: + for gchild in child.get_child_elements(): + if gchild.get_tag() == tags.GEDCOM_TAG_VERSION: + record['gedcom']['version'] = gchild.get_value() + continue + + if gchild.get_tag() == tags.GEDCOM_TAG_FORMAT: + record['gedcom']['format'] = gchild.get_value() + continue + + if child.get_tag() == tags.GEDCOM_TAG_CHARACTER: + record['character_set'] = child.get_value() + for gchild in child.get_child_elements(): + if gchild.get_tag() == tags.GEDCOM_TAG_VERSION: + record['character_set_version'] = gchild.get_value() + continue + + if child.get_tag() == tags.GEDCOM_TAG_PLACE: + for gchild in child.get_child_elements(): + if gchild.get_tag() == tags.GEDCOM_TAG_FORMAT: + record['place_hierarchy'] = gchild.get_value() + continue + + if child.get_tag() == tags.GEDCOM_TAG_NOTE: + record['notes'].append(note_structure(child)) + + return record diff --git a/gedcom/element/individual.py b/gedcom/element/individual.py index da61d08..f2af5d4 100644 --- a/gedcom/element/individual.py +++ b/gedcom/element/individual.py @@ -2,6 +2,7 @@ # Python GEDCOM Parser # +# Copyright (C) 2020 Christopher Horn (cdhorn at embarqmail dot com) # Copyright (C) 2018 Damon Brodie (damon.brodie at gmail.com) # Copyright (C) 2018-2019 Nicklas Reincke (contact at reynke.com) # Copyright (C) 2016 Andreas Oberritter @@ -25,71 +26,179 @@ # # Further information about the license: http://www.gnu.org/licenses/gpl-2.0.html -"""GEDCOM element consisting of tag `gedcom.tags.GEDCOM_TAG_INDIVIDUAL`""" +""" +GEDCOM element for a `INDIVIDUAL_RECORD` individual record identified by the +`gedcom.tags.GEDCOM_TAG_INDIVIDUAL` tag. +""" +from typing import Tuple, List import re as regex + +import gedcom.tags as tags from gedcom.element.element import Element +from gedcom.subparsers.personal_name_structure import personal_name_structure +from gedcom.subparsers.individual_event_structure import individual_event_structure +from gedcom.subparsers.individual_attribute_structure import individual_attribute_structure +from gedcom.subparsers.lds_individual_ordinance import lds_individual_ordinance +from gedcom.subparsers.child_to_family_link import child_to_family_link +from gedcom.subparsers.spouse_to_family_link import spouse_to_family_link +from gedcom.subparsers.association_structure import association_structure +from gedcom.subparsers.user_reference_number import user_reference_number +from gedcom.subparsers.change_date import change_date +from gedcom.subparsers.note_structure import note_structure +from gedcom.subparsers.source_citation import source_citation +from gedcom.subparsers.multimedia_link import multimedia_link from gedcom.helpers import deprecated -import gedcom.tags - -class NotAnActualIndividualError(Exception): - pass +INDIVIDUAL_SINGLE_TAGS = { + tags.GEDCOM_TAG_RESTRICTION: 'restriction', + tags.GEDCOM_TAG_SEX: 'sex', + tags.GEDCOM_TAG_REC_ID_NUMBER: 'record_id', + tags.GEDCOM_TAG_REC_FILE_NUMBER: 'permanent_file_number', + tags.GEDCOM_TAG_AFN: 'ancestral_file_number' +} class IndividualElement(Element): + """Element associated with an `INDIVIDUAL_RECORD`""" - def get_tag(self): - return gedcom.tags.GEDCOM_TAG_INDIVIDUAL + def get_tag(self) -> str: + return tags.GEDCOM_TAG_INDIVIDUAL - def is_deceased(self): - """Checks if this individual is deceased - :rtype: bool + def get_record(self) -> dict: + """Parse and return the full record in dictionary format. """ + record = { + 'key_to_individual': self.get_pointer(), + 'restriction': '', + 'names': [], + 'sex': 'U', + 'events': individual_event_structure(self), + 'attributes': individual_attribute_structure(self), + 'child_to_family': [], + 'spouse_to_family': [], + 'submitters': [], + 'associates': [], + 'aliases': [], + 'ancestors_interest': [], + 'descendants_interest': [], + 'permanent_file_number': '', + 'ancestral_file_number': '', + 'references': [], + 'record_id': '', + 'change_date': {}, + 'notes': [], + 'citations': [], + 'media': [] + } + lds_events = lds_individual_ordinance(self) + if len(lds_events) > 0: + for event in lds_events: + record['events'].append(event) + for child in self.get_child_elements(): - if child.get_tag() == gedcom.tags.GEDCOM_TAG_DEATH: + if child.get_tag() in INDIVIDUAL_SINGLE_TAGS: + record[INDIVIDUAL_SINGLE_TAGS[child.get_tag()]] = child.get_value() + continue + + if child.get_tag() == tags.GEDCOM_TAG_NAME: + record['names'].append(personal_name_structure(child)) + continue + + if child.get_tag() == tags.GEDCOM_TAG_FAMILY_CHILD: + record['child_to_family'].append(child_to_family_link(child)) + continue + + if child.get_tag() == tags.GEDCOM_TAG_FAMILY_SPOUSE: + record['spouse_to_family'].append(spouse_to_family_link(child)) + continue + + if child.get_tag() == tags.GEDCOM_TAG_NOTE: + record['notes'].append(note_structure(child)) + continue + + if child.get_tag() == tags.GEDCOM_TAG_SOURCE: + record['citations'].append(source_citation(child)) + continue + + if child.get_tag() == tags.GEDCOM_TAG_MEDIA: + record['media'].append(multimedia_link(child)) + continue + + if child.get_tag() == tags.GEDCOM_TAG_SUBMITTER: + record['submitters'].append(child.get_value()) + continue + + if child.get_tag() == tags.GEDCOM_TAG_ASSOCIATES: + record['associates'].append(association_structure(child)) + continue + + if child.get_tag() == tags.GEDCOM_TAG_ALIAS: + record['aliases'].append(child.get_value()) + continue + + if child.get_tag() == tags.GEDCOM_TAG_ANCES_INTEREST: + record['ancestors_interest'].append(child.get_value()) + continue + + if child.get_tag() == tags.GEDCOM_TAG_DESCENDANTS_INT: + record['descendants_interest'].append(child.get_value()) + continue + + if child.get_tag() == tags.GEDCOM_TAG_REFERENCE: + record['references'].append(user_reference_number(child)) + continue + + if child.get_tag() == tags.GEDCOM_TAG_CHANGE: + record['changed'] = change_date(child) + + return record + + def is_deceased(self) -> bool: + """Checks if this individual is deceased. + """ + for child in self.get_child_elements(): + if child.get_tag() == tags.GEDCOM_TAG_DEATH: return True return False - def is_child(self): - """Checks if this element is a child of a family - :rtype: bool + def is_child(self) -> bool: + """Checks if this element is a child of a family. """ found_child = False for child in self.get_child_elements(): - if child.get_tag() == gedcom.tags.GEDCOM_TAG_FAMILY_CHILD: + if child.get_tag() == tags.GEDCOM_TAG_FAMILY_CHILD: found_child = True return found_child - def is_private(self): - """Checks if this individual is marked private - :rtype: bool + def is_private(self) -> bool: + """Checks if this individual is marked private. """ for child in self.get_child_elements(): - if child.get_tag() == gedcom.tags.GEDCOM_TAG_PRIVATE: + if child.get_tag() == tags.GEDCOM_TAG_PRIVATE: private = child.get_value() if private == 'Y': return True return False - def get_name(self): + def get_name(self) -> Tuple[str, str]: """Returns an individual's names as a tuple: (`str` given_name, `str` surname) - :rtype: tuple """ given_name = "" surname = "" - # Return the first gedcom.tags.GEDCOM_TAG_NAME that is found. - # Alternatively as soon as we have both the gedcom.tags.GEDCOM_TAG_GIVEN_NAME and _SURNAME return those. + # Return the first tags.GEDCOM_TAG_NAME that is found. + # Alternatively as soon as we have both the tags.GEDCOM_TAG_GIVEN_NAME + # and _SURNAME return those. found_given_name = False found_surname_name = False for child in self.get_child_elements(): - if child.get_tag() == gedcom.tags.GEDCOM_TAG_NAME: + if child.get_tag() == tags.GEDCOM_TAG_NAME: # Some GEDCOM files don't use child tags but instead # place the name in the value of the NAME tag. if child.get_value() != "": @@ -102,14 +211,14 @@ def get_name(self): return given_name, surname - for childOfChild in child.get_child_elements(): + for gchild in child.get_child_elements(): - if childOfChild.get_tag() == gedcom.tags.GEDCOM_TAG_GIVEN_NAME: - given_name = childOfChild.get_value() + if gchild.get_tag() == tags.GEDCOM_TAG_GIVEN_NAME: + given_name = gchild.get_value() found_given_name = True - if childOfChild.get_tag() == gedcom.tags.GEDCOM_TAG_SURNAME: - surname = childOfChild.get_value() + if gchild.get_tag() == tags.GEDCOM_TAG_SURNAME: + surname = gchild.get_value() found_surname_name = True if found_given_name and found_surname_name: @@ -118,80 +227,74 @@ def get_name(self): # If we reach here we are probably returning empty strings return given_name, surname - def get_all_names(self): - return [a.get_value() for a in self.get_child_elements() if a.get_tag() == gedcom.tags.GEDCOM_TAG_NAME] + def get_all_names(self) -> List[str]: + """Return all names.""" + return [a.get_value() for a in self.get_child_elements() + if a.get_tag() == tags.GEDCOM_TAG_NAME] - def surname_match(self, surname_to_match): - """Matches a string with the surname of an individual - :type surname_to_match: str - :rtype: bool + def surname_match(self, surname_to_match: str) -> bool: + """Matches a string with the surname of an individual. """ (given_name, surname) = self.get_name() return regex.search(surname_to_match, surname, regex.IGNORECASE) @deprecated - def given_match(self, name): - """Matches a string with the given name of an individual + def given_match(self, name: str) -> bool: + """Matches a string with the given name of an individual. ::deprecated:: As of version 1.0.0 use `given_name_match()` method instead - :type name: str - :rtype: bool """ return self.given_name_match(name) - def given_name_match(self, given_name_to_match): - """Matches a string with the given name of an individual - :type given_name_to_match: str - :rtype: bool + def given_name_match(self, given_name_to_match: str) -> bool: + """Matches a string with the given name of an individual. """ (given_name, surname) = self.get_name() return regex.search(given_name_to_match, given_name, regex.IGNORECASE) - def get_gender(self): - """Returns the gender of a person in string format - :rtype: str + def get_gender(self) -> str: + """Returns the gender of a person in string format. """ gender = "" for child in self.get_child_elements(): - if child.get_tag() == gedcom.tags.GEDCOM_TAG_SEX: + if child.get_tag() == tags.GEDCOM_TAG_SEX: gender = child.get_value() return gender - def get_birth_data(self): - """Returns the birth data of a person formatted as a tuple: (`str` date, `str` place, `list` sources) - :rtype: tuple + def get_birth_data(self) -> Tuple[str, str, List[str]]: + """Returns the birth data of a person formatted as a tuple: + (`str` date, `str` place, `list` sources) """ date = "" place = "" sources = [] for child in self.get_child_elements(): - if child.get_tag() == gedcom.tags.GEDCOM_TAG_BIRTH: - for childOfChild in child.get_child_elements(): + if child.get_tag() == tags.GEDCOM_TAG_BIRTH: + for gchild in child.get_child_elements(): - if childOfChild.get_tag() == gedcom.tags.GEDCOM_TAG_DATE: - date = childOfChild.get_value() + if gchild.get_tag() == tags.GEDCOM_TAG_DATE: + date = gchild.get_value() - if childOfChild.get_tag() == gedcom.tags.GEDCOM_TAG_PLACE: - place = childOfChild.get_value() + if gchild.get_tag() == tags.GEDCOM_TAG_PLACE: + place = gchild.get_value() - if childOfChild.get_tag() == gedcom.tags.GEDCOM_TAG_SOURCE: - sources.append(childOfChild.get_value()) + if gchild.get_tag() == tags.GEDCOM_TAG_SOURCE: + sources.append(gchild.get_value()) return date, place, sources - def get_birth_year(self): - """Returns the birth year of a person in integer format - :rtype: int + def get_birth_year(self) -> int: + """Returns the birth year of a person in integer format. """ date = "" for child in self.get_child_elements(): - if child.get_tag() == gedcom.tags.GEDCOM_TAG_BIRTH: - for childOfChild in child.get_child_elements(): - if childOfChild.get_tag() == gedcom.tags.GEDCOM_TAG_DATE: - date_split = childOfChild.get_value().split() + if child.get_tag() == tags.GEDCOM_TAG_BIRTH: + for gchild in child.get_child_elements(): + if gchild.get_tag() == tags.GEDCOM_TAG_DATE: + date_split = gchild.get_value().split() date = date_split[len(date_split) - 1] if date == "": @@ -201,37 +304,36 @@ def get_birth_year(self): except ValueError: return -1 - def get_death_data(self): - """Returns the death data of a person formatted as a tuple: (`str` date, `str` place, `list` sources) - :rtype: tuple + def get_death_data(self) -> Tuple[str, str, List[str]]: + """Returns the death data of a person formatted as a tuple: + (`str` date, `str` place, `list` sources) """ date = "" place = "" sources = [] for child in self.get_child_elements(): - if child.get_tag() == gedcom.tags.GEDCOM_TAG_DEATH: - for childOfChild in child.get_child_elements(): - if childOfChild.get_tag() == gedcom.tags.GEDCOM_TAG_DATE: - date = childOfChild.get_value() - if childOfChild.get_tag() == gedcom.tags.GEDCOM_TAG_PLACE: - place = childOfChild.get_value() - if childOfChild.get_tag() == gedcom.tags.GEDCOM_TAG_SOURCE: - sources.append(childOfChild.get_value()) + if child.get_tag() == tags.GEDCOM_TAG_DEATH: + for gchild in child.get_child_elements(): + if gchild.get_tag() == tags.GEDCOM_TAG_DATE: + date = gchild.get_value() + if gchild.get_tag() == tags.GEDCOM_TAG_PLACE: + place = gchild.get_value() + if gchild.get_tag() == tags.GEDCOM_TAG_SOURCE: + sources.append(gchild.get_value()) return date, place, sources - def get_death_year(self): - """Returns the death year of a person in integer format - :rtype: int + def get_death_year(self) -> int: + """Returns the death year of a person in integer format. """ date = "" for child in self.get_child_elements(): - if child.get_tag() == gedcom.tags.GEDCOM_TAG_DEATH: - for childOfChild in child.get_child_elements(): - if childOfChild.get_tag() == gedcom.tags.GEDCOM_TAG_DATE: - date_split = childOfChild.get_value().split() + if child.get_tag() == tags.GEDCOM_TAG_DEATH: + for gchild in child.get_child_elements(): + if gchild.get_tag() == tags.GEDCOM_TAG_DATE: + date_split = gchild.get_value().split() date = date_split[len(date_split) - 1] if date == "": @@ -242,110 +344,103 @@ def get_death_year(self): return -1 @deprecated - def get_burial(self): - """Returns the burial data of a person formatted as a tuple: (`str` date, `str´ place, `list` sources) + def get_burial(self) -> Tuple[str, str, List[str]]: + """Returns the burial data of a person formatted as a tuple: + (`str` date, `str´ place, `list` sources) ::deprecated:: As of version 1.0.0 use `get_burial_data()` method instead - :rtype: tuple """ self.get_burial_data() - def get_burial_data(self): - """Returns the burial data of a person formatted as a tuple: (`str` date, `str´ place, `list` sources) - :rtype: tuple + def get_burial_data(self) -> Tuple[str, str, List[str]]: + """Returns the burial data of a person formatted as a tuple: + (`str` date, `str´ place, `list` sources) """ date = "" place = "" sources = [] for child in self.get_child_elements(): - if child.get_tag() == gedcom.tags.GEDCOM_TAG_BURIAL: - for childOfChild in child.get_child_elements(): + if child.get_tag() == tags.GEDCOM_TAG_BURIAL: + for gchild in child.get_child_elements(): - if childOfChild.get_tag() == gedcom.tags.GEDCOM_TAG_DATE: - date = childOfChild.get_value() + if gchild.get_tag() == tags.GEDCOM_TAG_DATE: + date = gchild.get_value() - if childOfChild.get_tag() == gedcom.tags.GEDCOM_TAG_PLACE: - place = childOfChild.get_value() + if gchild.get_tag() == tags.GEDCOM_TAG_PLACE: + place = gchild.get_value() - if childOfChild.get_tag() == gedcom.tags.GEDCOM_TAG_SOURCE: - sources.append(childOfChild.get_value()) + if gchild.get_tag() == tags.GEDCOM_TAG_SOURCE: + sources.append(gchild.get_value()) return date, place, sources @deprecated - def get_census(self): - """Returns a list of censuses of an individual formatted as tuples: (`str` date, `str´ place, `list` sources) + def get_census(self) -> List[Tuple[str, str, List[str]]]: + """Returns a list of censuses of an individual formatted as tuples: + (`str` date, `str´ place, `list` sources) ::deprecated:: As of version 1.0.0 use `get_census_data()` method instead - :rtype: list of tuple """ self.get_census_data() - def get_census_data(self): - """Returns a list of censuses of an individual formatted as tuples: (`str` date, `str´ place, `list` sources) - :rtype: list of tuple + def get_census_data(self) -> List[Tuple[str, str, List[str]]]: + """Returns a list of censuses of an individual formatted as tuples: + (`str` date, `str´ place, `list` sources) """ census = [] for child in self.get_child_elements(): - if child.get_tag() == gedcom.tags.GEDCOM_TAG_CENSUS: + if child.get_tag() == tags.GEDCOM_TAG_CENSUS: date = '' place = '' sources = [] - for childOfChild in child.get_child_elements(): + for gchild in child.get_child_elements(): - if childOfChild.get_tag() == gedcom.tags.GEDCOM_TAG_DATE: - date = childOfChild.get_value() + if gchild.get_tag() == tags.GEDCOM_TAG_DATE: + date = gchild.get_value() - if childOfChild.get_tag() == gedcom.tags.GEDCOM_TAG_PLACE: - place = childOfChild.get_value() + if gchild.get_tag() == tags.GEDCOM_TAG_PLACE: + place = gchild.get_value() - if childOfChild.get_tag() == gedcom.tags.GEDCOM_TAG_SOURCE: - sources.append(childOfChild.get_value()) + if gchild.get_tag() == tags.GEDCOM_TAG_SOURCE: + sources.append(gchild.get_value()) census.append((date, place, sources)) return census - def get_last_change_date(self): - """Returns the date of when the person data was last changed formatted as a string - :rtype: str + def get_last_change_date(self) -> str: + """Returns the date of when the person data was last changed formatted as a string. """ date = "" for child in self.get_child_elements(): - if child.get_tag() == gedcom.tags.GEDCOM_TAG_CHANGE: - for childOfChild in child.get_child_elements(): - if childOfChild.get_tag() == gedcom.tags.GEDCOM_TAG_DATE: - date = childOfChild.get_value() + if child.get_tag() == tags.GEDCOM_TAG_CHANGE: + for gchild in child.get_child_elements(): + if gchild.get_tag() == tags.GEDCOM_TAG_DATE: + date = gchild.get_value() return date - def get_occupation(self): - """Returns the occupation of a person - :rtype: str + def get_occupation(self) -> str: + """Returns the occupation of a person. """ occupation = "" for child in self.get_child_elements(): - if child.get_tag() == gedcom.tags.GEDCOM_TAG_OCCUPATION: + if child.get_tag() == tags.GEDCOM_TAG_OCCUPATION: occupation = child.get_value() return occupation - def birth_year_match(self, year): - """Returns `True` if the given year matches the birth year of this person - :type year: int - :rtype: bool + def birth_year_match(self, year: int) -> bool: + """Returns `True` if the given year matches the birth year of this person. """ return self.get_birth_year() == year - def birth_range_match(self, from_year, to_year): - """Checks if the birth year of a person lies within the given range - :type from_year: int - :type to_year: int - :rtype: bool + def birth_range_match(self, from_year: int, to_year: int) -> bool: + """Checks if the birth year of a person lies within the given range. """ birth_year = self.get_birth_year() @@ -354,18 +449,13 @@ def birth_range_match(self, from_year, to_year): return False - def death_year_match(self, year): - """Returns `True` if the given year matches the death year of this person - :type year: int - :rtype: bool + def death_year_match(self, year: int) -> bool: + """Returns `True` if the given year matches the death year of this person. """ return self.get_death_year() == year - def death_range_match(self, from_year, to_year): - """Checks if the death year of a person lies within the given range - :type from_year: int - :type to_year: int - :rtype: bool + def death_range_match(self, from_year: int, to_year: int) -> bool: + """Checks if the death year of a person lies within the given range. """ death_year = self.get_death_year() @@ -374,8 +464,8 @@ def death_range_match(self, from_year, to_year): return False - def criteria_match(self, criteria): - """Checks if this individual matches all of the given criteria + def criteria_match(self, criteria: str) -> bool: + """Checks if this individual matches all of the given criteria. `criteria` is a colon-separated list, where each item in the list has the form [name]=[value]. The following criteria are supported: @@ -389,9 +479,6 @@ def criteria_match(self, criteria): birth_range=[from_year-to_year] Match a person whose birth year is in the range of years from [from_year] to [to_year], including both [from_year] and [to_year]. - - :type criteria: str - :rtype: bool """ # Check if criteria is a valid criteria and can be split by `:` and `=` characters diff --git a/gedcom/element/note.py b/gedcom/element/note.py new file mode 100644 index 0000000..2035f54 --- /dev/null +++ b/gedcom/element/note.py @@ -0,0 +1,74 @@ +# -*- coding: utf-8 -*- + +# Python GEDCOM Parser +# +# Copyright (C) 2020 Christopher Horn (cdhorn at embarqmail dot com) +# Copyright (C) 2018 Damon Brodie (damon.brodie at gmail.com) +# Copyright (C) 2018-2019 Nicklas Reincke (contact at reynke.com) +# Copyright (C) 2016 Andreas Oberritter +# Copyright (C) 2012 Madeleine Price Ball +# Copyright (C) 2005 Daniel Zappala (zappala at cs.byu.edu) +# Copyright (C) 2005 Brigham Young University +# +# 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. +# +# Further information about the license: http://www.gnu.org/licenses/gpl-2.0.html + +""" +GEDCOM element for a `NOTE_RECORD` note record identified by the +`gedcom.tags.GEDCOM_TAG_NOTE` tag. +""" + +import gedcom.tags as tags +from gedcom.element.element import Element +from gedcom.subparsers.source_citation import source_citation +from gedcom.subparsers.change_date import change_date +from gedcom.subparsers.user_reference_number import user_reference_number + + +class NoteElement(Element): + """Element associated with a `NOTE_RECORD`""" + + def get_tag(self) -> str: + return tags.GEDCOM_TAG_NOTE + + def get_record(self) -> dict: + """Parse and return the full record in dictionary format. + """ + record = { + 'key_to_note': self.get_pointer(), + 'note': self.get_multi_line_value(), + 'references': [], + 'record_id': '', + 'citations': [], + 'change_date': {} + } + for child in self.get_child_elements(): + if child.get_tag() == tags.GEDCOM_TAG_REFERENCE: + record['references'].append(user_reference_number(child)) + continue + + if child.get_tag() == tags.GEDCOM_TAG_REC_ID_NUMBER: + record['record_id'] = child.get_value() + continue + + if child.get_tag() == tags.GEDCOM_TAG_SOURCE: + record['citations'].append(source_citation(child)) + continue + + if child.get_tag() == tags.GEDCOM_TAG_CHANGE: + record['change_date'] = change_date(child) + + return record diff --git a/gedcom/element/object.py b/gedcom/element/object.py index 0090e2f..5942545 100644 --- a/gedcom/element/object.py +++ b/gedcom/element/object.py @@ -2,6 +2,7 @@ # Python GEDCOM Parser # +# Copyright (C) 2020 Christopher Horn (cdhorn at embarqmail dot com) # Copyright (C) 2018 Damon Brodie (damon.brodie at gmail.com) # Copyright (C) 2018-2019 Nicklas Reincke (contact at reynke.com) # Copyright (C) 2016 Andreas Oberritter @@ -25,20 +26,83 @@ # # Further information about the license: http://www.gnu.org/licenses/gpl-2.0.html -"""GEDCOM element consisting of tag `gedcom.tags.GEDCOM_TAG_OBJECT`""" +""" +GEDCOM element for a `MULTIMEDIA_RECORD` media record identified by the +`gedcom.tags.GEDCOM_TAG_OBJECT` tag. +""" +import gedcom.tags as tags from gedcom.element.element import Element -import gedcom.tags - - -class NotAnActualObjectError(Exception): - pass +from gedcom.subparsers.note_structure import note_structure +from gedcom.subparsers.source_citation import source_citation +from gedcom.subparsers.change_date import change_date +from gedcom.subparsers.user_reference_number import user_reference_number class ObjectElement(Element): + """Element associated with a `MULTIMEDIA_RECORD`""" - def is_object(self): - """Checks if this element is an actual object - :rtype: bool + def get_tag(self) -> str: + return tags.GEDCOM_TAG_OBJECT + + def get_record(self) -> dict: + """Parse and return the full record in dictionary format. """ - return self.get_tag() == gedcom.tags.GEDCOM_TAG_OBJECT + record = { + 'key_to_object': self.get_pointer(), + 'file': '', + 'format': '', + 'type': '', + 'title': '', + 'references': [], + 'record_id': '', + 'citations': [], + 'notes': [], + 'change_date': {} + } + for child in self.get_child_elements(): + if child.get_tag() == tags.GEDCOM_TAG_FILE: + record['file'] = child.get_value() + + for gchild in child.get_child_elements(): + if gchild.get_tag() == tags.GEDCOM_TAG_FORMAT: + record['format'] = gchild.get_value() + + for ggchild in gchild.get_child_elements(): + if ggchild.get_tag() == tags.GEDCOM_TAG_TYPE: + record['type'] = ggchild.get_value() + continue + + if gchild.get_tag() == tags.GEDCOM_TAG_TITLE: + record['title'] = gchild.get_value() + continue + continue + + if child.get_tag() == tags.GEDCOM_TAG_FORMAT: + record['format'] = child.get_value() + continue + + if child.get_tag() == tags.GEDCOM_TAG_TYPE: + record['type'] = child.get_value() + continue + + if child.get_tag() == tags.GEDCOM_TAG_NOTE: + record['notes'].append(note_structure(child)) + continue + + if child.get_tag() == tags.GEDCOM_TAG_SOURCE: + record['citations'].append(source_citation(child)) + continue + + if child.get_tag() == tags.GEDCOM_TAG_REFERENCE: + record['references'].append(user_reference_number(child)) + continue + + if child.get_tag() == tags.GEDCOM_TAG_REC_ID_NUMBER: + record['record_id'] = child.get_value() + continue + + if child.get_tag() == tags.GEDCOM_TAG_CHANGE: + record['change_date'] = change_date(child) + + return record diff --git a/gedcom/element/repository.py b/gedcom/element/repository.py new file mode 100644 index 0000000..f0dc469 --- /dev/null +++ b/gedcom/element/repository.py @@ -0,0 +1,84 @@ +# -*- coding: utf-8 -*- + +# Python GEDCOM Parser +# +# Copyright (C) 2020 Christopher Horn (cdhorn at embarqmail dot com) +# Copyright (C) 2018 Damon Brodie (damon.brodie at gmail.com) +# Copyright (C) 2018-2019 Nicklas Reincke (contact at reynke.com) +# Copyright (C) 2016 Andreas Oberritter +# Copyright (C) 2012 Madeleine Price Ball +# Copyright (C) 2005 Daniel Zappala (zappala at cs.byu.edu) +# Copyright (C) 2005 Brigham Young University +# +# 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. +# +# Further information about the license: http://www.gnu.org/licenses/gpl-2.0.html + +""" +GEDCOM element for a `REPOSITORY_RECORD` repository record identified by the +`gedcom.tags.GEDCOM_TAG_REPOSITORY` tag. +""" + +import gedcom.tags as tags +from gedcom.element.element import Element +from gedcom.subparsers.address_structure import address_structure +from gedcom.subparsers.note_structure import note_structure +from gedcom.subparsers.change_date import change_date +from gedcom.subparsers.user_reference_number import user_reference_number + + +class RepositoryElement(Element): + """Element associated with a `REPOSITORY_RECORD`""" + + def get_tag(self) -> str: + return tags.GEDCOM_TAG_REPOSITORY + + def get_record(self) -> dict: + """Parse and return the full record in dictionary format. + """ + record = { + 'key_to_repository': self.get_pointer(), + 'name': '', + 'address': {}, + 'references': [], + 'record_id': '', + 'change_date': {}, + 'notes': [] + } + for child in self.get_child_elements(): + if child.get_tag() == tags.GEDCOM_TAG_NAME: + record['name'] = child.get_value() + continue + + if child.get_tag() == tags.GEDCOM_TAG_ADDRESS: + record['address'] = address_structure(self) + continue + + if child.get_tag() == tags.GEDCOM_TAG_NOTE: + record['notes'].append(note_structure(child)) + continue + + if child.get_tag() == tags.GEDCOM_TAG_REFERENCE: + record['references'].append(user_reference_number(child)) + continue + + if child.get_tag() == tags.GEDCOM_TAG_REC_ID_NUMBER: + record['record_id'] = child.get_value() + continue + + if child.get_tag() == tags.GEDCOM_TAG_CHANGE: + record['change_date'] = change_date(child) + + return record diff --git a/gedcom/element/root.py b/gedcom/element/root.py index 826c378..6ad719a 100644 --- a/gedcom/element/root.py +++ b/gedcom/element/root.py @@ -31,7 +31,8 @@ class RootElement(Element): - """Virtual GEDCOM root element containing all logical records as children""" + """Virtual GEDCOM root element containing all logical records as children.""" - def __init__(self, level=-1, pointer="", tag="ROOT", value="", crlf="\n", multi_line=True): + def __init__(self, level: int = -1, pointer: str = "", tag: str = "ROOT", value: str = "", + crlf: str = "\n", multi_line: bool = True): super(RootElement, self).__init__(level, pointer, tag, value, crlf, multi_line) diff --git a/gedcom/element/source.py b/gedcom/element/source.py new file mode 100644 index 0000000..e73b52c --- /dev/null +++ b/gedcom/element/source.py @@ -0,0 +1,137 @@ +# -*- coding: utf-8 -*- + +# Python GEDCOM Parser +# +# Copyright (C) 2020 Christopher Horn (cdhorn at embarqmail dot com) +# Copyright (C) 2018 Damon Brodie (damon.brodie at gmail.com) +# Copyright (C) 2018-2019 Nicklas Reincke (contact at reynke.com) +# Copyright (C) 2016 Andreas Oberritter +# Copyright (C) 2012 Madeleine Price Ball +# Copyright (C) 2005 Daniel Zappala (zappala at cs.byu.edu) +# Copyright (C) 2005 Brigham Young University +# +# 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. +# +# Further information about the license: http://www.gnu.org/licenses/gpl-2.0.html + +""" +GEDCOM element for a `SOURCE_RECORD` source record identified by the +`gedcom.tags.GEDCOM_TAG_SOURCE` tag. +""" + +import gedcom.tags as tags +from gedcom.element.element import Element +from gedcom.subparsers.change_date import change_date +from gedcom.subparsers.note_structure import note_structure +from gedcom.subparsers.multimedia_link import multimedia_link +from gedcom.subparsers.user_reference_number import user_reference_number +from gedcom.subparsers.source_repository_citation import source_repository_citation + +SOURCE_PLURAL_TAGS = { + tags.GEDCOM_TAG_AUTHOR: 'author', + tags.GEDCOM_TAG_TITLE: 'title', + tags.GEDCOM_TAG_PUBLICATION: 'publication', + tags.GEDCOM_TAG_TEXT: 'text' +} + +SOURCE_SINGLE_TAGS = { + tags.GEDCOM_TAG_ABBREVIATION: 'abbreviation', + tags.GEDCOM_TAG_REC_ID_NUMBER: 'record_id', + tags.GEDCOM_PROGRAM_DEFINED_TAG_APID: 'apid' +} + + +class SourceElement(Element): + """Element associated with a SOURCE_RECORD""" + + def get_tag(self) -> str: + return tags.GEDCOM_TAG_SOURCE + + def get_record(self) -> dict: + """Parse and return the full record in dictionary format. + """ + record = { + 'key_to_source': self.get_pointer(), + 'data': { + 'events': '', + 'date': '', + 'place': '', + 'agency': '', + 'notes': [] + }, + 'author': '', + 'title': '', + 'abbreviation': '', + 'publication': '', + 'text': '', + 'repository': {}, + 'references': [], + 'record_id': '', + 'change_date': {}, + 'notes': [], + 'media': [], + 'apid': '' + } + for child in self.get_child_elements(): + if child.get_tag() in SOURCE_PLURAL_TAGS: + record[SOURCE_PLURAL_TAGS[child.get_tag()]] = child.get_multi_line_value() + continue + + if child.get_tag() in SOURCE_SINGLE_TAGS: + record[SOURCE_SINGLE_TAGS[child.get_tag()]] = child.get_value() + continue + + if child.get_tag() == tags.GEDCOM_TAG_NOTE: + record['notes'].append(note_structure(child)) + continue + + if child.get_tag() == tags.GEDCOM_TAG_OBJECT: + record['media'].append(multimedia_link(child)) + continue + + if child.get_tag() == tags.GEDCOM_TAG_REPOSITORY: + record['repository'] = source_repository_citation(child) + continue + + if child.get_tag() == tags.GEDCOM_TAG_DATA: + for gchild in child.get_child_elements(): + if gchild.get_tag() == tags.GEDCOM_TAG_EVENT: + record['data']['events'] = gchild.get_value() + for ggchild in gchild.get_child_elements(): + if ggchild.get_tag() == tags.GEDCOM_TAG_DATE: + record['data']['date'] = ggchild.get_value() + continue + + if ggchild.get_tag() == tags.GEDCOM_TAG_PLACE: + record['data']['place'] = ggchild.get_value() + continue + + if gchild.get_tag() == tags.GEDCOM_TAG_AGENCY: + record['data']['agency'] = gchild.get_value() + continue + + if gchild.get_tag() == tags.GEDCOM_TAG_NOTE: + record['data']['notes'].append(note_structure(gchild)) + continue + + if child.get_tag() == tags.GEDCOM_TAG_REFERENCE: + record['references'].append(user_reference_number(child)) + continue + + if child.get_tag() == tags.GEDCOM_TAG_CHANGE: + record['change_date'] = change_date(child) + continue + + return record diff --git a/gedcom/element/submission.py b/gedcom/element/submission.py new file mode 100644 index 0000000..7eb90d3 --- /dev/null +++ b/gedcom/element/submission.py @@ -0,0 +1,83 @@ +# -*- coding: utf-8 -*- + +# Python GEDCOM Parser +# +# Copyright (C) 2020 Christopher Horn (cdhorn at embarqmail dot com) +# Copyright (C) 2018 Damon Brodie (damon.brodie at gmail.com) +# Copyright (C) 2018-2019 Nicklas Reincke (contact at reynke.com) +# Copyright (C) 2016 Andreas Oberritter +# Copyright (C) 2012 Madeleine Price Ball +# Copyright (C) 2005 Daniel Zappala (zappala at cs.byu.edu) +# Copyright (C) 2005 Brigham Young University +# +# 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. +# +# Further information about the license: http://www.gnu.org/licenses/gpl-2.0.html + +""" +GEDCOM element for a `SUBMISSION_RECORD` submission record identified by the +`gedcom.tags.GEDCOM_TAG_SUBMISSION` tag. +""" + +import gedcom.tags as tags +from gedcom.element.element import Element +from gedcom.subparsers.note_structure import note_structure +from gedcom.subparsers.change_date import change_date + +SUBMISSION_TAGS = { + tags.GEDCOM_TAG_SUBMITTER: 'key_to_submitter', + tags.GEDCOM_TAG_FAMILY_FILE: 'family_file', + tags.GEDCOM_TAG_TEMPLE: 'temple', + tags.GEDCOM_TAG_ANCESTORS: 'generations_of_ancestors', + tags.GEDCOM_TAG_DESCENDANTS: 'generations_of_decendants', + tags.GEDCOM_TAG_ORDINANCE: 'ordinance_process_flag', + tags.GEDCOM_TAG_REC_ID_NUMBER: 'record_id' +} + + +class SubmissionElement(Element): + """Element associated with a `SUBMISSION_RECORD`""" + + def get_tag(self) -> str: + return tags.GEDCOM_TAG_SUBMISSION + + def get_record(self) -> dict: + """Parse and return the record in dictionary format + """ + record = { + 'key_to_submission': self.get_pointer(), + 'key_to_submitter': '', + 'family_file': '', + 'temple': '', + 'generations_of_ancestors': '', + 'generations_of_descendants': '', + 'ordinance_process_flag': '', + 'record_id': '', + 'notes': [], + 'change_date': {} + } + for child in self.get_child_elements(): + if child.get_tag() in SUBMISSION_TAGS: + record[SUBMISSION_TAGS[child.get_tag()]] = child.get_value() + continue + + if child.get_tag() == tags.GEDCOM_TAG_NOTE: + record['notes'].append(note_structure(child)) + continue + + if child.get_tag() == tags.GEDCOM_TAG_CHANGE: + record['change_date'] = change_date(child) + + return record diff --git a/gedcom/element/submitter.py b/gedcom/element/submitter.py new file mode 100644 index 0000000..8e48737 --- /dev/null +++ b/gedcom/element/submitter.py @@ -0,0 +1,94 @@ +# -*- coding: utf-8 -*- + +# Python GEDCOM Parser +# +# Copyright (C) 2020 Christopher Horn (cdhorn at embarqmail dot com) +# Copyright (C) 2018 Damon Brodie (damon.brodie at gmail.com) +# Copyright (C) 2018-2019 Nicklas Reincke (contact at reynke.com) +# Copyright (C) 2016 Andreas Oberritter +# Copyright (C) 2012 Madeleine Price Ball +# Copyright (C) 2005 Daniel Zappala (zappala at cs.byu.edu) +# Copyright (C) 2005 Brigham Young University +# +# 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. +# +# Further information about the license: http://www.gnu.org/licenses/gpl-2.0.html + +""" +GEDCOM element for a `SUBMITTER_RECORD` submitter record identified by the +`gedcom.tags.GEDCOM_TAG_SUBMITTER` tag. +""" + +import gedcom.tags as tags +from gedcom.element.element import Element +from gedcom.subparsers.address_structure import address_structure +from gedcom.subparsers.note_structure import note_structure +from gedcom.subparsers.change_date import change_date +from gedcom.subparsers.multimedia_link import multimedia_link + + +class SubmitterElement(Element): + """Element associated with a `SUBMITTER_RECORD`""" + + def get_tag(self) -> str: + return tags.GEDCOM_TAG_SUBMITTER + + def get_record(self) -> dict: + """Parse and return the record in dictionary format + """ + record = { + 'key_to_submitter': self.get_pointer(), + 'name': '', + 'address': {}, + 'media': [], + 'language': '', + 'registered_file_number': '', + 'record_id': '', + 'notes': [], + 'change_date': {} + } + for child in self.get_child_elements(): + if child.get_tag() == tags.GEDCOM_TAG_NAME: + record['name'] = child.get_value() + continue + + if child.get_tag() == tags.GEDCOM_TAG_ADDRESS: + record['address'] = address_structure(self) + continue + + if child.get_tag() == tags.GEDCOM_TAG_NOTE: + record['notes'].append(note_structure(child)) + continue + + if child.get_tag() == tags.GEDCOM_TAG_OBJECT: + record['media'].append(multimedia_link(child)) + continue + + if child.get_tag() == tags.GEDCOM_TAG_LANGUAGE: + record['language'] = child.get_value() + continue + + if child.get_tag() == tags.GEDCOM_TAG_REC_FILE_NUMBER: + record['registered_file_number'] = child.get_value() + continue + + if child.get_tag() == tags.GEDCOM_TAG_REC_ID_NUMBER: + record['record_id'] = child.get_value() + continue + + if child.get_tag() == tags.GEDCOM_TAG_CHANGE: + record['change_date'] = change_date(child) + + return record diff --git a/gedcom/errors.py b/gedcom/errors.py new file mode 100644 index 0000000..f8885f2 --- /dev/null +++ b/gedcom/errors.py @@ -0,0 +1,100 @@ +# -*- coding: utf-8 -*- + +# Python GEDCOM Parser +# +# Copyright (C) 2020 Christopher Horn (cdhorn at embarqmail dot com) +# Copyright (C) 2018 Damon Brodie (damon.brodie at gmail.com) +# Copyright (C) 2018-2019 Nicklas Reincke (contact at reynke.com) +# Copyright (C) 2016 Andreas Oberritter +# Copyright (C) 2012 Madeleine Price Ball +# Copyright (C) 2005 Daniel Zappala (zappala at cs.byu.edu) +# Copyright (C) 2005 Brigham Young University +# +# 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. +# +# Further information about the license: http://www.gnu.org/licenses/gpl-2.0.html + +""" +Module containing the exception handling classes. +""" + + +class GedcomFormatViolationError(Exception): + """Raised when the document format does not appear to conform + to the GEDCOM standard and strict parsing required. + """ + + +class GedcomStructureViolationError(Exception): + """Raised when the structure of a record does not conform to + the GEDCOM standard. + """ + + +class GedcomCharacterSetUnsupportedError(Exception): + """Raised when a GEDCOM appears to contain a character set + the standard or the parser does not support. + """ + + +class GedcomVersionUnsupportedError(Exception): + """Raised when a particular GEDCOM version is not supported + by the parser and the standard for that version requires the + parser to reject it. + """ + + +class GedcomFormatUnsupportedError(Exception): + """Raised if the GEDCOM format is not recognized by the + parser. Note some common misspellings as documented on page 148 + in the 5.5.5 GEDCOM standard are treated as `LINEAGE-LINKED` + and allowed when parsing older GEDCOM data. + """ + + +class NotAnActualIndividualError(Exception): + """Raised if record does not appear to be an `INDIVIDUAL_RECORD`""" + + +class NotAnActualFamilyError(Exception): + """Raised if record does not appear to be a `FAM_RECORD`""" + + +class NotAnActualSourceError(Exception): + """Raised if record does not appear to be a `SOURCE_RECORD`""" + + +class NotAnActualRepositoryError(Exception): + """Raised if record does not appear to be a `REPOSITORY_RECORD`""" + + +class NotAnActualNoteError(Exception): + """Raised if record does not appear to be a `NOTE_RECORD`""" + + +class NotAnActualObjectError(Exception): + """Raised if record does not appear to be a `MULTIMEDIA_RECORD`""" + + +class NotAnActualHeaderError(Exception): + """Raised if record does not appear to be a `HEADER`""" + + +class NotAnActualSubmitterError(Exception): + """Raised if record does not appear to be a `SUBMITTER_RECORD`""" + + +class NotAnActualSubmissionError(Exception): + """Raised if record does not appear to be a `SUBMISSION_RECORD`""" diff --git a/gedcom/gedcom.md b/gedcom/gedcom.md index 56076be..e09365a 100644 --- a/gedcom/gedcom.md +++ b/gedcom/gedcom.md @@ -82,6 +82,7 @@ Disabling strict parsing will allow the parser to gracefully handle the followin Licensed under the [GNU General Public License v2](http://www.gnu.org/licenses/gpl-2.0.html) **Python GEDCOM Parser** +
    Copyright (C) 2020 Christopher Horn (cdhorn at embarqmail dot com)
    Copyright (C) 2018 Damon Brodie (damon.brodie at gmail.com)
    Copyright (C) 2018-2019 Nicklas Reincke (contact at reynke.com)
    Copyright (C) 2016 Andreas Oberritter diff --git a/gedcom/parser.py b/gedcom/parser.py index 473ad9e..c0eeea1 100644 --- a/gedcom/parser.py +++ b/gedcom/parser.py @@ -2,6 +2,7 @@ # Python GEDCOM Parser # +# Copyright (C) 2020 Christopher Horn (cdhorn at embarqmail dot com) # Copyright (C) 2018 Damon Brodie (damon.brodie at gmail.com) # Copyright (C) 2018-2019 Nicklas Reincke (contact at reynke.com) # Copyright (C) 2016 Andreas Oberritter @@ -26,35 +27,63 @@ # Further information about the license: http://www.gnu.org/licenses/gpl-2.0.html """ -Module containing the actual `gedcom.parser.Parser` used to generate elements - out of each line - -which can in return be manipulated. +Module containing the actual `gedcom.parser.Parser` used to generate elements +out of each line - which can in return be manipulated. """ import re as regex +from sys import stdout from sys import version_info +from typing import Tuple, List, IO + +import gedcom.tags as tags +import gedcom.standards as standards + +from gedcom.detect import get_encoding, get_version from gedcom.element.element import Element -from gedcom.element.family import FamilyElement, NotAnActualFamilyError -from gedcom.element.file import FileElement -from gedcom.element.individual import IndividualElement, NotAnActualIndividualError +from gedcom.element.header import HeaderElement +from gedcom.element.family import FamilyElement +from gedcom.element.individual import IndividualElement +from gedcom.element.note import NoteElement from gedcom.element.object import ObjectElement +from gedcom.element.source import SourceElement +from gedcom.element.submission import SubmissionElement +from gedcom.element.submitter import SubmitterElement +from gedcom.element.repository import RepositoryElement from gedcom.element.root import RootElement -import gedcom.tags + +from gedcom.errors import GedcomVersionUnsupportedError +from gedcom.errors import GedcomFormatUnsupportedError +from gedcom.errors import GedcomFormatViolationError +from gedcom.errors import NotAnActualIndividualError +from gedcom.errors import NotAnActualFamilyError + +ERROR_TEMPLATE = "Line <{0}:{1}> of document violates GEDCOM format {2}\nSee: {3}" + +RECORD_ELEMENTS = { + tags.GEDCOM_TAG_HEADER: HeaderElement, + tags.GEDCOM_TAG_INDIVIDUAL: IndividualElement, + tags.GEDCOM_TAG_FAMILY: FamilyElement, + tags.GEDCOM_TAG_NOTE: NoteElement, + tags.GEDCOM_TAG_OBJECT: ObjectElement, + tags.GEDCOM_TAG_SOURCE: SourceElement, + tags.GEDCOM_TAG_SUBMISSION: SubmissionElement, + tags.GEDCOM_TAG_SUBMITTER: SubmitterElement, + tags.GEDCOM_TAG_REPOSITORY: RepositoryElement +} FAMILY_MEMBERS_TYPE_ALL = "ALL" -FAMILY_MEMBERS_TYPE_CHILDREN = gedcom.tags.GEDCOM_TAG_CHILD -FAMILY_MEMBERS_TYPE_HUSBAND = gedcom.tags.GEDCOM_TAG_HUSBAND +FAMILY_MEMBERS_TYPE_CHILDREN = tags.GEDCOM_TAG_CHILD +FAMILY_MEMBERS_TYPE_HUSBAND = tags.GEDCOM_TAG_HUSBAND FAMILY_MEMBERS_TYPE_PARENTS = "PARENTS" -FAMILY_MEMBERS_TYPE_WIFE = gedcom.tags.GEDCOM_TAG_WIFE - +FAMILY_MEMBERS_TYPE_WIFE = tags.GEDCOM_TAG_WIFE -class GedcomFormatViolationError(Exception): - pass +class Parser(): + """Parses and manipulates GEDCOM formatted data. -class Parser(object): - """Parses and manipulates GEDCOM 5.5 format data - - For documentation of the GEDCOM 5.5 format, see: http://homepages.rootsweb.ancestry.com/~pmcbride/gedcom/55gctoc.htm + For documentation of the different GEDCOM standards see the + links defined in `gedcom.standards` This parser reads and parses a GEDCOM file. @@ -70,35 +99,36 @@ def __init__(self): self.__root_element = RootElement() def invalidate_cache(self): - """Empties the element list and dictionary to cause `gedcom.parser.Parser.get_element_list()` - and `gedcom.parser.Parser.get_element_dictionary()` to return updated data. + """Empties the element list and dictionary to cause + `gedcom.parser.Parser.get_element_list()` and + `gedcom.parser.Parser.get_element_dictionary()` to return updated data. The update gets deferred until each of the methods actually gets called. """ self.__element_list = [] self.__element_dictionary = {} - def get_element_list(self): - """Returns a list containing all elements from within the GEDCOM file + def get_element_list(self) -> List[Element]: + """Returns a list containing all elements from within the GEDCOM file. By default elements are in the same order as they appeared in the file. This list gets generated on-the-fly, but gets cached. If the database - was modified, you should call `gedcom.parser.Parser.invalidate_cache()` once to let this - method return updated data. + was modified, you should call `gedcom.parser.Parser.invalidate_cache()` once + to let this method return updated data. - Consider using `gedcom.parser.Parser.get_root_element()` or `gedcom.parser.Parser.get_root_child_elements()` to access + Consider using `gedcom.parser.Parser.get_root_element()` or + `gedcom.parser.Parser.get_root_child_elements()` to access the hierarchical GEDCOM tree, unless you rarely modify the database. - - :rtype: list of Element """ if not self.__element_list: for element in self.get_root_child_elements(): self.__build_list(element, self.__element_list) return self.__element_list - def get_element_dictionary(self): - """Returns a dictionary containing all elements, identified by a pointer, from within the GEDCOM file + def get_element_dictionary(self) -> dict: + """Returns a dictionary containing all elements, identified by a pointer, + from within the GEDCOM file. Only elements identified by a pointer are listed in the dictionary. The keys for the dictionary are the pointers. @@ -106,46 +136,51 @@ def get_element_dictionary(self): This dictionary gets generated on-the-fly, but gets cached. If the database was modified, you should call `invalidate_cache()` once to let this method return updated data. - - :rtype: dict of Element """ if not self.__element_dictionary: self.__element_dictionary = { - element.get_pointer(): element for element in self.get_root_child_elements() if element.get_pointer() + element.get_pointer(): + element for element in self.get_root_child_elements() if element.get_pointer() } return self.__element_dictionary - def get_root_element(self): - """Returns a virtual root element containing all logical records as children + def get_root_element(self) -> RootElement: + """Returns a virtual root element containing all logical records as children. When printed, this element converts to an empty string. - - :rtype: RootElement """ return self.__root_element - def get_root_child_elements(self): - """Returns a list of logical records in the GEDCOM file + def get_root_child_elements(self) -> List[Element]: + """Returns a list of logical records in the GEDCOM file. By default, elements are in the same order as they appeared in the file. - - :rtype: list of Element """ return self.get_root_element().get_child_elements() - def parse_file(self, file_path, strict=True): - """Opens and parses a file, from the given file path, as GEDCOM 5.5 formatted data - :type file_path: str - :type strict: bool + def parse_file(self, file_path: str, strict: bool = True): + """Opens and parses a file, from the given file path, as GEDCOM formatted data. """ - with open(file_path, 'rb') as gedcom_stream: + codec = get_encoding(file_path) + real_version, reported_version, reported_format = get_version(file_path, codec) + + if reported_version == '5.5.5': + errmsg = "This parser does not properly support the GEDCOM " + reported_version + \ + " standard at this time\nSee: {0}".format(standards.GEDCOM_5_5_5) + raise GedcomVersionUnsupportedError(errmsg) + + if reported_format not in ['LINEAGE-LINKED', 'LINEAGE_LINKED', + 'LINAGE-LINKED', 'Lineage - Linked']: + errmsg = "This parser does not recognize the GEDCOM format " + reported_format + \ + " at this time\nSee: {0}".format(standards.GEDCOM_5_5_5) + raise GedcomFormatUnsupportedError(errmsg) + + with open(file_path, 'r', encoding=codec) as gedcom_stream: self.parse(gedcom_stream, strict) - def parse(self, gedcom_stream, strict=True): - """Parses a stream, or an array of lines, as GEDCOM 5.5 formatted data - :type gedcom_stream: a file stream, or str array of lines with new line at the end - :type strict: bool + def parse(self, gedcom_stream: IO, strict: bool = True): + """Parses a stream, or an array of lines, as GEDCOM formatted data. """ self.invalidate_cache() self.__root_element = RootElement() @@ -154,24 +189,18 @@ def parse(self, gedcom_stream, strict=True): last_element = self.get_root_element() for line in gedcom_stream: - last_element = self.__parse_line(line_number, line.decode('utf-8-sig'), last_element, strict) + last_element = self.__parse_line(line_number, line, last_element, strict) line_number += 1 # Private methods @staticmethod - def __parse_line(line_number, line, last_element, strict=True): - """Parse a line from a GEDCOM 5.5 formatted document + def __parse_line(line_number: int, line: str, last_element: Element, + strict: bool = True) -> Element: + """Parse a line from a GEDCOM formatted document. Each line should have the following (bracketed items optional): level + ' ' + [pointer + ' ' +] tag + [' ' + line_value] - - :type line_number: int - :type line: str - :type last_element: Element - :type strict: bool - - :rtype: Element """ # Level must start with non-negative int, no leading zeros. @@ -190,43 +219,43 @@ def __parse_line(line_number, line, last_element, strict=True): end_of_line_regex = '([\r\n]{1,2})' # Complete regex - gedcom_line_regex = level_regex + pointer_regex + tag_regex + value_regex + end_of_line_regex + gedcom_line_regex = level_regex + pointer_regex + tag_regex + \ + value_regex + end_of_line_regex regex_match = regex.match(gedcom_line_regex, line) if regex_match is None: if strict: - error_message = ("Line <%d:%s> of document violates GEDCOM format 5.5" % (line_number, line) - + "\nSee: https://chronoplexsoftware.com/gedcomvalidator/gedcom/gedcom-5.5.pdf") - raise GedcomFormatViolationError(error_message) + errmsg = ERROR_TEMPLATE.format(line_number, line, '5.5.1', standards.GEDCOM_5_5_1) + raise GedcomFormatViolationError(errmsg) + + # Quirk check - see if this is a line without a CRLF (which could be the last line) + last_line_regex = level_regex + pointer_regex + tag_regex + value_regex + regex_match = regex.match(last_line_regex, line) + if regex_match is not None: + line_parts = regex_match.groups() + + level = int(line_parts[0]) + pointer = line_parts[1].rstrip(' ') + tag = line_parts[2] + value = line_parts[3][1:] + crlf = '\n' else: - # Quirk check - see if this is a line without a CRLF (which could be the last line) - last_line_regex = level_regex + pointer_regex + tag_regex + value_regex - regex_match = regex.match(last_line_regex, line) - if regex_match is not None: - line_parts = regex_match.groups() - - level = int(line_parts[0]) - pointer = line_parts[1].rstrip(' ') - tag = line_parts[2] - value = line_parts[3][1:] - crlf = '\n' - else: - # Quirk check - Sometimes a gedcom has a text field with a CR. - # This creates a line without the standard level and pointer. - # If this is detected then turn it into a CONC or CONT. - line_regex = '([^\n\r]*|)' - cont_line_regex = line_regex + end_of_line_regex - regex_match = regex.match(cont_line_regex, line) - line_parts = regex_match.groups() - level = last_element.get_level() - tag = last_element.get_tag() - pointer = None - value = line_parts[0][1:] - crlf = line_parts[1] - if tag != gedcom.tags.GEDCOM_TAG_CONTINUED and tag != gedcom.tags.GEDCOM_TAG_CONCATENATION: - # Increment level and change this line to a CONC - level += 1 - tag = gedcom.tags.GEDCOM_TAG_CONCATENATION + # Quirk check - Sometimes a gedcom has a text field with a CR. + # This creates a line without the standard level and pointer. + # If this is detected then turn it into a CONC or CONT. + line_regex = '([^\n\r]*|)' + cont_line_regex = line_regex + end_of_line_regex + regex_match = regex.match(cont_line_regex, line) + line_parts = regex_match.groups() + level = last_element.get_level() + tag = last_element.get_tag() + pointer = None + value = line_parts[0][1:] + crlf = line_parts[1] + if tag not in [tags.GEDCOM_TAG_CONTINUED, tags.GEDCOM_TAG_CONCATENATION]: + # Increment level and change this line to a CONC + level += 1 + tag = tags.GEDCOM_TAG_CONCATENATION else: line_parts = regex_match.groups() @@ -238,20 +267,14 @@ def __parse_line(line_number, line, last_element, strict=True): # Check level: should never be more than one higher than previous line. if level > last_element.get_level() + 1: - error_message = ("Line %d of document violates GEDCOM format 5.5" % line_number - + "\nLines must be no more than one level higher than previous line." - + "\nSee: https://chronoplexsoftware.com/gedcomvalidator/gedcom/gedcom-5.5.pdf") - raise GedcomFormatViolationError(error_message) + errmsg = "Line {0} of document violates GEDCOM format 5.5.1\n".format(line_number) + \ + "Lines must be no more than one level higher than previous line.\n" + \ + "See: {0}".format(standards.GEDCOM_5_5_1) + raise GedcomFormatViolationError(errmsg) # Create element. Store in list and dict, create children and parents. - if tag == gedcom.tags.GEDCOM_TAG_INDIVIDUAL: - element = IndividualElement(level, pointer, tag, value, crlf, multi_line=False) - elif tag == gedcom.tags.GEDCOM_TAG_FAMILY: - element = FamilyElement(level, pointer, tag, value, crlf, multi_line=False) - elif tag == gedcom.tags.GEDCOM_TAG_FILE: - element = FileElement(level, pointer, tag, value, crlf, multi_line=False) - elif tag == gedcom.tags.GEDCOM_TAG_OBJECT: - element = ObjectElement(level, pointer, tag, value, crlf, multi_line=False) + if tag in RECORD_ELEMENTS: + element = RECORD_ELEMENTS[tag](level, pointer, tag, value, crlf, multi_line=False) else: element = Element(level, pointer, tag, value, crlf, multi_line=False) @@ -266,10 +289,8 @@ def __parse_line(line_number, line, last_element, strict=True): return element - def __build_list(self, element, element_list): - """Recursively add elements to a list containing elements - :type element: Element - :type element_list: list of Element + def __build_list(self, element: Element, element_list: List[Element]): + """Recursively add elements to a list containing elements. """ element_list.append(element) for child in element.get_child_elements(): @@ -277,81 +298,74 @@ def __build_list(self, element, element_list): # Methods for analyzing individuals and relationships between individuals - def get_marriages(self, individual): - """Returns a list of marriages of an individual formatted as a tuple (`str` date, `str` place) - :type individual: IndividualElement - :rtype: tuple + def get_marriages(self, individual: IndividualElement) -> Tuple[str, str]: + """Returns a list of marriages of an individual formatted as a tuple: + (`str` date, `str` place) """ marriages = [] if not isinstance(individual, IndividualElement): raise NotAnActualIndividualError( - "Operation only valid for elements with %s tag" % gedcom.tags.GEDCOM_TAG_INDIVIDUAL + "Operation only valid for elements with %s tag" % tags.GEDCOM_TAG_INDIVIDUAL ) # Get and analyze families where individual is spouse. - families = self.get_families(individual, gedcom.tags.GEDCOM_TAG_FAMILY_SPOUSE) + families = self.get_families(individual, tags.GEDCOM_TAG_FAMILY_SPOUSE) for family in families: for family_data in family.get_child_elements(): - if family_data.get_tag() == gedcom.tags.GEDCOM_TAG_MARRIAGE: + if family_data.get_tag() == tags.GEDCOM_TAG_MARRIAGE: date = '' place = '' for marriage_data in family_data.get_child_elements(): - if marriage_data.get_tag() == gedcom.tags.GEDCOM_TAG_DATE: + if marriage_data.get_tag() == tags.GEDCOM_TAG_DATE: date = marriage_data.get_value() - if marriage_data.get_tag() == gedcom.tags.GEDCOM_TAG_PLACE: + if marriage_data.get_tag() == tags.GEDCOM_TAG_PLACE: place = marriage_data.get_value() marriages.append((date, place)) return marriages - def get_marriage_years(self, individual): - """Returns a list of marriage years (as integers) for an individual - :type individual: IndividualElement - :rtype: list of int + def get_marriage_years(self, individual: IndividualElement) -> List[int]: + """Returns a list of marriage years for an individual. """ dates = [] if not isinstance(individual, IndividualElement): raise NotAnActualIndividualError( - "Operation only valid for elements with %s tag" % gedcom.tags.GEDCOM_TAG_INDIVIDUAL + "Operation only valid for elements with %s tag" % tags.GEDCOM_TAG_INDIVIDUAL ) # Get and analyze families where individual is spouse. - families = self.get_families(individual, gedcom.tags.GEDCOM_TAG_FAMILY_SPOUSE) + families = self.get_families(individual, tags.GEDCOM_TAG_FAMILY_SPOUSE) for family in families: for child in family.get_child_elements(): - if child.get_tag() == gedcom.tags.GEDCOM_TAG_MARRIAGE: - for childOfChild in child.get_child_elements(): - if childOfChild.get_tag() == gedcom.tags.GEDCOM_TAG_DATE: - date = childOfChild.get_value().split()[-1] + if child.get_tag() == tags.GEDCOM_TAG_MARRIAGE: + for gchild in child.get_child_elements(): + if gchild.get_tag() == tags.GEDCOM_TAG_DATE: + date = gchild.get_value().split()[-1] try: dates.append(int(date)) except ValueError: pass return dates - def marriage_year_match(self, individual, year): - """Checks if one of the marriage years of an individual matches the supplied year. Year is an integer. - :type individual: IndividualElement - :type year: int - :rtype: bool + def marriage_year_match(self, individual: IndividualElement, year: int) -> bool: + """Checks if one of the marriage years of an individual matches the supplied year. + Year is an integer. """ if not isinstance(individual, IndividualElement): raise NotAnActualIndividualError( - "Operation only valid for elements with %s tag" % gedcom.tags.GEDCOM_TAG_INDIVIDUAL + "Operation only valid for elements with %s tag" % tags.GEDCOM_TAG_INDIVIDUAL ) years = self.get_marriage_years(individual) return year in years - def marriage_range_match(self, individual, from_year, to_year): - """Check if one of the marriage years of an individual is in a given range. Years are integers. - :type individual: IndividualElement - :type from_year: int - :type to_year: int - :rtype: bool + def marriage_range_match(self, individual: IndividualElement, + from_year: int, to_year: int) -> bool: + """Check if one of the marriage years of an individual is in a given range. + Years are integers. """ if not isinstance(individual, IndividualElement): raise NotAnActualIndividualError( - "Operation only valid for elements with %s tag" % gedcom.tags.GEDCOM_TAG_INDIVIDUAL + "Operation only valid for elements with %s tag" % tags.GEDCOM_TAG_INDIVIDUAL ) years = self.get_marriage_years(individual) @@ -360,20 +374,19 @@ def marriage_range_match(self, individual, from_year, to_year): return True return False - def get_families(self, individual, family_type=gedcom.tags.GEDCOM_TAG_FAMILY_SPOUSE): - """Return family elements listed for an individual + def get_families(self, individual: IndividualElement, + family_type: str = tags.GEDCOM_TAG_FAMILY_SPOUSE) -> List[FamilyElement]: + """Return family elements listed for an individual. + + Optional argument `family_type` can be used to return specific subsets: - family_type can be `gedcom.tags.GEDCOM_TAG_FAMILY_SPOUSE` (families where the individual is a spouse) or - `gedcom.tags.GEDCOM_TAG_FAMILY_CHILD` (families where the individual is a child). If a value is not - provided, `gedcom.tags.GEDCOM_TAG_FAMILY_SPOUSE` is default value. + `tags.GEDCOM_TAG_FAMILY_SPOUSE`: Default, families where the individual is a spouse. - :type individual: IndividualElement - :type family_type: str - :rtype: list of FamilyElement + `tags.GEDCOM_TAG_FAMILY_CHILD`: Families where the individual is a child. """ if not isinstance(individual, IndividualElement): raise NotAnActualIndividualError( - "Operation only valid for elements with %s tag" % gedcom.tags.GEDCOM_TAG_INDIVIDUAL + "Operation only valid for elements with %s tag" % tags.GEDCOM_TAG_INDIVIDUAL ) families = [] @@ -388,19 +401,19 @@ def get_families(self, individual, family_type=gedcom.tags.GEDCOM_TAG_FAMILY_SPO return families - def get_ancestors(self, individual, ancestor_type="ALL"): - """Return elements corresponding to ancestors of an individual + def get_ancestors(self, individual: IndividualElement, + ancestor_type: str = "ALL") -> List[Element]: + """Return elements corresponding to ancestors of an individual. + + Optional argument `ancestor_type` can be used to return specific subsets: - Optional `ancestor_type`. Default "ALL" returns all ancestors, "NAT" can be - used to specify only natural (genetic) ancestors. + "ALL": Default, returns all ancestors. - :type individual: IndividualElement - :type ancestor_type: str - :rtype: list of Element + "NAT": Return only natural (genetic) ancestors. """ if not isinstance(individual, IndividualElement): raise NotAnActualIndividualError( - "Operation only valid for elements with %s tag" % gedcom.tags.GEDCOM_TAG_INDIVIDUAL + "Operation only valid for elements with %s tag" % tags.GEDCOM_TAG_INDIVIDUAL ) parents = self.get_parents(individual, ancestor_type) @@ -412,49 +425,53 @@ def get_ancestors(self, individual, ancestor_type="ALL"): return ancestors - def get_parents(self, individual, parent_type="ALL"): - """Return elements corresponding to parents of an individual + def get_parents(self, individual: IndividualElement, + parent_type: str = "ALL") -> List[IndividualElement]: + """Return elements corresponding to parents of an individual. - Optional parent_type. Default "ALL" returns all parents. "NAT" can be - used to specify only natural (genetic) parents. + Optional argument `parent_type` can be used to return specific subsets: - :type individual: IndividualElement - :type parent_type: str - :rtype: list of IndividualElement + "ALL": Default, returns all parents. + + "NAT": Return only natural (genetic) parents. """ if not isinstance(individual, IndividualElement): raise NotAnActualIndividualError( - "Operation only valid for elements with %s tag" % gedcom.tags.GEDCOM_TAG_INDIVIDUAL + "Operation only valid for elements with %s tag" % tags.GEDCOM_TAG_INDIVIDUAL ) parents = [] - families = self.get_families(individual, gedcom.tags.GEDCOM_TAG_FAMILY_CHILD) + families = self.get_families(individual, tags.GEDCOM_TAG_FAMILY_CHILD) for family in families: if parent_type == "NAT": for family_member in family.get_child_elements(): - if family_member.get_tag() == gedcom.tags.GEDCOM_TAG_CHILD \ + if family_member.get_tag() == tags.GEDCOM_TAG_CHILD \ and family_member.get_value() == individual.get_pointer(): for child in family_member.get_child_elements(): if child.get_value() == "Natural": - if child.get_tag() == gedcom.tags.GEDCOM_PROGRAM_DEFINED_TAG_MREL: - parents += self.get_family_members(family, gedcom.tags.GEDCOM_TAG_WIFE) - elif child.get_tag() == gedcom.tags.GEDCOM_PROGRAM_DEFINED_TAG_FREL: - parents += self.get_family_members(family, gedcom.tags.GEDCOM_TAG_HUSBAND) + if child.get_tag() == tags.GEDCOM_PROGRAM_DEFINED_TAG_MREL: + parents += self.get_family_members(family, + tags.GEDCOM_TAG_WIFE) + elif child.get_tag() == tags.GEDCOM_PROGRAM_DEFINED_TAG_FREL: + parents += self.get_family_members(family, + tags.GEDCOM_TAG_HUSBAND) else: parents += self.get_family_members(family, "PARENTS") return parents - def find_path_to_ancestor(self, descendant, ancestor, path=None): - """Return path from descendant to ancestor + def find_path_to_ancestor(self, descendant: IndividualElement, + ancestor: IndividualElement, path: str = None): + """Return path from descendant to ancestor. :rtype: object """ - if not isinstance(descendant, IndividualElement) and isinstance(ancestor, IndividualElement): + if not isinstance(descendant, IndividualElement) and isinstance(ancestor, + IndividualElement): raise NotAnActualIndividualError( - "Operation only valid for elements with %s tag." % gedcom.tags.GEDCOM_TAG_INDIVIDUAL + "Operation only valid for elements with %s tag." % tags.GEDCOM_TAG_INDIVIDUAL ) if not path: @@ -462,33 +479,34 @@ def find_path_to_ancestor(self, descendant, ancestor, path=None): if path[-1].get_pointer() == ancestor.get_pointer(): return path - else: - parents = self.get_parents(descendant, "NAT") - for parent in parents: - potential_path = self.find_path_to_ancestor(parent, ancestor, path + [parent]) - if potential_path is not None: - return potential_path + + parents = self.get_parents(descendant, "NAT") + for parent in parents: + potential_path = self.find_path_to_ancestor(parent, ancestor, path + [parent]) + if potential_path is not None: + return potential_path return None - def get_family_members(self, family, members_type=FAMILY_MEMBERS_TYPE_ALL): - """Return array of family members: individual, spouse, and children + def get_family_members(self, family: FamilyElement, + members_type: str = FAMILY_MEMBERS_TYPE_ALL) -> List[IndividualElement]: + """Return array of family members: individual, spouse, and children. Optional argument `members_type` can be used to return specific subsets: "FAMILY_MEMBERS_TYPE_ALL": Default, return all members of the family + "FAMILY_MEMBERS_TYPE_PARENTS": Return individuals with "HUSB" and "WIFE" tags (parents) + "FAMILY_MEMBERS_TYPE_HUSBAND": Return individuals with "HUSB" tags (father) + "FAMILY_MEMBERS_TYPE_WIFE": Return individuals with "WIFE" tags (mother) - "FAMILY_MEMBERS_TYPE_CHILDREN": Return individuals with "CHIL" tags (children) - :type family: FamilyElement - :type members_type: str - :rtype: list of IndividualElement + "FAMILY_MEMBERS_TYPE_CHILDREN": Return individuals with "CHIL" tags (children) """ if not isinstance(family, FamilyElement): raise NotAnActualFamilyError( - "Operation only valid for element with %s tag." % gedcom.tags.GEDCOM_TAG_FAMILY + "Operation only valid for element with %s tag." % tags.GEDCOM_TAG_FAMILY ) family_members = [] @@ -496,19 +514,19 @@ def get_family_members(self, family, members_type=FAMILY_MEMBERS_TYPE_ALL): for child_element in family.get_child_elements(): # Default is ALL - is_family = (child_element.get_tag() == gedcom.tags.GEDCOM_TAG_HUSBAND - or child_element.get_tag() == gedcom.tags.GEDCOM_TAG_WIFE - or child_element.get_tag() == gedcom.tags.GEDCOM_TAG_CHILD) + is_family = (child_element.get_tag() == tags.GEDCOM_TAG_HUSBAND + or child_element.get_tag() == tags.GEDCOM_TAG_WIFE + or child_element.get_tag() == tags.GEDCOM_TAG_CHILD) if members_type == FAMILY_MEMBERS_TYPE_PARENTS: - is_family = (child_element.get_tag() == gedcom.tags.GEDCOM_TAG_HUSBAND - or child_element.get_tag() == gedcom.tags.GEDCOM_TAG_WIFE) + is_family = (child_element.get_tag() == tags.GEDCOM_TAG_HUSBAND + or child_element.get_tag() == tags.GEDCOM_TAG_WIFE) elif members_type == FAMILY_MEMBERS_TYPE_HUSBAND: - is_family = child_element.get_tag() == gedcom.tags.GEDCOM_TAG_HUSBAND + is_family = child_element.get_tag() == tags.GEDCOM_TAG_HUSBAND elif members_type == FAMILY_MEMBERS_TYPE_WIFE: - is_family = child_element.get_tag() == gedcom.tags.GEDCOM_TAG_WIFE + is_family = child_element.get_tag() == tags.GEDCOM_TAG_WIFE elif members_type == FAMILY_MEMBERS_TYPE_CHILDREN: - is_family = child_element.get_tag() == gedcom.tags.GEDCOM_TAG_CHILD + is_family = child_element.get_tag() == tags.GEDCOM_TAG_CHILD if is_family and child_element.get_value() in element_dictionary: family_members.append(element_dictionary[child_element.get_value()]) @@ -517,9 +535,9 @@ def get_family_members(self, family, members_type=FAMILY_MEMBERS_TYPE_ALL): # Other methods - def to_gedcom_string(self, recursive=False): - """Formats all elements and optionally all of the sub-elements into a GEDCOM string - :type recursive: bool + def to_gedcom_string(self, recursive: bool = False) -> str: + """Formats all elements and optionally all of the sub-elements into a + GEDCOM string. """ is_gte_python_3 = version_info[0] >= 3 output = '' if is_gte_python_3 else b'' @@ -533,13 +551,10 @@ def to_gedcom_string(self, recursive=False): return output def print_gedcom(self): - """Write GEDCOM data to stdout""" - from sys import stdout + """Write GEDCOM data to stdout.""" self.save_gedcom(stdout) - def save_gedcom(self, open_file, recursive=True): - """Save GEDCOM data to a file - :type open_file: file - :type recursive: bool + def save_gedcom(self, open_file: IO, recursive: bool = True): + """Save GEDCOM data to a file. """ open_file.write(self.to_gedcom_string(recursive)) diff --git a/gedcom/reader.py b/gedcom/reader.py new file mode 100644 index 0000000..cac6727 --- /dev/null +++ b/gedcom/reader.py @@ -0,0 +1,124 @@ +# -*- coding: utf-8 -*- + +# Python GEDCOM Parser +# +# Copyright (C) 2020 Christopher Horn (cdhorn at embarqmail dot com) +# Copyright (C) 2018 Damon Brodie (damon.brodie at gmail.com) +# Copyright (C) 2018-2019 Nicklas Reincke (contact at reynke.com) +# Copyright (C) 2016 Andreas Oberritter +# Copyright (C) 2012 Madeleine Price Ball +# Copyright (C) 2005 Daniel Zappala (zappala at cs.byu.edu) +# Copyright (C) 2005 Brigham Young University +# +# 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. +# +# Further information about the license: http://www.gnu.org/licenses/gpl-2.0.html + +""" +Module containing a `gedcom.reader.Reader` with higher order methods than the +base `gedcom.parser.Parser` for extracting records as structured data. +""" + +from typing import Union + +from gedcom.parser import Parser +from gedcom.element.header import HeaderElement +from gedcom.element.individual import IndividualElement +from gedcom.element.family import FamilyElement +from gedcom.element.note import NoteElement +from gedcom.element.object import ObjectElement +from gedcom.element.source import SourceElement +from gedcom.element.submission import SubmissionElement +from gedcom.element.submitter import SubmitterElement +from gedcom.element.repository import RepositoryElement + +ELEMENT_TYPES = { + 'header': HeaderElement, + 'individual': IndividualElement, + 'family': FamilyElement, + 'note': NoteElement, + 'media': ObjectElement, + 'source': SourceElement, + 'submission': SubmissionElement, + 'submitter': SubmitterElement, + 'repository': RepositoryElement +} + +RECORD_KEYS = { + 'header': None, + 'individual': 'key_to_individual', + 'family': 'key_to_family', + 'media': 'key_to_object', + 'note': 'key_to_note', + 'source': 'key_to_source', + 'submission': 'key_to_submission', + 'submitter': 'key_to_submitter', + 'repository': 'key_to_repository' +} + + +class Reader(Parser): + """Simple wrapper around the core `gedcom.parser.Parser` with methods for + extracting parsed records as structured data. + """ + + def get_records_by_type(self, record_type: str, + return_output_as_list: bool = True) -> Union[list, dict]: + """Return either a list or dictionary with all of the requested records for the + given `gedcom.records` record type. + """ + record_list = [] + record_dict = {} + + for element in self.get_root_child_elements(): + if isinstance(element, ELEMENT_TYPES[record_type]): + record = element.get_record() + if return_output_as_list: + record_list.append(record) + else: + if RECORD_KEYS[record_type] is not None: + record_dict.update({record[RECORD_KEYS[record_type]]: record}) + else: + record_dict.update({'@HEAD@': record}) + + if return_output_as_list: + return record_list + + return record_dict + + def get_all_records(self, return_entries_as_list: bool = True) -> dict: + """Return a dictionary with all of the available records in the GEDCOM broken + down by record type.""" + record_dict = {} + + for key in RECORD_KEYS: + if return_entries_as_list: + record_dict.update({key: []}) + else: + record_dict.update({key: {}}) + + for element in self.get_root_child_elements(): + for key in ELEMENT_TYPES: + if isinstance(element, ELEMENT_TYPES[key]): + record = element.get_record() + if return_entries_as_list: + record_dict[key].append(record) + else: + if key != 'header': + record_dict[key].update({record[RECORD_KEYS[key]]: record}) + else: + record_dict['header'].update({'@HEAD@': record}) + + return record_dict diff --git a/gedcom/records.py b/gedcom/records.py new file mode 100644 index 0000000..a2ae70f --- /dev/null +++ b/gedcom/records.py @@ -0,0 +1,55 @@ +# -*- coding: utf-8 -*- + +# Python GEDCOM Parser +# +# Copyright (C) 2020 Christopher Horn (cdhorn at embarqmail dot com) +# Copyright (C) 2018 Damon Brodie (damon.brodie at gmail.com) +# Copyright (C) 2018-2019 Nicklas Reincke (contact at reynke.com) +# Copyright (C) 2016 Andreas Oberritter +# Copyright (C) 2012 Madeleine Price Ball +# Copyright (C) 2005 Daniel Zappala (zappala at cs.byu.edu) +# Copyright (C) 2005 Brigham Young University +# +# 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. +# +# Further information about the license: http://www.gnu.org/licenses/gpl-2.0.html + +"""Module containing the standard GEDCOM record types recognized by the +GEDCOM `gedcom.reader.Reader`.""" + + +GEDCOM_RECORD_FAMILY = 'family' +"""Identifies the `FAM_RECORD` record type.""" + +GEDCOM_RECORD_HEADER = 'header' +"""Identifies the `HEADER` record type.""" + +GEDCOM_RECORD_INDIVIDUAL = 'individual' +"""Identifies the `INDIVIDUAL_RECORD` record type.""" + +GEDCOM_RECORD_NOTE = 'note' +"""Identifies the `NOTE_RECORD` record type.""" + +GEDCOM_RECORD_SOURCE = 'source' +"""Identifies the `SOURCE_RECORD` record type.""" + +GEDCOM_RECORD_REPOSITORY = 'repository' +"""Identifies the `REPOSITORY_RECORD` record type.""" + +GEDCOM_RECORD_SUBMISSION = 'submission' +"""Identifies the `SUBMISSION_RECORD` record type.""" + +GEDCOM_RECORD_SUBMITTER = 'submitter' +"""Identifies the `SUBMITTER_RECORD` record type.""" diff --git a/gedcom/element/file.py b/gedcom/standards.py similarity index 59% rename from gedcom/element/file.py rename to gedcom/standards.py index d02e8eb..7bbd9b1 100644 --- a/gedcom/element/file.py +++ b/gedcom/standards.py @@ -2,6 +2,7 @@ # Python GEDCOM Parser # +# Copyright (C) 2020 Christopher Horn (cdhorn at embarqmail dot com) # Copyright (C) 2018 Damon Brodie (damon.brodie at gmail.com) # Copyright (C) 2018-2019 Nicklas Reincke (contact at reynke.com) # Copyright (C) 2016 Andreas Oberritter @@ -25,17 +26,19 @@ # # Further information about the license: http://www.gnu.org/licenses/gpl-2.0.html -"""GEDCOM element consisting of tag `gedcom.tags.GEDCOM_TAG_FILE`""" +"""Module containing links to the documentation for the various GEDCOM standards.""" -from gedcom.element.element import Element -import gedcom.tags +GEDCOM_5_5 = "https://edge.fscdn.org/assets/img/documents/" + \ + "gedcom55-82e1509bd8dbe7477e3b500e4f62c240.pdf" +"""The official FamilySearch GEDCOM 5.5 Standard.""" +GEDCOM_5_5_1 = "https://edge.fscdn.org/assets/img/documents/" + \ + "ged551-5bac5e57fe88dd37df0e153d9c515335.pdf" +"""The official FamilySearch GEDCOM 5.5.1 Standard.""" -class NotAnActualFileError(Exception): - pass +GEDCOM_5_5_1_GEDCOM_L_ADDENDUM = "https://genealogy.net/GEDCOM/" + \ + "GEDCOM551%20GEDCOM-L%20Addendum-R1.pdf" +"""The GEDCOM-L working group GEDCOM 5.5.1 Addendum.""" - -class FileElement(Element): - - def get_tag(self): - return gedcom.tags.GEDCOM_TAG_FILE +GEDCOM_5_5_5 = "https://www.gedcom.org/specs/GEDCOM555.zip" +"""The gedcom.org GEDCOM 5.5.5 Specification With Annotations.""" diff --git a/gedcom/subparsers/__init__.py b/gedcom/subparsers/__init__.py new file mode 100644 index 0000000..69162ac --- /dev/null +++ b/gedcom/subparsers/__init__.py @@ -0,0 +1,48 @@ +# -*- coding: utf-8 -*- + +# Python GEDCOM Parser +# +# Copyright (C) 2020 Christopher Horn (cdhorn at embarqmail dot com) +# +# 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. +# +# Further information about the license: http://www.gnu.org/licenses/gpl-2.0.html + +"""Module containing parsers for extracting various substructures from the +different record types as defined in the GEDCOM standard.""" + +__all__ = [ + "address_structure", + "association_structure", + "change_date", + "child_to_family_link", + "event_detail", + "family_event_detail", + "family_event_structure", + "individual_attribute_structure", + "individual_event_detail", + "individual_event_structure", + "lds_individual_ordinance", + "lds_spouse_sealing", + "multimedia_link", + "note_structure", + "personal_name_pieces", + "personal_name_structure", + "place_structure", + "source_citation", + "source_repository_citation", + "spouse_to_family_link", + "user_reference_number" +] diff --git a/gedcom/subparsers/address_structure.py b/gedcom/subparsers/address_structure.py new file mode 100644 index 0000000..873c8c4 --- /dev/null +++ b/gedcom/subparsers/address_structure.py @@ -0,0 +1,84 @@ +# -*- coding: utf-8 -*- + +# Python GEDCOM Parser +# +# Copyright (C) 2020 Christopher Horn (cdhorn at embarqmail dot com) +# +# 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. +# +# Further information about the license: http://www.gnu.org/licenses/gpl-2.0.html + +""" +Substructure parser for a `ADDRESS_STRUCTURE` embedded record. + +This is referenced as part of a larger structure so there is no anchor tag. +The `gedcom.tags.GEDCOM_TAG_ADDRESS` tag is at the same level as some of +the other parts of this structure. +""" + +import gedcom.tags as tags +from gedcom.element.element import Element + +ADDRESS_TAGS = { + tags.GEDCOM_PROGRAM_DEFINED_TAG_ADDRESSE: 'addresse', + tags.GEDCOM_TAG_ADDRESS1: 'address1', + tags.GEDCOM_TAG_ADDRESS2: 'address2', + tags.GEDCOM_TAG_ADDRESS3: 'address3', + tags.GEDCOM_TAG_CITY: 'city', + tags.GEDCOM_TAG_STATE: 'state', + tags.GEDCOM_TAG_POSTAL_CODE: 'postal_code', + tags.GEDCOM_TAG_COUNTRY: 'country' +} + +CONTACT_TAGS = { + tags.GEDCOM_TAG_PHONE: 'phone', + tags.GEDCOM_TAG_EMAIL: 'email', + tags.GEDCOM_TAG_FAX: 'fax', + tags.GEDCOM_TAG_WWW: 'www' +} + + +def address_structure(element: Element) -> dict: + """Parses and extracts a `ADDRESS_STRUCTURE` structure. + + The `element` should be the parent that contains it. + """ + record = { + 'address': '', + 'addresse': '', + 'address1': '', + 'address2': '', + 'address3': '', + 'city': '', + 'state': '', + 'postal_code': '', + 'country': '', + 'phone': [], + 'email': [], + 'fax': [], + 'www': [] + } + for child in element.get_child_elements(): + if child.get_tag() == tags.GEDCOM_TAG_ADDRESS: + record['address'] = child.get_multi_line_value() + for gchild in child.get_child_elements(): + if gchild.get_tag() in ADDRESS_TAGS: + record[ADDRESS_TAGS[gchild.get_tag()]] = gchild.get_value() + continue + + if child.get_tag() in CONTACT_TAGS: + record[CONTACT_TAGS[child.get_tag()]].append(child.get_value()) + + return record diff --git a/gedcom/subparsers/association_structure.py b/gedcom/subparsers/association_structure.py new file mode 100644 index 0000000..45dd76e --- /dev/null +++ b/gedcom/subparsers/association_structure.py @@ -0,0 +1,58 @@ +# -*- coding: utf-8 -*- + +# Python GEDCOM Parser +# +# Copyright (C) 2020 Christopher Horn (cdhorn at embarqmail dot com) +# +# 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. +# +# Further information about the license: http://www.gnu.org/licenses/gpl-2.0.html + +""" +Substructure parser for the `ASSOCIATION_STRUCTURE` record. + +This is anchored by the `gedcom.tags.GEDCOM_TAG_ASSOCIATES` tag. +""" + +import gedcom.tags as tags +from gedcom.element.element import Element +from gedcom.subparsers.note_structure import note_structure +from gedcom.subparsers.source_citation import source_citation + + +def association_structure(element: Element) -> dict: + """Parses and extracts the `ASSOCIATION_STRUCTURE` structure. + + The `element` should contain the `gedcom.tags.GEDCOM_TAG_ASSOCIATES` tag. + """ + record = { + 'key_to_individual': element.get_value(), + 'relationship': '', + 'citations': [], + 'notes': [] + } + for child in element.get_child_elements(): + if child.get_tag() == tags.GEDCOM_TAG_RELATIONSHIP: + record['relationship'] = child.get_value() + continue + + if child.get_tag() == tags.GEDCOM_TAG_NOTE: + record['notes'].append(note_structure(child)) + continue + + if child.get_tag() == tags.GEDCOM_TAG_SOURCE: + record['citations'].append(source_citation(child)) + + return record diff --git a/gedcom/subparsers/change_date.py b/gedcom/subparsers/change_date.py new file mode 100644 index 0000000..f53823d --- /dev/null +++ b/gedcom/subparsers/change_date.py @@ -0,0 +1,56 @@ +# -*- coding: utf-8 -*- + +# Python GEDCOM Parser +# +# Copyright (C) 2020 Christopher Horn (cdhorn at embarqmail dot com) +# +# 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. +# +# Further information about the license: http://www.gnu.org/licenses/gpl-2.0.html + +""" +Substructure parser for a `CHANGE_DATE` record. + +This is anchored by the `gedcom.tags.GEDCOM_TAG_CHANGE` tag. +""" + +import gedcom.tags as tags +from gedcom.element.element import Element +from gedcom.subparsers.note_structure import note_structure + + +def change_date(element: Element) -> dict: + """Parses and extracts a `CHANGE_DATE` structure. + + The `element` should contain the `gedcom.tags.GEDCOM_TAG_CHANGE` tag. + """ + record = { + 'date': '', + 'time': '', + 'notes': [] + } + for child in element.get_child_elements(): + if child.get_tag() == tags.GEDCOM_TAG_DATE: + record['date'] = child.get_value() + for gchild in child.get_child_elements(): + if gchild.get_tag() == tags.GEDCOM_TAG_TIME: + record['time'] = gchild.get_value() + continue + continue + + if child.get_tag() == tags.GEDCOM_TAG_NOTE: + record['notes'].append(note_structure(child)) + + return record diff --git a/gedcom/subparsers/child_to_family_link.py b/gedcom/subparsers/child_to_family_link.py new file mode 100644 index 0000000..8f63141 --- /dev/null +++ b/gedcom/subparsers/child_to_family_link.py @@ -0,0 +1,57 @@ +# -*- coding: utf-8 -*- + +# Python GEDCOM Parser +# +# Copyright (C) 2020 Christopher Horn (cdhorn at embarqmail dot com) +# +# 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. +# +# Further information about the license: http://www.gnu.org/licenses/gpl-2.0.html + +""" +Substructure parser for a `CHILD_TO_FAMILY_LINK` record. + +This is anchored by the `gedcom.tags.GEDCOM_TAG_FAMILY_CHILD` tag. +""" + +import gedcom.tags as tags +from gedcom.element.element import Element +from gedcom.subparsers.note_structure import note_structure + + +def child_to_family_link(element: Element) -> dict: + """Parses and extracts a `CHILD_TO_FAMILY_LINK` structure. + + The `element` should contain the `gedcom.tags.GEDCOM_TAG_FAMILY_CHILD` tag. + """ + record = { + 'key_to_family': element.get_value(), + 'pedigree': '', + 'status': '', + 'notes': [] + } + for child in element.get_child_elements(): + if child.get_tag() == tags.GEDCOM_TAG_PEDIGREE: + record['pedigree'] = child.get_value() + continue + + if child.get_tag() == tags.GEDCOM_TAG_STATUS: + record['status'] = child.get_value() + continue + + if child.get_tag() == tags.GEDCOM_TAG_NOTE: + record['notes'].append(note_structure(child)) + + return record diff --git a/gedcom/subparsers/event_detail.py b/gedcom/subparsers/event_detail.py new file mode 100644 index 0000000..2dac099 --- /dev/null +++ b/gedcom/subparsers/event_detail.py @@ -0,0 +1,89 @@ +# -*- coding: utf-8 -*- + +# Python GEDCOM Parser +# +# Copyright (C) 2020 Christopher Horn (cdhorn at embarqmail dot com) +# +# 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. +# +# Further information about the license: http://www.gnu.org/licenses/gpl-2.0.html + +""" +Substructure parser for a `EVENT_DETAIL` embedded record. + +This is referenced as part of a larger structure so there is no anchor tag. +""" + +import gedcom.tags as tags +from gedcom.element.element import Element +from gedcom.subparsers.place_structure import place_structure +from gedcom.subparsers.address_structure import address_structure +from gedcom.subparsers.note_structure import note_structure +from gedcom.subparsers.source_citation import source_citation +from gedcom.subparsers.multimedia_link import multimedia_link + +EVENT_TAGS = { + tags.GEDCOM_TAG_TYPE: 'type', + tags.GEDCOM_TAG_DATE: 'date', + tags.GEDCOM_TAG_AGENCY: 'responsible_agency', + tags.GEDCOM_TAG_RELIGION: 'religious_affiliation', + tags.GEDCOM_TAG_CAUSE: 'cause_of_event', + tags.GEDCOM_TAG_RESTRICTION: 'restriction' +} + + +def event_detail(element: Element) -> dict: + """Parses and extracts a `EVENT_DETAIL` structure. + + The `element` should be the parent that contains it. + """ + record = { + 'type': '', + 'date': '', + 'place': {}, + 'address': {}, + 'responsible_agency': '', + 'religious_affiliation': '', + 'cause_of_event': '', + 'restriction_notice': '', + 'notes': [], + 'citations': [], + 'media': [] + } + for child in element.get_child_elements(): + if child.get_tag() in EVENT_TAGS: + record[EVENT_TAGS[child.get_tag()]] = child.get_value() + continue + + if child.get_tag() == tags.GEDCOM_TAG_PLACE: + record['place'] = place_structure(child) + continue + + if child.get_tag() == tags.GEDCOM_TAG_ADDRESS: + record['address'] = address_structure(element) + continue + + if child.get_tag() == tags.GEDCOM_TAG_NOTE: + record['notes'].append(note_structure(child)) + continue + + if child.get_tag() == tags.GEDCOM_TAG_SOURCE: + record['citations'].append(source_citation(child)) + continue + + if child.get_tag() == tags.GEDCOM_TAG_OBJECT: + record['media'].append(multimedia_link(child)) + + return record diff --git a/gedcom/subparsers/family_event_detail.py b/gedcom/subparsers/family_event_detail.py new file mode 100644 index 0000000..4b1ba9b --- /dev/null +++ b/gedcom/subparsers/family_event_detail.py @@ -0,0 +1,54 @@ +# -*- coding: utf-8 -*- + +# Python GEDCOM Parser +# +# Copyright (C) 2020 Christopher Horn (cdhorn at embarqmail dot com) +# +# 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. +# +# Further information about the license: http://www.gnu.org/licenses/gpl-2.0.html + +""" +Substructure parser for a `FAMILY_EVENT_DETAIL` emdedded record. + +This is referenced as part of a larger structure so there is no anchor tag. +""" + +import gedcom.tags as tags +from gedcom.element.element import Element +from gedcom.subparsers.event_detail import event_detail + + +def family_event_detail(element: Element) -> dict: + """Parses and extracts a `FAMILY_EVENT_DETAIL` structure. + + The `element` shouldbe the parent that contains it. + """ + record = event_detail(element) + record['husband_age'] = '' + record['wife_age'] = '' + for child in element.get_child_elements(): + if child.get_tag() == tags.GEDCOM_TAG_HUSBAND: + for gchild in child.get_child_elements(): + if gchild.get_tag() == tags.GEDCOM_TAG_AGE: + record['husband_age'] = gchild.get_value() + continue + + if child.get_tag() == tags.GEDCOM_TAG_WIFE: + for gchild in child.get_child_elements(): + if gchild.get_tag() == tags.GEDCOM_TAG_AGE: + record['wife_age'] = gchild.get_value() + + return record diff --git a/gedcom/subparsers/family_event_structure.py b/gedcom/subparsers/family_event_structure.py new file mode 100644 index 0000000..1dac1af --- /dev/null +++ b/gedcom/subparsers/family_event_structure.py @@ -0,0 +1,65 @@ +# -*- coding: utf-8 -*- + +# Python GEDCOM Parser +# +# Copyright (C) 2020 Christopher Horn (cdhorn at embarqmail dot com) +# +# 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. +# +# Further information about the license: http://www.gnu.org/licenses/gpl-2.0.html + +""" +Substructure parser for a `FAMILY_EVENT_STRUCTURE` embedded record. + +This is referenced as part of a larger structure so there is no anchor tag. +""" + +from typing import List + +import gedcom.tags as tags +from gedcom.element.element import Element +from gedcom.subparsers.family_event_detail import family_event_detail + +EVENT_TAGS = { + tags.GEDCOM_TAG_ANNULMENT: 'annulment', + tags.GEDCOM_TAG_CENSUS: 'census', + tags.GEDCOM_TAG_DIVORCE: 'divorce', + tags.GEDCOM_TAG_DIVORCE_FILED: 'divorce_filed', + tags.GEDCOM_TAG_ENGAGEMENT: 'engagement', + tags.GEDCOM_TAG_MARRIAGE: 'marriage', + tags.GEDCOM_TAG_MARRIAGE_BANN: 'marriage_bann', + tags.GEDCOM_TAG_MARR_CONTRACT: 'marriage_contract', + tags.GEDCOM_TAG_MARR_LICENSE: 'marriage_license', + tags.GEDCOM_TAG_MARR_SETTLEMENT: 'marriage_settlement', + tags.GEDCOM_TAG_RESIDENCE: 'residence', + tags.GEDCOM_TAG_EVENT: 'event' +} + + +def family_event_structure(element: Element) -> List[dict]: + """Parses and extracts a `FAMILY_EVENT_STRUCTURE` structure. + + The `element` should be the parent that contains it. + """ + records = [] + for child in element.get_child_elements(): + if child.get_tag() in EVENT_TAGS: + record = family_event_detail(child) + record['description'] = child.get_multi_line_value() + record['tag'] = child.get_tag() + record['event'] = EVENT_TAGS[child.get_tag()] + records.append(record) + + return records diff --git a/gedcom/subparsers/individual_attribute_structure.py b/gedcom/subparsers/individual_attribute_structure.py new file mode 100644 index 0000000..43a2d0f --- /dev/null +++ b/gedcom/subparsers/individual_attribute_structure.py @@ -0,0 +1,69 @@ +# -*- coding: utf-8 -*- + +# Python GEDCOM Parser +# +# Copyright (C) 2020 Christopher Horn (cdhorn at embarqmail dot com) +# +# 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. +# +# Further information about the license: http://www.gnu.org/licenses/gpl-2.0.html + +""" +Substructure parser for the `INDIVIDUAL_ATTRIBUTE_STRUCTURE` embedded record. + +This is referenced as part of a larger structure so there is no anchor tag. +""" + +from typing import List + +import gedcom.tags as tags +from gedcom.element.element import Element +from gedcom.subparsers.individual_event_detail import individual_event_detail + +ATTRIBUTE_TAGS = { + tags.GEDCOM_TAG_CASTE: 'caste', + tags.GEDCOM_TAG_PHY_DESCRIPTION: 'physical_description', + tags.GEDCOM_TAG_EDUCATION: 'eduction', + tags.GEDCOM_TAG_IDENT_NUMBER: 'identity_number', + tags.GEDCOM_TAG_NATIONALITY: 'nationality', + tags.GEDCOM_TAG_CHILDREN_COUNT: 'number_of_children', + tags.GEDCOM_TAG_MARRIAGE_COUNT: 'number_of_marriages', + tags.GEDCOM_TAG_OCCUPATION: 'occupation', + tags.GEDCOM_TAG_PROPERTY: 'property', + tags.GEDCOM_TAG_RELIGION: 'religion', + tags.GEDCOM_TAG_RESIDENCE: 'residence', + tags.GEDCOM_TAG_SOC_SEC_NUMBER: 'social_security_number', + tags.GEDCOM_TAG_TITLE: 'title', + tags.GEDCOM_TAG_FACT: 'fact', + tags.GEDCOM_PROGRAM_DEFINED_TAG_DCAUSE: 'cause_of_death' +} + + +def individual_attribute_structure(element: Element) -> List[dict]: + """Parses and extracts the `INDIVIDUAL_ATTRIBUTE_STRUCTURE` structures. + + The `element` should be the parent that contains them. + """ + records = [] + for child in element.get_child_elements(): + if child.get_tag() in ATTRIBUTE_TAGS: + record = individual_event_detail(child) + record['description'] = child.get_multi_line_value() + record['tag'] = child.get_tag() + record['attribute'] = ATTRIBUTE_TAGS[child.get_tag()] + records.append(record) + continue + + return records diff --git a/gedcom/subparsers/individual_event_detail.py b/gedcom/subparsers/individual_event_detail.py new file mode 100644 index 0000000..58e55a3 --- /dev/null +++ b/gedcom/subparsers/individual_event_detail.py @@ -0,0 +1,45 @@ +# -*- coding: utf-8 -*- + +# Python GEDCOM Parser +# +# Copyright (C) 2020 Christopher Horn (cdhorn at embarqmail dot com) +# +# 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. +# +# Further information about the license: http://www.gnu.org/licenses/gpl-2.0.html + +""" +Substructure parser for a `INDIVIDUAL_EVENT_DETAIL` emdedded record. + +This is referenced as part of a larger structure so there is no anchor tag. +""" + +import gedcom.tags as tags +from gedcom.element.element import Element +from gedcom.subparsers.event_detail import event_detail + + +def individual_event_detail(element: Element) -> dict: + """Parses and extracts a `INDIVIDUAL_EVENT_DETAIL` structure. + + The `element` should be the parent that contains it. + """ + record = event_detail(element) + record['age'] = '' + for child in element.get_child_elements(): + if child.get_tag() == tags.GEDCOM_TAG_AGE: + record['age'] = child.get_value() + + return record diff --git a/gedcom/subparsers/individual_event_structure.py b/gedcom/subparsers/individual_event_structure.py new file mode 100644 index 0000000..5304a61 --- /dev/null +++ b/gedcom/subparsers/individual_event_structure.py @@ -0,0 +1,110 @@ +# -*- coding: utf-8 -*- + +# Python GEDCOM Parser +# +# Copyright (C) 2020 Christopher Horn (cdhorn at embarqmail dot com) +# +# 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. +# +# Further information about the license: http://www.gnu.org/licenses/gpl-2.0.html + +""" +Substructure parser for a `INDIVIDUAL_EVENT_STRUCTURE` embedded record. + +This is referenced as part of a larger structure so there is no anchor tag. +""" + +from typing import List + +import gedcom.tags as tags +from gedcom.element.element import Element +from gedcom.subparsers.individual_event_detail import individual_event_detail + +EVENT_TAGS = { + tags.GEDCOM_TAG_DEATH: 'death', + tags.GEDCOM_TAG_BURIAL: 'burial', + tags.GEDCOM_TAG_CREMATION: 'cremation', + tags.GEDCOM_TAG_BAPTISM: 'baptism', + tags.GEDCOM_TAG_BAR_MITZVAH: 'bar_mitzvah', + tags.GEDCOM_TAG_BAS_MITZVAH: 'bas_mitzvah', + tags.GEDCOM_TAG_BLESSING: 'blessing', + tags.GEDCOM_TAG_ADULT_CHRISTENING: 'adult_christening', + tags.GEDCOM_TAG_CONFIRMATION: 'confirmation', + tags.GEDCOM_TAG_FIRST_COMMUNION: 'first_communion', + tags.GEDCOM_TAG_ORDINATION: 'ordination', + tags.GEDCOM_TAG_NATURALIZATION: 'naturalization', + tags.GEDCOM_TAG_EMIGRATION: 'emmigration', + tags.GEDCOM_TAG_IMMIGRATION: 'immigration', + tags.GEDCOM_TAG_CENSUS: 'census', + tags.GEDCOM_TAG_PROBATE: 'probate', + tags.GEDCOM_TAG_WILL: 'will', + tags.GEDCOM_TAG_GRADUATION: 'graduation', + tags.GEDCOM_TAG_RETIREMENT: 'retirement', + tags.GEDCOM_TAG_EVENT: 'event', + tags.GEDCOM_PROGRAM_DEFINED_TAG_DEGREE: 'degree', + tags.GEDCOM_PROGRAM_DEFINED_TAG_FUNERAL: 'funeral', + tags.GEDCOM_PROGRAM_DEFINED_TAG_MEDICAL: 'medical', + tags.GEDCOM_PROGRAM_DEFINED_TAG_MILITARY: 'military' +} + +BIRTH_EVENT_TAGS = { + tags.GEDCOM_TAG_BIRTH: 'birth', + tags.GEDCOM_TAG_CHRISTENING: 'christening' +} + + +def individual_event_structure(element: Element) -> List[dict]: + """Parses and extracts a `INDIVIDUAL_EVENT_STRUCTURE` structure. + + The `element` should be the parent that contains it. + """ + records = [] + for child in element.get_child_elements(): + if child.get_tag() in BIRTH_EVENT_TAGS: + record = individual_event_detail(child) + record['tag'] = child.get_tag() + record['event'] = BIRTH_EVENT_TAGS[child.get_tag()] + record['description'] = child.get_multi_line_value() + record['family'] = '' + for gchild in child.get_child_elements(): + if gchild.get_tag() == tags.GEDCOM_TAG_FAMILY_CHILD: + record['family'] = gchild.get_value() + records.append(record) + continue + + if child.get_tag() in EVENT_TAGS: + record = individual_event_detail(child) + record['tag'] = child.get_tag() + record['event'] = EVENT_TAGS[child.get_tag()] + record['description'] = child.get_multi_line_value() + records.append(record) + continue + + if child.get_tag() == tags.GEDCOM_TAG_ADOPTION: + record = individual_event_detail(child) + record['tag'] = child.get_tag() + record['event'] = 'adoption' + record['description'] = child.get_multi_line_value() + record['family'] = '' + record['parent'] = '' + for gchild in child.get_child_elements(): + if gchild.get_tag() == tags.GEDCOM_TAG_FAMILY_CHILD: + record['family'] = gchild.get_value() + for ggchild in gchild.get_child_elements(): + if ggchild.get_tag() == tags.GEDCOM_TAG_ADOPTION: + record['parent'] = ggchild.get_value() + records.append(record) + + return records diff --git a/gedcom/subparsers/lds_individual_ordinance.py b/gedcom/subparsers/lds_individual_ordinance.py new file mode 100644 index 0000000..2588558 --- /dev/null +++ b/gedcom/subparsers/lds_individual_ordinance.py @@ -0,0 +1,95 @@ +# -*- coding: utf-8 -*- + +# Python GEDCOM Parser +# +# Copyright (C) 2020 Christopher Horn (cdhorn at embarqmail dot com) +# +# 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. +# +# Further information about the license: http://www.gnu.org/licenses/gpl-2.0.html + +""" +Substructure parser for a `LDS_INDIVIDUAL_ORDINANCE` embedded record. + +This is referenced as part of a larger structure so there is no anchor tag. +""" + +from typing import List + +import gedcom.tags as tags +from gedcom.element.element import Element +from gedcom.subparsers.note_structure import note_structure +from gedcom.subparsers.source_citation import source_citation + +ORDINANCE_TAGS = { + tags.GEDCOM_TAG_BAPTISM_LDS: 'lds_baptism', + tags.GEDCOM_TAG_CONFIRMATION_L: 'lds_confirmation', + tags.GEDCOM_TAG_ENDOWMENT: 'lds_endowment', + tags.GEDCOM_TAG_SEALING_CHILD: 'lds_sealing_child' +} + +ORDINANCE_ATTRIBUTE_TAGS = { + tags.GEDCOM_TAG_DATE: 'date', + tags.GEDCOM_TAG_TEMPLE: 'temple', + tags.GEDCOM_TAG_PLACE: 'place', + tags.GEDCOM_TAG_FAMILY_CHILD: 'key_to_family' +} + + +def lds_individual_ordinance(element: Element) -> List[dict]: + """Parses and extracts a `LDS_INDIVIDUAL_ORDINANCE` structure. + + The `element` should be the parent that contains it. + """ + records = [] + for child in element.get_child_elements(): + if child.get_tag() in ORDINANCE_TAGS: + record = { + 'date': '', + 'temple': '', + 'place': '', + 'status': '', + 'status_change': '', + 'notes': [], + 'citations': [], + 'tag': child.get_tag(), + 'event': ORDINANCE_TAGS[child.get_tag()] + } + if child.get_tag() == tags.GEDCOM_TAG_SEALING_CHILD: + record.update({'key_to_family': ''}) + for gchild in child.get_child_elements(): + if gchild.get_tag() in ORDINANCE_ATTRIBUTE_TAGS: + record[ORDINANCE_ATTRIBUTE_TAGS[gchild.get_tag()]] = gchild.get_value() + continue + + if gchild.get_tag() == tags.GEDCOM_TAG_STATUS: + record['status'] = gchild.get_value() + for ggchild in gchild.get_child_elements(): + if ggchild.get_tag() == tags.GEDCOM_TAG_DATE: + record['status_change'] = ggchild.get_value() + continue + + if gchild.get_tag() == tags.GEDCOM_TAG_NOTE: + record['notes'].append(note_structure(child)) + continue + + if gchild.get_tag() == tags.GEDCOM_TAG_SOURCE: + record['citations'].append(source_citation(child)) + continue + + records.append(record) + continue + + return records diff --git a/gedcom/subparsers/lds_spouse_sealing.py b/gedcom/subparsers/lds_spouse_sealing.py new file mode 100644 index 0000000..cdc4545 --- /dev/null +++ b/gedcom/subparsers/lds_spouse_sealing.py @@ -0,0 +1,86 @@ +# -*- coding: utf-8 -*- + +# Python GEDCOM Parser +# +# Copyright (C) 2020 Christopher Horn (cdhorn at embarqmail dot com) +# +# 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. +# +# Further information about the license: http://www.gnu.org/licenses/gpl-2.0.html + +""" +Substructure parser for a `LDS_SPOUSE_SEALING` embedded record. + +This is referenced as part of a larger structure so there is no anchor tag. +""" + +from typing import List + +import gedcom.tags as tags +from gedcom.element.element import Element +from gedcom.subparsers.note_structure import note_structure +from gedcom.subparsers.source_citation import source_citation + +SEALING_TAGS = { + tags.GEDCOM_TAG_DATE: 'date', + tags.GEDCOM_TAG_TEMPLE: 'temple', + tags.GEDCOM_TAG_PLACE: 'place', + tags.GEDCOM_TAG_FAMILY_CHILD: 'key_to_family' +} + + +def lds_spouse_sealing(element: Element) -> List[dict]: + """Parses and extracts a `LDS_SPOUSE_SEALING` structure. + + The `element` should be the parent that contains it. + """ + records = [] + for child in element.get_child_elements(): + if child.get_tag() == tags.GEDCOM_TAG_SEALING_SPOUSE: + record = { + 'date': '', + 'temple': '', + 'place': '', + 'status': '', + 'status_change': '', + 'notes': [], + 'citations': [], + 'tag': tags.GEDCOM_TAG_SEALING_SPOUSE, + 'event': 'lds_spouse_sealing' + } + for gchild in child.get_child_elements(): + if gchild.get_tag() in SEALING_TAGS: + record[SEALING_TAGS[gchild.get_tag()]] = gchild.get_value() + continue + + if gchild.get_tag() == tags.GEDCOM_TAG_STATUS: + record['status'] = gchild.get_value() + for ggchild in gchild.get_child_elements(): + if ggchild.get_tag() == tags.GEDCOM_TAG_DATE: + record['status_change'] = ggchild.get_value() + continue + + if gchild.get_tag() == tags.GEDCOM_TAG_NOTE: + record['notes'].append(note_structure(child)) + continue + + if gchild.get_tag() == tags.GEDCOM_TAG_SOURCE: + record['citations'].append(source_citation(child)) + continue + + records.append(record) + continue + + return records diff --git a/gedcom/subparsers/multimedia_link.py b/gedcom/subparsers/multimedia_link.py new file mode 100644 index 0000000..3e0bc3f --- /dev/null +++ b/gedcom/subparsers/multimedia_link.py @@ -0,0 +1,75 @@ +# -*- coding: utf-8 -*- + +# Python GEDCOM Parser +# +# Copyright (C) 2020 Christopher Horn (cdhorn at embarqmail dot com) +# +# 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. +# +# Further information about the license: http://www.gnu.org/licenses/gpl-2.0.html + +""" +Substructure parser for a `MULTIMEDIA_LINK` record. + +This is anchored by the `gedcom.tags.GEDCOM_TAG_OBJECT` tag. +""" + +import gedcom.tags as tags +from gedcom.element.element import Element + +MEDIA_TAGS = { + tags.GEDCOM_TAG_FILE: 'file', + tags.GEDCOM_TAG_FORMAT: 'format', + tags.GEDCOM_TAG_MEDIA: 'type', + tags.GEDCOM_TAG_TITLE: 'title', + tags.GEDCOM_PROGRAM_DEFINED_TAG_PHOTO: 'preferred', + tags.GEDCOM_PROGRAM_DEFINED_TAG_PRIMARY: 'preferred' +} + + +def multimedia_link(element: Element) -> dict: + """Parse and extract a `MULTIMEDIA_LINK` structure. + + The `element` should contain the `gedcom.tags.GEDCOM_TAG_OBJECT` tag. + """ + record = { + 'key_to_object': element.get_value(), + 'file': '', + 'format': '', + 'type': '', + 'title': '', + 'preferred': '' + } + if record['key_to_object'] not in [None, '']: + if '@' in record['key_to_object']: + return record + + record['key_to_object'] = '' + for child in element.get_child_elements(): + if child.get_tag() == tags.GEDCOM_TAG_FILE: + record['file'] = child.get_value() + for gchild in child.get_child_elements(): + if gchild.get_tag() == tags.GEDCOM_TAG_FORMAT: + record['format'] = gchild.get_value() + for ggchild in gchild.get_child_elements(): + if ggchild.get_tag() == tags.GEDCOM_TAG_MEDIA: + record['type'] = ggchild.get_value() + continue + continue + + if child.get_tag() in MEDIA_TAGS: + record[MEDIA_TAGS[child.get_tag()]] = child.get_value() + + return record diff --git a/gedcom/subparsers/note_structure.py b/gedcom/subparsers/note_structure.py new file mode 100644 index 0000000..45f1c52 --- /dev/null +++ b/gedcom/subparsers/note_structure.py @@ -0,0 +1,47 @@ +# -*- coding: utf-8 -*- + +# Python GEDCOM Parser +# +# Copyright (C) 2020 Christopher Horn (cdhorn at embarqmail dot com) +# +# 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. +# +# Further information about the license: http://www.gnu.org/licenses/gpl-2.0.html + +""" +Substructure parser for a `NOTE_STRUCTURE` record. + +This is anchored by the `gedcom.tags.GEDCOM_TAG_NOTE` tag. +""" + +from gedcom.element.element import Element + + +def note_structure(element: Element) -> dict: + """Parse and extract a `NOTE_STRUCTURE` structure. + + The `element` should contain the `gedcom.tags.GEDCOM_TAG_NOTE` tag. + """ + record = { + 'key_to_note': element.get_value(), + 'note': '' + } + if record['key_to_note'] not in [None, '']: + if '@' in record['key_to_note']: + return record + record['key_to_note'] = '' + record['note'] = element.get_multi_line_value() + + return record diff --git a/gedcom/subparsers/personal_name_pieces.py b/gedcom/subparsers/personal_name_pieces.py new file mode 100644 index 0000000..d7c78e6 --- /dev/null +++ b/gedcom/subparsers/personal_name_pieces.py @@ -0,0 +1,74 @@ +# -*- coding: utf-8 -*- + +# Python GEDCOM Parser +# +# Copyright (C) 2020 Christopher Horn (cdhorn at embarqmail dot com) +# +# 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. +# +# Further information about the license: http://www.gnu.org/licenses/gpl-2.0.html + +""" +Substructure parser for a `PERSONAL_NAME_PIECES` embedded record. + +This is referenced as part of a larger structure so there is no anchor tag. +""" + +import gedcom.tags as tags +from gedcom.element.element import Element +from gedcom.subparsers.note_structure import note_structure +from gedcom.subparsers.source_citation import source_citation + +NAME_TAGS = { + tags.GEDCOM_TAG_NAME_PREFIX: 'prefix', + tags.GEDCOM_TAG_GIVEN_NAME: 'given', + tags.GEDCOM_TAG_NICKNAME: 'nick', + tags.GEDCOM_TAG_SURN_PREFIX: 'surname_prefix', + tags.GEDCOM_TAG_SURNAME: 'surname', + tags.GEDCOM_TAG_NAME_SUFFIX: 'suffix', + tags.GEDCOM_PROGRAM_DEFINED_TAG_RUFNAME: 'rufname' +} + + +def personal_name_pieces(element: Element) -> dict: + """Parse and extract a `PERSONAL_NAME_PIECES` structure. + + The `element` should be the parent that contains it. + """ + record = { + 'prefix': '', + 'given': '', + 'nick': '', + 'surname_prefix': '', + 'surname': '', + 'suffix': '', + 'rufname': '', + 'notes': [], + 'citations': [] + } + for child in element.get_child_elements(): + if child.get_tag() in NAME_TAGS: + record[NAME_TAGS[child.get_tag()]] = child.get_value() + continue + + if child.get_tag() == tags.GEDCOM_TAG_NOTE: + record['notes'].append(note_structure(child)) + continue + + if child.get_tag() == tags.GEDCOM_TAG_SOURCE: + record['citations'].append(source_citation(child)) + continue + + return record diff --git a/gedcom/subparsers/personal_name_structure.py b/gedcom/subparsers/personal_name_structure.py new file mode 100644 index 0000000..c20fd5b --- /dev/null +++ b/gedcom/subparsers/personal_name_structure.py @@ -0,0 +1,75 @@ +# -*- coding: utf-8 -*- + +# Python GEDCOM Parser +# +# Copyright (C) 2020 Christopher Horn (cdhorn at embarqmail dot com) +# +# 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. +# +# Further information about the license: http://www.gnu.org/licenses/gpl-2.0.html + +""" +Substructure parser for a `PERSONAL_NAME_STRUCTURE` record. + +This is anchored by the `gedcom.tags.GEDCOM_TAG_NAME` tag. +""" + +import gedcom.tags as tags +from gedcom.element.element import Element +from gedcom.subparsers.personal_name_pieces import personal_name_pieces + + +def extract_name(element: Element) -> dict: + """Parse and extract a `NAME` for a `PERSONAL_NAME_STRUCTURE` structure. + + The `element` should contain one of the name tags: + + `gedcom.tags.GEDCOM_TAG_NAME` + + `gedcom.tags.GEDCOM_TAG_PHONETIC` + + `gedcom.tags.GEDCOM_TAG_ROMANIZED` + """ + record = { + 'name': '', + 'type': '', + 'pieces': {} + } + record['name'] = element.get_value() + record['pieces'] = personal_name_pieces(element) + for child in element.get_child_elements(): + if child.get_tag() == tags.GEDCOM_TAG_TYPE: + record['type'] = child.get_value() + return record + + +def personal_name_structure(element: Element) -> dict: + """Parse and extract a `PERSONAL_NAME_STRUCTURE` structure. + + The `element` should contain the `gedcom.tags.GEDCOM_TAG_NAME` tag. + """ + record = extract_name(element) + record['phonetic'] = [] + record['romanized'] = [] + for child in element.get_child_elements(): + if child.get_tag() == tags.GEDCOM_TAG_PHONETIC: + record['phonetic'].append(extract_name(child)) + continue + + if child.get_tag() == tags.GEDCOM_TAG_ROMANIZED: + record['romanized'].append(extract_name(child)) + continue + + return record diff --git a/gedcom/subparsers/place_structure.py b/gedcom/subparsers/place_structure.py new file mode 100644 index 0000000..13ac917 --- /dev/null +++ b/gedcom/subparsers/place_structure.py @@ -0,0 +1,88 @@ +# -*- coding: utf-8 -*- + +# Python GEDCOM Parser +# +# Copyright (C) 2020 Christopher Horn (cdhorn at embarqmail dot com) +# +# 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. +# +# Further information about the license: http://www.gnu.org/licenses/gpl-2.0.html + +""" +Substructure parser for a `PLACE_STRUCTURE` record. + +This is anchored by the `gedcom.tags.GEDCOM_TAG_PLACE` tag. +""" + +import gedcom.tags as tags +from gedcom.element.element import Element +from gedcom.subparsers.note_structure import note_structure + + +def place_structure(element: Element) -> dict: + """Parse and extract a `PLACE_STRUCTURE` structure. + + The `element` should contain the `gedcom.tags.GEDCOM_TAG_PLACE` tag. + """ + record = { + 'name': element.get_value(), + 'hierarchy': '', + 'phonetic': [], + 'romanized': [], + 'latitude': '', + 'longitude': '', + 'notes': [] + } + for child in element.get_child_elements(): + if child.get_tag() == tags.GEDCOM_TAG_FORMAT: + record['hierarchy'] = child.get_value() + continue + + if child.get_tag() == tags.GEDCOM_TAG_NOTE: + record['notes'].append(note_structure(child)) + continue + + if child.get_tag() == tags.GEDCOM_TAG_PHONETIC: + subrecord = { + 'name': child.get_value(), + 'type': '' + } + for gchild in child.get_child_elements(): + if gchild.get_tag() == tags.GEDCOM_TAG_TYPE: + subrecord['type'] = gchild.get_value() + record['phonetic'].append(subrecord) + continue + + if child.get_tag() == tags.GEDCOM_TAG_ROMANIZED: + subrecord = { + 'name': child.get_value(), + 'type': '' + } + for gchild in child.get_child_elements(): + if gchild.get_tag() == tags.GEDCOM_TAG_TYPE: + subrecord['type'] = gchild.get_value() + record['romanized'].append(subrecord) + continue + + if child.get_tag() == tags.GEDCOM_TAG_MAP: + for gchild in child.get_child_elements(): + if gchild.get_tag() == tags.GEDCOM_TAG_LATITUDE: + record['latitude'] = gchild.get_value() + continue + + if gchild.get_tag() == tags.GEDCOM_TAG_LONGITUDE: + record['longitude'] = gchild.get_value() + + return record diff --git a/gedcom/subparsers/source_citation.py b/gedcom/subparsers/source_citation.py new file mode 100644 index 0000000..ef61f03 --- /dev/null +++ b/gedcom/subparsers/source_citation.py @@ -0,0 +1,97 @@ +# -*- coding: utf-8 -*- + +# Python GEDCOM Parser +# +# Copyright (C) 2020 Christopher Horn (cdhorn at embarqmail dot com) +# +# 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. +# +# Further information about the license: http://www.gnu.org/licenses/gpl-2.0.html + +""" +Substructure parser for a `SOURCE_CITATION` record. + +This is anchored by the `gedcom.tags.GEDCOM_TAG_SOURCE` tag. +""" + +import gedcom.tags as tags +from gedcom.element.element import Element +from gedcom.subparsers.multimedia_link import multimedia_link +from gedcom.subparsers.note_structure import note_structure + +CITATION_TAGS = { + tags.GEDCOM_TAG_PAGE: 'page', + tags.GEDCOM_TAG_DATE: 'date', + tags.GEDCOM_TAG_QUALITY_OF_DATA: 'quality', + tags.GEDCOM_PROGRAM_DEFINED_TAG_APID: 'apid' +} + + +def source_citation(element: Element) -> dict: + """Parse and extract a `SOURCE_CITATION` structure. + + The `element` should contain the `gedcom.tags.GEDCOM_TAG_SOURCE` tag. + """ + record = { + 'key_to_source': element.get_value(), + 'source': '', + 'page': '', + 'event': '', + 'role': '', + 'date': '', + 'text': '', + 'media': [], + 'notes': [], + 'quality': '', + 'apid': '' + } + if record['key_to_source'] not in [None, '']: + if '@' not in record['key_to_source']: + record['key_to_source'] = '' + record['source'] = element.get_multi_line_value() + + for child in element.get_child_elements(): + if child.get_tag() in CITATION_TAGS: + record[CITATION_TAGS[child.get_tag()]] = child.get_value() + continue + + if child.get_tag() == tags.GEDCOM_TAG_EVENT: + record['event'] = child.get_value() + for gchild in child.get_child_elements(): + if gchild.get_tag() == tags.GEDCOM_TAG_ROLE: + record['role'] = gchild.get_value() + continue + + if child.get_tag() == tags.GEDCOM_TAG_DATA: + for gchild in child.get_child_elements(): + if gchild.get_tag() == tags.GEDCOM_TAG_DATE: + record['date'] = gchild.get_value() + continue + if gchild.get_tag() == tags.GEDCOM_TAG_TEXT: + record['text'] = gchild.get_multi_line_value() + continue + + if child.get_tag() == tags.GEDCOM_TAG_OBJECT: + record['media'].append(multimedia_link(child)) + continue + + if child.get_tag() == tags.GEDCOM_TAG_NOTE: + record['notes'].append(note_structure(child)) + continue + + if child.get_tag() == tags.GEDCOM_TAG_TEXT: + record['text'] = child.get_multi_line_value() + + return record diff --git a/gedcom/subparsers/source_repository_citation.py b/gedcom/subparsers/source_repository_citation.py new file mode 100644 index 0000000..dc67f40 --- /dev/null +++ b/gedcom/subparsers/source_repository_citation.py @@ -0,0 +1,60 @@ +# -*- coding: utf-8 -*- + +# Python GEDCOM Parser +# +# Copyright (C) 2020 Christopher Horn (cdhorn at embarqmail dot com) +# +# 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. +# +# Further information about the license: http://www.gnu.org/licenses/gpl-2.0.html + +""" +Substructure parser for a `SOURCE_REPOSITORY_CITATION` record. + +This is anchored by the `gedcom.tags.GEDCOM_TAG_REPOSITORY` tag. +""" + +import gedcom.tags as tags +from gedcom.element.element import Element +from gedcom.subparsers.note_structure import note_structure + + +def source_repository_citation(element: Element) -> dict: + """Parse and extract a `SOURCE_REPOSITORY_CITATION` structure. + + The `element` should contain the `gedcom.tags.GEDCOM_TAG_REPOSITORY` tag. + """ + record = { + 'key_to_repository': element.get_value(), + 'call_number': '', + 'media_type': '', + 'notes': [] + } + if record['key_to_repository'] not in [None, '']: + if '@' not in record['key_to_repository']: + record['key_to_repository'] = '' + + for child in element.get_child_elements(): + if child.get_tag() == tags.GEDCOM_TAG_NOTE: + record['notes'].append(note_structure(child)) + continue + + if child.get_tag() == tags.GEDCOM_TAG_CALL_NUMBER: + record['call_number'] = child.get_value() + for gchild in child.get_child_elements(): + if gchild.get_tag() == tags.GEDCOM_TAG_MEDIA: + record['media_type'] = gchild.get_value() + + return record diff --git a/gedcom/subparsers/spouse_to_family_link.py b/gedcom/subparsers/spouse_to_family_link.py new file mode 100644 index 0000000..3d2895e --- /dev/null +++ b/gedcom/subparsers/spouse_to_family_link.py @@ -0,0 +1,47 @@ +# -*- coding: utf-8 -*- + +# Python GEDCOM Parser +# +# Copyright (C) 2020 Christopher Horn (cdhorn at embarqmail dot com) +# +# 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. +# +# Further information about the license: http://www.gnu.org/licenses/gpl-2.0.html + +""" +Substructure parser for a `SPOUSE_TO_FAMILY_LINK` record. + +This is anchored by the `gedcom.tags.GEDCOM_TAG_FAMILY_SPOUSE` tag. +""" + +import gedcom.tags as tags +from gedcom.element.element import Element +from gedcom.subparsers.note_structure import note_structure + + +def spouse_to_family_link(element: Element) -> dict: + """Parse and extract a `SPOUSE_TO_FAMILY_LINK` structure. + + The `element` should contain the `gedcom.tags.GEDCOM_TAG_FAMILY_SPOUSE` tag. + """ + record = { + 'key_to_family': element.get_value(), + 'notes': [] + } + for child in element.get_child_elements(): + if child.get_tag() == tags.GEDCOM_TAG_NOTE: + record['notes'].append(note_structure(child)) + + return record diff --git a/gedcom/subparsers/user_reference_number.py b/gedcom/subparsers/user_reference_number.py new file mode 100644 index 0000000..a1e4d7c --- /dev/null +++ b/gedcom/subparsers/user_reference_number.py @@ -0,0 +1,49 @@ +# -*- coding: utf-8 -*- + +# Python GEDCOM Parser +# +# Copyright (C) 2020 Christopher Horn (cdhorn at embarqmail dot com) +# +# 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. +# +# Further information about the license: http://www.gnu.org/licenses/gpl-2.0.html + +""" +Parser for a `USER_REFERENCE_NUMBER` structure. + +This is anchored by the `gedcom.tags.GEDCOM_TAG_REFERENCE` tag. + +This is not a formally documented structure in the standard but it is +a substructure that repeats itself in a number of record types. +""" + +import gedcom.tags as tags +from gedcom.element.element import Element + + +def user_reference_number(element: Element) -> dict: + """Parse and extract a `USER_REFERENCE_NUMBER` structure. + + The `element` should contain the `gedcom.tags.GEDCOM_TAG_REFERENCE` tag. + """ + record = { + 'reference': element.get_value(), + 'type': '' + } + for child in element.get_child_elements(): + if child.get_tag() == tags.GEDCOM_TAG_TYPE: + record['type'] = child.get_value() + + return record diff --git a/gedcom/tags.py b/gedcom/tags.py index 9efa002..63c6e95 100644 --- a/gedcom/tags.py +++ b/gedcom/tags.py @@ -2,6 +2,7 @@ # Python GEDCOM Parser # +# Copyright (C) 2020 Christopher Horn (cdhorn at embarqmail dot com) # Copyright (C) 2018 Damon Brodie (damon.brodie at gmail.com) # Copyright (C) 2018-2019 Nicklas Reincke (contact at reynke.com) # Copyright (C) 2016 Andreas Oberritter @@ -26,63 +27,392 @@ # Further information about the license: http://www.gnu.org/licenses/gpl-2.0.html """ -GEDCOM tags. +Module containing the standard GEDCOM tags and some of the most common program defined extensions. """ -GEDCOM_PROGRAM_DEFINED_TAG_MREL = "_MREL" -"""Value: `_MREL` +GEDCOM_PROGRAM_DEFINED_TAG_ADDRESSE = "_NAME" +"""Value: `_NAME` + +Name of addresse in a `gedcom.tags.GEDCOM_TAG_ADDRESS` structure. + +5.5.1 GEDCOM-L Addendum.""" + +GEDCOM_PROGRAM_DEFINED_TAG_ADMINISTRATIVE_ID = "_AIDN" +"""Value: `_AIDN` + +Identifier for a location with the intention of an administrative authority, +e.g. community identifier. + +5.5.1 GEDCOM-L Addendum.""" + +GEDCOM_PROGRAM_DEFINED_TAG_APID = "_APID" +"""Value: `_APID` + +Ancestry page identifier. For a citation, points to the page in a Ancestry +database for the record supporting the citation. For a source record it +points to the database as a whole. -Relationship to a mother.""" +Ancestry.com Extension.""" + +GEDCOM_PROGRAM_DEFINED_TAG_DCAUSE = "_DCAUSE" +"""Value: `_DCAUSE` + +Cause of death.""" + +GEDCOM_PROGRAM_DEFINED_TAG_DEGREE = "_DEG" +"""Value: `_DEG` + +Degree or recognition of accomplishment received by an individual.""" + +GEDCOM_PROGRAM_DEFINED_TAG_DEMOGRAPHIC_DATA = "_DMGD" +"""Value: `_DMGD` + +A number of ojects, during an ascertainment, e.g. the count of households. + +5.5.1 GEDCOM-L Addendum.""" GEDCOM_PROGRAM_DEFINED_TAG_FREL = "_FREL" """Value: `_FREL` -Relationship to a father.""" +Type of relationship between child and the father in a family.""" + +GEDCOM_PROGRAM_DEFINED_TAG_FUNERAL = "_FUN" +"""Value: `_FUN` + +Funeral for an individual.""" + +GEDCOM_PROGRAM_DEFINED_TAG_GOVERNMENT = "_GOV" +"""Value: `_GOV` + +The official government id of the object in the Historical Place Register / +Historic Gazeteer. + +5.5.1 GEDCOM-L Addendum.""" + +GEDCOM_PROGRAM_DEFINED_TAG_GOVERNMENT_TYPE = "_GOVTYPE" +"""Value: `_GOVTYPE` + +An integer positive number as defined in the GOV system. +See http://gov.genealogy.net.net/type/list. + +5.5.1 GEDCOM-L Addendum.""" + +GEDCOM_PROGRAM_DEFINED_TAG_HOME_PERSON = "_HME" +"""Value: `_HME` + +Home person in the tree.""" + +GEDCOM_PROGRAM_DEFINED_TAG_LOCATION = "_LOC" +"""Value: `_LOC` + +Location data record. + +5.5.1 GEDCOM-L Addendum.""" + +GEDCOM_PROGRAM_DEFINED_TAG_MAIDENHEAD = "_MAIDENHEAD" +"""Value: `_MAIDENHEAD` + +The maidenhead code. + +5.5.1 GEDCOM-L Addendum.""" + +GEDCOM_PROGRAM_DEFINED_TAG_MEDICAL = "_MDCL" +"""Value: `_MDCL` + +Medical information about an individual.""" + +GEDCOM_PROGRAM_DEFINED_TAG_MILITARY = "_MILT" +"""Value: `_MILT` + +A military related event in the individuals life.""" + +GEDCOM_PROGRAM_DEFINED_TAG_MREL = "_MREL" +"""Value: `_MREL` + +Type of relationship between child and the mother in a family.""" + +GEDCOM_PROGRAM_DEFINED_TAG_PHOTO = "_PHOTO" +"""Value: `_PHOTO` + +Used by some programs to identify the primary multimedia object for an +individual, the same as `gedcom.tags.GEDCOM_PROGRAM_DEFINED_TAG_PRIMARY`.""" + +GEDCOM_PROGRAM_DEFINED_TAG_POSTAL_CODE = "_POST" +"""Value: `_POST` + +The official zip code, called ADDRESS_POSTAL_CODE in the standard. + +5.5.1 GEDCOM-L Addendum.""" + +GEDCOM_PROGRAM_DEFINED_TAG_PREFERRED = "_PREF" +"""Value: `_PREF` + +Indicates a preferred spouse, child or parents.""" + +GEDCOM_PROGRAM_DEFINED_TAG_PRIMARY = "_PRIM" +"""Value: `_PRIM` + +Primary multimedia object for an individual.""" + +GEDCOM_PROGRAM_DEFINED_TAG_SCHEMA = "_SCHEMA" +"""Value: `_SCHEMA` + +Schema substructure extension to describe user defined tags. + +5.5.1 GEDCOM-L Addendum.""" + +GEDCOM_PROGRAM_DEFINED_TAG_RUFNAME = "_RUFNAME" +"""Value: `_RUFNAME` + +An official given name of a German individual used in legal documents. + +5.5.1 GEDCOM-L Addendum.""" + +GEDCOM_PROGRAM_DEFINED_TAG_UUID = "_UID" +"""Value: `_UID` + +Universal identification number. + +5.5.1 GEDCOM-L Addendum.""" + +GEDCOM_TAG_ABBREVIATION = "ABBR" +"""Value: `ABBR` + +A short name of a title, description, or name.""" + +GEDCOM_TAG_ADDRESS = "ADDR" +"""Value: `ADDR` + +The contemporary place, usually required for postal purposes, of an individual, +a submitter of information, a repository, a business, a school, or a company.""" + +GEDCOM_TAG_ADDRESS1 = "ADR1" +"""Value: `ADR1` + +The first line of an address.""" + +GEDCOM_TAG_ADDRESS2 = "ADR2" +"""Value: `ADR2` + +The second line of an address.""" + +GEDCOM_TAG_ADDRESS3 = "ADR3" +"""Value: `ADR3` + +The third line of an address.""" + +GEDCOM_TAG_ADOPTION = "ADOP" +"""Value: `ADOP` + +Pertaining to creation of a child-parent relationship that does not exist +biologically.""" + +GEDCOM_TAG_AFN = "AFN" +"""Value: `AFN` + +Ancestral File Number, a unique permanent record file number of an individual +record stored in Ancestral File.""" + +GEDCOM_TAG_AGE = "AGE" +"""Value: `AGE` + +The age of the individual at the time an event occurred, or the age listed in +the document.""" + +GEDCOM_TAG_AGENCY = "AGNC" +"""Value: `AGNC` + +The institution or individual having authority and/or responsibility to manage +or govern.""" + +GEDCOM_TAG_ALIAS = "ALIA" +"""Value: `ALIA` + +An indicator to link different record descriptions of a person who may be the +same person.""" + +GEDCOM_TAG_ANCESTORS = "ANCE" +"""Value: `ANCE` + +Pertaining to forbearers of an individual.""" + +GEDCOM_TAG_ANCES_INTEREST = "ANCI" +"""Value: `ANCI` + +Indicates an interest in additional research for ancestors of this individual. +(See also `gedcom.tags.GEDCOM_TAG_DESCENDANTS_INT`)""" + +GEDCOM_TAG_ANNULMENT = "ANUL" +"""Value: `ANUL` + +Declaring a marriage void from the beginning (never existed).""" + +GEDCOM_TAG_ASSOCIATES = "ASSO" +"""Value: `ASSO` + +An indicator to link friends, neighbors, relatives, or associates of an +individual.""" + +GEDCOM_TAG_AUTHOR = "AUTH" +"""Value: `AUTH` + +The name of the individual who created or compiled information.""" + +GEDCOM_TAG_BAPTISM_LDS = "BAPL" +"""Value: `BAPL` + +The event of baptism performed at age eight or later by priesthood authority +of the LDS Church. (See also `gedcom.tags.GEDCOM_TAG_BAPTISM`)""" + +GEDCOM_TAG_BAPTISM = "BAPM" +"""Value: `BAPM` + +The event of baptism (not LDS), performed in infancy or later.""" + +GEDCOM_TAG_BAR_MITZVAH = "BARM" +"""Value: `BARM` + +The ceremonial event held when a Jewish boy reaches age 13.""" + +GEDCOM_TAG_BAS_MITZVAH = "BASM" +"""Value: `BASM` + +The ceremonial event held when a Jewish girl reaches age 13, also known as +Bat Mitzvah.""" GEDCOM_TAG_BIRTH = "BIRT" """Value: `BIRT` The event of entering into life.""" +GEDCOM_TAG_BLESSING = "BLES" +"""Value: `BLES` + +A religious event of bestowing divine care or intercession. Sometimes given +in connection with a naming ceremony.""" + GEDCOM_TAG_BURIAL = "BURI" """Value: `BURI` The event of the proper disposing of the mortal remains of a deceased person.""" +GEDCOM_TAG_CALL_NUMBER = "CALN" +"""Value: `CALN` + +The number used by a repository to identify the specific items in its +collections.""" + +GEDCOM_TAG_CASTE = "CAST" +"""Value: `CAST` + +The name of an individual's rank or status in society, based on racial or +religious differences, or differences in wealth, inherited rank, profession, +occupation, etc.""" + +GEDCOM_TAG_CAUSE = "CAUSE" +"""Value: `CAUS` + +A description of the cause of the associated event or fact, such as the cause +of death.""" + GEDCOM_TAG_CENSUS = "CENS" """Value: `CENS`. -The event of the periodic count of the population for a designated locality, such as a national or state Census.""" +The event of the periodic count of the population for a designated locality, +such as a national or state Census.""" GEDCOM_TAG_CHANGE = "CHAN" """Value: `CHAN` Indicates a change, correction, or modification. Typically used in connection -with a `gedcom.tags.GEDCOM_TAG_DATE` to specify when a change in information occurred.""" +with a `gedcom.tags.GEDCOM_TAG_DATE` to specify when a change in information +occurred.""" + +GEDCOM_TAG_CHARACTER = "CHAR" +"""Value: `CHAR` + +An indicator of the character set used in writing this automated information.""" GEDCOM_TAG_CHILD = "CHIL" """Value: `CHIL` The natural, adopted, or sealed (LDS) child of a father and a mother.""" +GEDCOM_TAG_CHRISTENING = "CHR" +"""Value: `CHR` + +The religious event (not LDS) of baptizing and/or naming a child.""" + +GEDCOM_TAG_ADULT_CHRISTENING = "CHRA" +"""Value: `CHRA` + +The religious event (not LDS) of baptizing and/or naming an adult person.""" + +GEDCOM_TAG_CITY = "CITY" +"""Value: `CITY` + +A lower level jurisdictional unit. Normally an incorporated municipal unit.""" + GEDCOM_TAG_CONCATENATION = "CONC" """Value: `CONC` -An indicator that additional data belongs to the superior value. The information from the `CONC` value is to -be connected to the value of the superior preceding line without a space and without a carriage return and/or -new line character. Values that are split for a `CONC` tag must always be split at a non-space. If the value is -split on a space the space will be lost when concatenation takes place. This is because of the treatment that -spaces get as a GEDCOM delimiter, many GEDCOM values are trimmed of trailing spaces and some systems look for -the first non-space starting after the tag to determine the beginning of the value.""" +An indicator that additional data belongs to the superior value. The information +from the `CONC` value is to be connected to the value of the superior preceding +line without a space and without a carriage return and/or new line character. +Values that are split for a `CONC` tag must always be split at a non-space. If +the value is split on a space the space will be lost when concatenation takes +place. This is because of the treatment that spaces get as a GEDCOM delimiter, +many GEDCOM values are trimmed of trailing spaces and some systems look for +the first non-space starting after the tag to determine the beginning of the +value.""" + +GEDCOM_TAG_CONFIRMATION = "CONF" +"""Value: `CONF` + +The religious event (not LDS) of conferring the gift of the Holy Ghost and, +among protestants, full church membership.""" + +GEDCOM_TAG_CONFIRMATION_L = "CONL" +"""Value: `CONL` + +The religious event by which a person receives membership in the LDS Church.""" GEDCOM_TAG_CONTINUED = "CONT" """Value: `CONT` -An indicator that additional data belongs to the superior value. The information from the `CONT` value is to be -connected to the value of the superior preceding line with a carriage return and/or new line character. -Leading spaces could be important to the formatting of the resultant text. When importing values from `CONT` lines -the reader should assume only one delimiter character following the `CONT` tag. Assume that the rest of the leading -spaces are to be a part of the value.""" +An indicator that additional data belongs to the superior value. The information +from the `CONT` value is to be connected to the value of the superior preceding +line with a carriage return and/or new line character. Leading spaces could be +important to the formatting of the resultant text. When importing values from +`CONT` lines the reader should assume only one delimiter character following +the `CONT` tag. Assume that the rest of the leading spaces are to be a part +of the value.""" + +GEDCOM_TAG_COPYRIGHT = "COPR" +"""Value: `COPR` + +A statement that accompanies data to protect it from unlawful duplication +and distribution.""" + +GEDCOM_TAG_CORPORATE = "CORP" +"""Value: `CORP` + +A name of an institution, agency, corporation, or company.""" + +GEDCOM_TAG_CREMATION = "CREM" +"""Value: `CREM` + +Disposal of the remains of a person's body by fire.""" + +GEDCOM_TAG_COUNTRY = "CTRY" +"""Value: `CTRY` + +The name or code of a country.""" + +GEDCOM_TAG_DATA = "DATA" +"""Value: `DATA` + +Pertaining to stored automation information.""" GEDCOM_TAG_DATE = "DATE" """Value: `DATE` @@ -94,90 +424,539 @@ The event when mortal life terminates.""" +GEDCOM_TAG_DESCENDANTS = "DESC" +"""Value: `DESC` + +Pertaining to offspring of an individual.""" + +GEDCOM_TAG_DESCENDANTS_INT = "DESI" +"""Value: `DESI` + +Indicates an interest in research to identify additional descendants of this +individual. (See also `gedcom.tags.GEDCOM_TAG_ANCES_INTEREST`)""" + +GEDCOM_TAG_DESTINATION = "DEST" +"""Value: `DEST` + +A system receiving data.""" + +GEDCOM_TAG_DIVORCE = "DIV" +"""Value: `DIV` + +The event of disolving a marriage through civil action.""" + +GEDCOM_TAG_DIVORCE_FILED = "DIVF" +"""Value: `DIVF` + +An event of filing for a divorce by a spouse.""" + +GEDCOM_TAG_PHY_DESCRIPTION = "DSCR" +"""Value: `DSCR` + +The physical characteristics of a person, place, or thing.""" + +GEDCOM_TAG_EDUCATION = "EDUC" +"""Value: `EDUC` + +Indicator of a level of education attained.""" + +GEDCOM_TAG_EMAIL = "EMAIL" +"""Value: `EMAIL` + +An electronic address that can be used for contact such as an email address.""" + +GEDCOM_TAG_EMIGRATION = "EMIG" +"""Value: `EMIG` + +An event of leaving one's homeland with the intent of residing elsewhere.""" + +GEDCOM_TAG_ENDOWMENT = "ENDL" +"""Value: `ENDL` + +A religious event where an endowment ordinance for an individual was performed +by priesthood authority in an LDS temple.""" + +GEDCOM_TAG_ENGAGEMENT = "ENGA" +"""Value: `ENGA` + +An event of recording or announcing an agreement between two people to become +married.""" + +GEDCOM_TAG_EVENT = "EVEN" +"""Value: `EVEN` + +A noteworthy happening related to an individual, a group, or an organization.""" + +GEDCOM_TAG_FACT = "FACT" +"""Value: `FACT` + +Pertaining to a noteworthy attribute or fact concerning an individual, a group, +or an organization. A `FACT` structure is usually qualified or classified by a +subordinate use of the `gedcom.tags.GEDCOM_TAG_TYPE` tag.""" + GEDCOM_TAG_FAMILY = "FAM" """Value: `FAM`. -Identifies a legal, common law, or other customary relationship of man and woman and their children, -if any, or a family created by virtue of the birth of a child to its biological father and mother.""" +Identifies a legal, common law, or other customary relationship of man and woman +and their children, if any, or a family created by virtue of the birth of a +child to its biological father and mother.""" GEDCOM_TAG_FAMILY_CHILD = "FAMC" """Value: `FAMC` Identifies the family in which an individual appears as a child.""" +GEDCOM_TAG_FAMILY_FILE = "FAMF" +"""Value: `FAMF` + +Pertaining to, or the name of, a family file. Names stored in a file that are +assigned to a family for doing temple ordinance work.""" + GEDCOM_TAG_FAMILY_SPOUSE = "FAMS" """Value: `FAMS` Identifies the family in which an individual appears as a spouse.""" +GEDCOM_TAG_FAX = "FAX" +"""Value: `FAX` + +A FAX telephone number appropriate for sending data facsimiles.""" + +GEDCOM_TAG_FIRST_COMMUNION = "FCOM" +"""Value: `FCOM` + +A religious rite, the first act of sharing in the Lord's supper as part of +church worship.""" + GEDCOM_TAG_FILE = "FILE" """Value: `FILE` -An information storage place that is ordered and arranged for preservation and reference.""" +An information storage place that is ordered and arranged for preservation and +reference.""" + +GEDCOM_TAG_PHONETIC = "FONE" +"""Value: `FONE` + +A phonetic variation of a superior text string.""" + +GEDCOM_TAG_FORMAT = "FORM" +"""Value: `FORM` + +An assigned name given to a consistent format in which information can be +conveyed.""" + +GEDCOM_TAG_GEDCOM = "GEDC" +"""Value: `GEDC` + +Information about the use of GEDCOM in a transmission.""" GEDCOM_TAG_GIVEN_NAME = "GIVN" """Value: `GIVN` A given or earned name used for official identification of a person.""" +GEDCOM_TAG_GRADUATION = "GRAD" +"""Value: `GRAD` + +An event of awarding educational diplomas or degrees to individuals.""" + +GEDCOM_TAG_HEADER = "HEAD" +"""Value: `HEAD` + +Identifies information pertaining to an entire GEDCOM transmission.""" + GEDCOM_TAG_HUSBAND = "HUSB" """Value: `HUSB` An individual in the family role of a married man or father.""" +GEDCOM_TAG_IDENT_NUMBER = "IDNO" +"""Value: `IDNO` + +A number assigned to identify a person within some significant external system.""" + +GEDCOM_TAG_IMMIGRATION = "IMMI" +"""Value: `IMMI` + +An event of entering into a new locality witht he intent of residing there.""" + GEDCOM_TAG_INDIVIDUAL = "INDI" """Value: `INDI` A person.""" +GEDCOM_TAG_LANGUAGE = "LANG" +"""Value: `LANG` + +The name of the language used in a communication or transmission of information.""" + +GEDCOM_TAG_LATITUDE = "LATI" +"""Value: `LATI` + +A value indicating a coordinate position on a line, plane, or space.""" + +GEDCOM_TAG_LEGATEE = "LEGA" +"""Value: `LEGA` + +A role of an individual acting as a person receiving a bequest or legal devise.""" + +GEDCOM_TAG_LONGITUDE = "LONG" +"""Value: `LONG` + +A value indicating a coordinate position on a line, plane, or space.""" + +GEDCOM_TAG_MAP = "MAP" +"""Value: `MAP` + +Pertains to a representation of measurements usually presented in a graphical +form.""" + +GEDCOM_TAG_MARRIAGE_BANN = "MARB" +"""Value: `MARB`. + +An event of an official public notice given that two people intend to marry.""" + +GEDCOM_TAG_MARR_CONTRACT = "MARC" +"""Value: `MARC`. + +An event of recording a formal agreement of marriage, including the prenuptial +agreement in which marriage partners reach agreement about the property rights +of one or both, securing property to their children.""" + +GEDCOM_TAG_MARR_LICENSE = "MARL" +"""Value: `MARL`. + +An event of obtaining a legal license to marry.""" + GEDCOM_TAG_MARRIAGE = "MARR" """Value: `MARR`. -A legal, common-law, or customary event of creating a family unit of a man and a woman as husband and wife.""" +A legal, common-law, or customary event of creating a family unit of a man and +a woman as husband and wife.""" + +GEDCOM_TAG_MARR_SETTLEMENT = "MARS" +"""Value: `MARS`. + +An event of creating an agreement between two people contemplating marriage, +at which time they agree to release or modify property rights that would +otherwise arise from the marriage.""" + +GEDCOM_TAG_MEDIA = "MEDI" +"""Value: `MEDI`. + +Identifies information about the media or having to do with the medium in which +information is stored.""" GEDCOM_TAG_NAME = "NAME" """Value: `NAME`. -A word or combination of words used to help identify an individual, title, or other item. -More than one NAME line should be used for people who were known by multiple names.""" +A word or combination of words used to help identify an individual, title, or +other item. More than one `NAME` line should be used for people who were known +by multiple names.""" + +GEDCOM_TAG_NATIONALITY = "NATI" +"""Value: `NATI` + +The national heritage of an individual.""" + +GEDCOM_TAG_NATURALIZATION = "NATU" +"""Value: `NATU` + +The event of obtaining citizenship.""" + +GEDCOM_TAG_CHILDREN_COUNT = "NCHI" +"""Value: `NCHI` + +The number of children that this person is known to be the parent of (all +marriages) when subordinate to an individual, or that belong to this family +when subordinate to a `gedcom.tags.GEDCOM_TAG_FAMILY` record.""" + +GEDCOM_TAG_NICKNAME = "NICK" +"""Value: `NICK` + +A descriptive or familiar that is used instead of, or in addition to, one's +proper name.""" + +GEDCOM_TAG_MARRIAGE_COUNT = "NMR" +"""Value: `NMR` + +The number of times this person has participated in a family as a spouse or +parent.""" + +GEDCOM_TAG_NOTE = "NOTE" +"""Value: `NOTE` + +Additional information provided by the submitter for understanding the +enclosing data.""" + +GEDCOM_TAG_NAME_PREFIX = "NPFX" +"""Value: `NPFX` + +Text which appears on a name line before the given and surname parts of a name. +i.e. ( Lt. Cmndr. ) Joseph /Allen/ jr. In this example Lt. Cmndr. is considered +as the name prefix portion.""" + +GEDCOM_TAG_NAME_SUFFIX = "NSFX" +"""Value: `NSFX` + +Text which appears on a name line after or behind the given and surname parts +of a name. i.e. Lt. Cmndr. Joseph /Allen/ ( jr. ) In this example jr. is +considered as the name suffix portion.""" GEDCOM_TAG_OBJECT = "OBJE" """Value: `OBJE` -Pertaining to a grouping of attributes used in describing something. Usually referring to the data required -to represent a multimedia object, such an audio recording, a photograph of a person, or an image of a document.""" +Pertaining to a grouping of attributes used in describing something. Usually +referring to the data required to represent a multimedia object, such an audio +recording, a photograph of a person, or an image of a document.""" GEDCOM_TAG_OCCUPATION = "OCCU" """Value: `OCCU` The type of work or profession of an individual.""" +GEDCOM_TAG_ORDINANCE = "ORDI" +"""Value: `ORDI` + +Pertaining to a religious ordinance in general.""" + +GEDCOM_TAG_ORDINATION = "ORDN" +"""Value: `ORDN` + +A religious event of receiving authority to act in religious matters.""" + +GEDCOM_TAG_PAGE = "PAGE" +"""Value: `PAGE` + +A number or description to identify where information can be found in a +referenced work.""" + +GEDCOM_TAG_PEDIGREE = "PEDI" +"""Value: `PEDI` + +Information pertaining to an individual to parent lineage chart.""" + +GEDCOM_TAG_PHONE = "PHON" +"""Value: `PHON` + +A unique number assigned to access a specific telephone.""" + GEDCOM_TAG_PLACE = "PLAC" """Value: `PLAC` A jurisdictional name to identify the place or location of an event.""" +GEDCOM_TAG_POSTAL_CODE = "POST" +"""Value: `POST` + +A code used by a postal service to identify an area to facilitate mail handling.""" + GEDCOM_TAG_PRIVATE = "PRIV" """Value: `PRIV` Flag for private address or event.""" +GEDCOM_TAG_PROBATE = "PROB" +"""Value: `PROB` + +An event of judicial determination of the validity of a will. May indicate +several related court activities over several dates.""" + +GEDCOM_TAG_PROPERTY = "PROP" +"""Value: `PROP` + +Pertaining to possessions such as real estate or other property of interest.""" + +GEDCOM_TAG_PUBLICATION = "PUBL" +"""Value: `PUBL` + +Refers to when and/or were a work was published or created.""" + +GEDCOM_TAG_QUALITY_OF_DATA = "QUAY" +"""Value: `QUAY` + +An assessment of the certainty of the evidence to support the conclusion drawn +from evidence.""" + +GEDCOM_TAG_REFERENCE = "REFN" +"""Value: `REFN` + +A description or number used to identify an item for filing, storage, or other +reference purposes.""" + +GEDCOM_TAG_RELATIONSHIP = "RELA" +"""Value: `RELA` + +A relationship value between the indicated contexts.""" + +GEDCOM_TAG_RELIGION = "RELI" +"""Value: `RELI` + +A religious denomination to which a person is affiliated or for which a record +applies.""" + +GEDCOM_TAG_REPOSITORY = "REPO" +"""Value: `REPO` + +An institution or person that has the specified item as part of their +collection(s).""" + +GEDCOM_TAG_RESIDENCE = "RESI" +"""Value: `RESI` + +The act of dwelling at a place for a period of time.""" + +GEDCOM_TAG_RESTRICTION = "RESN" +"""Value: `RESN` + +A processing indicator signifying access to information has been denied or +otherwise restricted.""" + +GEDCOM_TAG_RETIREMENT = "RETI" +"""Value: `RETI` + +An event of exiting an occupational relationship with an employer after a +qualifying time period.""" + +GEDCOM_TAG_REC_FILE_NUMBER = "RFN" +"""Value: `RFN` + +A permanent number assigned to a record that uniquely identifies it within a +known file.""" + +GEDCOM_TAG_REC_ID_NUMBER = "RIN" +"""Value: `RIN` + +A number assigned to a record by an originating automated system that can be +used by a receiving system to report results pertaining to that record.""" + +GEDCOM_TAG_ROLE = "ROLE" +"""Value: `ROLE` + +A name given to a role played by an individual in connection with an event.""" + +GEDCOM_TAG_ROMANIZED = "ROMN" +"""Value: `ROMN` + +A romanized variation of a superior text string.""" + GEDCOM_TAG_SEX = "SEX" """Value: `SEX` Indicates the sex of an individual--male or female.""" +GEDCOM_TAG_SEALING_CHILD = "SLGC" +"""Value: `SLGC` + +A religious event pertaining to the sealing of a child to his or her parents in +an LDS temple ceremony.""" + +GEDCOM_TAG_SEALING_SPOUSE = "SLGS" +"""Value: `SLGS` + +A religious event pertaining to the sealing of a husband and wife in an LDS +temple ceremony.""" + GEDCOM_TAG_SOURCE = "SOUR" """Value: `SOUR` The initial or original material from which information was obtained.""" +GEDCOM_TAG_SURN_PREFIX = "SPFX" +"""Value: `SPFX` + +A name piece used as a non-indexing pre-part of a surname.""" + +GEDCOM_TAG_SOC_SEC_NUMBER = "SSN" +"""Value: `SSN` + +A number assigned by the United States Social Security Administration. Used for +tax identification purposes.""" + +GEDCOM_TAG_STATE = "STAE" +"""Value: `STAE` + +A geographical division of a larger jurisdictional area, such as a State within +the United States of America.""" + +GEDCOM_TAG_STATUS = "STAT" +"""Value: `STAT` + +An assessment of the state or condition of something.""" + +GEDCOM_TAG_SUBMITTER = "SUBM" +"""Value: `SUBM` + +An individual or organization who contributes genealogical data to a file or +transfers it to someone else.""" + +GEDCOM_TAG_SUBMISSION = "SUBN" +"""Value: `SUBN` + +Pertains to a collection of data issued for processing.""" + GEDCOM_TAG_SURNAME = "SURN" """Value: `SURN` A family name passed on or used by members of a family.""" +GEDCOM_TAG_TEMPLE = "TEMP" +"""Value: `TEMP` + +The name or code that represents the name a temple of the LDS Church.""" + +GEDCOM_TAG_TEXT = "TEXT" +"""Value: `TEXT` + +The exact wording found in an original source document.""" + +GEDCOM_TAG_TIME = "TIME" +"""Value: `TIME` + +A time value in a 24-hour clock format, including hours, minutes, and optional +seconds, separated by a colon (:). Fractions of seconds are shown in decimal +notation.""" + +GEDCOM_TAG_TITLE = "TITL" +"""Value: `TITL` + +A description of a specific writing or other work, such as the title of a book +when used in a source context, or a formal designation used by an individual +in connection with positions of royalty or other social status, such as Grand +Duke.""" + +GEDCOM_TAG_TRAILER = "TRLR" +"""Value: `TRLR` + +At level 0, specifies the end of a GEDCOM transmission.""" + +GEDCOM_TAG_TYPE = "TYPE" +"""Value: `TYPE` + +A further qualification to the meaning of the associated superior tag. The value +does not have any computer processing reliability. It is more in the form of a +short one or two word note that should be displayed any time the associated data +is displayed.""" + +GEDCOM_TAG_VERSION = "VERS" +"""Value: `VERS` + +Indicates which version of a product, item, or publication is being used or +referenced.""" + GEDCOM_TAG_WIFE = "WIFE" """Value: `WIFE` An individual in the role as a mother and/or married woman.""" + +GEDCOM_TAG_WWW = "WWW" +"""Value: `WWW` + +World Wide Web home page.""" + +GEDCOM_TAG_WILL = "WILL" +"""Value: `WILL` + +A legal document treated as an event, by which a person disposes of his or her +estate, to take effect after death. The event date is the date the will was +signed while the person was alive. (See also `gedcom.tags.GEDCOM_TAG_PROBATE`)""" diff --git a/tests/element/test_file.py b/tests/element/test_file.py deleted file mode 100644 index fc13189..0000000 --- a/tests/element/test_file.py +++ /dev/null @@ -1,9 +0,0 @@ -from gedcom.element.element import Element -from gedcom.element.file import FileElement -import gedcom.tags - - -def test_initialization(): - file_element = FileElement(level=-1, pointer="", tag=gedcom.tags.GEDCOM_TAG_FILE, value="") - assert isinstance(file_element, Element) - assert isinstance(file_element, FileElement) diff --git a/tests/element/test_header.py b/tests/element/test_header.py new file mode 100644 index 0000000..a212af7 --- /dev/null +++ b/tests/element/test_header.py @@ -0,0 +1,9 @@ +from gedcom.element.element import Element +from gedcom.element.header import HeaderElement +import gedcom.tags + + +def test_initialization(): + header_element = HeaderElement(level=-1, pointer="", tag=gedcom.tags.GEDCOM_TAG_HEADER, value="") + assert isinstance(header_element, Element) + assert isinstance(header_element, HeaderElement) diff --git a/tests/element/test_note.py b/tests/element/test_note.py new file mode 100644 index 0000000..92cd521 --- /dev/null +++ b/tests/element/test_note.py @@ -0,0 +1,9 @@ +from gedcom.element.element import Element +from gedcom.element.note import NoteElement +import gedcom.tags + + +def test_initialization(): + note_element = NoteElement(level=-1, pointer="", tag=gedcom.tags.GEDCOM_TAG_NOTE, value="") + assert isinstance(note_element, Element) + assert isinstance(note_element, NoteElement) diff --git a/tests/element/test_repository.py b/tests/element/test_repository.py new file mode 100644 index 0000000..6d7bfaf --- /dev/null +++ b/tests/element/test_repository.py @@ -0,0 +1,9 @@ +from gedcom.element.element import Element +from gedcom.element.repository import RepositoryElement +import gedcom.tags + + +def test_initialization(): + repository_element = RepositoryElement(level=-1, pointer="", tag=gedcom.tags.GEDCOM_TAG_REPOSITORY, value="") + assert isinstance(repository_element, Element) + assert isinstance(repository_element, RepositoryElement) diff --git a/tests/element/test_source.py b/tests/element/test_source.py new file mode 100644 index 0000000..2373695 --- /dev/null +++ b/tests/element/test_source.py @@ -0,0 +1,9 @@ +from gedcom.element.element import Element +from gedcom.element.source import SourceElement +import gedcom.tags + + +def test_initialization(): + source_element = SourceElement(level=-1, pointer="", tag=gedcom.tags.GEDCOM_TAG_SOURCE, value="") + assert isinstance(source_element, Element) + assert isinstance(source_element, SourceElement) diff --git a/tests/element/test_submission.py b/tests/element/test_submission.py new file mode 100644 index 0000000..1155dff --- /dev/null +++ b/tests/element/test_submission.py @@ -0,0 +1,9 @@ +from gedcom.element.element import Element +from gedcom.element.submission import SubmissionElement +import gedcom.tags + + +def test_initialization(): + submission_element = SubmissionElement(level=-1, pointer="", tag=gedcom.tags.GEDCOM_TAG_SUBMISSION, value="") + assert isinstance(submission_element, Element) + assert isinstance(submission_element, SubmissionElement) diff --git a/tests/element/test_submitter.py b/tests/element/test_submitter.py new file mode 100644 index 0000000..f949d6d --- /dev/null +++ b/tests/element/test_submitter.py @@ -0,0 +1,9 @@ +from gedcom.element.element import Element +from gedcom.element.submitter import SubmitterElement +import gedcom.tags + + +def test_initialization(): + submitter_element = SubmitterElement(level=-1, pointer="", tag=gedcom.tags.GEDCOM_TAG_SUBMITTER, value="") + assert isinstance(submitter_element, Element) + assert isinstance(submitter_element, SubmitterElement) diff --git a/tests/test_parser.py b/tests/test_parser.py index 451a3fa..615a347 100644 --- a/tests/test_parser.py +++ b/tests/test_parser.py @@ -62,7 +62,7 @@ def test_parse_from_string(): 4 LONG W122.234319 """ gedcom_parser = Parser() - gedcom_parser.parse([(a + '\n').encode('utf-8-sig') for a in case_1.splitlines()]) + gedcom_parser.parse([(a + '\n') for a in case_1.splitlines()]) element_1 = gedcom_parser.get_root_child_elements()[0] assert isinstance(element_1, IndividualElement) assert element_1.get_tag() == 'INDI' @@ -86,7 +86,7 @@ def test_parse_from_string(): 2 _FREL Natural 2 _MREL Natural """ - gedcom_parser.parse([(a + '\n').encode('utf-8-sig') for a in case_2.splitlines()]) + gedcom_parser.parse([(a + '\n') for a in case_2.splitlines()]) element_2 = gedcom_parser.get_root_child_elements()[0] assert element_2.get_tag() == 'FAM' assert element_2.get_pointer() == '@F28@' @@ -112,7 +112,7 @@ def test_to_gedcom_string(): """ gedcom_parser = Parser() - gedcom_parser.parse([(a + '\n').encode('utf-8-sig') for a in case_1.splitlines()]) + gedcom_parser.parse([(a + '\n') for a in case_1.splitlines()]) case_1_string_array = case_1.splitlines() gedcom_string = gedcom_parser.to_gedcom_string(True) diff --git a/tox.ini b/tox.ini index 8cca615..2f00a83 100644 --- a/tox.ini +++ b/tox.ini @@ -13,6 +13,8 @@ basepython = py37: python3.7 py38: python3.8 deps = + chardet + ansel check-manifest flake8 pytest