private void AppendTextContent(string str) { if (htmlStack.Count > 0) { HtmlOutputToken current = htmlStack.Peek(); if (current.AttributeName != null || current.TagOpened) { Add(new HtmlOutputToken(TokenType.HTMLOP_TEXT) { Text = str }); } } }
private void ParseTextContent(string str) { int start = this.Count; int lastIndex = 0; for (Match m = reHtml.Match(str); m.Success; m = m.NextMatch()) { HtmlOutputToken current = htmlStack.Count > 0 ? htmlStack.Peek() : null; if (lastIndex != m.Index) { AppendTextContent(str.Substring(lastIndex, m.Index - lastIndex)); } lastIndex = m.Index + m.Length; switch (m.Value[0]) { case '<': if (m.Groups[1].Success) { if (current != null) { if (current.TagName == m.Groups[2].Value) { current.TagOpened = false; } else if (VoidTags.Contains(current.TagName)) { htmlStack.Pop(); if (htmlStack.Count > 0) { current = htmlStack.Peek(); } else { AppendTextContent(m.Value); } } } else { AppendTextContent(m.Value); } } else { EndTextContent(); htmlStack.Push(new HtmlOutputToken(TokenType.HTMLOP_ELEMENT_START) { TagName = m.Groups[2].Value }); Add(htmlStack.Peek()); } break; case '>': case '/': if (current != null && current.TagName != null) { if (!current.TagOpened || m.Value == "/>") { EndTextContent(); Add(new HtmlOutputToken(TokenType.HTMLOP_ELEMENT_END)); htmlStack.Pop(); StartTextContent(); } else if (m.Value == ">") { current.TagOpened = true; StartTextContent(); } } else { AppendTextContent(m.Value); } break; case '"': if (current != null && current.AttributeName != null) { EndTextContent(); Add(new HtmlOutputToken(TokenType.HTMLOP_ATTR_END) { AttributeName = current.AttributeName }); htmlStack.Pop(); } else { AppendTextContent(m.Value); } break; default: if (current != null) { if (m.Value.IndexOf('=') < 0) { Add(new HtmlOutputToken(TokenType.HTMLOP_ATTR_END) { AttributeName = m.Groups[3].Value }); } else { htmlStack.Push(new HtmlOutputToken(TokenType.HTMLOP_ATTR_START) { AttributeName = m.Groups[3].Value }); current.Attributes.Add(m.Groups[3].Value, htmlStack.Peek()); Add(htmlStack.Peek()); StartTextContent(); } } else { AppendTextContent(m.Value); } break; } } if (lastIndex != str.Length) { AppendTextContent(str.Substring(lastIndex)); } if (start < this.Count) { HtmlOutputToken p = this[start] as HtmlOutputToken; if (p != null) { p.Value = str; p.Index = this.Count; } } }
private object Evaluate() { StringBuilder sb = new StringBuilder(); try { int i = 0; int e = tokens.Count; while (i < e) { Token t = tokens[i++]; switch (t.Type) { case TokenType.OP_EVAL: EvaluateToken et = (EvaluateToken)t; int prevCount = evalCount; PipeValue result = et.Expression.Evaluate(this); if (result.IsEvallable) { string str = result.Type == PipeValueType.Object ? JsonConvert.SerializeObject(result) : result.ToString(); if (evalCount != prevCount || et.SuppressHtmlEncode) { sb.Append(str); } else { sb.Append(HttpUtility.HtmlEncode(str)); } } break; case TokenType.OP_ITER: IterationToken it = (IterationToken)t; IEnumerator iterable = it.Expression.Evaluate(this).GetEnumerator(); PushObjectStack(iterable); if (!iterable.MoveNext()) { i = it.Index; } break; case TokenType.OP_ITER_END: IterationEndToken iet = (IterationEndToken)t; if (!((IEnumerator)objStack.Peek().Value).MoveNext()) { PopObjectStack(); } else { i = iet.Index; } break; case TokenType.OP_TEST: ConditionToken ct = (ConditionToken)t; if (!(bool)ct.Expression.Evaluate(this) ^ ct.Negate) { i = ct.Index; } break; case TokenType.OP_JUMP: i = ((BranchToken)t).Index; break; default: OutputToken ot = (OutputToken)t; if (this.Options.OutputXml) { XmlElement currentElm = xmlStack.Peek(); HtmlOutputToken ht = (HtmlOutputToken)ot; switch (t.Type) { case TokenType.HTMLOP_ELEMENT_START: FlushOutput(sb, currentElm); xmlStack.Push(currentElm.OwnerDocument.CreateElement(ht.TagName)); currentElm.AppendChild(xmlStack.Peek()); break; case TokenType.HTMLOP_ELEMENT_END: FlushOutput(sb, currentElm); xmlStack.Pop(); break; case TokenType.HTMLOP_ATTR_END: XmlAttribute attr = currentElm.OwnerDocument.CreateAttribute(ht.AttributeName); attr.Value = sb.ToString(); currentElm.Attributes.Append(attr); sb.Clear(); break; case TokenType.HTMLOP_TEXT: sb.Append(ht.Text); break; } } else { sb.Append(ot.Value); i = ot.Index; } break; } } } finally { evalCount = (evalCount + 1) & 0xFFFF; } if (this.Options.OutputXml) { FlushOutput(sb, xmlStack.Peek()); return(xmlStack.Peek()); } return(Regex.Replace(sb.ToString(), @"^\s+(?=<)|(>)\s+(<|$)", m => m.Groups[1].Value + m.Groups[2].Value)); }