asg017 / unofficial-observablehq-compiler

An unofficial compiler for Observable notebook syntax
https://www.npmjs.com/package/@alex.garcia/unofficial-observablehq-compiler
115 stars 22 forks source link

Implement function to compile notebook JSON to ES module? #5

Closed bryangingechen closed 4 years ago

bryangingechen commented 5 years ago

I'm thinking of adapting the code I wrote in this notebook to the V3 runtime format using your compiler.

Would you welcome a PR that adds a function which takes as input a notebook JSON object (maybe also a JSON string) and outputs the define function? Something to worry about here is the fact that the notebook JSON format is not in any way officially supported so it could very well change without warning. However, something like this might still be useful for the folks who have been backing up their notebooks locally per this thread.

As I recall, I used the parser's parseCell function to implement the V1 version of this, so I might end up writing some kind of compile.cell function as discussed in #3.

asg017 commented 5 years ago

Sure, this makes sense! Maybe we can have a compile.notebook that takes in the notebook object and compiles it into a define function. I'd rather the object be the input instead of a JSON string (so it's not confused with compile.module).

bryangingechen commented 5 years ago

I thought a bit more about this and there are actually two parts to this:

nicola commented 4 years ago

any way (or hint) to make this work? this seems to me like a blocker if we want to be able to "import" local notebooks defined in this way

bryangingechen commented 4 years ago

I was hoping to get back to this within a few weeks or so, but if you'd like to work on it yourself, the basic idea is just to imitate the output of the files that are generated by the https://api.observablehq.com/@:user/:notebook.js?v=3 endpoint. I couldn't tell you the exact format from memory, but roughly speaking those files begin with import statements for all the referenced imports, then a define function which creates a main module and then populates it with variable objects for the code cells and module objects for the imports.

For the variable objects, we need to use the parser output to wrap the source code of each non-import cell and turn it into the source code for a variable definition (string to string). I think we may be able to reuse some of the logic in createRegularCellDefintion that appears before we pass things to the Function constructor.

Similarly, the parser output for import cells is used to create the module objects and the import statements at the top of the file. This will just take some fiddling.

Anyways, let me know if you start working on this. I'd be happy to give more suggestions / tips.

bryangingechen commented 4 years ago

I've started work on this. Hoping to PR something by the end of the week. 🤞

bryangingechen commented 4 years ago

This is now live as of v0.5.0. Woohoo!

nicola commented 4 years ago

that is awesome, thank you!