diff --git a/commonmark/src/main/java/org/commonmark/internal/util/AsciiMatcher.java b/commonmark/src/main/java/org/commonmark/internal/util/AsciiMatcher.java index 35769f82ddd47280816a95e33f5aea45274fb562..d31020fa37ea1343cc3dd425c673715eb52e0535 100644 --- a/commonmark/src/main/java/org/commonmark/internal/util/AsciiMatcher.java +++ b/commonmark/src/main/java/org/commonmark/internal/util/AsciiMatcher.java @@ -22,6 +22,10 @@ public class AsciiMatcher implements CharMatcher { return new Builder(new BitSet()); } + public static Builder builder(AsciiMatcher matcher) { + return new Builder((BitSet) matcher.set.clone()); + } + public static class Builder { private final BitSet set; 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 fe5725aee3c958b5e246ddcc7f408a0777f7f8cc..8cb67e0fd25d5a2d466ec47a2f35cd94fa9d47cf 100644 --- a/commonmark/src/main/java/org/commonmark/renderer/markdown/CoreMarkdownNodeRenderer.java +++ b/commonmark/src/main/java/org/commonmark/renderer/markdown/CoreMarkdownNodeRenderer.java @@ -24,6 +24,8 @@ public class CoreMarkdownNodeRenderer extends AbstractVisitor implements NodeRen private final AsciiMatcher textEscape = AsciiMatcher.builder().anyOf("[]<>`*&").build(); + private final CharMatcher textEscapeInHeading = + AsciiMatcher.builder(textEscape).anyOf("#").build(); private final CharMatcher linkDestinationNeedsAngleBrackets = AsciiMatcher.builder().c(' ').c('(').c(')').c('<').c('>').c('\\').build(); private final CharMatcher linkDestinationEscapeInAngleBrackets = @@ -366,11 +368,13 @@ public class CoreMarkdownNodeRenderer extends AbstractVisitor implements NodeRen } } + CharMatcher escape = text.getParent() instanceof Heading ? textEscapeInHeading : textEscape; + if (literal.endsWith("!") && text.getNext() instanceof Link) { - writer.writeEscaped(literal.substring(0, literal.length() - 1), textEscape); + writer.writeEscaped(literal.substring(0, literal.length() - 1), escape); writer.write("\\!"); } else { - writer.writeEscaped(literal, textEscape); + writer.writeEscaped(literal, escape); } } diff --git a/commonmark/src/test/java/org/commonmark/renderer/markdown/SpecMarkdownRendererTest.java b/commonmark/src/test/java/org/commonmark/renderer/markdown/SpecMarkdownRendererTest.java index 632f4acfc786474c0933b79078ec4214f8dd3516..d6bdf9cfb0c709a26090eb2cade74a21cef05487 100644 --- a/commonmark/src/test/java/org/commonmark/renderer/markdown/SpecMarkdownRendererTest.java +++ b/commonmark/src/test/java/org/commonmark/renderer/markdown/SpecMarkdownRendererTest.java @@ -62,7 +62,7 @@ public class SpecMarkdownRendererTest { System.out.println(); } - int expectedPassed = 646; + int expectedPassed = 647; assertTrue("Expected at least " + expectedPassed + " examples to pass but was " + passes.size(), passes.size() >= expectedPassed); }