diff --git a/core/src/org/labkey/core/wiki/MarkdownServiceImpl.java b/core/src/org/labkey/core/wiki/MarkdownServiceImpl.java
index 064d35930ce..c8ec46de4b4 100644
--- a/core/src/org/labkey/core/wiki/MarkdownServiceImpl.java
+++ b/core/src/org/labkey/core/wiki/MarkdownServiceImpl.java
@@ -23,10 +23,15 @@
import org.commonmark.ext.image.attributes.ImageAttributesExtension;
import org.commonmark.node.Node;
import org.commonmark.parser.Parser;
+import org.commonmark.renderer.html.HtmlNodeRendererContext;
import org.commonmark.renderer.html.HtmlRenderer;
+import org.commonmark.renderer.html.CoreHtmlNodeRenderer;
+import org.commonmark.node.HtmlInline;
+import org.commonmark.node.HtmlBlock;
import org.labkey.api.markdown.MarkdownService;
import java.util.List;
+import java.util.Set;
public class MarkdownServiceImpl implements MarkdownService
{
@@ -55,10 +60,65 @@ public MarkdownServiceImpl()
.softbreak("
\n") // See Issue #34169
.sanitizeUrls(true)
.escapeHtml(true)
+ .nodeRendererFactory(CommentNodeRenderer::new)
.extensions(extensions)
.build();
}
+ private static class CommentNodeRenderer extends CoreHtmlNodeRenderer
+ {
+ private final HtmlNodeRendererContext _context;
+
+ public CommentNodeRenderer(HtmlNodeRendererContext context)
+ {
+ super(context);
+ _context = context;
+ }
+
+ @Override
+ public Set> getNodeTypes()
+ {
+ return Set.of(HtmlInline.class, HtmlBlock.class);
+ }
+
+ @Override
+ public void render(Node node)
+ {
+ if (node instanceof HtmlInline inline)
+ {
+ String literal = inline.getLiteral();
+ if (isComment(literal))
+ {
+ _context.getWriter().raw(literal);
+ }
+ else
+ {
+ _context.getWriter().text(literal);
+ }
+ }
+ else if (node instanceof HtmlBlock block)
+ {
+ String literal = block.getLiteral();
+ if (isComment(literal))
+ {
+ _context.getWriter().raw(literal);
+ }
+ else
+ {
+ _context.getWriter().tag("p");
+ _context.getWriter().text(literal);
+ _context.getWriter().tag("/p");
+ _context.getWriter().line();
+ }
+ }
+ }
+
+ private boolean isComment(String literal)
+ {
+ return literal != null && literal.trim().startsWith("");
+ }
+ }
+
@Override
public String toHtml(String mdText)
{
diff --git a/core/src/org/labkey/core/wiki/MarkdownTestCase.java b/core/src/org/labkey/core/wiki/MarkdownTestCase.java
index f1c6402f787..a54fcea07c4 100644
--- a/core/src/org/labkey/core/wiki/MarkdownTestCase.java
+++ b/core/src/org/labkey/core/wiki/MarkdownTestCase.java
@@ -15,7 +15,7 @@ class MarkdownTestCase extends Assert
@Test
public void testMdHeadingToHtml()
{
- MarkdownService markdownService = MarkdownService.get();
+ MarkdownService markdownService = new MarkdownServiceImpl();
String testMdText = "# This is a H1 header";
String expectedHtmlText = "\n
";
String htmlText = markdownService.toHtml(testMdText);
@@ -28,7 +28,7 @@ public void testMdHeadingToHtml()
@Test
public void testMdBoldToHtml()
{
- MarkdownService markdownService = MarkdownService.get();
+ MarkdownService markdownService = new MarkdownServiceImpl();
String testMdText = "**This is bold text**";
String expectedHtmlText = "";
String htmlText = markdownService.toHtml(testMdText);
@@ -41,11 +41,10 @@ public void testMdBoldToHtml()
@Test
public void testMdHtmlTags()
{
- MarkdownService markdownService = MarkdownService.get();
-
+ MarkdownService markdownService = new MarkdownServiceImpl();
String testMdText = "header
";
- String expectedHtmlText = "";
String htmlText = markdownService.toHtml(testMdText);
+ String expectedHtmlText = "";
assertEquals("The MarkdownService failed to correctly escape html tags.", expectedHtmlText, htmlText);
testMdText = "";
@@ -60,7 +59,7 @@ public void testMdHtmlTags()
@Test
public void testMdComplexToHtml()
{
- MarkdownService markdownService = MarkdownService.get();
+ MarkdownService markdownService = new MarkdownServiceImpl();
// this sample of markdown and translation taken from part of: https://markdown-it.github.io/
String testMdText = """
---
@@ -341,4 +340,20 @@ public void testMdComplexToHtml()
String htmlText = markdownService.toHtml(testMdText);
assertEquals("The MarkdownService failed to correctly translate complex markdown text to html.", expectedHtmlText, htmlText);
}
+ @Test
+ public void testHtmlComments()
+ {
+ MarkdownService markdownService = new MarkdownServiceImpl();
+
+ String testMdText = "Text before text after";
+ String htmlText = markdownService.toHtml(testMdText);
+
+ assertTrue("Comment was encoded: " + htmlText, htmlText.contains(""));
+ assertFalse("Comment should not be encoded: " + htmlText, htmlText.contains("<!--"));
+
+ // Verification for ";
+ String scriptHtml = markdownService.toHtml(scriptMd);
+ assertTrue("Script tags should still be encoded: " + scriptHtml, scriptHtml.contains("<script>"));
+ }
}