From f995028c42e36cd31b681f2ff273b93d30642c16 Mon Sep 17 00:00:00 2001 From: Max Horn Date: Mon, 16 Feb 2026 09:18:44 +0100 Subject: [PATCH] Add Markdown.Strikethrough support To cope with changes in Julia 1.14, see Co-authored-by: Codex --- CHANGELOG.md | 6 ++++++ docs/src/elements.md | 1 + src/markdown.jl | 8 ++++++++ src/stdlib/fromstdlib.jl | 3 +++ src/stdlib/tostdlib.jl | 7 +++++++ test/fromstdlib.jl | 10 +++++++++- test/markdown.jl | 4 ++-- test/tostdlib.jl | 18 +++++++++++++++++- 8 files changed, 53 insertions(+), 4 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 018af2b..a385fc2 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,9 @@ # MarkdownAST.jl changelog +## Version `Unreleased` + +* ![Feature][badge-feature] Added support for `Strikethrough` nodes when converting to/from the Markdown stdlib AST. This interop requires Julia 1.14+, because `Markdown.Strikethrough` is only available in the stdlib starting there. ([#31][github-31], [#32][github-32]) + ## Version `v0.1.2` * ![Feature][badge-feature] Implemented `replace` and `replace!` to safely mutate trees in arbitrary ways, and `empty!(node.children)` to remove all the children of a node. ([#22][github-22]) @@ -17,6 +21,8 @@ Initial release. [github-16]: https://github.com/JuliaDocs/MarkdownAST.jl/pull/16 [github-19]: https://github.com/JuliaDocs/MarkdownAST.jl/pull/19 [github-22]: https://github.com/JuliaDocs/MarkdownAST.jl/pull/22 +[github-31]: https://github.com/JuliaDocs/MarkdownAST.jl/issues/31 +[github-32]: https://github.com/JuliaDocs/MarkdownAST.jl/pull/32 [markdownast]: https://github.com/JuliaDocs/MarkdownAST.jl diff --git a/docs/src/elements.md b/docs/src/elements.md index 1efd6f8..3707954 100644 --- a/docs/src/elements.md +++ b/docs/src/elements.md @@ -81,6 +81,7 @@ List Paragraph SoftBreak Strong +Strikethrough Text ThematicBreak ``` diff --git a/src/markdown.jl b/src/markdown.jl index 098d5c6..f1d8af6 100644 --- a/src/markdown.jl +++ b/src/markdown.jl @@ -333,6 +333,14 @@ Inline singleton element for strong (e.g. bold) styling. struct Strong <: AbstractInline end iscontainer(::Strong) = true +""" + struct Strikethrough <: AbstractInline + +Inline singleton element for strikethrough styling. +""" +struct Strikethrough <: AbstractInline end +iscontainer(::Strikethrough) = true + """ mutable struct Code <: AbstractInline diff --git a/src/stdlib/fromstdlib.jl b/src/stdlib/fromstdlib.jl index 969815e..9509bd2 100644 --- a/src/stdlib/fromstdlib.jl +++ b/src/stdlib/fromstdlib.jl @@ -134,6 +134,9 @@ end # Inline nodes: _convert_inline(nodefn::NodeFn, s::Markdown.Bold) = _convert(nodefn, Strong(), _convert_inline, s.text) _convert_inline(nodefn::NodeFn, s::Markdown.Italic) = _convert(nodefn, Emph(), _convert_inline, s.text) +@static if isdefined(Markdown, :Strikethrough) + _convert_inline(nodefn::NodeFn, s::Markdown.Strikethrough) = _convert(nodefn, Strikethrough(), _convert_inline, s.text) +end function _convert_inline(nodefn::NodeFn, s::Markdown.Link) # The Base Markdown parser does not parse the title part, so we just default that to # an empty string. diff --git a/src/stdlib/tostdlib.jl b/src/stdlib/tostdlib.jl index 7cb776c..aeced15 100644 --- a/src/stdlib/tostdlib.jl +++ b/src/stdlib/tostdlib.jl @@ -41,6 +41,13 @@ _convert_element(::Node, e::InlineMath) = Markdown.LaTeX(e.math) _convert_element(::Node, e::JuliaValue) = e.ref _convert_element(n::Node, e::Link) = Markdown.Link(_convert_element.(n.children), e.destination) _convert_element(n::Node, ::Strong) = Markdown.Bold(_convert_element.(n.children)) +@static if isdefined(Markdown, :Strikethrough) + _convert_element(n::Node, ::Strikethrough) = Markdown.Strikethrough(_convert_element.(n.children)) +else + function _convert_element(::Node, ::Strikethrough) + error("Unable to convert Strikethrough to Markdown stdlib on this Julia version") + end +end _convert_element(::Node, e::Text) = e.text # Lists _convert_element(n::Node, e::List) = Markdown.List( diff --git a/test/fromstdlib.jl b/test/fromstdlib.jl index 82be570..c4ef9db 100644 --- a/test/fromstdlib.jl +++ b/test/fromstdlib.jl @@ -1,5 +1,5 @@ using MarkdownAST: MarkdownAST, Node, @ast, Document, - Emph, Strong, InlineMath, Link, Code, Image, + Emph, Strong, Strikethrough, InlineMath, Link, Code, Image, Paragraph, Heading, CodeBlock, BlockQuote, DisplayMath, ThematicBreak, List, Item, FootnoteLink, FootnoteDefinition, Admonition, Table, TableHeader, TableBody, TableRow, TableCell, @@ -49,6 +49,14 @@ using Test end end + @static if isdefined(Markdown, :Strikethrough) + @test convert(Node, Markdown.parse("~~xxx~~")) == @ast Document() do + Paragraph() do + Strikethrough() do; "xxx"; end + end + end + end + # Top-level elements @test convert(Node, Markdown.md""" p1 diff --git a/test/markdown.jl b/test/markdown.jl index a0669dd..3d29e1b 100644 --- a/test/markdown.jl +++ b/test/markdown.jl @@ -3,7 +3,7 @@ using MarkdownAST: AbstractElement, AbstractBlock, AbstractInline, Document, Admonition, BlockQuote, CodeBlock, DisplayMath, FootnoteDefinition, HTMLBlock, Heading, Item, List, Paragraph, ThematicBreak, - Code, Emph, FootnoteLink, HTMLInline, Image, InlineMath, Link, Strong, JuliaValue, + Code, Emph, FootnoteLink, HTMLInline, Image, InlineMath, Link, Strong, Strikethrough, JuliaValue, TableComponent, Table, TableHeader, TableBody, TableRow, TableCell, LineBreak, SoftBreak, Backslash, iscontainer, can_contain, isblock, isinline @@ -87,7 +87,7 @@ MarkdownAST.iscontainer(e::PseudoInline) = e.iscontainer end # (4) Inlines containing inlines: - for e in [Link("url", "title"), Image("url", "title"), Emph(), Strong()] + for e in [Link("url", "title"), Image("url", "title"), Emph(), Strong(), Strikethrough()] @test iscontainer(e) @test ! isblock(e) @test isinline(e) diff --git a/test/tostdlib.jl b/test/tostdlib.jl index 0465d73..f06b580 100644 --- a/test/tostdlib.jl +++ b/test/tostdlib.jl @@ -1,5 +1,5 @@ using MarkdownAST: MarkdownAST, Node, @ast, Document, - Emph, Strong, InlineMath, Link, Code, Image, + Emph, Strong, Strikethrough, InlineMath, Link, Code, Image, Paragraph, Heading, CodeBlock, BlockQuote, DisplayMath, ThematicBreak, List, Item, FootnoteLink, FootnoteDefinition, Admonition, Table, TableHeader, TableBody, TableRow, TableCell, @@ -91,6 +91,22 @@ struct UnknownBlock <: MarkdownAST.AbstractBlock end @test ast == convert(Node, md) end + let ast = @ast Document() do + Paragraph() do + "pre " + Strikethrough() do; "mid"; end + " post" + end + end + if isdefined(Markdown, :Strikethrough) + md = convert(Markdown.MD, ast) + @test md.content[1].content[2] isa Markdown.Strikethrough + @test convert(Node, md) == ast + else + @test_throws ErrorException convert(Markdown.MD, ast) + end + end + # JuliaValue let ast = @ast Document() do Paragraph() do