diff --git a/src/compiler/cell.ts b/src/compiler/cell.ts index be3c776..5435de8 100644 --- a/src/compiler/cell.ts +++ b/src/compiler/cell.ts @@ -12,7 +12,7 @@ function encode(str: string) { ; } -class NullObserver implements ohq.Inspector { +export class NullObserver implements ohq.Inspector { pending() { } fulfilled(value: any) { @@ -22,7 +22,7 @@ class NullObserver implements ohq.Inspector { } export const nullObserver = new NullObserver(); -const nullObserverFactory: ohq.InspectorFactory = (name?: string) => nullObserver; +export const nullObserverFactory: ohq.InspectorFactory = (name?: string) => nullObserver; export class Cell { @@ -109,7 +109,7 @@ ${this._cellSource} break; case "viewof": this._variables.add(this._notebook.createVariable(this._observer(parsed.variable.id), parsed.variable.id, parsed.variable.inputs, parsed.variable.func)); - this._variables.add(this._notebook.createVariable(this._observer(parsed.variableValue.id), parsed.variableValue.id, parsed.variableValue.inputs, parsed.variableValue.func)); + this._variables.add(this._notebook.createVariable(undefined, parsed.variableValue.id, parsed.variableValue.inputs, parsed.variableValue.func)); break; case "mutable": this._variables.add(this._notebook.createVariable(undefined, parsed.initial.id, parsed.initial.inputs, parsed.initial.func)); @@ -132,7 +132,7 @@ ${this._cellSource} case "viewof": id = writer.function(parsed.variable); writer.define(parsed.variable, true, false, id); - writer.define(parsed.variableValue, true, true); + writer.define(parsed.variableValue, false, true); break; case "mutable": id = writer.function(parsed.initial); diff --git a/src/compiler/notebook.ts b/src/compiler/notebook.ts index 220b76c..16b0b48 100644 --- a/src/compiler/notebook.ts +++ b/src/compiler/notebook.ts @@ -1,23 +1,45 @@ +import { omd2ojs, ojsParse } from "@hpcc-js/observable-md/dist/index.node.js"; import { Runtime, Library } from "@observablehq/runtime"; import { FileAttachments } from "@observablehq/stdlib"; -import { Cell } from "./cell"; +import { Cell, nullObserverFactory } from "./cell"; import { observablehq as ohq } from "./types"; import { Writer } from "./writer"; export class Notebook { + protected _observerFactory: ohq.InspectorFactory; protected _runtime: ohq.Runtime; protected _main: ohq.Module; protected _cells: Set = new Set(); - constructor(notebook?: ohq.Notebook, plugins: object = {}) { + constructor(notebook?: ohq.Notebook, observerFactory: ohq.InspectorFactory = nullObserverFactory, plugins: object = {}) { + this._observerFactory = observerFactory; + this.create(notebook, plugins); + } + + parseOJS(ojs: string) { + this.dispose(); + this.create(); + const parsed = ojsParse(ojs); + parsed.cells.forEach((cell, idx) => { + this.createCell(this._observerFactory).text(ojs.substring(cell.start, cell.end), "ojs"); + }); + this.interpret(); + } + + parseOMD(omd: string) { + const tmp = omd2ojs(omd); + this.parseOJS(tmp.ojsArr.map(row => row.ojs).join("\n")); + } + + create(notebook?: Partial, plugins: object = {}) { const files = {}; notebook?.files?.forEach(f => files[f.name] = f.url); const library = new Library(); library.FileAttachment = function () { return FileAttachments(name => { - return files[name]; + return files[name] ?? name; }); }; @@ -46,6 +68,10 @@ export class Notebook { this._cells.delete(cell); } + interpret() { + this._cells.forEach(cell => cell.evaluate()); + } + compile(writer: Writer) { this._cells.forEach(cell => { try { diff --git a/src/notebook/renderers/renderer.ts b/src/notebook/renderers/renderer.ts index cb69476..6c658dd 100644 --- a/src/notebook/renderers/renderer.ts +++ b/src/notebook/renderers/renderer.ts @@ -5,6 +5,8 @@ import { Notebook } from "../../compiler/notebook"; import { Cell, nullObserver } from "../../compiler/cell"; import { observablehq } from "src/compiler/types"; +// import "../../../src/notebook/renderers/renderer.css"; + export const activate: ActivationFunction = context => { const notebooks: { [uri: string]: Notebook } = {}; diff --git a/src/webview.ts b/src/webview.ts index 6ec0400..0d9c076 100644 --- a/src/webview.ts +++ b/src/webview.ts @@ -1,7 +1,12 @@ /* eslint-disable no-inner-declarations */ -import { OJSRuntime, OJSSyntaxError, OMDRuntime, VariableValue } from "@hpcc-js/observable-md"; +import { OJSSyntaxError, VariableValue } from "@hpcc-js/observable-md"; import { hashSum, IObserverHandle } from "@hpcc-js/util"; +import { renderOJS, renderOMD } from "./compiler/index"; +import { Notebook } from "./compiler/notebook"; + +import "../src/webview.css"; + export interface Message { callbackID?: string; } @@ -39,13 +44,7 @@ const placeholder = document.getElementById("placeholder")!; if (window["__hpcc_test"]) { placeholder.innerText = ""; - const compiler = new OMDRuntime("#placeholder"); - - compiler.watch(notifcations => { - console.info(notifcations); - }); - - compiler.evaluate("", `\ + const notebook = renderOMD(`\ # OMD Generator Test ~~~ @@ -73,12 +72,20 @@ viewof; cars; \${JSON.stringify(cars, undefined, 2)} ~~~ -`, "."); +`, placeholder); + + // const compiler = new OMDRuntime("#placeholder"); + + // compiler.watch(notifcations => { + // console.info(notifcations); + // }); + + // compiler.evaluate("", , "."); } else { const vscode = acquireVsCodeApi(); let hash: string; - let compiler: OJSRuntime | OMDRuntime; + let notebook: Notebook; let watcher: IObserverHandle; function stringify(value: any): string { @@ -135,49 +142,79 @@ viewof; cars; watcher.release(); } - placeholder.innerText = ""; - compiler = languageId === "omd" ? new OMDRuntime("#placeholder") : new OJSRuntime("#placeholder"); + const callback = { + pending() { + }, - watcher = compiler.watch(variableValues => { - vscode.postMessage({ - command: "values", - content: valuesContent(variableValues) - }); - }); + fulfilled(value: any) { + vscode.postMessage({ + command: "values", + content: [{ + uid: "", + error: false, + value: stringify(value) + }], + callbackID + }); + }, - compiler.evaluate("", encode(content), folder) - .then(variableValues => { + rejected(error: any) { vscode.postMessage({ command: "values", - content: valuesContent(variableValues), + content: [{ + uid: "", + error: true, + value: stringify(error) + }], callbackID }); - }).catch((e: OJSSyntaxError) => { - // this._errors = [new OJSRuntimeError("error", e.start, e.end, e.message)]; - // this.runtimeUpdated(); - }); + } + + }; + + placeholder.innerText = ""; + notebook = languageId === "omd" ? renderOMD(encode(content), placeholder, callback) : renderOJS(encode(content), placeholder, callback); + + // watcher = compiler.watch(variableValues => { + // vscode.postMessage({ + // command: "values", + // content: valuesContent(variableValues) + // }); + // }); + + // compiler.evaluate("", encode(content), folder) + // .then(variableValues => { + // vscode.postMessage({ + // command: "values", + // content: valuesContent(variableValues), + // callbackID + // }); + // }).catch((e: OJSSyntaxError) => { + // // this._errors = [new OJSRuntimeError("error", e.start, e.end, e.message)]; + // // this.runtimeUpdated(); + // }); } else { - compiler.refresh().then(variableValues => { - vscode.postMessage({ - command: "values", - content: valuesContent(variableValues), - callbackID - }); - }); + // compiler.refresh().then(variableValues => { + // vscode.postMessage({ + // command: "values", + // content: valuesContent(variableValues), + // callbackID + // }); + // }); } } function pull(url: string, callbackID: string) { - placeholder.innerText = `Importing notebook: ${url}`; - compiler = new OJSRuntime("#placeholder"); - compiler.pull(url).then(text => { - placeholder.innerText = ""; - vscode.postMessage({ - command: "pullResponse", - content: text, - callbackID - }); - }); + // placeholder.innerText = `Importing notebook: ${url}`; + // compiler = new OJSRuntime("#placeholder"); + // compiler.pull(url).then(text => { + // placeholder.innerText = ""; + // vscode.postMessage({ + // command: "pullResponse", + // content: text, + // callbackID + // }); + // }); } async function echo(content: string) {