UNPKG

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
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 @I${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 ''; } }