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
3 changes: 3 additions & 0 deletions RELEASE_NOTES.md
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,9 @@
* Add missing `[<Test>]` attribute on `Can include-output-and-it` test so it is executed by the test runner.
* Add regression test confirming that types whose name matches their enclosing namespace are correctly included in generated API docs. [#944](https://github.com/fsprojects/FSharp.Formatting/issues/944)
* Fix crash (`failwith "tbd - IndirectImage"`) when `Markdown.ToMd` is called on a document containing reference-style images with bracket syntax. The indirect image is now serialised as `![alt](url)` when the reference is resolved, or in bracket notation when it is not. [#1094](https://github.com/fsprojects/FSharp.Formatting/pull/1094)
* Fix `Markdown.ToMd` serialising italic spans with asterisks incorrectly as bold spans. [#1102](https://github.com/fsprojects/FSharp.Formatting/pull/1102)
* Fix `Markdown.ToMd` serialising ordered list items with incorrect numbering and formatting. [#1102](https://github.com/fsprojects/FSharp.Formatting/pull/1102)
* Fix `Markdown.ToMd` not preserving indented code blocks: bare code output was re-parsed as a paragraph. Indented code blocks are now serialised as fenced code blocks, which round-trip correctly.
* Fix `Markdown.ToMd` serialising `*emphasis*` (italic) spans as `**...**` (bold) instead of `*...*`. [#1102](https://github.com/fsprojects/FSharp.Formatting/pull/1102)
* Fix `Markdown.ToMd` serialising ordered list items with 0-based numbering and no period (e.g. `0 first`) instead of 1-based with a period (e.g. `1. first`). [#1102](https://github.com/fsprojects/FSharp.Formatting/pull/1102)
* Fix `HtmlElement` SVG serialisation: `LinearGradient` now renders as `<linearGradient>` and `RadialGradient` now renders as `<radialGradient>` β€” both previously emitted the invalid tag `<radient>`.
Expand Down
12 changes: 6 additions & 6 deletions src/FSharp.Formatting.Markdown/MarkdownUtils.fs
Original file line number Diff line number Diff line change
Expand Up @@ -187,15 +187,15 @@ module internal MarkdownUtils =
yield String.replicate 3 (string c)
yield ""
| CodeBlock(code = code; fence = fence; language = language) ->
match fence with
| None -> ()
| Some f -> yield f + language
// Indented code blocks (fence = None) are serialised as fenced blocks so
// that the round-trip is valid β€” raw indented code without a '> ' prefix
// or 4-space indent would be parsed as a paragraph, not a code block.
let f = defaultArg fence "```"
yield f + language

yield code

match fence with
| None -> ()
| Some f -> yield f
yield f

yield ""
| ListBlock(Unordered, paragraphsl, _) ->
Expand Down
32 changes: 32 additions & 0 deletions tests/FSharp.Markdown.Tests/Markdown.fs
Original file line number Diff line number Diff line change
Expand Up @@ -1444,6 +1444,38 @@ let ``ToMd round-trip: indirect image with unresolved reference`` () =
result |> should contain "![alt text][unknown-ref]"

// --------------------------------------------------------------------------------------
// ToMd round-trip: indented code block (fence = None) β€” issue #fix-tomd-indented-codeblock
// --------------------------------------------------------------------------------------

[<Test>]
let ``ToMd round-trip: indented code block is preserved as a code block`` () =
// An indented code block (4-space indent) is serialised as a fenced block to
// guarantee the round-trip: outputting bare code without any fence would cause
// re-parsing to produce a paragraph instead of a code block.
let input = " let x = 1\n let y = 2"
let doc = Markdown.Parse(input)
// The parser should have produced a CodeBlock, not a Paragraph
let cbs =
doc.Paragraphs
|> List.choose (function
| CodeBlock _ as cb -> Some cb
| _ -> None)

cbs |> should haveLength 1
// ToMd should produce a fenced form so the round-trip is valid
let result = Markdown.ToMd(doc, newline = "\n")
result |> should contain "```"
result |> should contain "let x = 1"
result |> should contain "let y = 2"
// The serialised form re-parses to a CodeBlock, not a Paragraph
let doc2 = Markdown.Parse(result)

doc2.Paragraphs
|> List.choose (function
| CodeBlock _ as cb -> Some cb
| _ -> None)
|> should haveLength 1

// ToMd: HardLineBreak and HorizontalRule round-trip
// --------------------------------------------------------------------------------------

Expand Down