Пример #1
0
        private void ExecuteCustomTag(TagNode tag)
        {
            ITagHandler tagHandler = customTags[tag.TagName];

            bool processInnerElements = tagHandler.TagEnter(this);

            foreach (TagNodeAttribute attribute in tag.Attributes) {
                if (!tagHandler.TagAttribute(attribute.Name, EvaluateExpression(attribute.Value)))
                    throw new TemplateException(String.Format("{0} missing required attribute: {1}", tag.TagName, attribute.Name), tag.Line, tag.Column);
            }

            if (processInnerElements) {
                TextWriter saveWriter = writer;
                writer = new StringWriter();

                string innerContent ;

                try {
                    ProcessNodes(tag.ChildNodes);
                    innerContent = writer.ToString();
                } finally {
                    writer = saveWriter;
                }

                tagHandler.TagContent(innerContent);
            }

            tagHandler.TagExit(this);
        }
Пример #2
0
        private TagNode CollectForTag(TagNode tag, ref int index)
        {
            if (tag.Closed) // if self-closing tag, do not collect inner elements
                return tag;

            if (String.Compare(tag.TagName, "if", true) == 0) {
                tag = new IfTag(tag.Line, tag.Column, tag.GetAttributeValue("test"));
            }

            TagNode collectTag = tag;

            for (index++; index < nodes.Count; index++) {
                Node node = nodes[index];

                if (node is TextNode)
                    collectTag.ChildNodes.Add(node);
                else if (node is Expression)
                    collectTag.ChildNodes.Add(node);
                else if (node is TagNode) {
                    TagNode innerTag = (TagNode)node;
                    if (string.Compare(innerTag.TagName, "else", true) == 0) {
                        if (collectTag is IfTag) {
                            ((IfTag)collectTag).FalseBranch = innerTag;
                            collectTag = innerTag;
                        } else
                            throw new ParseException("else tag has to be positioned inside of if or elseif tag", innerTag.Line, innerTag.Column);

                    } else if (string.Compare(innerTag.TagName, "elif", true) == 0) {
                        if (collectTag is IfTag) {
                            TagNode newTag = new IfTag(innerTag.Line, innerTag.Column, innerTag.GetAttributeValue("test"));
                            ((IfTag)collectTag).FalseBranch = newTag;
                            collectTag = newTag;
                        } else
                            throw new ParseException("elseif tag is not positioned properly", innerTag.Line, innerTag.Column);
                    } else
                        collectTag.ChildNodes.Add(CollectForTag(innerTag, ref index));
                } else if (node is TagEnd) {
                    TagEnd tagClose = (TagEnd)node;
                    if (string.Compare(tag.TagName, tagClose.TagName, true) == 0)
                        return tag;

                    throw new ParseException("Close tag for " + tagClose.TagName + " doesn't have matching start tag.", node.Line, node.Column);
                } else
                    throw new ParseException("Invalid node: " + node.GetType(), node.Line, node.Column);

            }

            throw new ParseException("Start tag: " + tag.TagName + " does not have matching end tag.", tag.Line, tag.Column);
        }
Пример #3
0
        private TagNode ReadTag()
        {
            Consume(TokenKind.TagStart);
            Token name = Consume(TokenKind.ID);
            TagNode tag = new TagNode(name.Line, name.Column, name.Text);

            while (true) {
                if (Current.Kind == TokenKind.ID)
                    tag.Attributes.Add(ReadAttribute());
                else if (Current.Kind == TokenKind.TagEnd) {
                    Consume();
                    break;
                } else if (Current.Kind == TokenKind.TagEndClose) {
                    Consume();
                    tag.Closed = true;
                    break;
                } else
                    throw new ParseException("Invalid token in tag: " + Current.Kind, Current.Line, Current.Column);

            }

            return tag;
        }
Пример #4
0
        private void ProcessTemplate(string name, TagNode tag)
        {
            if (customTags != null && customTags.ContainsKey(name)) {
                ExecuteCustomTag(tag);
                return;
            }

            Template useTemplate = currentTemplate.FindTemplate(name);
            if (useTemplate == null)
                throw new TemplateException(String.Format("Template '{0}' not found", name), tag.Line, tag.Column);

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

            try {
                ProcessNodes(tag.ChildNodes);

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

            Template saveTemplate = currentTemplate;
            variableScope = new VariableScope(variableScope);
            variableScope["innerText"] = content;

            try {
                foreach (TagNodeAttribute attrib in tag.Attributes) {
                    object val = EvaluateExpression(attrib.Value);
                    variableScope[attrib.Name] = val;
                }

                currentTemplate = useTemplate;
                ProcessNodes(currentTemplate.Nodes);
            } finally {
                variableScope = variableScope.Parent;
                currentTemplate = saveTemplate;
            }
        }
Пример #5
0
        private void ProcessTagSet(TagNode tag)
        {
            Expression expName = tag.GetAttributeValue("name");
            if (expName == null)
                throw new TemplateException("Set is missing required attribute: name", tag.Line, tag.Column);

            Expression expValue = tag.GetAttributeValue("value");
            if (expValue == null)
                throw new TemplateException("Set is missing required attribute: value", tag.Line, tag.Column);

            string name = EvaluateExpression(expName).ToString();
            if (!Util.IsValidVariableName(name))
                throw new TemplateException("'" + name + "' is not valid variable name.", expName.Line, expName.Column);

            object value = EvaluateExpression(expValue);

            SetValue(name, value);
        }
Пример #6
0
 private void ProcessTag(TagNode tag)
 {
     string name = tag.TagName.ToLowerInvariant();
     try {
         switch (name) {
             case "template":
                 // skip those, because those are processed first
                 break;
             case "else":
                 ProcessNodes(tag.ChildNodes);
                 break;
             case "apply":
                 object val = EvaluateExpression(tag.GetAttributeValue("template"));
                 ProcessTemplate(val.ToString(), tag);
                 break;
             case "foreach":
                 ProcessForEach(tag);
                 break;
             case "for":
                 ProcessFor(tag);
                 break;
             case "set":
                 ProcessTagSet(tag);
                 break;
             default:
                 ProcessTemplate(tag.TagName, tag);
                 break;
         }
     } catch (TemplateException ex) {
         OnError(ex);
     } catch (Exception ex) {
         OnError("Error executing tag '" + name + "': " + ex.Message, tag.Line, tag.Column);
     }
 }
Пример #7
0
        private void ProcessForEach(TagNode tag)
        {
            Expression expCollection = tag.GetAttributeValue("collection");
            if (expCollection == null)
                throw new TemplateException("Foreach is missing required attribute: collection", tag.Line, tag.Column);

            object collection = EvaluateExpression(expCollection);
            if (!(collection is IEnumerable))
                throw new TemplateException("Collection used in foreach has to be enumerable", tag.Line, tag.Column);

            Expression expVar = tag.GetAttributeValue("var");
            if (expCollection == null)
                throw new TemplateException("Foreach is missing required attribute: var", tag.Line, tag.Column);

            object varObject = EvaluateExpression(expVar);
            if (varObject == null)
                varObject = "foreach";
            string varname = varObject.ToString();

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

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

                ProcessNodes(tag.ChildNodes);
            }
        }
Пример #8
0
        private void ProcessFor(TagNode tag)
        {
            Expression expFrom = tag.GetAttributeValue("from");
            if (expFrom == null)
                throw new TemplateException("For is missing required attribute: from", tag.Line, tag.Column);

            Expression expTo = tag.GetAttributeValue("to");
            if (expTo == null)
                throw new TemplateException("For is missing required attribute: to", tag.Line, tag.Column);

            Expression expIndex = tag.GetAttributeValue("index");
            if (expIndex == null)
                throw new TemplateException("For is missing required attribute: index", tag.Line, tag.Column);

            object obj = EvaluateExpression(expIndex);
            string indexName = obj.ToString();

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

            for (int index = start; index < end; index++) {
                SetValue(indexName, index);
                //variables[indexName] = index;

                ProcessNodes(tag.ChildNodes);
            }
        }