예제 #1
0
        /// ------------------------------------------------------------------------------------
        /// <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.
        }
예제 #2
0
        /// ------------------------------------------------------------------------------------
        /// <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="ihvoPara"></param>
        /// <param name="ichPosition"></param>
        /// <remarks>Currently, this does NOT attempt to find a close match, but some day it
        /// should</remarks>
        /// ------------------------------------------------------------------------------------
        protected void FindVerseNumber(ScrSection section, ScrReference targetRef,
                                       out int ihvoPara, out int ichPosition)
        {
            ihvoPara    = 0;
            ichPosition = 0;

            bool fChapterFound = ((ScrReference)section.VerseRefStart).Chapter == targetRef.Chapter;

            foreach (StTxtPara para in section.ContentOA.ParagraphsOS)
            {
                TsStringAccessor contents = para.Contents;
                TsRunInfo        tsi;
                ITsTextProps     ttpRun;
                int ich = 0;
                while (ich < contents.Text.Length)
                {
                    // Get props of current run.
                    ttpRun = contents.UnderlyingTsString.FetchRunInfoAt(ich, out tsi);
                    // See if it is our verse number style.
                    if (fChapterFound)
                    {
                        if (StStyle.IsStyle(ttpRun, ScrStyleNames.VerseNumber))
                        {
                            // The whole run is the verse number. Extract it.
                            string sVerseNum = 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)
                            {
                                ihvoPara    = para.OwnOrd - 1;
                                ichPosition = tsi.ichLim;
                                return;
                            }
                            // TODO: Currently, this does NOT attempt to detect when we have
                            // a close match
                        }
                    }
                    // See if it is our chapter number style.
                    else if (StStyle.IsStyle(ttpRun, ScrStyleNames.ChapterNumber))
                    {
                        // Assume the whole run is the chapter number. Extract it.
                        string sChapterNum = contents.Text.Substring(tsi.ichMin,
                                                                     tsi.ichLim - tsi.ichMin);
                        int nChapter = ScrReference.ChapterToInt(sChapterNum);
                        fChapterFound = (nChapter == targetRef.Chapter);
                    }
                    ich = tsi.ichLim;
                }
            }
        }
예제 #3
0
 /// ------------------------------------------------------------------------------------
 /// <summary>
 /// Gets the start and end references for the line of text with the given marker. (Sets
 /// m_currentStartRef and m_currentEndRef.)
 /// </summary>
 /// <param name="marker"></param>
 /// <param name="lineContents"></param>
 /// <param name="literalVerse"></param>
 /// <returns></returns>
 /// ------------------------------------------------------------------------------------
 private void GetReferenceForLine(string marker, ref string lineContents,
                                  ref string literalVerse)
 {
     // If this is a marker that will change the reference, then update
     // the reference
     if (marker == ScrImportSet.s_markerBook)
     {
         int book = BCVRef.BookToNumber(lineContents.ToUpper());
         if (book > 0)
         {
             m_currentStartRef.Book    = book;
             m_currentStartRef.Chapter = 1;
             m_currentStartRef.Verse   = 0;
         }
         m_currentEndRef = new BCVRef(m_currentStartRef);
         m_seenIdInFile  = true;
     }
     else if (marker == ScrImportSet.s_markerChapter)
     {
         string chapterText = lineContents;
         try
         {
             m_currentStartRef.Chapter = ScrReference.ChapterToInt(chapterText, out lineContents);
             m_currentStartRef.Verse   = 1;
             m_currentEndRef           = new BCVRef(m_currentStartRef);
         }
         catch (ArgumentException)
         {
             throw new ScriptureUtilsException(SUE_ErrorCode.InvalidChapterNumber,
                                               m_currentFile.FileName, m_lineNumber, lineContents,
                                               BCVRef.NumberToBookCode(m_currentStartRef.Book), chapterText, null);
         }
     }
     else if (marker == ScrImportSet.s_markerVerse)
     {
         BCVRef.VerseToScrRef(lineContents.TrimStart(),
                              out literalVerse, out lineContents, ref m_currentStartRef, ref m_currentEndRef);
     }
     else
     {
         if (lineContents == " ")
         {
             lineContents = string.Empty;
         }
     }
 }
예제 #4
0
        /// ------------------------------------------------------------------------------------
        /// <summary>
        /// Test converting the digits to a specific digit set
        /// </summary>
        /// <param name="zeroChar">zero character in the desired language</param>
        /// <param name="nineChar">nine character in the desired language</param>
        /// <param name="dlg">scripture properties dialog</param>
        /// ------------------------------------------------------------------------------------
        private void ScriptDigitConversionTest(char zeroChar, char nineChar, ScriptureProperties dlg)
        {
            m_scr.ScriptDigitZero = zeroChar;
            m_scr.UseScriptDigits = (zeroChar != '0');

            ReflectionHelper.CallMethod(dlg, "ConvertChapterVerseNumbers", null);

            int[] expectedNumbers = new int[] { 1, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 };
            int   expectedIndex   = 0;

            ITsString tss = ((IStTxtPara)((IScrSection)m_exodus.SectionsOS[0]).ContentOA.ParagraphsOS[0]).Contents.UnderlyingTsString;

            for (int i = 0; i < tss.RunCount; i++)
            {
                TsRunInfo    tri;
                ITsTextProps ttp   = tss.FetchRunInfo(i, out tri);
                IStStyle     style = m_scr.FindStyle(ttp);
                if (style != null &&
                    (style.Function == FunctionValues.Verse ||
                     style.Function == FunctionValues.Chapter))
                {
                    int    expectedNumber = expectedNumbers[expectedIndex++];
                    string runChars       = tss.GetChars(tri.ichMin, tri.ichLim);
                    // make sure the expected digits were found
                    Assert.AreEqual(expectedNumber, ScrReference.ChapterToInt(runChars));

                    // make sure that all of the digits are in the desired language
                    foreach (char c in runChars)
                    {
                        if (Char.IsDigit(c))
                        {
                            Assert.IsTrue(c >= zeroChar && c <= nineChar, "Found incorrect digit");
                        }
                    }
                }
            }

            // Make sure we saw all the expected numbers in the data
            Assert.AreEqual(expectedNumbers.Length, expectedIndex);
        }
예제 #5
0
파일: ScrVerse.cs 프로젝트: vkarthim/liblcm
        ///  ------------------------------------------------------------------------------------
        /// <summary>
        /// Advances the enumerator to the next verse in the paragraph.
        /// </summary>
        /// <returns>True if we successfully moved to the next ScrVerse; False if we reached
        /// the end of the paragraph.</returns>
        /// ------------------------------------------------------------------------------------
        public bool MoveNext()
        {
            InitializeParaContents();

            if (m_ich > m_paraLength)
            {
                return(false);
            }

            m_ichVerseStart = m_ichTextStart = m_ich;
            TsRunInfo    tsi;
            ITsTextProps ttpRun;
            string       sPara    = m_tssParaContents.Text;
            int          nChapter = -1;     // This is used to see if we found a chapter later.

            m_inVerseNum   = false;
            m_inChapterNum = false;
            while (m_ich < m_paraLength)
            {
                ttpRun = m_tssParaContents.FetchRunInfoAt(m_ich, out tsi);

                // If this run is our verse number style
                if (ttpRun.Style() == ScrStyleNames.VerseNumber)
                {
                    // If there is already a verse in process, a new verse number run will terminate it.
                    if (m_ichVerseStart != m_ich)
                    {
                        break;
                    }

                    // Assume the whole run is the verse number
                    string sVerseNum = sPara.Substring(m_ich, tsi.ichLim - tsi.ichMin);
                    int    nVerseStart, nVerseEnd;
                    ScrReference.VerseToInt(sVerseNum, out nVerseStart, out nVerseEnd);
                    m_startRef.Verse = nVerseStart;
                    m_endRef.Verse   = nVerseEnd;
                    m_ichVerseStart  = m_ich;                    //set VerseStart at beg of verse number
                    m_ich           += sVerseNum.Length;
                    m_ichTextStart   = m_ich;
                    m_inVerseNum     = true;
                }
                // If this run is our chapter number style
                else if (ttpRun.Style() == ScrStyleNames.ChapterNumber)
                {
                    // If there is already a verse being processed, then the chapter number
                    // run will end it
                    if (m_ichVerseStart != m_ich)
                    {
                        break;
                    }

                    try
                    {
                        // Assume the whole run is the chapter number
                        string sChapterNum = sPara.Substring(m_ich, tsi.ichLim - tsi.ichMin);
                        nChapter           = ScrReference.ChapterToInt(sChapterNum);
                        m_startRef.Chapter = m_endRef.Chapter = nChapter;
                        // Set the verse number to 1, since the first verse number after a
                        // chapter is optional. If we happen to get a verse number in the
                        // next run, this '1' will be overridden (though it will probably
                        // still be a 1).
                        m_startRef.Verse = m_endRef.Verse = 1;
                        m_ichVerseStart  = m_ich;                        //set VerseStart at beg of chapter number
                        m_ich           += sChapterNum.Length;
                        m_ichTextStart   = m_ich;
                        m_inChapterNum   = true;
                    }
                    catch (ArgumentException)
                    {
                        // ignore runs with invalid Chapter numbers
                        m_ich += tsi.ichLim - tsi.ichMin;
                    }
                }
                else                 // Process a text run.
                {
                    // If it comes after a chapter number, then just return the
                    // chapter number without adding the text.
                    if (nChapter > 0)
                    {
                        break;
                    }

                    // skip to the next run
                    m_ich += tsi.ichLim - tsi.ichMin;
                }
            }

            // determine if this verse is a complete paragraph, an empty para and/or a stanza break.
            m_isCompletePara = (m_ichVerseStart == 0 && m_ich == m_paraLength);
            if (string.IsNullOrEmpty(sPara))
            {
                //m_isEmptyPara = true;
                m_isStanzaBreak = string.Equals(ScrStyleNames.StanzaBreak, m_para.StyleName);
            }

            try
            {
                return((m_ich > m_ichVerseStart) || FirstTimeAtStanzaBreak);
            }
            finally
            {
                // Update the previous paragraph for the next time (but we do the update
                // in a 'finally' so that we can compare the current to the previous for
                // the return value).
                m_prevPara = m_para;
            }
        }
예제 #6
0
        /// ------------------------------------------------------------------------------------
        /// <summary>
        /// Find the start and end reference, by searching backwards in the given ITsString
        /// from the given position.
        /// </summary>
        /// <param name="tss">the given ITsString</param>
        /// <param name="ichPos">Index of character in paragraph whose reference we want</param>
        /// <param name="fAssocPrev">Consider this position to be associated with any preceding
        /// text in the paragraph (in the case where ichPos is at a chapter boundary).</param>
        /// <param name="refStart">[out] Start reference for the paragraph.</param>
        /// <param name="refEnd">[out] End reference for the paragraph.</param>
        /// <returns>A value of <see cref="ChapterVerseFound"/> that tells if a chapter and/or
        /// verse number was found in this paragraph.</returns>
        /// <remarks>If ichPos LT zero, we will not search this para, and simply return.
        /// Be careful not to use this method to search the contents of paragraph using
        /// character offsets from the BT!
        /// </remarks>
        /// ------------------------------------------------------------------------------------
        static public ChapterVerseFound GetBCVRefAtPosWithinTss(ITsString tss, int ichPos,
                                                                bool fAssocPrev, out BCVRef refStart, out BCVRef refEnd)
        {
            refStart = new BCVRef();
            refEnd   = new BCVRef();
            ChapterVerseFound retVal = ChapterVerseFound.None;

            if (tss.Length <= 0)
            {
                return(retVal);
            }

            TsRunInfo    tsi;
            ITsTextProps ttpRun;
            bool         fGotVerse = false;

            int ich = ichPos;

            if (ich > tss.Length)
            {
                ich = tss.Length;
            }
            while (ich >= 0)
            {
                // Get props of current run.
                ttpRun = tss.FetchRunInfoAt(ich, out tsi);

                // If we're at (the front edge of) a C/V number boundary and the
                // caller said to associate the position with the previous material, then
                // ignore this run unless we're at the beginning of the para.
                // The run is actually the *following*  run, which we don't care about.
                if (!fAssocPrev || ichPos <= 0 || ichPos != tsi.ichMin)
                {
                    // See if it is our verse number style.
                    if (!fGotVerse && StStyle.IsStyle(ttpRun, ScrStyleNames.VerseNumber))
                    {
                        // The whole run is the verse number. Extract it.
                        string sVerseNum = tss.get_RunText(tsi.irun);
                        //					string sVerseNum = tss.Text.Substring(tsi.ichMin,
                        //						tsi.ichLim - tsi.ichMin);
                        int startVerse, endVerse;
                        ScrReference.VerseToInt(sVerseNum, out startVerse, out endVerse);
                        refStart.Verse = startVerse;
                        refEnd.Verse   = endVerse;
                        fGotVerse      = true;
                        retVal         = ChapterVerseFound.Verse;
                    }
                    // See if it is our chapter number style.
                    else if (StStyle.IsStyle(ttpRun, ScrStyleNames.ChapterNumber))
                    {
                        try
                        {
                            // Assume the whole run is the chapter number. Extract it.
                            string sChapterNum = tss.get_RunText(tsi.irun);
                            int    nChapter    = ScrReference.ChapterToInt(sChapterNum);
                            refStart.Chapter = refEnd.Chapter = nChapter;

                            if (fGotVerse)
                            {
                                // Found a chapter number to go with the verse number we
                                // already found, so build the full reference using this
                                // chapter with the previously found verse (already set).
                                retVal |= ChapterVerseFound.Chapter;
                            }
                            else
                            {
                                // Found a chapter number but no verse number, so assume the
                                // edited text is in verse 1 of the chapter.
                                refStart.Verse = refEnd.Verse = 1;
                                fGotVerse      = true;
                                retVal         = ChapterVerseFound.Chapter | ChapterVerseFound.Verse;
                            }
                            break;
                        }
                        catch (ArgumentException)
                        {
                            // ignore runs with invalid Chapter numbers
                        }
                    }
                }

                // move index (going backwards) to the character just before the Min of the run
                // we just looked at
                ich = tsi.ichMin - 1;
            }
            return(retVal);
        }
예제 #7
0
        /// ------------------------------------------------------------------------------------
        /// <summary>
        /// Read the file to build mappings of the markers found
        /// </summary>
        /// ------------------------------------------------------------------------------------
        protected void GetMappingsFromStream(TextReader reader)
        {
            string lineIn;

            int chapter   = -1;
            int book      = -1;
            int lineCount = 0;

            // book and chapter strings for reporting info in exceptions
            string sBookId  = null;
            string sChapter = null;
            string sVerse   = null;

            // Keep track of the first reference in the file
            int firstBook    = -1;
            int firstChapter = -1;
            int firstVerse   = -1;

            ReferenceRange currentRange = null;
            string         marker;
            string         lineText;
            string         nextLineText = null;     // used for read-ahead for \fig line when doing strict scanning

            while ((lineIn = reader.ReadLine()) != null)
            {
                lineCount++;
                while (GetNextMarkerFromData(lineIn, out marker, out lineText))
                {
                    // Make sure the marker is valid
                    if (!IsValidMarker(marker))
                    {
                        throw new ScriptureUtilsException(SUE_ErrorCode.InvalidCharacterInMarker,
                                                          FileName, lineCount, lineIn, sBookId, sChapter, sVerse);
                    }

                    ImportMappingInfo markerMapping = GetOrCreateMarkerMapping(ref marker);

                    if (marker == ScrMappingList.MarkerBook)
                    {
                        sBookId = lineText.TrimStart().ToUpperInvariant();

                        // save the book number in the list for this file
                        book = ScrReference.BookToNumber(sBookId);
                        if (book <= 0)
                        {
                            throw new ScriptureUtilsException(SUE_ErrorCode.InvalidBookID, FileName,
                                                              lineCount, lineIn, sBookId, null, null);
                        }
                        sBookId = ScrReference.NumberToBookCode(book);

                        // Make a new reference range with the book id and
                        // start it out with chapter range of 0-0.
                        AddRangeToList(currentRange);
                        currentRange = new ReferenceRange(book, 0, 0);

                        // If this is the first book, remember it
                        if (firstBook == -1)
                        {
                            firstBook = book;
                        }
                        m_booksInFile.Add(book);
                        chapter = -1;
                    }
                    else
                    {
                        // make sure that a book has been started before seeing any non-excluded markers
                        // This error is a "strict" error because files can be added by a user before there
                        // is a chance to exclude markers in the mappings. When the file is added from the settings
                        // for import, then strict checking will be on.
                        if (book == -1 && m_doStrictFileChecking)
                        {
                            // if the marker is not excluded then throw an error
                            if (markerMapping != null && !markerMapping.IsExcluded)
                            {
                                throw new ScriptureUtilsException(SUE_ErrorCode.UnexcludedDataBeforeIdLine,
                                                                  FileName, lineCount, lineIn, null, null, null);
                            }
                        }

                        if (marker == ScrMappingList.MarkerChapter)
                        {
                            // If there is no book, then throw an error since chapter numbers
                            // are not valid without a book
                            if (book == -1)
                            {
                                throw new ScriptureUtilsException(SUE_ErrorCode.ChapterWithNoBook,
                                                                  FileName, lineCount, lineIn, null, null, null);
                            }
                            try
                            {
                                sChapter = lineText;
                                chapter  = ScrReference.ChapterToInt(sChapter);

                                // save the chapter number as the last chapter and possibly the first
                                // chapter number in the range.
                                if (currentRange.StartChapter == 0)
                                {
                                    currentRange.StartChapter = chapter;
                                }
                                currentRange.EndChapter = chapter;
                            }
                            catch (ArgumentException)
                            {
                                throw new ScriptureUtilsException(SUE_ErrorCode.InvalidChapterNumber,
                                                                  FileName, lineCount, lineIn, sBookId, sChapter, null);
                            }
                            // If this is the first chapter, remember it
                            if (firstChapter == -1)
                            {
                                firstChapter = chapter;
                            }
                        }

                        else if (marker == ScrMappingList.MarkerVerse)
                        {
                            // If a verse is seen without a book, throw an exception
                            if (book == -1)
                            {
                                throw new ScriptureUtilsException(SUE_ErrorCode.VerseWithNoBook,
                                                                  FileName, lineCount, lineIn, sBookId, null, lineText);
                            }

                            BCVRef firstRef = new BCVRef(book, chapter, 0);
                            BCVRef lastRef  = new BCVRef(book, chapter, 0);

                            // check for an invalid verse number
                            if (!BCVRef.VerseToScrRef(lineText, ref firstRef, ref lastRef) ||
                                firstRef.Verse == 0 || firstRef.Verse > lastRef.Verse)
                            {
                                throw new ScriptureUtilsException(SUE_ErrorCode.InvalidVerseNumber,
                                                                  FileName, lineCount, lineIn, sBookId, sChapter, lineText);
                            }

                            // If a chapter number has not been seen yet, then throw an exception
                            sVerse = firstRef.Verse.ToString();
                            if (chapter == -1 && !SingleChapterBook(book))
                            {
                                throw new ScriptureUtilsException(SUE_ErrorCode.MissingChapterNumber,
                                                                  FileName, lineCount, lineIn, sBookId, null, sVerse);
                            }

                            // If this is the first verse, remember it
                            if (firstVerse == -1)
                            {
                                firstVerse = firstRef.Verse;
                            }
                        }
                        else if (!markerMapping.IsExcluded && m_doStrictFileChecking &&
                                 markerMapping.MappingTarget == MappingTargetType.Figure)
                        {
                            // First, we need to consider whether any following lines also need
                            // to be read in, since the Figure parameters could be split across
                            // lines. (TE-7669)
                            Debug.Assert(nextLineText == null);
                            int    cExtraLinesRead = 0;
                            string sTempMarker, sTempLineText;
                            if (!GetNextMarkerFromData(lineText, out sTempMarker, out sTempLineText))
                            {
                                while ((nextLineText = reader.ReadLine()) != null)
                                {
                                    cExtraLinesRead++;
                                    if (GetNextMarkerFromData(nextLineText, out sTempMarker, out sTempLineText))
                                    {
                                        // Normally, we want to break the line right before the first marker.
                                        int ichMarkerPos = nextLineText.IndexOf(sTempMarker);
                                        // But if it's a \fig*, break after the marker.
                                        if (sTempMarker == markerMapping.EndMarker)
                                        {
                                            ichMarkerPos += sTempMarker.Length;
                                        }
                                        lineText    += " " + nextLineText.Substring(0, ichMarkerPos);
                                        nextLineText = nextLineText.Substring(ichMarkerPos);
                                        break;
                                    }
                                    else
                                    {
                                        lineText += " " + nextLineText;
                                    }
                                }
                            }

                            string figureParams    = lineText;
                            int    endMarkerLength = 0;
                            // Validate the tokens for a mapping target (only in strict checking)
                            if (!String.IsNullOrEmpty(markerMapping.EndMarker))
                            {
                                endMarkerLength = markerMapping.EndMarker.Length;
                                int ichEnd = figureParams.IndexOf(markerMapping.EndMarker);
                                if (ichEnd >= 0)
                                {
                                    figureParams = figureParams.Substring(0, ichEnd);
                                }
                                else
                                {
                                    endMarkerLength = 0;                                     // end marker is optional and not present
                                }
                            }
                            string[] tokens = figureParams.Split('|');
                            if (tokens.Length < 6)
                            {
                                throw new ScriptureUtilsException(SUE_ErrorCode.BadFigure, FileName,
                                                                  lineCount, lineIn, sBookId, sChapter, sVerse);
                            }
                            lineText   = lineText.Substring(figureParams.Length + endMarkerLength);
                            lineCount += cExtraLinesRead;
                        }
                    }
                    // Mark this mapping as "in-use" because it was found in the scanned file
                    markerMapping.SetIsInUse(m_domain, m_wsId, m_noteType, true);

                    if (m_scanInlineBackslashMarkers)
                    {
                        lineIn = lineText;
                    }
                    else
                    {
                        lineIn       = nextLineText;
                        nextLineText = null;
                        if (lineIn == null)
                        {
                            break;
                        }
                    }
                    if (string.IsNullOrEmpty(lineIn) && !string.IsNullOrEmpty(nextLineText))
                    {
                        lineIn       = nextLineText;
                        nextLineText = null;
                    }
                }
            }
            // Add the last range to the list
            AddRangeToList(currentRange);

            // If no books were found in the file then throw an exception
            if (book == -1)
            {
                throw new ScriptureUtilsException(SUE_ErrorCode.MissingBook,
                                                  FileName, lineCount, null, null, null, null);
            }


            // If no chapters were found then throw an exception
            if (chapter == -1 && !SingleChapterBook(book))
            {
                throw new ScriptureUtilsException(SUE_ErrorCode.NoChapterNumber,
                                                  FileName, lineCount, null, sBookId, null, null);
            }

            // Store the first reference for the file
            m_startRef.Book    = firstBook;
            m_startRef.Chapter = firstChapter == -1 ? 1 : firstChapter;
            m_startRef.Verse   = firstVerse == -1 ? 1 : firstVerse;
        }
예제 #8
0
        /// ------------------------------------------------------------------------------------
        /// <summary>
        /// Advances the enumerator to the next element of the collection.
        /// </summary>
        /// <returns>
        /// true if the enumerator was successfully advanced to the next element; false if the
        /// enumerator has passed the end of the collection.
        /// </returns>
        /// <exception cref="T:System.InvalidOperationException">The collection was modified
        /// after the enumerator was created. </exception>
        /// ------------------------------------------------------------------------------------
        public bool MoveNext()
        {
            if (m_currentScrText == null)
            {
                return(false);
            }

            while (++m_currentScrText.m_iRun < m_currentScrText.m_paraTss.RunCount)
            {
                m_internalToken.m_fParagraphStart = (m_currentScrText.m_iRun == 0);

                ITsTextProps runProps      = m_currentScrText.m_paraTss.get_Properties(m_currentScrText.m_iRun);
                string       charStyleName = runProps.GetStrPropValue((int)FwTextPropType.ktptNamedStyle);
                m_internalToken.m_sText      = m_currentScrText.m_paraTss.get_RunText(m_currentScrText.m_iRun);
                m_internalToken.m_paraOffset = m_currentScrText.m_paraTss.get_MinOfRun(m_currentScrText.m_iRun);
                int var;
                int ws = runProps.GetIntPropValues((int)FwTextPropType.ktptWs, out var);
                m_internalToken.m_icuLocale = GetLocale(ws);
                m_internalToken.Ws          = ws;
                switch (runProps.GetStrPropValue((int)FwTextPropType.ktptNamedStyle))
                {
                case ScrStyleNames.VerseNumber:
                    if (!m_foundStart || string.IsNullOrEmpty(m_internalToken.m_sText))
                    {
                        continue;
                    }

                    m_internalToken.m_textType = TextType.VerseNumber;
                    int verse = ScrReference.VerseToIntStart(m_internalToken.m_sText);
                    if (verse != 0)
                    {
                        m_internalToken.m_startRef.Verse = verse;
                    }
                    verse = ScrReference.VerseToIntEnd(m_internalToken.m_sText);
                    if (verse != 0)
                    {
                        m_internalToken.m_endRef.Verse = verse;
                    }

                    break;

                case ScrStyleNames.ChapterNumber:
                    if (string.IsNullOrEmpty(m_internalToken.m_sText))
                    {
                        continue;
                    }
                    int chapter = 0;
                    try
                    {
                        chapter = ScrReference.ChapterToInt(m_internalToken.m_sText);
                    }
                    catch
                    {
                        // Ignore exceptions. We'll flag them later as errors.
                    }
                    if (!m_foundStart)
                    {
                        if (m_chapterNum != chapter)
                        {
                            continue;
                        }
                        m_foundStart = true;
                    }
                    else if (m_chapterNum > 0 && m_chapterNum != chapter)
                    {
                        // Stop if we're only getting tokens for a single chapter (unless
                        // this is an (erroneous) second occurrence of the same chapter)
                        return(false);
                    }
                    m_internalToken.m_textType         = TextType.ChapterNumber;
                    m_internalToken.m_startRef.Chapter = m_internalToken.m_endRef.Chapter = chapter;
                    m_internalToken.m_startRef.Verse   = m_internalToken.m_endRef.Verse = 1;
                    break;

                default:
                {
                    if (!m_foundStart)
                    {
                        continue;
                    }
                    // Deal with footnotes and picture captions
                    Guid guidObj = StringUtils.GetGuidFromRun(m_currentScrText.m_paraTss, m_currentScrText.m_iRun, runProps);
                    if (guidObj == Guid.Empty)
                    {
                        m_internalToken.m_textType = m_currentScrText.DefaultTextType;
                    }
                    else if (m_outerText != null)
                    {
                        // It was possible through copy/paste to put ORCs into footnotes or pictures, but that is no
                        // longer allowed. This tokenizing code won't handle the nesting correctly, so just ignore
                        // the nested ORC. See TE-8609.
                        continue;
                    }
                    else
                    {
                        m_fOrcWasStartOfPara = m_internalToken.m_fParagraphStart;
                        int hvo = m_book.Cache.GetIdFromGuid(guidObj);
                        if (hvo > 0)
                        {
                            switch (m_book.Cache.GetClassOfObject(hvo))
                            {
                            case StFootnote.kclsidStFootnote:
                                m_outerText = m_currentScrText;
                                // footnotes are StTexts
                                m_currentScrText = new TokenizableText(new StText(m_book.Cache, hvo), TextType.Note);
                                return(MoveNext());

                            case CmPicture.kclsidCmPicture:
                            {
                                m_outerText = m_currentScrText;
                                CmPicture pict = new CmPicture(m_book.Cache, hvo);
                                m_currentScrText = new TokenizableText(
                                    pict.Caption.VernacularDefaultWritingSystem.UnderlyingTsString,
                                    ScrStyleNames.Figure, TextType.PictureCaption, pict,
                                    (int)CmPicture.CmPictureTags.kflidCaption);
                                return(MoveNext());
                            }
                            }
                        }
                    }
                }
                break;
                }
                m_internalToken.m_fNoteStart = (m_internalToken.m_textType == TextType.Note &&
                                                m_internalToken.m_fParagraphStart && m_currentScrText.m_iPara == 0);
                m_internalToken.m_paraStyleName = m_currentScrText.ParaStyleName;
                m_internalToken.m_charStyleName = charStyleName != null ? charStyleName : string.Empty;
                m_internalToken.m_object        = m_currentScrText.m_obj;
                m_internalToken.m_flid          = m_currentScrText.m_flid;

                // We need the current token to be a copy of our internal token so we don't change the
                // internal variables of whatever was returned from the enumerator.
                m_currentToken = m_internalToken.Copy();
                return(true);
            }
            // Finished that paragraph and didn't find any more runs; try next para in this text,
            // if any.
            if (!m_currentScrText.NextParagraph())
            {
                if (!m_foundStart)
                {
                    Debug.Fail("We should have found the desired chapter wtihin the section we were searching.");
                    return(false);
                }
                // Finished that text and didn't find any more paragraphs.
                // If we have been processing an inner text (footnote or picture caption), pop back
                // out to the "outer" one.
                if (m_outerText != null)
                {
                    m_currentScrText = m_outerText;
                    m_outerText      = null;
                    bool result = MoveNext();
                    if (result)
                    {
                        m_currentToken.m_fParagraphStart |= m_fOrcWasStartOfPara;
                        m_fOrcWasStartOfPara              = false;
                    }
                    return(result);
                }

                // Otherwise, try next text, if any.
                if (m_currentScrText.m_text.OwningFlid == (int)ScrBook.ScrBookTags.kflidTitle)
                {
                    // Get first section head text.
                    CurrentSectionIndex = 0;
                }
                else if (m_currentScrText.m_text.OwningFlid == (int)ScrSection.ScrSectionTags.kflidHeading)
                {
                    m_currentScrText = new TokenizableText(m_currentSection.ContentOA,
                                                           m_currentSection.IsIntro ? TextType.Other : TextType.Verse);
                }
                else
                {
                    Debug.Assert(m_currentScrText.m_text.OwningFlid == (int)ScrSection.ScrSectionTags.kflidContent);
                    if (m_iCurrentSection + 1 >= m_book.SectionsOS.Count)
                    {
                        return(false);
                    }
                    CurrentSectionIndex++;
                    if (m_chapterNum > 0 && ScrReference.GetChapterFromBcv(m_currentSection.VerseRefStart) != m_chapterNum)
                    {
                        return(false);
                    }
                }
            }
            return(MoveNext());
        }
예제 #9
0
        /// ------------------------------------------------------------------------------------
        /// <summary>
        /// Finds all ORCs in the given text and notes any orphaned footnotes or pictures.
        /// </summary>
        /// <param name="text">The text.</param>
        /// <param name="textLocationInfo">Additional information about the location of the
        /// text that can help the user find it.</param>
        /// <param name="startRef">Caller should pass in the initial reference to use as the
        /// basis for any references found in the course of parsing the text. Returned value
        /// will be the final reference found, which can be used as the basis for the subsequent
        /// text</param>
        /// <param name="endRef">Same as startRef, except in the case of verse bridges or
        /// section headings</param>
        /// <param name="footnotes">List of footnotes owned by the book that owns the
        /// given text. As footnotes are found, their locations will be set.</param>
        /// <param name="parasWithOrcs">List of paragraphs and ORC positions (excluding known
        /// picture ORCs).</param>
        /// <returns></returns>
        /// ------------------------------------------------------------------------------------
        private static bool FindOrcsWithoutPropsInText(IStText text, string textLocationInfo,
                                                       ref BCVRef startRef, ref BCVRef endRef,
                                                       List <FootnoteOrcLocation> footnotes, List <OrcLocation> parasWithOrcs)
        {
            bool foundOrphan = false;

            foreach (IStTxtPara para in text.ParagraphsOS)
            {
                ITsString tssContents = para.Contents;
                string    sContents   = tssContents.Text;
                if (sContents == null)
                {
                    continue;
                }

                int nRun = tssContents.RunCount;
                for (int i = 0; i < nRun; i++)
                {
                    TsRunInfo    runInfo;
                    ITsTextProps tprops    = tssContents.FetchRunInfo(i, out runInfo);
                    string       styleName = tprops.GetStrPropValue(
                        (int)FwTextPropType.ktptNamedStyle);

                    // When a verse number is encountered, save the number into
                    // the reference.
                    if (styleName == ScrStyleNames.VerseNumber)
                    {
                        string sVerseNum = sContents.Substring(runInfo.ichMin,
                                                               runInfo.ichLim - runInfo.ichMin);
                        int nVerseStart, nVerseEnd;
                        ScrReference.VerseToInt(sVerseNum, out nVerseStart, out nVerseEnd);
                        startRef.Verse = nVerseStart;
                        endRef.Verse   = nVerseEnd;
                    }

                    // If a chapter number is encountered then save the number into
                    // the reference and start the verse number back at 1.
                    else if (styleName == ScrStyleNames.ChapterNumber)
                    {
                        try
                        {
                            string sChapterNum = sContents.Substring(runInfo.ichMin,
                                                                     runInfo.ichLim - runInfo.ichMin);
                            startRef.Chapter = endRef.Chapter = ScrReference.ChapterToInt(sChapterNum);
                            startRef.Verse   = endRef.Verse = 1;
                        }
                        catch (ArgumentException)
                        {
                            // ignore runs with invalid Chapter numbers
                        }
                    }
                    else
                    {
                        // search contents for ORCs
                        for (int ich = runInfo.ichMin; ich < runInfo.ichLim; ich++)
                        {
                            if (sContents[ich] != StringUtils.kChObject)
                            {
                                continue;
                            }

                            OrcLocation orcLocation = new OrcLocation(para, ich, startRef, endRef, textLocationInfo);

                            ITsTextProps props   = tssContents.get_PropertiesAt(ich);
                            string       objData = props.GetStrPropValue((int)FwTextPropType.ktptObjData);

                            if (objData == null)
                            {
                                foundOrphan = true;
                            }
                            else
                            {
                                // first char. of strData is type code - GUID will follow it.
                                Guid objGuid = MiscUtils.GetGuidFromObjData(objData.Substring(1));

                                ICmObject obj;
                                if (!text.Cache.ServiceLocator.ObjectRepository.TryGetObject(objGuid, out obj))
                                {
                                    foundOrphan = true;
                                }
                                else if (obj.ClassID == ScrFootnoteTags.kClassId)
                                {
                                    foreach (FootnoteOrcLocation footnote in footnotes)
                                    {
                                        if (footnote.footnote.Guid == objGuid)
                                        {
                                            orcLocation.Footnote = footnote.footnote;
                                            footnote.location    = orcLocation;
                                            break;
                                        }
                                    }
                                }
                                else
                                {
                                    Debug.Assert(obj.ClassID == CmPictureTags.kClassId, "Unknown class id in embedded object: " + obj.ClassID);
                                    continue;
                                }
                            }
                            parasWithOrcs.Add(orcLocation);
                        }
                    }
                }
            }
            return(foundOrphan);
        }
예제 #10
0
        /// ------------------------------------------------------------------------------------
        /// <summary>
        /// Gets the reference for this footnote.
        /// </summary>
        /// <param name="owningBook">The owning book.</param>
        /// <param name="para">The para to search for a Scripture reference (verse or chapter).
        /// </param>
        /// <param name="startRef">The starting reference for this footnote (updated in this
        /// method).</param>
        /// <param name="endRef">The ending reference for this footnote (updated in this
        /// method).</param>
        /// <returns></returns>
        /// ------------------------------------------------------------------------------------
        private RefResult GetReference(IScrBook owningBook, IScrTxtPara para, BCVRef startRef, BCVRef endRef)
        {
            bool foundSelf = (para != ParaContainingOrcRA);
            IStFootnoteRepository footnoteRepo = Cache.ServiceLocator.GetInstance <IStFootnoteRepository>();

            ITsString tssContents = para.Contents;

            for (int i = tssContents.RunCount - 1; i >= 0; i--)
            {
                string styleName = tssContents.get_StringProperty(i, (int)FwTextPropType.ktptNamedStyle);
                if (foundSelf && styleName == ScrStyleNames.VerseNumber && startRef.Verse == 0)
                {
                    int nVerseStart, nVerseEnd;
                    ScrReference.VerseToInt(tssContents.get_RunText(i), out nVerseStart, out nVerseEnd);
                    startRef.Verse = nVerseStart;
                    endRef.Verse   = nVerseEnd;
                }
                else if (foundSelf && styleName == ScrStyleNames.ChapterNumber && startRef.Chapter == 0)
                {
                    try
                    {
                        startRef.Chapter = endRef.Chapter =
                            ScrReference.ChapterToInt(tssContents.get_RunText(i));
                    }
                    catch (ArgumentException)
                    {
                        // ignore runs with invalid Chapter numbers
                    }
                    if (startRef.Verse == 0)
                    {
                        startRef.Verse = endRef.Verse = 1;
                    }
                }
                else if (styleName == null)
                {
                    IScrFootnote footnote = (IScrFootnote)footnoteRepo.GetFootnoteFromObjData(tssContents.get_StringProperty(i, (int)FwTextPropType.ktptObjData));
                    if (footnote != null)
                    {
                        if (footnote == this)
                        {
                            foundSelf = true;
                            continue;
                        }
                        RefRange otherFootnoteLocation = ((ScrFootnote)footnote).FootnoteRefInfo_Internal;
                        if (foundSelf && otherFootnoteLocation != RefRange.EMPTY)
                        {
                            // Found another footnote with a reference we can use
                            if (startRef.Verse == 0)
                            {
                                startRef.Verse = otherFootnoteLocation.StartRef.Verse;
                                endRef.Verse   = otherFootnoteLocation.EndRef.Verse;
                            }

                            if (startRef.Chapter == 0)
                            {
                                startRef.Chapter = otherFootnoteLocation.StartRef.Chapter;
                                endRef.Chapter   = otherFootnoteLocation.EndRef.Chapter;
                            }
                        }
                        else if (foundSelf)
                        {
                            // Previous footnote does not have a reference yet. We presume, for performance
                            // reasons, that none of the previous footnotes have valid references yet, so
                            // we set all the footnotes for the book.
                            ((ScrBook)owningBook).RefreshFootnoteRefs();
                            return(RefResult.ScannedAllFootnotes);
                        }
                    }
                }

                if (startRef.Verse != 0 && endRef.Verse != 0 && startRef.Chapter != 0 &&
                    endRef.Chapter != 0)
                {
                    return(RefResult.Found);
                }
            }
            return(RefResult.NotFound);
        }