-
Notifications
You must be signed in to change notification settings - Fork 22
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Support rgl and htmlwidgets in pkgdown #78
Changes from all commits
ae42fc7
0174171
8749b5c
cdcef74
53a50bf
93114a0
de9f8c6
ea56396
858ca55
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -11,6 +11,7 @@ | |
#' components `path`, `width`, and `height`. | ||
#' @param env Environment in which to evaluate code; if not supplied, | ||
#' defaults to a child of the global environment. | ||
#' @param output_handler Custom output handler for `evaluate::evaluate`. | ||
#' @return An string containing HTML. | ||
#' @inheritParams highlight | ||
#' @export | ||
|
@@ -19,10 +20,12 @@ | |
evaluate_and_highlight <- function(code, | ||
fig_save, | ||
classes = downlit::classes_pandoc(), | ||
env = NULL) { | ||
env = NULL, | ||
output_handler = evaluate::new_output_handler()) { | ||
env <- env %||% child_env(global_env()) | ||
|
||
expr <- evaluate::evaluate(code, child_env(env), new_device = TRUE) | ||
expr <- evaluate::evaluate(code, child_env(env), new_device = TRUE, | ||
output_handler = output_handler) | ||
replay_html(expr, fig_save = fig_save, fig_id = unique_id(), classes = classes) | ||
} | ||
|
||
|
@@ -47,13 +50,20 @@ replay_html.list <- function(x, ...) { | |
parts <- merge_low_plot(parts) | ||
|
||
pieces <- character(length(parts)) | ||
dependencies <- list() | ||
for (i in seq_along(parts)) { | ||
pieces[i] <- replay_html(parts[[i]], ...) | ||
piece <- replay_html(parts[[i]], ...) | ||
dependencies <- c(dependencies, attr(piece, "dependencies")) | ||
pieces[i] <- piece | ||
} | ||
res <- paste0(pieces, collapse = "") | ||
|
||
# convert ansi escapes | ||
res <- fansi::sgr_to_html(res) | ||
|
||
# get dependencies from htmlwidgets etc. | ||
attr(res, "dependencies") <- dependencies | ||
|
||
res | ||
} | ||
|
||
|
@@ -150,12 +160,19 @@ unique_id <- function() { | |
|
||
# get MD5 digests of recorded plots so that merge_low_plot works | ||
digest_plot = function(x, level = 1) { | ||
if (!is.list(x) || level >= 3) return(digest::digest(x)) | ||
if (inherits(x, "otherRecordedplot")) | ||
return(x) | ||
if (!is.list(x) || level >= 3) return(structure(digest::digest(x), | ||
class = "plot_digest")) | ||
lapply(x, digest_plot, level = level + 1) | ||
} | ||
|
||
is_plot_output = function(x) { | ||
evaluate::is.recordedplot(x) || inherits(x, 'otherRecordedplot') | ||
} | ||
|
||
# merge low-level plotting changes | ||
merge_low_plot = function(x, idx = sapply(x, evaluate::is.recordedplot)) { | ||
merge_low_plot = function(x, idx = vapply(x, is_plot_output, logical(1L))) { | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I'm slightly nervous about modifying this code since it came from knitr. Are you planning to submit changes there as well? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. As mentioned a similar change was submitted in yihui/knitr#1892 . There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I just took a closer look at yihui/knitr#1892 . It didn't change the default for |
||
idx = which(idx); n = length(idx); m = NULL # store indices that will be removed | ||
if (n <= 1) return(x) | ||
|
||
|
@@ -172,8 +189,18 @@ merge_low_plot = function(x, idx = sapply(x, evaluate::is.recordedplot)) { | |
if (is.null(m)) x else x[-m] | ||
} | ||
|
||
# compare two recorded plots | ||
#' Compare two recorded plots | ||
#' | ||
#' @param p1,p2 Plot results | ||
#' | ||
#' @return Logical value indicating whether `p2` is a low-level update of `p1`. | ||
#' @export | ||
is_low_change = function(p1, p2) { | ||
UseMethod("is_low_change") | ||
} | ||
|
||
#' @export | ||
is_low_change.default = function(p1, p2) { | ||
p1 = p1[[1]]; p2 = p2[[1]] # real plot info is in [[1]] | ||
if ((n2 <- length(p2)) < (n1 <- length(p1))) return(FALSE) # length must increase | ||
identical(p1[1:n1], p2[1:n1]) | ||
|
Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.
Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Does this class come from rgl?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This class currently only exists in
rgl
, where I used classc("rglRecordedPlot", "otherRecordedPlot")
for the object it's supposed to handle. The idea is that it's an object that has both high level and low level versions (like base graphics, whereplot()
produces high level changes, butpoints()
produces low level changes). You don't want to display every low level change, you just want to display the plot after the last one.As far as I know the only implementations of this style of graphics are base graphics and
rgl
(that was written to emulate base), so it's not really necessary now: but if anyone else ever writes one, they wouldn't want their plots to be handled likergl
plots in other respects.I submitted similar changes to
knitr
back in September (yihui/knitr#1892); Yihui hasn't merged them yet. In that PR I used the name"knitr_other_plot"
instead of"otherRecordedPlot"
, but I didn't like that name much, and it doesn't make sense to use it forpkgdown
. I will probably suggest modifying theknitr
PR to use the same name as used inpkgdown
, whatever that turns out to be.There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I forgot,
"otherRecordedPlot"
isn't just an object with high and low levels, it could also be used just to break up a sequence of those. For example,knitr
treats"knit_image_paths"
objects like plots when deciding whether to break up a sequence of base graphics calls. The change would add"otherRecordedPlot"
objects to the list of things that count as plots.