Any simple MarkDown Viewer?

Hey there :slight_smile:

We are using latest Flow 24.5 and would like to display given MarkDown files.
Background: we get Release Notes from Jira, we would want them as MarkDown, and within the application we would like to show them after click to the user. Jira’s HTML export for the Release Notes is… well… :man_shrugging:

I have seen there is a Markdown Editor Add-on which could be used, but as a wrapper for a React MarkDown Editor.

All ideas or hints are welcome!

Cheers
Mojo

You can also do this in Java if you want. Use a library such as GitHub - commonmark/commonmark-java: Java library for parsing and rendering CommonMark (Markdown) to convert Markdown into HTML, then use the HTML component to render it. Optionally add some custom CSS for styling the output, though the default Lumo styles should probably cover most of the output.

If the Markdown doesn’t come from a trusted source, then I’d also suggest to sanitize the output to remove script tags, style tags, inline scripts, or whatever you want to look out for.

1 Like

A basic component using commonmark-java:

import org.commonmark.node.Node;
import org.commonmark.parser.Parser;
import org.commonmark.renderer.html.HtmlRenderer;

import com.vaadin.flow.component.Html;
import com.vaadin.flow.component.html.Div;

public class MarkdownViewer extends Div {
    public MarkdownViewer(String markdown) {
        setMarkdown(markdown);
    }

    public void setMarkdown(String markdown) {
        removeAll();
        String htmlContent = convertToHtml(markdown);
        Html html = new Html("<div>" + htmlContent + "</div>");
        add(html);
    }

    private String convertToHtml(String markdown) {
        Parser parser = Parser.builder().build();
        Node document = parser.parse(markdown);
        HtmlRenderer renderer = HtmlRenderer.builder().build();
        return renderer.render(document);
    }
}

That gives decent results with the default theme, though some margins should be added around headings:

This is what Github renders:

Is there a reason the Markdown Editod Add-on is a problem? It has a Viewer component (see MarkdownEditor/src/test/java/com/flowingcode/vaadin/addons/markdown/MarkdownViewerDemo.java at master · FlowingCode/MarkdownEditor · GitHub). Your original post kind of cuts off when you mention it’s a React component wrapper, but it shouldn’t matter from the Flow point of view - that’s just the implementation.

I have for years used RichText component in Viritin, in pretty much every app/demo I have worked with. Often inline nowadays with the awesome Java “”" syntax, earlier usually from a resource file or via raw InputStream.

Hi. I’m the creator of the Markdown Editor Add-on. It contains also a Markdown Viewer besides the editor. Like Olli said, it doesn’t matter that it is a react component wrapper from a Flow perspective.
If there is something that is not working as expected, let me know!
Regards.

Or… just get the finished html for each issue (by getting renderedFields)?
I believe that is what we do. (I wrote it, but it’s been a couple of years)

First of all: To everyone here big thanks for all the great answers! I really appreciate, and btw: this is a great community here!

Indeed I haven’t looked too deep into the MarkDown Addon, only saw that “wrapper for React” and nearly jumped over it. My fault… :person_shrugging:

I hope for getting MarkDown from Jira as it seems it is not yet clear if it is possible. If so, I will try out either the Addon or the cool viritin tools. Otherwise I have to get the HTML and build something slightly different.

That’s the way to go when you get told “display release info, I suppose it’ll be MarkDown”…

Thanks again!
Mojo

Hi,
for exactly the same use case, showing markdown formatted release notes, I use the the flexmark library, which convert markdown to html.

    <dependency>
        <groupId>com.vladsch.flexmark</groupId>
        <artifactId>flexmark-all</artifactId>
        <version>0.64.0</version>
    </dependency>

My releaseNotes.md is handwritten in src/main/resource and therefor automatically copied by the maven build process into the application jar, so I can access them by .getResourceAsStream()

@Route(value = ReleaseNotesView.ROUTE)
@PageTitle("Release Notes")
@AnonymousAllowed
public class ReleaseNotesView extends VerticalLayout {

public static final String ROUTE = "/releaseNotes";
public static final String FILE_NAME = "releaseNotes.md";

Parser parser = Parser.builder().build();
HtmlRenderer renderer = HtmlRenderer.builder().build();

public ReleaseNotesView() {
    setSizeFull();

    InputStreamReader in = new InputStreamReader(this.getClass().getResourceAsStream(FILE_NAME));
    BufferedReader reader = new BufferedReader(in);
    String content = reader.lines().collect(Collectors.joining(System.lineSeparator()));
    Document text = parser.parse(content);
    String htmlContent = renderer.render(text);
    Html html = new Html("<div>" + htmlContent + "</div>");

    Scroller scroller = new Scroller(html);
    scroller.setScrollDirection(Scroller.ScrollDirection.VERTICAL);
    add(scroller);
}

Kind regards
Dominik

The RichText component is using that same FlexMark library (developed for IntelliJ). That’s what I expect to be the best (and most actively maintained) JVM library currently available.

8 lines (+ importes) in Dominic’s example can be replaced with:

    var html = new RichText().withMarkDownResource(FILE_NAME);

… and it will be better performing on the server. The Html component infamously validates html content with JSOUP, which don’t really make that much sense in this kind of case (where HTML is coming from trusted source, generated by this kind of library. But if performance truly is a problem, you probably also want to create he html build time.

1 Like

Thats a good reason for switching to the richText component.
Thanks Matti for this hint.

Hey again :slight_smile:

Many great solutions here, thanks!
As I use the DynamicFileDownloader from viritin already I tried out the richText component and it works like a charm. Have to say, I wasn’t really aware of all that viritin content it provides.

Thanks again, and a nice day to everyone!

Cheers
Mojo

Hi, I am using 24.5.2 release of Vaadin. Using the same example in the link I couldnt render the md content in the page. When I inspect in the browser I can see the component but the element is empty. First time user of Vaadin here

If you use spring, take a look at the README: GitHub - FlowingCode/MarkdownEditor: Add-on providing Markdown editing and visualization capabilities

Hi.
Yes, as @knoobie said, please follow this guideline.
Hopefully after this issue is implemented, that won’t be necessary anymore.
If you still have problems, please let me know.

Note: After discussion with @marcoc_753 your mentioned issue won’t help here. Once an allowlist is defined by the application it takes precedence over configuration coming from addons (which is a good thing!).

I just want to point out that the package.properties feature is not about automatically discovering annotated classes in external JARs, but to improve Flow class scanning by allowing JARs to filter out their own unnecessary packages.

1 Like