Skip to content

Commit d18c964

Browse files
committed
Deploying to gh-pages from @ 8ad65f0 🚀
1 parent c38f7c0 commit d18c964

File tree

173 files changed

+9497
-5711
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

173 files changed

+9497
-5711
lines changed

demos/qwebr-auto-run.html

+123-57
Large diffs are not rendered by default.

demos/qwebr-code-cell-options.html

+123-57
Large diffs are not rendered by default.

demos/qwebr-custom-repository.html

+123-57
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22
<html xmlns="http://www.w3.org/1999/xhtml" lang="en" xml:lang="en"><head>
33

44
<meta charset="utf-8">
5-
<meta name="generator" content="quarto-1.6.4">
5+
<meta name="generator" content="quarto-1.6.25">
66

77
<meta name="viewport" content="width=device-width, initial-scale=1.0, user-scalable=yes">
88

@@ -69,11 +69,11 @@
6969
<script src="../site_libs/quarto-html/tippy.umd.min.js"></script>
7070
<script src="../site_libs/quarto-html/anchor.min.js"></script>
7171
<link href="../site_libs/quarto-html/tippy.css" rel="stylesheet">
72-
<link href="../site_libs/quarto-html/quarto-syntax-highlighting.css" rel="stylesheet" class="quarto-color-scheme" id="quarto-text-highlighting-styles">
73-
<link href="../site_libs/quarto-html/quarto-syntax-highlighting-dark.css" rel="prefetch" class="quarto-color-scheme quarto-color-alternate" id="quarto-text-highlighting-styles">
72+
<link href="../site_libs/quarto-html/quarto-syntax-highlighting-018089954d508eae8a473f0b7f0491f0.css" rel="stylesheet" class="quarto-color-scheme" id="quarto-text-highlighting-styles">
73+
<link href="../site_libs/quarto-html/quarto-syntax-highlighting-dark-5223d57514b7f3c9e8f675d86406bf62.css" rel="prefetch" class="quarto-color-scheme quarto-color-alternate" id="quarto-text-highlighting-styles">
7474
<script src="../site_libs/bootstrap/bootstrap.min.js"></script>
7575
<link href="../site_libs/bootstrap/bootstrap-icons.css" rel="stylesheet">
76-
<link href="../site_libs/bootstrap/bootstrap.min.css" rel="stylesheet" class="quarto-color-scheme" id="quarto-bootstrap" data-mode="light">
76+
<link href="../site_libs/bootstrap/bootstrap-e127080b54728d29fe72abdaeabf2e9f.min.css" rel="stylesheet" append-hash="true" class="quarto-color-scheme" id="quarto-bootstrap" data-mode="light">
7777
<link href="../site_libs/bootstrap/bootstrap-dark.min.css" rel="prefetch" class="quarto-color-scheme quarto-color-alternate" id="quarto-bootstrap" data-mode="dark">
7878
<script id="quarto-search-options" type="application/json">{
7979
"location": "sidebar",
@@ -329,7 +329,7 @@
329329
max-height: 100%;
330330
margin: 0;
331331
padding: 0;
332-
}
332+
}
333333

334334
/* Provide space to entries */
335335
.reveal div.qwebr-output-code-area pre div {
@@ -374,6 +374,16 @@
374374
overflow: scroll;
375375
}
376376

377+
iframe.qwebr-output-code-browse {
378+
width: 100%;
379+
380+
/*
381+
TODO: How to make the height automatic according to the widget size,
382+
or respect the quarto code block options?
383+
*/
384+
min-height: 500px;
385+
}
386+
377387
</style>
378388
<script type="module">
379389
// Document level settings ----
@@ -401,7 +411,7 @@
401411
};
402412

403413
// Store cell data
404-
globalThis.qwebrCellDetails = [{"id":1,"options":{"message":"true","editor-word-wrap":"true","output":"true","classes":"","editor-font-scale":"1","dpi":72,"out-width":"700px","read-only":"false","editor-max-height":"","context":"interactive","fig-height":5,"warning":"true","out-height":"","results":"markup","comment":"","fig-width":7,"label":"unnamed-chunk-1","fig-cap":"","editor-quick-suggestions":"false","autorun":"false"},"code":"# Check to see if the function works\ndemorwasmbinary::in_webr()\n\n# View help documentation\n?demorwasmbinary::in_webr"}];
414+
globalThis.qwebrCellDetails = [{"id":1,"code":"# Check to see if the function works\ndemorwasmbinary::in_webr()\n\n# View help documentation\n?demorwasmbinary::in_webr","options":{"fig-cap":"","message":"true","autorun":"false","editor-word-wrap":"true","fig-width":7,"out-width":"700px","classes":"","read-only":"false","results":"markup","label":"unnamed-chunk-1","dpi":72,"comment":"","context":"interactive","warning":"true","editor-quick-suggestions":"false","output":"true","editor-font-scale":"1","fig-height":5,"editor-max-height":"","out-height":""}}];
405415

406416
</script>
407417
<script type="module">
@@ -1223,11 +1233,15 @@
12231233
// Setup a shelter
12241234
globalThis.mainWebRCodeShelter = await new mainWebR.Shelter();
12251235

1226-
// Setup a pager to allow processing help documentation
1227-
await mainWebR.evalRVoid('webr::pager_install()');
1236+
// Setup a pager to allow processing help documentation
1237+
await mainWebR.evalRVoid('webr::pager_install()');
1238+
1239+
// Setup a viewer to allow processing htmlwidgets.
1240+
// This might not be available in old webr version
1241+
await mainWebR.evalRVoid('try({ webr::viewer_install() })');
12281242

12291243
// Override the existing install.packages() to use webr::install()
1230-
await mainWebR.evalRVoid('webr::shim_install()');
1244+
await mainWebR.evalRVoid('webr::shim_install()');
12311245

12321246
// Specify the repositories to pull from
12331247
// Note: webR does not use the `repos` option, but instead uses `webr_pkg_repos`
@@ -1265,7 +1279,7 @@
12651279
return Object.keys(arr).length === 0;
12661280
}
12671281

1268-
// Global version of the Escape HTML function that converts HTML
1282+
// Global version of the Escape HTML function that converts HTML
12691283
// characters to their HTML entities.
12701284
globalThis.qwebrEscapeHTMLCharacters = function(unsafe) {
12711285
return unsafe
@@ -1274,7 +1288,7 @@
12741288
.replace(/>/g, "&gt;")
12751289
.replace(/"/g, "&quot;")
12761290
.replace(/'/g, "&#039;");
1277-
};
1291+
};
12781292

12791293
// Passthrough results
12801294
globalThis.qwebrIdentity = function(x) {
@@ -1291,7 +1305,7 @@
12911305
qwebrRCommandHistory.push(
12921306
`# Ran code in ${options.label} at ${new Date().toLocaleString()} ----\n${codeToRun}`
12931307
);
1294-
}
1308+
};
12951309

12961310
// Function to attach a download button onto the canvas
12971311
// allowing the user to download the image.
@@ -1311,14 +1325,14 @@
13111325
link.download = 'qwebr-canvas-image.png';
13121326
link.click();
13131327
});
1314-
}
1315-
1328+
}
1329+
13161330

13171331
// Function to parse the pager results
1318-
globalThis.qwebrParseTypePager = async function (msg) {
1332+
globalThis.qwebrParseTypePager = async function (msg) {
13191333

13201334
// Split out the event data
1321-
const { path, title, deleteFile } = msg.data;
1335+
const { path, title, deleteFile } = msg.data;
13221336

13231337
// Process the pager data by reading the information from disk
13241338
const paged_data = await mainWebR.FS.readFile(path).then((data) => {
@@ -1327,30 +1341,49 @@
13271341

13281342
// Remove excessive backspace characters until none remain
13291343
while(content.match(/.[\b]/)){
1330-
content = content.replace(/.[\b]/g, '');
1344+
content = content.replace(/.[\b]/g, '');
13311345
}
13321346

13331347
// Returned cleaned data
13341348
return content;
13351349
});
13361350

13371351
// Unlink file if needed
1338-
if (deleteFile) {
1339-
await mainWebR.FS.unlink(path);
1340-
}
1352+
if (deleteFile) {
1353+
await mainWebR.FS.unlink(path);
1354+
}
13411355

13421356
// Return extracted data with spaces
13431357
return paged_data;
1344-
}
1358+
};
1359+
1360+
1361+
// Function to parse the browse results
1362+
globalThis.qwebrParseTypeBrowse = async function (msg) {
1363+
1364+
// msg.type === "browse"
1365+
const path = msg.data.url;
1366+
1367+
// Process the browse data by reading the information from disk
1368+
const browse_data = await mainWebR.FS.readFile(path).then((data) => {
1369+
// Obtain the file content
1370+
let content = new TextDecoder().decode(data);
1371+
1372+
return content;
1373+
});
1374+
1375+
// Return extracted data as-is
1376+
return browse_data;
1377+
};
13451378

13461379
// Function to run the code using webR and parse the output
13471380
globalThis.qwebrComputeEngine = async function(
1348-
codeToRun,
1349-
elements,
1381+
codeToRun,
1382+
elements,
13501383
options) {
13511384

13521385
// Call into the R compute engine that persists within the document scope.
1353-
// To be prepared for all scenarios, the following happens:
1386+
// To be prepared for all scenarios, the following happens:
13541387
// 1. We setup a canvas device to write to by making a namespace call into the {webr} package
13551388
// 2. We use values inside of the options array to set the figure size.
13561389
// 3. We capture the output stream information (STDOUT and STERR)
@@ -1370,11 +1403,11 @@
13701403
processOutput = qwebrIdentity;
13711404
}
13721405

1373-
// ----
1406+
// ----
13741407
// Convert from Inches to Pixels by using DPI (dots per inch)
13751408
// for bitmap devices (dpi * inches = pixels)
1376-
let fig_width = options["fig-width"] * options["dpi"]
1377-
let fig_height = options["fig-height"] * options["dpi"]
1409+
let fig_width = options["fig-width"] * options["dpi"];
1410+
let fig_height = options["fig-height"] * options["dpi"];
13781411

13791412
// Initialize webR
13801413
await mainWebR.init();
@@ -1386,7 +1419,7 @@
13861419
captureConditions: false,
13871420
// env: webR.objs.emptyEnv, // maintain a global environment for webR v0.2.0
13881421
};
1389-
1422+
13901423
// Determine if the browser supports OffScreen
13911424
if (qwebrOffScreenCanvasSupport()) {
13921425
// Mirror default options of webr::canvas()
@@ -1418,18 +1451,18 @@
14181451

14191452
// Start attempting to parse the result data
14201453
processResultOutput:try {
1421-
1454+
14221455
// Avoid running through output processing
1423-
if (options.results === "hide" || options.output === "false") {
1424-
break processResultOutput;
1456+
if (options.results === "hide" || options.output === "false") {
1457+
break processResultOutput;
14251458
}
14261459

14271460
// Merge output streams of STDOUT and STDErr (messages and errors are combined.)
1428-
// Require both `warning` and `message` to be true to display `STDErr`.
1461+
// Require both `warning` and `message` to be true to display `STDErr`.
14291462
const out = result.output
14301463
.filter(
1431-
evt => evt.type === "stdout" ||
1432-
( evt.type === "stderr" && (options.warning === "true" && options.message === "true"))
1464+
evt => evt.type === "stdout" ||
1465+
( evt.type === "stderr" && (options.warning === "true" && options.message === "true"))
14331466
)
14341467
.map((evt, index) => {
14351468
const className = `qwebr-output-code-${evt.type}`;
@@ -1441,15 +1474,31 @@
14411474

14421475
// Clean the state
14431476
// We're now able to process pager events.
1444-
// As a result, we cannot maintain a true 1-to-1 output order
1477+
// As a result, we cannot maintain a true 1-to-1 output order
14451478
// without individually feeding each line
14461479
const msgs = await mainWebR.flush();
14471480

14481481
// Use `map` to process the filtered "pager" events asynchronously
1449-
const pager = await Promise.all(
1450-
msgs.filter(msg => msg.type === 'pager').map(
1482+
const pager = [];
1483+
const browse = [];
1484+
1485+
await Promise.all(
1486+
msgs.map(
14511487
async (msg) => {
1452-
return await qwebrParseTypePager(msg);
1488+
1489+
const msgType = msg.type || "unknown";
1490+
1491+
switch(msgType) {
1492+
case 'pager':
1493+
const pager_data = await qwebrParseTypePager(msg);
1494+
pager.push(pager_data);
1495+
break;
1496+
case 'browse':
1497+
const browse_data = await qwebrParseTypeBrowse(msg);
1498+
browse.push(browse_data);
1499+
break;
1500+
}
1501+
return;
14531502
}
14541503
)
14551504
);
@@ -1512,40 +1561,57 @@
15121561
// Draw image onto Canvas
15131562
const ctx = canvas.getContext("2d");
15141563
ctx.drawImage(img, 0, 0, img.width, img.height);
1515-
1564+
15161565
// Append canvas to figure output area
15171566
figureElement.appendChild(canvas);
15181567

15191568
});
1520-
1569+
15211570
if (options['fig-cap']) {
15221571
// Create figcaption element
15231572
const figcaptionElement = document.createElement('figcaption');
15241573
figcaptionElement.innerText = options['fig-cap'];
15251574
// Append figcaption to figure
1526-
figureElement.appendChild(figcaptionElement);
1575+
figureElement.appendChild(figcaptionElement);
15271576
}
1528-
1577+
15291578
elements.outputGraphDiv.appendChild(figureElement);
15301579

15311580
}
15321581

15331582
// Display the pager data
1534-
if (pager) {
1535-
// Use the `pre` element to preserve whitespace.
1536-
pager.forEach((paged_data, index) => {
1537-
let pre_pager = document.createElement("pre");
1538-
pre_pager.innerText = paged_data;
1539-
pre_pager.classList.add("qwebr-output-code-pager");
1540-
pre_pager.setAttribute("id", `qwebr-output-code-pager-editor-${elements.id}-result-${index + 1}`);
1541-
elements.outputCodeDiv.appendChild(pre_pager);
1542-
});
1583+
if (pager.length > 0) {
1584+
// Use the `pre` element to preserve whitespace.
1585+
pager.forEach((paged_data, index) => {
1586+
const pre_pager = document.createElement("pre");
1587+
pre_pager.innerText = paged_data;
1588+
pre_pager.classList.add("qwebr-output-code-pager");
1589+
pre_pager.setAttribute("id", `qwebr-output-code-pager-editor-${elements.id}-result-${index + 1}`);
1590+
elements.outputCodeDiv.appendChild(pre_pager);
1591+
});
1592+
}
1593+
1594+
// Display the browse data
1595+
if (browse.length > 0) {
1596+
// Use the `pre` element to preserve whitespace.
1597+
browse.forEach((browse_data, index) => {
1598+
const iframe_browse = document.createElement('iframe');
1599+
iframe_browse.classList.add("qwebr-output-code-browse");
1600+
iframe_browse.setAttribute("id", `qwebr-output-code-browse-editor-${elements.id}-result-${index + 1}`);
1601+
iframe_browse.style.width = "100%";
1602+
iframe_browse.style.minHeight = "500px";
1603+
elements.outputCodeDiv.appendChild(iframe_browse);
1604+
1605+
iframe_browse.contentWindow.document.open();
1606+
iframe_browse.contentWindow.document.write(browse_data);
1607+
iframe_browse.contentWindow.document.close();
1608+
});
15431609
}
15441610
} finally {
15451611
// Clean up the remaining code
15461612
mainWebRCodeShelter.purge();
15471613
}
1548-
}
1614+
};
15491615

15501616
// Function to execute the code (accepts code as an argument)
15511617
globalThis.qwebrExecuteCode = async function (
@@ -1555,12 +1621,12 @@
15551621

15561622
// If options are not passed, we fall back on the bare minimum to handle the computation
15571623
if (qwebrIsObjectEmpty(options)) {
1558-
options = {
1559-
"context": "interactive",
1560-
"fig-width": 7, "fig-height": 5,
1561-
"out-width": "700px", "out-height": "",
1624+
options = {
1625+
"context": "interactive",
1626+
"fig-width": 7, "fig-height": 5,
1627+
"out-width": "700px", "out-height": "",
15621628
"dpi": 72,
1563-
"results": "markup",
1629+
"results": "markup",
15641630
"warning": "true", "message": "true",
15651631
};
15661632
}

0 commit comments

Comments
 (0)