diff --git a/org.eclipse.lsp4e.test/src/org/eclipse/lsp4e/test/internal/MarkdownUtilTest.java b/org.eclipse.lsp4e.test/src/org/eclipse/lsp4e/test/internal/MarkdownUtilTest.java new file mode 100644 index 000000000..b8ef63ffb --- /dev/null +++ b/org.eclipse.lsp4e.test/src/org/eclipse/lsp4e/test/internal/MarkdownUtilTest.java @@ -0,0 +1,64 @@ +/******************************************************************************* + * Copyright (c) 2026 Contributors to the Eclipse Foundation. + * This program and the accompanying materials are made + * available under the terms of the Eclipse Public License 2.0 + * which is available at https://www.eclipse.org/legal/epl-2.0/ + * + * SPDX-License-Identifier: EPL-2.0 + * + * Contributors: + * See git history + *******************************************************************************/ +package org.eclipse.lsp4e.test.internal; + +import static org.junit.jupiter.api.Assertions.assertEquals; + +import java.util.stream.Stream; + +import org.eclipse.lsp4e.internal.MarkdownUtil; +import org.junit.jupiter.params.ParameterizedTest; +import org.junit.jupiter.params.provider.Arguments; +import org.junit.jupiter.params.provider.MethodSource; + +public class MarkdownUtilTest { + + public static Stream renderToHtml() { + return Stream.of( // + Arguments.argumentSet("Simple", """ + # Heading 1 + - this is a test""", """ +

Heading 1

+ + """), // + Arguments.argumentSet("With table", """ + | Header | Another Header | + |---------|----------------| + | field 1 | value one |""", """ + + + + + + + + + + + + + +
HeaderAnother Header
field 1value one
+ """) // + ); + } + + @ParameterizedTest + @MethodSource + void renderToHtml(String markdown, String expectedHtml) throws Exception { + // Simple test to make sure we configured CommonMark correctly. + assertEquals(expectedHtml, MarkdownUtil.renderToHtml(markdown)); + } + +} diff --git a/org.eclipse.lsp4e/src/org/eclipse/lsp4e/internal/MarkdownUtil.java b/org.eclipse.lsp4e/src/org/eclipse/lsp4e/internal/MarkdownUtil.java new file mode 100644 index 000000000..209250fea --- /dev/null +++ b/org.eclipse.lsp4e/src/org/eclipse/lsp4e/internal/MarkdownUtil.java @@ -0,0 +1,43 @@ +/******************************************************************************* + * Copyright (c) 2026 Contributors to the Eclipse Foundation. + * This program and the accompanying materials are made + * available under the terms of the Eclipse Public License 2.0 + * which is available at https://www.eclipse.org/legal/epl-2.0/ + * + * SPDX-License-Identifier: EPL-2.0 + * + * Contributors: + * See git history + *******************************************************************************/ +package org.eclipse.lsp4e.internal; + +import java.util.List; + +import org.commonmark.Extension; +import org.commonmark.ext.gfm.tables.TablesExtension; +import org.commonmark.parser.Parser; +import org.commonmark.renderer.Renderer; +import org.commonmark.renderer.html.HtmlRenderer; + +public class MarkdownUtil { + + /** + * Used commonmark extensions + */ + private static final List EXTENSIONS = List.of(TablesExtension.create()); + + /** + * Singleton instance, as both classes are thread-safe, see + * https://github.com/commonmark/commonmark-java?tab=readme-ov-file#thread-safety + */ + private static final Parser PARSER = Parser.builder().extensions(EXTENSIONS).build(); + private static final Renderer RENDERER = HtmlRenderer.builder().extensions(EXTENSIONS).build(); + + /** + * Renders the given markdown content to HTML. + */ + public static String renderToHtml(String markdown) { + return RENDERER.render(PARSER.parse(markdown)); + } + +} diff --git a/org.eclipse.lsp4e/src/org/eclipse/lsp4e/operations/hover/LSPTextHover.java b/org.eclipse.lsp4e/src/org/eclipse/lsp4e/operations/hover/LSPTextHover.java index 9f91424dc..5b87ba634 100644 --- a/org.eclipse.lsp4e/src/org/eclipse/lsp4e/operations/hover/LSPTextHover.java +++ b/org.eclipse.lsp4e/src/org/eclipse/lsp4e/operations/hover/LSPTextHover.java @@ -29,11 +29,6 @@ import java.util.function.Predicate; import java.util.stream.Collectors; -import org.commonmark.Extension; -import org.commonmark.ext.gfm.tables.TablesExtension; -import org.commonmark.node.Node; -import org.commonmark.parser.Parser; -import org.commonmark.renderer.html.HtmlRenderer; import org.eclipse.jdt.annotation.Nullable; import org.eclipse.jface.internal.text.html.BrowserInformationControl; import org.eclipse.jface.text.AbstractReusableInformationControlCreator; @@ -53,6 +48,7 @@ import org.eclipse.lsp4e.LanguageServers; import org.eclipse.lsp4e.internal.CancellationUtil; import org.eclipse.lsp4e.internal.IdentifierUtil; +import org.eclipse.lsp4e.internal.MarkdownUtil; import org.eclipse.lsp4j.Hover; import org.eclipse.lsp4j.HoverParams; import org.eclipse.lsp4j.MarkedString; @@ -113,11 +109,7 @@ public class LSPTextHover implements ITextHover, ITextHoverExtension, ITextHover .collect(Collectors.joining("\n\n")) //$NON-NLS-1$ .trim(); if (!result.isEmpty()) { - List extensions = List.of(TablesExtension.create()); - Parser parser = Parser.builder().extensions(extensions).build(); - Node document = parser.parse(result); - HtmlRenderer renderer = HtmlRenderer.builder().extensions(extensions).build(); - return renderer.render(document); + return MarkdownUtil.renderToHtml(result); } else { return null; }