diff --git a/README.md b/README.md
index bcf552c5b0cb9bc1f7f7da1dfa994471b18f6b6a..25df264ef0497e5b2b58e79cc7118def41d6ae2d 100644
--- a/README.md
+++ b/README.md
@@ -13,13 +13,14 @@ Java library for parsing and rendering [Markdown] text according to the
 Introduction
 ------------
 
-Provides classes for parsing input to an abstract syntax tree of nodes
-(AST), visiting and manipulating nodes, and rendering to HTML. It
-started out as a port of [commonmark.js], but has since evolved into a
-full library with a nice API and the following features:
+Provides classes for parsing input to an abstract syntax tree (AST),
+visiting and manipulating nodes, and rendering to HTML or back to Markdown.
+It started out as a port of [commonmark.js], but has since evolved into an
+extensible library with the following features:
 
 * Small (core has no dependencies, extensions in separate artifacts)
-* Fast (10-20 times faster than pegdown, see benchmarks in repo)
+* Fast (10-20 times faster than [pegdown] which used to be a popular Markdown
+  library, see benchmarks in repo)
 * Flexible (manipulate the AST after parsing, customize HTML rendering)
 * Extensible (tables, strikethrough, autolinking and more, see below)
 
@@ -63,9 +64,9 @@ import org.commonmark.parser.Parser;
 import org.commonmark.renderer.html.HtmlRenderer;
 
 Parser parser = Parser.builder().build();
-Node document = parser.parse("This is *Sparta*");
+Node document = parser.parse("This is *Markdown*");
 HtmlRenderer renderer = HtmlRenderer.builder().build();
-renderer.render(document);  // "<p>This is <em>Sparta</em></p>\n"
+renderer.render(document);  // "<p>This is <em>Markdown</em></p>\n"
 ```
 
 This uses the parser and renderer with default options. Both builders have
@@ -81,8 +82,23 @@ to which tags are allowed, etc. That is the responsibility of the caller, and
 if you expose the resulting HTML, you probably want to run a sanitizer on it
 after this.
 
-For rendering to plain text, there's also a `TextContentRenderer` with
-a very similar API.
+#### Render to Markdown
+
+```java
+import org.commonmark.node.*;
+import org.commonmark.renderer.markdown.MarkdownRenderer;
+
+MarkdownRenderer renderer = MarkdownRenderer.builder().build();
+Node document = new Document();
+Heading heading = new Heading();
+heading.setLevel(2);
+heading.appendChild(new Text("My title"));
+document.appendChild(heading);
+
+renderer.render(document);  // "## My title\n"
+```
+
+For rendering to plain text with minimal markup, there's also `TextContentRenderer`.
 
 #### Use a visitor to process parsed nodes
 
@@ -390,6 +406,7 @@ BSD (2-clause) licensed, see LICENSE.txt file.
 [CommonMark]: https://commonmark.org/
 [Markdown]: https://daringfireball.net/projects/markdown/
 [commonmark.js]: https://github.com/commonmark/commonmark.js
+[pegdown]: https://github.com/sirthias/pegdown
 [CommonMark Dingus]: https://spec.commonmark.org/dingus/
 [Maven Central]: https://search.maven.org/#search|ga|1|g%3A%22org.commonmark%22
 [Semantic Versioning]: https://semver.org/
diff --git a/commonmark/pom.xml b/commonmark/pom.xml
index 64c45619261cde44b797a98c86711ceb658140bc..9988370a8b0e214ed539486efc5accf37cc4edd1 100644
--- a/commonmark/pom.xml
+++ b/commonmark/pom.xml
@@ -9,7 +9,7 @@
 
     <artifactId>commonmark</artifactId>
     <name>commonmark-java core</name>
-    <description>Core of commonmark-java (implementation of CommonMark for parsing markdown and rendering to HTML)</description>
+    <description>Core of commonmark-java (a library for parsing Markdown to an AST, modifying the AST and rendering it to HTML or Markdown)</description>
 
     <dependencies>
         <dependency>
diff --git a/commonmark/src/main/java/org/commonmark/package-info.java b/commonmark/src/main/java/org/commonmark/package-info.java
index e784703e9e2a8d90780a70d363024c952e5c828d..b683017f6e986b61817c905329031e933dcc5898 100644
--- a/commonmark/src/main/java/org/commonmark/package-info.java
+++ b/commonmark/src/main/java/org/commonmark/package-info.java
@@ -4,6 +4,7 @@
  * <li>{@link org.commonmark.parser} for parsing input text to AST nodes</li>
  * <li>{@link org.commonmark.node} for AST node types and visitors</li>
  * <li>{@link org.commonmark.renderer.html} for HTML rendering</li>
+ * <li>{@link org.commonmark.renderer.markdown} for Markdown rendering</li>
  * </ul>
  */
 package org.commonmark;
diff --git a/commonmark/src/main/java/org/commonmark/renderer/markdown/MarkdownNodeRendererContext.java b/commonmark/src/main/java/org/commonmark/renderer/markdown/MarkdownNodeRendererContext.java
index 5805c458b0ee4b38a2aaf7386ef013050767fd32..40640d1b44024c69a465fafcc5f8c119295d87ec 100644
--- a/commonmark/src/main/java/org/commonmark/renderer/markdown/MarkdownNodeRendererContext.java
+++ b/commonmark/src/main/java/org/commonmark/renderer/markdown/MarkdownNodeRendererContext.java
@@ -4,6 +4,9 @@ import org.commonmark.node.Node;
 
 import java.util.Set;
 
+/**
+ * Context that is passed to custom node renderers, see {@link MarkdownNodeRendererFactory#create}.
+ */
 public interface MarkdownNodeRendererContext {
 
     /**
diff --git a/commonmark/src/main/java/org/commonmark/renderer/markdown/MarkdownNodeRendererFactory.java b/commonmark/src/main/java/org/commonmark/renderer/markdown/MarkdownNodeRendererFactory.java
index adfe8a07b7cd7f2cb5f1676202eaf0400bea791e..14221ea568faa37fe932b45c18821caf0989e445 100644
--- a/commonmark/src/main/java/org/commonmark/renderer/markdown/MarkdownNodeRendererFactory.java
+++ b/commonmark/src/main/java/org/commonmark/renderer/markdown/MarkdownNodeRendererFactory.java
@@ -5,7 +5,7 @@ import org.commonmark.renderer.NodeRenderer;
 import java.util.Set;
 
 /**
- * Factory for instantiating new node renderers ƒor rendering.
+ * Factory for instantiating new node renderers for rendering custom nodes.
  */
 public interface MarkdownNodeRendererFactory {
 
diff --git a/commonmark/src/main/java/org/commonmark/renderer/markdown/MarkdownRenderer.java b/commonmark/src/main/java/org/commonmark/renderer/markdown/MarkdownRenderer.java
index 926105202e8f20c3a36e5481c7ed62604ed66f05..25fa9a142c6b62e9c56ba80f8f6409cb854d929d 100644
--- a/commonmark/src/main/java/org/commonmark/renderer/markdown/MarkdownRenderer.java
+++ b/commonmark/src/main/java/org/commonmark/renderer/markdown/MarkdownRenderer.java
@@ -9,14 +9,17 @@ import org.commonmark.renderer.Renderer;
 import java.util.*;
 
 /**
- * Renders nodes to CommonMark Markdown.
+ * Renders nodes to Markdown (CommonMark syntax); use {@link #builder()} to create a renderer.
  * <p>
- * Note that it does not currently attempt to preserve the exact syntax of the original input Markdown (if any):
+ * Note that it doesn't currently preserve the exact syntax of the original input Markdown (if any):
  * <ul>
  *     <li>Headings are output as ATX headings if possible (multi-line headings need Setext headings)</li>
  *     <li>Escaping might be over-eager, e.g. a plain {@code *} might be escaped
  *     even though it doesn't need to be in that particular context</li>
+ *     <li>Leading whitespace in paragraphs is not preserved</li>
  * </ul>
+ * However, it should produce Markdown that is semantically equivalent to the input, i.e. if the Markdown was parsed
+ * again and compared against the original AST, it should be the same (minus bugs).
  */
 public class MarkdownRenderer implements Renderer {
 
@@ -66,7 +69,7 @@ public class MarkdownRenderer implements Renderer {
      */
     public static class Builder {
 
-        private List<MarkdownNodeRendererFactory> nodeRendererFactories = new ArrayList<>();
+        private final List<MarkdownNodeRendererFactory> nodeRendererFactories = new ArrayList<>();
 
         /**
          * @return the configured {@link MarkdownRenderer}
@@ -106,9 +109,15 @@ public class MarkdownRenderer implements Renderer {
     }
 
     /**
-     * Extension for {@link MarkdownRenderer}.
+     * Extension for {@link MarkdownRenderer} for rendering custom nodes.
      */
     public interface MarkdownRendererExtension extends Extension {
+
+        /**
+         * Extend Markdown rendering, usually by registering custom node renderers using {@link Builder#nodeRendererFactory}.
+         *
+         * @param rendererBuilder the renderer builder to extend
+         */
         void extend(Builder rendererBuilder);
     }
 
diff --git a/commonmark/src/main/java/org/commonmark/renderer/markdown/package-info.java b/commonmark/src/main/java/org/commonmark/renderer/markdown/package-info.java
new file mode 100644
index 0000000000000000000000000000000000000000..f707671d502a69157db0ff7f97d7b2ded35fd699
--- /dev/null
+++ b/commonmark/src/main/java/org/commonmark/renderer/markdown/package-info.java
@@ -0,0 +1,4 @@
+/**
+ * Markdown rendering (see {@link org.commonmark.renderer.markdown.MarkdownRenderer})
+ */
+package org.commonmark.renderer.markdown;
diff --git a/commonmark/src/main/java/org/commonmark/renderer/text/package-info.java b/commonmark/src/main/java/org/commonmark/renderer/text/package-info.java
index 07a5580918e441e5115a98437d1e46d73624cdc9..8309f4bd618ff48eee5e8db47d095a8232627307 100644
--- a/commonmark/src/main/java/org/commonmark/renderer/text/package-info.java
+++ b/commonmark/src/main/java/org/commonmark/renderer/text/package-info.java
@@ -1,4 +1,4 @@
 /**
- * Text content rendering (see {@link org.commonmark.renderer.text.TextContentRenderer})
+ * Plain text rendering with minimal markup (see {@link org.commonmark.renderer.text.TextContentRenderer})
  */
 package org.commonmark.renderer.text;
diff --git a/commonmark/src/test/java/org/commonmark/test/UsageExampleTest.java b/commonmark/src/test/java/org/commonmark/test/UsageExampleTest.java
index 9ff646630645d4566107108f9f936bce2447eaf4..08235965a4c86345cb27641ac48d6d34d6469cb3 100644
--- a/commonmark/src/test/java/org/commonmark/test/UsageExampleTest.java
+++ b/commonmark/src/test/java/org/commonmark/test/UsageExampleTest.java
@@ -4,6 +4,7 @@ import org.commonmark.node.*;
 import org.commonmark.parser.Parser;
 import org.commonmark.renderer.NodeRenderer;
 import org.commonmark.renderer.html.*;
+import org.commonmark.renderer.markdown.MarkdownRenderer;
 import org.junit.Ignore;
 import org.junit.Test;
 
@@ -22,9 +23,21 @@ public class UsageExampleTest {
     @Test
     public void parseAndRender() {
         Parser parser = Parser.builder().build();
-        Node document = parser.parse("This is *Sparta*");
+        Node document = parser.parse("This is *Markdown*");
         HtmlRenderer renderer = HtmlRenderer.builder().escapeHtml(true).build();
-        assertEquals("<p>This is <em>Sparta</em></p>\n", renderer.render(document));
+        assertEquals("<p>This is <em>Markdown</em></p>\n", renderer.render(document));
+    }
+
+    @Test
+    public void renderToMarkdown() {
+        MarkdownRenderer renderer = MarkdownRenderer.builder().build();
+        Node document = new Document();
+        Heading heading = new Heading();
+        heading.setLevel(2);
+        heading.appendChild(new Text("My title"));
+        document.appendChild(heading);
+
+        assertEquals("## My title\n", renderer.render(document));
     }
 
     @Test