diff --git a/R/markdown.R b/R/markdown.R index b682b1eec..b7c657fcc 100644 --- a/R/markdown.R +++ b/R/markdown.R @@ -333,7 +333,10 @@ mdxml_link <- function(xml, state) { } else if (dest == "" || dest == xml_text(xml)) { paste0("\\url{", escape_comment(xml_text(xml)), "}") } else { - paste0("\\href{", dest, "}{", mdxml_link_text(contents, state), "}") + paste0( + "\\href{", escape_comment(dest), "}", + "{", mdxml_link_text(contents, state), "}" + ) } } diff --git a/tests/testthat/test-markdown-link.R b/tests/testthat/test-markdown-link.R index e7c07cfdd..0db803049 100644 --- a/tests/testthat/test-markdown-link.R +++ b/tests/testthat/test-markdown-link.R @@ -446,3 +446,19 @@ test_that("linking to self is unqualified", { "foo \\code{\\link[=fun]{fun()}} and \\link{obj} bar" ) }) + +test_that("percents are escaped in link targets", { + out1 <- roc_proc_text(rd_roclet(), " + #' Title + #' + #' [link % text](https://foo.bar/link%20target) + #' @md + foo <- function() {}")[[1]] + out2 <- roc_proc_text(rd_roclet(), " + #' Title + #' + #' \\href{https://foo.bar/link%20target}{link % text} + #' @md + foo <- function() {}")[[1]] + expect_equivalent_rd(out1, out2) +})