Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Convert back to markdown string #18

Open
goerz opened this issue Sep 11, 2023 · 4 comments
Open

Convert back to markdown string #18

goerz opened this issue Sep 11, 2023 · 4 comments

Comments

@goerz
Copy link
Member

goerz commented Sep 11, 2023

Is there an easy way to convert a MarkdownAST tree back to the markdown string it represents? I managed to do it via conversion back to the stdlib-Markdown:

julia> using MarkdownAST: @ast, Document, Heading, Paragraph
julia> using Markdown: MD

julia> md = @ast Document() do
           Heading(1) do
               "Top-level heading"
           end
           Paragraph() do
               "Some paragraph text"
           end
       end

julia> print(string(convert(MD, md)))
# Top-level heading

Some paragraph text

It would nice if string(md) or something like that could work directly.

@mortenpi
Copy link
Member

This is not implemented currently, and in general I am a little hesitant to adding "writers" to this package. However, a CommonMark-compatible representation of the standard elements seems reasonable and would be file (also #4 and #5). It would still require sorting out some sort of a writer interface for user-defined elements.

In the medium-term, we could also do this via CommonMark, if we implement the reverse of MichaelHatherly/CommonMark.jl#56. Although I guess this is not much different from doing it via the Markdown standard library, which is already possible.

@goerz
Copy link
Member Author

goerz commented Sep 11, 2023

I wouldn't put a very high priority on this – it's more of a "nice to have" feature.

I was looking into this in the context of debugging the transformations the DocumenterCitations plugin does. Dumping the full AST datastructure to screen is just very verbose and hard to read. It was much easier to view the before/after node as a markdown text. But as long as any MarkdownAST node can be converted to a Markdown.MD object that's probably good enough. I wasn't 100% sure if there might be any instances where that conversion might be "lossy".

@mortenpi
Copy link
Member

I wasn't 100% sure if there might be any instances where that conversion might be "lossy".

There are a few cases where you can't represent CommonMark elements with the Markdown standard library, so converting back and forth would be lossy.

# Raw HTML
_convert_element(::Node, e::HTMLBlock) = Markdown.Code("html", e.html)
_convert_element(::Node, e::HTMLInline) = Markdown.Code("", e.html)

However, quickly looking at the implementation in that file, just going from MarkdownAST -> stdlib should always work without erroring (and if there's some element we've forgotten, we should probably add a method for it).

@goerz
Copy link
Member Author

goerz commented Oct 6, 2023

I've been pretty happy using the following function, these last couple of weeks:

function ast_to_str(node::MarkdownAST.Node)
    if node.element isa MarkdownAST.Document
        document = node
    elseif node.element isa MarkdownAST.AbstractBlock
        document = MarkdownAST.@ast MarkdownAST.Document() do
            MarkdownAST.copy_tree(node)
        end
    else
        @assert node.element isa MarkdownAST.AbstractInline
        document = MarkdownAST.@ast MarkdownAST.Document() do
            MarkdownAST.Paragraph() do
                MarkdownAST.copy_tree(node)
            end
        end
    end
    text = Markdown.plain(convert(Markdown.MD, document))
    return strip(text)
end

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants