Skip to content

Commit

Permalink
feat: auto-tail output when depends-on
Browse files Browse the repository at this point in the history
  • Loading branch information
nalgeon committed Mar 15, 2024
1 parent d9778a5 commit c3cf4a8
Show file tree
Hide file tree
Showing 5 changed files with 80 additions and 17 deletions.
23 changes: 23 additions & 0 deletions src/codegen.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
// Code generation.

import text from "./text.js";

const HR = text.HORIZONTAL_RULE;
const horRules = {
javascript: `console.log("${HR}");`,
lua: `print("${HR}")`,
php: `echo "${HR}"`,
python: `print("${HR}")`,
r: `cat("${HR}\n")`,
ruby: `puts "${HR}"`,
typescript: `console.log("${HR}");`,
shell: `echo "${HR}"`,
sql: `select '${HR}';`,
};

// print a horizontal rule.
function hr(syntax) {
return horRules[syntax] || "";
}

export default { hr };
8 changes: 3 additions & 5 deletions src/output.js
Original file line number Diff line number Diff line change
Expand Up @@ -28,11 +28,9 @@ template.innerHTML = `
const builders = {
// returns the result as a text node.
[OutputMode.text]: (result, shouldTail) => {
const value = result.stdout || result.stderr || PLACEHOLDER;
if (shouldTail) {
return document.createTextNode(text.tail(value));
}
return document.createTextNode(value);
const value = result.stdout || result.stderr;
const output = shouldTail ? text.tail(value) : value;
return document.createTextNode(output || PLACEHOLDER);
},

// returns the result as an HTML table.
Expand Down
13 changes: 12 additions & 1 deletion src/snippet.js
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ import "./output.js";
import { EditorMode, CodeElement } from "./editor.js";
import { Executor } from "./executor.js";
import text from "./text.js";
import codegen from "./codegen.js";

// UI messages.
const messages = {
Expand Down Expand Up @@ -269,6 +270,14 @@ class CodapiSnippet extends HTMLElement {
this._toolbar.showStatus(message);
}

// what syntax is used.
get syntax() {
return this.getAttribute("syntax") || this.getAttribute("sandbox");
}
set syntax(value) {
this.setAttribute("syntax", value);
}

// selector is the code element css selector.
get selector() {
return this.getAttribute("selector");
Expand Down Expand Up @@ -308,12 +317,14 @@ class CodapiSnippet extends HTMLElement {
function gatherCode(curSnip) {
let code = curSnip.code;
let ids = curSnip.dependsOn ? curSnip.dependsOn.split(" ") : [];
// print separators between snippets to tail output later
const sep = curSnip.hasAttribute("output-tail") ? codegen.hr(curSnip.syntax) : "";
for (const id of ids) {
const snip = document.getElementById(id);
if (!snip) {
throw new Error(`#${id} dependency not found`);
}
code = snip.code + "\n" + code;
code = snip.code + `\n${sep}\n` + code;
if (snip.dependsOn) {
ids.push(...snip.dependsOn.split(" ").filter((i) => !ids.includes(i)));
}
Expand Down
20 changes: 15 additions & 5 deletions src/text.js
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
// tail separator
const TAIL_SEPARATOR = "---";
// Text handling.

const HORIZONTAL_RULE = "---";

// cut slices s around the first instance of sep,
// returning the text before and after sep.
Expand All @@ -15,8 +16,17 @@ function cut(s, sep) {
// tail returns the last part of s after the separator line.
// If s does not contain a separator, returns s unchanged.
function tail(s) {
const index = s.lastIndexOf(`\n${TAIL_SEPARATOR}`);
return index === -1 ? s : s.slice(index + 5);
if (s.endsWith(HORIZONTAL_RULE)) {
return "";
}
const index = s.lastIndexOf(`\n${HORIZONTAL_RULE}\n`);
if (index !== -1) {
return s.slice(index + HORIZONTAL_RULE.length + 2);
}
if (s.startsWith(HORIZONTAL_RULE)) {
return s.slice(HORIZONTAL_RULE.length + 1);
}
return s;
}

export default { cut, tail };
export default { cut, tail, HORIZONTAL_RULE };
33 changes: 27 additions & 6 deletions tests/snippet.js
Original file line number Diff line number Diff line change
Expand Up @@ -57,8 +57,9 @@ async function runTests() {
await testOutputModeHidden();

await testOutputPlaceholder();
await testOutputNoTail();
await testOutputTail();
await testOutputTailOff();
await testOutputTailOn();
await testOutputTailAuto();

await testTemplate();
await testTemplateChange();
Expand Down Expand Up @@ -763,9 +764,9 @@ async function testOutputPlaceholder() {
});
}

async function testOutputNoTail() {
async function testOutputTailOff() {
return new Promise((resolve, reject) => {
t.log("testOutputNoTail...");
t.log("testOutputTailOff...");
const ui = createSnippet(`
<pre><code>console.log("hello");
console.log("---");
Expand All @@ -781,9 +782,9 @@ console.log("world");</code></pre>
});
}

async function testOutputTail() {
async function testOutputTailOn() {
return new Promise((resolve, reject) => {
t.log("testOutputTail...");
t.log("testOutputTailOn...");
const ui = createSnippet(`
<pre><code>console.log("hello");
console.log("---");
Expand All @@ -799,6 +800,26 @@ console.log("world");</code></pre>
});
}

async function testOutputTailAuto() {
return new Promise((resolve, reject) => {
t.log("testOutputTailAuto...");
const html = `
<pre><code>console.log("hello")</code></pre>
<codapi-snippet id="step-1" engine="browser" sandbox="javascript">
</codapi-snippet>
<pre><code>console.log("world")</code></pre>
<codapi-snippet engine="browser" sandbox="javascript" depends-on="step-1" output-tail>
</codapi-snippet>
`;
const ui = createSnippet(html);
ui.snip.addEventListener("result", (event) => {
t.assert("output", ui.output.out.innerHTML == "world");
resolve();
});
ui.toolbar.run.click();
});
}

async function testTemplate() {
return new Promise((resolve, reject) => {
t.log("testTemplate...");
Expand Down

0 comments on commit c3cf4a8

Please sign in to comment.