PageRenderTime 153ms CodeModel.GetById 34ms app.highlight 13ms RepoModel.GetById 42ms app.codeStats 0ms

/Main/Source/HtmlToMaml/TopicCollection.cs

#
C# | 248 lines | 145 code | 36 blank | 67 comment | 20 complexity | aea6915a06cc24362ebe06c4b04d93a8 MD5 | raw file
Possible License(s): CC-BY-SA-3.0
  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
 22using System;
 23using System.Collections.Generic;
 24using System.Collections.ObjectModel;
 25using System.IO;
 26using System.Xml;
 27
 28using SandcastleBuilder.Utils;
 29
 30namespace HtmlToMamlConversion
 31{
 32    /// <summary>
 33    /// This is a collection of topic items
 34    /// </summary>
 35    public class TopicCollection : Collection<Topic>
 36    {
 37        #region Properties
 38        //=====================================================================
 39
 40        /// <summary>
 41        /// This is used to get the default topic
 42        /// </summary>
 43        /// <value>It returns the default topic or null if one is not set</value>
 44        public Topic DefaultTopic
 45        {
 46            get
 47            {
 48                Topic defaultTopic = null;
 49
 50                foreach(Topic t in this)
 51                {
 52                    if(t.IsDefaultTopic)
 53                        defaultTopic = t;
 54                    else
 55                        defaultTopic = t.Subtopics.DefaultTopic;
 56
 57                    if(defaultTopic != null)
 58                        break;
 59                }
 60
 61                return defaultTopic;
 62            }
 63        }
 64
 65        /// <summary>
 66        /// This is used to get the topic at which the table of content is
 67        /// split by the API content.
 68        /// </summary>
 69        /// <value>This will only be valid if it refers to a root level
 70        /// topic.  It will return null if a split location has not been
 71        /// set at the root level.</value>
 72        public Topic SplitTocAtTopic
 73        {
 74            get
 75            {
 76                foreach(Topic t in this)
 77                    if(t.SplitToc)
 78                        return t;
 79
 80                return null;
 81            }
 82        }
 83        #endregion
 84
 85        #region Conversion helpers
 86        //=====================================================================
 87
 88        /// <summary>
 89        /// Add all topics from the specified folder recursively to the
 90        /// topic collection.
 91        /// </summary>
 92        /// <param name="folder">The folder from which to get the files</param>
 93        /// <param name="topicDictionary">A dictionary used to contain the list
 94        /// of files index by name.</param>
 95        /// <remarks>Only files with a .htm? or .topic extension are added</remarks>
 96        public void AddTopicsFromFolder(string folder,
 97          Dictionary<FilePath, Topic> topicDictionary)
 98        {
 99            Topic topic, removeTopic;
100            FilePath topicPath;
101            string[] files = Directory.GetFiles(folder, "*.htm?");
102            string name;
103
104            // Add files
105            foreach(string file in files)
106            {
107                topic = new Topic(file);
108                this.Add(topic);
109                topicDictionary.Add(topic.SourceFile, topic);
110            }
111
112            files = Directory.GetFiles(folder, "*.topic");
113
114            foreach(string file in files)
115            {
116                topic = new Topic(file);
117                this.Add(topic);
118                topicPath = new FilePath(Path.ChangeExtension(
119                  topic.SourceFile.Path, ".html"), topic.SourceFile.BasePathProvider);
120                topicDictionary.Add(topicPath, topic);
121            }
122
123            // Add folders recursively
124            files = Directory.GetDirectories(folder);
125
126            foreach(string folderName in files)
127            {
128                topic = new Topic(null);
129                topic.Title = name = Path.GetFileName(folderName);
130                topic.Subtopics.AddTopicsFromFolder(folderName, topicDictionary);
131
132                // Ignore empty folders
133                if(topic.Subtopics.Count == 0)
134                    continue;
135
136                this.Add(topic);
137
138                // Look for a file with the same name as the folder
139                removeTopic = null;
140
141                foreach(Topic t in topic.Subtopics)
142                    if(t.SourceFile != null && Path.GetFileNameWithoutExtension(
143                      t.SourceFile) == name)
144                    {
145                        // If found, remove it as it represents the container node
146                        topic.Title = null;
147                        topic.SourceFile = t.SourceFile;
148                        topic.Id = t.Id;
149                        removeTopic = t;
150                        topicDictionary[topic.SourceFile] = topic;
151                        break;
152                    }
153
154                if(removeTopic != null)
155                    topic.Subtopics.Remove(removeTopic);
156            }
157        }
158
159        /// <summary>
160        /// Parse all files in the collection to extract the information for
161        /// conversion.
162        /// </summary>
163        /// <param name="fileParser">The file parser</param>
164        /// <param name="imageDictionary">The image dictionary</param>
165        public void ParseFiles(FileParser fileParser,
166          Dictionary<FilePath, ImageReference> imageDictionary)
167        {
168            foreach(Topic t in this)
169                t.ParseFile(fileParser, imageDictionary);
170        }
171        #endregion
172
173        #region Save to content layout file
174        //=====================================================================
175
176        /// <summary>
177        /// Save the topic collection to the named content layout file
178        /// </summary>
179        /// <param name="filename">The filename to which the content layout
180        /// is saved.</param>
181        public void Save(string filename)
182        {
183            XmlWriterSettings settings = new XmlWriterSettings();
184            XmlWriter writer = null;
185            Topic defaultTopic = this.DefaultTopic, splitToc = this.SplitTocAtTopic;
186
187            try
188            {
189                this.Sort();
190
191                settings.Indent = true;
192                settings.CloseOutput = true;
193                writer = XmlWriter.Create(filename, settings);
194
195                writer.WriteStartDocument();
196                writer.WriteStartElement("Topics");
197
198                if(defaultTopic != null)
199                    writer.WriteAttributeString("defaultTopic",
200                        defaultTopic.Id.ToString());
201
202                if(splitToc != null)
203                    writer.WriteAttributeString("splitTOCTopic",
204                        splitToc.Id.ToString());
205
206                foreach(Topic t in this)
207                    t.WriteXml(writer);
208
209                writer.WriteEndElement();
210                writer.WriteEndDocument();
211            }
212            finally
213            {
214                if(writer != null)
215                    writer.Close();
216            }
217        }
218        #endregion
219
220        #region Sort collection
221        //=====================================================================
222        
223        /// <summary>
224        /// This is used to sort the collection
225        /// </summary>
226        /// <remarks>Values are sorted by display title.  Comparisons are
227        /// case-sensitive.</remarks>
228        public void Sort()
229        {
230            ((List<Topic>)base.Items).Sort(
231                delegate(Topic x, Topic y)
232                {
233                    if(x.SortOrder < y.SortOrder)
234                        return -1;
235
236                    if(x.SortOrder > y.SortOrder)
237                        return 1;
238
239                    return String.Compare(x.Title, y.Title,
240                        StringComparison.CurrentCultureIgnoreCase);
241                });
242
243            foreach(Topic t in this)
244                t.Subtopics.Sort();
245        }
246        #endregion
247    }
248}