【问题标题】:Highlighting in ACE editor that is embedded in R Shiny在嵌入在 R Shiny 中的 ACE 编辑器中突出显示
【发布时间】:2021-10-11 19:31:49
【问题描述】:

我尝试在嵌入在 R Shiny 应用程序中的 ace 编辑器中突出显示一组单词。我遵循了Want to highlight/change color of certain words in Ace Editor? 的建议,但是当我使用我的应用程序需要的aceEditor() 函数时,突出显示不起作用。但是,如果我将 aceEditor() 函数替换为 tags$body 命令(见下文),则突出显示有效。请在下面查看我的代码。我的问题:有没有办法使用 aceEditor() 函数突出显示?

这是一个示例,其中单词 Mark 应该以蓝色显示。

使用aceEditor(),失败:

library(shiny)
library(shinyAce)

htmlScript = "<script>\n define('ace/mode/custom', [], function(require, exports, module) {\n var oop = require(\"ace/lib/oop\");\n var TextMode = require(\"ace/mode/text\").Mode;"
htmlScript = paste0(htmlScript,"\n var Tokenizer = require(\"ace/tokenizer\").Tokenizer;\n var CustomHighlightRules = require(\"ace/mode/custom_highlight_rules\").CustomHighlightRules;")
htmlScript = paste0(htmlScript,"\n\n var Mode = function() {\n this.HighlightRules = CustomHighlightRules;\n};\n oop.inherits(Mode, TextMode);\n\n (function() {\n\n}).call(Mode.prototype);\n\n exports.Mode = Mode;\n});")
htmlScript = paste0(htmlScript,"\n define('ace/mode/custom_highlight_rules', [], function(require, exports, module) {\n var oop = require(\"ace/lib/oop\");\n var TextHighlightRules = require(\"ace/mode/text_highlight_rules\").TextHighlightRules;\n")
htmlScript = paste0(htmlScript,"\n var CustomHighlightRules = function() {\n\n var keywordMapper = this.createKeywordMapper({\n \"variable.language\": \"this\",\n \"keyword\": \"Mark|Ben|Bill\",\n \"constant.language\": \"true|false|null\",\n \"customTokenName\": \"problem\"\n}, \"text\", true);\n")
htmlScript = paste0(htmlScript,"\n this.$rules = {\n\"start\": [\n{\nregex: \"\\\\w+\\\\b\",\n token: keywordMapper\n},\n]\n};\n this.normalizeRules()\n};\n\n oop.inherits(CustomHighlightRules, TextHighlightRules);\n\n")
htmlScript = paste0(htmlScript,"\nexports.CustomHighlightRules = CustomHighlightRules;\n});\n\nvar editor = ace.edit(\"editor\");\n\n editor.session.setMode(\"ace/mode/custom\");\n</script>")
  
ui <- fluidPage(
  tags$head(HTML("<script src=\"https://ajaxorg.github.io/ace-builds/src/ace.js\"></script>")),

  aceEditor("editor", value="Mark", mode = "text"), #Mark should be highlighted with blue color

  tags$body(HTML(htmlScript))
)

server <- function(input, output, session){}

shinyApp(ui, server)

使用tags$body 命令,有效:

ui <- fluidPage(
  tags$head(HTML("<script src=\"https://ajaxorg.github.io/ace-builds/src/ace.js\"></script>")),

  tags$body(HTML("<div id=\"editor\" style=\"height: 500px; width: 800px\"></div>")),

  tags$body(HTML(htmlScript))
)

server <- function(input, output, session){}

shinyApp(ui, server)

请在编辑器中输入Mark这个词,它会显示为蓝色。

【问题讨论】:

    标签: r shiny highlight ace-editor


    【解决方案1】:

    shinyAce 包装对ace 库的调用。特别是定义语法高亮的mode。我不是JavaScript 方面的专家,因此,我不知道aceEditor 在哪里以及如何推翻您的手动设置,但我知道如何让您的自定义样式生效。

    1. 创建一个.js 文件,内容如下:

      ace.define('ace/mode/custom', [], function(require, exports, module) {
         var oop = require("ace/lib/oop");
         var TextMode = require("ace/mode/text").Mode;
         var Tokenizer = require("ace/tokenizer").Tokenizer;
         var CustomHighlightRules = 
         require("ace/mode/custom_highlight_rules").CustomHighlightRules;
      
         var Mode = function() {
              this.HighlightRules = CustomHighlightRules;
         };
         oop.inherits(Mode, TextMode);
         (function() {
         }).call(Mode.prototype);
         exports.Mode = Mode;
      });
      
      ace.define('ace/mode/custom_highlight_rules', [], function(require, exports, module) {
         var oop = require("ace/lib/oop");
         var TextHighlightRules = 
         require("ace/mode/text_highlight_rules").TextHighlightRules;
      
         var CustomHighlightRules = function() {
      
             var keywordMapper = this.createKeywordMapper({
                 "variable.language": "this",
                 "keyword": "Mark|Ben|Bill",
                 "constant.language": "true|false|null",
                 "customTokenName": "problem"
             }, "text", true);
      
             this.$rules = {
                 "start": [{
                     regex: "\\w+\\b",
                     token: keywordMapper
                 }, ]
             };
             this.normalizeRules()
         };
      
         oop.inherits(CustomHighlightRules, TextHighlightRules);
         exports.CustomHighlightRules = CustomHighlightRules;
      });
      

      特别注意使用ace.define 而不是define

    2. 将文件放在显示的文件夹中

      system.file("www/ace", package = "shinyAce")
      

      名称为mode-custom.js

    3. 然后你就设置好了,下面的代码正确地高亮了Mark

      library(shiny)
      library(shinyAce)
      ui <- fluidPage(
         aceEditor("editor", value = "Mark", mode = "custom") 
      )
      
      server <- function(input, output, session){}
      shinyApp(ui, server)
      


    更新

    其实你不需要将js存放在lib文件夹中,现场定义即可。只需确保您使用ace.define 并在aceEditor 中使用模式名称即可:

    library(shiny)
    library(shinyAce)
    
    htmlScript = "<script>\n ace.define('ace/mode/custom', [], function(require, exports, module) {\n var oop = require(\"ace/lib/oop\");\n var TextMode = require(\"ace/mode/text\").Mode;"
    htmlScript = paste0(htmlScript,"\n var Tokenizer = require(\"ace/tokenizer\").Tokenizer;\n var CustomHighlightRules = require(\"ace/mode/custom_highlight_rules\").CustomHighlightRules;")
    htmlScript = paste0(htmlScript,"\n\n var Mode = function() {\n this.HighlightRules = CustomHighlightRules;\n};\n oop.inherits(Mode, TextMode);\n\n (function() {\n\n}).call(Mode.prototype);\n\n exports.Mode = Mode;\n});")
    htmlScript = paste0(htmlScript,"\n ace.define('ace/mode/custom_highlight_rules', [], function(require, exports, module) {\n var oop = require(\"ace/lib/oop\");\n var TextHighlightRules = require(\"ace/mode/text_highlight_rules\").TextHighlightRules;\n")
    htmlScript = paste0(htmlScript,"\n var CustomHighlightRules = function() {\n\n var keywordMapper = this.createKeywordMapper({\n \"variable.language\": \"this\",\n \"keyword\": \"Mark|Ben|Bill|Thorn|ULL\",\n \"constant.language\": \"true|false|null\",\n \"customTokenName\": \"problem\"\n}, \"text\", true);\n")
    htmlScript = paste0(htmlScript,"\n this.$rules = {\n\"start\": [\n{\nregex: \"\\\\w+\\\\b\",\n token: keywordMapper\n},\n]\n};\n this.normalizeRules()\n};\n\n oop.inherits(CustomHighlightRules, TextHighlightRules);\n\n")
    htmlScript = paste0(htmlScript,"\nexports.CustomHighlightRules = CustomHighlightRules;\n});\n\nvar editor = ace.edit(\"editor\");\n\n editor.session.setMode(\"ace/mode/custom\");\n</script>")
      
    ui <- fluidPage(
      aceEditor("editor", value="Mark", mode = "custom"), #Mark should be highlighted with blue color
      tags$body(HTML(htmlScript))
    )
    
    server <- function(input, output, session){}
    
    shinyApp(ui, server)
    ``
    

    【讨论】:

    • 非常感谢!我可以补充:将模式更改为“自定义”很重要。我的版本中有“文本”,但它不起作用。
    • 是的,这就是我说的意思:“你在 aceEditor 中使用模式的名称”。 - 如果有帮助,请采纳答案。
    猜你喜欢
    • 2015-02-16
    • 1970-01-01
    • 1970-01-01
    • 2022-12-03
    • 1970-01-01
    • 2012-02-08
    • 1970-01-01
    • 2013-12-03
    • 2019-06-27
    相关资源
    最近更新 更多