Ecosyste.ms: Awesome

An open API service indexing awesome lists of open source software.

Awesome Lists | Featured Topics | Projects

https://github.com/rayliwell/tree-sitter-rstml

Rust + html grammar for the tree-sitter parser library.
https://github.com/rayliwell/tree-sitter-rstml

html leptos parser rust tree-sitter

Last synced: about 16 hours ago
JSON representation

Rust + html grammar for the tree-sitter parser library.

Awesome Lists containing this project

README

        

# tree-sitter-rstml

[![GitHub License](https://img.shields.io/github/license/rayliwell/tree-sitter-rstml?color=purple)](https://github.com/rayliwell/tree-sitter-rstml/blob/main/LICENSE)
[![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/)
[![GitHub Tag](https://img.shields.io/github/v/tag/rayliwell/tree-sitter-rstml?label=version)](https://github.com/rayliwell/tree-sitter-rstml/tags)
[![NPM Version](https://img.shields.io/npm/v/tree-sitter-rstml?style=flat&logo=npm&color=blue)](https://www.npmjs.com/package/tree-sitter-rstml)
[![Crates.io Version](https://img.shields.io/crates/v/tree-sitter-rstml?logo=rust&color=blue)](https://crates.io/crates/tree-sitter-rstml)
[![docs.rs](https://img.shields.io/docsrs/tree-sitter-rust)](https://docs.rs/tree-sitter-rstml/latest/tree_sitter_rstml/)

Rust + html grammar for the [tree-sitter](https://github.com/tree-sitter/tree-sitter) parser library.

Rust 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.

## Usage

Since rstml isn't a supposed to be a standalone language, there are two grammars defined for convenience:



rstml
rust_with_rstml


Language
This grammar only parses the rstml template without requiring it to be wrapped in a view! macro invocation.
This grammar parses an entire rust source file as normal but will parse any view! macro invocations as a rstml template.


Intended use
This is intended to be injected into the tree-sitter-rust grammar. This approach provides the most flexibility by allowing the user to configure what should be interpreted as an rstml macro.
In cases where tree-sitter injection is unsupported, this grammar is the best option. The macro invocation behaviour cannot be configured by the user.


Example valid code


<div>Hello, world</div>




view! {
<div>Hello, world</div>
}




Parser location
rstml/src
rust_with_rstml/src


Rust binding usage

Show code

let code = "<div>Hello, world</div>";
let mut parser = tree_sitter::Parser::new();
parser.set_language(tree_sitter_rstml::language_rstml()).expect("Error loading rstml grammar");
let tree = parser.parse(code, None).unwrap();



Show code


let code = r#"
view! {
<div>hello, world</div>
}
"#;
let mut parser = tree_sitter::Parser::new();
parser.set_language(tree_sitter_rstml::language_rust_with_rstml()).expect("Error loading rust_with_rstml grammar");
let tree = parser.parse(code, None).unwrap();




JavaScript binding usage

Show code


const Parser = require('tree-sitter')
const code = '<div>Hello, world</div>'
const parser = new Parser()
parser.setLanguage(require('tree-sitter-rstml').rstml)
const tree = parser.parse(code)



Show code


const Parser = require('tree-sitter')
const code = `
view! {
<div>Hello, world</div>
}
`
const parser = new Parser()
parser.setLanguage(require('tree-sitter-rstml').rust_with_rstml)
const tree = parser.parse(code)


## Editor support

### Neovim

Neovim's [tree-sitter integration](https://neovim.io/doc/user/treesitter.html) supports syntax highlighting, indentation, and code folding.

| Without `rstml` highlighting | With `rstml` highlighting |
|---------------------------------------------------|-------------------------------------------------|
| ![before](/assets/neovim_before_highlighting.png) | ![after](/assets/neovim_after_highlighting.png) |

To use the Neovim support with [nvim-treesitter](https://github.com/nvim-treesitter/nvim-treesitter), you should:

- Ensure `"nvim-treesitter/nvim-treesitter"` is installed and configured correctly.
- Install the `"rayliwell/tree-sitter-rstml"` plugin in your preferred package manager.
- Ensure `require("tree-sitter-rstml").setup()` is ran after every time `nvim-treesitter` is loaded.

Here's an example config using [lazy.nvim](https://github.com/folke/lazy.nvim):

```lua
require("lazy").setup({
{
"nvim-treesitter/nvim-treesitter",
build = ":TSUpdate",
config = function ()
local configs = require("nvim-treesitter.configs")

configs.setup({
ensure_installed = { "c", "lua", "vim", "vimdoc", "query", "rust" },
sync_install = false,
highlight = { enable = true },
indent = { enable = true },
})
end
},
{
"rayliwell/tree-sitter-rstml",
dependencies = { "nvim-treesitter" },
build = ":TSUpdate",
config = function ()
require("tree-sitter-rstml").setup()
end
},
-- Automatic tag closing and renaming (optional but highly recommended)
{
"windwp/nvim-ts-autotag",
config = function()
require("nvim-ts-autotag").setup()
end,
},
})
```

> [!NOTE]
> 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.

### NixVim (Advanced)

To use the [NixVim](https://github.com/nix-community/nixvim) integration with flakes, you should:

- Add `github:rayliwell/tree-sitter-rstml` as a flake input.
- Import `inputs.tree-sitter-rstml.nixvimModule` inside of your NixVim configuration.

For example:
```nix
{
description = "NixVim configuration with tree-sitter-rstml.";

inputs = {
nixpkgs.url = "github:NixOS/nixpkgs/nixpkgs-unstable";
nixvim.url = "github:nix-community/nixvim";
tree-sitter-rstml.url = "github:rayliwell/tree-sitter-rstml/flake";
};

outputs =
{
system,
nixpkgs,
nixvim,
tree-sitter-rstml,
...
}:
let
forAllSystems =
function:
nixpkgs.lib.genAttrs [
"aarch64-darwin"
"aarch64-linux"
"x86_64-darwin"
"x86_64-linux"
] (system: function nixpkgs.legacyPackages.${system});
in
{
packages = forAllSystems (pkgs: {
default = nixvim.legacyPackages.${system}.makeNixvimWithModule {
inherit pkgs;
module = {
imports = [ tree-sitter-rstml.nixvimModule ];
};
};
});
};
}
```

### Emacs

Emacs' (29.1+) [tree-sitter integration](https://www.masteringemacs.org/article/how-to-get-started-tree-sitter) supports syntax highlighting and indentation.

| **Before (`rust-ts-mode`)** | **After (`rstml-ts-mode`)** |
|--------------------------------------------------|------------------------------------------------|
| ![before](/assets/emacs_before_highlighting.png) | ![after](/assets/emacs_after_highlighting.png) |

Emacs support is provided by the `rstml-ts-mode` package.

**You can read more on the project's [GitHub](https://github.com/rayliwell/rstml-ts-mode).**

## Acknowledgements

This 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.

Additionally, 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).

## License

Licensed under the [MIT License](https://mit-license.org/).

Copyright © 2024 Ryan Halliwell