From 0c5ad6e1f16ae2b655db93fd07c0af502fead16e Mon Sep 17 00:00:00 2001 From: Robin Stocker <robin@nibor.org> Date: Thu, 8 Feb 2024 23:26:03 +1100 Subject: [PATCH] Use parsed delimiter for emphasis if available --- .../markdown/CoreMarkdownNodeRenderer.java | 10 ++++-- .../markdown/MarkdownRendererTest.java | 34 ++++++++++++++----- 2 files changed, 32 insertions(+), 12 deletions(-) diff --git a/commonmark/src/main/java/org/commonmark/renderer/markdown/CoreMarkdownNodeRenderer.java b/commonmark/src/main/java/org/commonmark/renderer/markdown/CoreMarkdownNodeRenderer.java index 2db7ef30..748ff5df 100644 --- a/commonmark/src/main/java/org/commonmark/renderer/markdown/CoreMarkdownNodeRenderer.java +++ b/commonmark/src/main/java/org/commonmark/renderer/markdown/CoreMarkdownNodeRenderer.java @@ -45,7 +45,7 @@ public class CoreMarkdownNodeRenderer extends AbstractVisitor implements NodeRen this.context = context; this.writer = context.getWriter(); - textEscape = AsciiMatcher.builder().anyOf("[]<>`*&\n\\").anyOf(context.getSpecialCharacters()).build(); + textEscape = AsciiMatcher.builder().anyOf("[]<>`*_&\n\\").anyOf(context.getSpecialCharacters()).build(); textEscapeInHeading = AsciiMatcher.builder(textEscape).anyOf("#").build(); } @@ -282,8 +282,12 @@ public class CoreMarkdownNodeRenderer extends AbstractVisitor implements NodeRen @Override public void visit(Emphasis emphasis) { - // When emphasis is nested, a different delimiter needs to be used - char delimiter = writer.getLastChar() == '*' ? '_' : '*'; + String delimiter = emphasis.getOpeningDelimiter(); + // Use delimiter that was parsed if available + if (delimiter == null) { + // When emphasis is nested, a different delimiter needs to be used + delimiter = writer.getLastChar() == '*' ? "_" : "*"; + } writer.raw(delimiter); super.visit(emphasis); writer.raw(delimiter); diff --git a/commonmark/src/test/java/org/commonmark/renderer/markdown/MarkdownRendererTest.java b/commonmark/src/test/java/org/commonmark/renderer/markdown/MarkdownRendererTest.java index 20453eed..af6a3488 100644 --- a/commonmark/src/test/java/org/commonmark/renderer/markdown/MarkdownRendererTest.java +++ b/commonmark/src/test/java/org/commonmark/renderer/markdown/MarkdownRendererTest.java @@ -1,6 +1,6 @@ package org.commonmark.renderer.markdown; -import org.commonmark.node.Node; +import org.commonmark.node.*; import org.commonmark.parser.Parser; import org.junit.Test; @@ -173,9 +173,21 @@ public class MarkdownRendererTest { // When nesting, a different delimiter needs to be used assertRoundTrip("*_foo_*\n"); assertRoundTrip("*_*foo*_*\n"); + assertRoundTrip("_*foo*_\n"); // Not emphasis (needs * inside words) - assertRoundTrip("foo_bar_\n"); + assertRoundTrip("foo\\_bar\\_\n"); + + // Even when rendering a manually constructed tree, the emphasis delimiter needs to be chosen correctly. + Document doc = new Document(); + Paragraph p = new Paragraph(); + doc.appendChild(p); + Emphasis e1 = new Emphasis(); + p.appendChild(e1); + Emphasis e2 = new Emphasis(); + e1.appendChild(e2); + e2.appendChild(new Text("hi")); + assertEquals("*_hi_*\n", render(doc)); } @Test @@ -226,17 +238,21 @@ public class MarkdownRendererTest { assertRoundTrip("foo\nbar\n"); } - private Node parse(String source) { - return Parser.builder().build().parse(source); + private void assertRoundTrip(String input) { + String rendered = parseAndRender(input); + assertEquals(input, rendered); } - private String render(String source) { + private String parseAndRender(String source) { Node parsed = parse(source); - return MarkdownRenderer.builder().build().render(parsed); + return render(parsed); } - private void assertRoundTrip(String input) { - String rendered = render(input); - assertEquals(input, rendered); + private Node parse(String source) { + return Parser.builder().build().parse(source); + } + + private String render(Node node) { + return MarkdownRenderer.builder().build().render(node); } } -- GitLab