From 57b258c83f0ed4f2960200c6ff842a880266a666 Mon Sep 17 00:00:00 2001 From: mrcaseb Date: Tue, 19 Nov 2024 13:32:37 +0100 Subject: [PATCH 01/11] Allow discord venue --- R/reprex.R | 5 ++++- R/reprex_document.R | 2 +- R/reprex_impl.R | 5 +++-- R/venues.R | 4 ++++ 4 files changed, 12 insertions(+), 4 deletions(-) diff --git a/R/reprex.R b/R/reprex.R index d2cf4e05..3ffbddb1 100644 --- a/R/reprex.R +++ b/R/reprex.R @@ -113,6 +113,9 @@ #' * "ds" for Discourse, e.g., #' [forum.posit.co]( https://forum.posit.co/). Note: this is #' currently just an alias for "gh". +#' * "discord" for pasting into a Discord message. This is almost exactly the same +#' as "slack" but it removes a blank space between the opening backticks and the +#' language name, i.e. it returns " ` ```r ` " instead of " ` ``` r ` ". #' @param advertise Logical. Whether to include a footer that describes when and #' how the reprex was created. If unspecified, the option `reprex.advertise` #' is consulted and, if that is not defined, default is `TRUE` for venues @@ -262,7 +265,7 @@ #' @export reprex <- function(x = NULL, input = NULL, wd = NULL, - venue = c("gh", "r", "rtf", "html", "slack", "so", "ds"), + venue = c("gh", "r", "rtf", "html", "slack", "so", "ds", "discord"), render = TRUE, diff --git a/R/reprex_document.R b/R/reprex_document.R index 7fccbeb8..b3a37b54 100644 --- a/R/reprex_document.R +++ b/R/reprex_document.R @@ -32,7 +32,7 @@ #' @export #' @examples #' reprex_document() -reprex_document <- function(venue = c("gh", "r", "rtf", "html", "slack", "so", "ds"), +reprex_document <- function(venue = c("gh", "r", "rtf", "html", "slack", "so", "ds", "discord"), advertise = NULL, session_info = opt(FALSE), diff --git a/R/reprex_impl.R b/R/reprex_impl.R index 462dc201..38d3a2a5 100644 --- a/R/reprex_impl.R +++ b/R/reprex_impl.R @@ -1,7 +1,7 @@ reprex_impl <- function(x_expr = NULL, input = NULL, wd = NULL, - venue = c("gh", "r", "rtf", "html", "slack", "so", "ds"), + venue = c("gh", "r", "rtf", "html", "slack", "so", "ds", "discord"), render = TRUE, new_session = TRUE, @@ -115,7 +115,8 @@ advertise_default <- function(venue) { so = TRUE, r = FALSE, rtf = FALSE, - slack = FALSE + slack = FALSE, + discord = FALSE ) default[[venue]] } diff --git a/R/venues.R b/R/venues.R index 8c0d9931..5b47155e 100644 --- a/R/venues.R +++ b/R/venues.R @@ -26,6 +26,10 @@ reprex_rtf <- function(...) reprex(..., venue = "rtf") #' @rdname reprex_venue reprex_slack <- function(...) reprex(..., venue = "slack") +#' @export +#' @rdname reprex_venue +reprex_dircord <- function(...) reprex(..., venue = "discord") + # these should exist for completeness, but I predict they'd never get used and # they just clutter the auto-complete landscape # reprex_gh <- function(...) reprex(..., venue = "gh") From 207a71215e14c803b09cb30e5e6eda79e2c9b6f6 Mon Sep 17 00:00:00 2001 From: mrcaseb Date: Tue, 19 Nov 2024 13:33:15 +0100 Subject: [PATCH 02/11] discord util --- R/utils-io.R | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/R/utils-io.R b/R/utils-io.R index 1955aabd..434d1572 100644 --- a/R/utils-io.R +++ b/R/utils-io.R @@ -216,6 +216,10 @@ md_file_slack <- function(path) { path_mutate(path, suffix = "slack", ext = "md") } +md_file_discord <- function(path) { + path_mutate(path, suffix = "discord", ext = "md") +} + std_file <- function(path) { path_mutate(path, suffix = "std_out_err", ext = "txt") } From 10c47e24d6b398f638c3ae490affc302c17bcce3 Mon Sep 17 00:00:00 2001 From: mrcaseb Date: Tue, 19 Nov 2024 13:33:26 +0100 Subject: [PATCH 03/11] redocument --- man/reprex.Rd | 5 ++++- man/reprex_addin.Rd | 3 +++ man/reprex_document.Rd | 5 ++++- man/reprex_venue.Rd | 3 +++ man/un-reprex.Rd | 3 +++ 5 files changed, 17 insertions(+), 2 deletions(-) diff --git a/man/reprex.Rd b/man/reprex.Rd index d06798bd..46b8666d 100644 --- a/man/reprex.Rd +++ b/man/reprex.Rd @@ -8,7 +8,7 @@ reprex( x = NULL, input = NULL, wd = NULL, - venue = c("gh", "r", "rtf", "html", "slack", "so", "ds"), + venue = c("gh", "r", "rtf", "html", "slack", "so", "ds", "discord"), render = TRUE, advertise = NULL, session_info = opt(FALSE), @@ -69,6 +69,9 @@ support CommonMark-style fenced code blocks in January 2019. \item "ds" for Discourse, e.g., \href{https://forum.posit.co/}{forum.posit.co}. Note: this is currently just an alias for "gh". +\item "discord" for pasting into a Discord message. This is almost exactly the same +as "slack" but it removes a blank space between the opening backticks and the +language name, i.e. it returns " \verb{```r} " instead of " \verb{``` r} ". }} \item{render}{Logical. Whether to call \code{\link[rmarkdown:render]{rmarkdown::render()}} on the templated diff --git a/man/reprex_addin.Rd b/man/reprex_addin.Rd index 41910c0c..534a73ee 100644 --- a/man/reprex_addin.Rd +++ b/man/reprex_addin.Rd @@ -35,6 +35,9 @@ support CommonMark-style fenced code blocks in January 2019. \item "ds" for Discourse, e.g., \href{https://forum.posit.co/}{forum.posit.co}. Note: this is currently just an alias for "gh". +\item "discord" for pasting into a Discord message. This is almost exactly the same +as "slack" but it removes a blank space between the opening backticks and the +language name, i.e. it returns " \verb{```r} " instead of " \verb{``` r} ". }} } \description{ diff --git a/man/reprex_document.Rd b/man/reprex_document.Rd index 59f02639..6d7001df 100644 --- a/man/reprex_document.Rd +++ b/man/reprex_document.Rd @@ -5,7 +5,7 @@ \title{reprex output format} \usage{ reprex_document( - venue = c("gh", "r", "rtf", "html", "slack", "so", "ds"), + venue = c("gh", "r", "rtf", "html", "slack", "so", "ds", "discord"), advertise = NULL, session_info = opt(FALSE), style = opt(FALSE), @@ -41,6 +41,9 @@ support CommonMark-style fenced code blocks in January 2019. \item "ds" for Discourse, e.g., \href{https://forum.posit.co/}{forum.posit.co}. Note: this is currently just an alias for "gh". +\item "discord" for pasting into a Discord message. This is almost exactly the same +as "slack" but it removes a blank space between the opening backticks and the +language name, i.e. it returns " \verb{```r} " instead of " \verb{``` r} ". }} \item{advertise}{Logical. Whether to include a footer that describes when and diff --git a/man/reprex_venue.Rd b/man/reprex_venue.Rd index c1b9766a..6072a0d8 100644 --- a/man/reprex_venue.Rd +++ b/man/reprex_venue.Rd @@ -6,6 +6,7 @@ \alias{reprex_r} \alias{reprex_rtf} \alias{reprex_slack} +\alias{reprex_dircord} \title{Venue-specific shortcuts} \usage{ reprex_html(...) @@ -15,6 +16,8 @@ reprex_r(...) reprex_rtf(...) reprex_slack(...) + +reprex_dircord(...) } \arguments{ \item{...}{Passed along to \code{\link[=reprex]{reprex()}}.} diff --git a/man/un-reprex.Rd b/man/un-reprex.Rd index 16636f20..8babcec8 100644 --- a/man/un-reprex.Rd +++ b/man/un-reprex.Rd @@ -70,6 +70,9 @@ support CommonMark-style fenced code blocks in January 2019. \item "ds" for Discourse, e.g., \href{https://forum.posit.co/}{forum.posit.co}. Note: this is currently just an alias for "gh". +\item "discord" for pasting into a Discord message. This is almost exactly the same +as "slack" but it removes a blank space between the opening backticks and the +language name, i.e. it returns " \verb{```r} " instead of " \verb{``` r} ". }} \item{comment}{regular expression that matches commented output lines} From 5474f6fe9201ebf92a7670b525865f64648738c4 Mon Sep 17 00:00:00 2001 From: mrcaseb Date: Tue, 19 Nov 2024 13:33:45 +0100 Subject: [PATCH 04/11] version bump and export --- DESCRIPTION | 2 +- NAMESPACE | 1 + 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/DESCRIPTION b/DESCRIPTION index 2efb6244..1b23b01c 100644 --- a/DESCRIPTION +++ b/DESCRIPTION @@ -1,6 +1,6 @@ Package: reprex Title: Prepare Reproducible Example Code via the Clipboard -Version: 2.1.1.9000 +Version: 2.1.1.9001 Authors@R: c( person("Jennifer", "Bryan", , "jenny@posit.co", role = c("aut", "cre"), comment = c(ORCID = "0000-0002-6983-2759")), diff --git a/NAMESPACE b/NAMESPACE index 68165e11..465c3571 100644 --- a/NAMESPACE +++ b/NAMESPACE @@ -3,6 +3,7 @@ export(reprex) export(reprex_addin) export(reprex_clean) +export(reprex_dircord) export(reprex_document) export(reprex_html) export(reprex_invert) From 6c0b93161bf28a0029024461b608f41af7566c49 Mon Sep 17 00:00:00 2001 From: mrcaseb Date: Tue, 19 Nov 2024 13:34:00 +0100 Subject: [PATCH 05/11] venue test --- tests/testthat/test-venues.R | 20 ++++++++++++++++++++ 1 file changed, 20 insertions(+) diff --git a/tests/testthat/test-venues.R b/tests/testthat/test-venues.R index a6dbb0f8..fd2db9cd 100644 --- a/tests/testthat/test-venues.R +++ b/tests/testthat/test-venues.R @@ -112,3 +112,23 @@ test_that("venue = 'slack' works", { ret <- ret[nzchar(ret)] expect_identical(ret, output) }) + +test_that("venue = 'discord' works", { + skip_on_cran() + input <- c( + "#' Hello world", + "## comment", + "1:5" + ) + output <- c( + "Hello world", + "```r", + "## comment", + "1:5", + "#> [1] 1 2 3 4 5", + "```" + ) + ret <- reprex(input = input, venue = "discord") + ret <- ret[nzchar(ret)] + expect_identical(ret, output) +}) From 242fa8c0f3f128d6601274b1d0fefc10e823433b Mon Sep 17 00:00:00 2001 From: mrcaseb Date: Tue, 19 Nov 2024 13:35:57 +0100 Subject: [PATCH 06/11] fix simplify_image_links (see #473) --- R/reprex_render.R | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/R/reprex_render.R b/R/reprex_render.R index 72e82c1c..0bde979e 100644 --- a/R/reprex_render.R +++ b/R/reprex_render.R @@ -335,7 +335,14 @@ remove_info_strings <- function(x) { # input: ![](https://i.imgur.com/woc4vHs.png) # output: https://i.imgur.com/woc4vHs.png simplify_image_links <- function(x) { - sub("(^!\\[\\]\\()(.+)(\\)$)", "\\2", x, perl = TRUE) + x <- remove_empty_html_comments(x) + sub("(^!\\[\\]\\()(.+)(\\))$", "\\2", x, perl = TRUE) +} + +# input: ![](https://i.imgur.com/woc4vHs.png) +# output: ![](https://i.imgur.com/woc4vHs.png) +remove_empty_html_comments <- function(x){ + sub("", "", x, perl = TRUE) } # used when venue is "rtf" From 540d5693962fe95b6eaf94c5cbf3686711fdbced Mon Sep 17 00:00:00 2001 From: mrcaseb Date: Tue, 19 Nov 2024 13:36:14 +0100 Subject: [PATCH 07/11] discordify --- R/reprex_render.R | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) diff --git a/R/reprex_render.R b/R/reprex_render.R index 0bde979e..4d63693b 100644 --- a/R/reprex_render.R +++ b/R/reprex_render.R @@ -170,6 +170,7 @@ reprex_render_impl <- function(input, r = pp_md_to_r(md_file, comment = comment), rtf = pp_highlight(pp_md_to_r(md_file, comment = comment)), slack = pp_slackify(md_file), + discord = pp_discordify(md_file), html = pp_html_render(md_file), md_file ) @@ -326,12 +327,28 @@ pp_slackify <- function(input) { slack_file } +# used when venue is "discord" +# https://www.markdownguide.org/tools/discord/ +pp_discordify <- function(input) { + output_lines <- read_lines(md_file(input)) + output_lines <- discord_info_string(output_lines) + output_lines <- simplify_image_links(output_lines) + discord_file <- md_file_discord(input) + write_lines(output_lines, discord_file) + discord_file +} + # remove "info strings" from opening code fences, e.g. ```r # https://spec.commonmark.org/0.29/#info-string remove_info_strings <- function(x) { sub("^```[^`]*$", "```", x, perl = TRUE) } +# remove blank space from opening code fences, e.g. ``` r +discord_info_string <- function(x) { + sub("^```[[:blank:]]?", "```", x, perl = TRUE) +} + # input: ![](https://i.imgur.com/woc4vHs.png) # output: https://i.imgur.com/woc4vHs.png simplify_image_links <- function(x) { From 3815876ac01ee578c629257d663338a40e16a005 Mon Sep 17 00:00:00 2001 From: mrcaseb Date: Tue, 19 Nov 2024 13:36:52 +0100 Subject: [PATCH 08/11] news bullet --- NEWS.md | 3 +++ 1 file changed, 3 insertions(+) diff --git a/NEWS.md b/NEWS.md index dc0f76c4..262d30d5 100644 --- a/NEWS.md +++ b/NEWS.md @@ -1,5 +1,8 @@ # reprex (development version) +* New reprex `venue = "discord"` returns output that allows syntax highlighting in discord. (#474) +* Reprex venues `"slack"`, and `"discord"` now correctly simplify image hyperlinks. (#474) + # reprex 2.1.1 * `reprex(style = FALSE)` will never nag about installing styler (#461). From c962f9b1bbb9eac51ad0c8222c18463f4d1b2c25 Mon Sep 17 00:00:00 2001 From: mrcaseb <38586519+mrcaseb@users.noreply.github.com> Date: Sun, 9 Nov 2025 13:09:44 +0100 Subject: [PATCH 09/11] fix trailing `)` --- R/reprex_document.R | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/R/reprex_document.R b/R/reprex_document.R index 849ace5e..5eeb3aa6 100644 --- a/R/reprex_document.R +++ b/R/reprex_document.R @@ -33,7 +33,7 @@ #' @examples #' reprex_document() reprex_document <- function( - venue = c("gh", "r", "rtf", "html", "slack", "so", "ds", "discord")), + venue = c("gh", "r", "rtf", "html", "slack", "so", "ds", "discord"), advertise = NULL, session_info = opt(FALSE), From 0e80024df005b41e00e3540686564c5c874d1484 Mon Sep 17 00:00:00 2001 From: mrcaseb <38586519+mrcaseb@users.noreply.github.com> Date: Sun, 9 Nov 2025 13:10:42 +0100 Subject: [PATCH 10/11] air suggestion Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com> --- R/reprex_render.R | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/R/reprex_render.R b/R/reprex_render.R index 9990b226..725fbd7d 100644 --- a/R/reprex_render.R +++ b/R/reprex_render.R @@ -366,7 +366,7 @@ simplify_image_links <- function(x) { # input: ![](https://i.imgur.com/woc4vHs.png) # output: ![](https://i.imgur.com/woc4vHs.png) -remove_empty_html_comments <- function(x){ +remove_empty_html_comments <- function(x) { sub("", "", x, perl = TRUE) } From 51e1ebb0485ea028a427634adead4d6c7d523c23 Mon Sep 17 00:00:00 2001 From: mrcaseb <38586519+mrcaseb@users.noreply.github.com> Date: Sun, 9 Nov 2025 14:57:44 +0100 Subject: [PATCH 11/11] Typo --- R/venues.R | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/R/venues.R b/R/venues.R index efbe3a66..f9f60a98 100644 --- a/R/venues.R +++ b/R/venues.R @@ -28,7 +28,7 @@ reprex_slack <- function(...) reprex(..., venue = "slack") #' @export #' @rdname reprex_venue -reprex_dircord <- function(...) reprex(..., venue = "discord") +reprex_discord <- function(...) reprex(..., venue = "discord") # these should exist for completeness, but I predict they'd never get used and # they just clutter the auto-complete landscape