public void GetTextTokens_WholeBook() { ScrChecksDataSource dataSource = new ScrChecksDataSource(Cache); m_scrInMemoryCache.AddBookToMockedScripture(1, "Genesis"); int iExodus = 2; IScrBook exodus = m_scrInMemoryCache.AddBookToMockedScripture(iExodus, "Exodus"); m_scrInMemoryCache.AddTitleToMockedBook(exodus.Hvo, "Exodus"); IScrSection section = m_scrInMemoryCache.AddIntroSectionToMockedBook(exodus.Hvo); StTxtPara paraIntroSectHead = m_scrInMemoryCache.AddParaToMockedText(section.HeadingOAHvo, ScrStyleNames.IntroSectionHead); m_scrInMemoryCache.AddRunToMockedPara(paraIntroSectHead, "Everything you wanted to know about Exodus but were afraid to ask", null); StTxtPara paraIntroSectContent = m_scrInMemoryCache.AddParaToMockedText(section.ContentOAHvo, ScrStyleNames.IntroParagraph); m_scrInMemoryCache.AddRunToMockedPara(paraIntroSectContent, "There's not much to say, really.", null); section.AdjustReferences(); section = m_scrInMemoryCache.AddSectionToMockedBook(exodus.Hvo); StTxtPara paraSectHead1 = m_scrInMemoryCache.AddSectionHeadParaToSection(section.Hvo, "Head1", ScrStyleNames.SectionHead); StTxtPara paraSect1Content = m_scrInMemoryCache.AddParaToMockedSectionContent(section.Hvo, ScrStyleNames.NormalParagraph); m_scrInMemoryCache.AddRunToMockedPara(paraSect1Content, "1", ScrStyleNames.ChapterNumber); m_scrInMemoryCache.AddRunToMockedPara(paraSect1Content, "1", ScrStyleNames.VerseNumber); m_scrInMemoryCache.AddRunToMockedPara(paraSect1Content, "Chapter 1 Verse 1 Text", null); section.AdjustReferences(); section = m_scrInMemoryCache.AddSectionToMockedBook(exodus.Hvo); StTxtPara paraSectHead2 = m_scrInMemoryCache.AddSectionHeadParaToSection(section.Hvo, "Head2", ScrStyleNames.SectionHead); StTxtPara paraSect2Content1 = m_scrInMemoryCache.AddParaToMockedSectionContent(section.Hvo, ScrStyleNames.NormalParagraph); m_scrInMemoryCache.AddRunToMockedPara(paraSect2Content1, "2", ScrStyleNames.ChapterNumber); m_scrInMemoryCache.AddRunToMockedPara(paraSect2Content1, "Chapter 2 Verse 1 Text", null); m_scrInMemoryCache.AddRunToMockedPara(paraSect2Content1, "2", ScrStyleNames.VerseNumber); m_scrInMemoryCache.AddRunToMockedPara(paraSect2Content1, "Chapter 2 Verse 2 Text ", null); m_scrInMemoryCache.AddRunToMockedPara(paraSect2Content1, "Wow!", "Emphasis"); StTxtPara paraSect2Content2 = m_scrInMemoryCache.AddParaToMockedSectionContent(section.Hvo, "Line 1"); m_scrInMemoryCache.AddRunToMockedPara(paraSect2Content2, "Selah", ScrStyleNames.Interlude); StFootnote footnote = m_scrInMemoryCache.AddFootnote(exodus, paraSect2Content2, 5, "This is the text of the footnote"); m_scrInMemoryCache.AddRunToMockedPara((StTxtPara)footnote.ParagraphsOS[0], "Favorite", Cache.DefaultUserWs); m_scrInMemoryCache.AddRunToMockedPara(paraSect2Content2, " or say, \"la\".", null); CmPicture pict; using (DummyFileMaker filemaker = new DummyFileMaker("junk.jpg", true)) { ITsStrFactory factory = TsStrFactoryClass.Create(); pict = new CmPicture(Cache, filemaker.Filename, factory.MakeString("Test picture caption", Cache.DefaultVernWs), StringUtils.LocalPictures); ITsStrBldr bldr = paraSect2Content2.Contents.UnderlyingTsString.GetBldr(); pict.AppendPicture(Cache.DefaultVernWs, bldr); paraSect2Content2.Contents.UnderlyingTsString = bldr.GetString(); } section.AdjustReferences(); Assert.IsTrue(dataSource.GetText(iExodus, 0)); IEnumerator<ITextToken> tokens = dataSource.TextTokens().GetEnumerator(); VerifyToken(tokens, "Exodus", ScrStyleNames.MainBookTitle, string.Empty, exodus.TitleOA.ParagraphsOS[0]); VerifyToken(tokens, "Everything you wanted to know about Exodus but were afraid to ask", ScrStyleNames.IntroSectionHead, string.Empty, paraIntroSectHead); VerifyToken(tokens, "There's not much to say, really.", ScrStyleNames.IntroParagraph, string.Empty, paraIntroSectContent); BCVRef expectedRef = new BCVRef(iExodus, 1, 1); VerifyToken(tokens, "Head1", ScrStyleNames.SectionHead, string.Empty, expectedRef, true, TextType.Other, paraSectHead1); VerifyToken(tokens, "1", ScrStyleNames.NormalParagraph, ScrStyleNames.ChapterNumber, expectedRef, true, TextType.ChapterNumber, paraSect1Content); VerifyToken(tokens, "1", ScrStyleNames.NormalParagraph, ScrStyleNames.VerseNumber, expectedRef, false, TextType.VerseNumber, paraSect1Content); VerifyToken(tokens, "Chapter 1 Verse 1 Text", "Paragraph", string.Empty, expectedRef, false, TextType.Verse, paraSect1Content); expectedRef.Chapter = 2; VerifyToken(tokens, "Head2", ScrStyleNames.SectionHead, string.Empty, expectedRef, true, TextType.Other, paraSectHead2); VerifyToken(tokens, "2", ScrStyleNames.NormalParagraph, ScrStyleNames.ChapterNumber, expectedRef, true, TextType.ChapterNumber, paraSect2Content1); VerifyToken(tokens, "Chapter 2 Verse 1 Text", ScrStyleNames.NormalParagraph, string.Empty, expectedRef, false, TextType.Verse, paraSect2Content1); expectedRef.Verse = 2; VerifyToken(tokens, "2", ScrStyleNames.NormalParagraph, ScrStyleNames.VerseNumber, expectedRef, false, TextType.VerseNumber, paraSect2Content1); VerifyToken(tokens, "Chapter 2 Verse 2 Text ", ScrStyleNames.NormalParagraph, string.Empty, expectedRef, false, TextType.Verse, paraSect2Content1); VerifyToken(tokens, "Wow!", ScrStyleNames.NormalParagraph, ScrStyleNames.Emphasis, expectedRef, false, TextType.Verse, paraSect2Content1); VerifyToken(tokens, "Selah", "Line 1", ScrStyleNames.Interlude, expectedRef, true, TextType.Verse, paraSect2Content2); VerifyToken(tokens, "This is the text of the footnote", ScrStyleNames.NormalFootnoteParagraph, string.Empty, expectedRef, true, TextType.Note, footnote.ParagraphsOS[0]); VerifyToken(tokens, "Favorite", ScrStyleNames.NormalFootnoteParagraph, string.Empty, expectedRef, expectedRef, false, TextType.Note, "en", footnote.ParagraphsOS[0], (int)StTxtPara.StTxtParaTags.kflidContents); VerifyToken(tokens, " or say, \"la\".", "Line 1", string.Empty, expectedRef, false, TextType.Verse, paraSect2Content2); VerifyToken(tokens, "Test picture caption", ScrStyleNames.Figure, string.Empty, expectedRef, expectedRef, true, TextType.PictureCaption, null, pict, (int)CmPicture.CmPictureTags.kflidCaption); Assert.IsFalse(tokens.MoveNext()); }
/// ------------------------------------------------------------------------------------ /// <summary> /// Create an ITsString from a format string. /// </summary> /// <param name="book">The book for inserting footnotes into (can be null if there are /// no footnotes)</param> /// <param name="strBldr">The ITsStrBldr to add the text to (if null a new one will be /// created)</param> /// <param name="format">format string, which may include these special "commands": /// \c - insert a chapter number run /// \v - insert a verse number run /// \* - insert a simple text run /// \*(char style name) - insert a text run with a character style. /// \i - insert a picture (text must be the text rep of the picture (see pic code)) /// \f - insert a footnote</param> /// \^ - end of the current footnote (required for every footnote) /// <param name="ws">writing system for each run of text</param> /// <returns>the completed ITsString</returns> /// ------------------------------------------------------------------------------------ public static ITsString CreateFormatText(IScrBook book, ITsStrBldr strBldr, string format, int ws) { if (strBldr == null) strBldr = TsStrBldrClass.Create(); int nChapter = 1, nVerse = 1; for (int i = 0; i < format.Length; ) { // skip the backslash (verify that it is there first) if (format[i] != '\\') Debug.Assert(false, @"Format string must start every text run with \*: {0}" + format.Substring(i)); if (++i >= format.Length) break; // save the field type character char field = format[i]; if (++i >= format.Length) break; // determine the endmarker we'll look for string endMarker = (field == 'f' || field == 'i') ? @"\^" : @"\"; // extract the data for the field int lim = format.IndexOf(endMarker, i); if (lim == -1 && field == 'f') Debug.Assert(false, @"Format string must have a \^ to end footnote!"); else if (lim == -1) lim = format.Length; string fieldData = format.Substring(i, lim - i); // remember pos of next backslash, or the end of the format string i = lim; //skip empty commands, such as \^ if (fieldData.Length == 0) continue; // what kind of command is this? switch (field) { case 'c': Int32.TryParse(fieldData, out nChapter); AddRunToStrBldr(strBldr, fieldData, ws, "Chapter Number"); break; case 'v': FdoCache cache = book.Cache; LgWritingSystem vernWs = new LgWritingSystem(cache, cache.DefaultVernWs); string sBridge = cache.LangProject.TranslatedScriptureOA.Bridge; string [] pieces = fieldData.Split(new string[] {sBridge}, 2, StringSplitOptions.RemoveEmptyEntries); StringBuilder strb = new StringBuilder(); string sLastVerse = pieces[pieces.Length - 1]; Int32.TryParse(fieldData, out nVerse); if (vernWs.RightToLeft && pieces.Length == 2) { // The verse number run has a bridge and is in a right-to-left // writing system. Construct a verse bridge with right-to-left // characters adjacent to the bridge character. strb.Append(pieces[0] + '\u200f' + sBridge + '\u200f' + pieces[1]); } else strb.Append(fieldData); AddRunToStrBldr(strBldr, strb.ToString(), ws, "Verse Number"); break; case 'f': StFootnote footnote = new StFootnote(); book.FootnotesOS.Append(footnote); footnote.InsertOwningORCIntoPara(strBldr, strBldr.Length, ws); footnote.FootnoteMarker.UnderlyingTsString = TsStringHelper.MakeTSS("a", ws); // auto-generate if (fieldData.IndexOf(@"\f") != -1) Debug.Assert(false, @"Format string must not nest \f within another \f..\^"); StTxtPara para = AppendParagraph(footnote, fieldData, ws); //recursively calls CreateText to process any char styles para.StyleRules = StyleUtils.ParaStyleTextProps("Note General Paragraph"); //TODO: add multiple paragraphs for a footnote break; case 'i': CmPicture picture = new CmPicture(book.Cache, fieldData, StringUtils.LocalPictures, new BCVRef(book.CanonicalNum, nChapter, nVerse), book.Cache.LangProject.TranslatedScriptureOA as IPictureLocationBridge); picture.AppendPicture(ws, strBldr); break; case '*': { int wsRun = ws; string charStyleName = null; // if we have an optional character style in parens, process it if (fieldData[0] == '(') { int endParen = fieldData.IndexOf(")", 0); Debug.Assert(endParen > 1); // caller must provide something within parens if (endParen != -1) { charStyleName = fieldData.Substring(1, endParen - 1); fieldData = fieldData.Substring(endParen + 1); } } // if we have an optional writing system specifier, process it if (fieldData[0] == '|' && fieldData.Length > 3 && fieldData[3] == '|') { wsRun = book.Cache.LanguageWritingSystemFactoryAccessor.GetWsFromStr(fieldData.Substring(1, 2)); if (wsRun > 0) fieldData = fieldData.Substring(4); else wsRun = ws; } AddRunToStrBldr(strBldr, fieldData, wsRun, charStyleName); break; } } } return strBldr.GetString(); }