PageRenderTime 48ms CodeModel.GetById 5ms RepoModel.GetById 1ms app.codeStats 0ms

/SharpTAL/TemplateParser/AbstractTemplateParser.cs

https://bitbucket.org/rlacko/sharptal
C# | 149 lines | 107 code | 8 blank | 34 comment | 26 complexity | 274aa35217320d2afd6aa6de8bcdae67 MD5 | raw file
Possible License(s): Apache-2.0
  1. //
  2. // AbstractTemplateParser.cs
  3. //
  4. // Author:
  5. // Roman Lacko (backup.rlacko@gmail.com)
  6. //
  7. // Copyright (c) 2010 - 2013 Roman Lacko
  8. //
  9. // Permission is hereby granted, free of charge, to any person obtaining
  10. // a copy of this software and associated documentation files (the
  11. // "Software"), to deal in the Software without restriction, including
  12. // without limitation the rights to use, copy, modify, merge, publish,
  13. // distribute, sublicense, and/or sell copies of the Software, and to
  14. // permit persons to whom the Software is furnished to do so, subject to
  15. // the following conditions:
  16. //
  17. // The above copyright notice and this permission notice shall be
  18. // included in all copies or substantial portions of the Software.
  19. //
  20. // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
  21. // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
  22. // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
  23. // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
  24. // LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
  25. // OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
  26. // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
  27. //
  28. namespace SharpTAL.TemplateParser
  29. {
  30. using System;
  31. using System.Linq;
  32. using System.Collections.Generic;
  33. using System.Collections.Specialized;
  34. /// <summary>
  35. /// Abstract XML/HTML parser
  36. /// </summary>
  37. public abstract class AbstractTemplateParser
  38. {
  39. protected abstract void HandleStartTag(Tag tag);
  40. protected abstract void HandleEndTag(Tag tag);
  41. protected abstract void HandleData(string data);
  42. protected abstract void HandleComment(string data);
  43. protected abstract void HandleCData(string data);
  44. protected abstract void HandleProcessingInstruction(Element e);
  45. protected abstract void HandleDefault(string data);
  46. public void ParseTemplate(string templateBody, string templatePath, Dictionary<string, string> defaultNamespaces)
  47. {
  48. IEnumerable<Token> tokens = Tokenizer.TokenizeXml(templateBody, templatePath);
  49. ElementParser parser = new ElementParser(tokens, defaultNamespaces);
  50. foreach (var e in parser.Parse())
  51. HandleElement(e);
  52. }
  53. void HandleElement(Element e)
  54. {
  55. if (e.Kind == ElementKind.Element || e.Kind == ElementKind.StartTag)
  56. {
  57. // Start tag
  58. Token name = e.StartTagTokens["name"] as Token;
  59. Token suffix = e.StartTagTokens["suffix"] as Token;
  60. Tag tag = new Tag();
  61. tag.Name = name.ToString();
  62. tag.Suffix = suffix.ToString();
  63. tag.SourcePath = name.Filename;
  64. Location loc = name.Location;
  65. tag.LineNumber = loc.Line;
  66. tag.LinePosition = loc.Position;
  67. tag.Attributes = new List<TagAttribute>();
  68. List<Dictionary<string, object>> attrs = e.StartTagTokens["attrs"] as List<Dictionary<string, object>>;
  69. foreach (var attr in attrs)
  70. {
  71. Token attr_name = attr["name"] as Token;
  72. Token attr_value = attr["value"] as Token;
  73. Token attr_eq = attr["eq"] as Token;
  74. Token attr_quote = attr["quote"] as Token;
  75. TagAttribute a = new TagAttribute
  76. {
  77. Name = attr_name.ToString(),
  78. Value = attr_value.ToString(),
  79. Eq = attr_eq.ToString(),
  80. Quote = attr_quote.ToString(),
  81. QuoteEntity = Utils.Char2Entity(attr_quote.ToString())
  82. };
  83. tag.Attributes.Add(a);
  84. }
  85. if ((e.Children.Count == 0 && suffix.ToString() == "/>") || e.EndTagTokens.Count == 0)
  86. {
  87. // Singleton element
  88. tag.Singleton = true;
  89. HandleStartTag(tag);
  90. HandleEndTag(tag);
  91. }
  92. else
  93. {
  94. tag.Singleton = false;
  95. HandleStartTag(tag);
  96. }
  97. // Children
  98. foreach (var item in e.Children)
  99. HandleElement(item);
  100. // End tag
  101. if (e.EndTagTokens.Count > 0)
  102. {
  103. Token end_name = e.EndTagTokens["name"] as Token;
  104. Token end_suffix = e.EndTagTokens["suffix"] as Token;
  105. Tag end_tag = new Tag();
  106. end_tag.Name = end_name.ToString();
  107. end_tag.Suffix = end_suffix.ToString();
  108. end_tag.SourcePath = end_name.Filename;
  109. Location end_loc = end_name.Location;
  110. end_tag.LineNumber = end_loc.Line;
  111. end_tag.LinePosition = end_loc.Position;
  112. HandleEndTag(end_tag);
  113. }
  114. }
  115. else if (e.Kind == ElementKind.Text)
  116. {
  117. foreach (Token token in e.StartTagTokens.Values)
  118. HandleData(token.ToString());
  119. }
  120. else if (e.Kind == ElementKind.Comment)
  121. {
  122. foreach (Token token in e.StartTagTokens.Values)
  123. HandleComment(token.ToString());
  124. }
  125. else if (e.Kind == ElementKind.CData)
  126. {
  127. foreach (Token token in e.StartTagTokens.Values)
  128. HandleCData(token.ToString());
  129. }
  130. else if (e.Kind == ElementKind.ProcessingInstruction)
  131. {
  132. HandleProcessingInstruction(e);
  133. }
  134. else if (e.Kind == ElementKind.Default)
  135. {
  136. foreach (Token token in e.StartTagTokens.Values)
  137. HandleDefault(token.ToString());
  138. }
  139. }
  140. }
  141. }