forked from coatless-r-n-d/webR-quarto-demos
-
Notifications
You must be signed in to change notification settings - Fork 10
/
_webr-setup.qmd
108 lines (96 loc) · 3.31 KB
/
_webr-setup.qmd
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
```{r}
#| results: asis
#| echo: false
webr_counter = 0
cat("importScripts('https://webr.r-wasm.org/v0.1.0/webr-worker.js');", file = "webr-worker.js")
cat("importScripts('https://webr.r-wasm.org/v0.1.0/webr-serviceworker.js');", file = "webr-serviceworker.js")
webr_editor = function(code = I(encodeString(code, quote = '`')), width, height) {
webr_counter <<- webr_counter + 1
output = glue::glue('
<button class="btn btn-default btn-webr" disabled type="button" id="webr-run-button-{{ webr_counter }}">Loading webR...</button>
<div id="webr-editor-{{ webr_counter }}"></div>
<div id="webr-code-output-{{ webr_counter }}"><pre style="visibility: hidden"></pre></div>
<script type="module">
const runButton = document.getElementById("webr-run-button-{{ webr_counter }}");
const outputDiv = document.getElementById("webr-code-output-{{ webr_counter }}");
const editorDiv = document.getElementById("webr-editor-{{ webr_counter }}");
const editor = CodeMirror((elt) => {
elt.style.border = "1px solid #eee";
elt.style.height = "auto";
editorDiv.append(elt);
},{
value: {{code}},
lineNumbers: true,
mode: "r",
theme: "light default",
viewportMargin: Infinity,
});
runButton.onclick = async () => {
runButton.disabled = true;
let canvas = undefined;
await globalThis.webR.init();
await webR.evalRVoid("canvas(width={{width}}, height={{height}})");
const result = await webRCodeShelter.captureR(editor.getValue(), {
withAutoprint: true,
captureStreams: true,
captureConditions: false,
env: webR.objs.emptyEnv,
});
try {
await webR.evalRVoid("dev.off()");
const out = result.output.filter(
evt => evt.type == "stdout" || evt.type == "stderr"
).map((evt) => evt.data).join("\\n");
const msgs = await webR.flush();
msgs.forEach(msg => {
if (msg.type === "canvasExec"){
if (!canvas) {
canvas = document.createElement("canvas");
canvas.setAttribute("width", 2 * {{width}});
canvas.setAttribute("height", 2 * {{height}});
canvas.style.width="700px";
canvas.style.display="block";
canvas.style.margin="auto";
}
Function(`this.getContext("2d").${msg.data}`).bind(canvas)();
}
});
outputDiv.innerHTML = "";
const pre = document.createElement("pre");
if (/\\S/.test(out)) {
const code = document.createElement("code");
code.innerText = out;
pre.appendChild(code);
} else {
pre.style.visibility = "hidden";
}
outputDiv.appendChild(pre);
if (canvas) {
const p = document.createElement("p");
p.appendChild(canvas);
outputDiv.appendChild(p);
}
} finally {
webRCodeShelter.purge();
runButton.disabled = false;
}
}
await globalThis.webR.init();
runButton.innerText = "Run code";
runButton.disabled = false;
</script>
', .open = "{{", .close = "}}")
}
```
```{r}
#| echo: false
knitr::knit_engines$set(webr = function(options) {
code = paste(options$code, collapse = "\n")
w = knitr::opts_current$get('fig.width') * 72
h = knitr::opts_current$get('fig.height') * 72
options$results = 'asis'
form = webr_editor(code = I(encodeString(code, quote = '`')), width = w, height = h)
form
}
)
```