mirror of
https://github.com/remko/waforth
synced 2025-01-18 22:26:39 +01:00
notebook: Move some files
This commit is contained in:
parent
3494e15a65
commit
a29e0f9567
17 changed files with 307 additions and 42 deletions
1
.github/workflows/build.yml
vendored
1
.github/workflows/build.yml
vendored
|
@ -13,5 +13,6 @@ jobs:
|
||||||
- uses: actions/checkout@v2
|
- uses: actions/checkout@v2
|
||||||
- uses: ./.github/actions/setup
|
- uses: ./.github/actions/setup
|
||||||
- run: yarnpkg build
|
- run: yarnpkg build
|
||||||
|
- run: make -C src/web/notebook
|
||||||
- run: yarnpkg lint
|
- run: yarnpkg lint
|
||||||
- run: yarnpkg test --coverage
|
- run: yarnpkg test --coverage
|
||||||
|
|
|
@ -164,9 +164,9 @@ Because it is powered by WebAssembly, this extension works both in the desktop v
|
||||||
|
|
||||||
<div align="center">
|
<div align="center">
|
||||||
<div>
|
<div>
|
||||||
<a href="https://github.dev/remko/waforth/blob/master/src/web/vscode-extension/examples/drawing-with-forth.wafnb"><img src="https://raw.githubusercontent.com/remko/waforth/master/src/web/vscode-extension/doc/notebook.gif" alt="WAForth notebook"></a>
|
<a href="https://github.dev/remko/waforth/blob/master/src/web/notebook/examples/drawing-with-forth.wafnb"><img src="https://raw.githubusercontent.com/remko/waforth/master/src/web/vscode-extension/doc/notebook.gif" alt="WAForth notebook"></a>
|
||||||
</div>
|
</div>
|
||||||
<figcaption><em><a href="https://github.dev/remko/waforth/blob/master/src/web/vscode-extension/examples/drawing-with-forth.wafnb">WAForth notebook</a></em></figcaption>
|
<figcaption><em><a href="https://github.dev/remko/waforth/blob/master/src/web/notebook/examples/drawing-with-forth.wafnb">WAForth notebook</a></em></figcaption>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -7,6 +7,7 @@
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"@types/file-saver": "^2.0.5",
|
"@types/file-saver": "^2.0.5",
|
||||||
"@types/lodash": "^4.14.182",
|
"@types/lodash": "^4.14.182",
|
||||||
|
"@types/marked": "^4.0.7",
|
||||||
"@types/node": "^17.0.31",
|
"@types/node": "^17.0.31",
|
||||||
"@types/vscode": "^1.73.1",
|
"@types/vscode": "^1.73.1",
|
||||||
"@typescript-eslint/eslint-plugin": "^5.30.5",
|
"@typescript-eslint/eslint-plugin": "^5.30.5",
|
||||||
|
@ -20,6 +21,7 @@
|
||||||
"file-saver": "^2.0.5",
|
"file-saver": "^2.0.5",
|
||||||
"immutability-helper": "^3.1.1",
|
"immutability-helper": "^3.1.1",
|
||||||
"lodash": "^4.17.21",
|
"lodash": "^4.17.21",
|
||||||
|
"marked": "^4.2.2",
|
||||||
"mocha": "^9.2.2",
|
"mocha": "^9.2.2",
|
||||||
"prettier": "^2.6.2",
|
"prettier": "^2.6.2",
|
||||||
"react": "^18.0.0",
|
"react": "^18.0.0",
|
||||||
|
|
|
@ -3,13 +3,7 @@
|
||||||
|
|
||||||
const { createServer } = require("http");
|
const { createServer } = require("http");
|
||||||
|
|
||||||
function withWatcher(
|
function withWatcher(config, handleBuildFinished = undefined, port = 8880) {
|
||||||
config,
|
|
||||||
handleBuildFinished = () => {
|
|
||||||
/* do nothing */
|
|
||||||
},
|
|
||||||
port = 8880
|
|
||||||
) {
|
|
||||||
const watchClients = [];
|
const watchClients = [];
|
||||||
createServer((req, res) => {
|
createServer((req, res) => {
|
||||||
return watchClients.push(
|
return watchClients.push(
|
||||||
|
@ -31,7 +25,9 @@ function withWatcher(
|
||||||
if (error) {
|
if (error) {
|
||||||
console.error(error);
|
console.error(error);
|
||||||
} else {
|
} else {
|
||||||
|
if (handleBuildFinished != null) {
|
||||||
await handleBuildFinished(result);
|
await handleBuildFinished(result);
|
||||||
|
}
|
||||||
watchClients.forEach((res) => res.write("data: update\n\n"));
|
watchClients.forEach((res) => res.write("data: update\n\n"));
|
||||||
watchClients.length = 0;
|
watchClients.length = 0;
|
||||||
}
|
}
|
||||||
|
|
2
src/web/notebook/.gitignore
vendored
Normal file
2
src/web/notebook/.gitignore
vendored
Normal file
|
@ -0,0 +1,2 @@
|
||||||
|
/dist
|
||||||
|
/examples/*.html
|
8
src/web/notebook/Makefile
Normal file
8
src/web/notebook/Makefile
Normal file
|
@ -0,0 +1,8 @@
|
||||||
|
all:
|
||||||
|
./build.js
|
||||||
|
|
||||||
|
dev:
|
||||||
|
./build.js --development --watch
|
||||||
|
|
||||||
|
clean:
|
||||||
|
-rm -rf dist
|
106
src/web/notebook/build.js
Executable file
106
src/web/notebook/build.js
Executable file
|
@ -0,0 +1,106 @@
|
||||||
|
#!/usr/bin/env node
|
||||||
|
/* eslint-env node */
|
||||||
|
/* eslint @typescript-eslint/no-var-requires:0 */
|
||||||
|
|
||||||
|
const esbuild = require("esbuild");
|
||||||
|
const path = require("path");
|
||||||
|
const fs = require("fs");
|
||||||
|
const { wasmTextPlugin } = require("../../../scripts/esbuild/wasm-text");
|
||||||
|
|
||||||
|
let dev = false;
|
||||||
|
let watch = false;
|
||||||
|
for (const arg of process.argv.slice(2)) {
|
||||||
|
switch (arg) {
|
||||||
|
case "--development":
|
||||||
|
dev = true;
|
||||||
|
break;
|
||||||
|
case "--watch":
|
||||||
|
watch = true;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
const buildConfig = {
|
||||||
|
bundle: true,
|
||||||
|
logLevel: "info",
|
||||||
|
// target: "es6",
|
||||||
|
minify: !dev,
|
||||||
|
loader: {
|
||||||
|
".wasm": "binary",
|
||||||
|
".fs": "text",
|
||||||
|
},
|
||||||
|
plugins: [wasmTextPlugin({ debug: true })],
|
||||||
|
};
|
||||||
|
|
||||||
|
let nbBuildConfig = {
|
||||||
|
...buildConfig,
|
||||||
|
outdir: path.join(__dirname, "dist"),
|
||||||
|
entryPoints: [path.join(__dirname, "src", "wafnb.ts")],
|
||||||
|
publicPath: "/dist",
|
||||||
|
assetNames: "[name].txt",
|
||||||
|
sourcemap: !!dev,
|
||||||
|
loader: {
|
||||||
|
...buildConfig.loader,
|
||||||
|
".svg": "dataurl",
|
||||||
|
},
|
||||||
|
};
|
||||||
|
|
||||||
|
let generatorBuildConfig = {
|
||||||
|
...buildConfig,
|
||||||
|
banner: { js: "#!/usr/bin/env node" },
|
||||||
|
platform: "node",
|
||||||
|
outfile: path.join(__dirname, "dist", "wafnb2html"),
|
||||||
|
entryPoints: [path.join(__dirname, "src", "wafnb2html.mjs")],
|
||||||
|
sourcemap: dev ? "inline" : undefined,
|
||||||
|
loader: {
|
||||||
|
...buildConfig.loader,
|
||||||
|
".js": "text",
|
||||||
|
".css": "text",
|
||||||
|
},
|
||||||
|
define: watch
|
||||||
|
? {
|
||||||
|
WAFNB_CSS_PATH: JSON.stringify(path.join(__dirname, "/dist/wafnb.css")),
|
||||||
|
WAFNB_JS_PATH: JSON.stringify(path.join(__dirname, "/dist/wafnb.js")),
|
||||||
|
}
|
||||||
|
: undefined,
|
||||||
|
};
|
||||||
|
|
||||||
|
function handleGeneratorBuildFinished(result) {
|
||||||
|
return fs.chmodSync(path.join(__dirname, "dist", "wafnb2html"), "755");
|
||||||
|
}
|
||||||
|
|
||||||
|
if (watch) {
|
||||||
|
nbBuildConfig = {
|
||||||
|
...nbBuildConfig,
|
||||||
|
watch: {
|
||||||
|
async onRebuild(error) {
|
||||||
|
if (error) {
|
||||||
|
console.error(error);
|
||||||
|
}
|
||||||
|
},
|
||||||
|
},
|
||||||
|
};
|
||||||
|
generatorBuildConfig = {
|
||||||
|
...generatorBuildConfig,
|
||||||
|
watch: {
|
||||||
|
async onRebuild(error, result) {
|
||||||
|
if (error) {
|
||||||
|
console.error(error);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
return handleGeneratorBuildFinished(result);
|
||||||
|
},
|
||||||
|
},
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
(async () => {
|
||||||
|
try {
|
||||||
|
await esbuild.build(nbBuildConfig);
|
||||||
|
await handleGeneratorBuildFinished(
|
||||||
|
await esbuild.build(generatorBuildConfig)
|
||||||
|
);
|
||||||
|
} catch (e) {
|
||||||
|
process.exit(1);
|
||||||
|
}
|
||||||
|
})();
|
|
@ -53,18 +53,13 @@
|
||||||
{
|
{
|
||||||
"kind": 1,
|
"kind": 1,
|
||||||
"language": "markdown",
|
"language": "markdown",
|
||||||
"value": "# Combining words\n\nWe can create more complex figures by using the `SQUARE` word from above, and repeating it.\n\n| *Tip*: Play with the numbers in `FLOWER` to create variations of the flower "
|
"value": "## Combining words\n\nWe can create more complex figures by using the `SQUARE` word from above, and repeating it.\n\n| *Tip*: Play with the numbers in `FLOWER` to create variations of the flower "
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"kind": 2,
|
"kind": 2,
|
||||||
"language": "waforth",
|
"language": "waforth",
|
||||||
"value": ": SQUARE ( n -- )\n 4 0 DO\n DUP FORWARD\n 90 RIGHT\n LOOP\n DROP\n;\n\n: FLOWER ( n -- )\n 24 0 DO\n DUP SQUARE\n 15 RIGHT\n LOOP\n DROP\n;\n\n250 FLOWER"
|
"value": ": SQUARE ( n -- )\n 4 0 DO\n DUP FORWARD\n 90 RIGHT\n LOOP\n DROP\n;\n\n: FLOWER ( n -- )\n 24 0 DO\n DUP SQUARE\n 15 RIGHT\n LOOP\n DROP\n;\n\n250 FLOWER"
|
||||||
},
|
},
|
||||||
{
|
|
||||||
"kind": 2,
|
|
||||||
"language": "waforth",
|
|
||||||
"value": " 4 0 DO\n DUP FORWARD\n 90 RIGHT\n LOOP\n DROP\n;\n\n: FLOWER ( n -- )\n 24 0 DO\n DUP SQUARE\n 15 RIGHT\n LOOP\n DROP\n;\n\n250 FLOWER"
|
|
||||||
},
|
|
||||||
{
|
{
|
||||||
"kind": 1,
|
"kind": 1,
|
||||||
"language": "markdown",
|
"language": "markdown",
|
||||||
|
@ -88,7 +83,7 @@
|
||||||
{
|
{
|
||||||
"kind": 1,
|
"kind": 1,
|
||||||
"language": "markdown",
|
"language": "markdown",
|
||||||
"value": "# Fractals\n\nYou can create more complex recursive drawings, called *fractals*. \n\nA famous fractal is the *Koch snowflake*.\n\n| *Tip*: Change the `DEPTH` constant to make a coarser or finer grained snowflake"
|
"value": "## Fractals\n\nYou can create more complex recursive drawings, called *fractals*. \n\nA famous fractal is the *Koch snowflake*.\n\n| *Tip*: Change the `DEPTH` constant to make a coarser or finer grained snowflake"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"kind": 2,
|
"kind": 2,
|
21
src/web/notebook/src/Notebook.ts
Normal file
21
src/web/notebook/src/Notebook.ts
Normal file
|
@ -0,0 +1,21 @@
|
||||||
|
export type Notebook = {
|
||||||
|
cells: NotebookCell[];
|
||||||
|
};
|
||||||
|
|
||||||
|
export type NotebookCell = {
|
||||||
|
language: string;
|
||||||
|
value: string;
|
||||||
|
kind: number;
|
||||||
|
editable?: boolean;
|
||||||
|
};
|
||||||
|
|
||||||
|
export function parseNotebook(contents: string): Notebook {
|
||||||
|
if (contents.trim().length === 0) {
|
||||||
|
return { cells: [] };
|
||||||
|
}
|
||||||
|
return JSON.parse(contents);
|
||||||
|
}
|
||||||
|
|
||||||
|
export function serializeNotebook(notebook: Notebook) {
|
||||||
|
return JSON.stringify(notebook, undefined, 2);
|
||||||
|
}
|
88
src/web/notebook/src/generator.ts
Normal file
88
src/web/notebook/src/generator.ts
Normal file
|
@ -0,0 +1,88 @@
|
||||||
|
import fs from "fs";
|
||||||
|
import path from "path";
|
||||||
|
import { parseNotebook } from "./Notebook";
|
||||||
|
// eslint-disable-next-line @typescript-eslint/no-var-requires
|
||||||
|
const marked = require("../../../../node_modules/marked/lib/marked.cjs").marked;
|
||||||
|
|
||||||
|
declare let WAFNB_JS_PATH: string | undefined;
|
||||||
|
declare let WAFNB_CSS_PATH: string | undefined;
|
||||||
|
|
||||||
|
const titleRE = /^#[^#](.*)$/;
|
||||||
|
|
||||||
|
function escapeHTML(s: string) {
|
||||||
|
return s
|
||||||
|
.replace(/&/g, "&")
|
||||||
|
.replace(/</g, "<")
|
||||||
|
.replace(/>/g, ">")
|
||||||
|
.replace(/"/g, """);
|
||||||
|
}
|
||||||
|
export async function generate({
|
||||||
|
file,
|
||||||
|
css,
|
||||||
|
js,
|
||||||
|
}: {
|
||||||
|
bundle?: boolean;
|
||||||
|
js?: string;
|
||||||
|
css?: string;
|
||||||
|
file: string;
|
||||||
|
}) {
|
||||||
|
let outfile = file.replace(".wafnb", ".html");
|
||||||
|
if (outfile === file) {
|
||||||
|
outfile = outfile + ".html";
|
||||||
|
}
|
||||||
|
|
||||||
|
let style: string;
|
||||||
|
let script: string;
|
||||||
|
if (typeof WAFNB_JS_PATH !== "undefined") {
|
||||||
|
const cssPath = path.relative(path.dirname(outfile), WAFNB_CSS_PATH!);
|
||||||
|
const jsPath = path.relative(path.dirname(outfile), WAFNB_JS_PATH!);
|
||||||
|
style = `<link rel="stylesheet" href="${cssPath}">`;
|
||||||
|
script = `<script type="application/javascript" src="${jsPath}"></script>`;
|
||||||
|
} else {
|
||||||
|
style = `<style>${css}</style>`;
|
||||||
|
script = `<script type="application/javascript">${js}</script>`;
|
||||||
|
}
|
||||||
|
|
||||||
|
const nb = parseNotebook(
|
||||||
|
await fs.promises.readFile(file, {
|
||||||
|
encoding: "utf-8",
|
||||||
|
flag: "r",
|
||||||
|
})
|
||||||
|
);
|
||||||
|
let title: string | null = null;
|
||||||
|
let out = ["<div class='content'>"];
|
||||||
|
for (const cell of nb.cells) {
|
||||||
|
switch (cell.kind) {
|
||||||
|
case 1:
|
||||||
|
if (title == null) {
|
||||||
|
let m: RegExpExecArray | null = null;
|
||||||
|
for (const v of cell.value.split("\n")) {
|
||||||
|
m = titleRE.exec(v);
|
||||||
|
if (m != null) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (m != null) {
|
||||||
|
title = m[1].trim();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
out.push(
|
||||||
|
"<div class='text-cell'>" + marked.parse(cell.value) + "</div>"
|
||||||
|
);
|
||||||
|
break;
|
||||||
|
case 2:
|
||||||
|
out.push(
|
||||||
|
"<div data-hook='code-cell' class='raw-code-cell'>" +
|
||||||
|
escapeHTML(cell.value) +
|
||||||
|
"</div>"
|
||||||
|
);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
throw new Error("unexpected kind");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
out.push("</div>");
|
||||||
|
|
||||||
|
out = [`<title>${escapeHTML(title ?? "")}</title>`, style, ...out, script];
|
||||||
|
return fs.promises.writeFile(outfile, out.join("\n"));
|
||||||
|
}
|
21
src/web/notebook/src/wafnb.css
Normal file
21
src/web/notebook/src/wafnb.css
Normal file
|
@ -0,0 +1,21 @@
|
||||||
|
body {
|
||||||
|
font-family: sans-serif;
|
||||||
|
}
|
||||||
|
|
||||||
|
.content {
|
||||||
|
max-width: 40em;
|
||||||
|
margin-left: auto;
|
||||||
|
margin-right: auto;
|
||||||
|
}
|
||||||
|
|
||||||
|
code.raw-code-cell {
|
||||||
|
font-family: monospace;
|
||||||
|
padding: 0.5em 1em;
|
||||||
|
display: block;
|
||||||
|
white-space: pre;
|
||||||
|
background-color: #eee;
|
||||||
|
}
|
||||||
|
|
||||||
|
.editor {
|
||||||
|
flex: 1;
|
||||||
|
}
|
12
src/web/notebook/src/wafnb.ts
Normal file
12
src/web/notebook/src/wafnb.ts
Normal file
|
@ -0,0 +1,12 @@
|
||||||
|
import "./wafnb.css";
|
||||||
|
import Editor from "../../thurtle/Editor";
|
||||||
|
|
||||||
|
for (const n of document.querySelectorAll("[data-hook=code-cell")) {
|
||||||
|
n.className = "code-cell";
|
||||||
|
const program = n.textContent ?? "";
|
||||||
|
const editor = new Editor();
|
||||||
|
editor.setValue(program);
|
||||||
|
n.innerHTML = "";
|
||||||
|
n.appendChild(editor.el);
|
||||||
|
editor.el.style.minHeight = "10em"; // FIXME
|
||||||
|
}
|
13
src/web/notebook/src/wafnb2html.mjs
Normal file
13
src/web/notebook/src/wafnb2html.mjs
Normal file
|
@ -0,0 +1,13 @@
|
||||||
|
import wafnbJS from "../dist/wafnb.js";
|
||||||
|
import wafnbCSS from "../dist/wafnb.css";
|
||||||
|
import { generate } from "./generator";
|
||||||
|
import process from "process";
|
||||||
|
|
||||||
|
(async () => {
|
||||||
|
const file = process.argv[2];
|
||||||
|
if (file == null) {
|
||||||
|
console.error("missing file");
|
||||||
|
process.exit(-1);
|
||||||
|
}
|
||||||
|
await generate({ file, js: wafnbJS, css: wafnbCSS });
|
||||||
|
})();
|
|
@ -8,15 +8,15 @@ Logo-like Forth Turtle graphics.
|
||||||
|
|
||||||
<div align="center">
|
<div align="center">
|
||||||
<div>
|
<div>
|
||||||
<a href="https://github.dev/remko/waforth/blob/master/src/web/vscode-extension/examples/drawing-with-forth.wafnb"><img src="https://raw.githubusercontent.com/remko/waforth/master/src/web/vscode-extension/doc/notebook.gif" alt="WAForth notebook"></a>
|
<a href="https://github.dev/remko/waforth/blob/master/src/web/notebook/examples/drawing-with-forth.wafnb"><img src="https://raw.githubusercontent.com/remko/waforth/master/src/web/notebook/doc/notebook.gif" alt="WAForth notebook"></a>
|
||||||
</div>
|
</div>
|
||||||
<figcaption><em><a href="https://github.dev/remko/waforth/blob/master/src/web/vscode-extension/examples/drawing-with-forth.wafnb">WAForth notebook</a></em></figcaption>
|
<figcaption><em><a href="https://github.dev/remko/waforth/blob/master/src/web/notebook/examples/drawing-with-forth.wafnb">WAForth notebook</a></em></figcaption>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
## Installation & Usage
|
## Installation & Usage
|
||||||
|
|
||||||
Install the extension from the [Visual Studio Code Marketplace](https://marketplace.visualstudio.com/items?itemName=remko.waforth-vscode-extension).
|
Install the extension from the [Visual Studio Code Marketplace](https://marketplace.visualstudio.com/items?itemName=remko.waforth-vscode-extension).
|
||||||
Once the extension is installed, you can create a new WAForth notebook from the command pallet (*WAForth: New notebook*), or open [this example notebook](https://raw.githubusercontent.com/remko/waforth/master/src/web/vscode-extension/examples/drawing-with-forth.wafnb).
|
Once the extension is installed, you can create a new WAForth notebook from the command pallet (*WAForth: New notebook*), or open [this example notebook](https://raw.githubusercontent.com/remko/waforth/master/src/web/notebook/examples/drawing-with-forth.wafnb).
|
||||||
|
|
||||||
The extension also works in the web-based VS Code environments.
|
The extension also works in the web-based VS Code environments.
|
||||||
For example, install the extension on https://github.dev, and then open [this example notebook](https://github.dev/remko/waforth/blob/master/src/web/vscode-extension/examples/drawing-with-forth.wafnb).
|
For example, install the extension on https://github.dev, and then open [this example notebook](https://github.dev/remko/waforth/blob/master/src/web/notebook/examples/drawing-with-forth.wafnb).
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
{
|
{
|
||||||
"name": "waforth-vscode-extension",
|
"name": "waforth-vscode-extension",
|
||||||
"version": "0.1.6",
|
"version": "0.1.7",
|
||||||
"displayName": "WAForth",
|
"displayName": "WAForth",
|
||||||
"description": "WAForth interactive notebooks",
|
"description": "WAForth interactive notebooks",
|
||||||
"categories": [
|
"categories": [
|
||||||
|
|
|
@ -2,6 +2,11 @@ import * as vscode from "vscode";
|
||||||
import WAForth, { ErrorCode, isSuccess } from "../../waforth";
|
import WAForth, { ErrorCode, isSuccess } from "../../waforth";
|
||||||
import draw from "../../thurtle/draw";
|
import draw from "../../thurtle/draw";
|
||||||
import JSJSX from "thurtle/jsjsx";
|
import JSJSX from "thurtle/jsjsx";
|
||||||
|
import {
|
||||||
|
parseNotebook,
|
||||||
|
Notebook,
|
||||||
|
serializeNotebook,
|
||||||
|
} from "../../notebook/src/Notebook";
|
||||||
|
|
||||||
export async function activate(context: vscode.ExtensionContext) {
|
export async function activate(context: vscode.ExtensionContext) {
|
||||||
context.subscriptions.push(
|
context.subscriptions.push(
|
||||||
|
@ -41,30 +46,15 @@ export function deactivate() {
|
||||||
// Notebook Serializer
|
// Notebook Serializer
|
||||||
//////////////////////////////////////////////////
|
//////////////////////////////////////////////////
|
||||||
|
|
||||||
interface RawNotebookData {
|
|
||||||
cells: RawNotebookCell[];
|
|
||||||
}
|
|
||||||
|
|
||||||
interface RawNotebookCell {
|
|
||||||
language: string;
|
|
||||||
value: string;
|
|
||||||
kind: vscode.NotebookCellKind;
|
|
||||||
editable?: boolean;
|
|
||||||
}
|
|
||||||
|
|
||||||
export class NotebookSerializer implements vscode.NotebookSerializer {
|
export class NotebookSerializer implements vscode.NotebookSerializer {
|
||||||
public readonly label: string = "WAForth Content Serializer";
|
public readonly label: string = "WAForth Content Serializer";
|
||||||
|
|
||||||
public async deserializeNotebook(
|
public async deserializeNotebook(
|
||||||
data: Uint8Array
|
data: Uint8Array
|
||||||
): Promise<vscode.NotebookData> {
|
): Promise<vscode.NotebookData> {
|
||||||
const contents = new TextDecoder().decode(data);
|
let raw: Notebook;
|
||||||
if (contents.trim().length === 0) {
|
|
||||||
return new vscode.NotebookData([]);
|
|
||||||
}
|
|
||||||
let raw: RawNotebookData;
|
|
||||||
try {
|
try {
|
||||||
raw = <RawNotebookData>JSON.parse(contents);
|
raw = parseNotebook(new TextDecoder().decode(data));
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
vscode.window.showErrorMessage("Error parsing:", (e as any).message);
|
vscode.window.showErrorMessage("Error parsing:", (e as any).message);
|
||||||
raw = { cells: [] };
|
raw = { cells: [] };
|
||||||
|
@ -79,7 +69,7 @@ export class NotebookSerializer implements vscode.NotebookSerializer {
|
||||||
public async serializeNotebook(
|
public async serializeNotebook(
|
||||||
data: vscode.NotebookData
|
data: vscode.NotebookData
|
||||||
): Promise<Uint8Array> {
|
): Promise<Uint8Array> {
|
||||||
const contents: RawNotebookData = { cells: [] };
|
const contents: Notebook = { cells: [] };
|
||||||
for (const cell of data.cells) {
|
for (const cell of data.cells) {
|
||||||
contents.cells.push({
|
contents.cells.push({
|
||||||
kind: cell.kind,
|
kind: cell.kind,
|
||||||
|
@ -87,12 +77,12 @@ export class NotebookSerializer implements vscode.NotebookSerializer {
|
||||||
value: cell.value,
|
value: cell.value,
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
return new TextEncoder().encode(JSON.stringify(contents, undefined, 2));
|
return new TextEncoder().encode(serializeNotebook(contents));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
//////////////////////////////////////////////////
|
//////////////////////////////////////////////////
|
||||||
// Notebook Serializer
|
// Notebook Controller
|
||||||
//////////////////////////////////////////////////
|
//////////////////////////////////////////////////
|
||||||
|
|
||||||
async function createNotebookController(
|
async function createNotebookController(
|
||||||
|
|
10
yarn.lock
10
yarn.lock
|
@ -112,6 +112,11 @@
|
||||||
resolved "https://registry.yarnpkg.com/@types/lodash/-/lodash-4.14.182.tgz#05301a4d5e62963227eaafe0ce04dd77c54ea5c2"
|
resolved "https://registry.yarnpkg.com/@types/lodash/-/lodash-4.14.182.tgz#05301a4d5e62963227eaafe0ce04dd77c54ea5c2"
|
||||||
integrity sha512-/THyiqyQAP9AfARo4pF+aCGcyiQ94tX/Is2I7HofNRqoYLgN1PBoOWu2/zTA5zMxzP5EFutMtWtGAFRKUe961Q==
|
integrity sha512-/THyiqyQAP9AfARo4pF+aCGcyiQ94tX/Is2I7HofNRqoYLgN1PBoOWu2/zTA5zMxzP5EFutMtWtGAFRKUe961Q==
|
||||||
|
|
||||||
|
"@types/marked@^4.0.7":
|
||||||
|
version "4.0.7"
|
||||||
|
resolved "https://registry.yarnpkg.com/@types/marked/-/marked-4.0.7.tgz#400a76809fd08c2bbd9e25f3be06ea38c8e0a1d3"
|
||||||
|
integrity sha512-eEAhnz21CwvKVW+YvRvcTuFKNU9CV1qH+opcgVK3pIMI6YZzDm6gc8o2vHjldFk6MGKt5pueSB7IOpvpx5Qekw==
|
||||||
|
|
||||||
"@types/node@^17.0.31":
|
"@types/node@^17.0.31":
|
||||||
version "17.0.31"
|
version "17.0.31"
|
||||||
resolved "https://registry.yarnpkg.com/@types/node/-/node-17.0.31.tgz#a5bb84ecfa27eec5e1c802c6bbf8139bdb163a5d"
|
resolved "https://registry.yarnpkg.com/@types/node/-/node-17.0.31.tgz#a5bb84ecfa27eec5e1c802c6bbf8139bdb163a5d"
|
||||||
|
@ -1307,6 +1312,11 @@ make-error@^1.1.1:
|
||||||
resolved "https://registry.yarnpkg.com/make-error/-/make-error-1.3.6.tgz#2eb2e37ea9b67c4891f684a1394799af484cf7a2"
|
resolved "https://registry.yarnpkg.com/make-error/-/make-error-1.3.6.tgz#2eb2e37ea9b67c4891f684a1394799af484cf7a2"
|
||||||
integrity sha512-s8UhlNe7vPKomQhC1qFelMokr/Sc3AgNbso3n74mVPA5LTZwkB9NlXf4XPamLxJE8h0gh73rM94xvwRT2CVInw==
|
integrity sha512-s8UhlNe7vPKomQhC1qFelMokr/Sc3AgNbso3n74mVPA5LTZwkB9NlXf4XPamLxJE8h0gh73rM94xvwRT2CVInw==
|
||||||
|
|
||||||
|
marked@^4.2.2:
|
||||||
|
version "4.2.2"
|
||||||
|
resolved "https://registry.yarnpkg.com/marked/-/marked-4.2.2.tgz#1d2075ad6cdfe42e651ac221c32d949a26c0672a"
|
||||||
|
integrity sha512-JjBTFTAvuTgANXx82a5vzK9JLSMoV6V3LBVn4Uhdso6t7vXrGx7g1Cd2r6NYSsxrYbQGFCMqBDhFHyK5q2UvcQ==
|
||||||
|
|
||||||
merge2@^1.3.0, merge2@^1.4.1:
|
merge2@^1.3.0, merge2@^1.4.1:
|
||||||
version "1.4.1"
|
version "1.4.1"
|
||||||
resolved "https://registry.yarnpkg.com/merge2/-/merge2-1.4.1.tgz#4368892f885e907455a6fd7dc55c0c9d404990ae"
|
resolved "https://registry.yarnpkg.com/merge2/-/merge2-1.4.1.tgz#4368892f885e907455a6fd7dc55c0c9d404990ae"
|
||||||
|
|
Loading…
Reference in a new issue