public BookBlockIndices GetIndicesOfFirstBlockAtReference(VerseRef verseRef) { var bookId = verseRef.Book; int bookIndex = -1; BookScript book = null; for (int i = 0; i < m_books.Count; i++) { book = m_books[i]; if (book.BookId == bookId) { bookIndex = i; break; } } if (bookIndex == -1 || book == null) { return(null); } var blockIndex = book.Blocks.IndexOf( a => a.ChapterNumber == verseRef.ChapterNum && a.InitialStartVerseNumber <= verseRef.VerseNum && a.LastVerse >= verseRef.VerseNum); return(blockIndex == -1 ? null : new BookBlockIndices(bookIndex, blockIndex)); }
internal void SetIndices(BookBlockIndices indices) { m_currentBookIndex = indices.BookIndex; m_currentBook = m_books[m_currentBookIndex]; m_currentBlockIndex = indices.BlockIndex; m_currentBlock = m_currentBook.GetScriptBlocks()[m_currentBlockIndex]; }
public BlockMatchup GetBlocksForVerseMatchedToReferenceText(BookScript vernacularBook, int iBlock, ScrVers vernacularVersification) { if (iBlock < 0 || iBlock >= vernacularBook.GetScriptBlocks().Count) { throw new ArgumentOutOfRangeException("iBlock"); } if (!Books.Any(b => b.BookId == vernacularBook.BookId)) { return(null); } int bookNum = BCVRef.BookToNumber(vernacularBook.BookId); var referenceBook = Books.Single(b => b.BookId == vernacularBook.BookId); var verseSplitLocationsBasedOnRef = GetVerseSplitLocations(referenceBook, bookNum); var matchup = new BlockMatchup(vernacularBook, iBlock, portion => { MakesSplits(portion, bookNum, vernacularVersification, verseSplitLocationsBasedOnRef, "vernacular", LanguageName); }, nextVerse => { nextVerse.Versification = vernacularVersification; return(verseSplitLocationsBasedOnRef.Any(s => s.Before.CompareTo(nextVerse) == 0)); }, this); if (!matchup.AllScriptureBlocksMatch) { MatchVernBlocksToReferenceTextBlocks(matchup.CorrelatedBlocks, vernacularBook.BookId, vernacularVersification); } return(matchup); }
public BlockMatchup GetBlocksForVerseMatchedToReferenceText(BookScript vernacularBook, int iBlock, ScrVers vernacularVersification, uint predeterminedBlockCount = 0) { if (iBlock < 0 || iBlock >= vernacularBook.GetScriptBlocks().Count) { throw new ArgumentOutOfRangeException("iBlock"); } if (!CanDisplayReferenceTextForBook(vernacularBook)) { return(null); } int bookNum = BCVRef.BookToNumber(vernacularBook.BookId); var verseSplitLocationsBasedOnRef = GetVerseSplitLocations(vernacularBook.BookId); var matchup = new BlockMatchup(vernacularBook, iBlock, portion => { MakesSplits(portion, bookNum, vernacularVersification, verseSplitLocationsBasedOnRef, "vernacular", LanguageName); }, nextVerse => IsOkayToSplitAtVerse(nextVerse, vernacularVersification, verseSplitLocationsBasedOnRef), this, predeterminedBlockCount); if (!matchup.AllScriptureBlocksMatch) { MatchVernBlocksToReferenceTextBlocks(matchup.CorrelatedBlocks, vernacularBook.BookId, vernacularVersification); } return(matchup); }
private BookScript NextBook() { if (IsLastBook(m_currentBook)) { return(null); } return(m_currentBook = m_books[++m_currentBookIndex]); }
private BookScript PreviousBook() { if (IsFirstBook(m_currentBook)) { return(null); } return(m_currentBook = m_books[--m_currentBookIndex]); }
public BookScript Clone(bool join) { BookScript newBook = (BookScript)MemberwiseClone(); newBook.Blocks = new List <Block>(GetScriptBlocks(join).Select(b => b.Clone())); newBook.m_unappliedSplitBlocks = new List <List <Block> >(m_unappliedSplitBlocks.Select(l => l.Select(b => b.Clone()).ToList())); return(newBook); }
public bool IsFirstBook(BookScript book) { if (!m_books.Any()) { return(false); } return(book == m_books.First()); }
public static List <BookScript> ParseProject(IEnumerable <UsxDocument> books, IStylesheet stylesheet, BackgroundWorker projectWorker) { var numBlocksPerBook = new ConcurrentDictionary <string, int>(); var blocksInBook = new ConcurrentDictionary <string, XmlNodeList>(); Parallel.ForEach(books, bookScript => { var nodeList = bookScript.GetChaptersAndParas(); blocksInBook.AddOrUpdate(bookScript.BookId, nodeList, (s, list) => nodeList); numBlocksPerBook.AddOrUpdate(bookScript.BookId, nodeList.Count, (s, i) => nodeList.Count); }); int allProjectBlocks = numBlocksPerBook.Values.Sum(); int completedProjectBlocks = 0; var bookScripts = new List <BookScript>(); Parallel.ForEach(blocksInBook, book => { var bookId = book.Key; Logger.WriteEvent("Creating bookScript ({0})", bookId); var bookScript = new BookScript(bookId, new UsxParser(bookId, stylesheet, book.Value).Parse()); Logger.WriteEvent("Created bookScript ({0}, {1})", bookId, bookScript.BookId); bookScripts.Add(bookScript); Logger.WriteEvent("Added bookScript ({0}, {1})", bookId, bookScript.BookId); completedProjectBlocks += numBlocksPerBook[bookId]; projectWorker.ReportProgress(MathUtilities.Percent(completedProjectBlocks, allProjectBlocks, 99)); }); // This code is an attempt to figure out how we are getting null reference exceptions on the Sort call (See PG-275 & PG-287) foreach (var bookScript in bookScripts) { if (bookScript == null || bookScript.BookId == null) { var nonNullBookScripts = bookScripts.Where(b => b != null).Select(b => b.BookId); var nonNullBookScriptsStr = string.Join(";", nonNullBookScripts); var initialMessage = bookScript == null ? "BookScript is null." : "BookScript has null BookId."; throw new ApplicationException(string.Format("{0} Number of BookScripts: {1}. BookScripts which are NOT null: {2}", initialMessage, bookScripts.Count, nonNullBookScriptsStr)); } } try { bookScripts.Sort((a, b) => BCVRef.BookToNumber(a.BookId).CompareTo(BCVRef.BookToNumber(b.BookId))); } catch (NullReferenceException n) { // This code is an attempt to figure out how we are getting null reference exceptions on the Sort call (See PG-275 & PG-287) StringBuilder sb = new StringBuilder(); foreach (var bookScript in bookScripts) { sb.Append(Environment.NewLine).Append(bookScript.BookId).Append("(").Append(BCVRef.BookToNumber(bookScript.BookId)).Append(")"); } throw new NullReferenceException("Null reference exception while sorting books." + sb, n); } projectWorker.ReportProgress(100); return(bookScripts); }
public BlockNavigator(IReadOnlyList <BookScript> books) { m_books = books; m_currentBook = m_books.FirstOrDefault(b => b.HasScriptBlocks); if (m_currentBook == null) { throw new ArgumentException("The list of books must contain at least one block."); } m_currentBlock = m_currentBook[0]; }
private Block PeekNthNextBlockWithinBook(int n, int bookIndex, int blockIndex) { BookScript book = m_books[bookIndex]; if (book.GetScriptBlocks().Count < blockIndex + n + 1) { return(null); } return(book[blockIndex + n]); }
public bool IsFirstBlock(Block block) { BookScript book = GetBookScriptContainingBlock(block); if (book == null) { return(false); } return(IsFirstBlockInBook(book, block) && IsFirstBook(book)); }
public void ApplyUserDecisions(BookScript sourceBookScript, ScrVers versification = null) { foreach (var sourceUnappliedSplit in sourceBookScript.UnappliedSplits) { List <Block> targetUnappliedSplit = sourceUnappliedSplit.Select(splitPart => splitPart.Clone()).ToList(); m_unappliedSplitBlocks.Add(targetUnappliedSplit); } ApplyUserSplits(sourceBookScript); ApplyUserAssignments(sourceBookScript, versification); CleanUpMultiBlockQuotes(versification); }
private BookScript CreateBookScript() { Logger.WriteEvent("Creating bookScript ({0})", m_bookId); var bookScript = new BookScript(m_bookId, Parse(), null) { PageHeader = PageHeader, MainTitle = MainTitle }; Logger.WriteEvent("Created bookScript ({0}, {1})", m_bookId, bookScript.BookId); return(bookScript); }
private void ApplyUserAssignments(BookScript sourceBookScript, ScrVers versification) { var comparer = new BlockElementContentsComparer(); int iTarget = 0; var bookNum = BCVRef.BookToNumber(sourceBookScript.BookId); foreach (var sourceBlock in sourceBookScript.m_blocks.Where(b => b.UserConfirmed)) { if (m_blocks[iTarget].ChapterNumber < sourceBlock.ChapterNumber) { iTarget = GetIndexOfFirstBlockForVerse(sourceBlock.ChapterNumber, sourceBlock.InitialStartVerseNumber); } else { while (m_blocks[iTarget].InitialStartVerseNumber < sourceBlock.InitialStartVerseNumber) { iTarget++; if (iTarget == m_blocks.Count) { return; } } } do { if (m_blocks[iTarget].StyleTag == sourceBlock.StyleTag && m_blocks[iTarget].IsParagraphStart == sourceBlock.IsParagraphStart && m_blocks[iTarget].BlockElements.SequenceEqual(sourceBlock.BlockElements, comparer)) { if (sourceBlock.CharacterIdOverrideForScript == null) { m_blocks[iTarget].SetCharacterAndCharacterIdInScript(sourceBlock.CharacterId, bookNum, versification); } else { m_blocks[iTarget].CharacterId = sourceBlock.CharacterId; m_blocks[iTarget].CharacterIdOverrideForScript = sourceBlock.CharacterIdOverrideForScript; } m_blocks[iTarget].Delivery = sourceBlock.Delivery; m_blocks[iTarget].UserConfirmed = true; iTarget++; if (iTarget == m_blocks.Count) { return; } break; } } while (++iTarget < m_blocks.Count && m_blocks[iTarget].ChapterNumber == sourceBlock.ChapterNumber && m_blocks[iTarget].InitialStartVerseNumber == sourceBlock.InitialStartVerseNumber); } }
private int GetBookIndex(BookScript bookToFind) { int i = 0; foreach (BookScript book in m_books) { if (book == bookToFind) { return(i); } i++; } throw new ArgumentException("Book is not part of book list"); }
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 Block PeekPreviousBlock() { if (IsFirstBlock(m_currentBlock)) { return(null); } if (IsFirstBlockInBook(m_currentBook, m_currentBlock)) { BookScript previousBook = PeekPreviousBook(); if (!previousBook.HasScriptBlocks) { return(null); } return(previousBook[previousBook.GetScriptBlocks().Count - 1]); } return(m_currentBook[m_currentBlockIndex - 1]); }
public Block PeekNextBlock() { if (IsLastBlock()) { return(null); } if (IsLastBlockInBook(m_currentBook, m_currentBlock)) { BookScript nextBook = PeekNextBook(); if (!nextBook.HasScriptBlocks) { return(null); } return(nextBook[0]); } return(m_currentBook[m_currentBlockIndex + 1]); }
internal void ApplyTo(BookScript vernacularBook, ScrVers vernacularVersification) { ReloadModifiedBooks(); int bookNum = BCVRef.BookToNumber(vernacularBook.BookId); var referenceBook = Books.Single(b => b.BookId == vernacularBook.BookId); var verseSplitLocationsBasedOnRef = GetVerseSplitLocations(referenceBook, bookNum); var verseSplitLocationsBasedOnVern = GetVerseSplitLocations(vernacularBook, bookNum); MakesSplits(vernacularBook, bookNum, vernacularVersification, verseSplitLocationsBasedOnRef, "vernacular", LanguageName); if (MakesSplits(referenceBook, bookNum, Versification, verseSplitLocationsBasedOnVern, LanguageName, "vernacular")) { m_modifiedBooks.Add(referenceBook.BookId); } MatchVernBlocksToReferenceTextBlocks(vernacularBook.GetScriptBlocks(), vernacularBook.BookId, vernacularVersification); }
public Block NextBlock() { if (IsLastBlock()) { return(null); } if (IsLastBlockInBook(m_currentBook, m_currentBlock)) { BookScript nextBook = NextBook(); if (!nextBook.HasScriptBlocks) { return(null); } m_currentBlockIndex = 0; return(nextBook[m_currentBlockIndex]); } return(m_currentBlock = m_currentBook[++m_currentBlockIndex]); }
public BookBlockIndices GetIndicesOfFirstBlockAtReference(VerseRef verseRef, bool allowMidQuoteBlock = false) { var bookId = verseRef.Book; int bookIndex = -1; BookScript book = null; for (int i = 0; i < m_books.Count; i++) { book = m_books[i]; if (book.BookId == bookId) { bookIndex = i; break; } } if (bookIndex == -1 || book == null) { return(null); } var block = book.Blocks.FirstOrDefault( a => a.ChapterNumber == verseRef.ChapterNum && a.InitialStartVerseNumber <= verseRef.VerseNum && a.LastVerseNum >= verseRef.VerseNum); if (block == null) { return(null); } int blockIndex = book.Blocks.IndexOf(block); if (!allowMidQuoteBlock) { if (block.IsContinuationOfPreviousBlockQuote) { blockIndex = book.Blocks.FindLastIndex(blockIndex, b => b.MultiBlockQuote == MultiBlockQuote.Start); } } return(blockIndex == -1 ? null : new BookBlockIndices(bookIndex, blockIndex)); }
private void ApplyUserSplits(BookScript sourceBookScript) { int splitId = Block.kNotSplit; List <Block> split = null; foreach (var block in sourceBookScript.Blocks.Where(b => b.SplitId != Block.kNotSplit)) { if (block.SplitId != splitId) { if (split != null) { m_unappliedSplitBlocks.Add(split); } split = new List <Block>(); splitId = block.SplitId; } split.Add(block); } if (split != null) { m_unappliedSplitBlocks.Add(split); } var comparer = new SplitBlockComparer(); for (int index = 0; index < m_unappliedSplitBlocks.Count; index++) { var unappliedSplit = m_unappliedSplitBlocks[index]; var firstBlockOfSplit = unappliedSplit.First(); var i = GetIndexOfFirstBlockThatStartsWithVerse(firstBlockOfSplit.ChapterNumber, firstBlockOfSplit.InitialStartVerseNumber); var iFirstMatchingBlock = i; var iUnapplied = 0; bool blocksMatch; do { var splitBlock = unappliedSplit[iUnapplied]; var parsedBlock = m_blocks[i++]; blocksMatch = comparer.Equals(splitBlock, parsedBlock); if (iUnapplied > 0 || blocksMatch) { if (!blocksMatch) { break; } if (iUnapplied == 0) { iFirstMatchingBlock = i; } iUnapplied++; } } while (i < m_blocks.Count && iUnapplied < unappliedSplit.Count); if (blocksMatch) { m_unappliedSplitBlocks.RemoveAt(index--); } else { var combinedBlock = CombineBlocks(unappliedSplit); for (int iBlock = iFirstMatchingBlock; iBlock < m_blocks.Count && m_blocks[iBlock].InitialStartVerseNumber == combinedBlock.InitialStartVerseNumber; iBlock++) { if (comparer.Equals(combinedBlock, m_blocks[iBlock])) { i = iBlock; for (iUnapplied = 1; iUnapplied < unappliedSplit.Count; iUnapplied++) { var elementsOfBlockPrecedingSplit = unappliedSplit[iUnapplied - 1].BlockElements; var textElementAtEndOfBlockPrecedingSplit = elementsOfBlockPrecedingSplit.Last() as ScriptText; int offset = textElementAtEndOfBlockPrecedingSplit != null ? textElementAtEndOfBlockPrecedingSplit.Content.Length : 0; string verse; if (unappliedSplit[iUnapplied].BlockElements.First() is Verse) { var lastVerseInPrecedingBlock = elementsOfBlockPrecedingSplit.OfType <Verse>().LastOrDefault(); if (lastVerseInPrecedingBlock != null) { verse = lastVerseInPrecedingBlock.Number; } else { verse = m_blocks[i].InitialVerseNumberOrBridge; } } else { verse = unappliedSplit[iUnapplied].InitialVerseNumberOrBridge; } SplitBlock(m_blocks[i++], verse, offset); if (unappliedSplit[iUnapplied - 1].MatchesReferenceText) { m_blocks[i - 1].SetMatchedReferenceBlock(unappliedSplit[iUnapplied - 1].ReferenceBlocks.Single().Clone()); } } if (unappliedSplit[iUnapplied - 1].MatchesReferenceText) { m_blocks[i].SetMatchedReferenceBlock(unappliedSplit[iUnapplied - 1].ReferenceBlocks.Single().Clone()); } m_unappliedSplitBlocks.RemoveAt(index--); break; } } } } }
private BookScript TryLoadBook(string[] files, string bookCode) { var fileName = files.FirstOrDefault(f => Path.GetFileName(f) == bookCode + Constants.kBookScriptFileExtension); return(fileName != null?BookScript.Deserialize(fileName, Versification) : null); }
public bool CanDisplayReferenceTextForBook(BookScript vernacularBook) { return(Books.Any(b => b.BookId == vernacularBook.BookId)); }
public BlockMatchup(BookScript vernacularBook, int iBlock, Action <PortionScript> splitBlocks, Func <VerseRef, bool> isOkayToBreakAtVerse, IReferenceLanguageInfo heSaidProvider, uint predeterminedBlockCount = 0) { m_vernacularBook = vernacularBook; int bookNum = BCVRef.BookToNumber(m_vernacularBook.BookId); m_referenceLanguageInfo = heSaidProvider; var blocks = m_vernacularBook.GetScriptBlocks(); var originalAnchorBlock = blocks[iBlock]; if (predeterminedBlockCount == 0) { var blocksForVersesCoveredByBlock = vernacularBook.GetBlocksForVerse(originalAnchorBlock.ChapterNumber, originalAnchorBlock.InitialStartVerseNumber).ToList(); var indexOfAnchorBlockInVerse = blocksForVersesCoveredByBlock.IndexOf(originalAnchorBlock); if (indexOfAnchorBlockInVerse < 0) { Logger.WriteEvent($"Anchor block not found in verse: {m_vernacularBook.BookId} {originalAnchorBlock.ChapterNumber}:" + $"{originalAnchorBlock.InitialStartVerseNumber} Verse apparently occurs more than once in the Scripture text."); // REVIEW: This logic assumes that the repeated verse is wholly contained in this onwe block. blocksForVersesCoveredByBlock = new List <Block>() { originalAnchorBlock }; indexOfAnchorBlockInVerse = 0; } m_iStartBlock = iBlock - indexOfAnchorBlockInVerse; while (m_iStartBlock > 0) { if (blocksForVersesCoveredByBlock.First().InitialStartVerseNumber < originalAnchorBlock.InitialStartVerseNumber && !blocksForVersesCoveredByBlock.First().StartsAtVerseStart) { var prepend = vernacularBook.GetBlocksForVerse(originalAnchorBlock.ChapterNumber, blocksForVersesCoveredByBlock.First().InitialStartVerseNumber).ToList(); prepend.RemoveAt(prepend.Count - 1); m_iStartBlock -= prepend.Count; blocksForVersesCoveredByBlock.InsertRange(0, prepend); } if (m_iStartBlock == 0 || isOkayToBreakAtVerse(new VerseRef(bookNum, originalAnchorBlock.ChapterNumber, blocksForVersesCoveredByBlock.First().InitialStartVerseNumber))) { break; } m_iStartBlock--; blocksForVersesCoveredByBlock.Insert(0, blocks[m_iStartBlock]); } int iLastBlock = m_iStartBlock + blocksForVersesCoveredByBlock.Count - 1; int i = iLastBlock; AdvanceToCleanVerseBreak(blocks, verseNum => 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())); try { CorrelatedAnchorBlock = m_portion.GetScriptBlocks()[iBlock - m_iStartBlock]; } catch (Exception ex) { Logger.WriteEvent(ex.Message); Logger.WriteEvent($"iBlock = {iBlock}; m_iStartBlock = {m_iStartBlock}"); foreach (var block in m_portion.GetScriptBlocks()) { Logger.WriteEvent($"block = {block}"); } throw; } } else { m_iStartBlock = iBlock; m_portion = new PortionScript(vernacularBook.BookId, vernacularBook.GetScriptBlocks().Skip(iBlock).Take((int)predeterminedBlockCount).Select(b => b.Clone())); CorrelatedAnchorBlock = m_portion.GetScriptBlocks().First(); } if (splitBlocks != null) { int origCount = m_portion.GetScriptBlocks().Count; splitBlocks(m_portion); m_numberOfBlocksAddedBySplitting = m_portion.GetScriptBlocks().Count - origCount; } }
private bool IsLastBlockInBook(BookScript book, int blockIndex) { return(blockIndex == book.GetScriptBlocks().Count - 1); }
public bool IsFirstBlockInBook(BookScript book, Block block) { return(block == book.GetScriptBlocks().FirstOrDefault()); }