AI prompts
base on 🌿 Powerful and seamless HTML-aware ERB parsing and tooling. <div align="center">
<img alt="Herb HTML+ERB parser" height="256px" src="https://github.com/user-attachments/assets/d0714ee1-ca33-4aa4-aaa9-d632ba79d54a">
</div>
<h2 align="center">Herb</h2>
<h4 align="center">HTML + ERB (HTML Embedded Ruby)</h4>
<div align="center">Powerful and seamless HTML-aware ERB parsing and tooling.</div>
## Contributing
This project builds the Herb program and its associated unit tests using a Makefile for automation. The Makefile provides several useful commands for compiling, running tests, and cleaning the project.
### Requirements
- [**Check**](https://libcheck.github.io/check/): For unit testing.
- [**Clang 19**](https://clang.llvm.org): The compiler used to build this project.
- [**Clang Format 19**](https://clang.llvm.org/docs/ClangFormat.html): For formatting the project.
- [**Clang Tidy 19**](https://clang.llvm.org/extra/clang-tidy/): For linting the project.
- [**Prism Ruby Parser v1.4.0**](https://github.com/ruby/prism/releases/tag/v1.4.0): We use Prism for Parsing the Ruby Source Code in the HTML+ERB files.
- [**Ruby**](https://www.ruby-lang.org/en/): We need Ruby as a dependency for `bundler`.
- [**Bundler**](https://bundler.io): We are using `bundler` to build [`prism`](https://github.com/ruby/prism) from source so we can build `herb` against it.
- [**Emscripten**](https://emscripten.org): For the WebAssembly build of `libherb` so it can be used in the browser using the [`@herb-tools/browser`](https://github.com/marcoroth/herb/blob/main/javascript/packages/browser) package.
- [**Doxygen**](https://www.doxygen.nl): For building the C-Reference documentation pages.
##### For Linux
```bash
xargs sudo apt-get install < Aptfile
```
or:
```bash
sudo apt-get install check clang-19 clang-tidy-19 clang-format-19 emscripten doxygen
```
##### For macOS (using Homebrew)
```bash
brew bundle
```
or:
```bash
brew install check llvm@19 emscripten doxygen
```
### Building
#### Clone the Repo
Clone the Git Repository:
```
git clone https://github.com/marcoroth/herb && cd herb/
```
#### Build Herb
We can now compile all source files in `src/` and generate the `herb` executable.
```bash
make all
```
> [!NOTE]
For any consecutive builds you can just run `make`/`make all`.
### Run
The `herb` executable exposes a few commands for interacting with `.html.erb` files:
```
❯ ./herb
./herb [command] [options]
Herb 🌿 Powerful and seamless HTML-aware ERB parsing and tooling.
./herb lex [file] - Lex a file
./herb lex_json [file] - Lex a file and return the result as json.
./herb parse [file] - Parse a file
./herb ruby [file] - Extract Ruby from a file
./herb html [file] - Extract HTML from a file
./herb prism [file] - Extract Ruby from a file and parse the Ruby source with Prism
```
Running the executable shows a pretty-printed output for the respective command and the time it took to execute:
```
❯ ./herb lex examples/simple_erb.html.erb
#<Herb::Token type="TOKEN_ERB_START" value="<%" range=[0, 2] start=(1:0) end=(1:2)>
#<Herb::Token type="TOKEN_ERB_CONTENT" value=" title " range=[2, 9] start=(1:2) end=(1:9)>
#<Herb::Token type="TOKEN_ERB_END" value="%>" range=[9, 11] start=(1:9) end=(1:11)>
#<Herb::Token type="TOKEN_NEWLINE" value="\n" range=[11, 12] start=(1:0) end=(2:1)>
#<Herb::Token type="TOKEN_EOF" value="" range=[12, 12] start=(2:1) end=(2:1)>
Finished lexing in:
12 µs
0.012 ms
0.000012 s
```
### Building the Ruby extension
We use `rake` and `rake-compiler` to compile the Ruby extension. Running rake will generate the needed templates, run make, build the needed artifacts, and run the Ruby tests.
```bash
rake
```
If `rake` was successful you can use `bundle console` to interact with `Herb`:
```bash
bundle console
```
```
irb(main):001> Herb.parse("<div></div>")
# => #<Herb::ParseResult:0x0000000 ... >
```
### Test
Builds the test suite from files in `test/` and creates the `run_herb_tests` executable to run the tests:
#### For the C Tests
```bash
make test && ./run_herb_tests
```
#### For the Ruby Tests
```bash
rake test
```
### Clean
Removes the `herb`, `run_herb_tests`, `prism` installation, and all `.o` files.
```bash
make clean
```
### Local Integration Testing
The `bin/integration` script allows for quick local iteration. On every run it cleans the directory, builds the source from scratch and runs all checks, including the C-Tests, Ruby Tests, Linters, and examples in succession.
```bash
bin/integration
```
The integration was successful if you see:
```
❯ bin/integration
[...]
Integration successful!
```
## License
This project is licensed under the MIT License - see the [LICENSE](LICENSE.txt) file for details.
", Assign "at most 3 tags" to the expected json: {"id":"13500","tags":[]} "only from the tags list I provide: [{"id":77,"name":"3d"},{"id":89,"name":"agent"},{"id":17,"name":"ai"},{"id":54,"name":"algorithm"},{"id":24,"name":"api"},{"id":44,"name":"authentication"},{"id":3,"name":"aws"},{"id":27,"name":"backend"},{"id":60,"name":"benchmark"},{"id":72,"name":"best-practices"},{"id":39,"name":"bitcoin"},{"id":37,"name":"blockchain"},{"id":1,"name":"blog"},{"id":45,"name":"bundler"},{"id":58,"name":"cache"},{"id":21,"name":"chat"},{"id":49,"name":"cicd"},{"id":4,"name":"cli"},{"id":64,"name":"cloud-native"},{"id":48,"name":"cms"},{"id":61,"name":"compiler"},{"id":68,"name":"containerization"},{"id":92,"name":"crm"},{"id":34,"name":"data"},{"id":47,"name":"database"},{"id":8,"name":"declarative-gui "},{"id":9,"name":"deploy-tool"},{"id":53,"name":"desktop-app"},{"id":6,"name":"dev-exp-lib"},{"id":59,"name":"dev-tool"},{"id":13,"name":"ecommerce"},{"id":26,"name":"editor"},{"id":66,"name":"emulator"},{"id":62,"name":"filesystem"},{"id":80,"name":"finance"},{"id":15,"name":"firmware"},{"id":73,"name":"for-fun"},{"id":2,"name":"framework"},{"id":11,"name":"frontend"},{"id":22,"name":"game"},{"id":81,"name":"game-engine "},{"id":23,"name":"graphql"},{"id":84,"name":"gui"},{"id":91,"name":"http"},{"id":5,"name":"http-client"},{"id":51,"name":"iac"},{"id":30,"name":"ide"},{"id":78,"name":"iot"},{"id":40,"name":"json"},{"id":83,"name":"julian"},{"id":38,"name":"k8s"},{"id":31,"name":"language"},{"id":10,"name":"learning-resource"},{"id":33,"name":"lib"},{"id":41,"name":"linter"},{"id":28,"name":"lms"},{"id":16,"name":"logging"},{"id":76,"name":"low-code"},{"id":90,"name":"message-queue"},{"id":42,"name":"mobile-app"},{"id":18,"name":"monitoring"},{"id":36,"name":"networking"},{"id":7,"name":"node-version"},{"id":55,"name":"nosql"},{"id":57,"name":"observability"},{"id":46,"name":"orm"},{"id":52,"name":"os"},{"id":14,"name":"parser"},{"id":74,"name":"react"},{"id":82,"name":"real-time"},{"id":56,"name":"robot"},{"id":65,"name":"runtime"},{"id":32,"name":"sdk"},{"id":71,"name":"search"},{"id":63,"name":"secrets"},{"id":25,"name":"security"},{"id":85,"name":"server"},{"id":86,"name":"serverless"},{"id":70,"name":"storage"},{"id":75,"name":"system-design"},{"id":79,"name":"terminal"},{"id":29,"name":"testing"},{"id":12,"name":"ui"},{"id":50,"name":"ux"},{"id":88,"name":"video"},{"id":20,"name":"web-app"},{"id":35,"name":"web-server"},{"id":43,"name":"webassembly"},{"id":69,"name":"workflow"},{"id":87,"name":"yaml"}]" returns me the "expected json"