Skip to content

Commit c3cf4a8

Browse files
committed
feat: auto-tail output when depends-on
1 parent d9778a5 commit c3cf4a8

File tree

5 files changed

+80
-17
lines changed

5 files changed

+80
-17
lines changed

src/codegen.js

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
// Code generation.
2+
3+
import text from "./text.js";
4+
5+
const HR = text.HORIZONTAL_RULE;
6+
const horRules = {
7+
javascript: `console.log("${HR}");`,
8+
lua: `print("${HR}")`,
9+
php: `echo "${HR}"`,
10+
python: `print("${HR}")`,
11+
r: `cat("${HR}\n")`,
12+
ruby: `puts "${HR}"`,
13+
typescript: `console.log("${HR}");`,
14+
shell: `echo "${HR}"`,
15+
sql: `select '${HR}';`,
16+
};
17+
18+
// print a horizontal rule.
19+
function hr(syntax) {
20+
return horRules[syntax] || "";
21+
}
22+
23+
export default { hr };

src/output.js

Lines changed: 3 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -28,11 +28,9 @@ template.innerHTML = `
2828
const builders = {
2929
// returns the result as a text node.
3030
[OutputMode.text]: (result, shouldTail) => {
31-
const value = result.stdout || result.stderr || PLACEHOLDER;
32-
if (shouldTail) {
33-
return document.createTextNode(text.tail(value));
34-
}
35-
return document.createTextNode(value);
31+
const value = result.stdout || result.stderr;
32+
const output = shouldTail ? text.tail(value) : value;
33+
return document.createTextNode(output || PLACEHOLDER);
3634
},
3735

3836
// returns the result as an HTML table.

src/snippet.js

Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@ import "./output.js";
66
import { EditorMode, CodeElement } from "./editor.js";
77
import { Executor } from "./executor.js";
88
import text from "./text.js";
9+
import codegen from "./codegen.js";
910

1011
// UI messages.
1112
const messages = {
@@ -269,6 +270,14 @@ class CodapiSnippet extends HTMLElement {
269270
this._toolbar.showStatus(message);
270271
}
271272

273+
// what syntax is used.
274+
get syntax() {
275+
return this.getAttribute("syntax") || this.getAttribute("sandbox");
276+
}
277+
set syntax(value) {
278+
this.setAttribute("syntax", value);
279+
}
280+
272281
// selector is the code element css selector.
273282
get selector() {
274283
return this.getAttribute("selector");
@@ -308,12 +317,14 @@ class CodapiSnippet extends HTMLElement {
308317
function gatherCode(curSnip) {
309318
let code = curSnip.code;
310319
let ids = curSnip.dependsOn ? curSnip.dependsOn.split(" ") : [];
320+
// print separators between snippets to tail output later
321+
const sep = curSnip.hasAttribute("output-tail") ? codegen.hr(curSnip.syntax) : "";
311322
for (const id of ids) {
312323
const snip = document.getElementById(id);
313324
if (!snip) {
314325
throw new Error(`#${id} dependency not found`);
315326
}
316-
code = snip.code + "\n" + code;
327+
code = snip.code + `\n${sep}\n` + code;
317328
if (snip.dependsOn) {
318329
ids.push(...snip.dependsOn.split(" ").filter((i) => !ids.includes(i)));
319330
}

src/text.js

Lines changed: 15 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
1-
// tail separator
2-
const TAIL_SEPARATOR = "---";
1+
// Text handling.
2+
3+
const HORIZONTAL_RULE = "---";
34

45
// cut slices s around the first instance of sep,
56
// returning the text before and after sep.
@@ -15,8 +16,17 @@ function cut(s, sep) {
1516
// tail returns the last part of s after the separator line.
1617
// If s does not contain a separator, returns s unchanged.
1718
function tail(s) {
18-
const index = s.lastIndexOf(`\n${TAIL_SEPARATOR}`);
19-
return index === -1 ? s : s.slice(index + 5);
19+
if (s.endsWith(HORIZONTAL_RULE)) {
20+
return "";
21+
}
22+
const index = s.lastIndexOf(`\n${HORIZONTAL_RULE}\n`);
23+
if (index !== -1) {
24+
return s.slice(index + HORIZONTAL_RULE.length + 2);
25+
}
26+
if (s.startsWith(HORIZONTAL_RULE)) {
27+
return s.slice(HORIZONTAL_RULE.length + 1);
28+
}
29+
return s;
2030
}
2131

22-
export default { cut, tail };
32+
export default { cut, tail, HORIZONTAL_RULE };

tests/snippet.js

Lines changed: 27 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -57,8 +57,9 @@ async function runTests() {
5757
await testOutputModeHidden();
5858

5959
await testOutputPlaceholder();
60-
await testOutputNoTail();
61-
await testOutputTail();
60+
await testOutputTailOff();
61+
await testOutputTailOn();
62+
await testOutputTailAuto();
6263

6364
await testTemplate();
6465
await testTemplateChange();
@@ -763,9 +764,9 @@ async function testOutputPlaceholder() {
763764
});
764765
}
765766

766-
async function testOutputNoTail() {
767+
async function testOutputTailOff() {
767768
return new Promise((resolve, reject) => {
768-
t.log("testOutputNoTail...");
769+
t.log("testOutputTailOff...");
769770
const ui = createSnippet(`
770771
<pre><code>console.log("hello");
771772
console.log("---");
@@ -781,9 +782,9 @@ console.log("world");</code></pre>
781782
});
782783
}
783784

784-
async function testOutputTail() {
785+
async function testOutputTailOn() {
785786
return new Promise((resolve, reject) => {
786-
t.log("testOutputTail...");
787+
t.log("testOutputTailOn...");
787788
const ui = createSnippet(`
788789
<pre><code>console.log("hello");
789790
console.log("---");
@@ -799,6 +800,26 @@ console.log("world");</code></pre>
799800
});
800801
}
801802

803+
async function testOutputTailAuto() {
804+
return new Promise((resolve, reject) => {
805+
t.log("testOutputTailAuto...");
806+
const html = `
807+
<pre><code>console.log("hello")</code></pre>
808+
<codapi-snippet id="step-1" engine="browser" sandbox="javascript">
809+
</codapi-snippet>
810+
<pre><code>console.log("world")</code></pre>
811+
<codapi-snippet engine="browser" sandbox="javascript" depends-on="step-1" output-tail>
812+
</codapi-snippet>
813+
`;
814+
const ui = createSnippet(html);
815+
ui.snip.addEventListener("result", (event) => {
816+
t.assert("output", ui.output.out.innerHTML == "world");
817+
resolve();
818+
});
819+
ui.toolbar.run.click();
820+
});
821+
}
822+
802823
async function testTemplate() {
803824
return new Promise((resolve, reject) => {
804825
t.log("testTemplate...");

0 commit comments

Comments
 (0)