Skip to content

Commit

Permalink
Ensure <para> items are ported (#165)
Browse files Browse the repository at this point in the history
* Preserve <para></para>

* Fix newline handling in XML, something changed.

* Add test to confirm <para> items are ported.
  • Loading branch information
carlossanlop committed Jul 26, 2023
1 parent 2070c3d commit 842204c
Show file tree
Hide file tree
Showing 7 changed files with 97 additions and 35 deletions.
1 change: 1 addition & 0 deletions src/PortToDocs/src/libraries/Configuration.cs
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ namespace ApiDocsSync.PortToDocs
{
public class Configuration
{
public const string NewLine = "\n";
private static readonly char Separator = ',';

private enum Mode
Expand Down
10 changes: 6 additions & 4 deletions src/PortToDocs/src/libraries/Docs/DocsCommentsContainer.cs
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
// Licensed to the .NET Foundation under one or more agreements.
// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the MIT license.

using System;
Expand Down Expand Up @@ -45,7 +45,9 @@ public void SaveToDisk()
Encoding = type.FileEncoding,
OmitXmlDeclaration = true,
Indent = true,
CheckCharacters = false
CheckCharacters = false,
NewLineChars = Configuration.NewLine,
NewLineHandling = NewLineHandling.Replace
};

using (XmlWriter xw = XmlWriter.Create(type.FilePath, xws))
Expand All @@ -55,9 +57,9 @@ public void SaveToDisk()

// Workaround to delete the annoying endline added by XmlWriter.Save
string fileData = File.ReadAllText(type.FilePath);
if (!fileData.EndsWith(Environment.NewLine))
if (!fileData.EndsWith(Configuration.NewLine))
{
File.WriteAllText(type.FilePath, fileData + Environment.NewLine, type.FileEncoding);
File.WriteAllText(type.FilePath, fileData + Configuration.NewLine, type.FileEncoding);
}

Log.Success(" [Saved]");
Expand Down
2 changes: 1 addition & 1 deletion src/PortToDocs/src/libraries/Docs/DocsException.cs
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,7 @@ public DocsException(IDocsAPI parentAPI, XElement xException)

public void AppendException(string toAppend)
{
XmlHelper.AppendFormattedAsXml(XEException, $"\r\n\r\n-or-\r\n\r\n{toAppend}", removeUndesiredEndlines: false);
XmlHelper.AppendFormattedAsXml(XEException, $"\n\n-or-\n\n{toAppend}", removeUndesiredEndlines: false);
ParentAPI.Changed = true;
}

Expand Down
6 changes: 3 additions & 3 deletions src/PortToDocs/src/libraries/ToDocsPorter.cs
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
// Licensed to the .NET Foundation under one or more agreements.
// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the MIT license.

using System;
Expand Down Expand Up @@ -528,14 +528,14 @@ private MissingComments GetMissingCommentsForMemberFromInterface(MissingComments
cleanedInterfaceRemarks += line;
if (i < splitted.Length - 1)
{
cleanedInterfaceRemarks += Environment.NewLine;
cleanedInterfaceRemarks += Configuration.NewLine;
}
}
}

// Only port the interface remarks if the user desired that
// Otherwise, always add the EII special message
mc.Remarks = eiiMessage + (!Config.SkipInterfaceRemarks ? Environment.NewLine + Environment.NewLine + cleanedInterfaceRemarks : string.Empty);
mc.Remarks = eiiMessage + (!Config.SkipInterfaceRemarks ? Configuration.NewLine + Configuration.NewLine + cleanedInterfaceRemarks : string.Empty);

mc.IsEII = true;
}
Expand Down
29 changes: 5 additions & 24 deletions src/PortToDocs/src/libraries/XmlHelper.cs
Original file line number Diff line number Diff line change
Expand Up @@ -77,20 +77,13 @@ internal class XmlHelper
{ "False ", "`false` " },
{ "<c>", "`"},
{ "</c>", "`"},
{ "<para>", "" },
{ "</para>", "\r\n\r\n" },
{ "\" />", ">" },
{ "<![CDATA[", "" },
{ "]]>", "" },
{ "<note type=\"inheritinfo\">", ""},
{ "</note>", "" }
};

private static readonly Dictionary<string, string> _replaceableExceptionPatterns = new Dictionary<string, string>{
{ "<para>", "\r\n" },
{ "</para>", "" }
};

private static readonly Dictionary<string, string> _replaceableMarkdownRegexPatterns = new Dictionary<string, string> {
// Replace primitives: https://docs.microsoft.com/en-us/dotnet/csharp/language-reference/builtin-types/built-in-types
{ @"\<(see|seealso){1} cref\=""bool""[ ]*\/\>", "`bool`" },
Expand Down Expand Up @@ -200,12 +193,12 @@ public static string GetFormattedAsMarkdown(string value, bool isMember)
string remarksTitle = string.Empty;
if (!updatedValue.Contains("## Remarks"))
{
remarksTitle = "## Remarks\r\n\r\n";
remarksTitle = "## Remarks\n\n";
}

string spaces = isMember ? " " : " ";

xeFormat.ReplaceAll(new XCData("\r\n\r\n" + remarksTitle + updatedValue + "\r\n\r\n" + spaces));
xeFormat.ReplaceAll(new XCData("\n\n" + remarksTitle + updatedValue + "\n\n" + spaces));

// Attribute at the end, otherwise it would be replaced by ReplaceAll
xeFormat.SetAttributeValue("type", "text/markdown");
Expand Down Expand Up @@ -299,7 +292,7 @@ public static void AddChildFormattedAsXml(XElement parent, XElement child, strin

private static string RemoveUndesiredEndlines(string value)
{
value = Regex.Replace(value, @"((?'undesiredEndlinePrefix'[^\.\:])(\r\n)+[ \t]*)", @"${undesiredEndlinePrefix} ");
value = Regex.Replace(value, @"((?'undesiredEndlinePrefix'[^\.\:])[\r\n]+[ \t]*)", @"${undesiredEndlinePrefix} ");

return value.Trim();
}
Expand All @@ -317,20 +310,8 @@ private static string ReplaceMarkdownPatterns(string value)
return updatedValue;
}

internal static string ReplaceExceptionPatterns(string value)
{
string updatedValue = value;
foreach (KeyValuePair<string, string> kvp in _replaceableExceptionPatterns)
{
if (updatedValue.Contains(kvp.Key))
{
updatedValue = updatedValue.Replace(kvp.Key, kvp.Value);
}
}

updatedValue = Regex.Replace(updatedValue, @"[\r\n\t ]+\-[ ]?or[ ]?\-[\r\n\t ]+", "\r\n\r\n-or-\r\n\r\n");
return updatedValue;
}
internal static string ReplaceExceptionPatterns(string value) =>
Regex.Replace(value, @"[\r\n\t ]+\-[ ]?or[ ]?\-[\r\n\t ]+", "\n\n-or-\n\n");

private static string ReplaceNormalElementPatterns(string value)
{
Expand Down
55 changes: 54 additions & 1 deletion src/PortToDocs/tests/PortToDocs.Strings.Tests.cs
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
// Licensed to the .NET Foundation under one or more agreements.
// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the MIT license.

using System.Collections.Generic;
Expand Down Expand Up @@ -2119,6 +2119,59 @@ public void PartialInheritDoc_WithInterface()
TestWithStrings(intellisenseFile, docFiles, configuration);
}

[Fact]
public void Preserve_Para()
{
// Paragraphs are indicated with <para></para>. Ensure they are preserved.

string originalIntellisense = @"<?xml version=""1.0""?>
<doc>
<assembly>
<name>MyAssembly</name>
</assembly>
<members>
<member name=""T:MyNamespace.MyType"">
<summary><para>I am paragraph one.</para><para>I am paragraph number two.</para></summary>
</member>
</members>
</doc>";

string originalDocs = @"<Type Name=""MyType"" FullName=""MyNamespace.MyType"">
<TypeSignature Language=""DocId"" Value=""T:MyNamespace.MyType"" />
<AssemblyInfo>
<AssemblyName>MyAssembly</AssemblyName>
</AssemblyInfo>
<Docs>
<summary>To be added.</summary>
<remarks>To be added.</remarks>
</Docs>
<Members></Members>
</Type>";

string expectedDocs = @"<Type Name=""MyType"" FullName=""MyNamespace.MyType"">
<TypeSignature Language=""DocId"" Value=""T:MyNamespace.MyType"" />
<AssemblyInfo>
<AssemblyName>MyAssembly</AssemblyName>
</AssemblyInfo>
<Docs>
<summary>
<para>I am paragraph one.</para>
<para>I am paragraph number two.</para>
</summary>
<remarks>To be added.</remarks>
</Docs>
<Members></Members>
</Type>";

Configuration configuration = new()
{
MarkdownRemarks = true
};
configuration.IncludedAssemblies.Add(FileTestData.TestAssembly);

TestWithStrings(originalIntellisense, originalDocs, expectedDocs, configuration);
}

private static void TestWithStrings(string intellisenseFile, string originalDocsFile, string expectedDocsFile, Configuration configuration) =>
TestWithStrings(intellisenseFile, new List<StringTestData>() { new StringTestData(originalDocsFile, expectedDocsFile) }, configuration);

Expand Down
29 changes: 27 additions & 2 deletions src/PortToDocs/tests/StringTestData.cs
Original file line number Diff line number Diff line change
@@ -1,6 +1,9 @@
// Licensed to the .NET Foundation under one or more agreements.
// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the MIT license.

using System.IO;
using System.Text;
using System.Xml;
using System.Xml.Linq;

namespace ApiDocsSync.PortToDocs.Tests
Expand All @@ -17,6 +20,28 @@ public StringTestData(string original, string expected)
public string Original { get; }
public string Expected { get; }
public XDocument XDoc { get; }
public string Actual => XDoc.ToString();
public string Actual
{
get
{
XmlWriterSettings xws = new()
{
Encoding = Encoding.UTF8,
OmitXmlDeclaration = true,
Indent = true,
CheckCharacters = true,
NewLineChars = Configuration.NewLine,
NewLineHandling = NewLineHandling.Replace
};
using MemoryStream ms = new();
using (XmlWriter xw = XmlWriter.Create(ms, xws))
{
XDoc.Save(xw);
}
ms.Position = 0;
using StreamReader sr = new(ms, Encoding.UTF8, detectEncodingFromByteOrderMarks: true);
return sr.ReadToEnd();
}
}
}
}

0 comments on commit 842204c

Please sign in to comment.