Skip to content

Commit

Permalink
fixes #16. README/CONTRIBUTION updated
Browse files Browse the repository at this point in the history
  • Loading branch information
EmranMR committed Jul 10, 2023
1 parent ff63c11 commit 8c81456
Show file tree
Hide file tree
Showing 15 changed files with 63,417 additions and 69,322 deletions.
89 changes: 84 additions & 5 deletions CONTRIBUTION.md
Original file line number Diff line number Diff line change
@@ -1,17 +1,96 @@
# HELLO! 👋

Welcome to the contribution guide, and I hope you enjoyed the grammar.
Here you will find out how the grammar is organised and how you can contribute, so that it adheres to the grammar styles.
Here you will find out how the grammar is organised and how you can contribute, so that it adheres to the grammar styles.

### Prerequisite:
- You need to know how to use the [tree-sitter cli](https://tree-sitter.github.io/tree-sitter/creating-parsers#tool-overview) for generating and testing
- Make sure you are familiar with this chapter from [tree-sitter](https://tree-sitter.github.io/tree-sitter/creating-parsers#writing-the-grammar) especially the functions.
- in depth knowledge is not necessary unless you are contributing to the core.

### General Overview:
The grammar is pretty over engineered, i.e there are lots of aliases and hidden rules. However I personally believe it is easy to read and follow. This was intentional so that it is future proof, extensible and maintainable. Thanks to this, there is a 98% chance that the future new directive rules can be added with **no more than 6 lines of code** for future directives! I will explain that below 😊
The grammar is pretty abstracted, i.e there are lots of aliases and hidden rules. However I personally believe it is easy to read and follow. This was intentional so that it is future proof, extensible and maintainable. Thanks to this, there is a 98% chance that the future new directive rules can be added with **no more than 6 lines of code**!

Everything is organised in the order they appear in `_definition`, and then subcategorised based on their similarities. such as being either `nested` or `inline`. The actual building blocks are all defined at the bottom of the document below the `directive body`. The `rules` are then made like a lego using the building blocks. As a result any changes below that line will likely be a breaking change so hopefully do not need to touch those definitions.
### How to set up
1. Clone this repo
2. Install the dependancies
4. To check if your set up is working just run `npm run test`.
> Make sure you have set up your `tree-sitter`'s `parser-directories` path correctly in your config file see [path](https://tree-sitter.github.io/tree-sitter/syntax-highlighting#paths)
### How to add new directives
TBA
### Overview
Go ahead open up the `grammar.js` in the root directory.

Everything is organised in the order they appear in the document inside`_definition`. The `rules` are then made up like lego using the "building block" rules written at the bottom of the `grammar.js`. As a result any changes below the "warning comment" will likely to cause breakage, so make sure you run the test every time you amend anything. However it is very unlikely you would need to touch anything below that line, unless you are writing a very **complicated** rule.
### $._definition:
This is basically what the parser uses as a starting point to read the `blade` document. The following explains the grouping/name convention:
#### 1. $.keyword:
These are the stand-alone directives that can appear anywhere in the document, with ***NO*** *parameters* for example:
- `@csrf`
#### 2. $.php_statement
These are the directives or rules that need their content parsed as `php`
- `{{}}`
- `{!! !!}`
- ...
#### 3. $.attribute
Blade attributes, such as:
- `@class()`
- `@style()`
- ...
#### 4. $._inline_directive
These are the directives that ***take on*** parameters.
- `@yield()`
- `@extends()`
- ...
> Names starting with `_` are hiddent when parsing. see [tree-sitter](https://tree-sitter.github.io/tree-sitter/creating-parsers#writing-the-grammar)
#### 5. $._nested_directives
Directive that have *start* and *end* directive, with a *body*
- `@if() @endif`
- `@error @enderror`
- ...
#### 6. $.loop_operator
Very unlikely you would need to touch this, but these are loop operators that can appear in any subtree.
- `@break`
- `@continue`
- ...

#### 7. $.text
This is another rule which is very unlikely you would need to ever touch. This will capture anything that is not blade, and used for `injection` purposes.

### Adding New Directives:
First thing to do is to find out what category it falls into; so look into the `_definition`, pick rule group and dig in to get an idea.

As an example look below on how the `@if` directive is defined:
```mermaid
graph TD;
A($._definition)-->B($._nested_directive)-->C($.conditional)-->D[/Directives\];
D---> E($._if);
D--> G(...);
E --> H($.directive_start) & I($._if_statement_body) & J($.directive_end)
```

### Test it:
Whenever you define a new rule, you need to test it in two ways:
1. Write an example extract in the `example-file.blade.php`
- Then parse it in your terminal, and check the output
```bash
npm run parse
```
2. Once happy with your result, write the appropiate `test` files inside the appropiate group (or make one) in the `corpus/`

To finish off and ensure your rule is not breaking any other rules, just do the followig:
```
npm run test
```
If all green you are good to go 👍
### Pull requests:
Once you have:
1. added your rule
2. generated the parser
3. wrote the test
4. and your `npm run test` output was all green
you are ready to do a pull request for a review
> Ensure you include eveyrthing in the `src/*` as well
109 changes: 51 additions & 58 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,72 +1,63 @@
# Tree-Sitter-Blade
# Tree-Sitter-Blade 🌳
#### ⚠️ Please keep an eye on the *release-notes* until v1.0.0 is out.⚠️

## Introduction (feel free to skip)

This project aims to write the tree-sitter grammar for Laravel Blade
since there is none available at the moment. It is currently in beta,
until I get some feedback from the community, so far It has passed my
own stress tests. The grammar is up to date as of **_Laravel 10.x_**
- There might be minor breaking changes, once the [split-parser](https://github.com/EmranMR/tree-sitter-blade/issues/5) is released and tested.
- This could possibly be due to change of **rule names**, which might in return affect your `injection.scm` or `highlights.scm`

I am using **_Nova_** editor by **Panic** 🤘 and also working on an
all in one
[Laravel extension for Nova](https://github.com/EmranMR/Laravel-Nova-Extension)
in parallel hence the need for the tree-sitter-blade grammar. That
project is not yet public due to Nova's php injection shortcomings. I
will post updates as soon as the problem is fixed by Panic.
> The grammar is up to date as of **_Laravel 10.x_**
## Introduction (feel free to skip)

However I decided to release this project in advance considering that
a lot of amazing new editors are now tree-sitter based, and there is a
[demand for the blade support](https://github.com/laravel/framework/discussions/45286)
This project aims to write the tree-sitter grammar for [Laravel Blade](https://laravel.com/docs/10.x/blade#main-content). It is currently in beta,
until I get some feedback from the community. So far It has passed my own stress tests.

As a result this should be universally suitable for all editors
including **NeoVim**, and hopefully in the future **Zed** (RIP _Atom_
🪦).
This is very useful for editors and services that are based on tree-sitter. Such as, but not limited to:
- ***Neovim***
- ***zed***
- ***Nova*** by panic
- ***Github***

I would be more than happy to collaborate with people experienced with
any of those editors. Please raise an
[issue](https://github.com/EmranMR/tree-sitter-blade/issues) with
detailed examples of what you are trying to achieve.

If you found this project helpful, I would really appreciate if you
can [sponsor](https://github.com/sponsors/EmranMR) me so that I could
keep maintaining and improving the grammar to include the entire
Laravel ecosystem inlcluding Livewire, Inertia and so forth.
Furthermore keeping the project up to date with future releases of
Laravel.
## Sponsorship ❤️
If you found this project helpful, I would really appreciate if you can [sponsor](https://github.com/sponsors/EmranMR) me so that I could keep maintaining and improving the grammar to include the entire **Laravel Ecosystem** inlcluding **Livewire**, **AlpineJS**, **Inertia** and so forth. Furthermore keeping the project up to date with **future releases of Laravel**.

## How to inject languages:

When you parse your code there are three main important injection
points. There is an example in the `queries/injection.scm`. For ease
of use I have narrowed everything down to the following rules/queries:

#### 1. (html)

- You need to inject html in the `(html)` nodes
#### 1. (php)
- This will inject `html/php` into your document
- You need to inject `php` in the `(php)` nodes
- make sure it is `(#set! injection.combined)`

#### 2. (php)

```
((php) @injection.content
(#set! injection.combined)
(#set! injection.language php))
```

#### 2. (php_only) 🚧
> This will be availble once the [split parser](https://github.com/tree-sitter/tree-sitter-php/pull/180) is merged into `tre-sitter-php`.The name might also change.
- You inject php into `(php)` nodes. This is for all the php
directives including `{{ x }}`, `{!! x !!}} ` and so forth
- Optional: `(#set! injection.combined)` but considering laravel
will render the different `php` points like havin multiple
`<?php code ?>` The codes should have the same scope. In Nova you
also get extra autocompletion which are built-in.

### 3. (parameter)

#### 3. (parameter) 🚧
> This will be availble once the [split parser](https://github.com/tree-sitter/tree-sitter-php/pull/180) is merged into `tre-sitter-php`.The name might also change.
- optional: It will add a nice syntax highlighting for your parameters
- This is also a php injection point. I initially had this aliased
as `(php)` however decided to keep it separate.
as `(php-only)` however decided to keep it separate.
- This is for all the inline directives such as `@extends(x)`,
`@yield(x)` and so forth
- you inject `php` in `(parameter)` to get a nice syntax
highlighting
- Do _NOT_ add `(#set! injection.combined)`
- Because they are _parameter_. this is just for syntax highlighting
and getting nice `php` autocompletion if needed.
- Do ***NOT*** add `(#set! injection.combined)`
- Because they are _parameter_.
- This is just for syntax highlighting and getting nice `php` IDE autocompletion if needed.

### 4. (javascript)
#### 4. (javascript)

- TBA
- I would really appreciate if anyone experienced with **_inertia_**
Expand Down Expand Up @@ -112,33 +103,35 @@ The grammar is written in a way so that you can easily add folding
functionality. All you have to do is to mark the regions between
`(directive_start)` and `(directive_end)`

I am not sure what sort of capture groups other editors use for
folding, so please do let me know and I will add the `folds.scm` in
the `queries/`

I will however put an example once I write one for Nova.
You will need to first find out what capture groups your editor uses. I will add an example in `folds.scm` for your information once I write one for Nova.

## Quick Note about `queries/` folder

I would like some input from **_NeoVim_** users on how they deal with
queries and `queries/` folder. If the editor uses the queries stored
in the `queries/` from this repo, more than happy to accept any pull
requests with regards to that. At the moment all the `.scm` files in
that folder are just stubs. 🔴
This is for `tree-sitter cli`. Your editor or service might use different ***capture group*** name or ***predicates***.

Consequently you will need to find out in their documentation how you could approach queries or where they are stored and used by your editor. For example ***Nova*** does not use anything in this folder and uses it's own `Queries` folder instead.

At the moment consider all the `.scm` files in that folder as stubs based on the upcoming Nova extension I am developing. 🔴

## Issues
If something does not look right please raise an
[issue](https://github.com/EmranMR/tree-sitter-blade/issues) with
detailed examples of what you are trying to achieve.

- code excerpts or screenshots would be appreciated

If you need help with anything else, feel free to use the [discussion tab](https://github.com/EmranMR/tree-sitter-blade/discussions)

## Contribution

See the [contribution](/CONTRIBUTION.md) guidelines for more details,
as well as in depth info about the `grammar` itself. Please note, if
you are contributing to the `grammar.js` file, I would start accepting
the pull requests once, I have finished writing the tests
`test/corpus`
as well as in depth info about the `grammar` itself.

## Todos

- [x] Write the grammar
- [x] Write the tests
- [ ] Support Livewire 🪼
- [ ] Write the tests
- [ ] support AlpineJS
- [ ] support for Javascript injection points (examples needed from
the users please raise an
Expand Down
28 changes: 14 additions & 14 deletions corpus/attributes.txt
Original file line number Diff line number Diff line change
Expand Up @@ -7,11 +7,11 @@
---

(blade
(html)
(php)
(attribute
(directive)
(parameter))
(html))
(php))

==================
@style
Expand All @@ -22,11 +22,11 @@
---

(blade
(html)
(php)
(attribute
(directive)
(parameter))
(html))
(php))

==================
@checked
Expand All @@ -37,11 +37,11 @@
---

(blade
(html)
(php)
(attribute
(directive)
(parameter))
(html))
(php))

==================
@selected
Expand All @@ -52,11 +52,11 @@
---

(blade
(html)
(php)
(attribute
(directive)
(parameter))
(html))
(php))

==================
@disabled
Expand All @@ -67,11 +67,11 @@
---

(blade
(html)
(php)
(attribute
(directive)
(parameter))
(html))
(php))

==================
@readonly
Expand All @@ -82,11 +82,11 @@
---

(blade
(html)
(php)
(attribute
(directive)
(parameter))
(html))
(php))

==================
@required
Expand All @@ -97,8 +97,8 @@
---

(blade
(html)
(php)
(attribute
(directive)
(parameter))
(html))
(php))
Loading

0 comments on commit 8c81456

Please sign in to comment.