@hpcc-js/observablehq-compiler 1.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (46) hide show
  1. package/README.md +106 -0
  2. package/bin/ojscc.mjs +75 -0
  3. package/dist/index.css +1 -0
  4. package/dist/index.esm.css +1 -0
  5. package/dist/index.esm.js +7168 -0
  6. package/dist/index.esm.js.map +1 -0
  7. package/dist/index.js +7176 -0
  8. package/dist/index.js.map +1 -0
  9. package/package.json +80 -0
  10. package/src/__package__.ts +3 -0
  11. package/src/__tests__/File Attachments.ts +895 -0
  12. package/src/__tests__/Introduction to Imports.ts +749 -0
  13. package/src/__tests__/Observable TimeChart.ts +772 -0
  14. package/src/__tests__/index.ts +13 -0
  15. package/src/__tests__/node.ts +177 -0
  16. package/src/__tests__/tsconfig.json +21 -0
  17. package/src/compiler.md +234 -0
  18. package/src/compiler.ts +264 -0
  19. package/src/cst.ts +172 -0
  20. package/src/index.css +460 -0
  21. package/src/index.ts +7 -0
  22. package/src/util.md +113 -0
  23. package/src/util.ts +154 -0
  24. package/src/writer.ts +80 -0
  25. package/types/__package__.d.ts +4 -0
  26. package/types/__package__.d.ts.map +1 -0
  27. package/types/__tests__/File Attachments.d.ts +110 -0
  28. package/types/__tests__/File Attachments.d.ts.map +1 -0
  29. package/types/__tests__/Introduction to Imports.d.ts +120 -0
  30. package/types/__tests__/Introduction to Imports.d.ts.map +1 -0
  31. package/types/__tests__/Observable TimeChart.d.ts +111 -0
  32. package/types/__tests__/Observable TimeChart.d.ts.map +1 -0
  33. package/types/__tests__/index.d.ts +2 -0
  34. package/types/__tests__/index.d.ts.map +1 -0
  35. package/types/__tests__/node.d.ts +2 -0
  36. package/types/__tests__/node.d.ts.map +1 -0
  37. package/types/compiler.d.ts +88 -0
  38. package/types/compiler.d.ts.map +1 -0
  39. package/types/cst.d.ts +42 -0
  40. package/types/cst.d.ts.map +1 -0
  41. package/types/index.d.ts +6 -0
  42. package/types/index.d.ts.map +1 -0
  43. package/types/util.d.ts +26 -0
  44. package/types/util.d.ts.map +1 -0
  45. package/types/writer.d.ts +19 -0
  46. package/types/writer.d.ts.map +1 -0
package/README.md ADDED
@@ -0,0 +1,106 @@
1
+ # @hpcc-js/observablehq-compiler
2
+
3
+ An unofficial compiler, interpreter and download tool for [Observable HQ](https://observablehq.com/) notebooks.
4
+
5
+ * [Quick Start](#quick-start)
6
+ * [Compiler](./src/compiler)
7
+ * [Utilities](./src/util)
8
+
9
+ ## Quick Start
10
+
11
+ This library contains a command line tool (`ojscc`) for downloading and compiling notebooks and an interpreter for rendering notebooks in the browser:
12
+ * [Command line interface](#command-line-interface)
13
+ * [JS Interpreter](#js-interpreter)
14
+
15
+ ## Command line interface
16
+
17
+ To call `ojscc` without installing:
18
+
19
+ ```sh
20
+ npx -p @hpcc-js/observablehq-compiler ojscc [download | compile] ...
21
+ ```
22
+
23
+ To install `ojscc` as a global command:
24
+ ```sh
25
+ npm install --global @hpcc-js/observablehq-compiler
26
+ ```
27
+
28
+ Then it can be called by:
29
+ ```sh
30
+ ojscc [download | compile] ...
31
+ ```
32
+
33
+ ### Usage:
34
+
35
+ General:
36
+ ```sh
37
+ ojscc [command]
38
+
39
+ Commands:
40
+ ojscc download Download ObservableHQ Notebook
41
+ ojscc compile Compile ObservableHQ Notebook
42
+
43
+ Options:
44
+ --version Show version number [boolean]
45
+ -h, --help Show help [boolean]
46
+ ```
47
+
48
+ Download:
49
+ ```sh
50
+ ohqcc download [-o myfile.ojsnb] https://observablehq.com/@user/notebook
51
+
52
+ Options:
53
+ --version Show version number [boolean]
54
+ -h, --help Show help [boolean]
55
+ -o, --output Optional output file path
56
+ ```
57
+
58
+ Compile:
59
+ ```sh
60
+ ohqcc compile [-o myfile.js] myfile.ojsnb
61
+
62
+ Options:
63
+ --version Show version number [boolean]
64
+ -h, --help Show help [boolean]
65
+ -o, --output Optional output file path
66
+ ```
67
+
68
+ ## JS Interpreter
69
+
70
+ To install with npm :
71
+ ```
72
+ npm install --save @hpcc-js/observablehq-compiler
73
+ ```
74
+
75
+ The interpreter is 100% compatible with:
76
+ * [ObservableHQ Runtime](https://github.com/observablehq/runtime)
77
+ * [ObservableHQ Inspector](https://github.com/observablehq/inspector)
78
+ * [ObservableHQ Library](https://github.com/observablehq/library)
79
+
80
+ It also supports fetching notebooks directly from the ObservableHQ repository.
81
+
82
+ ```js
83
+ import { Library, Runtime, Inspector } from "@observablehq/runtime";
84
+ import { download, compile } from "@hpcc-js/observablehq-compiler";
85
+
86
+ const placeholder = document.getElementById("placeholder");
87
+
88
+ const ohqnb = await download("https://observablehq.com/@observablehq/summary-table");
89
+ const compiledNB = await compile(ohqnb);
90
+
91
+ const library = new Library();
92
+ const runtime = new Runtime(library);
93
+ compiledNB(runtime, name => {
94
+ const div = document.createElement("div");
95
+ placeholder.appendChild(div);
96
+ return new Inspector(div);
97
+ });
98
+ ```
99
+
100
+ Which produces (screenshot):
101
+
102
+ ---
103
+
104
+ ![Sumary Table](./resources/summary-table.png)
105
+
106
+ ---
package/bin/ojscc.mjs ADDED
@@ -0,0 +1,75 @@
1
+ #!/usr/bin/env node
2
+ /* eslint-disable no-undef */
3
+ /* eslint-disable @typescript-eslint/no-var-requires */
4
+
5
+ import fetch, { Blob, blobFrom, blobFromSync, File, fileFrom, fileFromSync, FormData, Headers, Request, Response } from "node-fetch";
6
+ if (!globalThis.fetch) {
7
+ globalThis.fetch = fetch;
8
+ globalThis.Headers = Headers;
9
+ globalThis.Request = Request;
10
+ globalThis.Response = Response;
11
+ }
12
+ import { promises as fs } from "fs";
13
+ import { compile, download, Writer } from "../dist/index.js";
14
+ import yargsMode from "yargs/yargs";
15
+
16
+ async function doDownload(url, filePath) {
17
+ const nb = await download(url);
18
+ if (filePath) {
19
+ fs.writeFile(filePath, JSON.stringify(nb, undefined, 4));
20
+ } else {
21
+ console.info(nb);
22
+ }
23
+ }
24
+
25
+ async function doCompile(url, filePath) {
26
+ const nb = await download(url);
27
+ const define = await compile(nb, process.cwd());
28
+ const w = new Writer();
29
+ define.write(w);
30
+ if (filePath) {
31
+ fs.writeFile(filePath, w.toString());
32
+ } else {
33
+ console.info(w.toString());
34
+ }
35
+ }
36
+
37
+ const yargs = yargsMode(process.argv.slice(2));
38
+ yargs
39
+ .scriptName("ojscc")
40
+ .wrap(Math.min(90, yargs.terminalWidth()))
41
+ .command("download", "Download ObservableHQ Notebook",
42
+ function (yargs) {
43
+ return yargs
44
+ .usage("ohqcc download [-o myfile.ojsnb] https://observablehq.com/@user/notebook")
45
+ .demandCommand(1, "URL required")
46
+ .option("o", {
47
+ alias: "output",
48
+ describe: "Optional output file path"
49
+ })
50
+ ;
51
+ }, function (argv) {
52
+ doDownload(argv._[1], argv.o);
53
+ }
54
+ )
55
+ .command("compile", "Compile ObservableHQ Notebook",
56
+ function (yargs) {
57
+ return yargs
58
+ .usage("ohqcc compile [-o myfile.js] myfile.ojsnb")
59
+ .demandCommand(1, "URL required")
60
+ .option("o", {
61
+ alias: "output",
62
+ describe: "Optional output file path"
63
+ })
64
+ ;
65
+ },
66
+ async function (argv) {
67
+ doCompile(argv._[1], argv.o);
68
+ }
69
+ )
70
+ .help("h")
71
+ .alias("h", "help")
72
+ .epilog("https://github.com/hpcc-systems/Visualization/tree/trunk/packages/observablehq-compiler")
73
+ ;
74
+
75
+ yargs.argv;
package/dist/index.css ADDED
@@ -0,0 +1 @@
1
+ @import url("https://fonts.googleapis.com/css2?family=Source+Serif+Pro:ital,wght@0,400;0,600;0,700;1,400;1,600;1,700&display=swap");:root{--syntax-normal:#1b1e23;--syntax-comment:#828282;--syntax-number:#20a5ba;--syntax-keyword:#c30771;--syntax-atom:#10a778;--syntax-string:#008ec4;--syntax-error:#ffbedc;--syntax-unknown-variable:#838383;--syntax-known-variable:#005f87;--syntax-matchbracket:#20bbfc;--syntax-key:#6636b4;--mono-fonts:82%/1.5 Menlo,Consolas,monospace}.observablehq--collapsed,.observablehq--expanded,.observablehq--function,.observablehq--gray,.observablehq--import,.observablehq--string:after,.observablehq--string:before{color:var(--syntax-normal)}.observablehq--collapsed,.observablehq--expanded.observablehq--inspect a{cursor:pointer}.observablehq--field{margin-left:1em;text-indent:-1em}.observablehq--empty{color:var(--syntax_comment)}.observablehq--blue,.observablehq--keyword,a[href]{color:#3182bd}.hljs-deletion,.hljs-variable,.observablehq--forbidden,.observablehq--pink{color:#e377c2}.observablehq--orange{color:#e6550d}.hljs-literal,.observablehq--boolean,.observablehq--null,.observablehq--undefined{color:var(--syntax-atom)}.hljs-bullet,.hljs-link,.hljs-number,.hljs-regexp,.observablehq--bigint,.observablehq--date,.observablehq--green,.observablehq--number,.observablehq--regexp,.observablehq--symbol{color:var(--syntax-number)}.observablehq--index,.observablehq--key{color:var(--syntax-key)}.observablehq--prototype-key{color:#aaa}.observablehq--empty{font-style:oblique}.hljs-addition,.hljs-meta,.hljs-string,.hljs-symbol,.hljs-template-tag,.hljs-template-variable,.observablehq--purple,.observablehq--string{color:var(--syntax-string)}.observablehq--error,.observablehq--red{color:#e7040f}.observablehq--inspect,.observablehq:empty:after,.observablehq>link:only-child,.observablehq>style:only-child{display:block;font:var(--monospace-font);overflow-x:auto;padding:4px 0;white-space:pre}.observablehq--error .observablehq--inspect{white-space:pre-wrap;word-break:break-all}:root{--syntax-diff:#24292e;--syntax-diff-bg:#fff;--hr:rgba(0,0,0,.05);--monospace:Menlo,Consolas,monospace;--monospace-font:14px/1.5 var(--monospace);--serif:"Source Serif Pro","Iowan Old Style","Apple Garamond","Palatino Linotype","Times New Roman","Droid Serif",Times,serif,"Apple Color Emoji","Segoe UI Emoji","Segoe UI Symbol";--sans-serif:-apple-system,BlinkMacSystemFont,"avenir next",avenir,helvetica,"helvetica neue",ubuntu,roboto,noto,"segoe ui",arial,sans-serif}html{-webkit-text-size-adjust:100%;-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale;color:#1b1e23;font:17px/1.5 var(--serif)}body{margin:0 14px}body.fullscreen{margin:0}h1,h2,h3,h4,h5,h6{color:#333;font-weight:700;line-height:1.15;margin-bottom:.25rem;margin-top:0}h2~p,h2~table,h3~p,h3~table,h4~p,h4~table{margin-top:0}.observablehq:first-of-type h1+h2{font-size:20px;font-style:italic;font-weight:400;margin-bottom:1rem}a[href]{text-decoration:none}a[href]:hover{text-decoration:underline}h1 code,h2 code,h3 code,h4 code,h5 code,h6 code{font-size:90%}code,pre,tt{font-family:var(--monospace);font-size:14px;line-height:1.5}img{max-width:calc(100vw - 28px)}.katex-display,figcaption,figure,h1,h2,h3,h4,h5,h6,p,table{max-width:640px}blockquote,ol,ul{max-width:600px}blockquote{margin:1rem 1.5rem}ol,ul{padding-left:28px}hr{background:no-repeat 50%/100% 1px linear-gradient(to right,var(--hr),var(--hr));border:none;height:1px;margin:1rem 0;padding:1rem 0}pre{padding:2px 0}.observablehq--md-pre{overflow-x:auto}input:not([type]),input[type=email],input[type=number],input[type=password],input[type=range],input[type=search],input[type=tel],input[type=text],input[type=url]{width:240px}button,canvas,input{vertical-align:middle}button,input,textarea{accent-color:#3b5fc0}table{border-collapse:collapse;font:13px/1.2 var(--sans-serif);width:100%}table code,table pre,table tt{font-size:inherit;line-height:inherit}td>pre:only-child,th>pre:only-child{margin:0;padding:0}th{color:#111;text-align:left;vertical-align:bottom}td{color:#444;vertical-align:top}td,th{padding:3px 6.5px 3px 0}td:last-child,th:last-child{padding-right:0}tr:not(:last-child){border-bottom:1px solid #eee}thead tr{border-bottom:1px solid #ccc}figure,table{margin:1rem 0}figure img{max-width:100%}figcaption{color:var(--syntax-unknown-variable);font:small var(--sans-serif)}.observablehq--caret{margin-right:4px;vertical-align:baseline}.observablehq--field{margin-left:1rem;text-indent:-1rem}.hljs-comment,.observablehq--empty,.observablehq--prototype-key{color:var(--syntax-comment)}.hljs-built_in{color:var(--syntax-known-variable)}.observablehq--unknown{color:var(--syntax-unknown-variable)}.hljs-doctag,.hljs-keyword,.hljs-name,.hljs-section,.hljs-selector-class,.hljs-selector-id,.hljs-selector-tag,.hljs-strong,.hljs-tag,.hljs-type{color:var(--syntax-keyword)}.observablehq{margin:17px 0;min-height:1.5rem;position:relative}.observablehq:before{bottom:1px;content:"";left:-14px;position:absolute;top:0;transition:background-color .25s linear;width:4px}.observablehq--changed:before,.observablehq--running:before{background-color:#a9b0bc;transition:none}.observablehq--error:before{background-color:#e7040f}.observablehq:not(.observablehq--running):empty:after{color:var(--syntax-comment);content:"<detached>";font-style:oblique}.observablehq>link:only-child,.observablehq>style:only-child{color:var(--syntax-keyword);visibility:hidden;white-space:nowrap}.observablehq>link:only-child:before{content:"<link>";pointer-events:none;text-decoration:none;visibility:visible}.observablehq>style:only-child:before{content:"<style>";visibility:visible}.observablehq--inspect.observablehq--import{white-space:normal}.observablehq--inspect::-webkit-scrollbar{display:none}.observablehq--string-expand{background:#eee;border-radius:2px;color:var(--syntax-normal);cursor:pointer;font-size:80%;margin-left:6px;padding:2px 6px;position:sticky;right:0;vertical-align:middle}.observablehq--string-expand:active,.observablehq--string-expand:hover{background:#ddd}
@@ -0,0 +1 @@
1
+ @import url("https://fonts.googleapis.com/css2?family=Source+Serif+Pro:ital,wght@0,400;0,600;0,700;1,400;1,600;1,700&display=swap");:root{--syntax-normal:#1b1e23;--syntax-comment:#828282;--syntax-number:#20a5ba;--syntax-keyword:#c30771;--syntax-atom:#10a778;--syntax-string:#008ec4;--syntax-error:#ffbedc;--syntax-unknown-variable:#838383;--syntax-known-variable:#005f87;--syntax-matchbracket:#20bbfc;--syntax-key:#6636b4;--mono-fonts:82%/1.5 Menlo,Consolas,monospace}.observablehq--collapsed,.observablehq--expanded,.observablehq--function,.observablehq--gray,.observablehq--import,.observablehq--string:after,.observablehq--string:before{color:var(--syntax-normal)}.observablehq--collapsed,.observablehq--expanded.observablehq--inspect a{cursor:pointer}.observablehq--field{margin-left:1em;text-indent:-1em}.observablehq--empty{color:var(--syntax_comment)}.observablehq--blue,.observablehq--keyword,a[href]{color:#3182bd}.hljs-deletion,.hljs-variable,.observablehq--forbidden,.observablehq--pink{color:#e377c2}.observablehq--orange{color:#e6550d}.hljs-literal,.observablehq--boolean,.observablehq--null,.observablehq--undefined{color:var(--syntax-atom)}.hljs-bullet,.hljs-link,.hljs-number,.hljs-regexp,.observablehq--bigint,.observablehq--date,.observablehq--green,.observablehq--number,.observablehq--regexp,.observablehq--symbol{color:var(--syntax-number)}.observablehq--index,.observablehq--key{color:var(--syntax-key)}.observablehq--prototype-key{color:#aaa}.observablehq--empty{font-style:oblique}.hljs-addition,.hljs-meta,.hljs-string,.hljs-symbol,.hljs-template-tag,.hljs-template-variable,.observablehq--purple,.observablehq--string{color:var(--syntax-string)}.observablehq--error,.observablehq--red{color:#e7040f}.observablehq--inspect,.observablehq:empty:after,.observablehq>link:only-child,.observablehq>style:only-child{display:block;font:var(--monospace-font);overflow-x:auto;padding:4px 0;white-space:pre}.observablehq--error .observablehq--inspect{white-space:pre-wrap;word-break:break-all}:root{--syntax-diff:#24292e;--syntax-diff-bg:#fff;--hr:rgba(0,0,0,.05);--monospace:Menlo,Consolas,monospace;--monospace-font:14px/1.5 var(--monospace);--serif:"Source Serif Pro","Iowan Old Style","Apple Garamond","Palatino Linotype","Times New Roman","Droid Serif",Times,serif,"Apple Color Emoji","Segoe UI Emoji","Segoe UI Symbol";--sans-serif:-apple-system,BlinkMacSystemFont,"avenir next",avenir,helvetica,"helvetica neue",ubuntu,roboto,noto,"segoe ui",arial,sans-serif}html{-webkit-text-size-adjust:100%;-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale;color:#1b1e23;font:17px/1.5 var(--serif)}body{margin:0 14px}body.fullscreen{margin:0}h1,h2,h3,h4,h5,h6{color:#333;font-weight:700;line-height:1.15;margin-bottom:.25rem;margin-top:0}h2~p,h2~table,h3~p,h3~table,h4~p,h4~table{margin-top:0}.observablehq:first-of-type h1+h2{font-size:20px;font-style:italic;font-weight:400;margin-bottom:1rem}a[href]{text-decoration:none}a[href]:hover{text-decoration:underline}h1 code,h2 code,h3 code,h4 code,h5 code,h6 code{font-size:90%}code,pre,tt{font-family:var(--monospace);font-size:14px;line-height:1.5}img{max-width:calc(100vw - 28px)}.katex-display,figcaption,figure,h1,h2,h3,h4,h5,h6,p,table{max-width:640px}blockquote,ol,ul{max-width:600px}blockquote{margin:1rem 1.5rem}ol,ul{padding-left:28px}hr{background:no-repeat 50%/100% 1px linear-gradient(to right,var(--hr),var(--hr));border:none;height:1px;margin:1rem 0;padding:1rem 0}pre{padding:2px 0}.observablehq--md-pre{overflow-x:auto}input:not([type]),input[type=email],input[type=number],input[type=password],input[type=range],input[type=search],input[type=tel],input[type=text],input[type=url]{width:240px}button,canvas,input{vertical-align:middle}button,input,textarea{accent-color:#3b5fc0}table{border-collapse:collapse;font:13px/1.2 var(--sans-serif);width:100%}table code,table pre,table tt{font-size:inherit;line-height:inherit}td>pre:only-child,th>pre:only-child{margin:0;padding:0}th{color:#111;text-align:left;vertical-align:bottom}td{color:#444;vertical-align:top}td,th{padding:3px 6.5px 3px 0}td:last-child,th:last-child{padding-right:0}tr:not(:last-child){border-bottom:1px solid #eee}thead tr{border-bottom:1px solid #ccc}figure,table{margin:1rem 0}figure img{max-width:100%}figcaption{color:var(--syntax-unknown-variable);font:small var(--sans-serif)}.observablehq--caret{margin-right:4px;vertical-align:baseline}.observablehq--field{margin-left:1rem;text-indent:-1rem}.hljs-comment,.observablehq--empty,.observablehq--prototype-key{color:var(--syntax-comment)}.hljs-built_in{color:var(--syntax-known-variable)}.observablehq--unknown{color:var(--syntax-unknown-variable)}.hljs-doctag,.hljs-keyword,.hljs-name,.hljs-section,.hljs-selector-class,.hljs-selector-id,.hljs-selector-tag,.hljs-strong,.hljs-tag,.hljs-type{color:var(--syntax-keyword)}.observablehq{margin:17px 0;min-height:1.5rem;position:relative}.observablehq:before{bottom:1px;content:"";left:-14px;position:absolute;top:0;transition:background-color .25s linear;width:4px}.observablehq--changed:before,.observablehq--running:before{background-color:#a9b0bc;transition:none}.observablehq--error:before{background-color:#e7040f}.observablehq:not(.observablehq--running):empty:after{color:var(--syntax-comment);content:"<detached>";font-style:oblique}.observablehq>link:only-child,.observablehq>style:only-child{color:var(--syntax-keyword);visibility:hidden;white-space:nowrap}.observablehq>link:only-child:before{content:"<link>";pointer-events:none;text-decoration:none;visibility:visible}.observablehq>style:only-child:before{content:"<style>";visibility:visible}.observablehq--inspect.observablehq--import{white-space:normal}.observablehq--inspect::-webkit-scrollbar{display:none}.observablehq--string-expand{background:#eee;border-radius:2px;color:var(--syntax-normal);cursor:pointer;font-size:80%;margin-left:6px;padding:2px 6px;position:sticky;right:0;vertical-align:middle}.observablehq--string-expand:active,.observablehq--string-expand:hover{background:#ddd}