Example #1
0
File: Nocco.cs Project: JakeH/nocco
        /// <summary>
        /// Generates the HTML result for a single source file.
        /// </summary>
        /// <param name="sourceFile"></param>
        /// <param name="docsDirectory"></param>
        /// <param name="job"></param>
        /// <returns>Generated document FileInfo</returns>
        private static DocumentSummary GenerateDocumentHtml(FileInfo sourceFile, DirectoryInfo docsDirectory, NoccoJob job, IEnumerable<FileInfo> othersInSameJob)
        {
            DocumentSummary summary = new DocumentSummary() { DocumentFile = sourceFile };

            var destinationFile = GetAbsoluteDocDestination(sourceFile, docsDirectory, job.JobBaseDirectory);

            //the relative path from the destination file to the documation folder
            string docsRelative = Helpers.GetPathRelativeTo(destinationFile.Directory, docsDirectory);

            //get the opposite direction for the index page
            summary.RelativeUri = Helpers.ConvertPathSeparator(Path.Combine(
                    Helpers.GetPathRelativeTo(docsDirectory, destinationFile.Directory), destinationFile.Name));

            AbDocumentTemplate TemplateGenerator = Helpers.GetTemplateGenerator<AbDocumentTemplate>(
                new FileInfo(App.ResolveDirectory(App.Settings.DocumentTemplateFile)));

            //setup template generator settings
            TemplateGenerator.Title = sourceFile.Name;
            summary.Title = TemplateGenerator.Title;

            if (job.GenerateInlineIndex)
            {
                //list of other files in this same job, relative to myself
                TemplateGenerator.OtherDocumentsInJob = othersInSameJob.DefaultIfEmpty()
                            .Select(o =>
                                {
                                    var abs = GetAbsoluteDocDestination(o, docsDirectory, job.JobBaseDirectory);
                                    return Path.Combine(Helpers.GetPathRelativeTo(destinationFile.Directory, abs.Directory), abs.Name);
                                })
                            .ToArray();
            }

            TemplateGenerator.Sections = ParseSections(sourceFile, job.Language, summary);
            TemplateGenerator.DocsRelative = docsRelative;

            if (job.GenerateIndexFile)
            {
                TemplateGenerator.IndexFile = Helpers.ConvertPathSeparator(Path.Combine(docsRelative, job.IndexFilename));
            }

            //generate documenation file
            TemplateGenerator.Generate(destinationFile.FullName);

            return summary;
        }
Example #2
0
File: Nocco.cs Project: JakeH/nocco
        /// <summary>
        /// Create separated and formatted sections for comments and code for use in documenation file 
        /// </summary>
        /// <param name="source"></param>
        /// <param name="language"></param>
        /// <returns></returns>
        private static IEnumerable<Section> ParseSections(FileInfo source, LanguageConfig language, DocumentSummary summary)
        {
            var sections = new List<Section>();
            var hasCode = false;
            var docsText = new StringBuilder();
            var codeText = new StringBuilder();

            bool OkayToReplaceSection = true;

            //generates a section of comment and code
            Func<StringBuilder, StringBuilder, Section> GenerateSection = (docs, code) =>
            {
                var docsString = docs.ToString();

                //highlight comments if required
                if (language.MarkdownMaps != null)
                {
                    docsString = language.MarkdownMaps.Aggregate(docsString,
                        (currentDocs, map) =>
                            Regex.Replace(currentDocs, map.FindPattern, map.Replacement, RegexOptions.Multiline)
                        );
                }

                var ret = new Section
                {
                    DocsHtml = MarkdownFormatter.Transform(docsString),
                    CodeHtml = System.Web.HttpUtility.HtmlEncode(code.ToString())
                };

                //set the top section for the summary, just in case, but ideally we want the second block
                //or a block after the first which has both sections
                if (summary.TopSection == null)
                {
                    //easy winner
                    summary.TopSection = ret;
                }
                else if (OkayToReplaceSection)
                {
                    summary.TopSection = ret;
                    OkayToReplaceSection = false;
                }
                else
                {
                    if (string.IsNullOrWhiteSpace(summary.TopSection.CodeHtml) ||
                        string.IsNullOrWhiteSpace(summary.TopSection.DocsHtml))
                    {
                        if (!string.IsNullOrWhiteSpace(ret.CodeHtml) &&
                            !string.IsNullOrWhiteSpace(ret.DocsHtml))
                        {
                            //winner by content superiority
                            summary.TopSection = ret;
                        }
                    }
                }

                return ret;

            };

            foreach (var result in Parser.Process(source, language.CommentDefinitions))
            {

                //if this line matches a comment line
                if (result.ResultType == ResultType.Comment)
                {
                    //if we hit this comment line after already processing code, we need to make a new section
                    if (hasCode)
                    {
                        yield return GenerateSection(docsText, codeText);

                        hasCode = false;
                        docsText = new StringBuilder();
                        codeText = new StringBuilder();
                    }

                    //update the summary
                    summary.LinesOfComment++;

                    docsText.AppendLine(result.MatchingDefinition.CleanComment(result.Result));
                }
                else //hit code or unknown line
                {
                    //update the summary
                    summary.LinesOfCode++;

                    hasCode = true;
                    codeText.AppendLine(result.Result);
                }

               }

            yield return GenerateSection(docsText, codeText);
        }