private void AppendToLine(TagOpenToken token)
 {
     if (!token.TextProperties.Inline)
     {
         if (_block != null)
         {
             _block.EndParagraph();
             _firstTokenID = token.ID;
             _output.Enqueue(_block);
         }
         EnterMargin(token.TextProperties);
         _block     = null;
         _textWidth = _textIndent = token.TextProperties.TextIndent;
         _separator = false;
     }
     PushTag(token);
 }
        public IEnumerable <TokenBlockBase> GetLines(BookTokenIterator bookTokens, string lastText, int firstTokenID,
                                                     int stopTokenID = -1, string stopText = null)
        {
            _firstTokenID = firstTokenID;

            _tree        = bookTokens.BuildTree(_firstTokenID);
            _lastOpenTag = _tree.Peek();
            _fontSize    = GetCurrentFontSize();
            _separator   = false;
            bool firstText = true;

            _marginLeft = _marginRight = 0.0;

            foreach (TagOpenToken openTagToken in _tree.Reverse())
            {
                EnterMargin(openTagToken.TextProperties);
            }

            if (string.IsNullOrEmpty(stopText) && stopTokenID > 0)
            {
                --stopTokenID;
            }

            while (bookTokens.MoveNext())
            {
                foreach (TokenBlockBase baseTokenLine in OutputLines(false))
                {
                    yield return(baseTokenLine);
                }

                if (!Append(bookTokens, lastText, stopTokenID, stopText, ref firstText))
                {
                    break;
                }
            }
            foreach (TokenBlockBase baseTokenLine in OutputLines(true))
            {
                yield return(baseTokenLine);
            }
        }
Exemple #3
0
        private IEnumerable <TokenBase> ParseNodes(HtmlNode container, Stack <TextVisualProperties> propertiesStack, TokenIndex top, EpubPath path, int parentID = -1)
        {
            foreach (HtmlNode child in container.ChildNodes)
            {
                var asText = child as HtmlTextNode;
                if (asText != null && !string.IsNullOrEmpty(asText.Text))
                {
                    foreach (TokenBase text in ParseText(asText.Text, top))
                    {
                        yield return(text);
                    }
                }
                else
                {
                    TextVisualProperties properties = propertiesStack.Peek().Clone().Update(child, _css);
                    properties.LinkID = string.Empty;

                    if (child.Name == "a" || child.Name == "span")
                    {
                        ParseAnchors(top, path, child);
                    }

                    if (child.Name == "a")
                    {
                        string href = child.GetAttributeValue("href", string.Empty);
                        if (!string.IsNullOrEmpty(href))
                        {
                            if (href.StartsWith("#"))
                            {
                                properties.LinkID = path.CurrentFilePath + href;
                            }
                            else
                            {
                                properties.LinkID = path + href;
                            }
                        }
                    }
                    if (string.Equals(child.Name, "img"))
                    {
                        HtmlAttributeCollection attributes = child.Attributes;
                        string src          = attributes.Contains("src") ? attributes["src"].Value : string.Empty;
                        var    pictureToken = new PictureToken(top.Index++, (path) + src);
                        yield return(pictureToken);
                    }
                    else
                    {
                        if (child is HtmlCommentNode)
                        {
                            continue;
                        }

                        var tagOpenToken = new TagOpenToken(top.Index++, child, properties, parentID);
                        yield return(tagOpenToken);

                        propertiesStack.Push(properties);
                        foreach (TokenBase token in ParseNodes(child, propertiesStack, top, path, tagOpenToken.ID))
                        {
                            yield return(token);
                        }
                        propertiesStack.Pop();
                        yield return(new TagCloseToken(top.Index++, parentID));
                    }
                }
            }
        }
        private IEnumerable <TokenBase> ParseNodes(XContainer container, Stack <TextVisualProperties> propertiesStack, TokenIndex top, int bookLevel, int parentID = -1)
        {
            foreach (XNode node in container.Nodes())
            {
                var text = node as XText;
                if ((text != null) && !string.IsNullOrEmpty(text.Value))
                {
                    foreach (TokenBase token in ParseText(text.Value, top))
                    {
                        yield return(token);
                    }
                }
                var element = node as XElement;
                if (element == null)
                {
                    continue;
                }

                TextVisualProperties properties = propertiesStack.Peek().Clone().Update(element, _styleSheet);

                string localName = element.Name.LocalName;
                int    level     = bookLevel;

                if (localName == "a")
                {
                    ProcessLinks(properties, element);
                }
                ProcessAnchors(top, element);

                if (localName == "section")
                {
                    yield return(new NewPageToken(top.Index++));

                    level++;
                }

                if (localName == "title")
                {
                    ProcessTitleData(top, element, level);
                }

                if (localName == "image")
                {
                    XAttribute hrefAttr     = element.Attributes().FirstOrDefault(t => (t.Name.LocalName == "href"));
                    string     href         = ((hrefAttr != null) ? hrefAttr.Value : string.Empty).TrimStart('#');
                    var        pictureToken = new PictureToken(top.Index++, href);
                    yield return(pictureToken);
                }
                else
                {
                    var tagOpen = new TagOpenToken(top.Index++, element, properties, parentID);
                    yield return(tagOpen);

                    propertiesStack.Push(properties);
                    foreach (TokenBase token in ParseNodes(element, propertiesStack, top, level, tagOpen.ID))
                    {
                        yield return(token);
                    }
                    propertiesStack.Pop();

                    yield return(new TagCloseToken(top.Index++, parentID));
                }
            }
        }
        private IEnumerable <TokenBase> ParseTokens(HtmlNode container, Stack <TextVisualProperties> propertiesStack, TokenIndex top, int parentID = -1)
        {
            foreach (HtmlNode child in container.ChildNodes)
            {
                var node = child as HtmlTextNode;
                if (node != null)
                {
                    if (!string.IsNullOrEmpty(node.Text))
                    {
                        foreach (TokenBase token in ParseText(node.Text, top))
                        {
                            yield return(token);
                        }
                    }
                }
                else
                {
                    TextVisualProperties properties = propertiesStack.Peek().Clone().Update(child, _css);
                    properties.LinkID = string.Empty;

                    if (child.Name == "a" || child.Name == "span")
                    {
                        ParseAnchors(top, child);
                    }

                    if (child.Name == "a")
                    {
                        string attributeValue = child.GetAttributeValue("href", string.Empty);
                        if (!string.IsNullOrEmpty(attributeValue))
                        {
                            properties.LinkID = attributeValue;
                        }
                    }
                    //TODO: add images support
                    //if (string.Equals(child.Name, imageParser.ImageTag))
                    //{
                    //    int oldTopIndex;
                    //    HtmlAttributeCollection attributes = child.Attributes;
                    //    string imagePath = attributes.Contains("src") ? attributes["src"].Value : string.Empty;
                    //    top.Index = (oldTopIndex = top.Index) + 1;
                    //    var pictureToken = new PictureToken(oldTopIndex)
                    //    {
                    //        ImageID = imagePath
                    //    };
                    //    yield return pictureToken;
                    //}
                    //else
                    {
                        if (child is HtmlCommentNode)
                        {
                            continue;
                        }

                        var tagOpen = new TagOpenToken(top.Index++, child, properties, parentID);
                        yield return(tagOpen);

                        propertiesStack.Push(properties);
                        foreach (TokenBase token in ParseTokens(child, propertiesStack, top, tagOpen.ID))
                        {
                            yield return(token);
                        }
                        propertiesStack.Pop();
                        yield return(new TagCloseToken(top.Index++, parentID));
                    }
                }
            }
        }
 private void PopTag()
 {
     _tree.Pop();
     _lastOpenTag = _tree.Peek();
     _fontSize    = GetCurrentFontSize();
 }
 private void PushTag(TagOpenToken tag)
 {
     _tree.Push(tag);
     _lastOpenTag = tag;
     _fontSize    = GetCurrentFontSize();
 }