• Stars
    star
    175
  • Rank 210,735 (Top 5 %)
  • Language
    JavaScript
  • License
    ISC License
  • Created over 6 years ago
  • Updated 6 months ago

Reviews

There are no reviews yet. Be the first to send feedback to the community and the maintainers!

Repository Details

The Observable parser.

@observablehq/parser

To parse a cell:

import {parseCell} from "@observablehq/parser";

const cell = parseCell(`hello = "world"`);

Examples

(In these examples, the node.start and node.end indexes into the input string are not shown for brevity. If options.locations is true, node.loc will also be populated with the line and column numbers.)

An expression cell (where cell.body is a type of expression):

1 + 2
{
  "type": "Cell",
  "id": null,
  "async": false,
  "generator": false,
  "body": {
    "type": "BinaryExpression",
    "left": {
      "type": "Literal",
      "value": 1,
      "raw": "1"
    },
    "operator": "+",
    "right": {
      "type": "Literal",
      "value": 2,
      "raw": "2"
    }
  }
}

A block cell (where cell.body is a BlockStatement):

{
  return 1 + 2;
}
{
  "type": "Cell",
  "id": null,
  "async": false,
  "generator": false,
  "body": {
    "type": "BlockStatement",
    "body": [
      {
        "type": "ReturnStatement",
        "argument": {
          "type": "BinaryExpression",
          "left": {
            "type": "Literal",
            "value": 1,
            "raw": "1"
          },
          "operator": "+",
          "right": {
            "type": "Literal",
            "value": 2,
            "raw": "2"
          }
        }
      }
    ]
  }
}

An empty cell (where cell.body is null):

{
  "type": "Cell",
  "id": null,
  "async": false,
  "generator": false,
  "body": null
}

A named expression cell (where cell.id is an Identifier):

foo = 42
{
  "type": "Cell",
  "id": {
    "type": "Identifier",
    "name": "foo"
  },
  "async": false,
  "generator": false,
  "body": {
    "type": "Literal",
    "value": 42,
    "raw": "42"
  }
}

A named block cell (where cell.id is an Identifier):

foo = {
  return 42;
}
{
  "type": "Cell",
  "id": {
    "type": "Identifier",
    "name": "foo"
  },
  "async": false,
  "generator": false,
  "body": {
    "type": "BlockStatement",
    "body": [
      {
        "type": "ReturnStatement",
        "argument": {
          "type": "Literal",
          "value": 42,
          "raw": "42"
        }
      }
    ]
  }
}

An asynchronous expression cell (where cell.async is true):

2 * await value
{
  "type": "Cell",
  "id": null,
  "async": true,
  "generator": false,
  "body": {
    "type": "BinaryExpression",
    "left": {
      "type": "Literal",
      "value": 2,
      "raw": "2"
    },
    "operator": "*",
    "right": {
      "type": "AwaitExpression",
      "argument": {
        "type": "Identifier",
        "name": "value"
      }
    }
  }
}

A generator expression cell (where cell.generator is true):

yield* [1, 2, 3]
{
  "type": "Cell",
  "id": null,
  "async": false,
  "generator": true,
  "body": {
    "type": "YieldExpression",
    "delegate": true,
    "argument": {
      "type": "ArrayExpression",
      "elements": [
        {
          "type": "Literal",
          "value": 1,
          "raw": "1"
        },
        {
          "type": "Literal",
          "value": 2,
          "raw": "2"
        },
        {
          "type": "Literal",
          "value": 3,
          "raw": "3"
        }
      ]
    }
  }
}

A viewof expression cell (where cell.id is a ViewExpression):

viewof x = DOM.range()
{
  "type": "Cell",
  "id": {
    "type": "ViewExpression",
    "id": {
      "type": "Identifier",
      "name": "x"
    }
  },
  "async": false,
  "generator": false,
  "body": {
    "type": "CallExpression",
    "callee": {
      "type": "MemberExpression",
      "object": {
        "type": "Identifier",
        "name": "DOM"
      },
      "property": {
        "type": "Identifier",
        "name": "range"
      },
      "computed": false
    },
    "arguments": []
  }
}

A viewof reference within an expression cell (where cell.body contains a ViewExpression):

viewof x.tagName
{
  "type": "Cell",
  "id": null,
  "async": false,
  "generator": false,
  "body": {
    "type": "MemberExpression",
    "object": {
      "type": "ViewExpression",
      "id": {
        "type": "Identifier",
        "name": "x"
      }
    },
    "property": {
      "type": "Identifier",
      "name": "tagName"
    },
    "computed": false
  }
}

An import cell (where cell.body is an ImportDeclaration):

import {foo} from "module"
{
  "type": "Cell",
  "id": null,
  "async": false,
  "generator": false,
  "body": {
    "type": "ImportDeclaration",
    "specifiers": [
      {
        "type": "ImportSpecifier",
        "view": false,
        "imported": {
          "type": "Identifier",
          "name": "foo"
        },
        "local": {
          "type": "Identifier",
          "name": "foo"
        }
      }
    ],
    "source": {
      "type": "Literal",
      "value": "module",
      "raw": "\"module\""
    }
  }
}

Importing a view (where specifier.view is true):

import {viewof foo} from "module"
{
  "type": "Cell",
  "id": null,
  "async": false,
  "generator": false,
  "body": {
    "type": "ImportDeclaration",
    "specifiers": [
      {
        "type": "ImportSpecifier",
        "view": true,
        "imported": {
          "type": "Identifier",
          "name": "foo"
        },
        "local": {
          "type": "Identifier",
          "name": "foo"
        }
      }
    ],
    "source": {
      "type": "Literal",
      "value": "module",
      "raw": "\"module\""
    }
  }
}

Importing a view imports both the view symbol (viewof foo) and the value symbol (foo). Likewise, if the specified view is renamed during import (e.g., viewof foo as bar), both the view symbol and the value symbol are renamed (e.g., viewof bar and bar).

Importing with injection (where declaration.injections is present):

import {chart} with {sales as data} from "@mbostock/d3-bar-chart"
{
  "type": "Cell",
  "id": null,
  "async": false,
  "generator": false,
  "body": {
    "type": "ImportDeclaration",
    "specifiers": [
      {
        "type": "ImportSpecifier",
        "view": false,
        "imported": {
          "type": "Identifier",
          "name": "chart"
        },
        "local": {
          "type": "Identifier",
          "name": "chart"
        }
      }
    ],
    "injections": [
      {
        "type": "ImportSpecifier",
        "view": false,
        "imported": {
          "type": "Identifier",
          "name": "sales"
        },
        "local": {
          "type": "Identifier",
          "name": "data"
        }
      }
    ],
    "source": {
      "type": "Literal",
      "value": "@mbostock/d3-bar-chart",
      "raw": "\"@mbostock/d3-bar-chart\""
    }
  }
}

For an injection, specifier.imported and specifier.local are reversed compared to a normal specifier: they are from the perspective of the imported module rather than the importing module. So in the example above, the importing module’s variable sales is injected into the imported module (the chart), replacing the variable data.

Injecting a view injects both the view symbol (viewof foo) and the value symbol (foo). Likewise, if the specified view is renamed during injection (e.g., viewof foo as bar), both the view symbol and the value symbol are renamed (e.g., viewof bar and bar).

API Reference

# parseCell(input[, options]) <>

Returns a cell.

# peekId(input) <>

Tries to find the ID of a cell given a snippet of its contents, and returns it as a string if found.

Cell

# cell.id

The name of the cell: null if the cell is anonymous; otherwise an Identifier or a ViewExpression.

# cell.body

The body of the cell: null for an empty cell; an ImportDeclaration for an import cell; otherwise a BlockStatement or an expression node.

# cell.async

A boolean indicating whether the cell body is asynchronous (i.e., whether it contains an await statement). False for import and empty cells.

# cell.generator

A boolean indicating whether the cell body is a generator (i.e., whether it contains a yield statement). False for import and empty cells.

ViewExpression

# view.id

The view identifier: an Identifier.

ImportDeclaration

# declaration.injections

An array of ImportSpecifier nodes, if the import declaration has a with clause, and otherwise null.

ImportSpecifier

# specifier.view

A boolean indicating whether the import specifies a view.

More Repositories

1

plot

A concise API for exploratory data visualization implementing a layered grammar of graphics
HTML
3,811
star
2

framework

A static site generator for data apps, dashboards, reports, and more. Observable Framework combines JavaScript on the front-end for interactive graphics with any language on the back-end for data analysis.
TypeScript
1,660
star
3

runtime

The reactive dataflow runtime that powers Observable Framework and Observable notebooks
JavaScript
958
star
4

stdlib

The Observable standard library.
JavaScript
943
star
5

htl

A tagged template literal that allows safe interpolation of values into HTML, following the HTML5 spec
JavaScript
290
star
6

inspector

The Observable standard inspector.
JavaScript
131
star
7

array

Manipulate columnar data efficiently using typed arrays.
JavaScript
125
star
8

inputs

Better input elements
JavaScript
111
star
9

examples

Examples of using Observable in a variety of contexts
HTML
102
star
10

datasets

Test datasets for convenience in Observable notebooks.
JavaScript
67
star
11

database-proxy

A proxy to connect Observable notebooks to databases on private networks
JavaScript
47
star
12

vega

Convenience methods for using Vega and Vega-Lite in Observable.
JavaScript
42
star
13

feedback

Customer submitted bugs and feature requests
41
star
14

graphviz

A convenience method for using Graphviz.
JavaScript
39
star
15

plot-create-react-app-example

An example of Observable Plot with Create React App
JavaScript
38
star
16

prettier-react-tachyons

A prettier transform for React and Tachyon users.
JavaScript
29
star
17

notebook-download-example

An example of downloading and embedding an Observable notebook into a web app.
JavaScript
23
star
18

rollup-plugin-credits

Generate license credits
JavaScript
16
star
19

react-zoomable-sunburst

create-react-app + observablehq
JavaScript
15
star
20

katex

A minimally-tweaked distribution of KaTeX.
CSS
9
star
21

create

JavaScript
9
star
22

plot-cheatsheets

An interactive reference + PDF for learning Observable Plot
7
star
23

documentation

7
star
24

observable-jupyter

This repository has been archived. Please see the fork maintained by Thomas Ballinger.
Jupyter Notebook
4
star
25

odsc-visualization

Code for talk at ODSC East 2024
JavaScript
3
star
26

.github

Default community health files for Observable's open-source projects
2
star
27

codemirror-testing

A repo to test out CodeMirror outside of our infrastructure
TypeScript
1
star