Esempio n. 1
0
        public static ParseResult <Image> Parse(GedcomLine first, ILineProvider lineProvider)
        {
            var image = new Image();

            image.ID = ParserHelper.ParseID(first.GetFirstItem()).ToString();

            var initialLevel = first.Level;

            GedcomLine          line = default;
            ReadOnlySpan <char> currentRawLine;

            while ((currentRawLine = lineProvider.ReadLine()) != null)
            {
                line = ParserHelper.ParseLine(currentRawLine);

                if (line.Level == first.Level)
                {
                    break;
                }

                var splitLine = line.GetFirstItem();
                if (ParserHelper.Equals(splitLine, "TITL"))
                {
                    var title = line.GetLineContent(4);
                    image.Title = title.ToString();
                }
                else if (ParserHelper.Equals(splitLine, "FILE"))
                {
                    var filePath = line.GetLineContent(4);
                    image.FilePath = filePath.ToString();
                }
            }

            return(ParseResult.Create(image, line));
        }
Esempio n. 2
0
        private static void ParseNames(GedcomLine gedcomLine, Individual individual)
        {
            individual.FirstName  = string.Empty;
            individual.FirstNames = string.Empty;

            var content = gedcomLine.GetLineContent();

            // If there are no slashes to indicate surname, assume that the last entry is the surname
            int lastNameStart = content.IndexOf("/", StringComparison.Ordinal);

            if (lastNameStart != -1)
            {
                var preLine = content.Slice(0, lastNameStart).Trim();

                var    remainingLine      = content.Slice(lastNameStart + 1, content.Length - lastNameStart - 1);
                int    trailingSlashStart = remainingLine.IndexOf("/", StringComparison.Ordinal);
                string lastName;
                if (trailingSlashStart != -1)
                {
                    lastName = remainingLine.Slice(0, trailingSlashStart).ToString();
                }
                else
                {
                    lastName = remainingLine.ToString();
                }
                individual.LastName = lastName;

                var firstNames = preLine.ToString();
                individual.FirstNames = firstNames;
                var indexOfSpace = preLine.IndexOf(' ');
                individual.FirstName = (indexOfSpace == -1) ? firstNames : preLine.Slice(0, indexOfSpace).ToString();
            }
            else
            {
                var indexOfLast = content.LastIndexOf(' ');
                if (indexOfLast != -1)
                {
                    individual.LastName = content.Slice(indexOfLast + 1, content.Length - indexOfLast - 1).ToString();

                    var firstNamesSlice = content.Slice(0, indexOfLast);
                    var firstNames      = firstNamesSlice.ToString();
                    individual.FirstNames = firstNames;
                    var indexOfSpace = firstNamesSlice.IndexOf(' ');
                    individual.FirstName = (indexOfSpace == -1)
                        ? firstNames
                        : firstNamesSlice.Slice(0, indexOfSpace).ToString();
                }
                else
                {
                    individual.LastName = content.ToString();
                }
            }
        }
Esempio n. 3
0
        public static ParseResult <GedcomEvent> Parse(GedcomLine first, ILineProvider lineProvider)
        {
            GedcomEvent gedcomEvent = new GedcomEvent();

            var initialLevel = first.Level;

            GedcomLine          line = default;
            ReadOnlySpan <char> currentRawLine;

            while ((currentRawLine = lineProvider.ReadLine()).Length > 0)
            {
                line = ParserHelper.ParseLine(currentRawLine);

                if (line.Level <= first.Level)
                {
                    break;
                }

                ReadOnlySpan <char> tag = line.GetFirstItem();
                if (ParserHelper.Equals(tag, "DATE"))
                {
                    // If checks we're parsing actual date and not
                    // CREA or CHAN tags
                    // TODO: should actually put CREA and CHAN into different parser
                    if (line.Level == initialLevel + 1)
                    {
                        var dateContent = line.GetLineContent(4);
                        gedcomEvent.Date = dateContent.Length == 0 ? null : dateContent.ToString();
                    }
                }
                else if (ParserHelper.Equals(tag, "PLAC"))
                {
                    // If checks we're parsing actual date and not
                    // CREA or CHAN tags
                    // TODO: should actually put CREA and CHAN into different parser
                    if (line.Level == initialLevel + 1)
                    {
                        var placContent = line.GetLineContent(4);
                        gedcomEvent.Location = placContent.Length == 0 ? null : placContent.ToString();
                    }
                }
            }

            return(ParseResult.Create(gedcomEvent, line));
        }
Esempio n. 4
0
        public static ParseResult <Note> Parse(GedcomLine first, ILineProvider lineProvider)
        {
            string id   = ParserHelper.ParseID(first.GetFirstItem()).ToString();
            string text = null;

            var initialLevel = first.Level;

            GedcomLine          line = default;
            ReadOnlySpan <char> currentRawLine;

            while ((currentRawLine = lineProvider.ReadLine()).Length > 0)
            {
                line = ParserHelper.ParseLine(currentRawLine);

                if (line.Level == first.Level)
                {
                    break;
                }

                ReadOnlySpan <char> tag = line.GetFirstItem();

                if (ParserHelper.Equals(tag, "CONT"))
                {
                    string contText = line.GetLineContent(4).ToString();
                    text += Environment.NewLine + contText;
                }
                else if (ParserHelper.Equals(tag, "CONC"))
                {
                    // TODO: is GenesReunited maintaining the trailing space?
                    // If so, is this correct?
                    string concText = line.GetLineContent(4).ToString();
                    text += concText;
                }
            }

            return(ParseResult.Create(new Note(id, text), line));
        }
Esempio n. 5
0
        public static ParseResult <Family> Parse(GedcomLine first, ILineProvider lineProvider)
        {
            var family = new Family();

            family.ID = ParserHelper.ParseID(first.GetFirstItem()).ToString();

            bool inMarriage = false;

            var initialLevel = first.Level;

            GedcomLine          line = default;
            ReadOnlySpan <char> currentRawLine;

            while ((currentRawLine = lineProvider.ReadLine()).Length > 0)
            {
                line = ParserHelper.ParseLine(currentRawLine);

                if (line.Level == first.Level)
                {
                    break;
                }

                var tag = line.GetFirstItem();

                if (ParserHelper.Equals(tag, "MARR"))
                {
                    inMarriage = true;
                }
                else if (ParserHelper.Equals(tag, "DATE"))
                {
                    if (inMarriage) // TODO: should have MARR parser
                    {
                        var date = line.GetLineContent(4);
                        if (family.Marriage == null)
                        {
                            family.Marriage = new GedcomEvent();
                        }
                        family.Marriage.Date = date.ToString();
                    }
                }
                else if (ParserHelper.Equals(tag, "PLAC"))
                {
                    if (inMarriage) // Assume level + 1 is MARR
                    {
                        var place = line.GetLineContent(4);
                        if (family.Marriage == null)
                        {
                            family.Marriage = new GedcomEvent();
                        }
                        family.Marriage.Location = place.ToString();
                    }
                }
                else if (ParserHelper.Equals(tag, "HUSB"))
                {
                    // Ignore any husband and wife information in the middle of a marriage tag.
                    // Present for torture test files - and info redundant?
                    // can have e.g. "2 HUSB", with no additional info
                    var husbContent = line.GetLineContent(4);
                    if (husbContent.Length > 0)
                    {
                        family.HusbandID = ParserHelper.ParseID(husbContent).ToString();
                    }
                }
                else if (ParserHelper.Equals(tag, "WIFE"))
                {
                    var wifeContent = line.GetLineContent(4);
                    // Ignore any husband and wife information in the middle of a marriage tag.
                    // Present for torture test files - and info redundant?
                    // can have e.g. "2 HUSB", with no additional info
                    if (wifeContent.Length > 0)
                    {
                        family.WifeID = ParserHelper.ParseID(wifeContent).ToString();
                    }
                }
                else if (ParserHelper.Equals(tag, "CHIL"))
                {
                    var childContent = line.GetLineContent(4);
                    family.ChildIDs.Add(ParserHelper.ParseID(childContent).ToString());
                }
                else
                {
                    inMarriage = false;
                }
            }

            return(ParseResult.Create(family, line));
        }
Esempio n. 6
0
        public static ParseResult <Individual> Parse(GedcomLine first, ILineProvider lineProvider)
        {
            var individual = new Individual();

            individual.ID = ParserHelper.ParseID(first.GetFirstItem()).ToString();

            GedcomLine          line = default;
            ReadOnlySpan <char> currentRawLine;
            var newLine = false;

            while (true)
            {
                // TODO: this loop is really messy, as some of the parsing
                //  works on lines as retrieved from the parser, where some
                //  other iterations call onto a sub-parser which return a final
                //  line. Should split this logic
                if (!newLine)
                {
                    currentRawLine = lineProvider.ReadLine();
                    if (currentRawLine == null)
                    {
                        break;
                    }
                    line = ParserHelper.ParseLine(currentRawLine);
                }
                newLine = false;

                if (line.Level == 0)
                {
                    break;
                }

                var tag = line.GetFirstItem();
                if (ParserHelper.Equals(tag, "NAME") &&
                    individual.LastName == null && individual.FirstNames == null)
                {
                    ParseNames(line, individual);
                }
                else if (ParserHelper.Equals(tag, "SEX"))
                {
                    individual.Gender = ParserHelper.Equals(line.GetLineContent(3), "M") ? Gender.Male : Gender.Female;
                }
                else if (ParserHelper.Equals(tag, "FAMS"))
                {
                    individual.FamilyIDSpouse = ParserHelper.ParseID(line.GetLineContent(4)).ToString();
                }
                else if (ParserHelper.Equals(tag, "FAMC"))
                {
                    individual.FamilyIDChild = ParserHelper.ParseID(line.GetLineContent(4)).ToString();
                }

                else if (ParserHelper.Equals(tag, "OBJE"))
                {
                    var content = line.GetLineContent(4);
                    if (content.Length > 0)
                    {
                        individual.ImageID = ParserHelper.ParseID(content).ToString();
                    }
                }
                else if (ParserHelper.Equals(tag, "NOTE"))
                {
                    var noteContent = line.GetLineContent(4);
                    if (noteContent.Length > 0)
                    {
                        if (noteContent[0] == '@')
                        {
                            individual.NoteID = ParserHelper.ParseID(noteContent).ToString();
                        }
                        else
                        {
                            individual.Note = noteContent.ToString();
                        }
                    }
                }
                else if (ParserHelper.Equals(tag, "CONT"))
                {
                    var contContent = line.GetLineContent(4);
                    individual.Note += Environment.NewLine + contContent.ToString();
                }
                else if (ParserHelper.Equals(tag, "CONC"))
                {
                    // TODO: is GenesReunited maintaining the trailing space?
                    // If so, is this correct?
                    var concContent = line.GetLineContent(4);
                    if (concContent.Length > 0)
                    {
                        individual.Note += concContent.ToString();
                    }
                }
                else if (ParserHelper.Equals(tag, "BIRT"))
                {
                    var birthParseResult = EventParser.Parse(line, lineProvider);
                    if (individual.Birth == null)
                    {
                        individual.Birth = birthParseResult.Result;
                    }
                    line    = birthParseResult.Line;
                    newLine = true;
                }
                else if (ParserHelper.Equals(tag, "DEAT"))
                {
                    var deathParseResult = EventParser.Parse(line, lineProvider);
                    if (individual.Death == null)
                    {
                        individual.Death = deathParseResult.Result;
                    }
                    line    = deathParseResult.Line;
                    newLine = true;
                }
                else if (ParserHelper.Equals(tag, "BAPM"))
                {
                    var baptismParseResult = EventParser.Parse(line, lineProvider);
                    if (individual.Baptism == null)
                    {
                        individual.Baptism = baptismParseResult.Result;
                    }
                    line    = baptismParseResult.Line;
                    newLine = true;
                }
                else if (ParserHelper.Equals(tag, "RESI"))
                {
                    var residenceParseResult = EventParser.Parse(line, lineProvider);
                    individual.Residences.Add(residenceParseResult.Result);
                    line    = residenceParseResult.Line;
                    newLine = true;
                }
                else if (ParserHelper.Equals(tag, "CENS"))
                {
                    var censusParseResult = EventParser.Parse(line, lineProvider);
                    individual.Census.Add(censusParseResult.Result);
                    line    = censusParseResult.Line;
                    newLine = true;
                }
                else if (ParserHelper.Equals(tag, "MARR"))
                {
                    var marriageParseResult = EventParser.Parse(line, lineProvider);
                    if (marriageParseResult.Result != null)
                    {
                        individual.Marriages.Add(marriageParseResult.Result);
                    }
                    line    = marriageParseResult.Line;
                    newLine = true;
                    // TODO: cope with multiple marriage records
                    // It seems that ancestry only outputs multiple marriage records in an individual
                    //  if there's conflicting information, not for multiple marriages
                    // Multiple marriages for an individual are put into the FAMs tag
                }
                //case "ENGA":
                //    // TODO:
                //    // individual.Engagement = EventParser.Parse(parserLinesEnga);
                //    break;

                if (line.Level == 0)
                {
                    break;
                }
            }

            if (individual.LastName == null)
            {
                individual.LastName = string.Empty;
            }

            if (individual.FirstName == null)
            {
                individual.FirstName = string.Empty;
            }

            if (individual.FirstNames == null)
            {
                individual.FirstNames = string.Empty;
            }

            return(ParseResult.Create(individual, line));
        }
Esempio n. 7
0
        public static ParseResult <GedcomHeader> Parse(GedcomLine first, ILineProvider lineProvider)
        {
            CurrentLevel currentLevel = CurrentLevel.None;

            var header = new GedcomHeader();

            GedcomLine          line = default;
            ReadOnlySpan <char> currentRawLine;

            while ((currentRawLine = lineProvider.ReadLine()).Length > 0)
            {
                line = ParserHelper.ParseLine(currentRawLine);

                if (line.Level == 0)
                {
                    break;
                }

                if (line.Level == 1)
                {
                    var tag = line.GetFirstItem();
                    if (ParserHelper.Equals(tag, "SOUR"))
                    {
                        currentLevel = CurrentLevel.Sour;
                    }
                    else if (ParserHelper.Equals(tag, "GEDC"))
                    {
                        currentLevel = CurrentLevel.Gedc;
                    }
                    else if (ParserHelper.Equals(tag, "CHAR"))
                    {
                        header.GedcomCharacterSet = line.GetLineContent(4).ToString();
                    }
                }
                else if (line.Level == 2)
                {
                    if (currentLevel == CurrentLevel.Sour)
                    {
                        var tag = line.GetFirstItem();
                        if (ParserHelper.Equals(tag, "NAME"))
                        {
                            header.SourceName = line.GetLineContent(4).ToString();
                        }
                        else if (ParserHelper.Equals(tag, "VERS"))
                        {
                            header.SourceVers = line.GetLineContent(4).ToString();
                        }
                        else if (ParserHelper.Equals(tag, "CORP"))
                        {
                            header.SourceCorp = line.GetLineContent(4).ToString();
                        }
                    }
                    else if (currentLevel == CurrentLevel.Gedc)
                    {
                        if (ParserHelper.Equals(line.GetFirstItem(), "VERS"))
                        {
                            header.GedcomVers = line.GetLineContent(4).ToString();
                        }
                    }
                }
            }

            return(ParseResult.Create(header, line));
        }