From 0ecdcdeb7b515ce27e0a3dbc2905e5d72a058d3c Mon Sep 17 00:00:00 2001 From: Diego H Date: Wed, 6 Apr 2022 13:28:35 +0200 Subject: [PATCH] Improving package description auto-linking (#1315) Fixes #1265. Fixes #1164. --- NEWS.md | 3 ++ R/object-defaults.R | 1 + R/object-package.R | 29 ++++++++++++++++++ tests/testthat/test-object-package.R | 44 ++++++++++++++++++++++++++++ 4 files changed, 77 insertions(+) diff --git a/NEWS.md b/NEWS.md index 799e2186a..043e5992d 100644 --- a/NEWS.md +++ b/NEWS.md @@ -1,5 +1,8 @@ # roxygen2 (development version) +* DOIs, arXiv links, and urls in the `Description` field of the `DESCRIPTION` + are now converted to the appropriate Rd markup (@dieghernan, #1265, #1164). + * Arguments containing syntactically significant whitespace (e.g anonymous functions) are now wrapped correctly (#1281). diff --git a/R/object-defaults.R b/R/object-defaults.R index 59736e82a..a48ce69dc 100644 --- a/R/object-defaults.R +++ b/R/object-defaults.R @@ -41,6 +41,7 @@ object_defaults.package <- function(x) { desc <- x$value$desc description <- as.character(desc$Description) + description <- package_url_parse(description) logo_path <- file.path(x$value$path, "man", "figures", "logo.png") if (file.exists(logo_path)) { fig <- "\\if{html}{\\figure{logo.png}{options: align='right' alt='logo' width='120'}}" diff --git a/R/object-package.R b/R/object-package.R index c91cf278a..26f6e1397 100644 --- a/R/object-package.R +++ b/R/object-package.R @@ -374,3 +374,32 @@ itemize <- function(header, x) { "}\n" ) } + +package_url_parse <- function(x) { + # -> \doi{XX.XXX} to avoid CRAN Notes, etc. + x <- str_replace_all(x, "<(doi|DOI):(.*?)>", function(match) { + match <- str_remove_all(match, "^<(doi|DOI):|>$") + paste0("\\doi{", escape(match), "}") + }) + + # -> \url{http:XX.XXX} + x <- str_replace_all(x, "<(http|https):\\/\\/(.*?)>", function(match) { + match <- str_remove_all(match, "^<|>$") + paste0("\\url{", escape(match), "}") + }) + + # -> \href{https://arxiv.org/abs/XXX}{arXiv:XXX} + # https://github.com/wch/r-source/blob/trunk/src/library/tools/R/Rd2pdf.R#L149-L151 + patt_arxiv <- "<(arXiv:|arxiv:)([[:alnum:]/.-]+)([[:space:]]*\\[[^]]+\\])?>" + x <- str_replace_all(x, patt_arxiv, function(match) { + match <- str_remove_all(match, "^<(arXiv:|arxiv:)|>$") + # Special cases has . + # See https://CRAN.R-project.org/package=ciccr + # Extract arxiv id, split by space + arxiv_id <- str_split_fixed(match, " ", n = 2)[, 1] + + paste0("\\href{https://arxiv.org/abs/", escape(arxiv_id), "}{arXiv:", match, "}") + }) + + x +} diff --git a/tests/testthat/test-object-package.R b/tests/testthat/test-object-package.R index 76bccd604..6b6b44666 100644 --- a/tests/testthat/test-object-package.R +++ b/tests/testthat/test-object-package.R @@ -25,3 +25,47 @@ test_that("can convert DOIs in url", { "\\doi{10.5281/zenodo.1485309}" ) }) + +test_that("can autolink urls on package Description", { + expect_equal( + package_url_parse("x y"), + "x \\url{https://x.com} y" + ) + expect_equal( + package_url_parse("x y"), + "x \\url{https://x.com/\\%3C-\\%3E} y" + ) +}) + +test_that("can autolink DOIs", { + expect_equal(package_url_parse("x y"), "x \\doi{abcdef} y") + expect_equal(package_url_parse("x y"), "x \\doi{abcdef} y") + expect_equal(package_url_parse("x y"), "x \\doi{\\%3C-\\%3E} y") +}) + +test_that("can autolink arxiv", { + expect_equal( + package_url_parse("x y"), + "x \\href{https://arxiv.org/abs/abc}{arXiv:abc} y" + ) + expect_equal( + package_url_parse("x y"), + "x \\href{https://arxiv.org/abs/abc}{arXiv:abc} y" + ) + expect_equal( + package_url_parse("x y"), + "x \\href{https://arxiv.org/abs/abc}{arXiv:abc [def]} y" + ) +}) + +test_that("autolink several matching patterns", { + text <- "url doi arxiv " + expect_equal( + package_url_parse(text), + paste( + "url \\url{http://a.com}", + "doi \\doi{xx}", + "arxiv \\href{https://arxiv.org/abs/xx}{arXiv:xx}" + ) + ) +})