Пример #1
0
        protected virtual IList <CharacterVerse> ProcessLine(string[] items, int lineNumber)
        {
            var list = new List <CharacterVerse>();

            if (items.Length < kiQuoteType)
            {
                throw new ApplicationException("Bad format in CharacterVerse control file! Line #: " + lineNumber + "; Line contents: " + string.Join("\t", items));
            }
            if (items.Length > kMaxItems)
            {
                throw new ApplicationException("Incorrect number of fields in CharacterVerse control file! Line #: " + lineNumber + "; Line contents: " + string.Join("\t", items));
            }

            int chapter;

            if (!Int32.TryParse(items[1], out chapter))
            {
                Debug.Assert(false, string.Format("Invalid chapter number ({0}) on line {1}: {2}", items[1], lineNumber, items[0]));
            }
            for (int verse = ScrReference.VerseToIntStart(items[2]); verse <= ScrReference.VerseToIntEnd(items[2]); verse++)
            {
                list.Add(CreateCharacterVerse(new BCVRef(BCVRef.BookToNumber(items[0]), chapter, verse), items));
            }

            return(list);
        }
Пример #2
0
        /// <summary>
        /// Add the working block to the new list and create a new working block
        /// </summary>
        /// <param name="styleTag"></param>
        /// <param name="nonNarrator"></param>
        private void FlushBlock(string styleTag, bool nonNarrator)
        {
            if (!m_workingBlock.BlockElements.Any())
            {
                m_workingBlock.StyleTag = styleTag;
                return;
            }
            if (nonNarrator)
            {
                if (m_nextBlockContinuesQuote)
                {
                    m_workingBlock.MultiBlockQuote = MultiBlockQuote.Continuation;
                }
                m_nextBlockContinuesQuote = m_quoteLevel > 0;
                if (m_nextBlockContinuesQuote && m_workingBlock.MultiBlockQuote != MultiBlockQuote.Continuation)
                {
                    m_workingBlock.MultiBlockQuote = MultiBlockQuote.Start;
                }

                m_workingBlock.SetCharacterAndDelivery(
                    m_cvInfo.GetCharacters(m_bookNum, m_workingBlock.ChapterNumber, m_workingBlock.InitialStartVerseNumber, m_workingBlock.InitialEndVerseNumber, m_workingBlock.LastVerse, m_versification));
            }
            else
            {
                m_nextBlockContinuesQuote = false;
                m_workingBlock.SetStandardCharacter(m_bookId, CharacterVerseData.StandardCharacter.Narrator);
            }

            switch (m_workingBlock.MultiBlockQuote)
            {
            case MultiBlockQuote.Start:
                ProcessMultiBlock();
                m_currentMultiBlockQuote.Add(m_workingBlock);
                break;

            case MultiBlockQuote.Continuation:
                m_currentMultiBlockQuote.Add(m_workingBlock);
                break;

            case MultiBlockQuote.None:
                ProcessMultiBlock();
                break;
            }

            m_outputBlocks.Add(m_workingBlock);
            var lastVerse     = m_workingBlock.BlockElements.OfType <Verse>().LastOrDefault();
            int verseStartNum = m_workingBlock.InitialStartVerseNumber;
            int verseEndNum   = m_workingBlock.InitialEndVerseNumber;

            if (lastVerse != null)
            {
                verseStartNum = ScrReference.VerseToIntStart(lastVerse.Number);
                verseEndNum   = ScrReference.VerseToIntEnd(lastVerse.Number);
            }
            m_workingBlock = new Block(styleTag, m_workingBlock.ChapterNumber, verseStartNum, verseEndNum);
        }
Пример #3
0
        public IEnumerable <Block> Parse()
        {
            var           titleBuilder = new StringBuilder();
            IList <Block> blocks       = new List <Block>();

            foreach (XmlNode node in m_nodeList)
            {
                Block block = null;
                switch (node.Name)
                {
                case "chapter":
                    AddMainTitleIfApplicable(blocks, titleBuilder);
                    m_chapterNodeFound = true;
                    block = ProcessChapterNode(node);
                    if (block == null)
                    {
                        continue;
                    }
                    break;

                case "para":
                    if (!node.HasChildNodes)
                    {
                        continue;
                    }

                    var    usxPara = new UsxNode(node);
                    IStyle style   = m_stylesheet.GetStyle(usxPara.StyleTag);
                    if (style.IsChapterLabel)
                    {
                        block = ProcessChapterLabelNode(node.InnerText, usxPara);
                        if (block == null)
                        {
                            continue;
                        }

                        // The node before this was the chapter. We already added it, then found this label.
                        // Remove that block so it will be replaced with this one.
                        blocks.RemoveAt(blocks.Count - 1);
                        break;
                    }

                    if (style.IsParallelPassageReference || !style.IsPublishable)
                    {
                        continue;
                    }

                    if (style.HoldsBookNameOrAbbreviation)
                    {
                        if (style.Id.StartsWith("mt"))
                        {
                            titleBuilder.Append(node.InnerText).Append(" ");
                            if (style.Id == "mt1")
                            {
                                MainTitle = node.InnerText;
                            }
                        }
                        else if (style.Id == "h")
                        {
                            PageHeader = node.InnerText;
                        }
                        continue;
                    }
                    AddMainTitleIfApplicable(blocks, titleBuilder);

                    block = new Block(usxPara.StyleTag, m_currentChapter, m_currentStartVerse, m_currentEndVerse)
                    {
                        IsParagraphStart = true
                    };
                    if (m_currentChapter == 0)
                    {
                        block.SetStandardCharacter(m_bookId, CharacterVerseData.StandardCharacter.Intro);
                    }
                    else if (style.IsPublishable && !style.IsVerseText)
                    {
                        block.SetStandardCharacter(m_bookId, CharacterVerseData.StandardCharacter.ExtraBiblical);
                    }

                    var sb = new StringBuilder();
                    // <verse number="1" style="v" />
                    // Acakki me lok me kwena maber i kom Yecu Kricito, Wod pa Lubaŋa,
                    // <verse number="2" style="v" />
                    // <note caller="-" style="x"><char style="xo" closed="false">1.2: </char><char style="xt" closed="false">Mal 3.1</char></note>
                    // kit ma gicoyo kwede i buk pa lanebi Icaya ni,</para>
                    foreach (XmlNode childNode in usxPara.ChildNodes)
                    {
                        switch (childNode.Name)
                        {
                        case "verse":
                            if (sb.Length > 0)
                            {
                                sb.TrimStart();
                                block.BlockElements.Add(new ScriptText(sb.ToString()));
                                sb.Clear();
                            }
                            RemoveLastElementIfVerse(block);
                            var verseNumStr = childNode.Attributes.GetNamedItem("number").Value;
                            m_currentStartVerse = ScrReference.VerseToIntStart(verseNumStr);
                            m_currentEndVerse   = ScrReference.VerseToIntEnd(verseNumStr);
                            if (!block.BlockElements.Any() ||
                                (block.BlockElements.Count == 1 && block.FirstTextElementIsOnlyPunctuation))
                            {
                                block.InitialStartVerseNumber = m_currentStartVerse;
                                block.InitialEndVerseNumber   = m_currentEndVerse;
                            }

                            block.BlockElements.Add(new Verse(verseNumStr));
                            break;

                        case "char":
                            IStyle charStyle = m_stylesheet.GetStyle((new UsxNode(childNode)).StyleTag);
                            if (!charStyle.IsInlineQuotationReference && charStyle.IsPublishable)
                            {
                                sb.Append(childNode.InnerText);
                            }
                            break;

                        case "#text":
                            sb.Append(childNode.InnerText);
                            break;

                        case "#whitespace":
                            if (sb.Length > 0 && sb[sb.Length - 1] != ' ')
                            {
                                sb.Append(" ");
                            }
                            break;
                        }
                    }
                    sb.TrimStart();
                    if (sb.Length > 0)
                    {
                        block.BlockElements.Add(new ScriptText(sb.ToString()));
                        sb.Clear();
                    }
                    RemoveLastElementIfVerse(block);
                    break;
                }
                if (block != null && block.BlockElements.Count > 0)
                {
                    blocks.Add(block);
                }
            }
            return(blocks);
        }
Пример #4
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());
        }