gedcom-ts
Version:
A TypeScript library to create genealogy tree data model and to import/export data in a GEDCOM file (.ged).
190 lines (189 loc) • 6.13 kB
JavaScript
import { Separators } from '../commons/Separators';
import { Sex } from '../commons/People';
import { Identificator } from '../commons/Identificator.enum';
export class ExportFormatFile {
title;
extension;
constructor(title) {
this.title = title;
}
export(data) {
const link = document.createElement('a');
link.setAttribute('href', data);
link.setAttribute('download', `${this.title}${this.extension}`);
link.click();
}
}
export class GEDCOM extends ExportFormatFile {
peoples;
constructor(title, peoples) {
super(title);
this.extension = '.ged';
this.peoples = peoples;
}
get beginGedcom() {
const cr = Separators.CARRIAGE_RETURN;
const date = new Date();
const options = { day: '2-digit', month: '2-digit', year: 'numeric' };
const formattedTime = date.toLocaleTimeString('fr-FR');
return ('0 HEAD' +
cr +
'1 SOUR generated by gedcom-ts' +
cr +
`1 DATE ${date.toLocaleDateString('fr-FR', options)}` +
cr +
`2 TIME ${date.toLocaleTimeString('fr-FR')}` +
cr +
`1 FILE ${this.title}` +
cr +
'1 GEDC' +
cr +
'2 VERS 5.5.1' +
cr +
'2 FORM LINEAGE-LINKED' +
cr +
'1 CHAR UTF-8' +
cr);
}
get contentGedcom() {
let content = '';
const cr = Separators.CARRIAGE_RETURN;
if (this.peoples && this.peoples.length > 0) {
this.peoples.forEach((people) => {
const firstnames = people.firstnames ?? [];
const peopleLine = new PeopleLine(people.sosa, [...firstnames], people.lastname, people.FAMS, people.FAMC);
// sosa
content += peopleLine.indi;
if (peopleLine.famsLine) {
content += peopleLine.famsLine;
}
if (peopleLine.famcLine) {
content += peopleLine.famcLine;
}
// prénom et nom
content += peopleLine.firstnamesAndNames;
// sex
content += peopleLine.sex;
// birth
if (people.birth && (people.birth.dateAct?.date || people.birth.place)) {
const actLine = new ActLine(Identificator.BIRT, people.birth);
content += actLine.typeLine;
if (people.birth.dateAct?.date) {
content += actLine.dateLine;
}
if (people.birth.place) {
content += actLine.placeLine;
}
}
if (people.death && (people.death.dateAct?.date || people.death.place)) {
const actLine = new ActLine(Identificator.DEAT, people.death);
content += actLine.typeLine;
if (people.death.dateAct?.date) {
content += actLine.dateLine;
}
if (people.death.place) {
content += actLine.placeLine;
}
}
});
// content += 'toto' + cr;
}
return content;
}
download() {
const ged = `data:text/ged;charset=utf-8,${this.beginGedcom}${this.contentGedcom}${Identificator.TRLR}`;
const data = encodeURI(ged);
this.export(data);
}
}
export class LineGedcom {
cr = Separators.CARRIAGE_RETURN;
}
export class PeopleLine extends LineGedcom {
sosa;
fams;
famc;
firstnames;
lastnames;
constructor(sosa, firstnames, lastnames, fams, famc) {
super();
this.sosa = sosa;
this.firstnames = firstnames;
this.lastnames = lastnames ?? '';
this.fams = fams?.length > 0 ? fams : [];
if (famc) {
this.famc = famc;
}
}
get indi() {
if (this.sosa) {
return `0 ${this.sosa}@ INDI${this.cr}`;
}
return '';
}
get famsLine() {
return this.fams.reduce((pre, curr) => {
if (curr >= 0) {
pre += `1 FAMS @${curr}@${this.cr}`;
}
return pre;
}, '');
}
get famcLine() {
if (this.famc) {
return `1 FAMC @${this.famc}@${this.cr}`;
}
return null;
}
get firstnamesAndNames() {
if (this.firstnames || this.lastnames) {
let content = '1 NAME';
if (this.firstnames && this.firstnames.length > 0) {
this.firstnames[0] = `"${this.firstnames[0]}"`;
content += ` ${this.firstnames.join(' ')}`;
}
if (this.lastnames && this.lastnames.length > 0) {
content += ` /${this.lastnames}/`;
}
return content + this.cr;
}
return '';
}
get sex() {
if (this.sosa) {
return `1 SEX ${this.sosa === 1 || this.sosa % 2 ? Sex.F : Sex.M}${this.cr}`;
}
return '';
}
}
export class ActLine extends LineGedcom {
type;
act;
constructor(type, act) {
super();
this.type = type;
this.act = act;
}
get typeLine() {
return `1 ${this.type}${this.cr}`;
}
get dateLine() {
if (this.act?.dateAct?.date) {
const options = { day: '2-digit', month: 'short', year: 'numeric' };
return `2 ${Identificator.DATE} ${this.formatDate(this.act.dateAct)}${this.cr}`;
}
return '';
}
get placeLine() {
if (this.act?.place?.length > 0) {
return `2 ${Identificator.PLAC} ${this.act.place}${this.cr}`;
}
return '';
}
formatDate(dateAct) {
if (dateAct.date) {
return `${dateAct.day ? `${dateAct.day} ` : ''}${dateAct.month ? `${dateAct.month} ` : ''}${dateAct.year ? `${dateAct.year}` : ''}`;
}
return '';
}
}