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, "