From 0d0ed5a7ca9f2876ee83f51e5e1fd6784ec46220 Mon Sep 17 00:00:00 2001 From: Przemek Wiech Date: Sun, 24 Nov 2019 22:07:16 +0100 Subject: [PATCH] Show referenced notes --- src/details.tsx | 20 ++++++++++++++++++-- src/gedcom_util.ts | 12 ++++++++++-- 2 files changed, 28 insertions(+), 4 deletions(-) diff --git a/src/details.tsx b/src/details.tsx index 85395e2..066ea69 100644 --- a/src/details.tsx +++ b/src/details.tsx @@ -2,7 +2,7 @@ import * as React from 'react'; import flatMap from 'array.prototype.flatmap'; import Linkify from 'react-linkify'; import {FormattedMessage, InjectedIntl} from 'react-intl'; -import {GedcomData} from './gedcom_util'; +import {GedcomData, pointerToId} from './gedcom_util'; import {GedcomEntry} from 'parse-gedcom'; import {intlShape} from 'react-intl'; import {translateDate} from './date_util'; @@ -181,6 +181,20 @@ function getOtherDetails(entries: GedcomEntry[]) { )); } +/** + * If the entry is a reference to a top-level entry, the referenced entry is + * returned. Otherwise, returns the given entry unmodified. + */ +function dereference(entry: GedcomEntry, gedcom: GedcomData) { + if (entry.data) { + const dereferenced = gedcom.other[pointerToId(entry.data)]; + if (dereferenced) { + return dereferenced; + } + } + return entry; +} + export class Details extends React.Component { /** Make intl appear in this.context. */ static contextTypes = { @@ -189,7 +203,9 @@ export class Details extends React.Component { render() { const entries = this.props.gedcom.indis[this.props.indi].tree; - const entriesWithData = entries.filter(hasData); + const entriesWithData = entries + .map((entry) => dereference(entry, this.props.gedcom)) + .filter(hasData); return (
diff --git a/src/gedcom_util.ts b/src/gedcom_util.ts index 2a0d5d5..7b9f54c 100644 --- a/src/gedcom_util.ts +++ b/src/gedcom_util.ts @@ -2,9 +2,14 @@ import {JsonFam, JsonGedcomData, JsonIndi, gedcomEntriesToJson} from 'topola'; import {GedcomEntry, parse as parseGedcom} from 'parse-gedcom'; export interface GedcomData { + /** The HEAD entry. */ head: GedcomEntry; + /** INDI entries mapped by id. */ indis: {[key: string]: GedcomEntry}; + /** FAM entries mapped by id. */ fams: {[key: string]: GedcomEntry}; + /** Other entries mapped by id, e.g. NOTE, SOUR. */ + other: {[key: string]: GedcomEntry}; } export interface TopolaData { @@ -16,7 +21,7 @@ export interface TopolaData { * Returns the identifier extracted from a pointer string. * E.g. '@I123@' -> 'I123' */ -function pointerToId(pointer: string): string { +export function pointerToId(pointer: string): string { return pointer.substring(1, pointer.length - 1); } @@ -24,14 +29,17 @@ function prepareGedcom(entries: GedcomEntry[]): GedcomData { const head = entries.find((entry) => entry.tag === 'HEAD')!; const indis: {[key: string]: GedcomEntry} = {}; const fams: {[key: string]: GedcomEntry} = {}; + const other: {[key: string]: GedcomEntry} = {}; entries.forEach((entry) => { if (entry.tag === 'INDI') { indis[pointerToId(entry.pointer)] = entry; } else if (entry.tag === 'FAM') { fams[pointerToId(entry.pointer)] = entry; + } else if (entry.pointer) { + other[pointerToId(entry.pointer)] = entry; } }); - return {head, indis, fams}; + return {head, indis, fams, other}; } function strcmp(a: string, b: string) {