public Element(ElementKind kind, Token startTag) { Kind = kind; StartTagTokens = new Dictionary<string, object> { { "", startTag } }; EndTagTokens = new Dictionary<string, object>(); Children = new List<Element>(); }
Element visit_text(Token token) { return new Element(ElementKind.Text, token); }
Element visit_start_tag(Token token) { var ns = new Dictionary<string, string>(_namespaces.Last()); _namespaces.Add(ns); var node = parse_tag(token, ns); _index.Push(new KeyValuePair<Token, int>(node["name"] as Token, _queue.Count)); return new Element(ElementKind.StartTag, node); }
Element visit_processing_instruction(Token token) { Match match = MatchProcessingInstruction.Match(token.ToString()); Dictionary<string, object> node = Groupdict(MatchProcessingInstruction, match, token); return new Element(ElementKind.ProcessingInstruction, node); }
Element visit_end_tag(Token token) { Dictionary<string, string> ns; try { ns = _namespaces.Last(); _namespaces.RemoveAt(_namespaces.Count - 1); } catch (InvalidOperationException) { throw new ParseError("Unexpected end tag.", token); } Dictionary<string, object> node = parse_tag(token, ns); while (_index.Count > 0) { KeyValuePair<Token, int> idx = _index.Pop(); Token name = idx.Key; int pos = idx.Value; if (node["name"].Equals(name)) { Element el = _queue[pos]; _queue.RemoveAt(pos); Dictionary<string, object> start = el.StartTagTokens; List<Element> children = _queue.GetRange(pos, _queue.Count - pos); _queue.RemoveRange(pos, _queue.Count - pos); return new Element(ElementKind.Element, start, node, children); } } throw new ParseError("Unexpected end tag.", token); }
Element visit_empty_tag(Token token) { var ns = new Dictionary<string, string>(_namespaces.Last()); var node = parse_tag(token, ns); return new Element(ElementKind.Element, node); }
Element visit_default(Token token) { return new Element(ElementKind.Default, token); }
Element visit_comment(Token token) { return new Element(ElementKind.Comment, token); }
Element visit_cdata(Token token) { return new Element(ElementKind.CData, token); }
Element ParseToken(Token token) { TokenKind kind = token.Kind; if (kind == TokenKind.Comment) return visit_comment(token); if (kind == TokenKind.CData) return visit_cdata(token); if (kind == TokenKind.ProcessingInstruction) return visit_processing_instruction(token); if (kind == TokenKind.EndTag) return visit_end_tag(token); if (kind == TokenKind.EmptyTag) return visit_empty_tag(token); if (kind == TokenKind.StartTag) return visit_start_tag(token); if (kind == TokenKind.Text) return visit_text(token); return visit_default(token); }
static Dictionary<string, object> parse_tag(Token token, Dictionary<string, string> ns) { var node = match_tag(token); update_namespace(node["attrs"] as List<Dictionary<string, object>>, ns); string prefix = null; if ((node["name"] as Token).ToString().Contains(':')) prefix = (node["name"] as Token).ToString().Split(':')[0]; string defaultNs = prefix != null && ns.ContainsKey(prefix) ? ns[prefix] : XmlNs; node["namespace"] = defaultNs; node["ns_attrs"] = unpack_attributes(node["attrs"] as List<Dictionary<string, object>>, ns, defaultNs); return node; }
static Dictionary<string, object> match_tag(Token token) { Match match = MatchTagPrefixAndName.Match(token.ToString()); Dictionary<string, object> node = Groupdict(MatchTagPrefixAndName, match, token); int end = match.Index + match.Length; token = token.Substring(end); var attrs = new List<Dictionary<string, object>>(); node["attrs"] = attrs; foreach (Match m in MatchSingleAttribute.Matches(token.ToString())) { Dictionary<string, object> attr = Groupdict(MatchSingleAttribute, m, token); if (attr.Keys.Contains("alt_value")) { var altValue = attr["alt_value"] as Token; attr.Remove("alt_value"); if (!string.IsNullOrEmpty(altValue.ToString())) { attr["value"] = altValue; attr["quote"] = ""; } } if (attr.Keys.Contains("simple_value")) { var simpleValue = attr["simple_value"] as Token; attr.Remove("simple_value"); if (!string.IsNullOrEmpty(simpleValue.ToString())) { attr["quote"] = ""; attr["value"] = new Token(""); attr["eq"] = ""; } } attrs.Add(attr); int m_end = m.Index + m.Length; node["suffix"] = token.Substring(m_end); } return node; }
static Dictionary<string, object> Groupdict(Regex r, Match m, Token token) { var d = new Dictionary<string, object>(); foreach (string name in r.GetGroupNames()) { Group g = m.Groups[name]; if (g != null) { int i = g.Index; int j = g.Length; d.Add(name, token.Substring(i, j)); } else { d.Add(name, null); } } return d; }
public TemplateError(string msg, Token token) { _msg = msg; _token = token; _filename = token.Filename; }