From 5a924f9374529ab43364c21c8dbbd5b5b7c31fe3 Mon Sep 17 00:00:00 2001 From: Parham Date: Thu, 3 Aug 2023 16:44:41 +0330 Subject: [PATCH] FileConventions: fix WrapText function Split paragraph based on codeblock positions so that codeblocks with two lines, are not broken into multiple paragraphs. Fixes https://github.com/nblockchain/conventions/issues/117 --- src/FileConventions/Library.fs | 48 ++++++++++++++++++++++++++++++++-- 1 file changed, 46 insertions(+), 2 deletions(-) diff --git a/src/FileConventions/Library.fs b/src/FileConventions/Library.fs index 6a5ea3748..878657dd4 100644 --- a/src/FileConventions/Library.fs +++ b/src/FileConventions/Library.fs @@ -244,11 +244,55 @@ let private WrapParagraph (text: string) (maxCharsPerLine: int) : string = processWords String.Empty String.Empty words +let rec ExtractParagraphs (text: string) : List = + let codeBlockParagraphRegex = "(\s*)(```[\s\S]*```)(\s*)" + let matchedRegex = Regex.Match(text, codeBlockParagraphRegex) + let twoNewLines = $"{Environment.NewLine}{Environment.NewLine}" + + if matchedRegex.Success then + let preWhiteSpaceGroup = matchedRegex.Groups[1] + let postWhiteSpaceGroup = matchedRegex.Groups[3] + + let beforeMatch = text.Substring(0, matchedRegex.Index) + let afterMatch = text.Substring(matchedRegex.Index + matchedRegex.Length) + + let paragraphsBeforeMatch = ExtractParagraphs beforeMatch + let paragraphsAfterMatch = ExtractParagraphs afterMatch + + if preWhiteSpaceGroup.Value.Contains(twoNewLines) && postWhiteSpaceGroup.Value.Contains(twoNewLines) then + paragraphsBeforeMatch @ (List.singleton matchedRegex.Value) @ paragraphsAfterMatch + elif preWhiteSpaceGroup.Value.Contains(twoNewLines) then + match paragraphsAfterMatch with + | [] -> + paragraphsBeforeMatch @ (List.singleton matchedRegex.Value) + | head::tail -> + paragraphsBeforeMatch @ List.singleton (matchedRegex.Value + postWhiteSpaceGroup.Value + head) @ tail + elif postWhiteSpaceGroup.Value.Contains(twoNewLines) then + match List.rev paragraphsBeforeMatch with + | [] -> + (List.singleton matchedRegex.Value) @ paragraphsAfterMatch + | head::tail -> + List.rev tail @ List.singleton (head + preWhiteSpaceGroup.Value + matchedRegex.Value) @ paragraphsAfterMatch + else + match List.rev paragraphsBeforeMatch, paragraphsAfterMatch with + | [], [] -> + List.singleton matchedRegex.Value + | headPre::tailPre, [] -> + List.rev tailPre @ List.singleton (headPre + preWhiteSpaceGroup.Value + matchedRegex.Value) + | [], headPost::tailPost -> + List.singleton (matchedRegex.Value + postWhiteSpaceGroup.Value + headPost) @ tailPost + | headPre::tailPre, headPost::tailPost -> + List.rev tailPre @ List.singleton (headPre + preWhiteSpaceGroup.Value + matchedRegex.Value + postWhiteSpaceGroup.Value + headPost) @ tailPost + elif String.IsNullOrEmpty(text) then + List.Empty + else + text.Split $"{Environment.NewLine}{Environment.NewLine}" + |> Seq.toList + 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( $"{Environment.NewLine}{Environment.NewLine}", wrappedParagraphs