From e8f5ae462ae5299ef73f881a250fb50846e3fbb9 Mon Sep 17 00:00:00 2001 From: Fredi Kats Date: Fri, 17 May 2024 21:28:49 +0200 Subject: [PATCH] Support zone section in learn docs --- .../MsLearnDocumentationParser.cs | 4 ++ .../MsLearnDocumentationPreprocessor.cs | 62 +++++++++++++++++++ .../MsLearnDocumentationPreprocessorTests.cs | 35 +++++++++++ 3 files changed, 101 insertions(+) create mode 100644 Sources/Kysect.Configuin.MsLearn/MsLearnDocumentationPreprocessor.cs create mode 100644 Sources/Kysect.Configuin.Tests/MsLearnDocumentation/MsLearnDocumentationPreprocessorTests.cs diff --git a/Sources/Kysect.Configuin.MsLearn/MsLearnDocumentationParser.cs b/Sources/Kysect.Configuin.MsLearn/MsLearnDocumentationParser.cs index 4f90bb6..e264d78 100644 --- a/Sources/Kysect.Configuin.MsLearn/MsLearnDocumentationParser.cs +++ b/Sources/Kysect.Configuin.MsLearn/MsLearnDocumentationParser.cs @@ -20,6 +20,7 @@ public class MsLearnDocumentationParser : IMsLearnDocumentationParser private readonly MarkdownTableParser _markdownTableParser; private readonly MsLearnTableParser _msLearnTableParser; private readonly IMarkdownTextExtractor _textExtractor; + private readonly MsLearnDocumentationPreprocessor _documentationPreprocessor; public MsLearnDocumentationParser(IMarkdownTextExtractor textExtractor, ILogger logger) { @@ -28,12 +29,15 @@ public MsLearnDocumentationParser(IMarkdownTextExtractor textExtractor, ILogger _markdownTableParser = new MarkdownTableParser(textExtractor); _msLearnTableParser = new MsLearnTableParser(); + _documentationPreprocessor = new MsLearnDocumentationPreprocessor(); } public RoslynRules Parse(MsLearnDocumentationRawInfo rawInfo) { ArgumentNullException.ThrowIfNull(rawInfo); + rawInfo = _documentationPreprocessor.Process(rawInfo); + _logger.LogInformation("Parsing roslyn rules from MS Learn"); var roslynQualityRules = rawInfo.QualityRuleFileContents.SelectMany(ParseQualityRules).ToList(); diff --git a/Sources/Kysect.Configuin.MsLearn/MsLearnDocumentationPreprocessor.cs b/Sources/Kysect.Configuin.MsLearn/MsLearnDocumentationPreprocessor.cs new file mode 100644 index 0000000..a2acf3c --- /dev/null +++ b/Sources/Kysect.Configuin.MsLearn/MsLearnDocumentationPreprocessor.cs @@ -0,0 +1,62 @@ +using Kysect.CommonLib.BaseTypes.Extensions; +using Kysect.Configuin.MsLearn.Models; + +namespace Kysect.Configuin.MsLearn; + +public class MsLearnDocumentationPreprocessor +{ + public MsLearnDocumentationRawInfo Process(MsLearnDocumentationRawInfo info) + { + return new MsLearnDocumentationRawInfo( + info.QualityRuleFileContents.Select(Process).ToList(), + info.StyleRuleFileContents.Select(Process).ToList(), + Process(info.SharpFormattingOptionsContent), + Process(info.DotnetFormattingOptionsContent)); + } + + public string Process(string input) + { + input.ThrowIfNull(); + + // TODO: remove this hack + input = input + .Replace("\r\n", "\n") + .Replace("\n", Environment.NewLine); + + List lines = input.Split(Environment.NewLine).ToList(); + + lines = RemoveZones(lines); + + return string.Join(Environment.NewLine, lines); + } + + private List RemoveZones(List lines) + { + // TODO: Performance is not so good + while (lines.Any(l => l.StartsWith(":::zone "))) + { + int startIndex = lines.FindIndex(l => l.StartsWith(":::zone ")); + int endIndex = lines.FindIndex(l => l.StartsWith(":::zone-end")); + + if (startIndex == -1 || endIndex == -1 || startIndex >= endIndex) + throw new ArgumentException("Cannot find zones for removing"); + + if (lines[startIndex].StartsWith(":::zone pivot=\"lang-csharp-vb\"")) + { + lines.RemoveAt(endIndex); + lines.RemoveAt(startIndex); + continue; + } + + if (lines[startIndex].StartsWith(":::zone pivot=\"lang-fsharp\"")) + { + lines.RemoveRange(startIndex, endIndex - startIndex + 1); + continue; + } + + throw new ArgumentException($"Unsupported zone {lines[startIndex]}"); + } + + return lines; + } +} \ No newline at end of file diff --git a/Sources/Kysect.Configuin.Tests/MsLearnDocumentation/MsLearnDocumentationPreprocessorTests.cs b/Sources/Kysect.Configuin.Tests/MsLearnDocumentation/MsLearnDocumentationPreprocessorTests.cs new file mode 100644 index 0000000..943acd3 --- /dev/null +++ b/Sources/Kysect.Configuin.Tests/MsLearnDocumentation/MsLearnDocumentationPreprocessorTests.cs @@ -0,0 +1,35 @@ +using Kysect.Configuin.MsLearn; + +namespace Kysect.Configuin.Tests.MsLearnDocumentation; + +public class MsLearnDocumentationPreprocessorTests +{ + private readonly MsLearnDocumentationPreprocessor _preprocessor = new MsLearnDocumentationPreprocessor(); + + [Fact] + public void Process_InputWithZones_RemoveOnlyFsharpBlock() + { + var input = """ + first line + :::zone pivot="lang-csharp-vb" + second line + :::zone-end + third line + :::zone pivot="lang-fsharp" + fourth line + :::zone-end + fifth line + """; + + var expected = """ + first line + second line + third line + fifth line + """; + + string actual = _preprocessor.Process(input); + + actual.Should().Be(expected); + } +} \ No newline at end of file