private void ProcessTmpl(string name, Tag tag) { if (customTags != null && customTags.ContainsKey(name)) { ExecuteCustomTag(tag); return; } Tmpl useTmpl = _currentTmpl.FindTmpl(name); if (useTmpl == null) { string msg = string.Format("Tmpl '{0}' not found", name); throw new TmplException(msg, tag.Line, tag.Col); } TextWriter saveWriter = writer; writer = new StringWriter(); string content = string.Empty; try { ProcessElements(tag.InnerTokens); content = writer.ToString(); } finally { writer = saveWriter; } Tmpl saveTmpl = _currentTmpl; _variables = new Variable(_variables); _variables["innerText"] = content; try { foreach (DotAttribute attrib in tag.Attributes) { object val = EvalExpression(attrib.Expression); _variables[attrib.Name] = val; } _currentTmpl = useTmpl; ProcessElements(_currentTmpl.Elements); } finally { _variables = _variables.Parent; _currentTmpl = saveTmpl; } }
private void ProcessForeach(Tag tag) { Expression expCollection = tag.AttributeValue("list"); if (expCollection == null) { throw new TmplException("Foreach is missing required attribute: collection", tag.Line, tag.Col); } object collection = EvalExpression(expCollection); if (!(collection is IEnumerable)) { throw new TmplException("Collection used in foreach has to be enumerable", tag.Line, tag.Col); } Expression expVar = tag.AttributeValue("var"); if (expCollection == null) { throw new TmplException("Foreach is missing required attribute: var", tag.Line, tag.Col); } object varObject = EvalExpression(expVar); if (varObject == null) { varObject = "foreach"; } string varname = varObject.ToString(); Expression expIndex = tag.AttributeValue("index"); string indexname = null; if (expIndex != null) { object obj = 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; } ProcessElements(tag.InnerTokens); } }
private void ProcessTag(Tag tag) { string name = tag.Name.ToLowerInvariant(); try { switch (name) { case "define": break; case "else": ProcessElements(tag.InnerTokens); break; case "using": object val = EvalExpression(tag.AttributeValue("tmpl")); ProcessTmpl(val.ToString(), tag); break; case "foreach": ProcessForeach(tag); break; case "for": ProcessFor(tag); break; default: ProcessTmpl(tag.Name, tag); break; } } catch (TmplException ex) { DisplayError(ex); } catch (Exception ex) { DisplayError("Error executing tag '" + name + "': " + ex.Message, tag.Line, tag.Col); } }
private void ProcessFor(Tag tag) { Expression expFrom = tag.AttributeValue("from"); if (expFrom == null) { throw new TmplException("For is missing required attribute: start", tag.Line, tag.Col); } Expression expTo = tag.AttributeValue("to"); if (expTo == null) { throw new TmplException("For is missing required attribute: to", tag.Line, tag.Col); } Expression expIndex = tag.AttributeValue("index"); if (expIndex == null) { throw new TmplException("For is missing required attribute: index", tag.Line, tag.Col); } object obj = EvalExpression(expIndex); string indexName = obj.ToString(); int start = Convert.ToInt32(EvalExpression(expFrom)); int end = Convert.ToInt32(EvalExpression(expTo)); for (int index = start; index <= end; index++) { SetValue(indexName, index); ProcessElements(tag.InnerTokens); } }
private void ExecuteCustomTag(Tag tag) { ITmplHandler tagHandler = customTags[tag.Name]; bool processInnerTokens = true; bool captureInnerContent = false; tagHandler.BeforeProcess(this, tag, ref processInnerTokens, ref captureInnerContent); string innerContent = null; if (processInnerTokens) { TextWriter saveWriter = writer; if (captureInnerContent) { writer = new StringWriter(); } try { ProcessElements(tag.InnerTokens); innerContent = writer.ToString(); } finally { writer = saveWriter; } } tagHandler.AfterProcess(this, tag, innerContent); }
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 TmplException("Invalid token in tag: " + Current.TokenKind + " " + Current.Line + "," + Current.Col, Current.Line, Current.Col); } } return tag; }
private Tag CollectForTag(Tag tag, ref int index) { if (tag.IsClosed) { return tag; } if (string.Compare(tag.Name, "if", true) == 0) { tag = new IfStatement(tag.Line, tag.Col, tag.AttributeValue("test")); } Tag collectTag = tag; for (index++; index < elements.Count; index++) { Token elem = elements[index]; if (elem is Text) { collectTag.InnerTokens.Add(elem); } else if (elem is Expression) { collectTag.InnerTokens.Add(elem); } else if (elem is Tag) { Tag innerTag = (Tag) elem; if (string.Compare(innerTag.Name, "else", true) == 0) { if (collectTag is IfStatement) { ((IfStatement) collectTag).FalseBranch = innerTag; collectTag = innerTag; } else { throw new TmplException("else tag has to be positioned inside of if or elseif tag " + innerTag.Line + "," + innerTag.Col, innerTag.Line, innerTag.Col); } } else if (string.Compare(innerTag.Name, "elseif", true) == 0) { if (collectTag is IfStatement) { Tag newTag = new IfStatement(innerTag.Line, innerTag.Col, innerTag.AttributeValue("test")); ((IfStatement) collectTag).FalseBranch = newTag; collectTag = newTag; } else { throw new TmplException("elseif tag is not positioned properly" + innerTag.Line + "," + innerTag.Col, innerTag.Line, innerTag.Col); } } else { collectTag.InnerTokens.Add(CollectForTag(innerTag, ref index)); } } else if (elem is StatementClose) { StatementClose tagClose = (StatementClose) elem; return tag; } else { throw new TmplException("Invalid element: [" + elem.GetType().ToString() + "] " + elem.Line + "," + elem.Col, elem.Line, elem.Col); } } throw new TmplException("Start tag: [" + tag.Name + "] does not have matching end tag." + tag.Line + "," + tag.Col, tag.Line, tag.Col); }
private void visitTag(Tag tag) { WriteLine("Tag: " + tag.Name); AddAttribs(tag.Attributes); foreach (Token elem in tag.InnerTokens) { visitElement(elem); } }