Example #1
0
 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
             });
         }
     }
 }
Example #2
0
        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));
        }