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")); }
protected IEnumerable<TokenBase> ParseText(string text, TokenIndex top) { foreach (string word in text.BreakToWords()) { if (string.IsNullOrEmpty(word)) yield return new WhitespaceToken(top.Index++); else yield return new TextToken(top.Index++, WebUtility.HtmlDecode(word)); } }
private IEnumerable<TokenBase> ParseNodes(XContainer container, Stack<TextVisualProperties> propertiesStack, TokenIndex top, int bookLevel, string pointer, int parentID = -1) { var pointerIndex = 0; foreach (XNode node in container.Nodes()) { pointerIndex++; var text = node as XText; if (!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, pointer + @"/" + pointerIndex); yield return tagOpen; propertiesStack.Push(properties); foreach (TokenBase token in ParseNodes(element, propertiesStack, top, level, pointer+@"/"+pointerIndex, tagOpen.ID)) { yield return token; } propertiesStack.Pop(); yield return new TagCloseToken(top.Index++, parentID); } } }
private void ProcessTitleData(TokenIndex top, XElement xelement, int bookLevel) { var item = new BookChapter { Level = bookLevel, Title = GetText(xelement), TokenID = top.Index }; _chapters.Add(item); }
private void ProcessAnchors(TokenIndex top, XElement xelement) { XAttribute attribute = xelement.Attributes().FirstOrDefault(t => (t.Name.LocalName == "id")); if (attribute != null) { _anchors[attribute.Value] = top.Index; } }