From 8fd3f5159d522cd2b08836dab4c575c1ec816044 Mon Sep 17 00:00:00 2001 From: Martin Elff Date: Fri, 22 Dec 2023 15:19:25 +0100 Subject: [PATCH] Added support for special comments '#+opt:' and '#+par:' With a special comment starting with '#+opt:' it is now possible to set the options locally for a single notebook cell. The same could be achieved by calling 'RKernel::cell.options()' but this will lead to errors if the code of the cell is exported into a script or Rmarkdown file, etc. In the same way, a special comment starting with '#+par:' can be used to set the graphics parameters for a single notebook cell. --- pkg/DESCRIPTION | 4 ++-- pkg/R/evaluator.R | 45 +++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 47 insertions(+), 2 deletions(-) diff --git a/pkg/DESCRIPTION b/pkg/DESCRIPTION index 07db2d6..0bb5b41 100644 --- a/pkg/DESCRIPTION +++ b/pkg/DESCRIPTION @@ -1,7 +1,7 @@ Package: RKernel Title: Yet another R kernel for Jupyter -Version: 0.5 -Date: 2023-09-10 +Version: 0.6 +Date: 2023-12-22 Authors@R: c( person('Martin', 'Elff', email = 'martin@elff.eu', diff --git a/pkg/R/evaluator.R b/pkg/R/evaluator.R index 6db1117..9580f72 100644 --- a/pkg/R/evaluator.R +++ b/pkg/R/evaluator.R @@ -187,6 +187,11 @@ Evaluator <- R6Class("Evaluator", # log_out(sys.frames(),use.print=TRUE) # log_out(sys.parents(),use.print=TRUE) + cparsed <- private$parse_special_comments(code) + if(length(cparsed)){ + private$context$evaluate(cparsed,envir=.GlobalEnv) + } + private$results <- list() if(private$aborted) return(private$results) @@ -1044,7 +1049,47 @@ Evaluator <- R6Class("Evaluator", obj <- get(n,envir=exports) assign(n,obj,envir=private$env) } + }, + + parse_special_comments = function(code){ + exprs <- list() + opt_exprs <- private$parse_opt_special_comments(code) + par_exprs <- NULL + par_exprs <- private$parse_par_special_comments(code) + c(opt_exprs,par_exprs) + }, + + parse_opt_special_comments = function(code){ + code <- getMatch(code,gregexpr("#\\+opt:.*",code,perl=TRUE)) + if(length(code) && any(nzchar(code))){ + code <- gsub("#+opt:","",code,fixed=TRUE) + code <- trimws(code) + code <- paste0("cell.options(",code,")") + expr <- parse(text=code) + for(i in seq_along(expr)){ + expr[[i]][[1]] <- self$cell.options + } + } + else expr <- NULL + expr + }, + + parse_par_special_comments = function(code){ + code <- getMatch(code,gregexpr("#\\+par:.*?\n",code)) + if(length(code) && any(nzchar(code))){ + code <- gsub("#+par:","",code,fixed=TRUE) + code <- trimws(code) + code <- paste0("cell.par(",code,")") + expr <- parse(text=code) + for(i in seq_along(expr)){ + expr[[i]][[1]] <- self$cell.par + } + } + else expr <- NULL + expr } + + ) )