# parser **Repository Path**: mirrors_mourner/parser ## Basic Information - **Project Name**: parser - **Description**: The Observable parser. - **Primary Language**: Unknown - **License**: ISC - **Default Branch**: master - **Homepage**: None - **GVP Project**: No ## Statistics - **Stars**: 0 - **Forks**: 0 - **Created**: 2020-09-25 - **Last Updated**: 2026-03-01 ## Categories & Tags **Categories**: Uncategorized **Tags**: None ## README # @observablehq/parser [![CircleCI](https://circleci.com/gh/observablehq/parser.svg?style=svg&circle-token=c7004fecc8765b1b34f0be42ced4772038eb3910)](https://circleci.com/gh/observablehq/parser) To parse a cell: ```js 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](#cell_body) is a type of expression): ```js 1 + 2 ``` ```json { "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](#cell_body) is a BlockStatement): ```js { return 1 + 2; } ``` ```json { "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](#cell_body) is null): ```js ``` ```json { "type": "Cell", "id": null, "async": false, "generator": false, "body": null } ``` A named expression cell (where [*cell*.id](#cell_id) is an Identifier): ```js foo = 42 ``` ```json { "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](#cell_id) is an Identifier): ```js foo = { return 42; } ``` ```json { "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](#cell_async) is true): ```js 2 * await value ``` ```json { "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](#cell_generator) is true): ```js yield* [1, 2, 3] ``` ```json { "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](#cell_id) is a [ViewExpression](#viewexpression)): ```js viewof x = DOM.range() ``` ```json { "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](#cell_body) contains a [ViewExpression](#viewexpression)): ```js viewof x.tagName ``` ```json { "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](#cell_body) is an [ImportDeclaration](#importdeclaration)): ```js import {foo} from "module" ``` ```json { "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](#specifier_view) is true): ```js import {viewof foo} from "module" ``` ```json { "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](#declaration_injections) is present): ```js import {chart} with {sales as data} from "@mbostock/d3-bar-chart" ``` ```json { "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]) [<>](https://github.com/observablehq/parser/blob/master/src/parse.js "Source") Returns a [cell](#cell). # parseModule(input[, options]) [<>](https://github.com/observablehq/parser/blob/master/src/parse.js "Source") Returns a [program](#program). ### 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. ### Program # program.cells An array of [cells](#cell).