private static void FindAllScriptureBlocksThroughVerse(IReadOnlyList <Block> blockList, VerseRef endVerse, ref int i, ScrVers versification) { for (; ;) { var nextScriptureBlock = blockList.Skip(i + 1).FirstOrDefault(b => !CharacterVerseData.IsCharacterExtraBiblical(b.CharacterId)); if (nextScriptureBlock == null) { break; } var nextVerseRef = new VerseRef(endVerse.BookNum, nextScriptureBlock.ChapterNumber, nextScriptureBlock.InitialStartVerseNumber, versification); if (nextVerseRef > endVerse) { break; } i++; } }
public void Constructor_CharactersRemovedFromProjectLeavingGroupsThatWouldHaveNoCharacters_CharacterGroupsToRemoveNotEmpty() { // By jacking up the number of actors really high, we guarantee that most characters will end up in a group by themselves, // thus more-or-less ensuring that some groups will no longer contain any characters in use after excluding Mark from the // project. m_testProject.VoiceActorList.Actors = CharacterGroupGeneratorTests.GetVoiceActors(99, 22, 7); GenerateGroups(); m_testProject.AvailableBooks.Single(b => b.Code == "MRK").IncludeInScript = false; var adjuster = new CharacterGroupsAdjuster(m_testProject); Assert.AreEqual(0, adjuster.CharactersNotCoveredByAnyGroup.Count()); Assert.IsTrue(adjuster.CharactersNoLongerInUse.Contains(CharacterVerseData.GetStandardCharacterId("MRK", CharacterVerseData.StandardCharacter.Narrator))); Assert.IsTrue(adjuster.CharactersNoLongerInUse.Contains(CharacterVerseData.GetStandardCharacterId("MRK", CharacterVerseData.StandardCharacter.ExtraBiblical))); Assert.IsTrue(adjuster.CharactersNoLongerInUse.Contains(CharacterVerseData.GetStandardCharacterId("MRK", CharacterVerseData.StandardCharacter.BookOrChapter))); Assert.IsTrue(adjuster.CharacterGroupsToRemove.Any()); Assert.IsTrue(adjuster.GroupsAreNotInSynchWithData); }
public void Constructor_BooksWithDifferentAuthors_NoStatsCombined() { var keyStrokesByBook = new Dictionary <string, int>(); keyStrokesByBook[CharacterVerseData.GetStandardCharacterId("JER", CharacterVerseData.StandardCharacter.Narrator)] = 52000; keyStrokesByBook[CharacterVerseData.GetStandardCharacterId("EZK", CharacterVerseData.StandardCharacter.Narrator)] = 48000; keyStrokesByBook[CharacterVerseData.GetStandardCharacterId("HOS", CharacterVerseData.StandardCharacter.Narrator)] = 12000; keyStrokesByBook[CharacterVerseData.GetStandardCharacterId("JUD", CharacterVerseData.StandardCharacter.Narrator)] = 1000; var includedBooks = new List <string> { "JER", "EZK", "HOS", "JUD" }; Assert.AreEqual(52000, new AuthorStats(BiblicalAuthors.GetAuthorOfBook("JER"), includedBooks, keyStrokesByBook).KeyStrokeCount); Assert.AreEqual(48000, new AuthorStats(BiblicalAuthors.GetAuthorOfBook("EZK"), includedBooks, keyStrokesByBook).KeyStrokeCount); Assert.AreEqual(12000, new AuthorStats(BiblicalAuthors.GetAuthorOfBook("HOS"), includedBooks, keyStrokesByBook).KeyStrokeCount); Assert.AreEqual(1000, new AuthorStats(BiblicalAuthors.GetAuthorOfBook("JUD"), includedBooks, keyStrokesByBook).KeyStrokeCount); }
public BlockMatchup(BookScript vernacularBook, int iBlock, Action <PortionScript> splitBlocks, Func <VerseRef, bool> isOkayToBreakAtVerse, IReferenceLanguageInfo heSaidProvider) { m_vernacularBook = vernacularBook; int bookNum = BCVRef.BookToNumber(m_vernacularBook.BookId); m_referenceLanguageInfo = heSaidProvider; var blocks = m_vernacularBook.GetScriptBlocks(); var originalAnchorBlock = blocks[iBlock]; var blocksForVersesCoveredByBlock = vernacularBook.GetBlocksForVerse(originalAnchorBlock.ChapterNumber, originalAnchorBlock.InitialStartVerseNumber).ToList(); m_iStartBlock = iBlock - blocksForVersesCoveredByBlock.IndexOf(originalAnchorBlock); while (!blocksForVersesCoveredByBlock.First().StartsAtVerseStart&& blocksForVersesCoveredByBlock.First().InitialStartVerseNumber < originalAnchorBlock.InitialStartVerseNumber) { var prepend = vernacularBook.GetBlocksForVerse(originalAnchorBlock.ChapterNumber, blocksForVersesCoveredByBlock.First().InitialStartVerseNumber).ToList(); prepend.RemoveAt(prepend.Count - 1); m_iStartBlock -= prepend.Count; blocksForVersesCoveredByBlock.InsertRange(0, prepend); } int iLastBlock = m_iStartBlock + blocksForVersesCoveredByBlock.Count - 1; int i = iLastBlock; AdvanceToCleanVerseBreak(blocks, verseNum => { return(isOkayToBreakAtVerse(new VerseRef(bookNum, originalAnchorBlock.ChapterNumber, verseNum))); }, ref i); if (i > iLastBlock) { blocksForVersesCoveredByBlock.AddRange(blocks.Skip(iLastBlock + 1).Take(i - iLastBlock)); } while (CharacterVerseData.IsCharacterOfType(blocksForVersesCoveredByBlock.Last().CharacterId, CharacterVerseData.StandardCharacter.ExtraBiblical)) { blocksForVersesCoveredByBlock.RemoveAt(blocksForVersesCoveredByBlock.Count - 1); } m_portion = new PortionScript(vernacularBook.BookId, blocksForVersesCoveredByBlock.Select(b => b.Clone())); CorrelatedAnchorBlock = m_portion.GetScriptBlocks()[iBlock - m_iStartBlock]; if (splitBlocks != null) { int origCount = m_portion.GetScriptBlocks().Count; splitBlocks(m_portion); m_numberOfBlocksAddedBySplitting = m_portion.GetScriptBlocks().Count - origCount; } }
public string CharacterSelect(int splitId, IEnumerable <AssignCharacterViewModel.Character> characters = null) { if ((characters == null) && !string.IsNullOrEmpty(s_characterSelect)) { return(string.Format(s_characterSelect, splitId)); } const string optionTemplate = "<option value=\"{0}\">{1}</option>"; var sb = new StringBuilder("<select class=\"select-character\" data-splitid=\"{0}\"><option value=\"\"></option>"); if (characters != null) { foreach (var character in characters) { if (CharacterVerseData.IsCharacterStandard(character.CharacterId)) { } if (character.IsNarrator) { sb.AppendFormat(optionTemplate, CharacterVerseData.GetStandardCharacterId(BookCode, CharacterVerseData.StandardCharacter.Narrator), character.LocalizedDisplay); } else { var stdCharacterType = CharacterVerseData.GetStandardCharacterType(character.CharacterId); if (stdCharacterType == CharacterVerseData.StandardCharacter.NonStandard) { sb.AppendFormat(optionTemplate, character.CharacterId, character.LocalizedDisplay); } else { sb.AppendFormat(optionTemplate, CharacterVerseData.GetStandardCharacterId(BookCode, stdCharacterType), character.LocalizedDisplay); } } } } sb.Append("</select>"); s_characterSelect = sb.ToString(); return(string.Format(s_characterSelect, splitId)); }
public virtual Color GetForeColorByCharacterId(string characterId) { if (string.IsNullOrWhiteSpace(characterId)) { return(SpeechNonCharacter); } if (characterId == "Jesus") { return(SpeechJesus); } if (!CharacterVerseData.IsCharacterStandard(characterId)) { return(SpeechCharacter); } return(SpeechNonCharacter); }
public void Constructor_CharactersRemovedFromProjectButNotEnoughToResultInAnEmptyGroup_AdditionsButNoDeletions() { // By keeping the number of actors really low, we guarantee that groups will have lots of characters, // thus more-or-less ensuring that no groups will consist only of characters no longer in use after excluding Mark from the // project. m_testProject.VoiceActorList.Actors = CharacterGroupGeneratorTests.GetVoiceActors(7, 1, 1); GenerateGroups(); m_testProject.AvailableBooks.Single(b => b.Code == "MRK").IncludeInScript = false; var adjuster = new CharacterGroupsAdjuster(m_testProject); Assert.AreEqual(0, adjuster.CharactersNotCoveredByAnyGroup.Count()); Assert.IsTrue(adjuster.CharactersNoLongerInUse.Contains(CharacterVerseData.GetStandardCharacterId("MRK", CharacterVerseData.StandardCharacter.Narrator))); Assert.IsTrue(adjuster.CharactersNoLongerInUse.Contains(CharacterVerseData.GetStandardCharacterId("MRK", CharacterVerseData.StandardCharacter.ExtraBiblical))); Assert.IsTrue(adjuster.CharactersNoLongerInUse.Contains(CharacterVerseData.GetStandardCharacterId("MRK", CharacterVerseData.StandardCharacter.BookOrChapter))); Assert.AreEqual(0, adjuster.CharacterGroupsToRemove.Count()); Assert.IsFalse(adjuster.NewBooksHaveBeenIncluded); Assert.IsTrue(adjuster.BooksHaveBeenExcluded); Assert.IsTrue(adjuster.FullRegenerateRecommended); Assert.IsTrue(adjuster.GroupsAreNotInSynchWithData); }
public void Constructor_CharactersAddedToProject_AdditionsButNoDeletions() { m_testProject.VoiceActorList.Actors = CharacterGroupGeneratorTests.GetVoiceActors(9, 2, 1); GenerateGroups(); m_testProject.AvailableBooks.Single(b => b.Code == "ACT").IncludeInScript = true; var adjuster = new CharacterGroupsAdjuster(m_testProject); Assert.IsTrue(adjuster.CharactersNotCoveredByAnyGroup.Contains(CharacterVerseData.GetStandardCharacterId("ACT", CharacterVerseData.StandardCharacter.Narrator))); Assert.IsTrue(adjuster.CharactersNotCoveredByAnyGroup.Contains(CharacterVerseData.GetStandardCharacterId("ACT", CharacterVerseData.StandardCharacter.ExtraBiblical))); Assert.IsTrue(adjuster.CharactersNotCoveredByAnyGroup.Contains(CharacterVerseData.GetStandardCharacterId("ACT", CharacterVerseData.StandardCharacter.BookOrChapter))); Assert.IsTrue(adjuster.CharactersNotCoveredByAnyGroup.Contains("Gamaliel")); Assert.IsFalse(adjuster.CharactersNotCoveredByAnyGroup.Contains("Jesus")); Assert.IsFalse(adjuster.CharactersNotCoveredByAnyGroup.Contains("Peter (Simon)")); Assert.AreEqual(0, adjuster.CharactersNoLongerInUse.Count()); Assert.AreEqual(0, adjuster.CharacterGroupsToRemove.Count()); Assert.IsTrue(adjuster.NewBooksHaveBeenIncluded); Assert.IsFalse(adjuster.BooksHaveBeenExcluded); Assert.IsTrue(adjuster.FullRegenerateRecommended); Assert.IsTrue(adjuster.GroupsAreNotInSynchWithData); }
public void Constructor_CharactersAddedToProject_AdditionsButNoDeletions() { SetVoiceActors(9, 2, 1); GenerateGroups(); m_testProject.AvailableBooks.Single(b => b.Code == "ACT").IncludeInScript = true; m_testProject.ClearCharacterStatistics(); // This simulates behavior in UI when the project is saved after displaying ScriptureRangeSelectionDlg var adjuster = new CharacterGroupsAdjuster(m_testProject); Assert.IsTrue(adjuster.CharactersNotCoveredByAnyGroup.Contains(CharacterVerseData.GetStandardCharacterId("ACT", CharacterVerseData.StandardCharacter.Narrator))); Assert.IsTrue(adjuster.CharactersNotCoveredByAnyGroup.Contains(CharacterVerseData.GetStandardCharacterId("ACT", CharacterVerseData.StandardCharacter.ExtraBiblical))); Assert.IsTrue(adjuster.CharactersNotCoveredByAnyGroup.Contains(CharacterVerseData.GetStandardCharacterId("ACT", CharacterVerseData.StandardCharacter.BookOrChapter))); Assert.IsTrue(adjuster.CharactersNotCoveredByAnyGroup.Contains("Gamaliel")); Assert.IsFalse(adjuster.CharactersNotCoveredByAnyGroup.Contains("Jesus")); Assert.IsFalse(adjuster.CharactersNotCoveredByAnyGroup.Contains("Peter (Simon)")); Assert.AreEqual(0, adjuster.CharactersNoLongerInUse.Count()); Assert.AreEqual(0, adjuster.CharacterGroupsToRemove.Count()); Assert.IsTrue(adjuster.NewBooksHaveBeenIncluded); Assert.IsFalse(adjuster.BooksHaveBeenExcluded); Assert.IsTrue(adjuster.FullRegenerateRecommended); Assert.IsTrue(adjuster.GroupsAreNotInSynchWithData); }
public void DataIntegrity_AllNonNarratorCharacterDetailsHaveCharacterIdOrDefaultCharacter() { var characterIds = new List <string>(ControlCharacterVerseData.Singleton.GetAllQuoteInfo().Select(d => d.Character) .SelectMany(characters => characters.Split('/'))); var defaultCharacters = ControlCharacterVerseData.Singleton.GetAllQuoteInfo().Select(d => d.DefaultCharacter).ToList(); ISet <string> missingCharacters = new SortedSet <string>(); foreach (string character in CharacterDetailData.Singleton.GetAll().Select(d => d.CharacterId)) { if (!CharacterVerseData.IsCharacterStandard(character) && (!(characterIds.Contains(character) || defaultCharacters.Contains(character)))) { missingCharacters.Add(character); } } Assert.False(missingCharacters.Any(), "Characters in Character-Detail data but not in Character-Verse data:" + Environment.NewLine + missingCharacters.OnePerLineWithIndent()); }
/// <summary>Gets extra-biblical characters that are voiced by the same actor who is not the narrator</summary> /// <param name="book"></param> /// <param name="dramatizationPreferences"></param> /// <param name="bookData"></param> private static void GetOtherCharactersToTreatAsOne(BookScript book, ProjectDramatizationPreferences dramatizationPreferences, Dictionary <CharacterVerseData.StandardCharacter, HashSet <string> > bookData) { var bookTitleChapterId = CharacterVerseData.GetStandardCharacterId(book.BookId, CharacterVerseData.StandardCharacter.BookOrChapter); var sectionHeadId = CharacterVerseData.GetStandardCharacterId(book.BookId, CharacterVerseData.StandardCharacter.ExtraBiblical); var bookIntroductionId = CharacterVerseData.GetStandardCharacterId(book.BookId, CharacterVerseData.StandardCharacter.Intro); if ((dramatizationPreferences.BookTitleAndChapterDramatization & ExtraBiblicalMaterialSpeakerOption.NotNarratorOrOmitted) != 0) { if (dramatizationPreferences.BookTitleAndChapterDramatization == dramatizationPreferences.SectionHeadDramatization) { AddOrNew(bookData, CharacterVerseData.StandardCharacter.BookOrChapter, bookTitleChapterId); AddOrNew(bookData, CharacterVerseData.StandardCharacter.BookOrChapter, sectionHeadId); AddOrNew(bookData, CharacterVerseData.StandardCharacter.ExtraBiblical, bookTitleChapterId); AddOrNew(bookData, CharacterVerseData.StandardCharacter.ExtraBiblical, sectionHeadId); } if (dramatizationPreferences.BookTitleAndChapterDramatization == dramatizationPreferences.BookIntroductionsDramatization) { AddOrNew(bookData, CharacterVerseData.StandardCharacter.BookOrChapter, bookTitleChapterId); AddOrNew(bookData, CharacterVerseData.StandardCharacter.BookOrChapter, bookIntroductionId); AddOrNew(bookData, CharacterVerseData.StandardCharacter.Intro, bookTitleChapterId); AddOrNew(bookData, CharacterVerseData.StandardCharacter.Intro, bookIntroductionId); } } if ((dramatizationPreferences.SectionHeadDramatization & ExtraBiblicalMaterialSpeakerOption.NotNarratorOrOmitted) != 0) { if (dramatizationPreferences.SectionHeadDramatization == dramatizationPreferences.BookIntroductionsDramatization) { AddOrNew(bookData, CharacterVerseData.StandardCharacter.ExtraBiblical, sectionHeadId); AddOrNew(bookData, CharacterVerseData.StandardCharacter.ExtraBiblical, bookIntroductionId); AddOrNew(bookData, CharacterVerseData.StandardCharacter.Intro, sectionHeadId); AddOrNew(bookData, CharacterVerseData.StandardCharacter.Intro, bookIntroductionId); } } }
public void MakeMinimalAdjustments_FewDeletionsAndFewGroups_CharactersRemovedFromExistingCharacterGroups() { m_testProject.AvailableBooks.Single(b => b.Code == "JUD").IncludeInScript = true; m_testProject.VoiceActorList.Actors = CharacterGroupGeneratorTests.GetVoiceActors(20, 2, 1); GenerateGroups(); m_testProject.AvailableBooks.Single(b => b.Code == "JUD").IncludeInScript = false; var adjuster = new CharacterGroupsAdjuster(m_testProject); var charactersNotInUse = adjuster.CharactersNoLongerInUse.ToList(); Assert.IsTrue(charactersNotInUse.Count > 0); Assert.IsTrue(charactersNotInUse.Contains(CharacterVerseData.GetStandardCharacterId("JUD", CharacterVerseData.StandardCharacter.Narrator))); Assert.IsTrue(charactersNotInUse.Contains(CharacterVerseData.GetStandardCharacterId("JUD", CharacterVerseData.StandardCharacter.ExtraBiblical))); Assert.IsTrue(charactersNotInUse.Contains(CharacterVerseData.GetStandardCharacterId("JUD", CharacterVerseData.StandardCharacter.BookOrChapter))); var originalCountOfGroups = m_testProject.CharacterGroupList.CharacterGroups.Count; adjuster.MakeMinimalAdjustments(); Assert.IsFalse(adjuster.GroupsAreNotInSynchWithData); Assert.AreEqual(0, adjuster.CharactersNoLongerInUse.Count()); Assert.AreEqual(0, adjuster.CharactersNotCoveredByAnyGroup.Count()); Assert.AreEqual(originalCountOfGroups, m_testProject.CharacterGroupList.CharacterGroups.Count); Assert.IsFalse(m_testProject.CharacterGroupList.CharacterGroups.Any(g => g.CharacterIds.Any(c => charactersNotInUse.Contains(c)))); }
public void Constructor_FiveCharactersAddedRemovedOrRenamed_FullRegenerateRecommended() { SetVoiceActors(9, 2, 1); m_testProject.AvailableBooks.Single(b => b.Code == "LUK").IncludeInScript = false; m_testProject.ClearCharacterStatistics(); // This simulates behavior in UI when the project is saved after displaying ScriptureRangeSelectionDlg GenerateGroups(); try { RenameCharacter(41, 1, 27, "men in Capernaum synagogue", "dudes in the Capernaum teaching center"); RenameCharacter(41, 2, 12, "everyone who saw healing of paralytic", "witnesses of paralytic's healing"); SetBlockCharacterToNarrator("MRK", 9, 26, "many in crowd"); SetBlockCharacterToNarrator("MRK", 5, 35, "men from Jairus' house"); RenameCharacter(41, 7, 1, CharacterVerseData.GetStandardCharacterId("MRK", CharacterVerseData.StandardCharacter.Narrator), "Mephibosheth"); var adjuster = new CharacterGroupsAdjuster(m_testProject); Assert.AreEqual(3, adjuster.CharactersNotCoveredByAnyGroup.Count()); Assert.IsTrue(adjuster.CharactersNotCoveredByAnyGroup.Contains("dudes in the Capernaum teaching center")); Assert.IsTrue(adjuster.CharactersNotCoveredByAnyGroup.Contains("witnesses of paralytic's healing")); Assert.IsTrue(adjuster.CharactersNotCoveredByAnyGroup.Contains("Mephibosheth")); Assert.AreEqual(4, adjuster.CharactersNoLongerInUse.Count()); Assert.IsTrue(adjuster.CharactersNoLongerInUse.Contains("men in Capernaum synagogue")); Assert.IsTrue(adjuster.CharactersNoLongerInUse.Contains("everyone who saw healing of paralytic")); Assert.IsTrue(adjuster.CharactersNoLongerInUse.Contains("many in crowd")); Assert.IsTrue(adjuster.CharactersNoLongerInUse.Contains("men from Jairus' house")); Assert.AreEqual(0, adjuster.CharacterGroupsToRemove.Count()); Assert.IsFalse(adjuster.NewBooksHaveBeenIncluded); Assert.IsFalse(adjuster.BooksHaveBeenExcluded); Assert.IsTrue(adjuster.FullRegenerateRecommended); Assert.IsTrue(adjuster.GroupsAreNotInSynchWithData); } finally { CreateTestProject(); } }
public void DistributeBooksAmongNarratorGroups_FourAuthorsOfFourBooksAmongThreeNarrators_TwoAuthorsWithShortestBooksCombined() { var keyStrokesByBook = new Dictionary <string, int>(); keyStrokesByBook[CharacterVerseData.GetStandardCharacterId("JER", CharacterVerseData.StandardCharacter.Narrator)] = 52000; keyStrokesByBook[CharacterVerseData.GetStandardCharacterId("EZK", CharacterVerseData.StandardCharacter.Narrator)] = 48000; keyStrokesByBook[CharacterVerseData.GetStandardCharacterId("HOS", CharacterVerseData.StandardCharacter.Narrator)] = 12000; keyStrokesByBook[CharacterVerseData.GetStandardCharacterId("JUD", CharacterVerseData.StandardCharacter.Narrator)] = 1000; var authorStats = new List <AuthorStats>(); var jeremiah = new BiblicalAuthors.Author { Name = "Jeremiah" }; var ezekiel = new BiblicalAuthors.Author { Name = "Ezekiel" }; var hosea = new BiblicalAuthors.Author { Name = "Hosea" }; var jude = new BiblicalAuthors.Author { Name = "Jude" }; authorStats.Add(new AuthorStats(jeremiah, keyStrokesByBook, "JER")); authorStats.Add(new AuthorStats(ezekiel, keyStrokesByBook, "EZK")); authorStats.Add(new AuthorStats(hosea, keyStrokesByBook, "HOS")); authorStats.Add(new AuthorStats(jude, keyStrokesByBook, "JUD")); var narratorGroups = GetNarratorCharacterGroups(3); CharacterGroupGenerator.TrialGroupConfiguration.DistributeBooksAmongNarratorGroups(authorStats, narratorGroups); var groupForJeremiah = GetNarratorGroupForBook(narratorGroups, "JER"); var groupForJude = GetNarratorGroupForBook(narratorGroups, "JUD"); Assert.AreNotEqual(groupForJeremiah, GetNarratorGroupForBook(narratorGroups, "EZK")); Assert.AreNotEqual(groupForJeremiah, groupForJude); Assert.AreEqual(groupForJude, GetNarratorGroupForBook(narratorGroups, "HOS")); }
private void SetCharacterAndDelivery(Block block, Character selectedCharacter, Delivery selectedDelivery) { if (CharacterVerseData.IsCharacterUnclear(selectedCharacter.CharacterId)) { throw new ArgumentException("Character cannot be confirmed as ambiguous or unknown.", nameof(selectedCharacter)); } // If the user sets a non-narrator to a block we marked as narrator, we want to track it if (!selectedCharacter.IsNarrator && !block.IsQuote) { Analytics.Track("NarratorToQuote", new Dictionary <string, string> { { "book", CurrentBookId }, { "chapter", block.ChapterNumber.ToString(CultureInfo.InvariantCulture) }, { "initialStartVerse", block.InitialStartVerseNumber.ToString(CultureInfo.InvariantCulture) }, { "lastVerse", block.LastVerseNum.ToString(CultureInfo.InvariantCulture) }, { "character", selectedCharacter.CharacterId } }); } SetCharacter(block, selectedCharacter); block.Delivery = selectedDelivery.IsNormal ? null : selectedDelivery.Text; AddRecordsToProjectControlFilesIfNeeded(block); }
public bool IsModified(Character newCharacter, Delivery newDelivery) { Block currentBlock = CurrentBlockInOriginal; if (CharacterVerseData.IsCharacterExtraBiblical(currentBlock.CharacterId)) { return(false); // Can't change these. } if (newCharacter == null) { return(!(currentBlock.CharacterIsUnclear || currentBlock.CharacterId == null)); } if (newCharacter.IsNarrator) { if (!currentBlock.CharacterIs(CurrentBookId, CharacterVerseData.StandardCharacter.Narrator)) { return(true); } } else if (newCharacter.CharacterId != currentBlock.CharacterId) { return(true); } if (newDelivery == null) { return(true); } if (newDelivery.IsNormal) { return(!string.IsNullOrEmpty(currentBlock.Delivery)); } return(newDelivery.Text != currentBlock.Delivery); }
private void AddRecordToProjectCharacterVerseData(Block block, Character character, Delivery delivery) { CharacterDetail detail; if (m_pendingCharacterDetails.TryGetValue(character.CharacterId, out detail)) { m_project.AddProjectCharacterDetail(detail); m_project.SaveProjectCharacterDetailData(); m_pendingCharacterDetails.Remove(detail.CharacterId); } var cv = new CharacterVerse( new BCVRef(GetBlockVerseRef(block, ScrVers.English).BBBCCCVVV), character.IsNarrator ? CharacterVerseData.GetStandardCharacterId(CurrentBookId, CharacterVerseData.StandardCharacter.Narrator) : character.CharacterId, delivery.IsNormal ? null : delivery.Text, character.Alias, character.ProjectSpecific || delivery.ProjectSpecific); m_projectCharacterVerseData.Add(cv); m_project.SaveProjectCharacterVerseData(); }
public static void SimulateDisambiguationForAllBooks(Project testProject) { var cvData = new CombinedCharacterVerseData(testProject); foreach (var book in testProject.IncludedBooks) { var bookNum = BCVRef.BookToNumber(book.BookId); foreach (var block in book.GetScriptBlocks()) { if (block.CharacterId == CharacterVerseData.kUnknownCharacter) { block.SetCharacterAndCharacterIdInScript(CharacterVerseData.GetStandardCharacterId(book.BookId, CharacterVerseData.StandardCharacter.Narrator), bookNum, testProject.Versification); } else if (block.CharacterId == CharacterVerseData.kAmbiguousCharacter) { var cvEntry = cvData.GetCharacters(bookNum, block.ChapterNumber, block.InitialStartVerseNumber, block.InitialEndVerseNumber, versification: testProject.Versification).First(); block.SetCharacterAndCharacterIdInScript(cvEntry.Character, bookNum, testProject.Versification); block.Delivery = cvEntry.Delivery; } } } }
private void AddToBestNarratorGroup(string characterId) { // Need tests (and code here) to handle the following scenarios: // 0) number of narrators > number of books -> This should never happen! // 1) DONE: number of narrators == number of books -> Add narrator to first empty narrator group // 2) TODO: number of narrators > number of authors -> break up most prolific authors into multiple narrator groups // 3) DONE: number of narrators == number of authors -> add narrator to group with other books by same other, if any; otherwise first empty group // 4) TODO: number of narrators < number of authors -> shorter books share narrators // 5) DONE: single narrator -> EASY: only one group! CharacterGroup bestNarratorGroup = null; if (m_narratorGroupsByAuthor != null) { var author = BiblicalAuthors.GetAuthorOfBook(CharacterVerseData.GetBookCodeFromStandardCharacterId(characterId)); bestNarratorGroup = m_narratorGroupsByAuthor[author]; } if (bestNarratorGroup == null) { bestNarratorGroup = NarratorGroups.FirstOrDefault(g => !g.CharacterIds.Any()); bestNarratorGroup = bestNarratorGroup ?? NarratorGroups.First(); } bestNarratorGroup.CharacterIds.Add(characterId); }
// internal for testing internal List <List <object> > GetExportData(string bookId = null, int voiceActorId = -1) { var result = new List <List <object> >(); int blockNumber = 1; IEnumerable <BookScript> booksToInclude = bookId == null ? m_booksToExport : m_booksToExport.Where(b => b.BookId == bookId); foreach (var book in booksToInclude) { string singleVoiceNarratorOverride = null; if (book.SingleVoice) { singleVoiceNarratorOverride = CharacterVerseData.GetStandardCharacterId(book.BookId, CharacterVerseData.StandardCharacter.Narrator); } List <Block> pendingMismatchedReferenceBlocks = null; foreach (var block in book.GetScriptBlocks()) { if (block.IsChapterAnnouncement && block.ChapterNumber == 1) { if (Project.SkipChapterAnnouncementForFirstChapter) { continue; } if (Project.SkipChapterAnnouncementForSingleChapterBooks && Project.Versification.LastChapter(BCVRef.BookToNumber(book.BookId)) == 1) { continue; } } VoiceActor.VoiceActor voiceActor = null; bool includeInOutput = true; if (IncludeVoiceActors) { voiceActor = Project.GetVoiceActorForCharacter(singleVoiceNarratorOverride ?? block.CharacterIdInScript) ?? GetDummyActor(); includeInOutput = voiceActorId == -1 || voiceActor.Id == voiceActorId; } if (includeInOutput) { if (pendingMismatchedReferenceBlocks != null && block.ReferenceBlocks.Any()) { foreach (var refBlock in pendingMismatchedReferenceBlocks) { result.Add(GetExportDataForReferenceBlock(refBlock, book.BookId)); } pendingMismatchedReferenceBlocks = null; } result.Add(GetExportDataForBlock(block, blockNumber++, book.BookId, voiceActor, singleVoiceNarratorOverride, IncludeVoiceActors, Project.ReferenceText.HasSecondaryReferenceText)); if (!block.MatchesReferenceText && block.ReferenceBlocks.Any()) { pendingMismatchedReferenceBlocks = block.ReferenceBlocks; } } } if (pendingMismatchedReferenceBlocks != null) { foreach (var refBlock in pendingMismatchedReferenceBlocks) { result.Add(GetExportDataForReferenceBlock(refBlock, book.BookId)); } } } if (bookId == null && voiceActorId == -1) { AddAnnotations(result); } return(result); }
public bool MoveCharactersToGroup(IList <string> characterIds, CharacterGroup destGroup, bool warnUserAboutProximity = false) { CharacterGroup sourceGroup = GetSourceGroupForMove(characterIds, destGroup); if (sourceGroup == null) { return(false); } if (destGroup != null && warnUserAboutProximity && destGroup.CharacterIds.Count > 0) { var proximity = new Proximity(m_project); var testGroup = new CharacterIdHashSet(destGroup.CharacterIds); var resultsBefore = proximity.CalculateMinimumProximity(testGroup); int proximityBefore = resultsBefore.NumberOfBlocks; testGroup.AddRange(characterIds); var resultsAfter = proximity.CalculateMinimumProximity(testGroup); int proximityAfter = resultsAfter.NumberOfBlocks; if (proximityBefore > proximityAfter && proximityAfter <= Proximity.kDefaultMinimumProximity) { var firstReference = new BCVRef(BCVRef.BookToNumber(resultsAfter.FirstBook.BookId), resultsAfter.FirstBlock.ChapterNumber, resultsAfter.FirstBlock.InitialStartVerseNumber).ToString(); var secondReference = new BCVRef(BCVRef.BookToNumber(resultsAfter.SecondBook.BookId), resultsAfter.SecondBlock.ChapterNumber, resultsAfter.SecondBlock.InitialStartVerseNumber).ToString(); var dlgMessageFormat1 = (firstReference == secondReference) ? LocalizationManager.GetString("DialogBoxes.VoiceActorAssignmentDlg.MoveCharacterDialog.Message.Part1", "This move will result in a group with a minimum proximity of {0} blocks between [{1}] and [{2}] in {3}.") : LocalizationManager.GetString("DialogBoxes.VoiceActorAssignmentDlg.MoveCharacterDialog.Message.Part1", "This move will result in a group with a minimum proximity of {0} blocks between [{1}] in {3} and [{2}] in {4}."); dlgMessageFormat1 = string.Format(dlgMessageFormat1, resultsAfter.NumberOfBlocks, CharacterVerseData.GetCharacterNameForUi(resultsAfter.FirstBlock.CharacterIdInScript), CharacterVerseData.GetCharacterNameForUi(resultsAfter.SecondBlock.CharacterIdInScript), firstReference, secondReference); var dlgMessageFormat2 = LocalizationManager.GetString("DialogBoxes.VoiceActorAssignmentDlg.MoveCharacterDialog.Message.Part2", "Do you want to continue with this move?"); var dlgMessage = string.Format(dlgMessageFormat1 + Environment.NewLine + Environment.NewLine + dlgMessageFormat2); var dlgTitle = LocalizationManager.GetString("DialogBoxes.VoiceActorAssignmentDlg.MoveCharacterDialog.Title", "Confirm"); if (MessageBox.Show(dlgMessage, dlgTitle, MessageBoxButtons.YesNo) != DialogResult.Yes) { return(false); } } } m_undoStack.Push(new MoveCharactersToGroupUndoAction(m_project, sourceGroup, destGroup, characterIds)); m_project.CharacterGroupList.PopulateEstimatedHours(m_keyStrokesByCharacterId); Save(); return(true); }
/// <summary>Calculate the minimum number of blocks between two character ids in given collection</summary> public MinimumProximity CalculateMinimumProximity(ISet <string> characterIdsToCalculate) { if (!characterIdsToCalculate.Any()) { return(new MinimumProximity(Int32.MaxValue, null, null, null, null)); } RelatedCharactersData relChar = RelatedCharactersData.Singleton; bool foundFirst = false; int currentBlockCount = 0; int minBlockProximity = Int32.MaxValue; string prevCharacterId = null; ISet <string> prevMatchingCharacterIds = null; BookScript firstBook = null; Block firstBlock = null; BookScript secondBook = null; Block secondBlock = null; BookScript prevBook = null; Block prevBlock = null; bool breakOutOfBothLoops = false; bool calculateAnyRelatedCharacters = characterIdsToCalculate.Any(c => relChar.HasMatchingCharacterIdsOfADifferentAge(c)); foreach (var book in m_booksToConsider) { if (breakOutOfBothLoops) { break; } var countVersesRatherThanBlocks = !m_referenceText.HasContentForBook(book.BookId); var treatAsSameCharacter = m_considerSameExtrabiblicalCharacter[book]; if (m_narrationByAuthor) { var author = BiblicalAuthors.GetAuthorOfBook(book.BookId); if (author.CombineAuthorAndNarrator && !treatAsSameCharacter.Any(set => set.Contains(author.Name))) { if (!m_strictlyAdhereToNarratorPreferences || (characterIdsToCalculate.Contains(book.NarratorCharacterId) && characterIdsToCalculate.Contains(author.Name))) { HashSet <string> charactersToTreatAsOneWithNarrator = treatAsSameCharacter.FirstOrDefault(set => set.Contains(book.NarratorCharacterId)); if (charactersToTreatAsOneWithNarrator == null) { charactersToTreatAsOneWithNarrator = new HashSet <string>(); treatAsSameCharacter.Add(charactersToTreatAsOneWithNarrator); charactersToTreatAsOneWithNarrator.Add(book.NarratorCharacterId); charactersToTreatAsOneWithNarrator.Add(author.Name); } else { charactersToTreatAsOneWithNarrator.Add(author.Name); } } } } // We don't want to treat book ends as being directly adjacent but not infinitely distant, either. currentBlockCount += kDefaultMinimumBlocks * 5 / 3; // The amount of padding is somewhat arbitrary. foreach (var block in book.Blocks) { var characterId = block.CharacterIdInScript; // The original logic here was NOT split out for the single character vs. multiple character scenarios. // This made the code much more readable, but the performance was atrocious since we were creating // extra hashsets and doing extra intersects. Please consider the performance implications of any // changes to this code. (I'm sure it could be optimized further, too...) ISet <string> matchingCharacterIds = null; if (calculateAnyRelatedCharacters && relChar.TryGetMatchingCharacterIdsOfADifferentAge(characterId, out matchingCharacterIds)) { if (matchingCharacterIds.Count == 1) { matchingCharacterIds = null; } } else { foreach (var set in treatAsSameCharacter) { if (set.Contains(characterId)) { matchingCharacterIds = set; break; } } } if (matchingCharacterIds == null) { if ((prevMatchingCharacterIds == null && prevCharacterId == characterId) || (prevMatchingCharacterIds != null && prevMatchingCharacterIds.Contains(characterId))) { currentBlockCount = 0; prevBook = book; prevBlock = block; } else if (characterIdsToCalculate.Contains(characterId) && (!CharacterVerseData.IsCharacterOfType(characterId, CharacterVerseData.StandardCharacter.Narrator) || prevCharacterId == null || !CharacterVerseData.IsCharacterOfType(prevCharacterId, CharacterVerseData.StandardCharacter.Narrator))) { if (ProcessDifferentCharacter(book, block, characterId, matchingCharacterIds, ref foundFirst, ref currentBlockCount, ref minBlockProximity, ref firstBook, ref prevBook, ref firstBlock, ref prevBlock, ref secondBook, ref secondBlock, ref breakOutOfBothLoops, ref prevCharacterId, ref prevMatchingCharacterIds)) { break; } } else { IncrementCount(countVersesRatherThanBlocks, block, ref currentBlockCount); } } else if (prevMatchingCharacterIds != null && matchingCharacterIds.Intersect(prevMatchingCharacterIds).Any()) { currentBlockCount = 0; prevBook = book; prevBlock = block; prevMatchingCharacterIds = matchingCharacterIds; } else if (characterIdsToCalculate.Intersect(matchingCharacterIds).Any()) { if (ProcessDifferentCharacter(book, block, characterId, matchingCharacterIds, ref foundFirst, ref currentBlockCount, ref minBlockProximity, ref firstBook, ref prevBook, ref firstBlock, ref prevBlock, ref secondBook, ref secondBlock, ref breakOutOfBothLoops, ref prevCharacterId, ref prevMatchingCharacterIds)) { break; } } else { IncrementCount(countVersesRatherThanBlocks, block, ref currentBlockCount); } } } return(new MinimumProximity(minBlockProximity, firstBook, secondBook, firstBlock, secondBlock)); }
/// <summary>Populates bookData with the standard characters that should be allowed to be grouped together without causing proximity problems</summary> private void GetStandardCharactersToTreatAsOne(BookScript book, ProjectDramatizationPreferences dramatizationPreferences, Dictionary <ExtraBiblicalMaterialSpeakerOption, HashSet <string> > bookData) { if (m_strictlyAdhereToNarratorPreferences) { AddOrNew(bookData, dramatizationPreferences.BookTitleAndChapterDramatization, CharacterVerseData.GetStandardCharacterId(book.BookId, CharacterVerseData.StandardCharacter.BookOrChapter)); AddOrNew(bookData, dramatizationPreferences.SectionHeadDramatization, CharacterVerseData.GetStandardCharacterId(book.BookId, CharacterVerseData.StandardCharacter.ExtraBiblical)); AddOrNew(bookData, dramatizationPreferences.BookIntroductionsDramatization, CharacterVerseData.GetStandardCharacterId(book.BookId, CharacterVerseData.StandardCharacter.Intro)); bookData.Remove(ExtraBiblicalMaterialSpeakerOption.Omitted); // add the narrator to its group if there are others there already if (bookData.ContainsKey(ExtraBiblicalMaterialSpeakerOption.Narrator)) { bookData[ExtraBiblicalMaterialSpeakerOption.Narrator].Add(book.NarratorCharacterId); } } else { AddOrNew(bookData, ExtraBiblicalMaterialSpeakerOption.Narrator, book.NarratorCharacterId); if (dramatizationPreferences.BookTitleAndChapterDramatization != ExtraBiblicalMaterialSpeakerOption.Omitted) { bookData[ExtraBiblicalMaterialSpeakerOption.Narrator].Add(CharacterVerseData.GetStandardCharacterId(book.BookId, CharacterVerseData.StandardCharacter.BookOrChapter)); } if (dramatizationPreferences.SectionHeadDramatization != ExtraBiblicalMaterialSpeakerOption.Omitted) { bookData[ExtraBiblicalMaterialSpeakerOption.Narrator].Add(CharacterVerseData.GetStandardCharacterId(book.BookId, CharacterVerseData.StandardCharacter.ExtraBiblical)); } if (dramatizationPreferences.BookIntroductionsDramatization != ExtraBiblicalMaterialSpeakerOption.Omitted) { bookData[ExtraBiblicalMaterialSpeakerOption.Narrator].Add(CharacterVerseData.GetStandardCharacterId(book.BookId, CharacterVerseData.StandardCharacter.Intro)); } } }
public static ConcurrentDictionary <BookScript, IReadOnlyList <Block> > Unparse(IEnumerable <BookScript> books) { var blocksInBook = new ConcurrentDictionary <BookScript, IReadOnlyList <Block> >(); Parallel.ForEach(books, book => { var oldBlocks = book.GetScriptBlocks(); var newBlocks = new List <Block>(); Block currentBlock = null; foreach (var oldBlock in oldBlocks) { // is this a new chapter? if (oldBlock.IsParagraphStart || (currentBlock == null)) { if (currentBlock != null) { newBlocks.Add(currentBlock); } if (CharacterVerseData.IsCharacterExtraBiblical(oldBlock.CharacterId) && !oldBlock.UserConfirmed) { newBlocks.Add(oldBlock.Clone()); currentBlock = null; continue; } else { currentBlock = new Block(oldBlock.StyleTag, oldBlock.ChapterNumber, oldBlock.InitialStartVerseNumber, oldBlock.InitialEndVerseNumber); currentBlock.IsParagraphStart = oldBlock.IsParagraphStart; } } foreach (var element in oldBlock.BlockElements) { if (element is Verse) { currentBlock.BlockElements.Add(element.Clone()); continue; } // element is Glyssen.ScriptText // check if this text should be appended to the previous element var lastElement = currentBlock.BlockElements.LastOrDefault() as ScriptText; if (lastElement != null) { lastElement.Content += ((ScriptText)element).Content; } else { currentBlock.BlockElements.Add(element.Clone()); } } } // add the last block now if (currentBlock != null) { newBlocks.Add(currentBlock); } blocksInBook.AddOrUpdate(book, newBlocks, (script, list) => newBlocks); }); return(blocksInBook); }
public void DistributeBooksAmongNarratorGroups_ThirtySixNarrators_BottomFourAuthorsCombineIntoTwoGroups() { var narratorGroups = GetNarratorCharacterGroups(36); VerifyBasic(narratorGroups, 34); Assert.AreEqual(2, narratorGroups[34].CharacterIds.Count); Assert.AreEqual(2, narratorGroups[35].CharacterIds.Count); // Obadiah and Jude are tied for the fewest number of keystrokes. Haggai is by itself in second-to-last place. // Joel, Nahum, Habakkuk, Zephaniah, and Zechariah are all tied for third-to-last place. var bookCombinedWithHaggai = CharacterVerseData.GetBookCodeFromStandardCharacterId(narratorGroups[35].CharacterIds.Single( c => c != CharacterVerseData.GetStandardCharacterId("HAG", CharacterVerseData.StandardCharacter.Narrator))); string bookWhoseAuthorCombinedWithThirdToLastPlaceAuthor; if (bookCombinedWithHaggai == "JUD") { bookWhoseAuthorCombinedWithThirdToLastPlaceAuthor = "OBA"; } else { Assert.AreEqual("OBA", bookCombinedWithHaggai); bookWhoseAuthorCombinedWithThirdToLastPlaceAuthor = "JUD"; } var thirdToLastPlaceBookThatGotCombined = CharacterVerseData.GetBookCodeFromStandardCharacterId( narratorGroups[34].CharacterIds.Single(c => c != CharacterVerseData.GetStandardCharacterId(bookWhoseAuthorCombinedWithThirdToLastPlaceAuthor, CharacterVerseData.StandardCharacter.Narrator))); Assert.IsTrue( thirdToLastPlaceBookThatGotCombined == "JOL" || thirdToLastPlaceBookThatGotCombined == "NAM" || thirdToLastPlaceBookThatGotCombined == "HAB" || thirdToLastPlaceBookThatGotCombined == "ZEP" || thirdToLastPlaceBookThatGotCombined == "ZEC"); }
public void FixtureSetup() { m_keyStrokesByBook = new Dictionary <string, int>(); m_keyStrokesByBook[CharacterVerseData.GetStandardCharacterId("GEN", CharacterVerseData.StandardCharacter.Narrator)] = 50000; // MOSES m_keyStrokesByBook[CharacterVerseData.GetStandardCharacterId("EXO", CharacterVerseData.StandardCharacter.Narrator)] = 40000; // MOSES m_keyStrokesByBook[CharacterVerseData.GetStandardCharacterId("LEV", CharacterVerseData.StandardCharacter.Narrator)] = 27000; // MOSES m_keyStrokesByBook[CharacterVerseData.GetStandardCharacterId("NUM", CharacterVerseData.StandardCharacter.Narrator)] = 36000; // MOSES m_keyStrokesByBook[CharacterVerseData.GetStandardCharacterId("DEU", CharacterVerseData.StandardCharacter.Narrator)] = 34000; // MOSES: 187000 m_keyStrokesByBook[CharacterVerseData.GetStandardCharacterId("JOS", CharacterVerseData.StandardCharacter.Narrator)] = 24000; // JOSHUA: 24000 m_keyStrokesByBook[CharacterVerseData.GetStandardCharacterId("JDG", CharacterVerseData.StandardCharacter.Narrator)] = 21000; // JUDGES: 21000 m_keyStrokesByBook[CharacterVerseData.GetStandardCharacterId("RUT", CharacterVerseData.StandardCharacter.Narrator)] = 4000; // RUTH: 4000 m_keyStrokesByBook[CharacterVerseData.GetStandardCharacterId("1SA", CharacterVerseData.StandardCharacter.Narrator)] = 31000; // SAMUEL m_keyStrokesByBook[CharacterVerseData.GetStandardCharacterId("2SA", CharacterVerseData.StandardCharacter.Narrator)] = 24000; // SAMUEL: 55000 m_keyStrokesByBook[CharacterVerseData.GetStandardCharacterId("1KI", CharacterVerseData.StandardCharacter.Narrator)] = 24000; // KINGS m_keyStrokesByBook[CharacterVerseData.GetStandardCharacterId("2KI", CharacterVerseData.StandardCharacter.Narrator)] = 25000; // KINGS: 49000 m_keyStrokesByBook[CharacterVerseData.GetStandardCharacterId("1CH", CharacterVerseData.StandardCharacter.Narrator)] = 35000; // CHRONICLES m_keyStrokesByBook[CharacterVerseData.GetStandardCharacterId("2CH", CharacterVerseData.StandardCharacter.Narrator)] = 36000; // CHRONICLES: 71000 m_keyStrokesByBook[CharacterVerseData.GetStandardCharacterId("EZR", CharacterVerseData.StandardCharacter.Narrator)] = 10000; // EZRA: 10000 m_keyStrokesByBook[CharacterVerseData.GetStandardCharacterId("NEH", CharacterVerseData.StandardCharacter.Narrator)] = 13000; // NEHEMIAH: 13000 m_keyStrokesByBook[CharacterVerseData.GetStandardCharacterId("EST", CharacterVerseData.StandardCharacter.Narrator)] = 10000; // ESTHER: 10000 m_keyStrokesByBook[CharacterVerseData.GetStandardCharacterId("JOB", CharacterVerseData.StandardCharacter.Narrator)] = 42000; // JOB: 42000 m_keyStrokesByBook[CharacterVerseData.GetStandardCharacterId("PSA", CharacterVerseData.StandardCharacter.Narrator)] = 99999; // PSALMS: 99999 m_keyStrokesByBook[CharacterVerseData.GetStandardCharacterId("PRO", CharacterVerseData.StandardCharacter.Narrator)] = 31000; // SOLOMON m_keyStrokesByBook[CharacterVerseData.GetStandardCharacterId("ECC", CharacterVerseData.StandardCharacter.Narrator)] = 12000; // SOLOMON m_keyStrokesByBook[CharacterVerseData.GetStandardCharacterId("SNG", CharacterVerseData.StandardCharacter.Narrator)] = 8000; // SOLOMON: 51000 m_keyStrokesByBook[CharacterVerseData.GetStandardCharacterId("ISA", CharacterVerseData.StandardCharacter.Narrator)] = 66000; // ISAIAH: 66000 m_keyStrokesByBook[CharacterVerseData.GetStandardCharacterId("JER", CharacterVerseData.StandardCharacter.Narrator)] = 52000; // JEREMIAH m_keyStrokesByBook[CharacterVerseData.GetStandardCharacterId("LAM", CharacterVerseData.StandardCharacter.Narrator)] = 5000; // JEREMIAH: 57000 m_keyStrokesByBook[CharacterVerseData.GetStandardCharacterId("EZK", CharacterVerseData.StandardCharacter.Narrator)] = 48000; // EZEKIEL: 48000 m_keyStrokesByBook[CharacterVerseData.GetStandardCharacterId("DAN", CharacterVerseData.StandardCharacter.Narrator)] = 12000; // DANIEL: 12000 m_keyStrokesByBook[CharacterVerseData.GetStandardCharacterId("HOS", CharacterVerseData.StandardCharacter.Narrator)] = 14000; // HOSEA: 14000 m_keyStrokesByBook[CharacterVerseData.GetStandardCharacterId("JOL", CharacterVerseData.StandardCharacter.Narrator)] = 3000; // JOEL: 3000 m_keyStrokesByBook[CharacterVerseData.GetStandardCharacterId("AMO", CharacterVerseData.StandardCharacter.Narrator)] = 9000; // AMOS: 9000 m_keyStrokesByBook[CharacterVerseData.GetStandardCharacterId("OBA", CharacterVerseData.StandardCharacter.Narrator)] = 1000; // OBADIAH: 1000 m_keyStrokesByBook[CharacterVerseData.GetStandardCharacterId("JON", CharacterVerseData.StandardCharacter.Narrator)] = 4000; // JONAH: 4000 m_keyStrokesByBook[CharacterVerseData.GetStandardCharacterId("MIC", CharacterVerseData.StandardCharacter.Narrator)] = 7000; // MICAH: 7000 m_keyStrokesByBook[CharacterVerseData.GetStandardCharacterId("NAM", CharacterVerseData.StandardCharacter.Narrator)] = 3000; // NAHUM: 3000 m_keyStrokesByBook[CharacterVerseData.GetStandardCharacterId("HAB", CharacterVerseData.StandardCharacter.Narrator)] = 3000; // HABAKKUK: 3000 m_keyStrokesByBook[CharacterVerseData.GetStandardCharacterId("ZEP", CharacterVerseData.StandardCharacter.Narrator)] = 3000; // ZEPHANIAH: 3000 m_keyStrokesByBook[CharacterVerseData.GetStandardCharacterId("HAG", CharacterVerseData.StandardCharacter.Narrator)] = 2000; // HAGGAI: 2000 m_keyStrokesByBook[CharacterVerseData.GetStandardCharacterId("ZEC", CharacterVerseData.StandardCharacter.Narrator)] = 3000; // ZECHARIAH: 3000 m_keyStrokesByBook[CharacterVerseData.GetStandardCharacterId("MAL", CharacterVerseData.StandardCharacter.Narrator)] = 4000; // MALACHI: 4000 m_keyStrokesByBook[CharacterVerseData.GetStandardCharacterId("MAT", CharacterVerseData.StandardCharacter.Narrator)] = 28000; // MATTHEW: 28000 m_keyStrokesByBook[CharacterVerseData.GetStandardCharacterId("MRK", CharacterVerseData.StandardCharacter.Narrator)] = 16000; // MARK: 16000 m_keyStrokesByBook[CharacterVerseData.GetStandardCharacterId("LUK", CharacterVerseData.StandardCharacter.Narrator)] = 24000; // LUKE m_keyStrokesByBook[CharacterVerseData.GetStandardCharacterId("ACT", CharacterVerseData.StandardCharacter.Narrator)] = 28000; // LUKE: 52000 m_keyStrokesByBook[CharacterVerseData.GetStandardCharacterId("JHN", CharacterVerseData.StandardCharacter.Narrator)] = 20000; // JOHN m_keyStrokesByBook[CharacterVerseData.GetStandardCharacterId("1JN", CharacterVerseData.StandardCharacter.Narrator)] = 5000; // JOHN m_keyStrokesByBook[CharacterVerseData.GetStandardCharacterId("2JN", CharacterVerseData.StandardCharacter.Narrator)] = 1000; // JOHN m_keyStrokesByBook[CharacterVerseData.GetStandardCharacterId("3JN", CharacterVerseData.StandardCharacter.Narrator)] = 1000; // JOHN m_keyStrokesByBook[CharacterVerseData.GetStandardCharacterId("REV", CharacterVerseData.StandardCharacter.Narrator)] = 22000; // JOHN: 49000 m_keyStrokesByBook[CharacterVerseData.GetStandardCharacterId("ROM", CharacterVerseData.StandardCharacter.Narrator)] = 16000; // PAUL m_keyStrokesByBook[CharacterVerseData.GetStandardCharacterId("1CO", CharacterVerseData.StandardCharacter.Narrator)] = 16000; // PAUL m_keyStrokesByBook[CharacterVerseData.GetStandardCharacterId("2CO", CharacterVerseData.StandardCharacter.Narrator)] = 13000; // PAUL m_keyStrokesByBook[CharacterVerseData.GetStandardCharacterId("GAL", CharacterVerseData.StandardCharacter.Narrator)] = 6000; // PAUL m_keyStrokesByBook[CharacterVerseData.GetStandardCharacterId("EPH", CharacterVerseData.StandardCharacter.Narrator)] = 6000; // PAUL m_keyStrokesByBook[CharacterVerseData.GetStandardCharacterId("PHP", CharacterVerseData.StandardCharacter.Narrator)] = 4000; // PAUL m_keyStrokesByBook[CharacterVerseData.GetStandardCharacterId("COL", CharacterVerseData.StandardCharacter.Narrator)] = 4000; // PAUL m_keyStrokesByBook[CharacterVerseData.GetStandardCharacterId("1TH", CharacterVerseData.StandardCharacter.Narrator)] = 5000; // PAUL m_keyStrokesByBook[CharacterVerseData.GetStandardCharacterId("2TH", CharacterVerseData.StandardCharacter.Narrator)] = 3000; // PAUL m_keyStrokesByBook[CharacterVerseData.GetStandardCharacterId("1TI", CharacterVerseData.StandardCharacter.Narrator)] = 6000; // PAUL m_keyStrokesByBook[CharacterVerseData.GetStandardCharacterId("2TI", CharacterVerseData.StandardCharacter.Narrator)] = 4000; // PAUL m_keyStrokesByBook[CharacterVerseData.GetStandardCharacterId("TIT", CharacterVerseData.StandardCharacter.Narrator)] = 3000; // PAUL m_keyStrokesByBook[CharacterVerseData.GetStandardCharacterId("PHM", CharacterVerseData.StandardCharacter.Narrator)] = 1000; // PAUL: 87000 m_keyStrokesByBook[CharacterVerseData.GetStandardCharacterId("HEB", CharacterVerseData.StandardCharacter.Narrator)] = 13000; // HEBREWS: 13000 m_keyStrokesByBook[CharacterVerseData.GetStandardCharacterId("JAS", CharacterVerseData.StandardCharacter.Narrator)] = 5000; // JAMES: 5000 m_keyStrokesByBook[CharacterVerseData.GetStandardCharacterId("1PE", CharacterVerseData.StandardCharacter.Narrator)] = 5000; // PETER m_keyStrokesByBook[CharacterVerseData.GetStandardCharacterId("2PE", CharacterVerseData.StandardCharacter.Narrator)] = 3000; // PETER: 8000 m_keyStrokesByBook[CharacterVerseData.GetStandardCharacterId("JUD", CharacterVerseData.StandardCharacter.Narrator)] = 1000; // JUDE: 1000 m_authorStats = new List <AuthorStats>(); m_moses = new BiblicalAuthors.Author { Name = "Moses" }; m_joshua = new BiblicalAuthors.Author { Name = "Joshua" }; m_judges = new BiblicalAuthors.Author { Name = "Author of Judges" }; m_ruth = new BiblicalAuthors.Author { Name = "Author of Ruth" }; m_samuel = new BiblicalAuthors.Author { Name = "Samuel" }; m_kings = new BiblicalAuthors.Author { Name = "Author of Kings" }; m_chronicles = new BiblicalAuthors.Author { Name = "Author of Chronicles" }; m_ezra = new BiblicalAuthors.Author { Name = "Ezra" }; m_nehemiah = new BiblicalAuthors.Author { Name = "Nehemiah" }; m_esther = new BiblicalAuthors.Author { Name = "Author of Esther" }; m_job = new BiblicalAuthors.Author { Name = "Job" }; m_psalms = new BiblicalAuthors.Author { Name = "Author of Psalms" }; m_solomon = new BiblicalAuthors.Author { Name = "Solomon" }; m_isaiah = new BiblicalAuthors.Author { Name = "Isaiah" }; m_jeremiah = new BiblicalAuthors.Author { Name = "Jeremiah" }; m_ezekiel = new BiblicalAuthors.Author { Name = "Ezekiel" }; m_daniel = new BiblicalAuthors.Author { Name = "Daniel" }; m_hosea = new BiblicalAuthors.Author { Name = "Hosea" }; m_joel = new BiblicalAuthors.Author { Name = "Joel" }; m_amos = new BiblicalAuthors.Author { Name = "Amos" }; m_obadiah = new BiblicalAuthors.Author { Name = "Obadiah" }; m_jonah = new BiblicalAuthors.Author { Name = "Jonah" }; m_micah = new BiblicalAuthors.Author { Name = "Micah" }; m_nahum = new BiblicalAuthors.Author { Name = "Nahum" }; m_habakkuk = new BiblicalAuthors.Author { Name = "Habakkuk" }; m_zephaniah = new BiblicalAuthors.Author { Name = "Zephaniah" }; m_haggai = new BiblicalAuthors.Author { Name = "Haggai" }; m_zechariah = new BiblicalAuthors.Author { Name = "Zechariah" }; m_malachi = new BiblicalAuthors.Author { Name = "Malachi" }; m_matthew = new BiblicalAuthors.Author { Name = "Matthew" }; m_mark = new BiblicalAuthors.Author { Name = "Mark" }; m_luke = new BiblicalAuthors.Author { Name = "Luke" }; m_john = new BiblicalAuthors.Author { Name = "John" }; m_paul = new BiblicalAuthors.Author { Name = "Paul" }; m_hebrews = new BiblicalAuthors.Author { Name = "Author of Hebrews" }; m_james = new BiblicalAuthors.Author { Name = "James" }; m_peter = new BiblicalAuthors.Author { Name = "Peter" }; m_jude = new BiblicalAuthors.Author { Name = "Jude" }; m_authorStats.Add(new AuthorStats(m_moses, m_keyStrokesByBook, "GEN", "EXO", "LEV", "NUM", "DEU")); m_authorStats.Add(new AuthorStats(m_joshua, m_keyStrokesByBook, "JOS")); m_authorStats.Add(new AuthorStats(m_judges, m_keyStrokesByBook, "JDG")); m_authorStats.Add(new AuthorStats(m_ruth, m_keyStrokesByBook, "RUT")); m_authorStats.Add(new AuthorStats(m_samuel, m_keyStrokesByBook, "1SA", "2SA")); m_authorStats.Add(new AuthorStats(m_kings, m_keyStrokesByBook, "1KI", "2KI")); m_authorStats.Add(new AuthorStats(m_chronicles, m_keyStrokesByBook, "1CH", "2CH")); m_authorStats.Add(new AuthorStats(m_ezra, m_keyStrokesByBook, "EZR")); m_authorStats.Add(new AuthorStats(m_nehemiah, m_keyStrokesByBook, "NEH")); m_authorStats.Add(new AuthorStats(m_esther, m_keyStrokesByBook, "EST")); m_authorStats.Add(new AuthorStats(m_job, m_keyStrokesByBook, "JOB")); m_authorStats.Add(new AuthorStats(m_psalms, m_keyStrokesByBook, "PSA")); m_authorStats.Add(new AuthorStats(m_solomon, m_keyStrokesByBook, "PRO", "ECC", "SNG")); m_authorStats.Add(new AuthorStats(m_isaiah, m_keyStrokesByBook, "ISA")); m_authorStats.Add(new AuthorStats(m_jeremiah, m_keyStrokesByBook, "JER", "LAM")); m_authorStats.Add(new AuthorStats(m_ezekiel, m_keyStrokesByBook, "EZK")); m_authorStats.Add(new AuthorStats(m_daniel, m_keyStrokesByBook, "DAN")); m_authorStats.Add(new AuthorStats(m_hosea, m_keyStrokesByBook, "HOS")); m_authorStats.Add(new AuthorStats(m_joel, m_keyStrokesByBook, "JOL")); m_authorStats.Add(new AuthorStats(m_amos, m_keyStrokesByBook, "AMO")); m_authorStats.Add(new AuthorStats(m_obadiah, m_keyStrokesByBook, "OBA")); m_authorStats.Add(new AuthorStats(m_jonah, m_keyStrokesByBook, "JON")); m_authorStats.Add(new AuthorStats(m_micah, m_keyStrokesByBook, "MIC")); m_authorStats.Add(new AuthorStats(m_nahum, m_keyStrokesByBook, "NAM")); m_authorStats.Add(new AuthorStats(m_habakkuk, m_keyStrokesByBook, "HAB")); m_authorStats.Add(new AuthorStats(m_zephaniah, m_keyStrokesByBook, "ZEP")); m_authorStats.Add(new AuthorStats(m_haggai, m_keyStrokesByBook, "HAG")); m_authorStats.Add(new AuthorStats(m_zechariah, m_keyStrokesByBook, "ZEC")); m_authorStats.Add(new AuthorStats(m_malachi, m_keyStrokesByBook, "MAL")); m_authorStats.Add(new AuthorStats(m_matthew, m_keyStrokesByBook, "MAT")); m_authorStats.Add(new AuthorStats(m_mark, m_keyStrokesByBook, "MRK")); m_authorStats.Add(new AuthorStats(m_luke, m_keyStrokesByBook, "LUK", "ACT")); m_authorStats.Add(new AuthorStats(m_john, m_keyStrokesByBook, "JHN", "1JN", "2JN", "3JN", "REV")); m_authorStats.Add(new AuthorStats(m_paul, m_keyStrokesByBook, "ROM", "1CO", "2CO", "GAL", "EPH", "PHP", "COL", "1TH", "2TH", "1TI", "2TI", "TIT", "PHM")); m_authorStats.Add(new AuthorStats(m_hebrews, m_keyStrokesByBook, "HEB")); m_authorStats.Add(new AuthorStats(m_james, m_keyStrokesByBook, "JAS")); m_authorStats.Add(new AuthorStats(m_peter, m_keyStrokesByBook, "1PE", "2PE")); m_authorStats.Add(new AuthorStats(m_jude, m_keyStrokesByBook, "JUD")); Assert.AreEqual(38, m_authorStats.Count); }
private void SetBlockCharacterToNarrator(string bookCode, int chapter, int verse, string existingCharacterId) { m_testProject.Books.Single(book => book.BookId == bookCode).GetBlocksForVerse(chapter, verse) .Single(b => b.CharacterId == existingCharacterId).CharacterId = CharacterVerseData.GetStandardCharacterId(bookCode, CharacterVerseData.StandardCharacter.Narrator); }
public System.Collections.Generic.IReadOnlyList <Block> GetScriptBlocks(bool join) { if (!join) { return(GetScriptBlocks()); } EnsureBlockCount(); if (!join || m_blockCount == 0) { return(m_blocks); } var list = new List <Block>(m_blockCount); if (SingleVoice) { list.Add(m_blocks[0].Clone()); var prevBlock = list.Single(); prevBlock.MatchesReferenceText = false; var narrator = CharacterVerseData.GetStandardCharacterId(BookId, CharacterVerseData.StandardCharacter.Narrator); for (var i = 1; i < m_blockCount; i++) { var clonedBlock = m_blocks[i].Clone(); clonedBlock.MatchesReferenceText = false; if (!clonedBlock.CharacterIsStandard) { clonedBlock.CharacterId = narrator; } if (!clonedBlock.IsParagraphStart || (clonedBlock.IsFollowOnParagraphStyle && !CharacterUtils.EndsWithSentenceFinalPunctuation(prevBlock.GetText(false)))) // && clonedBlock.CharacterId == prevBlock.CharacterId) { prevBlock.CombineWith(clonedBlock); } else { list.Add(clonedBlock); prevBlock = clonedBlock; } } } else { list.Add(m_blocks[0]); if (m_styleSheet == null) { m_styleSheet = SfmLoader.GetUsfmStylesheet(); } for (var i = 1; i < m_blockCount; i++) { var block = m_blocks[i]; var prevBlock = list.Last(); if (block.MatchesReferenceText == prevBlock.MatchesReferenceText && block.CharacterIdInScript == prevBlock.CharacterIdInScript && (block.Delivery ?? Empty) == (prevBlock.Delivery ?? Empty)) { bool combine = false; if (block.MatchesReferenceText) { combine = block.ReferenceBlocks.Single().StartsWithEllipsis || ((!block.IsParagraphStart || (block.IsFollowOnParagraphStyle && !CharacterUtils.EndsWithSentenceFinalPunctuation(prevBlock.GetText(false)))) && !block.ContainsVerseNumber && ((!block.ReferenceBlocks.Single().BlockElements.OfType <Verse>().Any() && !CharacterUtils.EndsWithSentenceFinalPunctuation(prevBlock.GetText(false))) || block.ReferenceBlocks.Single().BlockElements.OfType <ScriptText>().All(t => t.Content.All(IsWhiteSpace)) || prevBlock.ReferenceBlocks.Single().BlockElements.OfType <ScriptText>().All(t => t.Content.All(IsWhiteSpace)))); } else if (!block.StartsAtVerseStart) { var style = (StyleAdapter)m_styleSheet.GetStyle(block.StyleTag); combine = !block.IsParagraphStart || (style.IsPoetic && !CharacterUtils.EndsWithSentenceFinalPunctuation(prevBlock.GetText(false))); } if (combine) { list[list.Count - 1] = Block.CombineBlocks(prevBlock, block); continue; } } list.Add(block); } } return(list); }
public void DataIntegrity_RequiredFieldsHaveValidFormatAndThereAreNoDuplicateLines() { Regex regex = new Regex(kRegexBCV + "(?<character>[^\t]+)\t(?<delivery>[^\t]*)\t(?<alias>[^\t]*)\t(?<type>" + typeof(QuoteType).GetRegexEnumValuesString() + ")\t(?<defaultCharacter>[^\t]*)\t(?<parallelPassageRef>[^\t]*)$", RegexOptions.Compiled); Regex extraSpacesRegex = new Regex("^ |\t | \t| $", RegexOptions.Compiled); var set = new HashSet <string>(); ISet <CharacterVerse> uniqueCharacterVerses = new HashSet <CharacterVerse>(); foreach (var line in AllDataLines) { var match = regex.Match(line); Assert.IsTrue(match.Success, "Failed to match line: " + line); var bookId = match.Result("${bookId}"); var bookNum = BCVRef.BookToNumber(bookId); Assert.IsTrue(bookNum > 0, "Line: " + line); Assert.IsTrue(bookNum <= 66, "Line: " + line); var chapterAsString = match.Result("${chapter}"); var chapter = Int32.Parse(chapterAsString); Assert.IsTrue(chapter > 0, "Line: " + line); Assert.IsTrue(chapter <= ScrVers.English.GetLastChapter(bookNum), "Line: " + line); var verseAsString = match.Result("${verse}"); var verse = Int32.Parse(verseAsString); Assert.IsTrue(verse > 0 || verse == 0 && bookId == "PSA", "Line: " + line); Assert.IsTrue(verse <= ScrVers.English.GetLastVerse(bookNum, chapter), "Line: " + line); var sEndVerse = match.Result("${endVerse}"); if (!string.IsNullOrEmpty(sEndVerse)) { var endVerse = Int32.Parse(sEndVerse); Assert.IsTrue(endVerse > verse, "Line: " + line); Assert.IsTrue(endVerse <= 152, "Line: " + line); } var character = match.Result("${character}"); var alias = match.Result("${alias}"); if (!string.IsNullOrEmpty(alias)) { Assert.AreNotEqual(character, alias, "Line: " + line); } var defaultCharacter = match.Result("${defaultCharacter}"); if (!string.IsNullOrEmpty(defaultCharacter)) { Assert.AreNotEqual(character, defaultCharacter, "Line: " + line); Assert.IsFalse(defaultCharacter.Contains("/"), $"Line: {line} has a default character which is a multi-character ID."); } string typeAsString = match.Result("${type}"); if (CharacterVerseData.IsCharacterOfType(character, CharacterVerseData.StandardCharacter.Narrator)) { Assert.AreNotEqual("Dialogue", typeAsString, "Line: " + line); } var matchResult = match.Result("$&"); Assert.IsTrue(set.Add(matchResult), "Duplicate line: " + matchResult); Assert.IsTrue(QuoteType.TryParse(typeAsString, out QuoteType type)); foreach (var bcvRef in CharacterVerseData.GetAllVerses(new [] { bookId, chapterAsString, verseAsString }, () => throw new Exception("This should never happen"))) { var cv = new CharacterVerse(bcvRef, character, match.Result("${delivery}"), alias, false, type, defaultCharacter); Assert.IsTrue(uniqueCharacterVerses.Add(cv), "Line is equivalent to another line even though they are not identical: " + matchResult); } var extraSpacesMatch = extraSpacesRegex.Match(line); Assert.IsFalse(extraSpacesMatch.Success, "Line with extra space(s): " + line); } }
public void MakeMinimalAdjustments_FewAdditions_NewGroupAddedWithNewCharacters() { SetVoiceActors(9, 2, 1); GenerateGroups(); m_testProject.AvailableBooks.Single(b => b.Code == "JUD").IncludeInScript = true; m_testProject.ClearCharacterStatistics(); // This simulates behavior in UI when the project is saved after displaying ScriptureRangeSelectionDlg var adjuster = new CharacterGroupsAdjuster(m_testProject); Assert.IsTrue(adjuster.CharactersNotCoveredByAnyGroup.Contains(CharacterVerseData.GetStandardCharacterId("JUD", CharacterVerseData.StandardCharacter.Narrator))); Assert.IsTrue(adjuster.CharactersNotCoveredByAnyGroup.Contains(CharacterVerseData.GetStandardCharacterId("JUD", CharacterVerseData.StandardCharacter.ExtraBiblical))); Assert.IsTrue(adjuster.CharactersNotCoveredByAnyGroup.Contains(CharacterVerseData.GetStandardCharacterId("JUD", CharacterVerseData.StandardCharacter.BookOrChapter))); var countOfCharactersNotCovered = adjuster.CharactersNotCoveredByAnyGroup.Count(); Assert.AreEqual(0, adjuster.CharactersNoLongerInUse.Count()); var originalCountOfGroups = m_testProject.CharacterGroupList.CharacterGroups.Count; adjuster.MakeMinimalAdjustments(); Assert.IsFalse(adjuster.GroupsAreNotInSynchWithData); Assert.AreEqual(0, adjuster.CharactersNotCoveredByAnyGroup.Count()); Assert.AreEqual(0, adjuster.CharactersNoLongerInUse.Count()); Assert.AreEqual(originalCountOfGroups + 1, m_testProject.CharacterGroupList.CharacterGroups.Count); var newGroup = m_testProject.CharacterGroupList.GroupContainingCharacterId(CharacterVerseData.GetStandardCharacterId("JUD", CharacterVerseData.StandardCharacter.Narrator)); Assert.IsFalse(m_testProject.CharacterGroupList.CharacterGroups.Any(g => g.GroupId == newGroup.GroupId && g != newGroup)); Assert.IsTrue(newGroup.CharacterIds.Contains(CharacterVerseData.GetStandardCharacterId("JUD", CharacterVerseData.StandardCharacter.ExtraBiblical))); Assert.IsTrue(newGroup.CharacterIds.Contains(CharacterVerseData.GetStandardCharacterId("JUD", CharacterVerseData.StandardCharacter.BookOrChapter))); Assert.AreEqual(countOfCharactersNotCovered, newGroup.CharacterIds.Count); }