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 2db7ef30cb6e56486cf1e256ad50a821a7827f64..748ff5dfb80ad292321b917932fdd35d4eb7cbe3 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 20453eed7fb5ca6a6f9be4260120cea9f9119feb..af6a3488a9f3f41139547a1f8c5c512834d2d075 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);
     }
 }