/// ------------------------------------------------------------------------------------ /// <summary> /// Given a Scripture section, this method returns the index of the paragraph containing /// the requested verse and the position of the character immediately following the /// verse number in that paragraph. If an exact match isn't found, the closest /// approximate place is found. /// </summary> /// <param name="section">The section whose paragraphs will be searched</param> /// <param name="targetRef">The reference being sought</param> /// <param name="iPara">The index of the paragraph where the verse was found</param> /// <param name="ichPosition">The index of the character immediately following the /// verse number in that paragraph</param> /// ------------------------------------------------------------------------------------ protected void FindVerseNumber(IScrSection section, ScrReference targetRef, out int iPara, out int ichPosition) { iPara = 0; ichPosition = 0; bool fChapterFound = (BCVRef.GetChapterFromBcv(section.VerseRefMin) == targetRef.Chapter); foreach (IStTxtPara para in section.ContentOA.ParagraphsOS) { if (para.Contents.Text == null) { continue; } TsRunInfo tsi; ITsTextProps ttpRun; int ich = 0; while (ich < para.Contents.Length) { // Get props of current run. ttpRun = para.Contents.FetchRunInfoAt(ich, out tsi); // See if it is our verse number style. if (fChapterFound) { if (ttpRun.Style() == ScrStyleNames.VerseNumber) { // The whole run is the verse number. Extract it. string sVerseNum = para.Contents.Text.Substring(tsi.ichMin, tsi.ichLim - tsi.ichMin); int startVerse, endVerse; ScrReference.VerseToInt(sVerseNum, out startVerse, out endVerse); if ((targetRef.Verse >= startVerse && targetRef.Verse <= endVerse) || targetRef.Verse < startVerse) { ichPosition = tsi.ichLim; return; } } } // See if it is our chapter number style. else if (ttpRun.Style() == ScrStyleNames.ChapterNumber) { try { // Assume the whole run is the chapter number. Extract it. string sChapterNum = para.Contents.Text.Substring(tsi.ichMin, tsi.ichLim - tsi.ichMin); fChapterFound = (ScrReference.ChapterToInt(sChapterNum) == targetRef.Chapter); } catch (ArgumentException) { // ignore runs with invalid Chapter numbers } } ich = tsi.ichLim; } iPara++; } iPara = 0; // Couldn't find it. }
/// ------------------------------------------------------------------------------------ /// <summary> /// Updates the Scripture reference for this footnote. /// </summary> /// ------------------------------------------------------------------------------------ private void UpdateFootnoteRef() { IScrBook owningBook = OwnerOfClass <IScrBook>(); if (owningBook == null) { throw new InvalidOperationException("Can not calculate footnote reference until footnote is inserted"); } if (ParaContainingOrcRA == null) { return; // Would be better to throw an exception, but will happen in tests } BCVRef startRef = new BCVRef(owningBook.CanonicalNum, 0, 0); BCVRef endRef = new BCVRef(owningBook.CanonicalNum, 0, 0); IScrSection owningSection = ParaContainingOrcRA.OwnerOfClass <IScrSection>(); if (owningSection != null && BCVRef.GetChapterFromBcv(owningSection.VerseRefStart) == BCVRef.GetChapterFromBcv(owningSection.VerseRefEnd)) { // Section only contains one chapter, so we know which chapter to use startRef.Chapter = endRef.Chapter = BCVRef.GetChapterFromBcv(owningSection.VerseRefStart); } IStText owningText = (IStText)ParaContainingOrcRA.Owner; for (int iPara = owningText.ParagraphsOS.IndexOf(ParaContainingOrcRA); iPara >= 0; iPara--) { IScrTxtPara para = (IScrTxtPara)owningText[iPara]; RefResult result = GetReference(owningBook, para, startRef, endRef); if (result == RefResult.ScannedAllFootnotes) { return; // no need to finish since full scan updated my reference } if (result == RefResult.Found) { break; } } if (owningSection != null) { if (startRef.Verse == 0) { startRef.Verse = endRef.Verse = new BCVRef(owningSection.VerseRefStart).Verse; } if (startRef.Chapter == 0) { startRef.Chapter = endRef.Chapter = new BCVRef(owningSection.VerseRefStart).Chapter; } } FootnoteRefInfo = new RefRange(startRef, endRef); }
/// ------------------------------------------------------------------------------------ /// <summary> /// Fills an array list from the cache with all the chapters for the book specified /// by m_scRef.Book. /// </summary> /// <returns>An array list containing all the chapters found in the cache for /// the book specified by m_scRef.Book.</returns> /// ------------------------------------------------------------------------------------ private List <int> LoadChapterListFromCache() { List <int> chapterList = new List <int>(); IScrBook book = ScrPassageControl.ScriptureObject.FindBook(m_scRef.Book); // Go through the sections of the book and collect the chapters for each // section. if (book != null) { foreach (IScrSection section in book.SectionsOS) { for (int chapter = (BCVRef.GetChapterFromBcv(section.VerseRefMin)); chapter <= (BCVRef.GetChapterFromBcv(section.VerseRefMax)); chapter++) { if (chapter != 0 && !chapterList.Contains(chapter)) { chapterList.Add(chapter); } } } } return(chapterList); }
/// ------------------------------------------------------------------------------------ /// <summary> /// Adjust the start and end section references to reflect the content of the section. /// </summary> /// <param name="fIsIntro">if set to <c>true</c> this is an intro section.</param> /// ------------------------------------------------------------------------------------ public void AdjustReferences(bool fIsIntro) { // If this is not the first section then get the previous section's end reference // as a starting point for this section ScrSection prevSection = PreviousSection; ScrReference currentRefStart = new ScrReference(OwningBook.CanonicalNum, 1, 0, Cache.LangProject.TranslatedScriptureOA.Versification); if (prevSection != null) { currentRefStart.BBCCCVVV = prevSection.VerseRefEnd; } // If this is not an intro section then start the verse at 1 so it will not // be an intro section. if (currentRefStart.Verse == 0 && !fIsIntro) { currentRefStart.Verse = 1; } // Default the starting reference for the case that there is no content. int newSectionStart = currentRefStart; // Scan the paragraphs of the section to get the min and max references ScrReference refMin = new ScrReference(currentRefStart); ScrReference refMax = new ScrReference(currentRefStart); ScrReference currentRefEnd = new ScrReference(currentRefStart); bool isFirstTextRun = true; if (ContentOA != null) { foreach (StTxtPara para in ContentOA.ParagraphsOS) { ITsString paraContents = para.Contents.UnderlyingTsString; int iLim = paraContents.RunCount; RefRunType runType = RefRunType.None; for (int iRun = 0; iRun < iLim;) { // for very first run in StText we want to set VerseRefStart int iLimTmp = (iRun == 0 && isFirstTextRun) ? iRun + 1 : iLim; runType = Scripture.GetNextRef(iRun, iLimTmp, paraContents, true, ref currentRefStart, ref currentRefEnd, out iRun); // If a verse or chapter was found, adjust the max and min if the current // verse refs are less than min or greater than max if (runType != RefRunType.None) { // If a chapter or verse is found at the start of the section, then use that // reference instead of the one from the previous section as the min and max. if (isFirstTextRun || currentRefStart < refMin) { refMin.BBCCCVVV = currentRefStart.BBCCCVVV; } if (isFirstTextRun || currentRefEnd > refMax) { refMax.BBCCCVVV = currentRefEnd.BBCCCVVV; } } // after the first run, store the starting reference if (isFirstTextRun) { newSectionStart = currentRefStart; isFirstTextRun = false; } } } } // Store the min and max as the reference range for the section VerseRefStart = newSectionStart; VerseRefMin = refMin; VerseRefMax = refMax; // Store the last reference for the section. bool verseRefEndHasChanged = (VerseRefEnd != currentRefEnd.BBCCCVVV); bool verseRefEndChapterHasChanged = (BCVRef.GetChapterFromBcv(VerseRefEnd) != currentRefEnd.Chapter); VerseRefEnd = currentRefEnd; // If the last reference changes then the next section's references have potentially been invalidated ScrSection nextSection = NextSection; if (nextSection != null) { if ((verseRefEndChapterHasChanged && !nextSection.StartsWithChapterNumber) || (verseRefEndHasChanged && !nextSection.StartsWithVerseOrChapterNumber)) { nextSection.AdjustReferences(); } } }
/// ------------------------------------------------------------------------------------ /// <summary> /// Determine if the section contains a given chapter number /// </summary> /// ------------------------------------------------------------------------------------ public bool ContainsChapter(int chapter) { return(chapter >= BCVRef.GetChapterFromBcv(VerseRefMin) && chapter <= BCVRef.GetChapterFromBcv(VerseRefMax)); }