public BookSpecAndNames(BookSpec bookSpec, string name)
 {
     Guard.Against.Null(bookSpec, nameof(bookSpec));
     BookSpec = bookSpec;
     Guard.Against.Null(name, nameof(name));
     Names.Add(name);
 }
 public BookSpecAndNames(BookSpec bookSpec, IEnumerable <string> names)
 {
     Guard.Against.Null(bookSpec, nameof(bookSpec));
     BookSpec = bookSpec;
     Guard.Against.NullOrEmpty(names, nameof(names));
     Names.AddRange(names);
 }
Exemple #3
0
        public BookSpec ParseBook(string text, List <ParseError> errors)
        {
            List <BookSpecAndNames> matches = FilterBooks(text);

            if (matches.Count == 0)
            {
                errors.Add(new ParseError(text, "No matching books"));
                return(null);
            }
            BookSpec      bookSpec = matches[0].BookSpec;
            StringBuilder sb       = new StringBuilder(matches[0].Names[0]);
            bool          multiple = false;

            for (int i = 0; i < matches.Count; i++)
            {
                if (matches[i].BookSpec != bookSpec)
                {
                    sb.Append(", ");
                    sb.Append(matches[i].Names[0]);
                    bookSpec = matches[i].BookSpec;
                    multiple = true;
                }
            }
            if (multiple)
            {
                errors.Add(new ParseError(text, "Multiple matches: " +
                                          sb.ToString()));
                return(null);
            }
            else
            {
                return(bookSpec);
            }
        }
Exemple #4
0
 private void AddBookAndName(List <BookSpecAndNames> matches,
                             ref BookSpecAndNames last, BookSpec book, string name)
 {
     if (last?.BookSpec == book)
     {
         last.Names.Add(name);
     }
     else
     {
         last = new BookSpecAndNames(book, name);
         matches.Add(last);
     }
 }
Exemple #5
0
        public BookAndChapterSpec ParseBookAndChapter(string text, EndpointType type, List <ParseError> errors)
        {
            Match match = Regex.Match(text, @"^\s*(\d*\s*\p{L}+)\s*(\d+)*\s*$");

            if (!match.Success)
            {
                errors.Add(new ParseError(text, "Not a book/book+chapter"));
                return(null);
            }
            string   bookSearchText = match.Groups[1].Value;
            BookSpec bookSpec       = ParseBook(bookSearchText, errors);

            if (bookSpec == null)
            {
                return(null);
            }
            if (!match.Groups[2].Success)
            {
                int chapterNumber = 1;
                if (type == EndpointType.End)
                {
                    chapterNumber = bookSpec.ChapterCount;
                }
                return(new BookAndChapterSpec(this, bookSpec.Names[0], chapterNumber));
            }
            else
            {
                string strval        = match.Groups[2].Value;
                int    chapterNumber = int.Parse(strval);
                if (chapterNumber < 1 || chapterNumber > bookSpec.ChapterCount)
                {
                    errors.Add(new ParseError(strval, "Chapter number out of range"));
                    return(null);
                }
                return(new BookAndChapterSpec(this, bookSpec.Names[0], chapterNumber));
            }
        }
Exemple #6
0
        public SectionSpec ParseSingleBookRange(string text, List <ParseError> errors)
        {
            Match match = Regex.Match(text, @"^\s*(\d*\s*\p{L}+)\s*((\d+)(\s*-\s*(\d+))*)*\s*$");

            if (!match.Success)
            {
                errors.Add(new ParseError(text, "Not a single book range"));
                return(null);
            }
            string   bookSearchText = match.Groups[1].Value;
            BookSpec bookSpec       = ParseBook(bookSearchText, errors);

            if (bookSpec == null)
            {
                return(null);
            }
            string bookName = bookSpec.Names[0];

            if (!match.Groups[2].Success)
            {
                // just book specified
                BookAndChapterSpec start = new BookAndChapterSpec(this, bookName, 1);
                BookAndChapterSpec end   = new BookAndChapterSpec(this, bookName, bookSpec.ChapterCount);
                return(new SectionSpec(start, end));
            }
            else if (!match.Groups[4].Success)
            {
                // just book and chapter specified
                string strval        = match.Groups[3].Value;
                int    chapterNumber = int.Parse(strval);
                if (chapterNumber < 1 || chapterNumber > bookSpec.ChapterCount)
                {
                    errors.Add(new ParseError(strval, "Chapter number out of range"));
                    return(null);
                }
                BookAndChapterSpec startAndEnd = new BookAndChapterSpec(this, bookName, chapterNumber);
                return(new SectionSpec(startAndEnd, startAndEnd));
            }
            else if (match.Groups[5].Success)
            {
                bool   valid        = true;
                string startString  = match.Groups[3].Value;
                int    startChapter = int.Parse(startString);
                if (startChapter < 1 || startChapter > bookSpec.ChapterCount)
                {
                    errors.Add(new ParseError(startString, "Start chapter number out of range"));
                    valid = false;
                }
                string endString  = match.Groups[5].Value;
                int    endChapter = int.Parse(endString);
                if (endChapter < 1 || endChapter > bookSpec.ChapterCount)
                {
                    errors.Add(new ParseError(endString, "End chapter number out of range"));
                    valid = false;
                }
                if (!valid)
                {
                    return(null);
                }
                BookAndChapterSpec start = new BookAndChapterSpec(this, bookName, startChapter);
                BookAndChapterSpec end   = new BookAndChapterSpec(this, bookName, endChapter);
                return(new SectionSpec(start, end));
            }
            return(null);
        }
Exemple #7
0
        public SectionParseResult ParseSection(string text)
        {
            List <ParseError> errors = new List <ParseError>();
            SectionSpec       spec   = null;

            if (text.Contains("-"))
            {
                string[] pieces = text.Split("-");
                if (pieces.Length > 2)
                {
                    errors.Add(new ParseError(text, "Too many dashes"));
                }
                if (Regex.IsMatch(pieces[1], @"[^\d\s]"))
                {
                    // two separate books
                    BookAndChapterSpec start = ParseBookAndChapter(pieces[0],
                                                                   EndpointType.Start, errors);
                    BookAndChapterSpec end = ParseBookAndChapter(pieces[1],
                                                                 EndpointType.End, errors);
                    if (start != null && end != null)
                    {
                        spec = new SectionSpec(start, end);
                    }
                }
                else if (pieces.Length == 2)
                {
                    // single book range
                    spec = ParseSingleBookRange(text, errors);
                }
            }
            else
            {
                if (Regex.IsMatch(text, @"\d\s*$"))
                {
                    BookAndChapterSpec start = ParseBookAndChapter(text, EndpointType.Start, errors);
                    spec = new SectionSpec(start, start);
                }
                else
                {
                    BookSpec book = ParseBook(text, errors);
                    if (book != null)
                    {
                        BookAndChapterSpec start = new BookAndChapterSpec(this, book.Names[0], 1);
                        BookAndChapterSpec end   = new BookAndChapterSpec(this, book.Names[0], book.ChapterCount);
                        spec = new SectionSpec(start, end);
                    }
                }
            }
            if (spec != null)
            {
                ValidateSectionSpec(text, spec, errors);
            }
            if (errors.Count > 0)
            {
                return(new SectionParseResult(null, errors));
            }
            else
            {
                return(new SectionParseResult(spec, errors));
            }
        }