Пример #1
0
		private Tag CollectForTag(Tag tag, ref int index)
		{
			if (tag.IsClosed) // if self-closing tag, do not collect inner elements
			{
				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 tag has to be positioned inside of if or elseif tag", 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 tag is not positioned properly", 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("Close tag for " + tagClose.Name + " doesn't have matching start tag.", elem.Line, elem.Col);
				}
				else
					throw new ParseException("Invalid element: " + elem.GetType().ToString(), elem.Line, elem.Col);

			}

			throw new ParseException("Start tag: " + tag.Name + " does not have matching end tag.", tag.Line, tag.Col);

		}
Пример #2
0
		protected void ProcessTemplate(string name, Tag tag)
		{
			Template useTemplate = currentTemplate.FindTemplate(name);
			if (useTemplate == null)
			{
				string msg = string.Format("Template '{0}' not found", name);
				WriteError(msg, tag.Line, tag.Col);
				return;
			}

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

			try
			{
				ProcessElements(tag.InnerElements);

				content = writer.ToString();
			}
			catch
			{
				return; // on error, do not do tag inclusion
			}
			finally
			{
				writer = saveWriter;
			}

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

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

				currentTemplate = useTemplate;
				ProcessElements(currentTemplate.Elements);
			}
			finally
			{
				variables = variables.Parent;
				currentTemplate = saveTemplate;
			}

			
		}
Пример #3
0
		protected void ProcessTag(Tag tag)
		{
			string name = tag.Name.ToLowerInvariant();
			switch (name)
			{
				case "template":
					// skip those, because those are processed first
					break;
				case "else":
					ProcessElements(tag.InnerElements);
					break;
				case "apply":
					object val = EvalExpression(tag.AttributeValue("template"));
					ProcessTemplate(val.ToString(), tag);
					break;
				case "foreach":
					ProcessForEach(tag);
					break;
				default:
					ProcessTemplate(tag.Name, tag);
					break;
			}
		}
Пример #4
0
		protected void ProcessForEach(Tag tag)
		{
			Expression expCollection = tag.AttributeValue("collection");
			if (expCollection == null)
			{
				WriteError("Foreach is missing required attribute: collection", tag.Line, tag.Col);
				return;
			}

			object collection = EvalExpression(expCollection);
			if (!(collection is IEnumerable))
			{
				WriteError("Collection used in foreach has to be enumerable", tag.Line, tag.Col);
				return;
			}

			Expression expVar = tag.AttributeValue("var");
			if (expCollection == null)
			{
				WriteError("Foreach is missing required attribute: var", tag.Line, tag.Col);
				return;
			}
			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.InnerElements);
			}
		}
Пример #5
0
		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("Invalid token in tag: " + Current.TokenKind, Current.Line, Current.Col);

			}

			return tag;

		}