Esempio n. 1
0
        /// <summary>
        /// Renders the <see cref="ExceptionDoc"/> element  to string containing the markup provided by <paramref name="markupProvider"/>
        /// </summary>
        /// <remarks>
        /// Builds the link with the reference according to the <c>cref</c> attribute value. The value represents the Documentation ID
        /// that can be matched to the information got during the code analysis or to build the link to MS API reference for the "MS objects".
        /// First, it tries to resolve the <see cref="Member"/> in code being documented (internal link). If not successful, tries to look for
        /// the <c>cref</c> (Documentation ID) in the MS API documentation if allowed/available (see <see cref="MsApiDocEngine"/> for details)
        /// <para>
        /// The link text is the the name of linked entity when using internal <see cref="IMarkupProvider.Link(string,net.adamec.dev.markupdoc.CodeModel.Member)"/>
        /// or the <c>cref</c> without the leading type information when rendering .
        /// When the link is not constructed ("target unknown"), the <c>cref</c>  value without the leading type information is rendered in italic
        /// </para>
        /// <para>
        /// The &lt;exception&gt; element is then rendered as <see cref="IMarkupProvider.DescriptionListItem"/> where
        ///<c>Term</c> is the link and <c>Description</c> is the fully trimmed element content.
        /// Important: it returns description list item, so must be encapsulated on higher level !!!
        /// </para>
        /// </remarks>
        /// <param name="markupProvider"><see cref="IMarkupProvider"/> allowing using the markup within the rendered content</param>
        /// <param name="member">Code model <see cref="Member"/> to render the XML Documentation Comment for</param>
        /// <param name="trim">Flag whether to (full) trim the rendered content</param>
        /// <returns>Rendered content of &lt;exception&gt; element of XML Documentation Comments.
        /// Important: it returns description list item, so must be encapsulated on higher level !!!</returns>
        ///<seealso cref="MsApiDocEngine"/>
        /// <seealso cref="MsApiDocOptions"/>
        protected override string RenderElement(IMarkupProvider markupProvider, Member member, bool trim = true)
        {
            //for exception always render both Ref(link if available) AND content

            //content
            var content = base.RenderElement(markupProvider, member, trim);

            //ref
            string exceptionRef;

            if (member.Root.AllMembersByDocId.TryGetValue(Ref, out var refMember))
            {
                exceptionRef = markupProvider.Link(refMember.Name, refMember);
            }
            else
            {
                //Try to get the MS API link from reference
                var msLink = MsApiDocEngine.GetLink(Ref);
                //Got the MS link, so use external link
                // ReSharper disable once ConvertIfStatementToConditionalTernaryExpression
                if (msLink != null)
                {
                    exceptionRef = markupProvider.ExternalLink(Ref.Substring(2), msLink);
                }
                else
                {
                    //No link -  Ref without leading "ref type"
                    exceptionRef = markupProvider.Italic(Ref.Substring(2));
                }
            }
            //output
            return(markupProvider.DescriptionListItem(exceptionRef, content));
        }
        /// <summary>
        /// Renders the element having the <c>cref</c> attribute to string containing the markup provided by <paramref name="markupProvider"/>
        /// </summary>
        /// <remarks>
        /// Builds the link with the reference according to the <c>cref</c> attribute value. The value represents the Documentation ID
        /// that can be matched to the information got during the code analysis or to build the link to MS API reference for the "MS objects".
        /// First, it tries to resolve the <see cref="Member"/> in code being documented (internal link). If not successful, tries to look for
        /// the <c>cref</c> (Documentation ID) in the MS API documentation if allowed/available (see <see cref="MsApiDocEngine"/> for details)
        /// <para>
        /// The link text is the rendered trimmed content of the tag if available,
        /// the name of linked entity when using internal <see cref="IMarkupProvider.Link(string,net.adamec.dev.markupdoc.CodeModel.Member)"/>
        /// or the <c>cref</c> without the leading type information when rendering <see cref="IMarkupProvider.ExternalLink"/>.
        /// When the link is not constructed ("target unknown"), the <c>cref</c>  value without the leading type information is rendered in italic
        /// </para>
        /// </remarks>
        /// <param name="markupProvider"><see cref="IMarkupProvider"/> allowing using the markup within the rendered content</param>
        /// <param name="member">Code model <see cref="Member"/> to render the XML Documentation Comment for</param>
        /// <param name="trim">Flag whether to (full) trim the rendered content</param>
        /// <returns>Rendered content of element of XML Documentation Comments</returns>
        ///<seealso cref="MsApiDocEngine"/>
        /// <seealso cref="MsApiDocOptions"/>
        protected override string RenderElement(IMarkupProvider markupProvider, Member member, bool trim = true) //used  for links
        {
            // ReSharper disable once RedundantArgumentDefaultValue
            var content = base.RenderElement(markupProvider, member, true); //always trim content for links

            if (string.IsNullOrEmpty(Ref))
            {
                return(content);
            }

            //Return Ref to existing member as link, if available. If no content provided, use the member's name
            if (member.Root.AllMembersByDocId.TryGetValue(Ref, out var refMember))
            {
                return(markupProvider.Link(!string.IsNullOrEmpty(content) ? content : refMember.Name, refMember));
            }

            //Try to get the MS API link from reference
            var msLink = MsApiDocEngine.GetLink(Ref);

            //Got the MS link, so return external link
            if (msLink != null)
            {
                return(markupProvider.ExternalLink(!string.IsNullOrEmpty(content) ? content : Ref.Substring(2), msLink));
            }

            //No link, return content if available otherwise Ref without leading "ref type"
            return(!string.IsNullOrEmpty(content) ? content : markupProvider.Italic(Ref.Substring(2)));
        }
Esempio n. 3
0
        /// <summary>
        /// Runs the documentation building logic
        /// </summary>
        /// <param name="projectFile">Project file of C# project to build the documentation for</param>
        /// <returns>Async task</returns>
        public async Task RunAsync(string projectFile)
        {
            if (string.IsNullOrEmpty(projectFile))
            {
                throw new ArgumentNullException(nameof(projectFile));
            }
            if (!File.Exists(projectFile))
            {
                throw new ArgumentException($"Project file {projectFile} doesn't exist");
            }

            var projectDir = new FileInfo(projectFile).DirectoryName;

            if (projectDir == null)
            {
                throw new Exception($"Can't get the project directory from {projectFile}");
            }

            //Read MS API local documentation to get the links to MS API online documentation
            MsApiDocEngine.ReadLocalDoc();

            //Prepare add-ons
            var addOns = GetAddOns();

            //Build code model
            var root = await ModelBuilder.BuildFromProjectSourcesAsync(projectFile, addOns);

            //Prepare for the output
            var targetBase = OutputOptions.Target; //full name w/o extension

            if (string.IsNullOrEmpty(targetBase))
            {
                targetBase = Path.Combine(projectDir, "doc");                                   //if not set, proj dir will be used and file doc.html/doc.md
            }
            var targetDir      = new FileInfo(targetBase).DirectoryName;
            var targetFileBase = new FileInfo(targetBase).Name;

            if (OutputOptions.SplitNs)
            {
                root.ProcessingInfo.SplitFileType = SplitTypeEnum.Namespace;
            }
            if (OutputOptions.SplitType)
            {
                root.ProcessingInfo.SplitFileType = SplitTypeEnum.Type;
            }

            root.ProcessingInfo.BaseMainFile = targetFileBase;

            //Generate markup outputs
            if (OutputOptions.Markdown)
            {
                var writer = new MarkupGenerator(
                    // ReSharper disable once AssignNullToNotNullAttribute
                    Path.Combine(targetDir, $"{targetFileBase}.{OutputOptions.MarkdownExtension}"), root,
                    new MarkdownMarkupProvider(OutputOptions));
                await writer.WriteModelAsync(OutputOptions.Title);
            }

            if (OutputOptions.Html)
            {
                var writer = new MarkupGenerator(
                    // ReSharper disable once AssignNullToNotNullAttribute
                    Path.Combine(targetDir, $"{targetFileBase}.{OutputOptions.HtmlExtension}"), root,
                    new HtmlMarkupProvider(OutputOptions));

                await writer.WriteModelAsync(OutputOptions.Title);
            }
        }