예제 #1
0
        /// <summary>
        /// 收集子标签。
        /// </summary>
        /// <param name="tag">指定一个标签实例。</param>
        /// <param name="index">指定标签索引。</param>
        /// <returns>Tag</returns>
        private Tag CollectForTag(Tag tag, ref int index)
        {
            if (tag.IsClosed) return tag;
            if (string.Compare(tag.Name, "if", true) == 0) tag = new TagIf(tag.Line, tag.Col, tag.AttributeValue("test"));

            Tag collectTag = tag;

            for (index++; index < _Elements.Count; index++)
            {
                Element elem = _Elements[index];

                if (elem is Text)
                    collectTag.InnerElements.Add(elem);
                else if (elem is Expression)
                    collectTag.InnerElements.Add(elem);
                else if (elem is Tag)
                {
                    Tag innerTag = (Tag)elem;
                    if (string.Compare(innerTag.Name, "else", true) == 0)
                    {
                        if (collectTag is TagIf)
                        {
                            ((TagIf)collectTag).FalseBranch = innerTag;
                            collectTag = innerTag;
                        }
                        else
                            throw new ParseException("else 标签必须包含在 if 或 elseif 之内。", innerTag.Line, innerTag.Col);

                    }
                    else if (string.Compare(innerTag.Name, "elseif", true) == 0)
                    {
                        if (collectTag is TagIf)
                        {
                            Tag newTag = new TagIf(innerTag.Line, innerTag.Col, innerTag.AttributeValue("test"));
                            ((TagIf)collectTag).FalseBranch = newTag;
                            collectTag = newTag;
                        }
                        else
                            throw new ParseException("elseif 标签位置不正确。", innerTag.Line, innerTag.Col);
                    }
                    else
                        collectTag.InnerElements.Add(CollectForTag(innerTag, ref index));
                }
                else if (elem is TagClose)
                {
                    TagClose tagClose = (TagClose)elem;
                    if (string.Compare(tag.Name, tagClose.Name, true) == 0)
                        return tag;

                    throw new ParseException("没有为闭合标签 " + tagClose.Name + " 找到合适的开始标签。", elem.Line, elem.Col);
                }
                else
                    throw new ParseException("无效标签: " + elem.GetType().ToString(), elem.Line, elem.Col);
            }

            throw new ParseException("没有为开始标签 " + tag.Name + " 找到合适的闭合标签。", tag.Line, tag.Col);
        }
예제 #2
0
        /// <summary>
        /// 处理 Set 标签。
        /// </summary>
        /// <param name="tag">包含 set 方法的标签实例。</param>
        protected void ProcessTagSet(Tag tag)
        {
            Expression expName = tag.AttributeValue("name");
            if (expName == null) throw new TemplateRuntimeException("Set 找不到必须的属性:name", tag.Line, tag.Col);

            Expression expValue = tag.AttributeValue("value");
            if (expValue == null) throw new TemplateRuntimeException("Set 找不到必须的属性:value", tag.Line, tag.Col);

            string name = this.EvalExpression(expName).ToString();
            if (!Smart.Framework.Utility.Converter.IsValidVariableName(name))
                throw new TemplateRuntimeException("指定了非法的标签名:'" + name + "'", expName.Line, expName.Col);

            object value = this.EvalExpression(expValue);

            this.SetValue(name, value);
        }
예제 #3
0
        /// <summary>
        /// 处理模板。
        /// </summary>
        /// <param name="name">指定模板名。</param>
        /// <param name="tag">指定一个标签实例。</param>
        protected void ProcessTemplate(string name, Tag tag)
        {
            if (_CustomTags != null && _CustomTags.ContainsKey(name))
            {
                ExecuteCustomTag(tag);
                return;
            }

            Template useTemplate = _CurrentTemplate.FindTemplate(name);
            if (useTemplate == null)
            {
                string msg = string.Format("模板未找到:'{0}'", name);
                throw new TemplateRuntimeException(msg, tag.Line, tag.Col);
            }

            // process inner elements and save content
            TextWriter saveWriter = _Writer;
            _Writer = new StringWriter();
            string content = string.Empty;

            try
            {
                this.ProcessElements(tag.InnerElements);

                content = _Writer.ToString();
            }
            finally
            {
                _Writer = saveWriter;
            }

            Template saveTemplate = _CurrentTemplate;
            _Variables = new VariableScope(_Variables);
            _Variables["innerText"] = content;

            try
            {
                foreach (TagAttribute attrib in tag.Attributes)
                {
                    object val = this.EvalExpression(attrib.Expression);
                    _Variables[attrib.Name] = val;
                }

                _CurrentTemplate = useTemplate;
                this.ProcessElements(_CurrentTemplate.Elements);
            }
            finally
            {
                _Variables = _Variables.Parent;
                _CurrentTemplate = saveTemplate;
            }
        }
예제 #4
0
 /// <summary>
 /// 处理标签。
 /// </summary>
 /// <param name="tag">指定一个标签实例。</param>
 protected void ProcessTag(Tag tag)
 {
     string name = tag.Name.ToLowerInvariant();
     try
     {
         switch (name)
         {
             case "template":
                 break;
             case "else":
                 this.ProcessElements(tag.InnerElements);
                 break;
             case "apply":
                 object val = this.EvalExpression(tag.AttributeValue("template"));
                 this.ProcessTemplate(val.ToString(), tag);
                 break;
             case "foreach":
                 this.ProcessForEach(tag);
                 break;
             case "for":
                 this.ProcessFor(tag);
                 break;
             case "set":
                 this.ProcessTagSet(tag);
                 break;
             default:
                 this.ProcessTemplate(tag.Name, tag);
                 break;
         }
     }
     catch (TemplateRuntimeException ex)
     {
         this.DisplayError(ex);
     }
     catch (Exception ex)
     {
         this.DisplayError("处理标记时出错:'" + name + "': " + ex.Message, tag.Line, tag.Col);
     }
 }
예제 #5
0
        /// <summary>
        /// 处理 foreach 标签。
        /// </summary>
        /// <param name="tag">包含 foreach 语句的标签实例。</param>
        protected void ProcessForEach(Tag tag)
        {
            Expression expCollection = tag.AttributeValue("collection");
            if (expCollection == null) throw new TemplateRuntimeException("Foreach 找不到必须的属性:collection", tag.Line, tag.Col);

            object collection = this.EvalExpression(expCollection);
            if (!(collection is IEnumerable)) throw new TemplateRuntimeException("foreach 的 Collection 必须可以转换为 enumerable", tag.Line, tag.Col);

            Expression expVar = tag.AttributeValue("var");
            if (expCollection == null) throw new TemplateRuntimeException("Foreach 找不到必须的属性:var", tag.Line, tag.Col);

            object varObject = this.EvalExpression(expVar);
            if (varObject == null) varObject = "foreach";

            string varname = varObject.ToString();

            Expression expIndex = tag.AttributeValue("index");
            string indexname = null;
            if (expIndex != null)
            {
                object obj = this.EvalExpression(expIndex);
                if (obj != null)
                    indexname = obj.ToString();
            }

            IEnumerator ienum = ((IEnumerable)collection).GetEnumerator();
            int index = 0;
            while (ienum.MoveNext())
            {
                index++;
                object value = ienum.Current;
                _Variables[varname] = value;
                if (indexname != null)
                    _Variables[indexname] = index;

                this.ProcessElements(tag.InnerElements);
            }
        }
예제 #6
0
        /// <summary>
        /// 处理 for 标签。
        /// </summary>
        /// <param name="tag">包含 for 语句的标签实例。</param>
        protected void ProcessFor(Tag tag)
        {
            Expression expFrom = tag.AttributeValue("from");
            if (expFrom == null) throw new TemplateRuntimeException("For 找不到必须的属性:from", tag.Line, tag.Col);

            Expression expTo = tag.AttributeValue("to");
            if (expTo == null) throw new TemplateRuntimeException("For 找不到必须的属性:to", tag.Line, tag.Col);

            Expression expIndex = tag.AttributeValue("index");
            if (expIndex == null) throw new TemplateRuntimeException("For 找不到必须的属性:index", tag.Line, tag.Col);

            object obj = this.EvalExpression(expIndex);
            string indexName = obj.ToString();

            int start = Convert.ToInt32(this.EvalExpression(expFrom));
            int end = Convert.ToInt32(this.EvalExpression(expTo));

            for (int index = start; index <= end; index++)
            {
                SetValue(indexName, index);
                this.ProcessElements(tag.InnerElements);
            }
        }
예제 #7
0
        /// <summary>
        /// 处理自定义标签。
        /// </summary>
        /// <param name="tag">指定一个自定义标签实例。</param>
        protected void ExecuteCustomTag(Tag tag)
        {
            ITagHandler tagHandler = _CustomTags[tag.Name];

            bool processInnerElements = true;
            bool captureInnerContent = false;

            tagHandler.TagBeginProcess(this, tag, ref processInnerElements, ref captureInnerContent);

            string innerContent = null;

            if (processInnerElements)
            {
                TextWriter saveWriter = _Writer;

                if (captureInnerContent)
                    _Writer = new StringWriter();

                try
                {
                    this.ProcessElements(tag.InnerElements);

                    innerContent = _Writer.ToString();
                }
                finally
                {
                    _Writer = saveWriter;
                }
            }

            tagHandler.TagEndProcess(this, tag, innerContent);
        }
예제 #8
0
        private Tag _ReadTag()
        {
            _Consume(TokenKind.TagStart);
            Token name = _Consume(TokenKind.id);
            Tag tag = new Tag(name.Line, name.Col, name.Data);

            while (true)
            {
                if (Current.TokenKind == TokenKind.id)
                    tag.Attributes.Add(_ReadAttribute());
                else if (Current.TokenKind == TokenKind.TagEnd)
                {
                    _Consume();
                    break;
                }
                else if (Current.TokenKind == TokenKind.TagEndClose)
                {
                    _Consume();
                    tag.IsClosed = true;
                    break;
                }
                else
                    throw new ParseException("无效的 Token 标记:" + Current.TokenKind, Current.Line, Current.Col);

            }

            return tag;
        }