예제 #1
0
        /// <summary>
        /// Runs this instance.
        /// </summary>
        public void Run(Config config)
        {
            if (AssemblyManager == null)
                throw new InvalidOperationException("AssemblyManager must be set");

            if (ModelBuilder == null)
                throw new InvalidOperationException("ModelBuilder must be set");

            // Setup the PageId function
            ModelBuilder.PageIdFunction = PageIdFunction;

            var assemblySources = AssemblyManager.Load(config);

            // Process all assemblies
            foreach (var assemblySource in assemblySources)
            {
                ModelBuilder.LoadFrom(assemblySource, Registry);
            }

            Namespaces.AddRange(Registry.Namespaces);

            Namespaces.Sort((from, to) => string.CompareOrdinal(@from.Name, to.Name));

            foreach (var @namespace in Namespaces)
            {
                ProcessDescendants(@namespace.Types);
            }

            foreach (var @namespace in Namespaces)
            {
                @namespace.Types.Sort((from, to) => string.CompareOrdinal(@from.Name, to.Name));

                FlattenHierarchy(@namespace.Types);
            }
        }
        /// <summary>
        /// Loads all assembly sources/xml doc and references
        /// </summary>
        public List<NAssemblySource> Load(Config config)
        {
            var configPath = Path.GetDirectoryName(Path.GetFullPath(config.FilePath));
            configPath = configPath ?? Environment.CurrentDirectory;
            // Load all sources
            foreach (var group in config.Groups)
            {
                group.MergeGroup = group.MergeGroup ?? "default";
                foreach (var source in group.Sources)
                {
                    // Setup full path
                    if (!string.IsNullOrEmpty(source.AssemblyPath))
                        source.AssemblyPath = Path.Combine(configPath, source.AssemblyPath);

                    if (!string.IsNullOrEmpty(source.DocumentationPath))
                        source.DocumentationPath = Path.Combine(configPath, source.DocumentationPath);

                    Load(group, source);
                }
            }

            var finalSources = new List<NAssemblySource>();

            // Check that all source assemblies have valid Xml associated with it
            foreach (var assemblySource in AssemblySources.Where(node => node.Assembly != null))
            {
                int countXmlDocFound = 0;
                NDocumentApi docFound = null;
                string assemblyName = ((AssemblyDefinition) assemblySource.Assembly).Name.Name;

                var docSources = new List<NAssemblySource>();
                if (assemblySource.Document != null)
                    docSources.Add(assemblySource);
                docSources.AddRange( AssemblySources.Where(node => node.Assembly == null) );

                foreach (var doc in docSources)
                {
                    var node = doc.Document.Document.SelectSingleNode("/doc/assembly/name");
                    if (assemblyName == node.InnerText.Trim())
                    {
                        docFound = doc.Document;
                        countXmlDocFound++;
                    }
                }

                if (countXmlDocFound == 0)
                    Logger.Fatal("Unable to find documentation for assembly [{0}]", assemblyName);
                else if (countXmlDocFound > 1)
                    Logger.Fatal("Cannot load from multiple ([{0}]) documentation sources for assembly [{1}]", countXmlDocFound, assemblyName);

                assemblySource.Document = docFound;
                finalSources.Add(assemblySource);

            }
            return finalSources;
        }
예제 #3
0
        /// <summary>
        /// Runs this instance.
        /// </summary>
        public void Run(Config config)
        {
            if (AssemblyManager == null)
                throw new InvalidOperationException("AssemblyManager must be set");

            if (ModelBuilder == null)
                throw new InvalidOperationException("ModelBuilder must be set");

            // Setup the PageId function
            ModelBuilder.PageIdFunction = PageIdFunction;

            var assemblySources = AssemblyManager.Load(config);

            // Add exclude list to ModelBuilder
            ModelBuilder.ExcludeList.Clear();
            foreach (var excludeItem in config.ExcludeList)
            {
                if (!string.IsNullOrWhiteSpace(excludeItem))
                {
                    ModelBuilder.ExcludeList.Add(excludeItem);
                }
            }

            // Process all assemblies
            foreach (var assemblySource in assemblySources)
            {
                ModelBuilder.LoadFrom(assemblySource, Registry);
            }

            Namespaces.AddRange(Registry.Namespaces);

            Namespaces.Sort((from, to) => string.CompareOrdinal(@from.Name, to.Name));

            foreach (var @namespace in Namespaces)
            {
                ProcessDescendants(@namespace.Types);
            }

            foreach (var @namespace in Namespaces)
            {
                @namespace.Types.Sort((from, to) => string.CompareOrdinal(@from.Name, to.Name));

                FlattenHierarchy(@namespace.Types);
            }

            // Link extension method to the corresponding classes
            ModelBuilder.ProcessExtensionMethods();

            // inherit documentation
            ModelBuilder.ProcessInheritedDoc();
        }
예제 #4
0
        /// <summary>
        /// Initialize this instance from the specified config.
        /// </summary>
        /// <param name="config">The config.</param>
        public void Init(Config config)
        {
            var exePath = Path.GetDirectoryName(typeof(Config).Assembly.Location);
            // Locate global styles
            var dirInfo = new DirectoryInfo(exePath);
            if (dirInfo.Name.ToLower() == "debug" || dirInfo.Name.ToLower() == "release")
                AddPath(Path.Combine(exePath, "..\\..\\" + DefaultStyleDirectoryName));
            else if (dirInfo.Name.ToLower() == "bin")
                AddPath(Path.Combine(exePath, "..\\" + DefaultStyleDirectoryName));

            // Add Style directory from sharpdoc executable path
            AddPath(Path.Combine(exePath, DefaultStyleDirectoryName));

            // Add from current directory
            AddPath(Path.Combine(Environment.CurrentDirectory, DefaultStyleDirectoryName));

            // Add from current path of config
            if (!string.IsNullOrEmpty(config.FilePath))
                AddPath(Path.Combine(Path.GetDirectoryName(config.FilePath), DefaultStyleDirectoryName));

            // Add path declared from config file
            AddPath(config.StyleDirectories);
        }
예제 #5
0
 /// <summary>
 /// Initializes a new instance of the <see cref="SharpDocApp"/> class.
 /// </summary>
 public SharpDocApp()
 {
     Config = new Config();
     StyleManager = new StyleManager();
 }
예제 #6
0
        /// <summary>
        /// Build topics for Assemblies, Namespaces and Types in order to use them in the TOC
        /// </summary>
        public void Run(Config config, Func<IModelReference, string> pageIdFunction)
        {
            RootTopic = config.RootTopic;

            // Load an existing root topic
            if (RootTopic != null)
            {
                RootTopic.ForEachTopic(
                    topic =>
                        {
                            topic.PageId = pageIdFunction(topic);

                            // Check that PageId is a valid filename
                            if (!Utility.IsValidFilename(topic.PageId))
                                Logger.Error("Invalid PageId [{0}] for topic [{1}]. Fileid must contain valid filename chars", topic.PageId, this);
                        });
            }

            NTopic topicLibrary = null;

            // If there are any assemblies, we have to generate class library topics
            if (Namespaces.Count >= 0)
            {
                // Find if a ClassLibrary topic is referenced in the config topic
                topicLibrary = (RootTopic != null) ? RootTopic.FindTopicById(NTopic.ClassLibraryTopicId) : null;
                if (topicLibrary == null)
                {
                    // If no class library topic found, create a new one
                    topicLibrary = NTopic.DefaultClassLibraryTopic;
                    if (RootTopic == null)
                        RootTopic = topicLibrary;
                    else
                        RootTopic.SubTopics.Add(topicLibrary);
                }
                ClassLibraryTopic = topicLibrary;
            }

            if (RootTopic == null)
            {
                Logger.Fatal("No root topic assigned/ no topic for class library ");
                return;
            }

            // Calculate starting index for class library based on index from topics
            int index = 0;
            var indices = new HashSet<int>();
            var topicToReindex = new List<NTopic>();
            RootTopic.ForEachTopic(
                topic =>
                    {
                        if (indices.Contains(topic.Index))
                        {
                            // Silently reassign an index, as index is no longer important
                            //Logger.Warning("Index [{0}] for Topic [{1}] is already used. Need to reassign a new index.", topic.Index, topic.Name);
                            topicToReindex.Add(topic);
                        }
                        else
                        {
                            indices.Add(topic.Index);
                            index = Math.Max(index, topic.Index);
                        }
                    });
            index++;
            foreach (var topicToIndex in topicToReindex)
            {
                topicToIndex.Index = index++;
            }

            foreach (var @namespace in Namespaces)
            {
                // Affect new Index based on previous topics
                @namespace.Index = index++;
                var namespaceTopic = new NTopic(@namespace) { Name = @namespace.Name + " Namespace", AttachedClassNode = @namespace };
                @namespace.TopicLink = namespaceTopic;
                topicLibrary.SubTopics.Add(namespaceTopic);
                @namespace.SeeAlsos.Add(new NSeeAlso(topicLibrary));

                foreach (var type in @namespace.Types)
                {
                    // Affect new Index based on previous topics
                    type.Index = index++;
                    var typeTopic = new NTopic(type) { Name = type.Name + " " + type.Category, AttachedClassNode = type};
                    type.TopicLink = typeTopic;
                    namespaceTopic.SubTopics.Add(typeTopic);
                    type.SeeAlsos.Add(new NSeeAlso(topicLibrary));

                    // We don't process fields for enums
                    if (!(type is NEnum))
                    {
                        foreach (var member in type.Members)
                        {
                            var memberTopic = new NTopic(member) { Name = member.Name, AttachedClassNode = type };
                            member.TopicLink = memberTopic;
                            typeTopic.SubTopics.Add(memberTopic);

                            // Affect new Index based on previous topics
                            member.Index = index++;
                            member.SeeAlsos.Add(new NSeeAlso(topicLibrary));
                        }
                    }
                }
            }

            SearchTopic = NTopic.DefaultSearchResultsTopic;
            SearchTopic.Index = index++;

            // Add SearchTopic to the root topic
            RootTopic.SubTopics.Add(SearchTopic);

            // Associate each topic with its parent
            RootTopic.BuildParents();

            // Register root topics and all sub topics (excluding class library topics)
            Registry.Register(RootTopic);
        }