/Main/Source/HtmlToMaml/TopicCollection.cs

# · C# · 248 lines · 145 code · 36 blank · 67 comment · 20 complexity · aea6915a06cc24362ebe06c4b04d93a8 MD5 · raw file

  1. //=============================================================================
  2. // System : HTML to MAML Converter
  3. // File : TopicCollection.cs
  4. // Author : Eric Woodruff (Eric@EWoodruff.us)
  5. // Updated : 09/17/2008
  6. // Note : Copyright 2008, Eric Woodruff, All rights reserved
  7. // Compiler: Microsoft Visual C#
  8. //
  9. // This file contains a class used to contain a collection of topics.
  10. //
  11. // This code is published under the Microsoft Public License (Ms-PL). A copy
  12. // of the license should be distributed with the code. It can also be found
  13. // at the project website: http://www.CodePlex.com/SandcastleStyles. This
  14. // notice, the author's name, and all copyright notices must remain intact in
  15. // all applications, documentation, and source files.
  16. //
  17. // Version Date Who Comments
  18. // ============================================================================
  19. // 1.0.0.0 09/12/2008 EFW Created the code
  20. //=============================================================================
  21. using System;
  22. using System.Collections.Generic;
  23. using System.Collections.ObjectModel;
  24. using System.IO;
  25. using System.Xml;
  26. using SandcastleBuilder.Utils;
  27. namespace HtmlToMamlConversion
  28. {
  29. /// <summary>
  30. /// This is a collection of topic items
  31. /// </summary>
  32. public class TopicCollection : Collection<Topic>
  33. {
  34. #region Properties
  35. //=====================================================================
  36. /// <summary>
  37. /// This is used to get the default topic
  38. /// </summary>
  39. /// <value>It returns the default topic or null if one is not set</value>
  40. public Topic DefaultTopic
  41. {
  42. get
  43. {
  44. Topic defaultTopic = null;
  45. foreach(Topic t in this)
  46. {
  47. if(t.IsDefaultTopic)
  48. defaultTopic = t;
  49. else
  50. defaultTopic = t.Subtopics.DefaultTopic;
  51. if(defaultTopic != null)
  52. break;
  53. }
  54. return defaultTopic;
  55. }
  56. }
  57. /// <summary>
  58. /// This is used to get the topic at which the table of content is
  59. /// split by the API content.
  60. /// </summary>
  61. /// <value>This will only be valid if it refers to a root level
  62. /// topic. It will return null if a split location has not been
  63. /// set at the root level.</value>
  64. public Topic SplitTocAtTopic
  65. {
  66. get
  67. {
  68. foreach(Topic t in this)
  69. if(t.SplitToc)
  70. return t;
  71. return null;
  72. }
  73. }
  74. #endregion
  75. #region Conversion helpers
  76. //=====================================================================
  77. /// <summary>
  78. /// Add all topics from the specified folder recursively to the
  79. /// topic collection.
  80. /// </summary>
  81. /// <param name="folder">The folder from which to get the files</param>
  82. /// <param name="topicDictionary">A dictionary used to contain the list
  83. /// of files index by name.</param>
  84. /// <remarks>Only files with a .htm? or .topic extension are added</remarks>
  85. public void AddTopicsFromFolder(string folder,
  86. Dictionary<FilePath, Topic> topicDictionary)
  87. {
  88. Topic topic, removeTopic;
  89. FilePath topicPath;
  90. string[] files = Directory.GetFiles(folder, "*.htm?");
  91. string name;
  92. // Add files
  93. foreach(string file in files)
  94. {
  95. topic = new Topic(file);
  96. this.Add(topic);
  97. topicDictionary.Add(topic.SourceFile, topic);
  98. }
  99. files = Directory.GetFiles(folder, "*.topic");
  100. foreach(string file in files)
  101. {
  102. topic = new Topic(file);
  103. this.Add(topic);
  104. topicPath = new FilePath(Path.ChangeExtension(
  105. topic.SourceFile.Path, ".html"), topic.SourceFile.BasePathProvider);
  106. topicDictionary.Add(topicPath, topic);
  107. }
  108. // Add folders recursively
  109. files = Directory.GetDirectories(folder);
  110. foreach(string folderName in files)
  111. {
  112. topic = new Topic(null);
  113. topic.Title = name = Path.GetFileName(folderName);
  114. topic.Subtopics.AddTopicsFromFolder(folderName, topicDictionary);
  115. // Ignore empty folders
  116. if(topic.Subtopics.Count == 0)
  117. continue;
  118. this.Add(topic);
  119. // Look for a file with the same name as the folder
  120. removeTopic = null;
  121. foreach(Topic t in topic.Subtopics)
  122. if(t.SourceFile != null && Path.GetFileNameWithoutExtension(
  123. t.SourceFile) == name)
  124. {
  125. // If found, remove it as it represents the container node
  126. topic.Title = null;
  127. topic.SourceFile = t.SourceFile;
  128. topic.Id = t.Id;
  129. removeTopic = t;
  130. topicDictionary[topic.SourceFile] = topic;
  131. break;
  132. }
  133. if(removeTopic != null)
  134. topic.Subtopics.Remove(removeTopic);
  135. }
  136. }
  137. /// <summary>
  138. /// Parse all files in the collection to extract the information for
  139. /// conversion.
  140. /// </summary>
  141. /// <param name="fileParser">The file parser</param>
  142. /// <param name="imageDictionary">The image dictionary</param>
  143. public void ParseFiles(FileParser fileParser,
  144. Dictionary<FilePath, ImageReference> imageDictionary)
  145. {
  146. foreach(Topic t in this)
  147. t.ParseFile(fileParser, imageDictionary);
  148. }
  149. #endregion
  150. #region Save to content layout file
  151. //=====================================================================
  152. /// <summary>
  153. /// Save the topic collection to the named content layout file
  154. /// </summary>
  155. /// <param name="filename">The filename to which the content layout
  156. /// is saved.</param>
  157. public void Save(string filename)
  158. {
  159. XmlWriterSettings settings = new XmlWriterSettings();
  160. XmlWriter writer = null;
  161. Topic defaultTopic = this.DefaultTopic, splitToc = this.SplitTocAtTopic;
  162. try
  163. {
  164. this.Sort();
  165. settings.Indent = true;
  166. settings.CloseOutput = true;
  167. writer = XmlWriter.Create(filename, settings);
  168. writer.WriteStartDocument();
  169. writer.WriteStartElement("Topics");
  170. if(defaultTopic != null)
  171. writer.WriteAttributeString("defaultTopic",
  172. defaultTopic.Id.ToString());
  173. if(splitToc != null)
  174. writer.WriteAttributeString("splitTOCTopic",
  175. splitToc.Id.ToString());
  176. foreach(Topic t in this)
  177. t.WriteXml(writer);
  178. writer.WriteEndElement();
  179. writer.WriteEndDocument();
  180. }
  181. finally
  182. {
  183. if(writer != null)
  184. writer.Close();
  185. }
  186. }
  187. #endregion
  188. #region Sort collection
  189. //=====================================================================
  190. /// <summary>
  191. /// This is used to sort the collection
  192. /// </summary>
  193. /// <remarks>Values are sorted by display title. Comparisons are
  194. /// case-sensitive.</remarks>
  195. public void Sort()
  196. {
  197. ((List<Topic>)base.Items).Sort(
  198. delegate(Topic x, Topic y)
  199. {
  200. if(x.SortOrder < y.SortOrder)
  201. return -1;
  202. if(x.SortOrder > y.SortOrder)
  203. return 1;
  204. return String.Compare(x.Title, y.Title,
  205. StringComparison.CurrentCultureIgnoreCase);
  206. });
  207. foreach(Topic t in this)
  208. t.Subtopics.Sort();
  209. }
  210. #endregion
  211. }
  212. }