diff --git a/pkg-r/DESCRIPTION b/pkg-r/DESCRIPTION index 10f15fe..d2c72e3 100644 --- a/pkg-r/DESCRIPTION +++ b/pkg-r/DESCRIPTION @@ -26,6 +26,7 @@ Imports: ellmer (>= 0.4.1), evaluate, glue, + highr, htmltools, httr2 (>= 1.1.0), jsonlite, diff --git a/pkg-r/R/run-r.R b/pkg-r/R/run-r.R index 18d614c..891ec9d 100644 --- a/pkg-r/R/run-r.R +++ b/pkg-r/R/run-r.R @@ -236,7 +236,7 @@ run_r_html <- function(code, segments) { } code_html <- sprintf( "
%s",
- html_escape(paste(c(code, output), collapse = "\n"))
+ highlight_r_html(paste(c(code, output), collapse = "\n"))
)
if (length(plot_html)) {
code_html <- paste0(
@@ -251,6 +251,17 @@ run_r_html <- function(code, segments) {
)
}
+highlight_r_html <- function(code) {
+ fallback <- tryCatch(
+ {
+ parse(text = code)
+ FALSE
+ },
+ error = function(...) TRUE
+ )
+ paste(highr::hi_html(code, fallback = fallback), collapse = "\n")
+}
+
# --- worker lifecycle --------------------------------------------------------
new_r_worker <- function(network = "none", protection = "sandbox") {
diff --git a/pkg-r/inst/www/commons-chat/commons-chat.css b/pkg-r/inst/www/commons-chat/commons-chat.css
index 3cd7580..7424302 100644
--- a/pkg-r/inst/www/commons-chat/commons-chat.css
+++ b/pkg-r/inst/www/commons-chat/commons-chat.css
@@ -373,12 +373,55 @@ shiny-chat-container
text-transform: uppercase;
}
-.commons-run-r-code {
+.commons-run-r-display .commons-run-r-code {
margin: 0;
overflow-x: auto;
white-space: pre;
}
+.commons-run-r-code .hl.com {
+ color: #a0a1a7;
+ font-style: italic;
+}
+
+.commons-run-r-code .hl.kwa {
+ color: #a626a4;
+}
+
+.commons-run-r-code .hl.kwc,
+.commons-run-r-code .hl.num {
+ color: #986801;
+}
+
+.commons-run-r-code .hl.kwd {
+ color: #4078f2;
+}
+
+.commons-run-r-code .hl.sng {
+ color: #50a14f;
+}
+
+[data-bs-theme="dark"] .commons-run-r-code .hl.com {
+ color: #5c6370;
+}
+
+[data-bs-theme="dark"] .commons-run-r-code .hl.kwa {
+ color: #c678dd;
+}
+
+[data-bs-theme="dark"] .commons-run-r-code .hl.kwc,
+[data-bs-theme="dark"] .commons-run-r-code .hl.num {
+ color: #d19a66;
+}
+
+[data-bs-theme="dark"] .commons-run-r-code .hl.kwd {
+ color: #61aeee;
+}
+
+[data-bs-theme="dark"] .commons-run-r-code .hl.sng {
+ color: #98c379;
+}
+
.commons-run-r-details > .commons-run-r-code {
margin-top: 0.4rem;
}
diff --git a/pkg-r/tests/testthat/test-run-r.R b/pkg-r/tests/testthat/test-run-r.R
index 1738cc8..0da0638 100644
--- a/pkg-r/tests/testthat/test-run-r.R
+++ b/pkg-r/tests/testthat/test-run-r.R
@@ -33,6 +33,16 @@ test_that("run_r executes code against stored handles", {
'',
fixed = TRUE
)
+ expect_match(
+ res@extra$display$html,
+ 'sum',
+ fixed = TRUE
+ )
+ expect_match(
+ res@extra$display$html,
+ '#> [1] 5650',
+ fixed = TRUE
+ )
expect_match(res@extra$display$html, "#> [1] 5650", fixed = TRUE)
expect_no_match(res@extra$display$html, "x',
+ fixed = TRUE
+ )
+ expect_match(
+ res@extra$display$html,
+ '1',
+ fixed = TRUE
+ )
expect_match(res@extra$display$html, "commons-run-r-code", fixed = TRUE)
expect_no_match(res@extra$display$html, "#>", fixed = TRUE)
expect_no_match(res@extra$display$html, "' +", list())
+ )
+
+ expect_match(html, "'<unsafe>'", fixed = TRUE)
+ expect_no_match(html, "", fixed = TRUE)
+})
+
test_that("run_r displays worker failures directly and escapes their HTML", {
res <- run_r_result("x <- ''", list(failure = "worker "))
expect_match(res@value, "Error: worker ", fixed = TRUE)
expect_equal(res@extra$display$title, "Analyzed data")
expect_false(res@extra$display$open)
- expect_match(res@extra$display$html, "'<unsafe>'", fixed = TRUE)
+ expect_match(res@extra$display$html, "'<unsafe>'", fixed = TRUE)
expect_match(res@extra$display$html, "#> worker <broke>", fixed = TRUE)
expect_match(res@extra$display$html, "commons-run-r-code", fixed = TRUE)
expect_no_match(res@extra$display$html, "