PageRenderTime 51ms CodeModel.GetById 18ms RepoModel.GetById 0ms app.codeStats 0ms

/src/Server/DeviceHive.DocGenerator/Html.cs

https://github.com/oryol/devicehive-.net
C# | 137 lines | 122 code | 13 blank | 2 comment | 12 complexity | f6aaa67badcbf896d9a71208e3043f01 MD5 | raw file
Possible License(s): MIT
  1. using System;
  2. using System.Collections.Generic;
  3. using System.Linq;
  4. using System.Text;
  5. using System.Text.RegularExpressions;
  6. using System.Web;
  7. using System.Xml.Linq;
  8. using DeviceHive.API.Models;
  9. namespace DeviceHive.DocGenerator
  10. {
  11. public static class Html
  12. {
  13. public static string Resource(MetadataResource resource)
  14. {
  15. var builder = new StringBuilder();
  16. builder.AppendLine("<pre>");
  17. builder.AppendLine("{");
  18. ResourceBlock(builder, resource.Properties, 1);
  19. builder.AppendLine("}");
  20. builder.AppendLine("</pre>");
  21. return builder.ToString();
  22. }
  23. private static void ResourceBlock(StringBuilder builder, MetadataParameter[] parameters, int indent)
  24. {
  25. var isFirstProperty = true;
  26. var processed = new List<MetadataParameter>();
  27. foreach (var parameter in parameters)
  28. {
  29. if (processed.Contains(parameter))
  30. continue;
  31. if (!isFirstProperty)
  32. builder.AppendLine(",");
  33. isFirstProperty = false;
  34. var innerObject = parameters.Where(p => p.Name.StartsWith(parameter.Name + "."));
  35. if (innerObject.Any())
  36. {
  37. var innerParams = innerObject.Select(o => new MetadataParameter { Name = o.Name.Substring(parameter.Name.Length + 1), Type = o.Type }).ToArray();
  38. builder.AppendFormat("{0}<span class=\"green\">&quot;{1}&quot;</span>: {{\n", new string(' ', 4 * indent), Encode(parameter.Name));
  39. ResourceBlock(builder, innerParams, indent + 1);
  40. builder.AppendFormat("{0}}}", new string(' ', 4 * indent));
  41. processed.AddRange(innerObject);
  42. continue;
  43. }
  44. var innerArray = parameters.Where(p => p.Name.StartsWith(parameter.Name + "[]."));
  45. if (innerArray.Any())
  46. {
  47. var innerParams = innerArray.Select(o => new MetadataParameter { Name = o.Name.Substring(parameter.Name.Length + 3), Type = o.Type }).ToArray();
  48. builder.AppendFormat("{0}<span class=\"green\">&quot;{1}&quot;</span>: [\n", new string(' ', 4 * indent), Encode(parameter.Name));
  49. builder.AppendFormat("{0}{{\n", new string(' ', 4 * (indent + 1)));
  50. ResourceBlock(builder, innerParams, indent + 2);
  51. builder.AppendFormat("{0}}}\n", new string(' ', 4 * (indent + 1)));
  52. builder.AppendFormat("{0}]", new string(' ', 4 * indent));
  53. processed.AddRange(innerArray);
  54. continue;
  55. }
  56. builder.AppendFormat("{0}<span class=\"green\">&quot;{1}&quot;</span>: <span class=\"blue\">{{{2}}}</span>",
  57. new string(' ', 4 * indent), Encode(parameter.Name), Encode(parameter.Type));
  58. }
  59. builder.AppendLine();
  60. }
  61. public static string Documentation(string text)
  62. {
  63. return DocumentationBlock(text);
  64. }
  65. private static string DocumentationBlock(string block)
  66. {
  67. if (block == null)
  68. return null;
  69. // look for content tags
  70. var startTagMatch = Regex.Match(block, @"\<(\w+)[^\>]*\>");
  71. if (startTagMatch.Success)
  72. {
  73. var tagName = startTagMatch.Groups[1].Value;
  74. var endTagMatch = Regex.Match(block.Substring(startTagMatch.Index + startTagMatch.Length), @"\<\/" + Regex.Escape(tagName) + @"\>");
  75. if (endTagMatch.Success)
  76. {
  77. var contents = DocumentationBlock(block.Substring(startTagMatch.Index + startTagMatch.Length, endTagMatch.Index));
  78. var substitution = Encode(startTagMatch.Value) + contents + Encode(endTagMatch.Value);
  79. switch (tagName)
  80. {
  81. case "para":
  82. substitution = "<p class=\"doc\">" + contents + "</p>";
  83. break;
  84. case "c":
  85. case "code":
  86. substitution = "<pre class=\"doc\">" + contents + "</pre>";
  87. break;
  88. case "list":
  89. substitution = "<ul class=\"doc\">" + contents + "</ul>";
  90. break;
  91. case "item":
  92. substitution = "<li class=\"doc\">" + contents + "</li>";
  93. break;
  94. case "description":
  95. substitution = contents;
  96. break;
  97. }
  98. return Encode(block.Substring(0, startTagMatch.Index)) + substitution +
  99. DocumentationBlock(block.Substring(startTagMatch.Index + startTagMatch.Length + endTagMatch.Index + endTagMatch.Length));
  100. }
  101. }
  102. // look for self-closing tags
  103. var tagMatch = Regex.Match(block, @"\<[^\>]+\/\>");
  104. if (tagMatch.Success)
  105. {
  106. var tag = XElement.Parse(tagMatch.Value);
  107. var substitution = Encode(tagMatch.Value);
  108. switch (tag.Name.LocalName)
  109. {
  110. case "see":
  111. substitution = string.Format(@"<a href=""#Reference/{0}"">{0}</a>", (string)tag.Attribute("cref"));
  112. break;
  113. }
  114. return Encode(block.Substring(0, tagMatch.Index)) + substitution +
  115. DocumentationBlock(block.Substring(tagMatch.Index + tagMatch.Length));
  116. }
  117. return Encode(block);
  118. }
  119. public static string Encode(string html)
  120. {
  121. return html == null ? null : HttpUtility.HtmlEncode(html);
  122. }
  123. }
  124. }