internal BookBlockIndices GetIndicesOfSpecificBlock(Block block) { if (block == m_currentBlock) { return(GetIndices()); } // In production code, I think this will always only be called for the current book, so we try that // first before looking at all the rest of the books for this block. var indexInCurrentBook = m_currentBook.GetScriptBlocks().IndexOf(block); if (indexInCurrentBook >= 0) { return(new BookBlockIndices(m_currentBookIndex, indexInCurrentBook)); } for (int iBook = 0; iBook < m_books.Count; iBook++) { if (iBook == m_currentBookIndex) { continue; } var book = m_books[iBook]; var iBlock = book.GetScriptBlocks().IndexOf(block); if (iBlock >= 0) { return(new BookBlockIndices(iBook, iBlock)); } } throw new ArgumentOutOfRangeException("block", block.ToString(), "Block not found in any book!"); }
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); }
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, 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 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 void Apply(Paratext.ScrVers versification) { if (!AllScriptureBlocksMatch) { throw new InvalidOperationException("Cannot apply reference blocks unless all Scripture blocks have corresponding reference blocks."); } var bogusRefBlock = GetInvalidReferenceBlockAtAnyLevel(CorrelatedBlocks); if (bogusRefBlock != null) { throw new InvalidReferenceTextException(bogusRefBlock); } if (m_numberOfBlocksAddedBySplitting > 0) { m_vernacularBook.ReplaceBlocks(m_iStartBlock, CorrelatedBlocks.Count - m_numberOfBlocksAddedBySplitting, CorrelatedBlocks.Select(b => b.Clone())); } int bookNum = BCVRef.BookToNumber(m_vernacularBook.BookId); var origBlocks = m_vernacularBook.GetScriptBlocks(); for (int i = 0; i < CorrelatedBlocks.Count; i++) { if (!CorrelatedBlocks[i].MatchesReferenceText) // e.g., section head { continue; } var vernBlock = origBlocks[m_iStartBlock + i]; var refBlock = CorrelatedBlocks[i].ReferenceBlocks.Single(); vernBlock.SetMatchedReferenceBlock(refBlock); vernBlock.SetCharacterAndDeliveryInfo(CorrelatedBlocks[i], bookNum, versification); if (CorrelatedBlocks[i].UserConfirmed) { if (vernBlock.CharacterIsUnclear()) { throw new InvalidOperationException("Character cannot be confirmed as ambigous or unknown."); } vernBlock.UserConfirmed = true; } //if (vernBlock.CharacterId != refBlock.CharacterId) //{ // vernBlock.CharacterId = refBlock.CharacterId; // if (refBlock.CharacterIdOverrideForScript != null) // vernBlock.CharacterIdOverrideForScript = refBlock.CharacterIdOverrideForScript; //} } m_numberOfBlocksAddedBySplitting = 0; }
public void Apply(ScrVers versification) { if (!AllScriptureBlocksMatch) { throw new InvalidOperationException("Cannot apply reference blocks unless all Scripture blocks have corresponding reference blocks."); } //var bogusRefBlock = GetInvalidReferenceBlockAtAnyLevel(CorrelatedBlocks); //if (bogusRefBlock != null) // throw new InvalidReferenceTextException(bogusRefBlock); if (m_numberOfBlocksAddedBySplitting > 0) { m_vernacularBook.ReplaceBlocks(m_iStartBlock, CorrelatedBlocks.Count - m_numberOfBlocksAddedBySplitting, CorrelatedBlocks.Select(b => b.Clone()).ToList()); } int bookNum = BCVRef.BookToNumber(m_vernacularBook.BookId); var origBlocks = m_vernacularBook.GetScriptBlocks(); for (int i = 0; i < CorrelatedBlocks.Count; i++) { var vernBlock = origBlocks[m_iStartBlock + i]; var refBlock = CorrelatedBlocks[i].ReferenceBlocks.Single(); vernBlock.SetMatchedReferenceBlock(refBlock); vernBlock.SetCharacterAndDeliveryInfo(CorrelatedBlocks[i], bookNum, versification); if (CorrelatedBlocks[i].UserConfirmed) { if (vernBlock.CharacterIsUnclear()) { throw new InvalidOperationException("Character cannot be confirmed as ambigous or unknown."); } vernBlock.UserConfirmed = true; } } if (m_numberOfBlocksAddedBySplitting == 0) { var lastBlockInMatchup = CorrelatedBlocks.Last(); foreach (var block in origBlocks.Skip(m_iStartBlock + OriginalBlockCount).TakeWhile(b => b.IsContinuationOfPreviousBlockQuote)) { block.CharacterId = lastBlockInMatchup.CharacterId; block.CharacterIdOverrideForScript = lastBlockInMatchup.CharacterIdOverrideForScript; } } else { m_numberOfBlocksAddedBySplitting = 0; } }
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]); }
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 bool IsFirstBlockInBook(BookScript book, Block block) { return(block == book.GetScriptBlocks().FirstOrDefault()); }
private bool IsLastBlockInBook(BookScript book, int blockIndex) { return(blockIndex == book.GetScriptBlocks().Count - 1); }
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; } }
public void Apply(ScrVers versification = null) { if (!AllScriptureBlocksMatch) { throw new InvalidOperationException("Cannot apply reference blocks unless all Scripture blocks have corresponding reference blocks."); } if (versification != null) { if (m_versification != null && m_versification != versification) { throw new ArgumentException("Apply called with unexpected versification!", nameof(versification)); } m_versification = versification; } if (m_numberOfBlocksAddedBySplitting > 0) { m_vernacularBook.ReplaceBlocks(m_iStartBlock, OriginalBlockCount, CorrelatedBlocks.Select(b => b.Clone()).ToList()); } int bookNum = BCVRef.BookToNumber(BookId); var origBlocks = m_vernacularBook.GetScriptBlocks(); for (int i = 0; i < CorrelatedBlocks.Count; i++) { var vernBlock = origBlocks[m_iStartBlock + i]; var refBlock = CorrelatedBlocks[i].ReferenceBlocks.Single(); vernBlock.SetMatchedReferenceBlock(refBlock); var basedOnBlock = CorrelatedBlocks[i].CharacterIsUnclear ? refBlock : CorrelatedBlocks[i]; vernBlock.SetCharacterAndDeliveryInfo(basedOnBlock, bookNum, m_versification); if (vernBlock.CharacterIsStandard) { vernBlock.MultiBlockQuote = MultiBlockQuote.None; } if (vernBlock.CharacterIsUnclear) { throw new InvalidOperationException("Vernacular block matched to reference block must have a CharacterId that is not ambiguous or unknown."); } if (CorrelatedBlocks[i].UserConfirmed) { vernBlock.UserConfirmed = true; } vernBlock.SplitId = CorrelatedBlocks[i].SplitId; } // No need to update following continuation blocks here if m_numberOfBlocksAddedBySplitting > 0 because the call to // ReplaceBlocks (above) already did it. if (m_numberOfBlocksAddedBySplitting == 0) { m_vernacularBook.UpdateFollowingContinuationBlocks(m_iStartBlock + OriginalBlockCount - 1); } else { m_numberOfBlocksAddedBySplitting = 0; } Debug.Assert(origBlocks.Skip(m_iStartBlock).Take(CorrelatedBlocks.Count) .All(b => !b.CharacterIsStandard || b.MultiBlockQuote == MultiBlockQuote.None), "Applying block matchup resulted in an illegal multi-block quote chain."); }