diff --git a/CHANGELOG.next.toml b/CHANGELOG.next.toml index 3a4e4163826432c19b362fe3d2efdb78d1c5c1d6..e2e86db52705d47963c5cd67d46c29730685081f 100644 --- a/CHANGELOG.next.toml +++ b/CHANGELOG.next.toml @@ -11,6 +11,18 @@ # meta = { "breaking" = false, "tada" = false, "bug" = false } # author = "rcoh" +[[aws-sdk-rust]] +message = "Generated docs should no longer contain links that don't go anywhere" +references = ["aws-sdk-rust#357"] +meta = { "breaking" = false, "tada" = false, "bug" = true } +author = "Velfi" + +[[smithy-rs]] +message = "Generated docs will convert `<a>` tags with no `href` attribute to `<pre>` tags" +references = ["aws-sdk-rust#357"] +meta = { "breaking" = false, "tada" = false, "bug" = true } +author = "Velfi" + [[smithy-rs]] message = "Made fluent operation structs cloneable" references = ["aws-sdk-rust#254"] diff --git a/codegen/build.gradle.kts b/codegen/build.gradle.kts index db7bad3b0731ba7befa7ecf1b7b6a5406cfb7a0f..ffdbb977b9d18a97e0c29078e168606e57031561 100644 --- a/codegen/build.gradle.kts +++ b/codegen/build.gradle.kts @@ -22,6 +22,7 @@ val kotestVersion: String by project dependencies { implementation(kotlin("stdlib-jdk8")) + implementation("org.jsoup:jsoup:1.14.3") api("software.amazon.smithy:smithy-codegen-core:$smithyVersion") api("com.moandjiezana.toml:toml4j:0.7.2") implementation("software.amazon.smithy:smithy-aws-traits:$smithyVersion") diff --git a/codegen/src/main/kotlin/software/amazon/smithy/rust/codegen/rustlang/RustWriter.kt b/codegen/src/main/kotlin/software/amazon/smithy/rust/codegen/rustlang/RustWriter.kt index 40082645d878a8cc4af85743ee1ed6faea4a6e51..8f8f3a9c1aad7b69bd5fdb8c37b68750eca97336 100644 --- a/codegen/src/main/kotlin/software/amazon/smithy/rust/codegen/rustlang/RustWriter.kt +++ b/codegen/src/main/kotlin/software/amazon/smithy/rust/codegen/rustlang/RustWriter.kt @@ -6,6 +6,8 @@ package software.amazon.smithy.rust.codegen.rustlang import org.intellij.lang.annotations.Language +import org.jsoup.Jsoup +import org.jsoup.nodes.Element import software.amazon.smithy.codegen.core.CodegenException import software.amazon.smithy.codegen.core.Symbol import software.amazon.smithy.codegen.core.writer.CodegenWriter @@ -212,7 +214,7 @@ fun <T : CodeWriter> T.documentShape(shape: Shape, model: Model, autoSuppressMis when (docTrait?.value?.isNotBlank()) { // If docs are modeled, then place them on the code generated shape true -> { - this.docs(escape(docTrait.value)) + this.docs(normalizeHtml(escape(docTrait.value))) note?.also { // Add a blank line between the docs and the note to visually differentiate write("///") @@ -260,6 +262,29 @@ fun <T : CodeWriter> T.docs(text: String, vararg args: Any, newlinePrefix: Strin /** Escape the [expressionStart] character to avoid problems during formatting */ fun CodeWriter.escape(text: String): String = text.replace("$expressionStart", "$expressionStart$expressionStart") +/** Parse input as HTML and normalize it */ +fun normalizeHtml(input: String): String { + val doc = Jsoup.parse(input) + doc.body().apply { + normalizeAnchors() // Convert anchor tags missing href attribute into pre tags + } + + return doc.body().html() +} + +private fun Element.normalizeAnchors() { + getElementsByTag("a").forEach { + val link = it.attr("href") + if (link.isBlank()) { + it.changeInto("code") + } + } +} + +private fun Element.changeInto(tagName: String) { + replaceWith(Element(tagName).also { elem -> elem.appendChildren(childNodesCopy()) }) +} + /** * Write _exactly_ the text as written into the code writer without newlines or formatting */