xref: /webtrees/app/Gedcom.php (revision 9abbcca9747738c136d30d39ec7be82574ab4b52)
1<?php
2
3/**
4 * webtrees: online genealogy
5 * Copyright (C) 2022 webtrees development team
6 * This program is free software: you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation, either version 3 of the License, or
9 * (at your option) any later version.
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
14 * You should have received a copy of the GNU General Public License
15 * along with this program. If not, see <https://www.gnu.org/licenses/>.
16 */
17
18declare(strict_types=1);
19
20namespace Fisharebest\Webtrees;
21
22/**
23 * GEDCOM 5.5.1 specification
24 */
25class Gedcom
26{
27    // 255 less the EOL character.
28    public const LINE_LENGTH = 253;
29
30    // Gedcom tags which indicate the start of life.
31    public const BIRTH_EVENTS = ['BIRT', 'CHR', 'BAPM'];
32
33    // Gedcom tags which indicate the end of life.
34    public const DEATH_EVENTS = ['DEAT', 'BURI', 'CREM'];
35
36    // Gedcom tags which indicate the start of a relationship.
37    public const MARRIAGE_EVENTS = ['MARR', '_NMR'];
38
39    // Gedcom tags which indicate the end of a relationship.
40    public const DIVORCE_EVENTS = ['DIV', 'ANUL', '_SEPR'];
41
42    // Regular expression to match a GEDCOM tag.
43    public const REGEX_TAG = '[_A-Z][_A-Z0-9]*';
44
45    // Regular expression to match a GEDCOM XREF.
46    public const REGEX_XREF = '[A-Za-z0-9:_.-]{1,20}';
47
48    // Separates the parts of a place name.
49    public const PLACE_SEPARATOR = ', ';
50
51    // Regex to match a (badly formed) GEDCOM place separator.
52    public const PLACE_SEPARATOR_REGEX = '/ *,[, ]*/';
53
54    // LATI and LONG tags
55    public const LATITUDE_NORTH = 'N';
56    public const LATITUDE_SOUTH = 'S';
57    public const LONGITUDE_EAST = 'E';
58    public const LONGITUDE_WEST = 'W';
59
60    // Not all record types allow a CHAN event.
61    public const RECORDS_WITH_CHAN = [
62        Family::RECORD_TYPE,
63        Individual::RECORD_TYPE,
64        Media::RECORD_TYPE,
65        Note::RECORD_TYPE,
66        Repository::RECORD_TYPE,
67        Source::RECORD_TYPE,
68        Submitter::RECORD_TYPE,
69    ];
70
71    // These preferences control multiple tag definitions
72    public const HIDDEN_TAGS = [
73        // Individual names
74        'NAME_NPFX' => ['INDI:NAME:NPFX', 'INDI:NAME:FONE:NPFX', 'INDI:NAME:ROMN:NPFX'],
75        'NAME_SPFX' => ['INDI:NAME:SPFX', 'INDI:NAME:FONE:SPFX', 'INDI:NAME:ROMN:SPFX'],
76        'NAME_NSFX' => ['INDI:NAME:NSFX', 'INDI:NAME:FONE:NSFX', 'INDI:NAME:ROMN:NSFX'],
77        'NAME_NICK' => ['INDI:NAME:NICK', 'INDI:NAME:FONE:NICK', 'INDI:NAME:ROMN:NICK'],
78        'NAME_FONE' => ['INDI:NAME:FONE'],
79        'NAME_ROMN' => ['INDI:NAME:ROMN'],
80        'NAME_NOTE' => ['INDI:NAME:NOTE'],
81        'NAME_SOUR' => ['INDI:NAME:SOUR'],
82        // Places
83        'PLAC_MAP'  => ['PLAC:MAP'],
84        'PLAC_FONE' => ['PLAC:FONE'],
85        'PLAC_ROMN' => ['PLAC:ROMN'],
86        'PLAC_FORM' => ['PLAC:FORM', 'HEAD:PLAC'],
87        'PLAC_NOTE' => ['PLAC:NOTE'],
88        // Addresses
89        'ADDR_FAX'  => ['FAX'],
90        'ADDR_PHON' => ['PHON'],
91        'ADDR_WWW'  => ['WWW'],
92        // Source citations
93        'SOUR_EVEN' => [':SOUR:EVEN'],
94        'SOUR_DATE' => [':SOUR:DATA:DATE'],
95        'SOUR_NOTE' => [':SOUR:NOTE'],
96        'SOUR_QUAY' => [':SOUR:QUAY'],
97        // Sources
98        'SOUR_DATA' => ['SOUR:DATA:EVEN', 'SOUR:DATA:AGNC', 'SOUR:DATA:NOTE'],
99        // Individuals
100        'BIRT_FAMC' => ['INDI:BIRT:FAMC'],
101        'RELI'      => ['INDI:RELI'],
102        'BAPM'      => ['INDI:BAPM'],
103        'CHR'       => ['INDI:CHR', 'INDI:CHRA'],
104        'FCOM'      => ['INDI:FCOM', 'INDI:CONF'],
105        'ORDN'      => ['INDI:ORDN'],
106        'BARM'      => ['INDI:BARM', 'INDI:BASM'],
107        'ALIA'      => ['INDI:ALIA'],
108        'ASSO'      => ['INDI:ASSO'],
109        // Families
110        'ENGA'      => ['FAM:ENGA'],
111        'MARB'      => ['FAM:MARB'],
112        'MARC'      => ['FAM:MARC'],
113        'MARL'      => ['FAM:MARL'],
114        'MARS'      => ['FAM:MARS'],
115        'ANUL'      => ['FAM:ANUL'],
116        'DIVF'      => ['FAM:DIVF'],
117        'FAM_RESI'  => ['FAM:RESI'],
118        'FAM_CENS'  => ['FAM:CENS'],
119        // LDS church
120        'LDS'       => ['INDI:BAPL', 'INDI:CONL', 'INDI:ENDL', 'INDI:SLGC', 'FAM:SLGS', 'HEAD:SUBN'],
121        // Identifiers
122        'AFN'       => ['INDI:AFN'],
123        'IDNO'      => ['INDI:IDNO'],
124        'SSN'       => ['INDI:SSN'],
125        'RFN'       => ['RFN'],
126        'REFN'      => ['REFN'],
127        'RIN'       => ['RIN'],
128        // Submitters
129        'SUBM'      => ['INDI:SUBM', 'FAM:SUBM'],
130        'ANCI'      => ['INDI:ANCI', 'INDI:DESI'],
131    ];
132}
133