/regg

Static Site Generator Written in Rust

Primary LanguageRustApache License 2.0Apache-2.0

🚧 Caution:

⚠️ The project is a Work in Progress and doesn't work.

Regg Template Engine

A simple template engine written in Rust 🦀

Regg's goal is to output JavaScript code that can be used with Vite's plugin API to generate static HTML.

Table of Content

Development

Run a .regg file:

cargo run -- <FILEPATH>

REPL:

cargo run

Roadmap

Templating Engine

  • Scanner (or Lexer or Tokenizer)
    • Support Markup Tags
    • Support Markup inside expressions (` and `)
    • Support Expressions
    • Support Code Blocks — code between --- and --- at the start
    • Support escaped expression syntax — \{ and \}
    • Add Tests
  • Parser
  • Traverser
  • Transformer
  • Code Generator
  • Compiler

Miscellaneous

  • Devise a Context Free Grammer
    • Port to Backus-Naur Form [Optional]
  • CLI with Clap-rs
    • REPL Mode
    • Take File Path to run files
    • Output Files [nice to have]
  • Precomiled Node.js addone
    • NAPI-rs integration

Syntax Guide

Frontmatter

---
  const greeting = 'hello world!';
  const navItems = ['home', 'about', 'contact']
---

The code inside the Frontmatter Fence Tokens (---) is called a Codeblock.
This is different from an expression that goes inside { and } as it does not need to be checked if it returns a string or number.

Expressions

<main>
  <h1>{greeting}</h1>
</main>

Stuff between { and } is a JavaScript expressions
The expressions should get evaluated into a string or number or markup.

Markup Expressions

<main>
  {
    navItems.map(navItem => {
      return (`<nav>{navItem}</nav>`)
    })
  }
</main>

A JavaScript Expression can return a Markup Expression.
A Markup Expression tells Regg that this markup contains JavaScript expressions that need to be evaluated.
The syntax is adding the Markup Expression between `( and `), this is valid JavaScript unlike JSX.
Although the expression part is Regg specific syntax that is evaluated by the templating engine at build time.

Context Free Grammar

Frontmatter -> CodeBlock
HTMLElement -> OpeningTagStart TextNode* OpeningTagEnd (HTMLElement* | TextNode) (ClosingTag | SelfClosingTag)
TextNode    -> Expression* (HTMLExprStart HTMLElement* HTMLExprEnd)* Expression*
OpeningTagStart      -> <foo             ; foo = \[A-Za-z]\
OpeningTagEnd        -> >                ;
SelfClosingTag       -> />               ;
ClosingTag           -> </foo>           ; foo = \[A-Za-z]\

CodeBlock            -> --- bar ---      ; bar = \*\
Expression           -> { bar }          ; bar = \*\
HTMLExprStart        -> (`               ;
HTMLExprEnd          -> `)               ;

Inspirations