From d566466308faf7f5d017edd6118bafd5f35bc56a Mon Sep 17 00:00:00 2001
From: Ian Davis <18375+iand@users.noreply.github.com>
Date: Fri, 23 Jan 2026 12:52:10 +0000
Subject: [PATCH 1/2] Add documentation for exported functions
---
decoder.go | 4 +-
doc.go | 115 +++++++++++++++++
encoder.go | 9 +-
helpers.go | 29 ++++-
scanner.go | 36 ++++--
types.go | 364 ++++++++++++++++++++++++++++++-----------------------
6 files changed, 380 insertions(+), 177 deletions(-)
create mode 100644 doc.go
diff --git a/decoder.go b/decoder.go
index 317bb68..08b5613 100644
--- a/decoder.go
+++ b/decoder.go
@@ -3,7 +3,6 @@ This is free and unencumbered software released into the public domain. For more
information, see or the accompanying UNLICENSE file.
*/
-// Package gedcom provides a functions to parse GEDCOM files.
package gedcom
import (
@@ -31,6 +30,9 @@ func NewDecoder(r io.Reader) *Decoder {
}
}
+// LogUnhandledTags configures the decoder to log any unrecognized GEDCOM tags
+// to the provided writer. This is useful for debugging GEDCOM files that
+// contain non-standard or vendor-specific tags.
func (d *Decoder) LogUnhandledTags(w io.Writer) {
d.tagLogger = log.New(w, "", log.Lshortfile)
}
diff --git a/doc.go b/doc.go
new file mode 100644
index 0000000..dc6454a
--- /dev/null
+++ b/doc.go
@@ -0,0 +1,115 @@
+/*
+This is free and unencumbered software released into the public domain. For more
+information, see or the accompanying UNLICENSE file.
+*/
+
+/*
+Package gedcom provides functions to parse and produce GEDCOM files.
+
+GEDCOM (Genealogical Data Communication) is a standard format used for
+exchanging genealogical data between software applications. This package
+includes functionality for both parsing existing GEDCOM files and generating
+new ones.
+
+# Decoding GEDCOM Files
+
+The package provides a streaming [Decoder] for reading GEDCOM files. Use
+[NewDecoder] to create a decoder that reads from an [io.Reader]:
+
+ data, err := os.ReadFile("family.ged")
+ if err != nil {
+ log.Fatal(err)
+ }
+
+ d := gedcom.NewDecoder(bytes.NewReader(data))
+ g, err := d.Decode()
+ if err != nil {
+ log.Fatal(err)
+ }
+
+ for _, ind := range g.Individual {
+ if len(ind.Name) > 0 {
+ fmt.Println(ind.Name[0].Name)
+ }
+ }
+
+The decoder is streaming and can handle large files without loading the entire
+contents into memory.
+
+# Encoding GEDCOM Files
+
+The package also provides an [Encoder] for generating GEDCOM files. Use
+[NewEncoder] to create an encoder that writes to an [io.Writer]:
+
+ g := &gedcom.Gedcom{
+ Header: &gedcom.Header{
+ SourceSystem: gedcom.SystemRecord{
+ Xref: "MyApp",
+ ProductName: "My Application",
+ },
+ CharacterSet: "UTF-8",
+ },
+ Individual: []*gedcom.IndividualRecord{
+ {
+ Xref: "I1",
+ Name: []*gedcom.NameRecord{
+ {Name: "John /Doe/"},
+ },
+ Sex: "M",
+ },
+ },
+ Trailer: &gedcom.Trailer{},
+ }
+
+ f, err := os.Create("output.ged")
+ if err != nil {
+ log.Fatal(err)
+ }
+ defer f.Close()
+
+ enc := gedcom.NewEncoder(f)
+ if err := enc.Encode(g); err != nil {
+ log.Fatal(err)
+ }
+
+# Data Model
+
+The [Gedcom] struct is the top-level container returned by the decoder and
+accepted by the encoder. It contains slices of records for individuals,
+families, sources, and other GEDCOM record types.
+
+[IndividualRecord] represents a person and contains their names, sex, life
+events (birth, death, etc.), family links, and citations.
+
+[FamilyRecord] represents a family unit and links to husband, wife, and
+children as [IndividualRecord] pointers.
+
+[EventRecord] is a flexible type used for both events (birth, death, marriage)
+and attributes (occupation, residence). The Tag field indicates the event type.
+
+[SourceRecord] and [CitationRecord] handle source citations for genealogical
+claims.
+
+# Name Parsing
+
+The [SplitPersonalName] helper function parses GEDCOM-formatted names:
+
+ parsed := gedcom.SplitPersonalName("John \"Jack\" /Smith/ Jr.")
+ // parsed.Given = "John"
+ // parsed.Nickname = "Jack"
+ // parsed.Surname = "Smith"
+ // parsed.Suffix = "Jr."
+
+# User-Defined Tags
+
+GEDCOM allows custom tags prefixed with an underscore. These are captured in
+[UserDefinedTag] slices on most record types, preserving vendor-specific
+extensions.
+
+# Specification Coverage
+
+This package implements approximately 80% of the GEDCOM 5.5 specification,
+which is sufficient for parsing about 99% of real-world GEDCOM files. It has
+not been extensively tested with non-ASCII character sets.
+*/
+package gedcom
diff --git a/encoder.go b/encoder.go
index c902019..159b879 100644
--- a/encoder.go
+++ b/encoder.go
@@ -12,7 +12,12 @@ import (
"strings"
)
-// An Encoder encodes and writes GEDCOM objects to an input stream.
+// Encoder writes GEDCOM-encoded data to an output stream.
+// Use [NewEncoder] to create an Encoder and [Encoder.Encode] to write
+// a [Gedcom] structure.
+//
+// The encoder handles GEDCOM line length limits automatically, using
+// CONT (continuation) and CONC (concatenation) tags to split long text.
type Encoder struct {
w *bufio.Writer
err error
@@ -26,6 +31,8 @@ func NewEncoder(w io.Writer) *Encoder {
}
}
+// Encode writes the GEDCOM-encoded representation of g to the encoder's output stream.
+// It writes the header, all records (individuals, families, sources, etc.), and trailer.
func (e *Encoder) Encode(g *Gedcom) error {
e.header(g.Header)
diff --git a/helpers.go b/helpers.go
index 53282a6..c3723e8 100644
--- a/helpers.go
+++ b/helpers.go
@@ -4,15 +4,32 @@ import (
"strings"
)
+// ParsedName contains the components of a personal name after parsing
+// with [SplitPersonalName].
type ParsedName struct {
- Full string
- Given string
- Surname string
- Suffix string
- Nickname string
+ Full string // Reconstructed full name without GEDCOM delimiters
+ Given string // Given name(s) / first name(s)
+ Surname string // Surname / family name / last name
+ Suffix string // Name suffix (e.g., "Jr.", "III", "PhD")
+ Nickname string // Nickname, if present in quotes
}
-// SplitPersonalName parses a name in the format "First Name /Surname/ suffix" into its components.
+// SplitPersonalName parses a GEDCOM-formatted personal name into its components.
+// GEDCOM names use slashes to delimit the surname: "Given Names /Surname/ Suffix".
+//
+// Examples:
+//
+// SplitPersonalName("John /Smith/")
+// // Returns: Given="John", Surname="Smith"
+//
+// SplitPersonalName("John \"Jack\" /Smith/ Jr.")
+// // Returns: Given="John", Nickname="Jack", Surname="Smith", Suffix="Jr."
+//
+// SplitPersonalName("Mary Jane /van der Berg/")
+// // Returns: Given="Mary Jane", Surname="van der Berg"
+//
+// The function also handles alternative surnames separated by slashes within
+// the surname delimiters (e.g., "/Smith/Smyth/" becomes Surname="Smith/Smyth").
func SplitPersonalName(name string) ParsedName {
name = strings.TrimSpace(name)
diff --git a/scanner.go b/scanner.go
index 7fb883c..bcfb9bf 100644
--- a/scanner.go
+++ b/scanner.go
@@ -11,15 +11,19 @@ import (
"strconv"
)
+// Line represents a single line from a GEDCOM file after tokenization.
+// A GEDCOM line has the format: "level [xref] tag [value]"
+// For example: "0 @I1@ INDI" or "1 NAME John /Smith/"
type Line struct {
- Level int
- Tag string
- Value string
- Xref string
- LineNumber int // the line number of the input file
- Offset int // the character offset in the input file
+ Level int // Hierarchy level (0 for top-level records)
+ Tag string // GEDCOM tag (e.g., "INDI", "NAME", "BIRT")
+ Value string // Optional value following the tag
+ Xref string // Optional cross-reference identifier (e.g., "I1" from "@I1@")
+ LineNumber int // Line number in the input file (1-indexed)
+ Offset int // Character offset in the input file
}
+// String returns the line in GEDCOM format.
func (l *Line) String() string {
if l.Xref != "" {
return fmt.Sprintf("%d @%s@ %s %s", l.Level, l.Xref, l.Tag, l.Value)
@@ -27,7 +31,12 @@ func (l *Line) String() string {
return fmt.Sprintf("%d %s %s", l.Level, l.Tag, l.Value)
}
-// A Scanner is a GEDCOM scanning state machine.
+// Scanner tokenizes GEDCOM input line by line. It is a low-level component
+// used by [Decoder]. Most users should use [Decoder] directly instead.
+//
+// A Scanner reads from an [io.RuneScanner] and breaks the input into
+// GEDCOM lines, parsing the level, optional cross-reference, tag, and
+// optional value from each line.
type Scanner struct {
r io.RuneScanner
err error
@@ -41,7 +50,9 @@ type Scanner struct {
xref string
}
-// NewScanner creates a new Scanner ready for use.
+// NewScanner creates a new Scanner that reads from r.
+// Use [Scanner.Next] to advance through the input and [Scanner.Line]
+// to retrieve the current line after each successful call to Next.
func NewScanner(r io.RuneScanner) *Scanner {
return &Scanner{
r: r,
@@ -307,10 +318,13 @@ func (s *Scanner) Err() error {
return s.err
}
+// ScanErr represents a scanning error with location information.
+// It wraps the underlying error and includes the line number and
+// character offset where the error occurred.
type ScanErr struct {
- Err error
- LineNumber int
- Offset int
+ Err error // The underlying error
+ LineNumber int // Line number where the error occurred (1-indexed)
+ Offset int // Character offset within the line
}
func (e *ScanErr) Error() string {
diff --git a/types.go b/types.go
index cadd09e..dd9b07c 100644
--- a/types.go
+++ b/types.go
@@ -5,6 +5,8 @@ information, see or the accompanying UNLICENSE file.
package gedcom
+// Gedcom represents a complete GEDCOM file. It is the top-level container
+// returned by [Decoder.Decode] and accepted by [Encoder.Encode].
type Gedcom struct {
Header *Header
Family []*FamilyRecord
@@ -50,230 +52,274 @@ type SystemRecord struct {
UserDefined []UserDefinedTag
}
+// SubmissionRecord contains information about a batch submission of genealogical data.
type SubmissionRecord struct {
Xref string
}
+// Trailer marks the end of a GEDCOM file. It contains no data.
type Trailer struct{}
+// FamilyRecord represents a family unit in GEDCOM. It links individuals
+// together as husband, wife, and children, and contains family events
+// such as marriage, divorce, and census records.
type FamilyRecord struct {
- Xref string
- Husband *IndividualRecord
- Wife *IndividualRecord
- Child []*IndividualRecord
- Event []*EventRecord
- NumberOfChildren string
- UserReference []*UserReferenceRecord
- AutomatedRecordId string
- Change ChangeRecord
- Note []*NoteRecord
- Citation []*CitationRecord
- Media []*MediaRecord
- UserDefined []UserDefinedTag
+ Xref string // Unique cross-reference identifier for this family (e.g., "@F1@")
+ Husband *IndividualRecord // Pointer to the husband/father individual
+ Wife *IndividualRecord // Pointer to the wife/mother individual
+ Child []*IndividualRecord // Pointers to child individuals
+ Event []*EventRecord // Family events (marriage, divorce, census, etc.)
+ NumberOfChildren string // Total number of children, may differ from len(Child)
+ UserReference []*UserReferenceRecord // User-provided reference numbers
+ AutomatedRecordId string // Unique record ID assigned by the source system
+ Change ChangeRecord // Record of when this record was last modified
+ Note []*NoteRecord // Notes attached to this family
+ Citation []*CitationRecord // Source citations for this family
+ Media []*MediaRecord // Media objects (photos, documents) for this family
+ UserDefined []UserDefinedTag // User-defined tags (prefixed with underscore)
}
+// IndividualRecord represents a person in GEDCOM. It contains the person's
+// names, sex, life events, attributes, and links to their families.
type IndividualRecord struct {
- Xref string
- Name []*NameRecord
- Sex string
- Event []*EventRecord
- Attribute []*EventRecord
- Parents []*FamilyLinkRecord
- Family []*FamilyLinkRecord
- Submitter []*SubmitterRecord
- Association []*AssociationRecord
- PermanentRecordFileNumber string
- AncestralFileNumber string
- UserReference []*UserReferenceRecord
- AutomatedRecordId string
- Change ChangeRecord
- Note []*NoteRecord
- Citation []*CitationRecord
- Media []*MediaRecord
- UserDefined []UserDefinedTag
+ Xref string // Unique cross-reference identifier (e.g., "@I1@")
+ Name []*NameRecord // Names (may have multiple for maiden names, aliases)
+ Sex string // Sex: "M" for male, "F" for female, "U" for unknown
+ Event []*EventRecord // Life events (birth, death, burial, etc.)
+ Attribute []*EventRecord // Attributes (occupation, residence, education, etc.)
+ Parents []*FamilyLinkRecord // Links to families where this person is a child
+ Family []*FamilyLinkRecord // Links to families where this person is a spouse
+ Submitter []*SubmitterRecord // Submitters of this record
+ Association []*AssociationRecord // Associations with other individuals
+ PermanentRecordFileNumber string // Permanent record file number
+ AncestralFileNumber string // Ancestral file number
+ UserReference []*UserReferenceRecord // User-provided reference numbers
+ AutomatedRecordId string // Unique record ID assigned by the source system
+ Change ChangeRecord // Record of when this record was last modified
+ Note []*NoteRecord // Notes attached to this individual
+ Citation []*CitationRecord // Source citations for this individual
+ Media []*MediaRecord // Media objects (photos, documents)
+ UserDefined []UserDefinedTag // User-defined tags (prefixed with underscore)
}
+// MediaRecord represents a multimedia object such as a photo, document,
+// or audio/video recording. It can be referenced by individuals, families,
+// events, and sources.
type MediaRecord struct {
- Xref string
- File []*FileRecord
- Title string
- UserReference []*UserReferenceRecord
- AutomatedRecordId string
- Change ChangeRecord
- Note []*NoteRecord
- Citation []*CitationRecord
- UserDefined []UserDefinedTag
+ Xref string // Unique cross-reference identifier (e.g., "@M1@")
+ File []*FileRecord // File references for this media object
+ Title string // Title or description of the media
+ UserReference []*UserReferenceRecord // User-provided reference numbers
+ AutomatedRecordId string // Unique record ID assigned by the source system
+ Change ChangeRecord // Record of when this record was last modified
+ Note []*NoteRecord // Notes attached to this media
+ Citation []*CitationRecord // Source citations
+ UserDefined []UserDefinedTag // User-defined tags
}
+// FileRecord contains information about a multimedia file.
type FileRecord struct {
- Name string
- Format string
- FormatType string
- Title string
- UserDefined []UserDefinedTag
+ Name string // File path or URL
+ Format string // File format (e.g., "jpeg", "gif", "pdf")
+ FormatType string // Media type (e.g., "photo", "document")
+ Title string // Title or caption for this file
+ UserDefined []UserDefinedTag // User-defined tags
}
+// UserReferenceRecord contains a user-defined reference number for a record.
type UserReferenceRecord struct {
- Number string
- Type string
+ Number string // The reference number
+ Type string // The type of reference
}
+// ChangeRecord indicates when a record was last modified.
type ChangeRecord struct {
- Date string
- Time string
- Note []*NoteRecord
+ Date string // Date of the change in GEDCOM date format
+ Time string // Time of the change
+ Note []*NoteRecord // Notes about the change
}
+// RepositoryRecord represents a repository where source documents are held,
+// such as a library, archive, or private collection.
type RepositoryRecord struct {
- Xref string
- Name string
- Address AddressRecord
- Note []*NoteRecord
- UserReference []*UserReferenceRecord
- AutomatedRecordId string
- Change ChangeRecord
- UserDefined []UserDefinedTag
+ Xref string // Unique cross-reference identifier (e.g., "@R1@")
+ Name string // Name of the repository
+ Address AddressRecord // Address of the repository
+ Note []*NoteRecord // Notes about the repository
+ UserReference []*UserReferenceRecord // User-provided reference numbers
+ AutomatedRecordId string // Unique record ID assigned by the source system
+ Change ChangeRecord // Record of when this record was last modified
+ UserDefined []UserDefinedTag // User-defined tags
}
+// SourceRecord represents a source of genealogical information, such as
+// a book, document, website, or oral interview.
type SourceRecord struct {
- Xref string
- Title string
- Data *SourceDataRecord
- Originator string
- FiledBy string
- PublicationFacts string
- Text string
- Repository *SourceRepositoryRecord
- UserReference []*UserReferenceRecord
- AutomatedRecordId string
- Change ChangeRecord
- Note []*NoteRecord
- Media []*MediaRecord
- UserDefined []UserDefinedTag
+ Xref string // Unique cross-reference identifier (e.g., "@S1@")
+ Title string // Title of the source
+ Data *SourceDataRecord // Data recorded from the source
+ Originator string // Author or creator of the source
+ FiledBy string // Person who filed the source
+ PublicationFacts string // Publication information
+ Text string // Verbatim text from the source
+ Repository *SourceRepositoryRecord // Repository where the source is held
+ UserReference []*UserReferenceRecord // User-provided reference numbers
+ AutomatedRecordId string // Unique record ID assigned by the source system
+ Change ChangeRecord // Record of when this record was last modified
+ Note []*NoteRecord // Notes about the source
+ Media []*MediaRecord // Media objects (photos of documents, etc.)
+ UserDefined []UserDefinedTag // User-defined tags
}
+// SourceDataRecord contains data recorded from a source.
type SourceDataRecord struct {
- Event []*SourceEventRecord
+ Event []*SourceEventRecord // Events covered by the source
}
+// SourceEventRecord describes an event type covered by a source.
type SourceEventRecord struct {
- Kind string
- Date string
- Place string
+ Kind string // Type of event (e.g., "BIRT", "MARR", "DEAT")
+ Date string // Date range covered by the source
+ Place string // Place jurisdiction covered by the source
}
+// SourceRepositoryRecord links a source to its repository.
type SourceRepositoryRecord struct {
- Repository *RepositoryRecord
- Note []*NoteRecord
- CallNumber []*SourceCallNumberRecord
+ Repository *RepositoryRecord // The repository holding the source
+ Note []*NoteRecord // Notes about the source at this repository
+ CallNumber []*SourceCallNumberRecord // Call numbers for locating the source
}
+// SourceCallNumberRecord contains a call number for a source in a repository.
type SourceCallNumberRecord struct {
- CallNumber string
- MediaType string
+ CallNumber string // The call number or shelf location
+ MediaType string // Type of media (e.g., "book", "microfilm")
}
+// CitationRecord represents a citation to a source for a specific claim.
+// It links to a [SourceRecord] and provides details about where in the
+// source the information was found.
type CitationRecord struct {
- Source *SourceRecord
- Page string
- Data DataRecord
- Quay string
- Media []*MediaRecord
- Note []*NoteRecord
- UserDefined []UserDefinedTag
+ Source *SourceRecord // The source being cited
+ Page string // Page number or location within the source
+ Data DataRecord // Data extracted from the source
+ Quay string // Quality assessment (0-3, with 3 being direct evidence)
+ Media []*MediaRecord // Media objects (e.g., photo of the source page)
+ Note []*NoteRecord // Notes about this citation
+ UserDefined []UserDefinedTag // User-defined tags
}
+// SubmitterRecord contains information about the person or organization
+// that submitted the genealogical data.
type SubmitterRecord struct {
- Xref string
- Name string
- Address *AddressRecord
- Media []*MediaRecord
- Language []string
- SubmitterRecordFileID string
- AutomatedRecordId string
- Note []*NoteRecord
- Change *ChangeRecord
+ Xref string // Unique cross-reference identifier (e.g., "@SUBM1@")
+ Name string // Name of the submitter
+ Address *AddressRecord // Address of the submitter
+ Media []*MediaRecord // Media objects (e.g., photo of submitter)
+ Language []string // Languages used by the submitter
+ SubmitterRecordFileID string // Submitter record file identifier
+ AutomatedRecordId string // Unique record ID assigned by the source system
+ Note []*NoteRecord // Notes from the submitter
+ Change *ChangeRecord // Record of when this record was last modified
}
+// NameRecord represents a name for an individual. An individual may have
+// multiple names (e.g., maiden name, married name, aliases).
+// The Name field contains the full name in GEDCOM format: "Given Name /Surname/ Suffix".
+// Use [SplitPersonalName] to parse the Name field into components.
type NameRecord struct {
- Name string
- Type string
- NamePiecePrefix string
- NamePieceGiven string
- NamePieceNick string
- NamePieceSurnamePrefix string
- NamePieceSurname string
- NamePieceSuffix string
- Phonetic []*VariantNameRecord
- Romanized []*VariantNameRecord
- Citation []*CitationRecord
- Note []*NoteRecord
- UserDefined []UserDefinedTag
+ Name string // Full name in GEDCOM format (e.g., "John /Smith/ Jr.")
+ Type string // Name type (e.g., "birth", "married", "aka")
+ NamePiecePrefix string // Name prefix (e.g., "Dr.", "Rev.")
+ NamePieceGiven string // Given name(s)
+ NamePieceNick string // Nickname
+ NamePieceSurnamePrefix string // Surname prefix (e.g., "van", "de")
+ NamePieceSurname string // Surname
+ NamePieceSuffix string // Name suffix (e.g., "Jr.", "III")
+ Phonetic []*VariantNameRecord // Phonetic variants of the name
+ Romanized []*VariantNameRecord // Romanized variants of the name
+ Citation []*CitationRecord // Source citations for this name
+ Note []*NoteRecord // Notes about this name
+ UserDefined []UserDefinedTag // User-defined tags
}
+// VariantNameRecord represents a phonetic or romanized variant of a name.
type VariantNameRecord struct {
- Name string
- Type string
- NamePiecePrefix string
- NamePieceGiven string
- NamePieceNick string
- NamePieceSurnamePrefix string
- NamePieceSurname string
- NamePieceSuffix string
- Citation []*CitationRecord
- Note []*NoteRecord
+ Name string // Full variant name
+ Type string // Variant type (e.g., "kana", "hangul" for phonetic)
+ NamePiecePrefix string // Name prefix
+ NamePieceGiven string // Given name(s)
+ NamePieceNick string // Nickname
+ NamePieceSurnamePrefix string // Surname prefix
+ NamePieceSurname string // Surname
+ NamePieceSuffix string // Name suffix
+ Citation []*CitationRecord // Source citations
+ Note []*NoteRecord // Notes
}
+// DataRecord contains data extracted from a source citation.
type DataRecord struct {
- Date string
- Text []string
- UserDefined []UserDefinedTag
+ Date string // Date the data was recorded
+ Text []string // Verbatim text from the source
+ UserDefined []UserDefinedTag // User-defined tags
}
+// EventRecord represents an event or attribute in a person's or family's life.
+// Common event tags include BIRT (birth), DEAT (death), MARR (marriage),
+// BURI (burial), CHR (christening), DIV (divorce).
+// Common attribute tags include OCCU (occupation), RESI (residence),
+// EDUC (education), RELI (religion).
type EventRecord struct {
- Tag string
- Value string
- Type string
- Date string
- Place PlaceRecord
- Address AddressRecord
- Age string
- ResponsibleAgency string
- ReligiousAffiliation string
- Cause string
- RestrictionNotice string // 5.5.1
- ChildInFamily *FamilyRecord // link to parent family for birth events
- AdoptedByParent string // for adoption event, one of HUSB,WIFE,BOTH
- Citation []*CitationRecord
- Media []*MediaRecord
- Note []*NoteRecord
- UserDefined []UserDefinedTag
+ Tag string // Event type tag (e.g., "BIRT", "DEAT", "MARR")
+ Value string // Event value, often "Y" to indicate event occurred
+ Type string // Detailed event type for generic EVEN tags
+ Date string // Date in GEDCOM date format
+ Place PlaceRecord // Location where the event occurred
+ Address AddressRecord // Address associated with the event
+ Age string // Age of the individual at the time of the event
+ ResponsibleAgency string // Agency responsible for the record
+ ReligiousAffiliation string // Religious affiliation associated with event
+ Cause string // Cause (e.g., cause of death)
+ RestrictionNotice string // Privacy restriction (GEDCOM 5.5.1)
+ ChildInFamily *FamilyRecord // Link to parent family for birth events
+ AdoptedByParent string // For adoption: "HUSB", "WIFE", or "BOTH"
+ Citation []*CitationRecord // Source citations for this event
+ Media []*MediaRecord // Media objects (e.g., photos, certificates)
+ Note []*NoteRecord // Notes about this event
+ UserDefined []UserDefinedTag // User-defined tags
}
+// NoteRecord contains a note or comment attached to a record.
type NoteRecord struct {
- Note string
- Citation []*CitationRecord
+ Note string // The note text
+ Citation []*CitationRecord // Source citations for the note
}
+// PlaceRecord represents a geographic location. The Name field typically
+// contains a comma-separated jurisdiction hierarchy (e.g., "City, County, State, Country").
type PlaceRecord struct {
- Name string
- Phonetic []*VariantPlaceNameRecord
- Romanized []*VariantPlaceNameRecord
- Latitude string
- Longitude string
- Citation []*CitationRecord
- Note []*NoteRecord
+ Name string // Place name (jurisdiction hierarchy)
+ Phonetic []*VariantPlaceNameRecord // Phonetic variants of the place name
+ Romanized []*VariantPlaceNameRecord // Romanized variants of the place name
+ Latitude string // Latitude in GEDCOM format (e.g., "N50.9333")
+ Longitude string // Longitude in GEDCOM format (e.g., "W1.8")
+ Citation []*CitationRecord // Source citations
+ Note []*NoteRecord // Notes about the place
}
+// VariantPlaceNameRecord represents a phonetic or romanized variant of a place name.
type VariantPlaceNameRecord struct {
- Name string
- Type string
+ Name string // The variant place name
+ Type string // Variant type (e.g., "kana", "hangul" for phonetic)
}
+// FamilyLinkRecord links an individual to a family. It is used both for
+// linking children to their parents (via [IndividualRecord.Parents]) and
+// for linking spouses to their families (via [IndividualRecord.Family]).
type FamilyLinkRecord struct {
- Family *FamilyRecord
- Type string
- Note []*NoteRecord
+ Family *FamilyRecord // Pointer to the linked family
+ Type string // Relationship type (e.g., "birth", "adopted", "foster")
+ Note []*NoteRecord // Notes about this family link
}
// See https://www.tamurajones.net/GEDCOMADDR.xhtml for very informative analysis of the ADDR structure
@@ -306,9 +352,11 @@ type UserDefinedTag struct {
UserDefined []UserDefinedTag
}
+// AssociationRecord links an individual to another person with a defined
+// relationship, such as godparent, witness, or friend.
type AssociationRecord struct {
- Xref string
- Relation string
- Citation []*CitationRecord
- Note []*NoteRecord
+ Xref string // Cross-reference to the associated individual
+ Relation string // Relationship type (e.g., "godparent", "witness")
+ Citation []*CitationRecord // Source citations
+ Note []*NoteRecord // Notes about this association
}
From 665b9c02ee3e7d023ccbe00bc891dcb843d6bfe7 Mon Sep 17 00:00:00 2001
From: Ian Davis <18375+iand@users.noreply.github.com>
Date: Fri, 23 Jan 2026 14:37:32 +0000
Subject: [PATCH 2/2] gofmt
---
types.go | 120 +++++++++++++++++++++++++++----------------------------
1 file changed, 60 insertions(+), 60 deletions(-)
diff --git a/types.go b/types.go
index dd9b07c..a0a8ce5 100644
--- a/types.go
+++ b/types.go
@@ -64,57 +64,57 @@ type Trailer struct{}
// together as husband, wife, and children, and contains family events
// such as marriage, divorce, and census records.
type FamilyRecord struct {
- Xref string // Unique cross-reference identifier for this family (e.g., "@F1@")
- Husband *IndividualRecord // Pointer to the husband/father individual
- Wife *IndividualRecord // Pointer to the wife/mother individual
- Child []*IndividualRecord // Pointers to child individuals
- Event []*EventRecord // Family events (marriage, divorce, census, etc.)
+ Xref string // Unique cross-reference identifier for this family (e.g., "@F1@")
+ Husband *IndividualRecord // Pointer to the husband/father individual
+ Wife *IndividualRecord // Pointer to the wife/mother individual
+ Child []*IndividualRecord // Pointers to child individuals
+ Event []*EventRecord // Family events (marriage, divorce, census, etc.)
NumberOfChildren string // Total number of children, may differ from len(Child)
UserReference []*UserReferenceRecord // User-provided reference numbers
AutomatedRecordId string // Unique record ID assigned by the source system
Change ChangeRecord // Record of when this record was last modified
Note []*NoteRecord // Notes attached to this family
- Citation []*CitationRecord // Source citations for this family
- Media []*MediaRecord // Media objects (photos, documents) for this family
- UserDefined []UserDefinedTag // User-defined tags (prefixed with underscore)
+ Citation []*CitationRecord // Source citations for this family
+ Media []*MediaRecord // Media objects (photos, documents) for this family
+ UserDefined []UserDefinedTag // User-defined tags (prefixed with underscore)
}
// IndividualRecord represents a person in GEDCOM. It contains the person's
// names, sex, life events, attributes, and links to their families.
type IndividualRecord struct {
- Xref string // Unique cross-reference identifier (e.g., "@I1@")
- Name []*NameRecord // Names (may have multiple for maiden names, aliases)
- Sex string // Sex: "M" for male, "F" for female, "U" for unknown
- Event []*EventRecord // Life events (birth, death, burial, etc.)
- Attribute []*EventRecord // Attributes (occupation, residence, education, etc.)
- Parents []*FamilyLinkRecord // Links to families where this person is a child
- Family []*FamilyLinkRecord // Links to families where this person is a spouse
- Submitter []*SubmitterRecord // Submitters of this record
- Association []*AssociationRecord // Associations with other individuals
- PermanentRecordFileNumber string // Permanent record file number
+ Xref string // Unique cross-reference identifier (e.g., "@I1@")
+ Name []*NameRecord // Names (may have multiple for maiden names, aliases)
+ Sex string // Sex: "M" for male, "F" for female, "U" for unknown
+ Event []*EventRecord // Life events (birth, death, burial, etc.)
+ Attribute []*EventRecord // Attributes (occupation, residence, education, etc.)
+ Parents []*FamilyLinkRecord // Links to families where this person is a child
+ Family []*FamilyLinkRecord // Links to families where this person is a spouse
+ Submitter []*SubmitterRecord // Submitters of this record
+ Association []*AssociationRecord // Associations with other individuals
+ PermanentRecordFileNumber string // Permanent record file number
AncestralFileNumber string // Ancestral file number
UserReference []*UserReferenceRecord // User-provided reference numbers
AutomatedRecordId string // Unique record ID assigned by the source system
Change ChangeRecord // Record of when this record was last modified
Note []*NoteRecord // Notes attached to this individual
- Citation []*CitationRecord // Source citations for this individual
- Media []*MediaRecord // Media objects (photos, documents)
- UserDefined []UserDefinedTag // User-defined tags (prefixed with underscore)
+ Citation []*CitationRecord // Source citations for this individual
+ Media []*MediaRecord // Media objects (photos, documents)
+ UserDefined []UserDefinedTag // User-defined tags (prefixed with underscore)
}
// MediaRecord represents a multimedia object such as a photo, document,
// or audio/video recording. It can be referenced by individuals, families,
// events, and sources.
type MediaRecord struct {
- Xref string // Unique cross-reference identifier (e.g., "@M1@")
- File []*FileRecord // File references for this media object
+ Xref string // Unique cross-reference identifier (e.g., "@M1@")
+ File []*FileRecord // File references for this media object
Title string // Title or description of the media
UserReference []*UserReferenceRecord // User-provided reference numbers
AutomatedRecordId string // Unique record ID assigned by the source system
Change ChangeRecord // Record of when this record was last modified
Note []*NoteRecord // Notes attached to this media
- Citation []*CitationRecord // Source citations
- UserDefined []UserDefinedTag // User-defined tags
+ Citation []*CitationRecord // Source citations
+ UserDefined []UserDefinedTag // User-defined tags
}
// FileRecord contains information about a multimedia file.
@@ -142,9 +142,9 @@ type ChangeRecord struct {
// RepositoryRecord represents a repository where source documents are held,
// such as a library, archive, or private collection.
type RepositoryRecord struct {
- Xref string // Unique cross-reference identifier (e.g., "@R1@")
- Name string // Name of the repository
- Address AddressRecord // Address of the repository
+ Xref string // Unique cross-reference identifier (e.g., "@R1@")
+ Name string // Name of the repository
+ Address AddressRecord // Address of the repository
Note []*NoteRecord // Notes about the repository
UserReference []*UserReferenceRecord // User-provided reference numbers
AutomatedRecordId string // Unique record ID assigned by the source system
@@ -167,8 +167,8 @@ type SourceRecord struct {
AutomatedRecordId string // Unique record ID assigned by the source system
Change ChangeRecord // Record of when this record was last modified
Note []*NoteRecord // Notes about the source
- Media []*MediaRecord // Media objects (photos of documents, etc.)
- UserDefined []UserDefinedTag // User-defined tags
+ Media []*MediaRecord // Media objects (photos of documents, etc.)
+ UserDefined []UserDefinedTag // User-defined tags
}
// SourceDataRecord contains data recorded from a source.
@@ -185,9 +185,9 @@ type SourceEventRecord struct {
// SourceRepositoryRecord links a source to its repository.
type SourceRepositoryRecord struct {
- Repository *RepositoryRecord // The repository holding the source
- Note []*NoteRecord // Notes about the source at this repository
- CallNumber []*SourceCallNumberRecord // Call numbers for locating the source
+ Repository *RepositoryRecord // The repository holding the source
+ Note []*NoteRecord // Notes about the source at this repository
+ CallNumber []*SourceCallNumberRecord // Call numbers for locating the source
}
// SourceCallNumberRecord contains a call number for a source in a repository.
@@ -217,10 +217,10 @@ type SubmitterRecord struct {
Address *AddressRecord // Address of the submitter
Media []*MediaRecord // Media objects (e.g., photo of submitter)
Language []string // Languages used by the submitter
- SubmitterRecordFileID string // Submitter record file identifier
- AutomatedRecordId string // Unique record ID assigned by the source system
- Note []*NoteRecord // Notes from the submitter
- Change *ChangeRecord // Record of when this record was last modified
+ SubmitterRecordFileID string // Submitter record file identifier
+ AutomatedRecordId string // Unique record ID assigned by the source system
+ Note []*NoteRecord // Notes from the submitter
+ Change *ChangeRecord // Record of when this record was last modified
}
// NameRecord represents a name for an individual. An individual may have
@@ -270,23 +270,23 @@ type DataRecord struct {
// Common attribute tags include OCCU (occupation), RESI (residence),
// EDUC (education), RELI (religion).
type EventRecord struct {
- Tag string // Event type tag (e.g., "BIRT", "DEAT", "MARR")
- Value string // Event value, often "Y" to indicate event occurred
- Type string // Detailed event type for generic EVEN tags
- Date string // Date in GEDCOM date format
- Place PlaceRecord // Location where the event occurred
- Address AddressRecord // Address associated with the event
- Age string // Age of the individual at the time of the event
- ResponsibleAgency string // Agency responsible for the record
- ReligiousAffiliation string // Religious affiliation associated with event
- Cause string // Cause (e.g., cause of death)
- RestrictionNotice string // Privacy restriction (GEDCOM 5.5.1)
- ChildInFamily *FamilyRecord // Link to parent family for birth events
- AdoptedByParent string // For adoption: "HUSB", "WIFE", or "BOTH"
+ Tag string // Event type tag (e.g., "BIRT", "DEAT", "MARR")
+ Value string // Event value, often "Y" to indicate event occurred
+ Type string // Detailed event type for generic EVEN tags
+ Date string // Date in GEDCOM date format
+ Place PlaceRecord // Location where the event occurred
+ Address AddressRecord // Address associated with the event
+ Age string // Age of the individual at the time of the event
+ ResponsibleAgency string // Agency responsible for the record
+ ReligiousAffiliation string // Religious affiliation associated with event
+ Cause string // Cause (e.g., cause of death)
+ RestrictionNotice string // Privacy restriction (GEDCOM 5.5.1)
+ ChildInFamily *FamilyRecord // Link to parent family for birth events
+ AdoptedByParent string // For adoption: "HUSB", "WIFE", or "BOTH"
Citation []*CitationRecord // Source citations for this event
- Media []*MediaRecord // Media objects (e.g., photos, certificates)
- Note []*NoteRecord // Notes about this event
- UserDefined []UserDefinedTag // User-defined tags
+ Media []*MediaRecord // Media objects (e.g., photos, certificates)
+ Note []*NoteRecord // Notes about this event
+ UserDefined []UserDefinedTag // User-defined tags
}
// NoteRecord contains a note or comment attached to a record.
@@ -298,13 +298,13 @@ type NoteRecord struct {
// PlaceRecord represents a geographic location. The Name field typically
// contains a comma-separated jurisdiction hierarchy (e.g., "City, County, State, Country").
type PlaceRecord struct {
- Name string // Place name (jurisdiction hierarchy)
- Phonetic []*VariantPlaceNameRecord // Phonetic variants of the place name
- Romanized []*VariantPlaceNameRecord // Romanized variants of the place name
- Latitude string // Latitude in GEDCOM format (e.g., "N50.9333")
- Longitude string // Longitude in GEDCOM format (e.g., "W1.8")
- Citation []*CitationRecord // Source citations
- Note []*NoteRecord // Notes about the place
+ Name string // Place name (jurisdiction hierarchy)
+ Phonetic []*VariantPlaceNameRecord // Phonetic variants of the place name
+ Romanized []*VariantPlaceNameRecord // Romanized variants of the place name
+ Latitude string // Latitude in GEDCOM format (e.g., "N50.9333")
+ Longitude string // Longitude in GEDCOM format (e.g., "W1.8")
+ Citation []*CitationRecord // Source citations
+ Note []*NoteRecord // Notes about the place
}
// VariantPlaceNameRecord represents a phonetic or romanized variant of a place name.