示例#1
0
        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!");
        }
示例#2
0
        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);
        }
示例#3
0
 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];
 }
示例#4
0
        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);
        }
示例#5
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]);
        }
示例#6
0
        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;
        }
示例#7
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;
            }
        }
示例#8
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;
            }
        }
示例#9
0
        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]);
        }
示例#10
0
        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);
        }
示例#11
0
 public bool IsFirstBlockInBook(BookScript book, Block block)
 {
     return(block == book.GetScriptBlocks().FirstOrDefault());
 }
示例#12
0
 private bool IsLastBlockInBook(BookScript book, int blockIndex)
 {
     return(blockIndex == book.GetScriptBlocks().Count - 1);
 }
示例#13
0
        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.");
        }