예제 #1
0
        public override IEnumerable <TokenBase> GetTokens()
        {
            var    top = new TokenIndex();
            string line;

            while ((line = _reader.ReadLine()) != null)
            {
                if (string.IsNullOrEmpty(line))
                {
                    continue;
                }

                var p        = new XElement("p");
                var property = new TextVisualProperties
                {
                    TextIndent = 32.0,
                    Inline     = false
                };

                yield return(new TagOpenToken(top.Index++, p, property, -1));

                foreach (TokenBase baseToken in ParseText(line, top))
                {
                    yield return(baseToken);
                }

                yield return(new TagCloseToken(top.Index++, -1));
            }
        }
예제 #2
0
 public TagOpenToken(int id, HtmlNode node, TextVisualProperties properties, int parentID)
     : base(id)
 {
     Name           = node.Name;
     TextProperties = properties;
     ParentID       = parentID;
 }
예제 #3
0
        public override IEnumerable <TokenBase> GetTokens()
        {
            _css = new CSS();

            var html = new HtmlDocument
            {
                OptionOutputAsXml  = true,
                OptionReadEncoding = false
            };

            html.Load(_reader);
            var root = html.DocumentNode.SelectSingleNode("//body");

            var cssNode = html.DocumentNode.SelectSingleNode("//style");

            if (cssNode != null)
            {
                _css.Analyze(cssNode.InnerText);
            }

            var stack = new Stack <TextVisualProperties>();
            var item  = new TextVisualProperties();

            stack.Push(item);

            return(ParseTokens(root, stack, new TokenIndex()));
        }
예제 #4
0
 public TagOpenToken(int id, XElement element, TextVisualProperties properties, int parentID)
     : base(id)
 {
     Name           = element.Name.LocalName;
     TextProperties = properties;
     ParentID       = parentID;
 }
예제 #5
0
 private TagOpenToken(int id, string name, TextVisualProperties properties, int parentId)
     : base(id)
 {
     Name           = name;
     TextProperties = properties;
     ParentID       = parentId;
 }
예제 #6
0
        private void AppendToLine(TextToken token, double textWidth)
        {
            string text = token.Text;

            if (string.IsNullOrEmpty(text))
            {
                return;
            }

            _block = _block ?? new TextTokenBlock
            {
                TextAlign    = _lastOpenTag.TextProperties.TextAlign,
                MarginLeft   = _marginLeft,
                MarginRight  = _marginRight,
                FirstTokenID = _firstTokenID,
                TextIndent   = _textIndent
            };

            _block.LastTokenID = token.ID;
            _block.UpdateHeight(GetTextHeight(text));
            if (_separator)
            {
                TextVisualProperties properties = _lastOpenTag.TextProperties.Clone();
                var inlineItem = _block.Inlines.OfType <TextElement>().LastOrDefault();
                if (inlineItem != null && string.IsNullOrEmpty(inlineItem.LinkID))
                {
                    properties.LinkID = string.Empty;
                }
                _block.AddText(" ", properties, _fontSize, GetTextSize(" ", properties));
            }
            _block.AddText(text, _lastOpenTag.TextProperties, _fontSize, GetTextSize(text, _lastOpenTag.TextProperties), token.Part, token.ID);
            _textWidth += textWidth;
        }
예제 #7
0
 public override IEnumerable<TokenBase> GetTokens()
 {
     var propertiesStack = new Stack<TextVisualProperties>();
     var item = new TextVisualProperties();
     propertiesStack.Push(item);
     var top = new TokenIndex();
     return _root.Elements(_ns + "body").SelectMany(b => ParseNodes(b, propertiesStack, top, 0, "2"));
 }
예제 #8
0
        public static TokenBase Load(BinaryReader reader, int id)
        {
            var name     = reader.ReadString();
            int parentID = reader.ReadInt32();
            TextVisualProperties properties = TextVisualProperties.Load(reader);

            return(new TagOpenToken(id, name, properties, parentID));
        }
예제 #9
0
        public override IEnumerable <TokenBase> GetTokens()
        {
            var propertiesStack = new Stack <TextVisualProperties>();
            var item            = new TextVisualProperties();

            propertiesStack.Push(item);
            var top = new TokenIndex();

            return(_root.Elements(_ns + "body").SelectMany(b => ParseNodes(b, propertiesStack, top, 0)));
        }
예제 #10
0
        private double GetTextWidth(string text, bool separator, TextVisualProperties properties)
        {
            if (separator)
            {
                text = " " + text;
            }
            double size  = _fontSize * (properties.SubOption || properties.SupOption ? 0.5 : 1.0);
            var    width = GetTextWidth(text, properties, size);

            return(width);
        }
예제 #11
0
        private static void ProcessLinks(TextVisualProperties properties, XElement xelement)
        {
            properties.LinkID = string.Empty;
            XAttribute attribute = xelement.Attributes().FirstOrDefault(t => (t.Name.LocalName == "href"));
            string     str       = ((attribute != null) ? attribute.Value : string.Empty).TrimStart('#');

            if (!string.IsNullOrEmpty(str))
            {
                properties.LinkID = str;
            }
        }
예제 #12
0
 public void AddText(string text, TextVisualProperties properties, double fontSize, Size size, string part = null, int tokenID = -1)
 {
     part = part ?? string.Empty;
     Inlines.Add(new TextElement
     {
         Text      = text,
         Width     = size.Width,
         Height    = size.Height,
         Bold      = properties.Bold,
         Italic    = properties.Italic,
         Size      = fontSize,
         SupOption = properties.SupOption,
         SubOption = properties.SubOption,
         Part      = part,
         LinkID    = properties.LinkID,
         TokenID   = tokenID
     });
 }
예제 #13
0
        public override IEnumerable <TokenBase> GetTokens()
        {
            var propertiesStack = new Stack <TextVisualProperties>();
            var item            = new TextVisualProperties();

            propertiesStack.Push(item);
            var top = new TokenIndex();

            foreach (EpubSpineItem spineItem in GetSpineItems())
            {
                yield return(new NewPageToken(top.Index++));

                AddAnchor(top, (_opfPath) + spineItem.Path);
                foreach (TokenBase token in ParseSpineItem(spineItem, propertiesStack, top))
                {
                    yield return(token);
                }
            }
        }
예제 #14
0
 private double GetTextWidth(string text, TextVisualProperties properties, double size)
 {
     return(text.Aggregate(0.0, (s, c) => s + _helper.GetSize(c, size, properties.Bold, properties.Italic).Width));
 }
예제 #15
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));
                    }
                }
            }
        }
예제 #16
0
 private void LeaveMargin(TextVisualProperties properties)
 {
     _marginLeft  -= properties.MarginLeft;
     _marginRight -= properties.MarginRight;
 }
예제 #17
0
 private void EnterMargin(TextVisualProperties properties)
 {
     _marginLeft  += properties.MarginLeft;
     _marginRight += properties.MarginRight;
 }
예제 #18
0
 private static void ProcessLinks(TextVisualProperties properties, XElement xelement)
 {
     properties.LinkID = string.Empty;
     XAttribute attribute = xelement.Attributes().FirstOrDefault(t => (t.Name.LocalName == "href"));
     string str = ((attribute != null) ? attribute.Value : string.Empty).TrimStart('#');
     if (!string.IsNullOrEmpty(str))
     {
         properties.LinkID = str;
     }
 }
예제 #19
0
        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));
                    }
                }
            }
        }
예제 #20
0
        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));
                }
            }
        }
예제 #21
0
 public void ApplyProperties(string[] selectors, TextVisualProperties properties)
 {
     foreach (CssRule rule in Rules.Where(r => r.Selectors.Any(selectors.Contains)))
     {
         string val;
         if (rule.TryGetValueForRule("font-weight", out val))
         {
             properties.Bold = val == "bold";
         }
         if (rule.TryGetValueForRule("font-style", out val))
         {
             properties.Italic = val == "italic";
         }
         if (rule.TryGetValueForRule("display", out val))
         {
             properties.Inline = val == "inline";
         }
         if (rule.TryGetValueForRule("vertical-align", out val))
         {
             properties.SupOption = val == "super";
         }
         if (rule.TryGetValueForRule("vertical-align", out val))
         {
             properties.SubOption = val == "sub";
         }
         if (rule.TryGetValueForRule("font-size", out val))
         {
             double size;
             FontSizeType type;
             if (TryParseFontSize(val, out size, out type))
             {
                 properties.FontSize = size;
                 properties.FontSizeType = type;
             }
         }
         if (rule.TryGetValueForRule("text-align", out val) && (val != "inherit"))
         {
             properties.TextAlign = val;
         }
         if (rule.TryGetValueForRule("margin", out val))
         {
             double left;
             double right;
             double bottom;
             ParseMargin(val, out left, out right, out bottom);
             properties.MarginLeft = left;
             properties.MarginRight = right;
             properties.MarginBottom = bottom;
         }
         if (rule.TryGetValueForRule("margin-left", out val))
         {
             properties.MarginLeft = ParseMarginValue(val);
         }
         if (rule.TryGetValueForRule("margin-right", out val))
         {
             properties.MarginRight = ParseMarginValue(val);
         }
         if (rule.TryGetValueForRule("margin-bottom", out val))
         {
             properties.MarginBottom = ParseMarginValue(val);
         }
         if (rule.TryGetValueForRule("text-indent", out val))
         {
             properties.TextIndent = ParseMarginValue(val);
         }
     }
 }
예제 #22
0
 private Size GetTextSize(string text, TextVisualProperties properties)
 {
     return(new Size(
                GetTextWidth(text, false, properties),
                GetTextHeight(text, properties.Bold, properties.Italic)));
 }