dotnet / roslynator

Roslynator is a set of code analysis tools for C#, powered by Roslyn.
https://josefpihrt.github.io/docs/roslynator
Other
3.07k stars 256 forks source link

generate-doc command tries to write newline characters into markdown table cell #1557

Open Roiskia opened 1 week ago

Roiskia commented 1 week ago

I used the generate-doc command and recieved an Cannot write newline characters in a table cell. error when the index files get generated.

roslynator version: 0.9.0.0

the command: roslynator generate-doc .\example.sln -o doc/ref --host docusaurus --heading "example" -v diag

It compiles the contained projects and starts to generate the documentation before emitting the following error. Using the host docusaurus or github manages to generate several index.md files before the error occures. Using the host sphinx failes before saving the first index.md.

Compiled solution 'C:\Users\user\source\example\example.sln' (in 290,4 s)
Relative path from root file to output directory is ''.
Generate documentation root to 'C:\Users\user\source\example\doc\ref\index.md'.
Documentation root successfully generated to 'C:\Users\user\source\example\doc\ref\index.md'.
Generate documentation to 'doc/ref'
(...)
System.AggregateException: One or more errors occurred. (Cannot write newline characters in a table cell.)
 ---> System.InvalidOperationException: Cannot write newline characters in a table cell.
   at DotMarkdown.MarkdownBaseWriter.<OnBeforeWriteLine>g__ThrowOnNewLineInTableCell|101_0()
   at DotMarkdown.MarkdownBaseWriter.OnBeforeWriteLine()
   at DotMarkdown.MarkdownBaseWriter.WriteLine()
   at Roslynator.Documentation.XmlExtensions.WriteContentTo(XElement element, DocumentationWriter writer, Boolean inlineOnly) in /_/src/Documentation/Extensions/XmlExtensions.cs:line 101
   at Roslynator.Documentation.DocumentationWriter.WriteTable(IEnumerable`1 symbols, String heading, Int32 headingLevel, String header1, String header2, SymbolDisplayFormat format, SymbolDisplayAdditionalMemberOptions additionalOptions, Boolean addLink, Boolean canIncludeInterfaceImplementation, INamedTypeSymbol containingType) in /_/src/Documentation/DocumentationWriter.cs:line 1470
   at Roslynator.Documentation.DocumentationGenerator.<>c__DisplayClass39_0.<GenerateNamespace>g__WriteTypes|1(IEnumerable`1 types, TypeKind typeKind, <>c__DisplayClass39_1&)
   at Roslynator.Documentation.DocumentationGenerator.GenerateNamespace(INamespaceSymbol namespaceSymbol, IEnumerable`1 types) in /_/src/Documentation/DocumentationGenerator.cs:line 399
   at Roslynator.Documentation.DocumentationGenerator.Generate(CancellationToken cancellationToken)+MoveNext() in /_/src/Documentation/DocumentationGenerator.cs:line 171
   at Roslynator.CommandLine.GenerateDocCommand.ExecuteAsync(ProjectOrSolution projectOrSolution, CancellationToken cancellationToken) in /_/src/CommandLine/Commands/GenerateDocCommand.cs:line 234
   at Roslynator.CommandLine.MSBuildWorkspaceCommand`1.ExecuteAsync(String path, MSBuildWorkspace workspace, CancellationToken cancellationToken) in /_/src/CommandLine/Commands/MSBuildWorkspaceCommand.cs:line 164
   at Roslynator.CommandLine.MSBuildWorkspaceCommand`1.ExecuteAsync(IEnumerable`1 paths, String msbuildPath, IEnumerable`1 properties) in /_/src/CommandLine/Commands/MSBuildWorkspaceCommand.cs:line 89
   at Roslynator.CommandLine.Program.GenerateDocAsync(GenerateDocCommandLineOptions options) in /_/src/CommandLine/Program.cs:line 738
   --- End of inner exception stack trace ---
   at System.Threading.Tasks.Task`1.GetResultCore(Boolean waitCompletionNotification)
   at Roslynator.CommandLine.Program.<>c.<Main>b__0_3(MSBuildCommandLineOptions options) in /_/src/CommandLine/Program.cs:line 181
   at CommandLine.ParserResultExtensions.MapResult[T1,T2,TResult](ParserResult`1 result, Func`2 parsedFunc1, Func`2 parsedFunc2, Func`2 notParsedFunc)
   at Roslynator.CommandLine.Program.Main(String[] args) in /_/src/CommandLine/Program.cs:line 169
josefpihrt commented 6 days ago

Hi,

I think I found the root cause. But it would be better if you can share the sample solution that can reproduce the error. If it's not possible, other option would be to clone Roslynator repo open CommandLine.sln, edit commandLineArgs in launchSettings.json, run it in debug mode and see the more details when it fails.

Roiskia commented 3 days ago

I updated to version 0.9.1.0 and retried the command. I got the same error again. As suggested, i proceeded with cloning the repository and ran roslynator in the debugger.

The issue seems to be an html linebreak tag <br/> in one of the summary tags to format the content. IntelliSense seems to respect html tags when rendering the tooltip of the symbol inside visual studio. This and other html tags (like unordered lists) are used all over the codebase inside the xml comments. They seem to be there to improve readability. Removing them wont be an option in my case (large proprietary project).

I am well aware that this is a "us" problem. As far as i am concerend this turnd into a feature request rather then a bug.

Would it be possible to make roslynator capable of handling this? I am not sure if there is a good solution for roslynator to handle arbitrary html tags inside the summary elements when their content has to be included inside markup tables. One way might be to omit the summary in the table, if an element is found, that would require a newline (or any other illegal charater) inside the table cell. Or remove any html tags from the source before writing to the table cell. Another option might be to use something else then tables to format the index.md files.

josefpihrt commented 3 days ago

@Roiskia Could you provide some xml doc comment from you project so I can reproduce it?

Roiskia commented 3 days ago

I was on the wrong tracks. It seems like the issue are para Tags, not br tags. Here is the simplest example that reproduces the error:

namespace Foo
{
    /// <summary>
    /// Lorem ipsum dolor sit amet.
    /// <para>
    /// consetetur sadipscing elitr.
    /// </para>
    /// </summary>
    public class Bar { }
}