{"id":15144301,"url":"https://github.com/rayliwell/tree-sitter-rstml","last_synced_at":"2025-10-11T22:30:46.435Z","repository":{"id":228793289,"uuid":"763786936","full_name":"rayliwell/tree-sitter-rstml","owner":"rayliwell","description":"Rust + html grammar for the tree-sitter parser library.","archived":false,"fork":false,"pushed_at":"2025-06-25T09:16:18.000Z","size":17182,"stargazers_count":68,"open_issues_count":9,"forks_count":4,"subscribers_count":3,"default_branch":"main","last_synced_at":"2025-09-28T05:25:47.455Z","etag":null,"topics":["emacs","html","leptos","neovim","neovim-plugin","nix","nix-flake","parser","rust","tree-sitter"],"latest_commit_sha":null,"homepage":"https://github.com/rayliwell/tree-sitter-rstml","language":"C","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/rayliwell.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,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null}},"created_at":"2024-02-26T23:13:31.000Z","updated_at":"2025-08-29T08:08:11.000Z","dependencies_parsed_at":"2024-11-13T12:35:30.708Z","dependency_job_id":"6f7d6fb8-c567-41d9-8628-bb8a5852e6da","html_url":"https://github.com/rayliwell/tree-sitter-rstml","commit_stats":{"total_commits":82,"total_committers":2,"mean_commits":41.0,"dds":"0.024390243902439046","last_synced_commit":"c0a807f052c80575e2b5e2c0e01a5c65baaaa08c"},"previous_names":["rayliwell/tree-sitter-rstml"],"tags_count":8,"template":false,"template_full_name":null,"purl":"pkg:github/rayliwell/tree-sitter-rstml","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/rayliwell%2Ftree-sitter-rstml","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/rayliwell%2Ftree-sitter-rstml/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/rayliwell%2Ftree-sitter-rstml/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/rayliwell%2Ftree-sitter-rstml/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/rayliwell","download_url":"https://codeload.github.com/rayliwell/tree-sitter-rstml/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/rayliwell%2Ftree-sitter-rstml/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":279009071,"owners_count":26084549,"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","status":"online","status_checked_at":"2025-10-11T02:00:06.511Z","response_time":55,"last_error":null,"robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":true,"can_crawl_api":true,"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":["emacs","html","leptos","neovim","neovim-plugin","nix","nix-flake","parser","rust","tree-sitter"],"created_at":"2024-09-26T10:40:22.275Z","updated_at":"2025-10-11T22:30:46.429Z","avatar_url":"https://github.com/rayliwell.png","language":"C","funding_links":[],"categories":[],"sub_categories":[],"readme":"# tree-sitter-rstml\n\n[![GitHub License](https://img.shields.io/github/license/rayliwell/tree-sitter-rstml?color=purple)](https://github.com/rayliwell/tree-sitter-rstml/blob/main/LICENSE)\n[![GitHub last commit (branch)](https://img.shields.io/github/last-commit/rayliwell/tree-sitter-rstml/main)](https://github.com/rayliwell/tree-sitter-rstml/commits/main/)\n[![GitHub Tag](https://img.shields.io/github/v/tag/rayliwell/tree-sitter-rstml?label=version)](https://github.com/rayliwell/tree-sitter-rstml/tags)\n[![NPM Version](https://img.shields.io/npm/v/tree-sitter-rstml?style=flat\u0026logo=npm\u0026color=blue)](https://www.npmjs.com/package/tree-sitter-rstml)\n[![Crates.io Version](https://img.shields.io/crates/v/tree-sitter-rstml?logo=rust\u0026color=blue)](https://crates.io/crates/tree-sitter-rstml)\n[![docs.rs](https://img.shields.io/docsrs/tree-sitter-rust)](https://docs.rs/tree-sitter-rstml/latest/tree_sitter_rstml/)\n\nRust + html grammar for the [tree-sitter](https://github.com/tree-sitter/tree-sitter) parser library.\n\nRust web frameworks, like [Leptos](https://github.com/leptos-rs/leptos), rely on JSX-style templates embedded inside Rust code using the [rstml](https://github.com/rs-tml/rstml) library. This project enables the parsing of those templates for various purposes, such as syntax highlighting in text editors.\n\n## Usage\n\nSince rstml isn't a supposed to be a standalone language, there are two grammars defined for convenience:\n\n\u003ctable\u003e\n    \u003ctr\u003e\n       \u003cth\u003e\u003c/th\u003e\n       \u003cth\u003e\u003ccode\u003erstml\u003c/code\u003e\u003c/th\u003e\n       \u003cth\u003e\u003ccode\u003erust_with_rstml\u003c/code\u003e\u003c/th\u003e\n    \u003c/tr\u003e\n    \u003ctr\u003e\n        \u003ctd\u003eLanguage\u003c/td\u003e\n        \u003ctd\u003eThis grammar only parses the rstml template without requiring it to be wrapped in a \u003ccode\u003eview!\u003c/code\u003e macro invocation.\u003c/td\u003e\n        \u003ctd\u003eThis grammar parses an entire rust source file as normal but will parse any \u003ccode\u003eview!\u003c/code\u003e macro invocations as a rstml template.\u003c/td\u003e\n    \u003c/tr\u003e\n    \u003ctr\u003e\n        \u003ctd\u003eIntended use\u003c/td\u003e\n        \u003ctd\u003eThis is intended to be \u003ca href=\"https://tree-sitter.github.io/tree-sitter/syntax-highlighting#language-injection\"\u003einjected\u003c/a\u003e into the \u003ca href=\"https://github.com/tree-sitter/tree-sitter-rust\"\u003etree-sitter-rust\u003c/a\u003e grammar. This approach provides the most flexibility by allowing the user to configure what should be interpreted as an rstml macro.\u003c/td\u003e\n        \u003ctd\u003eIn cases where tree-sitter injection is unsupported, this grammar is the best option. The macro invocation behaviour cannot be configured by the user.\u003c/td\u003e\n    \u003c/tr\u003e\n    \u003ctr\u003e\n        \u003ctd\u003eExample valid code\u003c/td\u003e\n        \u003ctd\u003e\n            \u003cpre lang=\"html\"\u003e\n\u0026lt;div\u0026gt;Hello, world\u0026lt;/div\u0026gt;\u003c/pre\u003e\n        \u003c/td\u003e\n        \u003ctd\u003e\n            \u003cpre lang=\"rust\"\u003e\nview! {\n    \u0026lt;div\u0026gt;Hello, world\u0026lt;/div\u0026gt;\n}\u003c/pre\u003e\n        \u003c/td\u003e\n    \u003c/tr\u003e\n    \u003ctr\u003e\n        \u003ctd\u003eParser location\u003c/td\u003e\n        \u003ctd\u003e\u003ccode\u003erstml/src\u003c/code\u003e\u003c/td\u003e\n        \u003ctd\u003e\u003ccode\u003erust_with_rstml/src\u003c/code\u003e\u003c/td\u003e\n    \u003c/tr\u003e\n    \u003ctr\u003e\n        \u003ctd\u003eRust binding usage\u003c/td\u003e\n        \u003ctd\u003e\n\u003cdetails\u003e\u003csummary\u003eShow code\u003c/summary\u003e\n\u003cpre lang=\"rust\"\u003e\nlet code = \u0026quot;\u0026lt;div\u0026gt;Hello, world\u0026lt;/div\u0026gt;\u0026quot;;\nlet mut parser = tree_sitter::Parser::new();\nparser.set_language(tree_sitter_rstml::language_rstml()).expect(\u0026quot;Error loading rstml grammar\u0026quot;);\nlet tree = parser.parse(code, None).unwrap();\n\u003c/pre\u003e\n\u003c/details\u003e\n        \u003c/td\u003e\n        \u003ctd\u003e\n\u003cdetails\u003e\u003csummary\u003eShow code\u003c/summary\u003e\n\u003cpre lang=\"rust\"\u003e\nlet code = r#\u0026quot;\n    view! {\n        \u0026lt;div\u0026gt;hello, world\u0026lt;/div\u0026gt;\n    }\n\u0026quot;#;\nlet mut parser = tree_sitter::Parser::new();\nparser.set_language(tree_sitter_rstml::language_rust_with_rstml()).expect(\u0026quot;Error loading rust_with_rstml grammar\u0026quot;);\nlet tree = parser.parse(code, None).unwrap();\n\u003c/pre\u003e\n\u003c/details\u003e\n       \u003c/td\u003e\n    \u003c/tr\u003e\n    \u003ctr\u003e\n        \u003ctd\u003eJavaScript binding usage\u003c/td\u003e\n        \u003ctd\u003e\n\u003cdetails\u003e\u003csummary\u003eShow code\u003c/summary\u003e\n\u003cpre lang=\"js\"\u003e\nconst Parser = require('tree-sitter')\nconst code = '\u0026lt;div\u0026gt;Hello, world\u0026lt;/div\u0026gt;'\nconst parser = new Parser()\nparser.setLanguage(require('tree-sitter-rstml').rstml)\nconst tree = parser.parse(code)\n\u003c/pre\u003e\n\u003c/details\u003e\n        \u003c/td\u003e\n        \u003ctd\u003e\n\u003cdetails\u003e\u003csummary\u003eShow code\u003c/summary\u003e\n\u003cpre lang=\"js\"\u003e\nconst Parser = require('tree-sitter')\nconst code = `\n    view! {\n        \u0026lt;div\u0026gt;Hello, world\u0026lt;/div\u0026gt;\n    }\n`\nconst parser = new Parser()\nparser.setLanguage(require('tree-sitter-rstml').rust_with_rstml)\nconst tree = parser.parse(code)\n\u003c/pre\u003e\n\u003c/details\u003e\n       \u003c/td\u003e\n    \u003c/tr\u003e\n\u003c/table\u003e\n\n## Editor support\n\n### Neovim\n\nNeovim's [tree-sitter integration](https://neovim.io/doc/user/treesitter.html) supports syntax highlighting, indentation, and code folding.\n\n| Without `rstml` highlighting                      | With `rstml` highlighting                       |\n|---------------------------------------------------|-------------------------------------------------|\n| ![before](/assets/neovim_before_highlighting.png) | ![after](/assets/neovim_after_highlighting.png) |\n\nTo use the Neovim support with [nvim-treesitter](https://github.com/nvim-treesitter/nvim-treesitter), you should:\n\n- Ensure `\"nvim-treesitter/nvim-treesitter\"` is installed and configured correctly.\n- Install the `\"rayliwell/tree-sitter-rstml\"` plugin in your preferred package manager.\n- Ensure `require(\"tree-sitter-rstml\").setup()` is ran after every time `nvim-treesitter` is loaded.\n\n\n\u003e [!NOTE]\n\u003e You may have to call `:TSInstall rust_with_rstml` the first time you open a Rust buffer for syntax highlighting to work correctly.\n\nHere's an example config using [lazy.nvim](https://github.com/folke/lazy.nvim):\n\n```lua\nrequire(\"lazy\").setup({\n    {\n        \"nvim-treesitter/nvim-treesitter\",\n        build = \":TSUpdate\",\n        config = function ()\n            local configs = require(\"nvim-treesitter.configs\")\n\n            configs.setup({\n                ensure_installed = { \"c\", \"lua\", \"vim\", \"vimdoc\", \"query\", \"rust\" },\n                sync_install = false,\n                highlight = { enable = true },\n                indent = { enable = true },\n            })\n        end\n    },\n    {\n        \"rayliwell/tree-sitter-rstml\",\n        dependencies = { \"nvim-treesitter\" },\n        build = \":TSUpdate\",\n        config = function ()\n            require(\"tree-sitter-rstml\").setup()\n        end\n    },\n    -- Automatic tag closing and renaming (optional but highly recommended)\n    {\n        \"windwp/nvim-ts-autotag\",\n        config = function()\n            require(\"nvim-ts-autotag\").setup()\n        end,\n    },\n})\n```\n\n\u003e [!NOTE]\n\u003e Neovim support is intended to work on the latest Neovim release and version of `nvim-treesitter`.  If you are using a Neovim distribution, like LunarVim, support is not guarenteed.\n\n### NixVim (Advanced)\n\nTo use the [NixVim](https://github.com/nix-community/nixvim) integration with flakes, you should:\n\n- Add `github:rayliwell/tree-sitter-rstml` as a flake input.\n- Import `inputs.tree-sitter-rstml.nixvimModule` inside of your NixVim configuration.\n\nFor example:\n```nix\n{\n  description = \"NixVim configuration with tree-sitter-rstml.\";\n\n  inputs = {\n    nixpkgs.url = \"github:NixOS/nixpkgs/nixpkgs-unstable\";\n    nixvim.url = \"github:nix-community/nixvim\";\n    tree-sitter-rstml.url = \"github:rayliwell/tree-sitter-rstml/flake\";\n  };\n\n  outputs =\n    {\n      system,\n      nixpkgs,\n      nixvim,\n      tree-sitter-rstml,\n      ...\n    }:\n    let\n      forAllSystems =\n        function:\n        nixpkgs.lib.genAttrs [\n          \"aarch64-darwin\"\n          \"aarch64-linux\"\n          \"x86_64-darwin\"\n          \"x86_64-linux\"\n        ] (system: function nixpkgs.legacyPackages.${system});\n    in\n    {\n      packages = forAllSystems (pkgs: {\n        default = nixvim.legacyPackages.${system}.makeNixvimWithModule {\n          inherit pkgs;\n          module = {\n            imports = [ tree-sitter-rstml.nixvimModule ];\n          };\n        };\n      });\n    };\n}\n```\n\n### Emacs\n\nEmacs' (29.1+) [tree-sitter integration](https://www.masteringemacs.org/article/how-to-get-started-tree-sitter) supports syntax highlighting and indentation.\n\n| **Before (`rust-ts-mode`)**                      | **After (`rstml-ts-mode`)**                    |\n|--------------------------------------------------|------------------------------------------------|\n| ![before](/assets/emacs_before_highlighting.png) | ![after](/assets/emacs_after_highlighting.png) |\n\nEmacs support is provided by the `rstml-ts-mode` package.\n\n**You can read more on the project's [GitHub](https://github.com/rayliwell/rstml-ts-mode).**\n\n## Acknowledgements\n\nThis project extends and heavily relies upon the [tree-sitter-rust](https://github.com/tree-sitter/tree-sitter-rust) grammar. It would not be possible without its [contributors](https://github.com/tree-sitter/tree-sitter-rust/graphs/contributors), as well as those who have [contributed](https://github.com/tree-sitter/tree-sitter/graphs/contributors) to the wider tree-sitter ecosystem.\n\nAdditionally, this project is based on the work of the [rstml](https://github.com/rs-tml/rstml) library. Originating as a fork of [syn-rsx](https://github.com/stoically/syn-rsx), whose creator, unfortunately, has [passed away](https://github.com/stoically/temporary-containers/issues/618).\n\n## License\n\nLicensed under the [MIT License](https://mit-license.org/).\n\nCopyright © 2024 Ryan Halliwell\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Frayliwell%2Ftree-sitter-rstml","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Frayliwell%2Ftree-sitter-rstml","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Frayliwell%2Ftree-sitter-rstml/lists"}