{"id":13339460,"url":"https://github.com/s0/tree-sitter-hast","last_synced_at":"2025-04-22T14:24:52.205Z","repository":{"id":48004981,"uuid":"192031490","full_name":"s0/tree-sitter-hast","owner":"s0","description":"NPM package to convert tree-sitter parsed syntax trees to syntax-highlighted hast","archived":false,"fork":false,"pushed_at":"2022-12-03T13:48:30.000Z","size":698,"stargazers_count":12,"open_issues_count":9,"forks_count":2,"subscribers_count":1,"default_branch":"master","last_synced_at":"2025-04-20T03:04:45.013Z","etag":null,"topics":["syntax-highlighting","syntax-tree","tree-sitter","unist"],"latest_commit_sha":null,"homepage":"https://www.npmjs.com/package/tree-sitter-hast","language":"TypeScript","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/s0.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null}},"created_at":"2019-06-15T03:20:36.000Z","updated_at":"2024-01-14T14:09:25.000Z","dependencies_parsed_at":"2023-01-23T16:15:53.414Z","dependency_job_id":null,"html_url":"https://github.com/s0/tree-sitter-hast","commit_stats":null,"previous_names":["samlanning/tree-sitter-hast"],"tags_count":3,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/s0%2Ftree-sitter-hast","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/s0%2Ftree-sitter-hast/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/s0%2Ftree-sitter-hast/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/s0%2Ftree-sitter-hast/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/s0","download_url":"https://codeload.github.com/s0/tree-sitter-hast/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":250256985,"owners_count":21400628,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["syntax-highlighting","syntax-tree","tree-sitter","unist"],"created_at":"2024-07-29T19:20:03.579Z","updated_at":"2025-04-22T14:24:52.184Z","avatar_url":"https://github.com/s0.png","language":"TypeScript","funding_links":[],"categories":[],"sub_categories":[],"readme":"# tree-sitter-hast\n\n[![Build Status](https://dev.azure.com/samlanning/tree-sitter/_apis/build/status/samlanning.tree-sitter-hast?branchName=master)](https://dev.azure.com/samlanning/tree-sitter/_build/latest?definitionId=2\u0026branchName=master) [![Total alerts](https://img.shields.io/lgtm/alerts/g/samlanning/tree-sitter-hast.svg?logo=lgtm\u0026logoWidth=18)](https://lgtm.com/projects/g/samlanning/tree-sitter-hast/alerts/) [![Language grade: JavaScript](https://img.shields.io/lgtm/grade/javascript/g/samlanning/tree-sitter-hast.svg?logo=lgtm\u0026logoWidth=18)](https://lgtm.com/projects/g/samlanning/tree-sitter-hast/context:javascript) [![](https://img.shields.io/npm/v/tree-sitter-hast.svg)](https://www.npmjs.com/package/tree-sitter-hast)\n\nNPM package to convert [`tree-sitter`](https://tree-sitter.github.io/) parsed syntax trees to syntax-highlighted [`hast`](https://github.com/syntax-tree/hast) (Hypertext Abstract Syntax Trees).\n\nThe main reason for this is so that tree-sitter can be used to syntax-highlight code in [`unified`](https://unified.js.org/) projects such as [`remark`](https://github.com/remarkjs/remark) or [`rehype`](https://github.com/rehypejs/rehype). Via plugins such as [`remark-tree-sitter`](https://github.com/samlanning/remark-tree-sitter).\n\n## Installation\n\n```bash\nnpm install tree-sitter-hast\n```\n\nor\n\n```bash\nyarn add tree-sitter-hast\n```\n\n`tree-sitter-hast` is written in TypeScript and includes type definitions, so there is no need to install a separate `@types/tree-sitter-hast` package if you are using TypeScript.\n\n## Usage\n\n### Scope Mappings\n\nFor syntax highlighting,\nthis package uses the same process that Atom uses with `tree-sitter`.\nThe HTML classes that are used for syntax-highlighting do not\ncorrespond directly to nodes in the tree produced by tree-sitter,\nso scope mappings are used to specify which classes should be\napplied to which syntax nodes.\n(You can read mode in [Atom's documentation on Creating a Grammar](https://flight-manual.atom.io/hacking-atom/sections/creating-a-grammar/#syntax-highlighting)).\n\nEvery Atom package that provides language support using the new `tree-sitter` mechanism\nalso includes a scope mapping,\nand this package provides functionality to directly use these packages for highlighting.\n\nTo use an atom language package, like any package you first need to install it using `npm install` or `yarn add`.\nUnfortunately most APM packages are not made available on NPM,\nso I've started to make some of them available under the NPM organization [`@atom-languages`](https://www.npmjs.com/org/atom-languages).\n\nAfter installing a language package, you can use `loadLanguagesFromPackage` to prepare them to be used with `tree-sitter-hast`.\n\n#### Example\n\n```bash\nnpm install tree-sitter-hast @atom-languages/language-typescript\n```\n\n[`examples/example-1.js`](examples/example-1.js)\n```js\nconst treeSitterHast = require('tree-sitter-hast');\n\ntreeSitterHast\n  .loadLanguagesFromPackage('@atom-languages/language-typescript')\n  .then(languages =\u003e {\n    console.log(Array.from(languages.keys()));\n});\n```\n\n**Output:**\n```js\n[ 'flow', 'tsx', 'typescript' ]\n```\n\n### Highlighting\n\nHighlighting is made available through the following functions:\n\n* `highlightText(language, text, [options])` - highlight some plain text, using a language that's been made available by `loadLanguagesFromPackage`\n* `highlightText(parser, scopeMappings, text, [options])` - highlight some plain text, and use a `Parser` that's already been prepared\n* `highlightTree(scopeMappings, text, tree, [options])` - highlight a tree that's already been parsed by `tree-sitter`\n\n#### Example\n\nThe following 3 examples all produce the same output.\n\n```bash\nnpm install tree-sitter-hast @atom-languages/language-typescript\n```\n\n[`examples/example-2-1.js`](examples/example-2-1.js)\n```js\nconst treeSitterHast = require('tree-sitter-hast');\n\nconst text = 'let v = 3';\n\ntreeSitterHast\n  .loadLanguagesFromPackage('@atom-languages/language-typescript')\n  .then(languages =\u003e {\n    const ts = languages.get('typescript');\n    const highlighted = treeSitterHast.highlightText(ts, text);\n    console.log(JSON.stringify(highlighted, null, 2));\n});\n```\n\n[`examples/example-2-2.js`](examples/example-2-2.js)\n```js\nconst Parser = require('tree-sitter');\nconst treeSitterHast = require('tree-sitter-hast');\n\nconst text = 'let v = 3';\n\ntreeSitterHast\n  .loadLanguagesFromPackage('@atom-languages/language-typescript')\n  .then(languages =\u003e {\n    const ts = languages.get('typescript');\n    const parser = new Parser();\n    parser.setLanguage(ts.grammar);\n    const highlighted = treeSitterHast.highlightText(parser, ts.scopeMappings, text);\n    console.log(JSON.stringify(highlighted, null, 2));\n});\n```\n\n[`examples/example-2-3.js`](examples/example-2-3.js)\n```js\nconst Parser = require('tree-sitter');\nconst treeSitterHast = require('tree-sitter-hast');\n\nconst text = 'let v = 3';\n\ntreeSitterHast\n  .loadLanguagesFromPackage('@atom-languages/language-typescript')\n  .then(languages =\u003e {\n    const ts = languages.get('typescript');\n    const parser = new Parser();\n    parser.setLanguage(ts.grammar);\n    const tree = parser.parse(text);\n    const highlighted = treeSitterHast.highlightTree(ts.scopeMappings, text, tree);\n    console.log(JSON.stringify(highlighted, null, 2));\n});\n```\n\n**Output:**\n```js\n{\n  \"type\": \"element\",\n  \"tagName\": \"span\",\n  \"properties\": {\n    \"className\": [\n      \"source\",\n      \"ts\"\n    ]\n  },\n  \"children\": [\n    {\n      \"type\": \"element\",\n      \"tagName\": \"span\",\n      \"properties\": {\n        \"className\": [\n          \"storage\",\n          \"type\"\n        ]\n      },\n      \"children\": [\n        {\n          \"type\": \"text\",\n          \"value\": \"let\"\n        }\n      ]\n    },\n    {\n      \"type\": \"text\",\n      \"value\": \" v \"\n    },\n    //...\n  ]\n}\n```\n\n### Exporting HTML\n\nFrom this point, converting the HAST to an HTML can be done in a single call using `hast-util-to-html` (part of `rehype`):\n\n```bash\nnpm install hast-util-to-html tree-sitter-hast @atom-languages/language-typescript\n```\n\n[`examples/example-3.js`](examples/example-3.js)\n```js\nconst toHtml = require('hast-util-to-html');\nconst Parser = require('tree-sitter');\nconst treeSitterHast = require('tree-sitter-hast');\n\nconst text = 'let v = 3';\n\ntreeSitterHast\n  .loadLanguagesFromPackage('@atom-languages/language-typescript')\n  .then(languages =\u003e {\n    const ts = languages.get('typescript');\n    const highlighted = treeSitterHast.highlightText(ts, text);\n\n    // stringify to HTML\n    console.log(toHtml(highlighted));\n});\n```\n\n**Output:**\n```html\n\u003cspan class=\"source ts\"\u003e\u003cspan class=\"storage type\"\u003elet\u003c/span\u003e v \u003cspan class=\"keyword operator js\"\u003e=\u003c/span\u003e \u003cspan class=\"constant numeric\"\u003e3\u003c/span\u003e\u003c/span\u003e\n```\n\n### Whitelisting Classes\n\nSometimes including the full list of classes applied by the scope mappings can be too much,\nand you'd like to only include those that you have stylesheets for.\n\nTo do this, you can pass in a `classWhitelist` via the options parameters to `highlightText` or `highlightTree`.\n\n```bash\nnpm install hast-util-to-html tree-sitter-hast @atom-languages/language-typescript\n```\n\n[`examples/example-4.js`](examples/example-4.js)\n```js\nconst toHtml = require('hast-util-to-html');\nconst Parser = require('tree-sitter');\nconst treeSitterHast = require('tree-sitter-hast');\n\nconst text = 'let v = 3';\n\ntreeSitterHast\n  .loadLanguagesFromPackage('@atom-languages/language-typescript')\n  .then(languages =\u003e {\n    const ts = languages.get('typescript');\n    const highlighted = treeSitterHast.highlightText(ts, text, {classWhitelist: ['storage', 'numeric']});\n\n    // stringify to HTML\n    console.log(toHtml(highlighted));\n});\n```\n\n**Output:**\n```html\n\u003cspan\u003e\u003cspan class=\"storage\"\u003elet\u003c/span\u003e v = \u003cspan class=\"numeric\"\u003e3\u003c/span\u003e\u003c/span\u003e\n```\n\n## TODO\n\n* Move prepare-language.ts over to highlight-tree-sitter\n* Pull out HAST type definitions into own repo (DefinitelyTyped?)\n* Update highlight-tree-sitter to not produce HTML when not needed\n* Move over matches patch to highlight-tree-sitter\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fs0%2Ftree-sitter-hast","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fs0%2Ftree-sitter-hast","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fs0%2Ftree-sitter-hast/lists"}