Rmarkdown 中的 Raku 代码
安装
首先,首先安装 R
编程语言。在此之后,运行 R
并执行以下命令来安装 rmarkdown
: install.packages("rmarkdown")
。在安装 rmarkdown 时,我收到以下错误消息:
Error: .onLoad failed in loadNamespace() for 'tcltk', details:
call: dyn.load(file, DLLpath = DLLpath, ...)
error: unable to load shared object '/usr/lib/R/library/tcltk/libs/tcltk.so':
libtk8.6.so: cannot open shared object file: No such file or directory
这可以通过安装包 tk
来解决,然后继续安装 rmarkdown。
Rmarkdown 的代码块
你可以用 rmarkdown 做的几乎所有都可以用“常规” markdown 来做的事情。然而,rmarkdown 的一个突出特性是它能够执行代码块并返回结果。为此,rmarkdown 使用了 knitr 包,这是一个使用 R 生成动态报告的引擎,除了 R 之外,它还支持其他语言引擎,您可以使用这些引擎来计算来自其他语言的代码。要列出可用引擎的名称,请在 R REPL 中执行 names(knitr::knit_engines$get())
命令。就像“常规” markdown 一样,代码块可以用三个反勾号创建,然后是代码,最后是另外三个反勾号。如果希望计算代码块,请在花括号 {}
中指定语言,该语言位于前三个反勾号之后。例如,要执行 Perl 5 代码,可以在 {}
中指定 perl
:
```{perl}
sub factorial {
my ($n) = @_;
return 1 if $n == 0;
return factorial($n - 1) * $n;
}
for (1..4) {
print "Factorial of $_: ", factorial($_), "\n";
}
```
如果任何表达式求值了,将按照如下方式处理,结果将显示在源代码下面:
sub factorial {
my ($n) = @_;
return 1 if $n == 0;
return factorial($n - 1) * $n;
}
for (1..4) {
print "Factorial of $_: ", factorial($_), "\n";
}
## Factorial of 1: 1
## Factorial of 2: 2
## Factorial of 3: 6
## Factorial of 4: 24
代码块的选项可以在花括号中指定。例如,为了防止对代码块的计算,您必须将 eval
设置为 FALSE
:
```{perl, eval=FALSE}
my $name = 'Nemy';
print "Hello, $name!\n";
```
这阻止了代码块的求值,只显示源代码:
my $name = 'Nemy';
print "Hello, $name!\n";
要隐藏源代码并且仍然显示它的求值,可以将 echo
设置为 FALSE
:
```{perl, echo=FALSE}
my $name = 'Nemy';
print "Hello, $name!\n";
```
只有结果被展示出来:
## Hello, Nemy!
在花括号中可以指定一些选项。下面是我常用的一些选项的小列表:
- engine-默认为
R
。knitr
将用命名语言计算这个块,例如engine = 'python'
。 - eval-默认情况下为
TRUE
。如果为FALSE
, knitr 将不会在代码块中运行代码。 - echo-默认情况下为
TRUE
。如果为FALSE
, knitr 将不会在最终文档中显示其结果上面的代码块中的代码。 - collapse-默认为
FALSE
。如果为TRUE
,knitr 将把该块创建的所有源代码块和输出块折叠成单个块。 - comment-默认情况下是
##
。knitr 将在最终文档的每行结果的开头添加的一个字符串,例如comment = '#=>'
。
在这里可以找到关于不同选项的更多信息。
Rmarkdown 中的 Raku
到目前为止,knitr 不支持 Raku 的语言引擎。但是,您可以使用 knitr 的引擎语言可扩展性来执行 rmarkdown 中的 Raku 代码块,方法是在您的文件中添加以下 R 代码块:
```{r setup}
library(knitr)
eng_raku <- function(options) {
# create a temporary file
f <- basename(tempfile("raku", '.', paste('.', "raku", sep = '')))
on.exit(unlink(f)) # cleanup temp file on function exit
writeLines(options$code, f)
out <- ''
# if eval != FALSE compile/run the code, preserving output
if (options$eval) {
out <- system(sprintf('raku %s', paste(f, options$engine.opts)), intern=TRUE)
}
# spit back stuff to the user
engine_output(options, options$code, out)
}
knitr::knit_engines$set(raku=eng_raku)
```
这将允许你这样做:
```{r, engine='raku'}
say [*] 1..5;
```
但是,您可以使用 Perl 5 的引擎语言并通过将 engine.path
设置为 raku
使其路径更改为 Raku 可执行文件的路径,而不是在每个正在处理 Raku 代码的文件中添加这段 R 代码。然后,您可以通过如下方式处理 Raku 代码:
```{perl, engine.path='raku'}
say [*] 1..5;
```
现在您应该能够计算 Raku 代码块:
```{perl, engine.path='raku', comment='#=>', collapse=TRUE}
class Point {
has $.x = 0;
has $.y = 0;
method distance-to-center() {
return sqrt($!x**2 + $!y**2);
}
}
my $p = Point.new(x => 3, y => 4);
say $p.distance-to-center();
```
会被处理成如下这样:
class Point {
has $.x = 0;
has $.y = 0;
method distance-to-center() {
return sqrt($!x**2 + $!y**2);
}
}
my $p = Point.new(x => 3, y => 4);
say $p.distance-to-center();
#=> 5
补遗
这篇文章是受我的启发,我希望有一个简单的设置,转录课堂笔记使用 vim
。注释可能闪烁着 LATEX
,一些代码片段,并转换为 .pdf
文件,以便在此过程中进行审阅。rmarkdown 的易用性和广泛的功能使其成为这项工作的合适工具。
要从 vim 直接将 .rmd
转换为 .pdf
文件,我的 .vimrc
中有以下一行映射到 F5,以简化过程:
autocmd Filetype rmd map <F5> :!echo<space>"require(rmarkdown);
<space>render('<c-r>%')"<space>\|<space>R<space>--vanilla<enter>
如您所见,这只是在 R 中加载 rmarkdown 包,将当前 .rmd 文件传递给函数 render
,并将其结果传递给 R --vanilla
以使程序非交互式。
注意,您可能需要安装 pandoc
才能正常工作。对于 pandoc latex 模板,我使用了 eisvogel.latex 的一个稍微改进版本。
以下是所有注释的 YAML 前言(元数据)的示例:
---
title: "Raku in rmarkdown"
author: "Luis F. Uceta"
date: Aug 13, 2018
output:
pdf_document:
latex_engine: pdflatex
toc: true
template: eisvogel.latex
fontsize: 12pt
geometry: margin=1in
linkcolor: red
urlcolor: blue
---
这是这个文件的 pdf
,使用了之前的 YAML
前言和前面提到的 latex 模板。请注意,此 pdf 可能不反映对本文所做的最新更改。