如何使用 highlight.js 突出显示所有 R 函数名称?
How to highlight all R function names with highlight.js?
我想为 R
语言扩展 highlight.js
功能,以便 (1) 所有函数名称后跟左括号 (
和 (2) 后跟 ::
和 :::
运算符的所有包名称都将突出显示(就像在 RStudio 中一样,见图 1。) .括号 (
、)
和运算符 ::
、:::
不应突出显示。
图 1。 R
代码部分(函数和包名称)的所需突出显示。
我的示例包含两个文件:index.html
和 r.min.js
。
HTML 文件:
<html lang="en-us">
<head> <meta charset="utf-8">
<link href='https://cdnjs.cloudflare.com/ajax/libs/highlight.js/9.12.0/styles/agate.min.css' rel='stylesheet' type='text/css' />
</head>
<body>
<pre class="r"><code>doc_name <-
officer::read_docx() %>%
flextable:::body_add_flextable(table_to_save) %>%
print(target = "word.docx")
.libPaths()
c("a", "b")
package::function()$field
</code></pre>
<script src="https://cdn.jsdelivr.net/gh/highlightjs/cdn-release@9.12.0/build/highlight.min.js"></script>
<script src="r.min.js"></script>
<script>hljs.initHighlightingOnLoad();</script>
</body>
</html>
r.min.js
文件:
hljs.registerLanguage("r",function(e){var r="([a-zA-Z]|\.[a-zA-Z.])[a-zA-Z0-9._]*";return{c:[e.HCM,{b:r,l:r,k:{keyword:"function if in break next repeat else for return switch while try tryCatch stop warning require library attach detach source setMethod setGeneric setGroupGeneric setClass ...",literal:"NULL NA TRUE FALSE T F Inf NaN NA_integer_|10 NA_real_|10 NA_character_|10 NA_complex_|10"},r:0},{cN:"number",b:"0[xX][0-9a-fA-F]+[Li]?\b",r:0},{cN:"number",b:"\d+(?:[eE][+\-]?\d*)?L\b",r:0},{cN:"number",b:"\d+\.(?!\d)(?:i\b)?",r:0},{cN:"number",b:"\d+(?:\.\d*)?(?:[eE][+\-]?\d*)?i?\b",r:0},{cN:"number",b:"\.\d+(?:[eE][+\-]?\d*)?i?\b",r:0},{b:"`",e:"`",r:0},{cN:"string",c:[e.BE],v:[{b:'"',e:'"'},{b:"'",e:"'"}]},
/* My attempt... */
/* ... to highlight function names between double
and triple colons and opening parenthesis (in red as symbol): */
{cN:"symbol",b:":::|::",e:"\(",eB:!0,eE:!0},
/* ... to highlight other function names (in red as symbol): */
{cN:"symbol", b:"([a-zA-Z]|\.[a-zA-Z.])[a-zA-Z0-9._]*",e:"\(",eE:!0},
/* ... to highlight package names (in cyan as variable): */
{cN:"variable",b:"(?<!\w)",e:":::|::",eE:!0},
]}});
r.min.js
基于 (this file) 并包含 highlight.js
规则来识别 r
代码元素。
我添加的行在评论下面 "My attempt." 缩写的含义:cN
- css class name, b
- "beggins", e
-"ends",eB
-"exclude begin",eE
-"exclude end",其他含义解释here.
我得到的结果(图2)并不令人满意。似乎我使用的正则表达式找不到 R
代码所需部分的正确开头和结尾。
图2.使用修改后的结果r.min.js
r.min.js
中正确的 highlight.js
代码应该是什么,才能使 R
代码的部分像在 RStudio 中一样突出显示?
听起来像是一个值得改进的地方,所以我修改了一段时间。
这应该很容易,
捕获包名称前缀的正则表达式可以这样写 (demo):
\w+(?=:::?)
对于这样的函数名称 (demo):
\.?\w+(?=\()
不幸的是,它并不那么容易应用于 highlight.js 语言解析规则。
经过一些回溯、跟踪和错误,我确定了以下代码,它给出了非常一致的突出显示:
/* ... to highlight other function names (in orange as a keyword): */
{
cN: "keyword",
b: /(^|\s*)(:::?|\.)\w+(?=\(|$)/
},
/* ... to highlight package names (in red as meta): */
{
cN: "meta",
b: /(^|\s*)\w+(?=:::?|$)/,
r: 0
},
- 我将 cN|className
keyword
用于函数,这就是它的本质,它对函数的预定义样式的干扰较小。
- 我建议使用 cN
meta
的软件包名称也是如此。这是其他包用于类似构造的,并且它再次为内置样式提供了更一致的结果,例如数字。
- 我还在关键字列表中添加了
print
和 c
。 R 语言的列表显然有些不完整。可以说每个函数名称(甚至来自 3rd 方包)都应该作为关键字添加——这是其他一些语言的做法——但这不是很实用)。
这就是我get.
示例代码:
hljs.registerLanguage("r",function(e){var r="([a-zA-Z]|\.[a-zA-Z.])[a-zA-Z0-9._]*";return{c:[e.HCM,{b:r,l:r,k:{keyword:"function if in break next repeat else for return switch while try tryCatch stop warning require library attach detach source setMethod setGeneric setGroupGeneric setClass c print ...",literal:"NULL NA TRUE FALSE T F Inf NaN NA_integer_|10 NA_real_|10 NA_character_|10 NA_complex_|10"},r:0},{cN:"number",b:"0[xX][0-9a-fA-F]+[Li]?\b",r:0},{cN:"number",b:"\d+(?:[eE][+\-]?\d*)?L\b",r:0},{cN:"number",b:"\d+\.(?!\d)(?:i\b)?",r:0},{cN:"number",b:"\d+(?:\.\d*)?(?:[eE][+\-]?\d*)?i?\b",r:0},{cN:"number",b:"\.\d+(?:[eE][+\-]?\d*)?i?\b",r:0},{b:"`",e:"`",r:0},{cN:"string",c:[e.BE],v:[{b:'"',e:'"'},{b:"'",e:"'"}]},
{cN: "keyword", b: /(^|\s*)(:::?|\.)\w+(?=\(|$)/},
{cN: "meta",b: /(^|\s*)\w+(?=:::?|$)/,r: 0 }, ]}});
hljs.initHighlightingOnLoad();
<html lang="en-us">
<head> <meta charset="utf-8"><link href='https://cdnjs.cloudflare.com/ajax/libs/highlight.js/9.12.0/styles/agate.min.css' rel='stylesheet' type='text/css' />
</head><body>
<pre class="r"><code>library(officer)
doc_name <-
officer::read_docx() %>%
flextable:::body_add_flextable(table_to_save) %>%
print(target = "word.docx")
.libPaths()
x = 4
c("a", "b")
package::function()$field
</code></pre>
<script src="https://cdn.jsdelivr.net/gh/highlightjs/cdn-release@9.12.0/build/highlight.min.js"></script>
</body></html>
非常接近,但远非完美。这里的主要障碍是我很难完全理解解析器如何解释模式。有些结果对我来说根本没有意义,但是 still work.
我想为 R
语言扩展 highlight.js
功能,以便 (1) 所有函数名称后跟左括号 (
和 (2) 后跟 ::
和 :::
运算符的所有包名称都将突出显示(就像在 RStudio 中一样,见图 1。) .括号 (
、)
和运算符 ::
、:::
不应突出显示。
R
代码部分(函数和包名称)的所需突出显示。
我的示例包含两个文件:index.html
和 r.min.js
。
HTML 文件:
<html lang="en-us">
<head> <meta charset="utf-8">
<link href='https://cdnjs.cloudflare.com/ajax/libs/highlight.js/9.12.0/styles/agate.min.css' rel='stylesheet' type='text/css' />
</head>
<body>
<pre class="r"><code>doc_name <-
officer::read_docx() %>%
flextable:::body_add_flextable(table_to_save) %>%
print(target = "word.docx")
.libPaths()
c("a", "b")
package::function()$field
</code></pre>
<script src="https://cdn.jsdelivr.net/gh/highlightjs/cdn-release@9.12.0/build/highlight.min.js"></script>
<script src="r.min.js"></script>
<script>hljs.initHighlightingOnLoad();</script>
</body>
</html>
r.min.js
文件:
hljs.registerLanguage("r",function(e){var r="([a-zA-Z]|\.[a-zA-Z.])[a-zA-Z0-9._]*";return{c:[e.HCM,{b:r,l:r,k:{keyword:"function if in break next repeat else for return switch while try tryCatch stop warning require library attach detach source setMethod setGeneric setGroupGeneric setClass ...",literal:"NULL NA TRUE FALSE T F Inf NaN NA_integer_|10 NA_real_|10 NA_character_|10 NA_complex_|10"},r:0},{cN:"number",b:"0[xX][0-9a-fA-F]+[Li]?\b",r:0},{cN:"number",b:"\d+(?:[eE][+\-]?\d*)?L\b",r:0},{cN:"number",b:"\d+\.(?!\d)(?:i\b)?",r:0},{cN:"number",b:"\d+(?:\.\d*)?(?:[eE][+\-]?\d*)?i?\b",r:0},{cN:"number",b:"\.\d+(?:[eE][+\-]?\d*)?i?\b",r:0},{b:"`",e:"`",r:0},{cN:"string",c:[e.BE],v:[{b:'"',e:'"'},{b:"'",e:"'"}]},
/* My attempt... */
/* ... to highlight function names between double
and triple colons and opening parenthesis (in red as symbol): */
{cN:"symbol",b:":::|::",e:"\(",eB:!0,eE:!0},
/* ... to highlight other function names (in red as symbol): */
{cN:"symbol", b:"([a-zA-Z]|\.[a-zA-Z.])[a-zA-Z0-9._]*",e:"\(",eE:!0},
/* ... to highlight package names (in cyan as variable): */
{cN:"variable",b:"(?<!\w)",e:":::|::",eE:!0},
]}});
r.min.js
基于 (this file) 并包含 highlight.js
规则来识别 r
代码元素。
我添加的行在评论下面 "My attempt." 缩写的含义:cN
- css class name, b
- "beggins", e
-"ends",eB
-"exclude begin",eE
-"exclude end",其他含义解释here.
我得到的结果(图2)并不令人满意。似乎我使用的正则表达式找不到 R
代码所需部分的正确开头和结尾。
图2.使用修改后的结果r.min.js
r.min.js
中正确的 highlight.js
代码应该是什么,才能使 R
代码的部分像在 RStudio 中一样突出显示?
听起来像是一个值得改进的地方,所以我修改了一段时间。
这应该很容易,
捕获包名称前缀的正则表达式可以这样写 (demo):
\w+(?=:::?)
对于这样的函数名称 (demo):
\.?\w+(?=\()
不幸的是,它并不那么容易应用于 highlight.js 语言解析规则。
经过一些回溯、跟踪和错误,我确定了以下代码,它给出了非常一致的突出显示:
/* ... to highlight other function names (in orange as a keyword): */
{
cN: "keyword",
b: /(^|\s*)(:::?|\.)\w+(?=\(|$)/
},
/* ... to highlight package names (in red as meta): */
{
cN: "meta",
b: /(^|\s*)\w+(?=:::?|$)/,
r: 0
},
- 我将 cN|className
keyword
用于函数,这就是它的本质,它对函数的预定义样式的干扰较小。 - 我建议使用 cN
meta
的软件包名称也是如此。这是其他包用于类似构造的,并且它再次为内置样式提供了更一致的结果,例如数字。 - 我还在关键字列表中添加了
print
和c
。 R 语言的列表显然有些不完整。可以说每个函数名称(甚至来自 3rd 方包)都应该作为关键字添加——这是其他一些语言的做法——但这不是很实用)。
这就是我get.
示例代码:
hljs.registerLanguage("r",function(e){var r="([a-zA-Z]|\.[a-zA-Z.])[a-zA-Z0-9._]*";return{c:[e.HCM,{b:r,l:r,k:{keyword:"function if in break next repeat else for return switch while try tryCatch stop warning require library attach detach source setMethod setGeneric setGroupGeneric setClass c print ...",literal:"NULL NA TRUE FALSE T F Inf NaN NA_integer_|10 NA_real_|10 NA_character_|10 NA_complex_|10"},r:0},{cN:"number",b:"0[xX][0-9a-fA-F]+[Li]?\b",r:0},{cN:"number",b:"\d+(?:[eE][+\-]?\d*)?L\b",r:0},{cN:"number",b:"\d+\.(?!\d)(?:i\b)?",r:0},{cN:"number",b:"\d+(?:\.\d*)?(?:[eE][+\-]?\d*)?i?\b",r:0},{cN:"number",b:"\.\d+(?:[eE][+\-]?\d*)?i?\b",r:0},{b:"`",e:"`",r:0},{cN:"string",c:[e.BE],v:[{b:'"',e:'"'},{b:"'",e:"'"}]},
{cN: "keyword", b: /(^|\s*)(:::?|\.)\w+(?=\(|$)/},
{cN: "meta",b: /(^|\s*)\w+(?=:::?|$)/,r: 0 }, ]}});
hljs.initHighlightingOnLoad();
<html lang="en-us">
<head> <meta charset="utf-8"><link href='https://cdnjs.cloudflare.com/ajax/libs/highlight.js/9.12.0/styles/agate.min.css' rel='stylesheet' type='text/css' />
</head><body>
<pre class="r"><code>library(officer)
doc_name <-
officer::read_docx() %>%
flextable:::body_add_flextable(table_to_save) %>%
print(target = "word.docx")
.libPaths()
x = 4
c("a", "b")
package::function()$field
</code></pre>
<script src="https://cdn.jsdelivr.net/gh/highlightjs/cdn-release@9.12.0/build/highlight.min.js"></script>
</body></html>
非常接近,但远非完美。这里的主要障碍是我很难完全理解解析器如何解释模式。有些结果对我来说根本没有意义,但是 still work.