diff --git a/codegen/aws/core/src/test/java/software/amazon/smithy/python/aws/codegen/MarkdownToRstDocConverterTest.java b/codegen/aws/core/src/test/java/software/amazon/smithy/python/aws/codegen/MarkdownToRstDocConverterTest.java index 5b58ecc66..8f4a7bd73 100644 --- a/codegen/aws/core/src/test/java/software/amazon/smithy/python/aws/codegen/MarkdownToRstDocConverterTest.java +++ b/codegen/aws/core/src/test/java/software/amazon/smithy/python/aws/codegen/MarkdownToRstDocConverterTest.java @@ -106,4 +106,13 @@ public void testConvertCommonmarkToRstWithNestedList() { String result = markdownToRstDocConverter.convertCommonmarkToRst(html); assertEquals(expected, result.trim()); } + + @Test + public void testConvertCommonmarkToRstWithFormatSpecifierCharacters() { + // Test that Smithy format specifier characters ($) are properly escaped and treated as literal text + String html = "

Testing $placeholder_one and $placeholder_two

"; + String expected = "Testing $placeholder_one and $placeholder_two"; + String result = markdownToRstDocConverter.convertCommonmarkToRst(html); + assertEquals(expected, result.trim()); + } } diff --git a/codegen/core/src/main/java/software/amazon/smithy/python/codegen/writer/MarkdownToRstDocConverter.java b/codegen/core/src/main/java/software/amazon/smithy/python/codegen/writer/MarkdownToRstDocConverter.java index 20dff4dcd..883e9b132 100644 --- a/codegen/core/src/main/java/software/amazon/smithy/python/codegen/writer/MarkdownToRstDocConverter.java +++ b/codegen/core/src/main/java/software/amazon/smithy/python/codegen/writer/MarkdownToRstDocConverter.java @@ -78,7 +78,7 @@ public void head(Node node, int depth) { if (!text.trim().isEmpty()) { if (text.startsWith(":param ")) { int secondColonIndex = text.indexOf(':', 1); - writer.write(text.substring(0, secondColonIndex + 1)); + writer.write("$L", text.substring(0, secondColonIndex + 1)); //TODO right now the code generator gives us a mixture of // RST and HTML (for instance :param xyz:

docs //

). Since we standardize to html above, that

tag @@ -91,16 +91,16 @@ public void head(Node node, int depth) { } else { writer.ensureNewline(); writer.indent(); - writer.write(text.substring(secondColonIndex + 1)); + writer.write("$L", text.substring(secondColonIndex + 1)); writer.dedent(); } } else { - writer.writeInline(text); + writer.writeInline("$L", text); } // Account for services making a paragraph tag that's empty except // for a newline } else if (node.parent() != null && ((Element) node.parent()).tagName().equals("p")) { - writer.writeInline(text.replaceAll("[ \\t]+", "")); + writer.writeInline("$L", text.replaceAll("[ \\t]+", "")); } } else if (node instanceof Element) { Element element = (Element) node; @@ -158,7 +158,7 @@ public void tail(Node node, int depth) { case "a": String href = element.attr("href"); if (!href.isEmpty()) { - writer.writeInline(" <").writeInline(href).writeInline(">`_"); + writer.writeInline(" <").writeInline("$L", href).writeInline(">`_"); } else { writer.writeInline("`"); } @@ -196,7 +196,7 @@ public void tail(Node node, int depth) { break; case "h1": String title = element.text(); - writer.ensureNewline().writeInline("=".repeat(title.length())).ensureNewline(); + writer.ensureNewline().writeInline("$L", "=".repeat(title.length())).ensureNewline(); break; default: break;