Skip to content

Commit

Permalink
fixed markdown special characters not escaped (fixes #117)
Browse files Browse the repository at this point in the history
fixed unhandled xml elements not rendering as is in markdown (fixes #126)
  • Loading branch information
Doraku committed Oct 12, 2024
1 parent 3ec6ac2 commit 2ff3a44
Show file tree
Hide file tree
Showing 67 changed files with 294 additions and 168 deletions.
4 changes: 3 additions & 1 deletion documentation/NEXT_RELEASENOTES.txt
Original file line number Diff line number Diff line change
Expand Up @@ -12,4 +12,6 @@
- fixed string and char const field definition
- fixed ExplicitInterfaceImplementationsSection config name (fixes #141)
- fixed StackOverflowException when using cyclic inheritdoc (fixes #142)
- fixed property getter/setter access modifier not taken into account (fixes #151)
- fixed property getter/setter access modifier not taken into account (fixes #151)
- fixed markdown special characters not escaped (fixes #117)
- fixed unhandled xml elements not rendering as is in markdown (fixes #126)
31 changes: 31 additions & 0 deletions source/DefaultDocumentation.Markdown/Elements/BrElement.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
using System;
using System.Xml.Linq;
using DefaultDocumentation.Api;

namespace DefaultDocumentation.Markdown.Elements;

/// <summary>
/// Handles <c>br</c> xml element.
/// </summary>
public sealed class BrElement : IElement
{
/// <summary>
/// The name of this implementation used at the configuration level.
/// </summary>
public const string ConfigName = "br";

/// <inheritdoc/>
public string Name => ConfigName;

/// <inheritdoc/>
public void Write(IWriter writer, XElement element)
{
writer.ThrowIfNull();
element.ThrowIfNull();

using (writer.AppendAsRaw())
{
writer.Append("<br/>");
}
}
}
11 changes: 7 additions & 4 deletions source/DefaultDocumentation.Markdown/Elements/CElement.cs
Original file line number Diff line number Diff line change
Expand Up @@ -23,9 +23,12 @@ public void Write(IWriter writer, XElement element)
writer.ThrowIfNull();
element.ThrowIfNull();

writer
.Append("`")
.Append(element.Value)
.Append("`");
using (writer.AppendAsRaw())
{
writer
.Append("`")
.Append(element.Value)
.Append("`");
}
}
}
20 changes: 11 additions & 9 deletions source/DefaultDocumentation.Markdown/Elements/CodeElement.cs
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,6 @@
using System.IO;
using System.Xml.Linq;
using DefaultDocumentation.Api;
using DefaultDocumentation.Markdown.Extensions;
using DefaultDocumentation.Markdown.Internal;

namespace DefaultDocumentation.Markdown.Elements;
Expand Down Expand Up @@ -59,13 +58,16 @@ public void Write(IWriter writer, XElement element)

string? source = element.GetSourceAttribute();

writer
.EnsureLineStartAndAppendLine()
.Append("```")
.AppendLine(element.GetLanguageAttribute() ?? "csharp")
.Append(source is null ? element : new XElement("code", GetCode(writer.Context.Settings, source, element.GetRegionAttribute())))
.TrimEnd(Environment.NewLine, " ")
.AppendLine()
.Append("```");
using (writer.AppendAsRaw())
{
writer
.EnsureLineStartAndAppendLine()
.Append("```")
.AppendLine(element.GetLanguageAttribute() ?? "csharp")
.Append(source is null ? element : new XElement("code", GetCode(writer.Context.Settings, source, element.GetRegionAttribute())))
.TrimEnd(Environment.NewLine, " ")
.AppendLine()
.Append("```");
}
}
}
24 changes: 13 additions & 11 deletions source/DefaultDocumentation.Markdown/Elements/ListElement.cs
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,6 @@
using System.Globalization;
using System.Xml.Linq;
using DefaultDocumentation.Api;
using DefaultDocumentation.Markdown.Extensions;

namespace DefaultDocumentation.Markdown.Elements;

Expand Down Expand Up @@ -127,19 +126,22 @@ public void Write(IWriter writer, XElement element)
return;
}

switch (element.GetTypeAttribute())
using (writer.AppendAsRaw())
{
case "bullet":
WriteBullet(writer, element);
break;
switch (element.GetTypeAttribute())
{
case "bullet":
WriteBullet(writer, element);
break;

case "number":
WriteNumber(writer, element);
break;
case "number":
WriteNumber(writer, element);
break;

case "table":
WriteTable(writer, element);
break;
case "table":
WriteTable(writer, element);
break;
}
}
}
}
24 changes: 13 additions & 11 deletions source/DefaultDocumentation.Markdown/Elements/NoteElement.cs
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,6 @@
using System.Globalization;
using System.Xml.Linq;
using DefaultDocumentation.Api;
using DefaultDocumentation.Markdown.Extensions;

namespace DefaultDocumentation.Markdown.Elements;

Expand Down Expand Up @@ -50,17 +49,20 @@ public void Write(IWriter writer, XElement element)
_ => string.Empty
};

writer.EnsureLineStart();

IWriter prefixedWriter = writer.ToPrefixedWriter("> ");
if (!string.IsNullOrEmpty(notePrefix))
using (writer.AppendAsRaw())
{
prefixedWriter
.Append("**")
.Append(notePrefix)
.AppendLine(":** ");
}
writer.EnsureLineStart();

prefixedWriter.AppendAsMarkdown(element);
IWriter prefixedWriter = writer.ToPrefixedWriter("> ");
if (!string.IsNullOrEmpty(notePrefix))
{
prefixedWriter
.Append("**")
.Append(notePrefix.SanitizeForMarkdown())
.AppendLine(":** ");
}

prefixedWriter.AppendAsMarkdown(element);
}
}
}
10 changes: 6 additions & 4 deletions source/DefaultDocumentation.Markdown/Elements/ParaElement.cs
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
using System.Xml.Linq;
using DefaultDocumentation.Api;
using DefaultDocumentation.Markdown.Extensions;

namespace DefaultDocumentation.Markdown.Elements;

Expand All @@ -20,8 +19,11 @@ public sealed class ParaElement : IElement
/// <inheritdoc/>
public void Write(IWriter writer, XElement element)
{
writer
.EnsureLineStartAndAppendLine()
.AppendAsMarkdown(element);
using (writer.AppendAsRaw())
{
writer
.EnsureLineStartAndAppendLine()
.AppendAsMarkdown(element);
}
}
}
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
using System;
using System.Xml.Linq;
using DefaultDocumentation.Api;
using DefaultDocumentation.Markdown.Extensions;
using DefaultDocumentation.Models;
using DefaultDocumentation.Models.Parameters;

Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
using System;
using System.Xml.Linq;
using DefaultDocumentation.Api;
using DefaultDocumentation.Markdown.Extensions;

namespace DefaultDocumentation.Markdown.Elements;

Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
using System;
using System.Xml.Linq;
using DefaultDocumentation.Api;
using DefaultDocumentation.Markdown.Extensions;
using DefaultDocumentation.Models;
using DefaultDocumentation.Models.Parameters;

Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
using System;
using System.Xml.Linq;
using DefaultDocumentation.Api;
using DefaultDocumentation.Markdown.Internal;
using DefaultDocumentation.Markdown.Writers;
using DefaultDocumentation.Models;
using DefaultDocumentation.Models.Parameters;
Expand All @@ -10,7 +10,7 @@
using ICSharpCode.Decompiler.TypeSystem;
using ICSharpCode.Decompiler.TypeSystem.Implementation;

namespace DefaultDocumentation.Markdown.Extensions;
namespace DefaultDocumentation.Api;

/// <summary>
/// Provides extension methods on the <see cref="IWriter"/> type.
Expand All @@ -27,6 +27,7 @@ public static class IWriterExtensions
private const string _currentItemKey = "Markdown.CurrentItem";
private const string _displayAsSingleLineKey = "Markdown.DisplayAsSingleLine";
private const string _handleLineBreakKey = "Markdown.HandleLineBreak";
private const string _renderAsRaw = "Markdown.RenderAsRaw";

/// <summary>
/// Gets the current item that is being processed by this <see cref="IWriter"/>.
Expand Down Expand Up @@ -119,6 +120,51 @@ public static IWriter SetHandleLineBreak(this IWriter writer, bool? value)
return writer;
}

/// <summary>
/// Gets whether the writer should append the next strings as is without sanitizing it.
/// This setting is used by the <see cref="MarkdownWriter"/> type.
/// </summary>
/// <param name="writer">The <see cref="IWriter"/> for which to get this setting.</param>
/// <returns>Whether strings should be sanitized.</returns>
public static bool GetRenderAsRaw(this IWriter writer)
{
writer.ThrowIfNull();

return writer.Context[_renderAsRaw] as bool? ?? false;
}

/// <summary>
/// Sets whether the writer should append the next strings as is without sanitizing it.
/// This setting is used by the <see cref="MarkdownWriter"/> type.
/// </summary>
/// <param name="writer">The <see cref="IWriter"/> for which to set this setting.</param>
/// <param name="value">Whether strings should be sanitized.</param>
/// <returns>The given <see cref="IWriter"/>.</returns>
public static IWriter SetRenderAsRaw(this IWriter writer, bool? value)
{
writer.ThrowIfNull();

writer.Context[_renderAsRaw] = value;

return writer;
}

/// <summary>
/// Append a string without sanitizing it for markdown regardless of the current <see cref="GetRenderAsRaw(IWriter)"/> value.
/// </summary>
/// <param name="writer">The <see cref="IWriter"/> to use.</param>
/// <returns>The given <see cref="IWriter"/>.</returns>
public static IDisposable AppendAsRaw(this IWriter writer)
{
writer.ThrowIfNull();

bool? previousRenderAsRaw = writer.GetRenderAsRaw();

writer.SetRenderAsRaw(true);

return new DisposableAction(() => writer.SetRenderAsRaw(previousRenderAsRaw));
}

/// <summary>
/// Append an url in the markdown format.
/// </summary>
Expand All @@ -131,20 +177,23 @@ public static IWriter AppendUrl(this IWriter writer, string? url, string? displa
{
writer.ThrowIfNull();

if (string.IsNullOrEmpty(url))
using (writer.AppendAsRaw())
{
writer.Append((displayedName ?? "").Prettify());
}
else
{
writer
.Append("[")
.Append((displayedName ?? url!).Prettify())
.Append("](")
.Append(url!)
.Append(" '")
.Append(tooltip ?? url!)
.Append("')");
if (string.IsNullOrEmpty(url))
{
writer.Append((displayedName ?? "").Prettify().SanitizeForMarkdown());
}
else
{
writer
.Append("[")
.Append((displayedName ?? url!).Prettify().SanitizeForMarkdown())
.Append("](")
.Append(url!)
.Append(" '")
.Append((tooltip ?? url!).SanitizeForMarkdown())
.Append("')");
}
}

return writer;
Expand Down
20 changes: 20 additions & 0 deletions source/DefaultDocumentation.Markdown/Internal/DisposableAction.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
using System;

namespace DefaultDocumentation.Markdown.Internal;

internal sealed class DisposableAction : IDisposable
{
private readonly Action _action;

public DisposableAction(Action action)
{
_action = action;
}

public void Dispose()
{
GC.SuppressFinalize(this);

_action();
}
}
Original file line number Diff line number Diff line change
@@ -1,7 +1,13 @@
namespace System;
using System.Text.RegularExpressions;

namespace System;

internal static class StringExtensions
{
private static readonly Regex _markdownSanitization = new(@"[\\\`\*_\{\}\[\]\<\>\(\)\#\+\-\.\!\|]", RegexOptions.Compiled);

public static string SanitizeForMarkdown(this string value) => _markdownSanitization.Replace(value, @"\$&");

public static string Prettify(this string value)
{
int genericIndex = value.IndexOf('`');
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,6 @@
using System.Linq;
using System.Xml.Linq;
using DefaultDocumentation.Api;
using DefaultDocumentation.Markdown.Extensions;
using DefaultDocumentation.Models;
using DefaultDocumentation.Models.Members;
using DefaultDocumentation.Models.Parameters;
Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
using System;
using System.Linq;
using DefaultDocumentation.Api;
using DefaultDocumentation.Markdown.Extensions;
using DefaultDocumentation.Models;
using DefaultDocumentation.Models.Members;
using DefaultDocumentation.Models.Parameters;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,6 @@
using System.Collections.Generic;
using System.Linq;
using DefaultDocumentation.Api;
using DefaultDocumentation.Markdown.Extensions;
using DefaultDocumentation.Models.Types;

namespace DefaultDocumentation.Markdown.Sections;
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
using DefaultDocumentation.Api;
using DefaultDocumentation.Markdown.Extensions;
using DefaultDocumentation.Models.Members;

namespace DefaultDocumentation.Markdown.Sections;
Expand Down
Loading

0 comments on commit 2ff3a44

Please sign in to comment.