Project

herb

0.07
There's a lot of open issues
A long-lived project that still receives updates
Powerful and seamless HTML-aware ERB parsing and tooling.
2005
2006
2007
2008
2009
2010
2011
2012
2013
2014
2015
2016
2017
2018
2019
2020
2021
2022
2023
2024
2025
 Dependencies
 Project Readme
Herb HTML+ERB parser

Herb

HTML + ERB (HTML Embedded Ruby)

Powerful and seamless HTML-aware ERB parsing and tooling.

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

For Linux
xargs sudo apt-get install < Aptfile

or:

sudo apt-get install check clang-19 clang-tidy-19 clang-format-19 emscripten doxygen
For macOS (using Homebrew)
brew bundle

or:

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.

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.

rake

If rake was successful you can use bundle console to interact with Herb:

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

make test && ./run_herb_tests

For the Ruby Tests

rake test

Clean

Removes the herb, run_herb_tests, prism installation, and all .o files.

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.

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 file for details.