Giter VIP home page Giter VIP logo

blog-cells's Introduction

blog-cells

Node.js CI npm

[VIEW DEMO]

Add interactive code cells to any webpage, similar to Jupyter or ObservableHQ. Works with direct HTML editing, static site generators like Jekyll / Hugo, and more.

Usage

Quickstart

Just drop in JS / CSS imports and start creating code cells using <script type="text/notebook-cell"> elements. blog-cells will transform these script tags into interactive, runnable code snippets.

<!-- Import blog-cells JS and CSS files. -->
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/[email protected]/dist/blog-cells.css" />
<script src="https://cdn.jsdelivr.net/npm/[email protected]/dist/blog-cells.js"></script>

<!-- Create your code cells in script tags -->
<script type="text/notebook-cell">
console.log("Hello World!");
</script>

Try it on CodePen or JSFiddle.

Other Languages

In addition to JavaScript, you can also embed code in other languages by adding a data-kernel attribute.

<script type="text/notebook-cell" data-kernel="python">
print("Hello World!")
</script>

The following kernel values are currently supported:

  • javascript (Default)
  • python

Cell Attributes

Cells can be configured with the following attributes:

  • data-autorun="true" - Automatically run a cell on page load. Autorun cells are run in the order that they appear on the page.
  • data-hidden="true" - Make a cell hidden by default - readers can toggle the cell's visibility.

Using <pre> tags instead of <script> tags

Script tags are great for defining notebook cells since they can hold pretty much any code without escaping. However, you can also use <pre class="notebook-cell"> tags instead. When using pre tags, reserved HTML characters should be escaped using HTML entities (this can be done by your static site generator).

<pre class="notebook-cell">
console.log("&lt;b&gt;HELLO&lt;/b&gt;");
</pre>

Creating a Custom Kernel

You can easily define and use your own custom kernels.

<!-- Import blog-cells JS and CSS files. -->
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/[email protected]/dist/blog-cells.css" />
<script src="https://cdn.jsdelivr.net/npm/[email protected]/dist/blog-cells.js"></script>

<!-- Define custom kernel -->
<script>
class JSONFormatKernel extends BlogCells.Kernel {
  async run(code, onOutput) {
    const data = JSON.parse(code.trim());
    onOutput({ type: "log", line: JSON.stringify(data, undefined, 2) });
  }
}
BlogCells.registerKernel("json-format", () => new JSONFormatKernel());
</script>
  
<!-- Use custom Kernel -->
<script type="text/notebook-cell" data-kernel="json-format">
[4, {"hello": 3}]
</script>

Developing

git clone https://github.com/rameshvarun/blog-cells.git
cd blog-cells
npm install
npm start

Attributions

This repo contains assets from other open source projects.

Alternatives

blog-cells's People

Contributors

rameshvarun avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar

blog-cells's Issues

Support TypeScript

The first step is to simply support type annotations that are unchecked (should be pretty easy with Babel). The next step (more complex) is to actually typecheck.

It should be possible but may require some parsing + creation of .d.ts files.

Custom Kernels

You should be able to define your own Kernel in a script tag and use it. Something like this:

<!-- Import Blog Cells -->
<script type="module" src="blog-cells.js" />

<!-- Define Kernel -->
<script>
class CustomKernel extends BlogCells.Kernel {
  async run(code, onOutput) {
    ...
  }
}

BlogCells.registerKernel("custom", () => new CustomKernel());
</script>

<!-- Create Cell -->
<script type="text/notebook-cell" data-kernel="custom">
code_in_a_custom_language()
</script>

[Python] Allow top-level await

Allow top level await, mainly for things like installing packages through micropip. Ideally this would happen automatically, but worst-case let the user mark a specific cell as an async cell.

Support Languages through RISC-V Emulation

Right now, we only support languages where the compiler/interpreter itself can run in WASM. For many languages, this will never be well supported (even if it's possible to hack it together).

We can support a wider variety of languages by emulating a RISC-V, linux-based machine. This should work particularly well for C, C++, and Rust, and allow code to use I/O, threading, and more that wouldn't be possible in pure WASM.

To keep machine images small, we should create minimal linux images using buildroot/busybox.

Example: https://bellard.org/jslinux/vm.html?cpu=riscv64&url=buildroot-riscv64.cfg&mem=256

x86 emulation could also be used (example: https://supabase.com/blog/postgres-wasm), but due to the complexity of the ISA, most x86 emulators only emulate a portion of the spec.

Get Rid of the `$`

There are three ways to get rid of the $ requirement, but all have trade-offs.

  1. Install exports onto globalThis. This could clobber built-ins and break things For example, if someone writes the code export const postMessage = () => {}, the worker won't be able communicate with the main page anymore.
  2. Auto-destructure values from $, eg add "const a = $.a" to the prelude. However this would make values early bound, whereas we want them to be late bound (lookup on use).
  3. Use Babel to transpile unbound globals, eg "console.log(a) -> console.log($.a)". However, it means that newer JS syntax can't be used in a notebook without upgrading it's Babel version.

Already implemented 3 in 283d100, but removed since I didn't have time to fully test.

Can't Load Directly from CDN

It would be great if you could simply import the scripts from a CDN, but by default, this doesn't seem to be possible since workers from remote domains can't be loaded without explicit CSP headers (which many people can't control).

There are maybe some workarounds but if there's a chance browsers could break them in the future, the best thing to do is make it easy for people to download the JS / CSS into their own site's folder.

Handle noscript Better

Right now, with Javascript disabled, the code simply doesn't show at all. We should handle this better. Maybe let people create code cells in <pre> tags and transform them in-place into cells?

Is output scope available to the main document?

I would like to run: let name = "Danny"

And then have my code in the main document check what value name is.

Preferable as a property bag or something on the blog-cell itself, as there will be multiple on the page.

Brings me to the second feature request; can the blog-cell emit a Event, so I now calculation was done.

Make Notebooks Archivable

Theoretically It should be possible to run notebooks from the Internet Archive, but this seems to have issues. At the very least, we should ensure that cells display properly.

One issue is #4 - to fix it I switched to inline Blob workers, but those aren't correctly handled in Wombat.

Support C#

Awesome work. It will be even more awesome if it supports C#.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.