Skip to content

Commit

Permalink
feat(gedcom): Add Note type
Browse files Browse the repository at this point in the history
Also adjust unused or erroneously-added fields from SourceRecord.
  • Loading branch information
rafaelespinoza committed Dec 28, 2023
1 parent 181255a commit 9c20ed5
Show file tree
Hide file tree
Showing 8 changed files with 149 additions and 10 deletions.
7 changes: 7 additions & 0 deletions internal/gedcom/event.go
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ type Event struct {
DateRange *date.Range
Place string
SourceCitations []*SourceCitation
Notes []*Note
}

func parseEvent(ctx context.Context, line *gedcom7.Line, subnodes []*gedcom.Node) (out *Event, err error) {
Expand Down Expand Up @@ -67,6 +68,12 @@ func parseEvent(ctx context.Context, line *gedcom7.Line, subnodes []*gedcom.Node
return nil, fmt.Errorf("error parsing source citation: %w", err)
}
out.SourceCitations = append(out.SourceCitations, citation)
case "NOTE":
note, err := parseNote(ctx, subline, subnode.GetSubnodes())
if err != nil {
return nil, fmt.Errorf("error parsing note: %w", err)
}
out.Notes = append(out.Notes, note)
default:
log.Warn(ctx, fields, "unsupported Tag")
}
Expand Down
7 changes: 7 additions & 0 deletions internal/gedcom/family_record.go
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ type FamilyRecord struct {
DivorcedAt *Event
AnnulledAt *Event
SourceCitations []*SourceCitation
Notes []*Note
}

func parseFamilyRecord(ctx context.Context, i int, line *gedcom7.Line, subnodes []*gedcom.Node) (out *FamilyRecord, err error) {
Expand Down Expand Up @@ -74,6 +75,12 @@ func parseFamilyRecord(ctx context.Context, i int, line *gedcom7.Line, subnodes
return nil, fmt.Errorf("error parsing source citation: %w", err)
}
out.SourceCitations = append(out.SourceCitations, citation)
case "NOTE":
note, err := parseNote(ctx, subline, subnode.GetSubnodes())
if err != nil {
return nil, fmt.Errorf("error parsing note: %w", err)
}
out.Notes = append(out.Notes, note)
default:
log.Warn(ctx, fields, "unsupported Tag")
}
Expand Down
50 changes: 44 additions & 6 deletions internal/gedcom/gedcom_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -146,6 +146,9 @@ func TestReadRecordsFields(t *testing.T) {
2 DATE 12 JUN 1995
1 DEAT
2 DATE 1 JAN 2000
1 NOTE The year 2000 problem, also commonly known as the Y2K problem, Y2K scare, millennium bug, Y2K bug, Y2K glitch, Y2K error, or simply Y2K,
2 CONT refers to potential computer errors related to the formatting and storage of calendar data for dates in and after the year 2000.
2 LANG en
1 FAMC @F1@
0 @F1@ FAM
1 HUSB @I1@
Expand All @@ -162,6 +165,8 @@ func TestReadRecordsFields(t *testing.T) {
1 ANUL
2 TYPE annulment
2 DATE 2001
1 NOTE Test that the parser can also read th
2 CONC e tag, CONC.
0 @S1@ SOUR
1 _UID 046A3AD191FF4DD3B0693F406E0A7FB87012
1 DATA
Expand Down Expand Up @@ -196,6 +201,7 @@ func TestReadRecordsFields(t *testing.T) {
MarriedAt: &gedcom.Event{Date: mustParseDate(t, "1985-01-18")},
DivorcedAt: &gedcom.Event{Date: mustParseDate(t, "2000-01-01")},
AnnulledAt: &gedcom.Event{Date: mustParseDate(t, "2001-01-01")},
Notes: []*gedcom.Note{{Payload: "Test that the parser can also read the tag, CONC."}},
},
}
if len(records.Families) != len(expected) {
Expand All @@ -212,6 +218,7 @@ func TestReadRecordsFields(t *testing.T) {

cmpStringSlices(t, errMsgPrefix+".ParentXrefs", got.ParentXrefs, exp.ParentXrefs)
cmpStringSlices(t, errMsgPrefix+".ChildXrefs", got.ChildXrefs, exp.ChildXrefs)
testNotes(t, errMsgPrefix+".Notes", got.Notes, exp.Notes)
}
})

Expand Down Expand Up @@ -240,8 +247,13 @@ func TestReadRecordsFields(t *testing.T) {
Names: []gedcom.PersonalName{
{Payload: "Mike /Foxtrot/", Given: "Mike", Nickname: "Millennium Bug", Surname: "Foxtrot"},
},
Birth: &gedcom.Event{Date: mustParseDate(t, "1995-06-12")},
Death: &gedcom.Event{Date: mustParseDate(t, "2000-01-01")},
Birth: &gedcom.Event{Date: mustParseDate(t, "1995-06-12")},
Death: &gedcom.Event{Date: mustParseDate(t, "2000-01-01")},
Notes: []*gedcom.Note{
{Payload: `The year 2000 problem, also commonly known as the Y2K problem, Y2K scare, millennium bug, Y2K bug, Y2K glitch, Y2K error, or simply Y2K,
refers to potential computer errors related to the formatting and storage of calendar data for dates in and after the year 2000.`,
Lang: "en"},
},
FamiliesAsChild: []string{"@F1@"},
},
}
Expand All @@ -268,6 +280,7 @@ func TestReadRecordsFields(t *testing.T) {

cmpStringSlices(t, errMsgPrefix+".FamiliesAsPartner", got.FamiliesAsPartner, exp.FamiliesAsPartner)
cmpStringSlices(t, errMsgPrefix+".FamiliesAsChild", got.FamiliesAsChild, exp.FamiliesAsChild)
testNotes(t, errMsgPrefix+".Notes", got.Notes, exp.Notes)
}
})

Expand All @@ -276,7 +289,7 @@ func TestReadRecordsFields(t *testing.T) {
{
Xref: "@S1@",
Title: "New York Times, March 4, 1946, pp. 1,3.",
Note: "Geneanet Community Trees Index",
Notes: []*gedcom.Note{{Payload: "Geneanet Community Trees Index"}},
Text: "yes",
RepositoryIDs: []string{"@R0@"},
},
Expand Down Expand Up @@ -315,11 +328,9 @@ func TestReadRecordsFields(t *testing.T) {
if got.Text != exp.Text {
t.Errorf("%s; wrong Text, got %q, exp %q", errMsgPrefix, got.Text, exp.Text)
}
if got.Note != exp.Note {
t.Errorf("%s; wrong Note, got %q, exp %q", errMsgPrefix, got.Note, exp.Note)
}

cmpStringSlices(t, errMsgPrefix+".RepositoryIDs", got.RepositoryIDs, exp.RepositoryIDs)
testNotes(t, errMsgPrefix+".Notes", got.Notes, exp.Notes)
}
})
}
Expand Down Expand Up @@ -406,3 +417,30 @@ func cmpStringMaps(t *testing.T, errMsgPrefix string, actual, expected map[strin
}
}
}

func testNotes(t *testing.T, errMsgPrefix string, actual, expected []*gedcom.Note) {
if len(actual) != len(expected) {
t.Errorf("%s; wrong length; got %d, exp %d", errMsgPrefix, len(actual), len(expected))
} else {
for i, got := range actual {
errMsgPrefix := fmt.Sprintf("%s[%d]", errMsgPrefix, i)
exp := expected[i]

if got.Payload != exp.Payload {
t.Errorf("%s; wrong Payload, got %q, exp %q", errMsgPrefix, got.Payload, exp.Payload)
}
if got.Lang != exp.Lang {
t.Errorf("%s; wrong Lang, got %q, exp %q", errMsgPrefix, got.Lang, exp.Lang)
}

if len(got.SourceCitations) != len(exp.SourceCitations) {
t.Errorf("%s; wrong number of SourceCitations; got %d, exp %d", errMsgPrefix, len(got.SourceCitations), len(exp.SourceCitations))
} else {
for j, got := range got.SourceCitations {
errMsgPrefix := fmt.Sprintf("%s[%d], ", errMsgPrefix, j)
cmpSourceCitation(t, errMsgPrefix, got, exp.SourceCitations[j])
}
}
}
}
}
7 changes: 7 additions & 0 deletions internal/gedcom/individual_record.go
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ type IndividualRecord struct {
FamiliesAsChild []string // Xref IDs of families where the person is a child.
FamiliesAsPartner []string // Xref IDs of families where the person is a partner, such as a spouse.
SourceCitations []*SourceCitation
Notes []*Note
}

func parseIndividualRecord(ctx context.Context, i int, line *gedcom7.Line, subnodes []*gedcom.Node) (out *IndividualRecord, err error) {
Expand Down Expand Up @@ -78,6 +79,12 @@ func parseIndividualRecord(ctx context.Context, i int, line *gedcom7.Line, subno
return nil, fmt.Errorf("error parsing source citation: %w", err)
}
out.SourceCitations = append(out.SourceCitations, citation)
case "NOTE":
note, err := parseNote(ctx, subline, subnode.GetSubnodes())
if err != nil {
return nil, fmt.Errorf("error parsing note: %w", err)
}
out.Notes = append(out.Notes, note)
default:
log.Warn(ctx, fields, "unsupported Tag")
}
Expand Down
62 changes: 62 additions & 0 deletions internal/gedcom/note.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,62 @@
package gedcom

import (
"context"
"fmt"

"github.com/funwithbots/go-gedcom/pkg/gedcom"
"github.com/funwithbots/go-gedcom/pkg/gedcom7"
"github.com/rafaelespinoza/ged/internal/log"
)

// A Note is a catch-all location for info that doesn't really fit within other
// defined structures. The Payload field may contain extra research notes,
// context, or alternative interpretations of other data. Its URI is g7:NOTE.
type Note struct {
Payload string
// Lang is the primary language for which the Note is written.
Lang string
SourceCitations []*SourceCitation
}

func parseNote(ctx context.Context, line *gedcom7.Line, subnodes []*gedcom.Node) (out *Note, err error) {
out = &Note{Payload: line.Payload}

var subline *gedcom7.Line

for _, subnode := range subnodes {
if subline, err = parseLine(subnode); err != nil {
return
}

fields := map[string]any{
"func": "parseEvent",
"line": line.Text,
"subtag": subline.Tag,
"subline": subline.Text,
}

log.Debug(ctx, fields, "")

switch subline.Tag {
case "CONC":
// This tag was deprecated in GEDCOM v7. The last GEDCOM version for
// which it was valid was v5.5.1. This tag would only appear in the
// data if the library parser is configured to allow deprecated
// tags. See func gedcom7.WithMaxDeprecatedTags.
out.Payload += subline.Payload
case "LANG":
out.Lang = subline.Payload
case "SOUR":
citation, err := parseSourceCitation(ctx, subline, subnode.GetSubnodes())
if err != nil {
return nil, fmt.Errorf("error parsing source citation: %w", err)
}
out.SourceCitations = append(out.SourceCitations, citation)
default:
log.Warn(ctx, fields, "unsupported Tag")
}
}

return
}
7 changes: 7 additions & 0 deletions internal/gedcom/personal_name.go
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ type PersonalName struct {
Payload string
Type enumset.NameType
SourceCitations []*SourceCitation
Notes []*Note

// The following fields are PERSONAL_NAME_PIECES.
NamePrefix string // URI is g7:NPFX
Expand Down Expand Up @@ -70,6 +71,12 @@ func parsePersonalName(ctx context.Context, line *gedcom7.Line, subnodes []*gedc
return nil, fmt.Errorf("error parsing source citation: %w", err)
}
out.SourceCitations = append(out.SourceCitations, citation)
case "NOTE":
note, err := parseNote(ctx, subline, subnode.GetSubnodes())
if err != nil {
return nil, fmt.Errorf("error parsing note: %w", err)
}
out.Notes = append(out.Notes, note)
default:
// There may be some metadata-related tags such as NAME-TYPE , or
// NOTE. For now, not parsing those, but might try to do so later.
Expand Down
9 changes: 8 additions & 1 deletion internal/gedcom/source.go
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,8 @@ type SourceCitation struct {
Page string
// Data is meant to represent extra info about a source. Its URI is G7:SOUR-DATA.
// This field is rather free-form, there is no payload.
Data map[string]string
Data map[string]string
Notes []*Note
}

func parseSourceCitation(ctx context.Context, line *gedcom7.Line, subnodes []*gedcom.Node) (out *SourceCitation, err error) {
Expand Down Expand Up @@ -53,6 +54,12 @@ func parseSourceCitation(ctx context.Context, line *gedcom7.Line, subnodes []*ge
}
out.Data[dataSubline.Tag] = dataSubline.Payload
}
case "NOTE":
note, err := parseNote(ctx, subline, subnode.GetSubnodes())
if err != nil {
return nil, fmt.Errorf("error parsing note: %w", err)
}
out.Notes = append(out.Notes, note)
default:
log.Warn(ctx, fields, "unsupported Tag")
}
Expand Down
10 changes: 7 additions & 3 deletions internal/gedcom/source_record.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ package gedcom

import (
"context"
"fmt"

"github.com/funwithbots/go-gedcom/pkg/gedcom"
"github.com/funwithbots/go-gedcom/pkg/gedcom7"
Expand All @@ -17,8 +18,7 @@ type SourceRecord struct {
Publication string
Text string
RepositoryIDs []string
Note string
OriginalLines []string
Notes []*Note

// TODO: add other fields such as Data, MultimediaLink, ChangeDate, CreationDate, as needed.
}
Expand Down Expand Up @@ -58,7 +58,11 @@ func parseSourceRecord(ctx context.Context, i int, line *gedcom7.Line, subnodes
case "REPO":
out.RepositoryIDs = append(out.RepositoryIDs, subline.Payload)
case "NOTE":
out.Note = subline.Payload
note, err := parseNote(ctx, subline, subnode.GetSubnodes())
if err != nil {
return nil, fmt.Errorf("error parsing note: %w", err)
}
out.Notes = append(out.Notes, note)
default:
log.Warn(ctx, fields, "unsupported Tag")
}
Expand Down

0 comments on commit 9c20ed5

Please sign in to comment.