Skip to content

Commit

Permalink
FileConventions: fix WrapText function
Browse files Browse the repository at this point in the history
Ignore codeblocks while splitting the text into paragraphs
because there might be a codeblock with multiple paragraphs.

Fixes #117
  • Loading branch information
parhamsaremi committed Aug 16, 2023
1 parent 1fa1684 commit fe739b6
Showing 1 changed file with 66 additions and 1 deletion.
67 changes: 66 additions & 1 deletion src/FileConventions/Library.fs
Original file line number Diff line number Diff line change
Expand Up @@ -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<string>)
(currentParagraph: List<string>)
(paragraphs: List<string>)
(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(
Expand Down

0 comments on commit fe739b6

Please sign in to comment.