From 1fa16845d9e48e78401b7f8015730a3f20b9ec3b Mon Sep 17 00:00:00 2001 From: Parham Date: Thu, 3 Aug 2023 14:40:05 +0330 Subject: [PATCH 1/2] FileConventions.Tests: add failing test Add failing test for WrapText function based on [1]. [1] https://github.com/nblockchain/conventions/issues/117 --- src/FileConventions.Test/WrapTextTests.fs | 22 ++++++++++++++++++++++ 1 file changed, 22 insertions(+) diff --git a/src/FileConventions.Test/WrapTextTests.fs b/src/FileConventions.Test/WrapTextTests.fs index 13d8431e..1e74ba21 100644 --- a/src/FileConventions.Test/WrapTextTests.fs +++ b/src/FileConventions.Test/WrapTextTests.fs @@ -107,3 +107,25 @@ let WrapTextTest5() = let expectedResult = text Assert.That(WrapText text characterCount, Is.EqualTo expectedResult) + +[] +let WrapTextTest6() = + let characterCount = 64 + + let commitMsg = + "foo: this is a header" + + Environment.NewLine + + Environment.NewLine + + "This is a body:" + + Environment.NewLine + + Environment.NewLine + + "```" + + Environment.NewLine + + "A code block that has two conditions, it has a very long line that exceeds the limit." + + Environment.NewLine + + Environment.NewLine + + "It also has multiple paragraphs." + + Environment.NewLine + + "```" + + Assert.That(WrapText commitMsg characterCount, Is.EqualTo commitMsg) From fc2c4d52d0658f1037a59e1aa38247187d94a70a Mon Sep 17 00:00:00 2001 From: Parham Date: Thu, 3 Aug 2023 16:44:41 +0330 Subject: [PATCH 2/2] FileConventions: fix WrapText function Ignore codeblocks while splitting the text into paragraphs because there might be a codeblock with multiple paragraphs. Fixes https://github.com/nblockchain/conventions/issues/117 --- src/FileConventions/Library.fs | 67 +++++++++++++++++++++++++++++++++- 1 file changed, 66 insertions(+), 1 deletion(-) diff --git a/src/FileConventions/Library.fs b/src/FileConventions/Library.fs index 6a5ea374..b85c6c23 100644 --- a/src/FileConventions/Library.fs +++ b/src/FileConventions/Library.fs @@ -244,9 +244,74 @@ let private WrapParagraph (text: string) (maxCharsPerLine: int) : string = processWords String.Empty String.Empty words +// This function will extract paragraphs and will ignore the paragraphs inside a +// code block. Each paragraph is determined by two consecutive new lines. +let ExtractParagraphs(text: string) = + let lines = text.Split Environment.NewLine |> Seq.toList + let codeBlockStartOrEndToken = "```" + + let rec processLines + (remainingLines: List) + (currentParagraph: List) + (paragraphs: List) + (insideCodeBlock: bool) + = + // process each line individually and form paragraphs + match remainingLines with + | [] -> + if not currentParagraph.IsEmpty then + String.Join(Environment.NewLine, List.rev currentParagraph) + :: paragraphs + else + paragraphs + | line :: rest -> + if String.IsNullOrWhiteSpace line then + // a new paragraph has been detected, if it's inside code block + // add to the previous paragraph. Otherwise, join the previous + // paragraph to a string and start a new paragraph + if insideCodeBlock then + processLines + rest + (line :: currentParagraph) + paragraphs + insideCodeBlock + elif not currentParagraph.IsEmpty then + let newParagraph = + String.Join( + Environment.NewLine, + List.rev currentParagraph + ) + + processLines + rest + List.Empty + (newParagraph :: paragraphs) + insideCodeBlock + else + processLines rest List.Empty paragraphs insideCodeBlock + elif line.Trim().StartsWith codeBlockStartOrEndToken then + // start or end of a code block has been detected, the line will + // be added to the current paragraph and the state which determines + // if we're inside a code block or not is switched. + let newInsideCodeBlock = not insideCodeBlock + + processLines + rest + (line :: currentParagraph) + paragraphs + newInsideCodeBlock + else + processLines + rest + (line :: currentParagraph) + paragraphs + insideCodeBlock + + List.rev <| processLines lines List.Empty List.Empty false + let WrapText (text: string) (maxCharsPerLine: int) : string = let wrappedParagraphs = - text.Split $"{Environment.NewLine}{Environment.NewLine}" + ExtractParagraphs text |> Seq.map(fun paragraph -> WrapParagraph paragraph maxCharsPerLine) String.Join(