private IEnumerable <CharacterDetail> GetStandardCharacters() { var list = new List <CharacterDetail>(); for (int booknum = 1; booknum <= BCVRef.LastBook; booknum++) { string bookCode = BCVRef.NumberToBookCode(booknum); list.Add(new CharacterDetail { CharacterId = CharacterVerseData.GetStandardCharacterId(bookCode, CharacterVerseData.StandardCharacter.Narrator), Gender = CharacterGender.Neuter, StandardCharacterType = CharacterVerseData.StandardCharacter.Narrator, Status = true }); list.Add(new CharacterDetail { CharacterId = CharacterVerseData.GetStandardCharacterId(bookCode, CharacterVerseData.StandardCharacter.BookOrChapter), Gender = CharacterGender.Neuter, StandardCharacterType = CharacterVerseData.StandardCharacter.BookOrChapter }); list.Add(new CharacterDetail { CharacterId = CharacterVerseData.GetStandardCharacterId(bookCode, CharacterVerseData.StandardCharacter.ExtraBiblical), Gender = CharacterGender.Neuter, StandardCharacterType = CharacterVerseData.StandardCharacter.ExtraBiblical }); list.Add(new CharacterDetail { CharacterId = CharacterVerseData.GetStandardCharacterId(bookCode, CharacterVerseData.StandardCharacter.Intro), Gender = CharacterGender.Neuter, StandardCharacterType = CharacterVerseData.StandardCharacter.Intro }); } return(list); }
public virtual void AddEntriesFor(int bookNumber, Block block) { bool added = false; foreach (var verse in block.AllVerses) { if (!ControlCharacterVerseData.Singleton.GetCharacters(bookNumber, block.ChapterNumber, verse, m_versification, true, true) .Any(c => c.Character == block.CharacterId && c.Delivery == (block.Delivery ?? Empty))) { foreach (var v in verse.AllVerseNumbers) { var verseRef = new VerseRef(bookNumber, block.ChapterNumber, v, m_versification); verseRef.ChangeVersification(ScrVers.English); added |= base.AddCharacterVerse(new CharacterVerse(verseRef.BBBCCCVVV, block.CharacterId, block.Delivery ?? Empty, Empty, true)); } } } if (added) { Analytics.Track("AddCharacter", new Dictionary <string, string> { { "verseReference", block.GetReferenceString(BCVRef.NumberToBookCode(bookNumber)) }, { "characterId", block.CharacterId }, { "delivery", block.Delivery } }); } }
private IEnumerable <string> GetUniqueOtNtBooks() { var books = new SortedSet <string>(Comparer <string> .Create((a, b) => BCVRef.BookToNumber(a).CompareTo(BCVRef.BookToNumber(b)))); foreach (Verse reference in References) { var bcvRef = new BCVRef(reference.VerseText); if (bcvRef.BookIsValid) { books.Add(BCVRef.NumberToBookCode(bcvRef.Book)); } else if (Char.IsLetter(reference.VerseText.Last())) { bcvRef = new BCVRef(reference.VerseText.Substring(0, reference.VerseText.Length - 1)); if (bcvRef.BookIsValid) { books.Add(BCVRef.NumberToBookCode(bcvRef.Book)); } else { Debug.Fail(reference.VerseText); } } else { Debug.Fail(reference.VerseText); } } return(books); }
private void AddStandardCharacters(List <CharacterDetail> list) { for (int booknum = 1; booknum <= BCVRef.LastBook; booknum++) { string bookCode = BCVRef.NumberToBookCode(booknum); list.Add(new CharacterDetail { CharacterId = CharacterVerseData.GetStandardCharacterId(bookCode, CharacterVerseData.StandardCharacter.Narrator), Gender = CharacterGender.Neuter, StandardCharacterType = CharacterVerseData.StandardCharacter.Narrator, //Status = true }); list.Add(new CharacterDetail { CharacterId = CharacterVerseData.GetStandardCharacterId(bookCode, CharacterVerseData.StandardCharacter.BookOrChapter), Gender = CharacterGender.Neuter, StandardCharacterType = CharacterVerseData.StandardCharacter.BookOrChapter }); list.Add(new CharacterDetail { CharacterId = CharacterVerseData.GetStandardCharacterId(bookCode, CharacterVerseData.StandardCharacter.ExtraBiblical), Gender = CharacterGender.Neuter, StandardCharacterType = CharacterVerseData.StandardCharacter.ExtraBiblical }); list.Add(new CharacterDetail { CharacterId = CharacterVerseData.GetStandardCharacterId(bookCode, CharacterVerseData.StandardCharacter.Intro), Gender = CharacterGender.Neuter, StandardCharacterType = CharacterVerseData.StandardCharacter.Intro }); } }
private static IEnumerable <Question> GetTrailingCustomizations(int bookNum, SortedDictionary <QuestionKey, Customizations> customizations, Question lastQuestionInBook, Category category, int iQuestion) { if (customizations != null) { Debug.Assert(lastQuestionInBook != null && iQuestion > 0 && category != null, $"Book {BCVRef.NumberToBookCode(bookNum)} has no built-in questions - cannot process customizations!"); while (customizations.Any(c => c.Value.IsAdditionOrInsertion)) { var insertionForPreviousReference = customizations.FirstOrDefault(c => c.Value.IsAdditionOrInsertion && customizations.All(other => c.Value == other.Value || !other.Key.Matches(c.Key))); var key = insertionForPreviousReference.Key; if (key == null) { Debug.Assert(!customizations.Any(), $"Detected circular chain of customizations for book: {BCVRef.NumberToBookCode(bookNum)}. There were {customizations.Count} customizations that could not be processed!"); break; } var newQ = lastQuestionInBook.AddedQuestionAfter = insertionForPreviousReference.Value.PopQuestion(key); if (!insertionForPreviousReference.Value.IsAdditionOrInsertion) { customizations.Remove(key); } category.Questions.Add(newQ); foreach (Question question in GetCustomizations(newQ, category, iQuestion, customizations)) { lastQuestionInBook = question; yield return(question); iQuestion++; } } } }
protected override void AdjustData(ILookup <int, CharacterVerse> bookLookup) { for (var b = 1; b <= 66; b++) { var book = bookLookup[b]; var narrator = GetStandardCharacterId(BCVRef.NumberToBookCode(b), StandardCharacter.Narrator); for (int i = 0; i < book.Count(); i++) { var cv = book.ElementAt(i); if (cv.QuoteType == QuoteType.Quotation && cv.DefaultCharacter == narrator) { // PG-1248: cv is a Quotation entry which, if used, would have the quote spoken by the original // speaker. (Even though the default character is the narrator, we ignore that.) if there is a // narrator Quotation entry for this same verse, we want it to be considered as the primary // option. We'll mark the cv we've found as an Alternate, so the quote parser will not // consider it as an option, but the user will still be able to use it to override the default. // Following line should be SingleOrDefault, but this is more efficient var quotationByNarrator = book.FirstOrDefault(a => a.Book == cv.Book && a.Chapter == cv.Chapter && a.Verse == cv.Verse && a.QuoteType == QuoteType.Quotation && a.Character == narrator); if (quotationByNarrator != null) { cv.ChangeToAlternate(); } } } } }
/// ------------------------------------------------------------------------------------ /// <summary> /// Loads the combo box with the appropriate book ids /// </summary> /// <param name="canonicalBookIds">1-based Canonical book numbers</param> /// ------------------------------------------------------------------------------------ private void LoadBooks(IEnumerable <int> canonicalBookIds) { foreach (int canonicalBookId in canonicalBookIds) { string bookCode = BCVRef.NumberToBookCode(canonicalBookId); m_cboBooks.Items.Add(bookCode); } if (m_cboBooks.Items.Count > 0) { m_cboBooks.SelectedIndex = 0; } }
private static IEnumerable <string> PartialTestamentBookSummary(BookSet bookSet, BookSet setToCompare) { if (bookSet.Count == 0) { return(Enumerable.Empty <string>()); } var result = new List <string>(); string start = null; string previous = null; foreach (int bookNum in setToCompare.SelectedBookNumbers) { if (bookSet.IsSelected(bookNum)) { string bookCode = BCVRef.NumberToBookCode(bookNum); if (start == null) { start = bookCode; } previous = bookCode; } else { if (start != null) { if (start == previous) { result.Add(start); } else { result.Add(start + "-" + previous); } start = null; previous = null; } } } if (previous != null) { if (start == previous) { result.Add(start); } else { result.Add(start + "-" + previous); } } return(result); }
public static void ForEachBookFileInProject(string projectDir, Action <string, string> action) { string[] files = Directory.GetFiles(projectDir, "???" + Constants.kBookScriptFileExtension); for (int i = 1; i <= BCVRef.LastBook; i++) { string bookCode = BCVRef.NumberToBookCode(i); string possibleFileName = Path.Combine(projectDir, bookCode + Constants.kBookScriptFileExtension); if (files.Contains(possibleFileName)) { action(bookCode, possibleFileName); } } }
public MockedBookForQuoteSystem(int bookNum, QuoteSystem desiredQuoteSystem, bool highlyConsistentData, bool includeSecondLevelQuotes) { #if USE_RANDOM_SEED Debug.WriteLine("Seed base = " + s_seedBase); var seed = s_seedBase + bookNum; #else var seed = 300 + bookNum; #endif m_random = new Random(seed); m_desiredQuoteSystem = desiredQuoteSystem; m_highlyConsistentData = highlyConsistentData; m_includeSecondLevelQuotes = includeSecondLevelQuotes && m_desiredQuoteSystem.NormalLevels.Count > 1; BookId = BCVRef.NumberToBookCode(bookNum); }
private void LoadBooks() { var files = BookScriptFiles; for (int i = 1; i <= BCVRef.LastBook; i++) { string bookCode = BCVRef.NumberToBookCode(i); var bookScript = TryLoadBook(files, bookCode); if (bookScript != null) { m_books.Add(bookScript); } } }
/// ------------------------------------------------------------------------------------ /// <summary> /// Gets the start and end references for the line of text with the given marker. (Sets /// m_currentStartRef and m_currentEndRef.) /// </summary> /// <param name="marker"></param> /// <param name="lineContents"></param> /// <param name="literalVerse"></param> /// <returns></returns> /// ------------------------------------------------------------------------------------ private void GetReferenceForLine(string marker, ref string lineContents, ref string literalVerse) { // If this is a marker that will change the reference, then update // the reference if (marker == ScrImportSet.s_markerBook) { int book = BCVRef.BookToNumber(lineContents.ToUpper()); if (book > 0) { m_currentStartRef.Book = book; m_currentStartRef.Chapter = 1; m_currentStartRef.Verse = 0; } m_currentEndRef = new BCVRef(m_currentStartRef); m_seenIdInFile = true; } else if (marker == ScrImportSet.s_markerChapter) { string chapterText = lineContents; try { m_currentStartRef.Chapter = ScrReference.ChapterToInt(chapterText, out lineContents); m_currentStartRef.Verse = 1; m_currentEndRef = new BCVRef(m_currentStartRef); } catch (ArgumentException) { throw new ScriptureUtilsException(SUE_ErrorCode.InvalidChapterNumber, m_currentFile.FileName, m_lineNumber, lineContents, BCVRef.NumberToBookCode(m_currentStartRef.Book), chapterText, null); } } else if (marker == ScrImportSet.s_markerVerse) { BCVRef.VerseToScrRef(lineContents.TrimStart(), out literalVerse, out lineContents, ref m_currentStartRef, ref m_currentEndRef); } else { if (lineContents == " ") { lineContents = string.Empty; } } }
private void RenameCharacter(int bookNum, int chapter, int verse, string existingCharacterId, string newCharacterId) { var block = m_testProject.Books.Single(book => book.BookId == BCVRef.NumberToBookCode(bookNum)).GetBlocksForVerse(chapter, verse) .Single(b => b.CharacterId == existingCharacterId); block.CharacterId = newCharacterId; m_testProject.ProjectCharacterVerseData.Add(new CharacterVerse(new BCVRef(bookNum, chapter, verse), newCharacterId, string.Empty, string.Empty, true)); if (!m_testProject.AllCharacterDetailDictionary.ContainsKey(newCharacterId)) { m_testProject.AddProjectCharacterDetail(new CharacterDetail { CharacterId = newCharacterId }); } }
public void Guess_NoTextForVersesWithQuotations_ReturnsDefaultQuoteSystem() { var mockedBooks = new List <IScrBook>(); for (int i = 1; i < BCVRef.LastBook; i++) { var mockedBook = MockRepository.GenerateMock <IScrBook>(); mockedBook.Stub(x => x.BookId).Return(BCVRef.NumberToBookCode(i)); mockedBook.Stub(x => x.GetVerseText(Arg <int> .Is.Anything, Arg <int> .Is.Anything)).Return(string.Empty); mockedBooks.Add(mockedBook); } bool certain; Assert.AreEqual(QuoteSystem.Default, QuoteSystemGuesser.Guess(ControlCharacterVerseData.Singleton, mockedBooks, ScrVers.English, out certain)); Assert.IsFalse(certain); }
private void RenameCharacter(int bookNum, int chapter, int verse, string existingCharacterId, string newCharacterId) { var block = m_testProject.Books.Single(book => book.BookId == BCVRef.NumberToBookCode(bookNum)).GetBlocksForVerse(chapter, verse) .Single(b => b.CharacterId == existingCharacterId); block.CharacterId = newCharacterId; m_testProject.ProjectCharacterVerseData.AddEntriesFor(bookNum, block); if (!m_testProject.AllCharacterDetailDictionary.ContainsKey(newCharacterId)) { m_testProject.AddProjectCharacterDetail(new CharacterDetail { CharacterId = newCharacterId }); } m_testProject.ClearCharacterStatistics(); // This simulates behavior in UI when user makes changes in AssignCharacterDlg }
/// ------------------------------------------------------------------------------------ /// <summary> /// Construct an import exception whose message contains a description of the error, /// including the offending segment, optional additional information, and BCV details. /// </summary> /// <param name="errorCode">numeric error code</param> /// <param name="moreInfo">Details about the specific problem</param> /// <param name="fileName">file name where the error was encountered</param> /// <param name="lineNumber">line number in the file where the error occurred</param> /// <param name="lineContents">Contents of problematic line (or segment)</param> /// <param name="scrRef">scripture reference where the error occurred</param> /// ------------------------------------------------------------------------------------ public ScriptureUtilsException(SUE_ErrorCode errorCode, string moreInfo, string fileName, int lineNumber, string lineContents, BCVRef scrRef) { bool fIncludeLineInfo; ErrorCode = errorCode; GetErrorMsgAndHelpTopic(errorCode, out m_message, out m_helpTopic, out fIncludeLineInfo); // Add file and Scripture reference information. m_message += Environment.NewLine + Environment.NewLine + FormatErrorDetails(fileName, fIncludeLineInfo, lineNumber, lineContents, BCVRef.NumberToBookCode(scrRef.Book), scrRef.Chapter.ToString(), scrRef.Verse.ToString()); // Add any details about the error. if (!string.IsNullOrEmpty(moreInfo)) { m_message += Environment.NewLine + moreInfo; } }
/// <summary> /// Gets all known (potential and/or expected) characters for the given reference range. If any of /// them are Hypothetical, those characters will only be included if the reference text contains a /// block actually assigned to that hypothetical character. Otherwise, the hypothetical character /// will be treated as a narrator "quotation." /// </summary> public HashSet <CharacterSpeakingMode> GetCharacters(int bookId, int chapter, IReadOnlyCollection <IVerse> verses, ScrVers versification = null, bool includeAlternatesAndRareQuotes = false, bool includeNarratorOverrides = false) { Debug.Assert(!includeNarratorOverrides, "Can't think of any valid reason the quote parser should ever want to consider" + "narrator overrides. These should be applied only after user has done disambiguation."); var result = m_cvInfo.GetCharacters(bookId, chapter, verses, versification, includeAlternatesAndRareQuotes, includeNarratorOverrides); var hypotheticalsToReplace = result.Where(cv => { if (cv.QuoteType == QuoteType.Hypothetical) { var refTextBook = m_referenceText.GetBook(bookId); if (refTextBook != null) { return(!refTextBook.GetBlocksForVerse(chapter, verses.First().StartVerse, verses.Last().EndVerse).Any(b => b.CharacterId == cv.Character)); } // REVIEW: Should we replace hypotheticals if there is no reference text for this book? } return(false); }).Select(c => c.Character).ToList(); if (hypotheticalsToReplace.Any()) { result.Add(new CharacterSpeakingMode(CharacterVerseData.GetStandardCharacterId(BCVRef.NumberToBookCode(bookId), CharacterVerseData.StandardCharacter.Narrator), String.Empty, String.Empty, false, QuoteType.Quotation)); result.RemoveAll(e => e.QuoteType == QuoteType.Hypothetical && hypotheticalsToReplace.Contains(e.Character)); } return(result); }
private void AddAnnotations(List <List <object> > data) { var annotationRowIndexes = new List <int>(); int lastIndexOfPreviousVerse = 0; BCVRef previousReferenceTextVerse = null; IEnumerable <VerseAnnotation> annotationsForPreviousVerse = null; for (int i = 0; i < data.Count; i++) { var row = data[i]; if (HasReferenceText(row)) { var referenceTextVerse = GetBcvRefForRow(row); if (referenceTextVerse != previousReferenceTextVerse) { if (previousReferenceTextVerse != null && annotationsForPreviousVerse != null) { foreach (var verseAnnotation in annotationsForPreviousVerse.Where(va => va.Annotation is Pause)) { if (ExportAnnotationsInSeparateRows) { var rowIndex = lastIndexOfPreviousVerse + 1 + verseAnnotation.Offset; data.Insert(rowIndex, GetExportDataForAnnotation(verseAnnotation, BCVRef.NumberToBookCode(previousReferenceTextVerse.Book), previousReferenceTextVerse.Chapter, previousReferenceTextVerse.Verse.ToString())); i++; annotationRowIndexes.Add(rowIndex); } else { annotationRowIndexes.Add(AddAnnotationData(data, lastIndexOfPreviousVerse, verseAnnotation)); } } } if (referenceTextVerse != previousReferenceTextVerse) { var annotationsForVerse = ControlAnnotations.Singleton.GetAnnotationsForVerse(referenceTextVerse); foreach (var verseAnnotation in annotationsForVerse.Where(va => va.Annotation is Sound)) { if (ExportAnnotationsInSeparateRows) { var rowIndex = i++ + verseAnnotation.Offset; data.Insert(rowIndex, GetExportDataForAnnotation(verseAnnotation, BCVRef.NumberToBookCode(referenceTextVerse.Book), referenceTextVerse.Chapter, referenceTextVerse.Verse.ToString())); annotationRowIndexes.Add(rowIndex); } else { annotationRowIndexes.Add(AddAnnotationData(data, i, verseAnnotation)); } } annotationsForPreviousVerse = annotationsForVerse; previousReferenceTextVerse = referenceTextVerse; } } lastIndexOfPreviousVerse = i; } } m_annotatedRowIndexes = annotationRowIndexes; }
private static void CompareAndCombineLists(bool includeFcbhNarrator, StringBuilder sb) { sb.Append("Control File Version").Append(kTab).Append(Environment.NewLine); sb.Append("#").Append(kTab).Append("C").Append(kTab).Append("V").Append(kTab) .Append("Character ID").Append(kTab).Append("FCBH Character ID").Append(kTab).Append("Delivery").Append(kTab) .Append("Alias").Append(kTab).Append("Quote Type").Append(kTab).Append("Default Character").Append(kTab) .Append("Parallel Passage").Append(Environment.NewLine); var allFcbh = TemplateData.All(includeFcbhNarrator); var control = ControlCharacterVerseData.Singleton.GetAllQuoteInfo(); var fcbhDictionary = new Dictionary <BCVRef, List <TemplateDatum> >(); foreach (TemplateDatum d in allFcbh) { List <TemplateDatum> list; if (fcbhDictionary.TryGetValue(d.BcvRef, out list)) { if (!list.Select(f => f.CharacterId).Contains(d.CharacterId)) { list.Add(d); } } else { list = new List <TemplateDatum> { d }; fcbhDictionary.Add(d.BcvRef, list); } } var controlDictionary = new Dictionary <BCVRef, List <Glyssen.Character.CharacterVerse> >(); foreach (Glyssen.Character.CharacterVerse cv in control) { List <Glyssen.Character.CharacterVerse> list; if (controlDictionary.TryGetValue(cv.BcvRef, out list)) { list.Add(cv); } else { list = new List <Glyssen.Character.CharacterVerse> { cv }; controlDictionary.Add(cv.BcvRef, list); } } foreach (BCVRef bcvRef in new SortedSet <BCVRef>(fcbhDictionary.Keys.Union(controlDictionary.Keys))) { List <TemplateDatum> fcbhList; List <Glyssen.Character.CharacterVerse> controlList; bool hasFcbh = fcbhDictionary.TryGetValue(bcvRef, out fcbhList); bool hasControl = controlDictionary.TryGetValue(bcvRef, out controlList); if (hasFcbh && fcbhList.Count == 1 && hasControl && controlList.Count == 1) { var cv = controlList[0]; var fcbhDatum = fcbhList[0]; sb.Append(cv.BookCode).Append(kTab) .Append(cv.Chapter).Append(kTab).Append(cv.Verse).Append(kTab).Append(cv.Character).Append(kTab) .Append(fcbhDatum.CharacterId).Append(kTab).Append(cv.Delivery).Append(kTab).Append(cv.Alias).Append(kTab) .Append(cv.QuoteType).Append(kTab).Append(cv.DefaultCharacter).Append(kTab).Append(cv.ParallelPassageReferences) .Append(Environment.NewLine); } else { if (hasControl) { foreach (Glyssen.Character.CharacterVerse cv in controlList) { if (hasFcbh && fcbhList.Select(f => f.CharacterId).Contains(cv.Character)) { sb.Append(cv.BookCode).Append(kTab) .Append(cv.Chapter).Append(kTab).Append(cv.Verse).Append(kTab).Append(cv.Character).Append(kTab) .Append(cv.Character).Append(kTab).Append(cv.Delivery).Append(kTab).Append(cv.Alias).Append(kTab) .Append(cv.QuoteType).Append(kTab).Append(cv.DefaultCharacter).Append(kTab).Append(cv.ParallelPassageReferences) .Append(Environment.NewLine); foreach (TemplateDatum d in fcbhList.Where(f => f.CharacterId == cv.Character)) { d.IsProcessed = true; } } else { sb.Append(cv.BookCode).Append(kTab) .Append(cv.Chapter).Append(kTab).Append(cv.Verse).Append(kTab).Append(cv.Character).Append(kTab) .Append(kTab).Append(cv.Delivery).Append(kTab).Append(cv.Alias).Append(kTab) .Append(cv.QuoteType).Append(kTab).Append(cv.DefaultCharacter).Append(kTab).Append(cv.ParallelPassageReferences) .Append(Environment.NewLine); } } } if (hasFcbh) { foreach (TemplateDatum d in fcbhList.Where(f => !f.IsProcessed)) { if (!d.BcvRef.BookIsValid) { Debug.Fail("Invalid book: " + d.BcvRef); } var bookCode = BCVRef.NumberToBookCode(d.BcvRef.Book); if (string.IsNullOrWhiteSpace(bookCode)) { Debug.Fail("Invalid book code: " + bookCode); } sb.Append(bookCode).Append(kTab) .Append(d.BcvRef.Chapter).Append(kTab).Append(d.BcvRef.Verse).Append(kTab).Append(kTab) .Append(d.CharacterId).Append(kTab).Append(kTab).Append(kTab) .Append(kTab).Append(kTab) .Append(Environment.NewLine); } } } } }