From dcc61b8823b8d4d4c1c0f41ae357e8098b9f74e3 Mon Sep 17 00:00:00 2001 From: Yufei Huang Date: Sun, 9 Apr 2023 17:26:48 +0800 Subject: [PATCH] fix: xml entity escape in documentation comment (#8596) --- samples/seed/dotnet/project/Project/Class1.cs | 22 ++ .../Microsoft.DocAsCode.Dotnet.csproj | 1 + .../Parsers/XmlComment.cs | 97 +++++-- .../Parsers/XmlCommentParserContext.cs | 2 + .../Visitors/SymbolVisitorAdapter.cs | 9 +- .../XmlCommentUnitTest.cs | 26 +- ...FromProject.Class1.html.view.verified.json | 268 +++++++++++++++++- .../CatLibrary.Cat-2.html.view.verified.json | 4 +- ...rary.ICatExtension.html.view.verified.json | 2 +- .../api/CatLibrary.html.view.verified.json | 4 +- .../SamplesTest.Seed/index.verified.json | 2 +- .../SamplesTest.Seed/xrefmap.verified.yml | 26 ++ ...-BuildFromProject.Class1.html.verified.png | 4 +- ...-BuildFromProject.Class1.html.verified.png | 4 +- ...-BuildFromProject.Class1.html.verified.png | 4 +- ...BuildFromProject.Class1.html.verified.html | 68 ++++- 16 files changed, 488 insertions(+), 55 deletions(-) diff --git a/samples/seed/dotnet/project/Project/Class1.cs b/samples/seed/dotnet/project/Project/Class1.cs index 0c4b56a15fe..fbf4234f6c0 100644 --- a/samples/seed/dotnet/project/Project/Class1.cs +++ b/samples/seed/dotnet/project/Project/Class1.cs @@ -74,4 +74,26 @@ public void Issue4017() { } /// ``` /// public void Issue2623() { } + + /// + /// > [!NOTE] + /// > This is a <note>. & " ' + /// + /// [link](https://www.github.com "title") + /// + /// ```csharp + /// for (var i = 0; i > 10; i++) // & " ' + /// var range = new Range<int> { Min = 0, Max = 10 }; + /// ``` + /// + /// + /// var range = new Range<int> { Min = 0, Max = 10 }; + /// + /// + public void Issue2723() { } + + /// + /// @"\\?\" `@"\\?\"` + /// + public void Issue4392() { } } diff --git a/src/Microsoft.DocAsCode.Dotnet/Microsoft.DocAsCode.Dotnet.csproj b/src/Microsoft.DocAsCode.Dotnet/Microsoft.DocAsCode.Dotnet.csproj index 17b6e797631..167db2bbcd2 100644 --- a/src/Microsoft.DocAsCode.Dotnet/Microsoft.DocAsCode.Dotnet.csproj +++ b/src/Microsoft.DocAsCode.Dotnet/Microsoft.DocAsCode.Dotnet.csproj @@ -22,6 +22,7 @@ + diff --git a/src/Microsoft.DocAsCode.Dotnet/Parsers/XmlComment.cs b/src/Microsoft.DocAsCode.Dotnet/Parsers/XmlComment.cs index e75773cfda4..f96c5c28157 100644 --- a/src/Microsoft.DocAsCode.Dotnet/Parsers/XmlComment.cs +++ b/src/Microsoft.DocAsCode.Dotnet/Parsers/XmlComment.cs @@ -1,7 +1,6 @@ // Copyright (c) Microsoft. All rights reserved. // Licensed under the MIT license. See LICENSE file in the project root for full license information. -using System.Globalization; using System.Text; using System.Text.RegularExpressions; using System.Web; @@ -9,6 +8,12 @@ using System.Xml.Linq; using System.Xml.XPath; +using Markdig; +using Markdig.Helpers; +using Markdig.Renderers.Roundtrip; +using Markdig.Syntax; +using Markdig.Syntax.Inlines; + using Microsoft.DocAsCode.Common; using Microsoft.DocAsCode.Plugins; using Microsoft.DocAsCode.DataContracts.ManagedReference; @@ -484,7 +489,10 @@ private string GetXmlValue(XPathNavigator node) if (node is null) return null; - return TrimEachLine(GetInnerXml(node)); + if (_context.SkipMarkup) + return TrimEachLine(node.InnerXml); + + return GetInnerXmlAsMarkdown(TrimEachLine(node.InnerXml)); } private static string TrimEachLine(string text, string indent = "") @@ -535,40 +543,71 @@ private static string TrimEachLine(string text, string indent = "") return builder.ToString().TrimEnd(); } - /// - /// `>` is always encoded to `>` in XML, when triple-slash-comments is considered as Markdown content, `>` is considered as blockquote - /// Decode `>` to enable the Markdown syntax considering `>` is not a Must-Encode in Text XElement - /// - /// - /// - private static string GetInnerXml(XPathNavigator node) + private static string GetInnerXmlAsMarkdown(string xml) { - using var sw = new StringWriter(CultureInfo.InvariantCulture); - using (var tw = new XmlWriterWithGtDecoded(sw)) + if (!xml.Contains('&')) + return xml; + + xml = HandleBlockQuote(xml); + var markdown = Markdown.Parse(xml, trackTrivia: true); + DecodeMarkdownCode(markdown); + var sw = new StringWriter(); + var rr = new RoundtripRenderer(sw); + rr.Write(markdown); + return sw.ToString(); + + static string HandleBlockQuote(string xml) { - if (node.MoveToFirstChild()) - { - do - { - tw.WriteNode(node, true); - } while (node.MoveToNext()); - node.MoveToParent(); - } + // > is encoded to > in XML. When interpreted as markdown, > is as blockquote + // Decode standalone > to > to enable the block quote markdown syntax + return Regex.Replace(xml, @"^(\s*)>", "$1>", RegexOptions.Multiline); } - return sw.ToString(); - } - - private sealed class XmlWriterWithGtDecoded : XmlTextWriter - { - public XmlWriterWithGtDecoded(TextWriter tw) : base(tw) { } + static void DecodeMarkdownCode(MarkdownObject node) + { + // Commonmark: Entity and numeric character references are treated as literal text in code spans and code blocks + switch (node) + { + case CodeInline codeInline: + codeInline.Content = XmlDecode(codeInline.Content); + break; - public XmlWriterWithGtDecoded(Stream w, Encoding encoding) : base(w, encoding) { } + case CodeBlock codeBlock: + var lines = new StringLineGroup(codeBlock.Lines.Count); + foreach (var line in codeBlock.Lines.Lines) + { + var newLine = line; + newLine.Slice = new StringSlice(XmlDecode(line.Slice.ToString()), line.Slice.NewLine); + lines.Add(newLine); + } + codeBlock.Lines = lines; + break; + + case ContainerBlock containerBlock: + foreach (var child in containerBlock) + DecodeMarkdownCode(child); + break; + + case ContainerInline containerInline: + foreach (var child in containerInline) + DecodeMarkdownCode(child); + break; + + case LeafBlock leafBlock when leafBlock.Inline is not null: + foreach (var child in leafBlock.Inline) + DecodeMarkdownCode(child); + break; + } + } - public override void WriteString(string text) + static string XmlDecode(string xml) { - var encoded = text.Replace("&", "&").Replace("<", "<").Replace("'", "'").Replace("\"", """); - WriteRaw(encoded); + return xml + .Replace(">", ">") + .Replace("<", "<") + .Replace("&", "&") + .Replace(""", "\"") + .Replace("'", "'"); } } } diff --git a/src/Microsoft.DocAsCode.Dotnet/Parsers/XmlCommentParserContext.cs b/src/Microsoft.DocAsCode.Dotnet/Parsers/XmlCommentParserContext.cs index 7457bea0710..957c4beeb25 100644 --- a/src/Microsoft.DocAsCode.Dotnet/Parsers/XmlCommentParserContext.cs +++ b/src/Microsoft.DocAsCode.Dotnet/Parsers/XmlCommentParserContext.cs @@ -7,6 +7,8 @@ namespace Microsoft.DocAsCode.Dotnet; internal class XmlCommentParserContext { + public bool SkipMarkup { get; init; } + public Action AddReferenceDelegate { get; init; } public Func ResolveCode { get; init; } diff --git a/src/Microsoft.DocAsCode.Dotnet/Visitors/SymbolVisitorAdapter.cs b/src/Microsoft.DocAsCode.Dotnet/Visitors/SymbolVisitorAdapter.cs index 2d8226355c0..699f51a4df0 100644 --- a/src/Microsoft.DocAsCode.Dotnet/Visitors/SymbolVisitorAdapter.cs +++ b/src/Microsoft.DocAsCode.Dotnet/Visitors/SymbolVisitorAdapter.cs @@ -22,16 +22,16 @@ internal class SymbolVisitorAdapter : SymbolVisitor private readonly YamlModelGenerator _generator; private readonly Dictionary _references = new(); private readonly IMethodSymbol[] _extensionMethods; - private readonly string _codeSourceBasePath; + private readonly ExtractMetadataConfig _config; private readonly SymbolFilter _filter; - public SymbolVisitorAdapter(Compilation compilation, YamlModelGenerator generator, ExtractMetadataConfig options, SymbolFilter filter, IMethodSymbol[] extensionMethods) + public SymbolVisitorAdapter(Compilation compilation, YamlModelGenerator generator, ExtractMetadataConfig config, SymbolFilter filter, IMethodSymbol[] extensionMethods) { _compilation = compilation; _generator = generator; _filter = filter; + _config = config; _extensionMethods = extensionMethods?.Where(_filter.IncludeApi).ToArray() ?? Array.Empty(); - _codeSourceBasePath = options.CodeSourceBasePath; } public override MetadataItem DefaultVisit(ISymbol symbol) @@ -728,6 +728,7 @@ private XmlCommentParserContext GetXmlCommentParserContext(MetadataItem item) { return new XmlCommentParserContext { + SkipMarkup = _config.ShouldSkipMarkup, AddReferenceDelegate = AddReferenceDelegate, Source = item.Source, ResolveCode = ResolveCode, @@ -747,7 +748,7 @@ void AddReferenceDelegate(string id, string commentId) string ResolveCode(string source) { - var basePath = _codeSourceBasePath ?? ( + var basePath = _config.CodeSourceBasePath ?? ( item.Source?.Path is {} sourcePath ? Path.GetDirectoryName(Path.GetFullPath(Path.Combine(EnvironmentContext.BaseDirectory, sourcePath))) : null); diff --git a/test/Microsoft.DocAsCode.Dotnet.Tests/XmlCommentUnitTest.cs b/test/Microsoft.DocAsCode.Dotnet.Tests/XmlCommentUnitTest.cs index cbc89f40c9f..a8e13561ede 100644 --- a/test/Microsoft.DocAsCode.Dotnet.Tests/XmlCommentUnitTest.cs +++ b/test/Microsoft.DocAsCode.Dotnet.Tests/XmlCommentUnitTest.cs @@ -2,10 +2,7 @@ // Licensed under the MIT license. See LICENSE file in the project root for full license information. using System.Text.RegularExpressions; -using System.Xml.Linq; - using Microsoft.DocAsCode.DataContracts.Common; - using Xunit; namespace Microsoft.DocAsCode.Dotnet.Tests; @@ -142,9 +139,9 @@ public void ExternalCodeBlockXaml() Assert.Equal( """ This is an example using source reference in a xaml file. -
<Grid>
-              <TextBlock Text="Hello World" />
-            </Grid>
+
<Grid>
+              <TextBlock Text="Hello World" />
+            </Grid>
""", commentModel.Examples.Single(), ignoreLineEndingDifferences: true); @@ -168,6 +165,13 @@ public int Main(string[] args) { Console.HelloWorld(); } + + ```js + function main() + { + return 0 + } + ``` """); @@ -185,6 +189,13 @@ public int Main(string[] args) { Console.HelloWorld(); } + + ```js + function main() + { + return 0 + } + ``` """, comment.Remarks, ignoreLineEndingDifferences: true); } @@ -304,7 +315,7 @@ Classes in assemblies are by definition complete.
public class XmlElement
                             : XmlLinkedNode
  1. - word inside list->listItem->list->listItem->para.> + word inside list->listItem->list->listItem->para.> the second line.
  2. item2 in numbered list
  • item2 in bullet list
  • @@ -362,7 +373,6 @@ Check empty code. public void SeeAltText() { string input = """ - Class summary Exception type diff --git a/test/docfx.Snapshot.Tests/SamplesTest.Seed/api/BuildFromProject.Class1.html.view.verified.json b/test/docfx.Snapshot.Tests/SamplesTest.Seed/api/BuildFromProject.Class1.html.view.verified.json index a546bbe900f..ab3dc1d956b 100644 --- a/test/docfx.Snapshot.Tests/SamplesTest.Seed/api/BuildFromProject.Class1.html.view.verified.json +++ b/test/docfx.Snapshot.Tests/SamplesTest.Seed/api/BuildFromProject.Class1.html.view.verified.json @@ -322,6 +322,139 @@ "hideTitleType": false, "hideSubtitle": false }, + { + "uid": "BuildFromProject.Class1.Issue2723", + "isEii": false, + "isExtensionMethod": false, + "parent": "BuildFromProject.Class1", + "isExternal": false, + "name": [ + { + "lang": "csharp", + "value": "Issue2723()" + }, + { + "lang": "vb", + "value": "Issue2723()" + } + ], + "nameWithType": [ + { + "lang": "csharp", + "value": "Class1.Issue2723()" + }, + { + "lang": "vb", + "value": "Class1.Issue2723()" + } + ], + "fullName": [ + { + "lang": "csharp", + "value": "BuildFromProject.Class1.Issue2723()" + }, + { + "lang": "vb", + "value": "BuildFromProject.Class1.Issue2723()" + } + ], + "specName": [ + { + "lang": "csharp", + "value": "" + }, + { + "lang": "vb", + "value": "" + } + ], + "syntax": { + "content": [ + { + "lang": "csharp", + "value": "public void Issue2723()" + }, + { + "lang": "vb", + "value": "Public Sub Issue2723()" + } + ] + }, + "source": { + "remote": { + "path": "samples/seed/dotnet/project/Project/Class1.cs", + "branch": "main", + "repo": "https://github.com/dotnet/docfx" + }, + "id": "Issue2723", + "path": "dotnet/project/Project/Class1.cs", + "startLine": 92.0, + "endLine": 0.0, + "isExternal": false + }, + "assemblies": [ + "BuildFromProject" + ], + "namespace": "BuildFromProject", + "remarks": "
    \n
    Note
    \n

    This is a <note>. & " '

    \n
    \n

    link

    \n
    for (var i = 0; i > 10; i++) // & " '\nvar range = new Range<int> { Min = 0, Max = 10 };\n
    \n
    var range = new Range<int> { Min = 0, Max = 10 };
    \n", + "example": [], + "overload": { + "uid": "BuildFromProject.Class1.Issue2723*", + "name": [ + { + "lang": "csharp", + "value": "Issue2723" + }, + { + "lang": "vb", + "value": "Issue2723" + } + ], + "nameWithType": [ + { + "lang": "csharp", + "value": "Class1.Issue2723" + }, + { + "lang": "vb", + "value": "Class1.Issue2723" + } + ], + "fullName": [ + { + "lang": "csharp", + "value": "BuildFromProject.Class1.Issue2723" + }, + { + "lang": "vb", + "value": "BuildFromProject.Class1.Issue2723" + } + ], + "specName": [ + { + "lang": "csharp", + "value": "" + }, + { + "lang": "vb", + "value": "" + } + ], + "id": "BuildFromProject_Class1_Issue2723_" + }, + "level": 0.0, + "type": "method", + "summary": "", + "platform": null, + "docurl": "https://github.com/dotnet/docfx/new/main/apiSpec/new?filename=BuildFromProject_Class1_Issue2723.md&value=---%0Auid%3A%20BuildFromProject.Class1.Issue2723%0Asummary%3A%20'*You%20can%20override%20summary%20for%20the%20API%20here%20using%20*MARKDOWN*%20syntax'%0A---%0A%0A*Please%20type%20below%20more%20information%20about%20this%20API%3A*%0A%0A", + "sourceurl": "https://github.com/dotnet/docfx/blob/main/samples/seed/dotnet/project/Project/Class1.cs/#L93", + "conceptual": "", + "implements": "", + "seealso": null, + "id": "BuildFromProject_Class1_Issue2723", + "hideTitleType": false, + "hideSubtitle": false + }, { "uid": "BuildFromProject.Class1.Issue4017", "isEii": false, @@ -398,7 +531,7 @@ "namespace": "BuildFromProject", "remarks": "
    void Update()\n{\n    myClass.Execute();\n}
    \n", "example": [ - "
    public void HookMessageDeleted(BaseSocketClient client)\n{\n    client.MessageDeleted += HandleMessageDelete;\n}\n\npublic Task HandleMessageDelete(Cacheable<IMessage, ulong> cachedMessage, ISocketMessageChannel channel)\n{\n    // check if the message exists in cache; if not, we cannot report what was removed\n    if (!cachedMessage.HasValue) return;\n    var message = cachedMessage.Value;\n    Console.WriteLine($"A message ({message.Id}) from {message.Author} was removed from the channel {channel.Name} ({channel.Id}):"\n        + Environment.NewLine\n        + message.Content);\n    return Task.CompletedTask;\n}
    \n" + "
    public void HookMessageDeleted(BaseSocketClient client)\n{\n    client.MessageDeleted += HandleMessageDelete;\n}\n\npublic Task HandleMessageDelete(Cacheable<IMessage, ulong> cachedMessage, ISocketMessageChannel channel)\n{\n    // check if the message exists in cache; if not, we cannot report what was removed\n    if (!cachedMessage.HasValue) return;\n    var message = cachedMessage.Value;\n    Console.WriteLine($\"A message ({message.Id}) from {message.Author} was removed from the channel {channel.Name} ({channel.Id}):\"\n        + Environment.NewLine\n        + message.Content);\n    return Task.CompletedTask;\n}
    \n" ], "overload": { "uid": "BuildFromProject.Class1.Issue4017*", @@ -457,6 +590,139 @@ "hideTitleType": false, "hideSubtitle": false }, + { + "uid": "BuildFromProject.Class1.Issue4392", + "isEii": false, + "isExtensionMethod": false, + "parent": "BuildFromProject.Class1", + "isExternal": false, + "name": [ + { + "lang": "csharp", + "value": "Issue4392()" + }, + { + "lang": "vb", + "value": "Issue4392()" + } + ], + "nameWithType": [ + { + "lang": "csharp", + "value": "Class1.Issue4392()" + }, + { + "lang": "vb", + "value": "Class1.Issue4392()" + } + ], + "fullName": [ + { + "lang": "csharp", + "value": "BuildFromProject.Class1.Issue4392()" + }, + { + "lang": "vb", + "value": "BuildFromProject.Class1.Issue4392()" + } + ], + "specName": [ + { + "lang": "csharp", + "value": "" + }, + { + "lang": "vb", + "value": "" + } + ], + "syntax": { + "content": [ + { + "lang": "csharp", + "value": "public void Issue4392()" + }, + { + "lang": "vb", + "value": "Public Sub Issue4392()" + } + ] + }, + "source": { + "remote": { + "path": "samples/seed/dotnet/project/Project/Class1.cs", + "branch": "main", + "repo": "https://github.com/dotnet/docfx" + }, + "id": "Issue4392", + "path": "dotnet/project/Project/Class1.cs", + "startLine": 97.0, + "endLine": 0.0, + "isExternal": false + }, + "assemblies": [ + "BuildFromProject" + ], + "namespace": "BuildFromProject", + "remarks": "

    @"\\\\?\\"

    \n", + "example": [], + "overload": { + "uid": "BuildFromProject.Class1.Issue4392*", + "name": [ + { + "lang": "csharp", + "value": "Issue4392" + }, + { + "lang": "vb", + "value": "Issue4392" + } + ], + "nameWithType": [ + { + "lang": "csharp", + "value": "Class1.Issue4392" + }, + { + "lang": "vb", + "value": "Class1.Issue4392" + } + ], + "fullName": [ + { + "lang": "csharp", + "value": "BuildFromProject.Class1.Issue4392" + }, + { + "lang": "vb", + "value": "BuildFromProject.Class1.Issue4392" + } + ], + "specName": [ + { + "lang": "csharp", + "value": "" + }, + { + "lang": "vb", + "value": "" + } + ], + "id": "BuildFromProject_Class1_Issue4392_" + }, + "level": 0.0, + "type": "method", + "summary": "", + "platform": null, + "docurl": "https://github.com/dotnet/docfx/new/main/apiSpec/new?filename=BuildFromProject_Class1_Issue4392.md&value=---%0Auid%3A%20BuildFromProject.Class1.Issue4392%0Asummary%3A%20'*You%20can%20override%20summary%20for%20the%20API%20here%20using%20*MARKDOWN*%20syntax'%0A---%0A%0A*Please%20type%20below%20more%20information%20about%20this%20API%3A*%0A%0A", + "sourceurl": "https://github.com/dotnet/docfx/blob/main/samples/seed/dotnet/project/Project/Class1.cs/#L98", + "conceptual": "", + "implements": "", + "seealso": null, + "id": "BuildFromProject_Class1_Issue4392", + "hideTitleType": false, + "hideSubtitle": false + }, { "uid": "BuildFromProject.Class1.Issue7484", "isEii": false, diff --git a/test/docfx.Snapshot.Tests/SamplesTest.Seed/api/CatLibrary.Cat-2.html.view.verified.json b/test/docfx.Snapshot.Tests/SamplesTest.Seed/api/CatLibrary.Cat-2.html.view.verified.json index b57f986b1c1..a756927c713 100644 --- a/test/docfx.Snapshot.Tests/SamplesTest.Seed/api/CatLibrary.Cat-2.html.view.verified.json +++ b/test/docfx.Snapshot.Tests/SamplesTest.Seed/api/CatLibrary.Cat-2.html.view.verified.json @@ -3688,10 +3688,10 @@ ], "level": 0.0 }, - "summary": "

    Here's main class of this Demo.

    \n

    You can see mostly type of article within this class and you for more detail, please see the remarks.

    \n

    \n

    this class is a template class. It has two Generic parameter. they are: T and K.

    \n

    The extension method of this class can refer to class

    \n", + "summary": "

    Here's main class of this Demo.

    \n

    You can see mostly type of article within this class and you for more detail, please see the remarks.

    \n

    \n

    this class is a template class. It has two Generic parameter. they are: T and K.

    \n

    The extension method of this class can refer to class

    \n", "remarks": "

    THIS is remarks overridden in MARKDWON file

    \n", "example": [ - "

    Here's example of how to create an instance of this class. As T is limited with class and K is limited with struct.

    \n
    var a = new Cat(object, int)();\nint catNumber = new int();\nunsafe\n{\n    a.GetFeetLength(catNumber);\n}
    \n

    As you see, here we bring in pointer so we need to add unsafe keyword.

    \n" + "

    Here's example of how to create an instance of this class. As T is limited with class and K is limited with struct.

    \n
    var a = new Cat(object, int)();\nint catNumber = new int();\nunsafe\n{\n    a.GetFeetLength(catNumber);\n}
    \n

    As you see, here we bring in pointer so we need to add unsafe keyword.

    \n" ], "syntax": { "content": [ diff --git a/test/docfx.Snapshot.Tests/SamplesTest.Seed/api/CatLibrary.ICatExtension.html.view.verified.json b/test/docfx.Snapshot.Tests/SamplesTest.Seed/api/CatLibrary.ICatExtension.html.view.verified.json index 1b047589bb6..0831e74c409 100644 --- a/test/docfx.Snapshot.Tests/SamplesTest.Seed/api/CatLibrary.ICatExtension.html.view.verified.json +++ b/test/docfx.Snapshot.Tests/SamplesTest.Seed/api/CatLibrary.ICatExtension.html.view.verified.json @@ -611,7 +611,7 @@ ], "level": 0.0 }, - "summary": "

    It's the class that contains ICat interface's extension method.

    \n

    This class must be public and static.

    \n

    Also it shouldn't be a geneic class

    \n", + "summary": "

    It's the class that contains ICat interface's extension method.

    \n

    This class must be public and static.

    \n

    Also it shouldn't be a geneic class

    \n", "example": [], "syntax": { "content": [ diff --git a/test/docfx.Snapshot.Tests/SamplesTest.Seed/api/CatLibrary.html.view.verified.json b/test/docfx.Snapshot.Tests/SamplesTest.Seed/api/CatLibrary.html.view.verified.json index 177baa176f4..68daacf524e 100644 --- a/test/docfx.Snapshot.Tests/SamplesTest.Seed/api/CatLibrary.html.view.verified.json +++ b/test/docfx.Snapshot.Tests/SamplesTest.Seed/api/CatLibrary.html.view.verified.json @@ -120,7 +120,7 @@ } ], "level": 0.0, - "summary": "

    Here's main class of this Demo.

    \n

    You can see mostly type of article within this class and you for more detail, please see the remarks.

    \n

    \n

    this class is a template class. It has two Generic parameter. they are: T and K.

    \n

    The extension method of this class can refer to class

    \n", + "summary": "

    Here's main class of this Demo.

    \n

    You can see mostly type of article within this class and you for more detail, please see the remarks.

    \n

    \n

    this class is a template class. It has two Generic parameter. they are: T and K.

    \n

    The extension method of this class can refer to class

    \n", "type": "class", "platform": null, "isEii": false, @@ -301,7 +301,7 @@ } ], "level": 0.0, - "summary": "

    It's the class that contains ICat interface's extension method.

    \n

    This class must be public and static.

    \n

    Also it shouldn't be a geneic class

    \n", + "summary": "

    It's the class that contains ICat interface's extension method.

    \n

    This class must be public and static.

    \n

    Also it shouldn't be a geneic class

    \n", "type": "class", "platform": null, "isEii": false, diff --git a/test/docfx.Snapshot.Tests/SamplesTest.Seed/index.verified.json b/test/docfx.Snapshot.Tests/SamplesTest.Seed/index.verified.json index b27e3c9be97..ef4ba50d1e6 100644 --- a/test/docfx.Snapshot.Tests/SamplesTest.Seed/index.verified.json +++ b/test/docfx.Snapshot.Tests/SamplesTest.Seed/index.verified.json @@ -22,7 +22,7 @@ "api/BuildFromProject.Class1.html": { "href": "api/BuildFromProject.Class1.html", "title": "Class Class1 | docfx seed website", - "keywords": "Class Class1 Namespace BuildFromProject Assembly BuildFromProject.dll public class Class1 Inheritance object Class1 Inherited Members object.Equals(object) object.Equals(object, object) object.GetHashCode() object.GetType() object.MemberwiseClone() object.ReferenceEquals(object, object) object.ToString() Methods Issue1651() Pricing models are used to calculate theoretical option values 1Black Scholes 2Black76 3Black76Fut 4Equity Tree 5Variance Swap 6Dividend Forecast public void Issue1651() Issue2623() public void Issue2623() Examples MyClass myClass = new MyClass(); void Update() { myClass.Execute(); } Remarks For example: MyClass myClass = new MyClass(); void Update() { myClass.Execute(); } Issue4017() public void Issue4017() Examples public void HookMessageDeleted(BaseSocketClient client) { client.MessageDeleted += HandleMessageDelete; } public Task HandleMessageDelete(Cacheable cachedMessage, ISocketMessageChannel channel) { // check if the message exists in cache; if not, we cannot report what was removed if (!cachedMessage.HasValue) return; var message = cachedMessage.Value; Console.WriteLine($\"A message ({message.Id}) from {message.Author} was removed from the channel {channel.Name} ({channel.Id}):\" + Environment.NewLine + message.Content); return Task.CompletedTask; } Remarks void Update() { myClass.Execute(); } Issue7484() public void Issue7484() Remarks There's really no reason to not believe that this class can test things. Term Description A Term A Description Bee Term Bee Description Issue896() Test public void Issue896() See Also Class1.Test XmlCommentIncludeTag() This method should do something... public void XmlCommentIncludeTag() Remarks This is remarks." + "keywords": "Class Class1 Namespace BuildFromProject Assembly BuildFromProject.dll public class Class1 Inheritance object Class1 Inherited Members object.Equals(object) object.Equals(object, object) object.GetHashCode() object.GetType() object.MemberwiseClone() object.ReferenceEquals(object, object) object.ToString() Methods Issue1651() Pricing models are used to calculate theoretical option values 1Black Scholes 2Black76 3Black76Fut 4Equity Tree 5Variance Swap 6Dividend Forecast public void Issue1651() Issue2623() public void Issue2623() Examples MyClass myClass = new MyClass(); void Update() { myClass.Execute(); } Remarks For example: MyClass myClass = new MyClass(); void Update() { myClass.Execute(); } Issue2723() public void Issue2723() Remarks Note This is a . & \" ' link for (var i = 0; i > 10; i++) // & \" ' var range = new Range { Min = 0, Max = 10 }; var range = new Range { Min = 0, Max = 10 }; Issue4017() public void Issue4017() Examples public void HookMessageDeleted(BaseSocketClient client) { client.MessageDeleted += HandleMessageDelete; } public Task HandleMessageDelete(Cacheable cachedMessage, ISocketMessageChannel channel) { // check if the message exists in cache; if not, we cannot report what was removed if (!cachedMessage.HasValue) return; var message = cachedMessage.Value; Console.WriteLine($\"A message ({message.Id}) from {message.Author} was removed from the channel {channel.Name} ({channel.Id}):\" + Environment.NewLine + message.Content); return Task.CompletedTask; } Remarks void Update() { myClass.Execute(); } Issue4392() public void Issue4392() Remarks @\"\\\\?\\\" @\"\\\\?\\\" Issue7484() public void Issue7484() Remarks There's really no reason to not believe that this class can test things. Term Description A Term A Description Bee Term Bee Description Issue896() Test public void Issue896() See Also Class1.Test XmlCommentIncludeTag() This method should do something... public void XmlCommentIncludeTag() Remarks This is remarks." }, "api/BuildFromProject.Class1.Test-1.html": { "href": "api/BuildFromProject.Class1.Test-1.html", diff --git a/test/docfx.Snapshot.Tests/SamplesTest.Seed/xrefmap.verified.yml b/test/docfx.Snapshot.Tests/SamplesTest.Seed/xrefmap.verified.yml index b01eecd3b43..6ec3102199a 100644 --- a/test/docfx.Snapshot.Tests/SamplesTest.Seed/xrefmap.verified.yml +++ b/test/docfx.Snapshot.Tests/SamplesTest.Seed/xrefmap.verified.yml @@ -109,6 +109,19 @@ references: isSpec: "True" fullName: BuildFromProject.Class1.Issue2623 nameWithType: Class1.Issue2623 +- uid: BuildFromProject.Class1.Issue2723 + name: Issue2723() + href: api/BuildFromProject.Class1.html#BuildFromProject_Class1_Issue2723 + commentId: M:BuildFromProject.Class1.Issue2723 + fullName: BuildFromProject.Class1.Issue2723() + nameWithType: Class1.Issue2723() +- uid: BuildFromProject.Class1.Issue2723* + name: Issue2723 + href: api/BuildFromProject.Class1.html#BuildFromProject_Class1_Issue2723_ + commentId: Overload:BuildFromProject.Class1.Issue2723 + isSpec: "True" + fullName: BuildFromProject.Class1.Issue2723 + nameWithType: Class1.Issue2723 - uid: BuildFromProject.Class1.Issue4017 name: Issue4017() href: api/BuildFromProject.Class1.html#BuildFromProject_Class1_Issue4017 @@ -122,6 +135,19 @@ references: isSpec: "True" fullName: BuildFromProject.Class1.Issue4017 nameWithType: Class1.Issue4017 +- uid: BuildFromProject.Class1.Issue4392 + name: Issue4392() + href: api/BuildFromProject.Class1.html#BuildFromProject_Class1_Issue4392 + commentId: M:BuildFromProject.Class1.Issue4392 + fullName: BuildFromProject.Class1.Issue4392() + nameWithType: Class1.Issue4392() +- uid: BuildFromProject.Class1.Issue4392* + name: Issue4392 + href: api/BuildFromProject.Class1.html#BuildFromProject_Class1_Issue4392_ + commentId: Overload:BuildFromProject.Class1.Issue4392 + isSpec: "True" + fullName: BuildFromProject.Class1.Issue4392 + nameWithType: Class1.Issue4392 - uid: BuildFromProject.Class1.Issue7484 name: Issue7484() href: api/BuildFromProject.Class1.html#BuildFromProject_Class1_Issue7484 diff --git a/test/docfx.Snapshot.Tests/SamplesTest.SeedHtml/1152x648/api-BuildFromProject.Class1.html.verified.png b/test/docfx.Snapshot.Tests/SamplesTest.SeedHtml/1152x648/api-BuildFromProject.Class1.html.verified.png index cfa2d70cab7..225281ed54b 100644 --- a/test/docfx.Snapshot.Tests/SamplesTest.SeedHtml/1152x648/api-BuildFromProject.Class1.html.verified.png +++ b/test/docfx.Snapshot.Tests/SamplesTest.SeedHtml/1152x648/api-BuildFromProject.Class1.html.verified.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:e104571d26bc36b7efeb49f071af2a26d2ad42fca45509f8289c34a4b9614298 -size 122216 +oid sha256:cf05635bb1dce4d95a70d630f7f62d8996bb9f53aa70195f7b0d942a11a28fcb +size 125698 diff --git a/test/docfx.Snapshot.Tests/SamplesTest.SeedHtml/1920x1080/api-BuildFromProject.Class1.html.verified.png b/test/docfx.Snapshot.Tests/SamplesTest.SeedHtml/1920x1080/api-BuildFromProject.Class1.html.verified.png index 1b06a1f0e98..25722c8bf06 100644 --- a/test/docfx.Snapshot.Tests/SamplesTest.SeedHtml/1920x1080/api-BuildFromProject.Class1.html.verified.png +++ b/test/docfx.Snapshot.Tests/SamplesTest.SeedHtml/1920x1080/api-BuildFromProject.Class1.html.verified.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:e26820a026280c77355f767ca6c2c471a3fdbc1a8aefd7279ef045714ef84154 -size 365198 +oid sha256:8b6c571357aac8b5bbbd3cccd6703a05e2fad7a69e6108195c96dbc003ae811e +size 421182 diff --git a/test/docfx.Snapshot.Tests/SamplesTest.SeedHtml/375x812/api-BuildFromProject.Class1.html.verified.png b/test/docfx.Snapshot.Tests/SamplesTest.SeedHtml/375x812/api-BuildFromProject.Class1.html.verified.png index 799b6d2b716..decef6e9d5a 100644 --- a/test/docfx.Snapshot.Tests/SamplesTest.SeedHtml/375x812/api-BuildFromProject.Class1.html.verified.png +++ b/test/docfx.Snapshot.Tests/SamplesTest.SeedHtml/375x812/api-BuildFromProject.Class1.html.verified.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:27d48849df6281752a8243cef194a2c2349ed15bd7e0dcedcf38982f6da06612 -size 244647 +oid sha256:e0bf646ee2798a1f96a730ff6792e1794d77ea3ab2faaad50073afe0147362e7 +size 284094 diff --git a/test/docfx.Snapshot.Tests/SamplesTest.SeedHtml/html/api-BuildFromProject.Class1.html.verified.html b/test/docfx.Snapshot.Tests/SamplesTest.SeedHtml/html/api-BuildFromProject.Class1.html.verified.html index 4c3cc4d5006..a03a582de22 100644 --- a/test/docfx.Snapshot.Tests/SamplesTest.SeedHtml/html/api-BuildFromProject.Class1.html.verified.html +++ b/test/docfx.Snapshot.Tests/SamplesTest.SeedHtml/html/api-BuildFromProject.Class1.html.verified.html @@ -595,6 +595,43 @@

    Remarks + +

    + Issue2723() + +

    + +
    +
    + +
    +
    public void Issue2723()
    +
    + + + + + + + + + +

    Remarks

    +
    +
    Note
    +

    This is a <note>. & " '

    +
    +

    link

    +
    for (var i = 0; i > 10; i++) // & " '
    +var range = new Range<int> { Min = 0, Max = 10 };
    +
    +
    var range = new Range<int> { Min = 0, Max = 10 };
    +
    + + + +

    @@ -644,6 +681,35 @@

    Remarks + +

    + Issue4392() + +

    + +
    +
    + +
    +
    public void Issue4392()
    +
    + + + + + + + + + +

    Remarks

    +

    @"\\?\" @"\\?\"

    +
    + + + +

    @@ -750,7 +816,7 @@

    Re