Skip to content

Commit 842204c

Browse files
authored
Ensure <para> items are ported (#165)
* Preserve <para></para> * Fix newline handling in XML, something changed. * Add test to confirm <para> items are ported.
1 parent 2070c3d commit 842204c

File tree

7 files changed

+97
-35
lines changed

7 files changed

+97
-35
lines changed

src/PortToDocs/src/libraries/Configuration.cs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@ namespace ApiDocsSync.PortToDocs
99
{
1010
public class Configuration
1111
{
12+
public const string NewLine = "\n";
1213
private static readonly char Separator = ',';
1314

1415
private enum Mode

src/PortToDocs/src/libraries/Docs/DocsCommentsContainer.cs

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
// Licensed to the .NET Foundation under one or more agreements.
1+
// Licensed to the .NET Foundation under one or more agreements.
22
// The .NET Foundation licenses this file to you under the MIT license.
33

44
using System;
@@ -45,7 +45,9 @@ public void SaveToDisk()
4545
Encoding = type.FileEncoding,
4646
OmitXmlDeclaration = true,
4747
Indent = true,
48-
CheckCharacters = false
48+
CheckCharacters = false,
49+
NewLineChars = Configuration.NewLine,
50+
NewLineHandling = NewLineHandling.Replace
4951
};
5052

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

5658
// Workaround to delete the annoying endline added by XmlWriter.Save
5759
string fileData = File.ReadAllText(type.FilePath);
58-
if (!fileData.EndsWith(Environment.NewLine))
60+
if (!fileData.EndsWith(Configuration.NewLine))
5961
{
60-
File.WriteAllText(type.FilePath, fileData + Environment.NewLine, type.FileEncoding);
62+
File.WriteAllText(type.FilePath, fileData + Configuration.NewLine, type.FileEncoding);
6163
}
6264

6365
Log.Success(" [Saved]");

src/PortToDocs/src/libraries/Docs/DocsException.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -35,7 +35,7 @@ public DocsException(IDocsAPI parentAPI, XElement xException)
3535

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

src/PortToDocs/src/libraries/ToDocsPorter.cs

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
// Licensed to the .NET Foundation under one or more agreements.
1+
// Licensed to the .NET Foundation under one or more agreements.
22
// The .NET Foundation licenses this file to you under the MIT license.
33

44
using System;
@@ -528,14 +528,14 @@ private MissingComments GetMissingCommentsForMemberFromInterface(MissingComments
528528
cleanedInterfaceRemarks += line;
529529
if (i < splitted.Length - 1)
530530
{
531-
cleanedInterfaceRemarks += Environment.NewLine;
531+
cleanedInterfaceRemarks += Configuration.NewLine;
532532
}
533533
}
534534
}
535535

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

540540
mc.IsEII = true;
541541
}

src/PortToDocs/src/libraries/XmlHelper.cs

Lines changed: 5 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -77,20 +77,13 @@ internal class XmlHelper
7777
{ "False ", "`false` " },
7878
{ "<c>", "`"},
7979
{ "</c>", "`"},
80-
{ "<para>", "" },
81-
{ "</para>", "\r\n\r\n" },
8280
{ "\" />", ">" },
8381
{ "<![CDATA[", "" },
8482
{ "]]>", "" },
8583
{ "<note type=\"inheritinfo\">", ""},
8684
{ "</note>", "" }
8785
};
8886

89-
private static readonly Dictionary<string, string> _replaceableExceptionPatterns = new Dictionary<string, string>{
90-
{ "<para>", "\r\n" },
91-
{ "</para>", "" }
92-
};
93-
9487
private static readonly Dictionary<string, string> _replaceableMarkdownRegexPatterns = new Dictionary<string, string> {
9588
// Replace primitives: https://docs.microsoft.com/en-us/dotnet/csharp/language-reference/builtin-types/built-in-types
9689
{ @"\<(see|seealso){1} cref\=""bool""[ ]*\/\>", "`bool`" },
@@ -200,12 +193,12 @@ public static string GetFormattedAsMarkdown(string value, bool isMember)
200193
string remarksTitle = string.Empty;
201194
if (!updatedValue.Contains("## Remarks"))
202195
{
203-
remarksTitle = "## Remarks\r\n\r\n";
196+
remarksTitle = "## Remarks\n\n";
204197
}
205198

206199
string spaces = isMember ? " " : " ";
207200

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

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

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

304297
return value.Trim();
305298
}
@@ -317,20 +310,8 @@ private static string ReplaceMarkdownPatterns(string value)
317310
return updatedValue;
318311
}
319312

320-
internal static string ReplaceExceptionPatterns(string value)
321-
{
322-
string updatedValue = value;
323-
foreach (KeyValuePair<string, string> kvp in _replaceableExceptionPatterns)
324-
{
325-
if (updatedValue.Contains(kvp.Key))
326-
{
327-
updatedValue = updatedValue.Replace(kvp.Key, kvp.Value);
328-
}
329-
}
330-
331-
updatedValue = Regex.Replace(updatedValue, @"[\r\n\t ]+\-[ ]?or[ ]?\-[\r\n\t ]+", "\r\n\r\n-or-\r\n\r\n");
332-
return updatedValue;
333-
}
313+
internal static string ReplaceExceptionPatterns(string value) =>
314+
Regex.Replace(value, @"[\r\n\t ]+\-[ ]?or[ ]?\-[\r\n\t ]+", "\n\n-or-\n\n");
334315

335316
private static string ReplaceNormalElementPatterns(string value)
336317
{

src/PortToDocs/tests/PortToDocs.Strings.Tests.cs

Lines changed: 54 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
// Licensed to the .NET Foundation under one or more agreements.
1+
// Licensed to the .NET Foundation under one or more agreements.
22
// The .NET Foundation licenses this file to you under the MIT license.
33

44
using System.Collections.Generic;
@@ -2119,6 +2119,59 @@ public void PartialInheritDoc_WithInterface()
21192119
TestWithStrings(intellisenseFile, docFiles, configuration);
21202120
}
21212121

2122+
[Fact]
2123+
public void Preserve_Para()
2124+
{
2125+
// Paragraphs are indicated with <para></para>. Ensure they are preserved.
2126+
2127+
string originalIntellisense = @"<?xml version=""1.0""?>
2128+
<doc>
2129+
<assembly>
2130+
<name>MyAssembly</name>
2131+
</assembly>
2132+
<members>
2133+
<member name=""T:MyNamespace.MyType"">
2134+
<summary><para>I am paragraph one.</para><para>I am paragraph number two.</para></summary>
2135+
</member>
2136+
</members>
2137+
</doc>";
2138+
2139+
string originalDocs = @"<Type Name=""MyType"" FullName=""MyNamespace.MyType"">
2140+
<TypeSignature Language=""DocId"" Value=""T:MyNamespace.MyType"" />
2141+
<AssemblyInfo>
2142+
<AssemblyName>MyAssembly</AssemblyName>
2143+
</AssemblyInfo>
2144+
<Docs>
2145+
<summary>To be added.</summary>
2146+
<remarks>To be added.</remarks>
2147+
</Docs>
2148+
<Members></Members>
2149+
</Type>";
2150+
2151+
string expectedDocs = @"<Type Name=""MyType"" FullName=""MyNamespace.MyType"">
2152+
<TypeSignature Language=""DocId"" Value=""T:MyNamespace.MyType"" />
2153+
<AssemblyInfo>
2154+
<AssemblyName>MyAssembly</AssemblyName>
2155+
</AssemblyInfo>
2156+
<Docs>
2157+
<summary>
2158+
<para>I am paragraph one.</para>
2159+
<para>I am paragraph number two.</para>
2160+
</summary>
2161+
<remarks>To be added.</remarks>
2162+
</Docs>
2163+
<Members></Members>
2164+
</Type>";
2165+
2166+
Configuration configuration = new()
2167+
{
2168+
MarkdownRemarks = true
2169+
};
2170+
configuration.IncludedAssemblies.Add(FileTestData.TestAssembly);
2171+
2172+
TestWithStrings(originalIntellisense, originalDocs, expectedDocs, configuration);
2173+
}
2174+
21222175
private static void TestWithStrings(string intellisenseFile, string originalDocsFile, string expectedDocsFile, Configuration configuration) =>
21232176
TestWithStrings(intellisenseFile, new List<StringTestData>() { new StringTestData(originalDocsFile, expectedDocsFile) }, configuration);
21242177

src/PortToDocs/tests/StringTestData.cs

Lines changed: 27 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,9 @@
1-
// Licensed to the .NET Foundation under one or more agreements.
1+
// Licensed to the .NET Foundation under one or more agreements.
22
// The .NET Foundation licenses this file to you under the MIT license.
33

4+
using System.IO;
5+
using System.Text;
6+
using System.Xml;
47
using System.Xml.Linq;
58

69
namespace ApiDocsSync.PortToDocs.Tests
@@ -17,6 +20,28 @@ public StringTestData(string original, string expected)
1720
public string Original { get; }
1821
public string Expected { get; }
1922
public XDocument XDoc { get; }
20-
public string Actual => XDoc.ToString();
23+
public string Actual
24+
{
25+
get
26+
{
27+
XmlWriterSettings xws = new()
28+
{
29+
Encoding = Encoding.UTF8,
30+
OmitXmlDeclaration = true,
31+
Indent = true,
32+
CheckCharacters = true,
33+
NewLineChars = Configuration.NewLine,
34+
NewLineHandling = NewLineHandling.Replace
35+
};
36+
using MemoryStream ms = new();
37+
using (XmlWriter xw = XmlWriter.Create(ms, xws))
38+
{
39+
XDoc.Save(xw);
40+
}
41+
ms.Position = 0;
42+
using StreamReader sr = new(ms, Encoding.UTF8, detectEncodingFromByteOrderMarks: true);
43+
return sr.ReadToEnd();
44+
}
45+
}
2146
}
2247
}

0 commit comments

Comments
 (0)