Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions RELEASE_NOTES.md
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,8 @@
* Replace `Enumerable.Cast<XAttribute>` (LINQ) with `Seq.cast<XAttribute>` (idiomatic F#) in `MarkdownUtils.fs`, removing the `open System.Linq` import.

### Fixed
* Fix `Markdown.ToMd` serialising table data rows with a hardcoded `\n` line separator instead of the configured newline. On Windows (where `Environment.NewLine` is `\r\n`) this produced mixed line endings in the output. Each data row is now yielded separately, consistent with how every other paragraph type works. The trailing blank line after a table was also emitting a literal `"\n"` string instead of the standard `""` empty-line sentinel.
* Fix `Markdown.ToFsx` hardcoding a `\n` newline in the `(* output: ...)` comment wrapper around code-cell outputs. The configured `ctx.Newline` is now used, ensuring consistent line endings on Windows.
* Fix `Markdown.ToMd` silently dropping YAML frontmatter when serialising a parsed `MarkdownDocument` back to Markdown text. Frontmatter is now preserved with its `---` delimiters.
* Fix `Markdown.ToMd` converting tight lists (no blank lines between items) into loose lists by emitting a blank line after every item. Tight lists now round-trip correctly without inter-item blank lines.
* Fix `Markdown.ToMd` serialising `HardLineBreak` as a bare newline instead of two trailing spaces + newline. The correct CommonMark representation `" \n"` is now emitted, so hard line breaks survive a round-trip through `ToMd`.
Expand Down
2 changes: 1 addition & 1 deletion src/FSharp.Formatting.Markdown/FsxFormatting.fs
Original file line number Diff line number Diff line change
Expand Up @@ -62,7 +62,7 @@ let rec formatParagraphs ctx paragraphs =
code2
+ (match codeOutput with
| [] -> ""
| _out -> "(* output: \n" + output + "*)")
| _out -> "(* output: " + ctx.Newline + output + "*)")
| Choice2Of2 markdown ->
"(**"
+ ctx.Newline
Expand Down
31 changes: 15 additions & 16 deletions src/FSharp.Formatting.Markdown/MarkdownUtils.fs
Original file line number Diff line number Diff line change
Expand Up @@ -268,22 +268,21 @@ module internal MarkdownUtils =
let replaceEmptyWith x s =
if System.String.IsNullOrWhiteSpace s then x else Some s

yield
[ for r in rows do
[ for ps in r do
let x =
[ for p in ps do
yield
formatParagraph ctx p
|> Seq.choose (replaceEmptyWith (Some ""))
|> String.concat "" ]

yield x |> Seq.choose (replaceEmptyWith (Some "")) |> String.concat "<br />" ]
|> Seq.choose (replaceEmptyWith (Some "&#32;"))
|> String.concat " | " ]
|> String.concat "\n"

yield "\n"
for r in rows do
yield
[ for ps in r do
let x =
[ for p in ps do
yield
formatParagraph ctx p
|> Seq.choose (replaceEmptyWith (Some ""))
|> String.concat "" ]

yield x |> Seq.choose (replaceEmptyWith (Some "")) |> String.concat "<br />" ]
|> Seq.choose (replaceEmptyWith (Some "&#32;"))
|> String.concat " | "

yield ""

| OutputBlock(output, "text/html", _executionCount) ->
yield (output.Trim())
Expand Down
23 changes: 23 additions & 0 deletions tests/FSharp.Markdown.Tests/Markdown.fs
Original file line number Diff line number Diff line change
Expand Up @@ -1406,6 +1406,29 @@ let ``ToMd handles a table`` () =
result |> should contain "A"
result |> should contain "B"

[<Test>]
let ``ToMd table rows each appear on their own line`` () =
// Previously, all data rows were joined into one string with a hardcoded "\n",
// which produced a single yield item. Now each row is yielded separately so the
// caller's newline is used. Verify that each row appears on a distinct line.
let md = "H1 | H2\n--- | ---\nR1C1 | R1C2\nR2C1 | R2C2"
let result = Markdown.ToMd(Markdown.Parse(md, newline = "\n"), newline = "\n")
let lines = result.Split('\n') |> Array.filter (fun s -> s.Trim() <> "")
// Expect: header row, separator row, two data rows
lines |> should haveLength 4

[<Test>]
let ``ToMd table row count is correct when Windows newline is used`` () =
// Regression: rows were previously joined with a hardcoded "\n" regardless of ctx.Newline,
// so on Windows the data section was a single element with embedded Unix newlines.
let md = "H1 | H2\n--- | ---\nR1C1 | R1C2\nR2C1 | R2C2"
let result = Markdown.ToMd(Markdown.Parse(md, newline = "\r\n"), newline = "\r\n")
// All line separators must be \r\n (no stray \n inside the result)
result |> should not' (contain "\r\n\n")
result |> should not' (contain "\n\r\n")
result |> should contain "R1C1"
result |> should contain "R2C1"

[<Test>]
let ``ToMd handles empty document`` () = "" |> toMd |> shouldEqual ""

Expand Down