Compiler

Observable HQ Notebook Compiler and Interpreter

Minimal JSON Notebook

While the compiler supports and persists the entire Observable HQ Notebook (v3), it only needs a minimal subset to actually function:

interface Notebook {
    files: File[];
    nodes: Node[];
}

interface Node {
    id: number | string;
    mode: "js" | "md";
    value: string;
}

interface File {
    name: string;
    url: string;
    mime_type?: string;
}

# compile(notebook) => Promise<function> ยท <>

Hello World Example

First take a simple hello world notebook

const notebook = {
    files: [],
    nodes: [
        {
            id: 1,
            value: "md`# ${h} ${w}`",
            mode: "js"
        },
        {
            id: 2,
            value: "h = \"Hello\"",
            mode: "js"
        },
        {
            id: 3,
            value: "w = \"World\"",
            mode: "js"
        }
    ]
}

Then import the compiler and invoke it:

import { compile } from "@hpcc-js/observablehq-compiler";

const compiledNotebook = await compile(notebook);

To render it to a web page, simply follow the same steps as if you had downloaded a compiled version from ObservableHQ site:


import { Library, Runtime, Inspector } from "https://cdn.skypack.dev/@observablehq/runtime";

const placeholder = document.getElementById("placeholder");

const library = new Library();
const runtime = new Runtime(library);

compiledNotebook(runtime, name => {
    const div = document.createElement("div");
    placeholder.appendChild(div);
    return new Inspector(div);
});

Putting it all together:

<div id="placeholder" style="height:100%;overflow-y:scroll">
</div>
<script type="module">
  import { Library, Runtime, Inspector } from "https://cdn.skypack.dev/@observablehq/runtime";
  import { compile } from "@hpcc-js/observablehq-compiler";

  const placeholder = document.getElementById("placeholder");

  const notebook = {
      files: [],
      nodes: [
          {
              id: 1,
              value: "md`# ${h} ${w}`",
              mode: "js"
          },
          {
              id: 2,
              value: "h = \"Hello\"",
              mode: "js"
          },
          {
              id: 3,
              value: "w = \"World\"",
              mode: "js"
          }
      ]
  }

  const compiledNotebook = await compile(notebook);

  const library = new Library();
  const runtime = new Runtime(library);
  compiledNotebook(runtime, name => {
      const div = document.createElement("div");
      placeholder.appendChild(div);
      return new Inspector(div);
  });
</script>

To output the generated code simply call toString on the compiled function:

<hpcc-codemirror id="placeholder" mode="javascript" theme="dark" style="width:100%;height:100%">
</hpcc-codemirror>
<script type="module">
  import "@hpcc-js/wc-editor";
  import { compile } from "@hpcc-js/observablehq-compiler";

  const notebook = {
      files: [],
      nodes: [
          {
              id: 1,
              value: "md`# ${h} ${w}`",
              mode: "js"
          },
          {
              id: 2,
              value: "h = \"Hello\"",
              mode: "js"
          },
          {
              id: 3,
              value: "w = \"World\"",
              mode: "js"
          }
      ]
  }

  const compiledNotebook = await compile(notebook);
  const placeholder = document.getElementById("placeholder");
  placeholder.text = compiledNotebook.toString();
</script>

MoreExamples

<div id="placeholder" style="height:400px;overflow-y:scroll">
</div>
<script type="module">
  import { Library, Runtime, Inspector } from "https://cdn.skypack.dev/@observablehq/runtime";
  import { download, compile } from "@hpcc-js/observablehq-compiler";

  const notebookUrl = "https://observablehq.com/@observablehq/plot";
  const placeholder = document.getElementById("placeholder");

  const notebook = await download(notebookUrl);
  const compiledNB = await compile(notebook);

  const library = new Library();
  const runtime = new Runtime(library);
  compiledNB(runtime, name => {
      const div = document.createElement("div");
      placeholder.appendChild(div);
      return new Inspector(div);
  });
</script>

<div id="placeholder" style="height:400px;overflow-y:scroll">
</div>
<script type="module">
  import { Library, Runtime, Inspector } from "https://cdn.skypack.dev/@observablehq/runtime";
  import { download, compile } from "@hpcc-js/observablehq-compiler";

  const notebookUrl = "https://observablehq.com/@mbostock/fullscreen-canvas";
  const placeholder = document.getElementById("placeholder");

  const notebook = await download(notebookUrl);
  const compiledNB = await compile(notebook);

  const library = new Library();
  const runtime = new Runtime(library);
  compiledNB(runtime, name => {
      const div = document.createElement("div");
      placeholder.appendChild(div);
      return new Inspector(div);
  });
</script>