private static void AppendTextToBlock(string text, TextBlockBuilder builder) { if (string.IsNullOrEmpty(text)) { return; } // Replace \r\n combinations with \n, and then replace \r with \n text = text.Replace("\r\n", "\n"); text = text.Replace("\r", "\n"); char lastchar = '\0'; foreach (char ch in text) { if (ch == '\n') { builder.Append(TagId.EOL); } else { builder.AppendChar(ch); lastchar = ch; } } }
private void AddTocEntry(TocEntry entry, int level, PageObject tocPage) { HtmlElement element = (HtmlElement)entry.Tag; IHTMLDOMNode entryNode = (IHTMLDOMNode)element.DomElement; Debug.WriteLine("Creating TOC entry \"" + entry.Title + "\""); TextBlockBuilder tbBuilder = new TextBlockBuilder(GetNextObjId(), m_CharMapper); if (m_HeadingNodePageId.ContainsKey(entryNode)) { ushort wHeadingTextPageId = m_HeadingNodePageId[entryNode]; ushort wHeadingTextBlockId = m_HeadingNodeTextBlockId[entryNode]; // Create the one button object that points to the first block // in the document page. ButtonObject button = new ButtonObject(GetNextObjId()); button.ButtonType = ButtonType.PushButton; button.SetObjectIds(wHeadingTextPageId, wHeadingTextBlockId); button.Serialize(); m_Book.Objects.Add(button); // TODO Need to set a different block attribute to control the X // position instead of just adding spaces. for (int i = 0; i < level; i++) { tbBuilder.Append(" "); } tbBuilder.Append(TagId.BeginButton, (uint)button.ID); tbBuilder.Append(entry.Title); tbBuilder.Append(TagId.EndButton); FlushTextToBlock(tocPage, tbBuilder, m_MainBodyTextAttr); tocPage.Children.Add(button); } // Now for all of the children foreach (TocEntry childEntries in entry.Children) { AddTocEntry(childEntries, level + 1, tocPage); } }
private void createCoverPage() { PageObject coverPage = createPage(); if (!string.IsNullOrEmpty(m_Book.MetaData.BookInfo.Title)) { TextBlockBuilder tbBuilder = new TextBlockBuilder(GetNextObjId(), m_CharMapper); tbBuilder.Append(TagId.EOL); tbBuilder.Append(TagId.EOL); tbBuilder.Append(m_Book.MetaData.BookInfo.Title); FlushTextToBlock(coverPage, tbBuilder, m_CenteredTextAttr); } if (!string.IsNullOrEmpty(m_Book.MetaData.BookInfo.Author)) { TextBlockBuilder tbBuilder = new TextBlockBuilder(GetNextObjId(), m_CharMapper); tbBuilder.Append("By "); tbBuilder.Append(m_Book.MetaData.BookInfo.Author); FlushTextToBlock(coverPage, tbBuilder, m_CenteredTextAttr); } if (!string.IsNullOrEmpty(m_Book.MetaData.BookInfo.Publisher)) { TextBlockBuilder tbBuilder = new TextBlockBuilder(GetNextObjId(), m_CharMapper); tbBuilder.Append("Publisher: "); tbBuilder.Append(m_Book.MetaData.BookInfo.Publisher); FlushTextToBlock(coverPage, tbBuilder, m_CenteredTextAttr); } if (!string.IsNullOrEmpty(m_Book.MetaData.BookInfo.FreeText)) { TextBlockBuilder tbBuilder = new TextBlockBuilder(GetNextObjId(), m_CharMapper); tbBuilder.Append(TagId.EOL); tbBuilder.Append(TagId.EOL); tbBuilder.Append("Notes: "); tbBuilder.Append(m_Book.MetaData.BookInfo.FreeText); FlushTextToBlock(coverPage, tbBuilder, m_MainBodyTextAttr); } addBookPage(coverPage); finalizePage(coverPage); }
/// <summary> /// Create the table of contents page (not to be confused with the TOC object) /// which refers to this page. This page is the one that has the links to the /// other pages within this book. /// </summary> private void createTocPage(PageObject firstPage, TocEntry tocEntries) { // Now create a TOC page PageObject tocPage = createPage(); TextBlockBuilder tbBuilder = new TextBlockBuilder(GetNextObjId(), m_CharMapper); tbBuilder.Append("Table of Contents"); tbBuilder.Append(TagId.EOL); BlockObject headingBlock = FlushTextToBlock(tocPage, tbBuilder, m_CenteredTextAttr); foreach (TocEntry tocEntry in tocEntries.Children) { AddTocEntry(tocEntry, 0, tocPage); } insertBookPage(tocPage, firstPage); finalizePage(tocPage); m_TocObject.AddEntry(tocPage.ID, headingBlock.ID, "Table of Contents"); }
/// <summary> /// Walk the supplied HTML DOM node (recursively) and add its contents into the /// supplied page using the supplied TextBlockBuilder. /// </summary> /// <remarks>When this routine is done there may be some residual text still in /// tbBuilder. The caller is resonsible for checking this and adding it to the /// page if present.</remarks> /// <param name="node">The HTML DOM node to recursively walk.</param> /// <param name="tbBuilder">The TextBlockBuilder to put the text into.</param> private TextBlockBuilder ParseDomNode(IHTMLDOMNode node, TextBlockBuilder tbBuilder) { TagType tagType = GetTagType(node.nodeName); switch (tagType) { case TagType.IMG: // Before we add the image, see if we need to write the text object first if (tbBuilder.HasText) { // Yes it has tbBuilder.Append(TagId.EOL); FlushTextToBlock(m_CurrentPage, tbBuilder, m_MainBodyTextAttr); tbBuilder = new TextBlockBuilder(GetNextObjId(), m_CharMapper); } IHTMLAttributeCollection attribs = (IHTMLAttributeCollection)node.attributes; object name = "src"; string src = ((IHTMLDOMAttribute)attribs.item(ref name)).nodeValue.ToString(); name = "height"; string height = ((IHTMLDOMAttribute)attribs.item(ref name)).nodeValue.ToString(); name = "width"; string width = ((IHTMLDOMAttribute)attribs.item(ref name)).nodeValue.ToString(); addPageImage(m_CurrentPage, src, ushort.Parse(width), ushort.Parse(height)); break; case TagType.text: AppendTextToBlock((string)node.nodeValue, tbBuilder); break; case TagType.I: tbBuilder.Append(TagId.ItalicBegin); break; case TagType.B: tbBuilder.Append(TagId.FontWeight, LegacyBBeB.k_BoldFontWeight); break; case TagType.SUP: tbBuilder.Append(TagId.BeginSup); break; case TagType.SUB: tbBuilder.Append(TagId.BeginSub); break; case TagType.H1: case TagType.H2: case TagType.H3: case TagType.H4: case TagType.H5: case TagType.H6: FlushTextToBlock(m_CurrentPage, tbBuilder, m_MainBodyTextAttr); tbBuilder = new TextBlockBuilder(GetNextObjId(), m_CharMapper); if (GetHeadingLevel(tagType) <= GetHeadingLevel(m_eNewPageHeadingFilter)) { if (m_CurrentPage.Children.Count > 0) // If current page not empty { // Start a new page finalizePage(m_CurrentPage); m_CurrentPage = createPage(); addBookPage(m_CurrentPage); } } m_HeadingNodePageId[node] = m_CurrentPage.ID; m_TextObjectIdHeadingNode[tbBuilder.TextObjectId] = node; tbBuilder.Append(TagId.FontSize, GetHeadingFontSize(tagType)); break; } if (node.hasChildNodes()) { IHTMLDOMChildrenCollection childNodes = (IHTMLDOMChildrenCollection)node.childNodes; foreach (IHTMLDOMNode child in childNodes) { tbBuilder = ParseDomNode(child, tbBuilder); } } switch (tagType) { case TagType.I: tbBuilder.Append(TagId.ItalicEnd); break; case TagType.B: tbBuilder.Append(TagId.FontWeight, LegacyBBeB.k_NormalFontWeight); break; case TagType.SUP: tbBuilder.Append(TagId.EndSup); break; case TagType.SUB: tbBuilder.Append(TagId.EndSub); break; case TagType.P: tbBuilder.Append(TagId.EOL); tbBuilder.Append(TagId.EOL); break; case TagType.H1: case TagType.H2: case TagType.H3: case TagType.H4: case TagType.H5: case TagType.H6: tbBuilder.Append(TagId.FontSize, LegacyBBeB.DefaultFontSize); FlushTextToBlock(m_CurrentPage, tbBuilder, m_MainBodyTextAttr); tbBuilder = new TextBlockBuilder(GetNextObjId(), m_CharMapper); break; case TagType.BR: tbBuilder.Append(TagId.EOL); break; } return(tbBuilder); }