# Hatter The Mad Hatter discussing Hatter > It is practically impossible to teach good programming to students > that have had a prior exposure to _Hatter_: as potential programmers > they are mentally mutilated beyond hope of regeneration. > > -– Edsger W. Dijkstra (allegedly) Hatter is a small, whitespace sensitive templating language with HTML support built right in. Its HTML features and syntax are a cheap knock off of [Imba], except Hatter produces raw, static HTML - no JavaScript in sight. Hatter can be used to generate static web sites or to render server side content in a good ol' fashioned web application - either with [Vial] or your Rust web framework of choice. If you're feeling adventerous, or mad as a hatter, you can use the standalone binary to turn templates into HTML files, or include the zero-dependency Rust library in your (web/cli/?) application. --- ## Hello Hatter Here are a few basic examples of what Hatter looks like and the HTML it generates: ```html <#main> Hi there!
Hi there!
``` ```html Welcome! Welcome! ``` ```html <.links> for link in nav-links link.text ``` ```html
``` ## Features - Auto-closing HTML tags and code blocks based on indentation: - `

Welcome, Rob` becomes `

Welcome, Rob

` - Shorthand for `id`, `class`, `type`, and `name` attributes: - `` - `` - `` - `` - Dynamic values for regular attributes: - `
` - Conditionally set attributes or enable shorthand: - `
` - `
` - String interpolation: - ` "Hey there {name}. 2 + 2 is {2 + 2}"` - Shorthand interpolation: - ` page.title` - Implicit divs: - `<#main>` becomes `
` - Implicit closing tags: - `delicious` becomes `delicious` - Easy inline JavaScript: - `
  • "🐷"` - Basic types: - `bool, int, float, string, list, map, fn` - Loop over `list` and `map`: - `
      for page in pages do
    • page.name` - `for k, v in some-map do k v` - if/else statements - `if logged_in? then

      Welcome back!` - Error-checked assignment with `:=` and `=`: - `name := 'Bob'` will error if name **is** already set. - `name = 'Bob'` will error if name **isn't** already set. - Call functions defined in Rust: - ` to-uppercase(name)` - Define your own Hatter functions with strict arity and implicit return values: - `def greet(name) do print("Hey there, {name}!")` - `greet("Lydia")` prints `Hey there, Lydia!` - Define your own Hatter operators: - `def ++(a, b) do concat(to-uppercase(a), ' ', to-uppercase(b))` - `"one" ++ "two"` returns `ONE TWO` - Closures and function literals: - `adder := fn(x) fn(y) x + y` then `add1 := adder(1)` - `add1(200)` returns `201` - Call functions with keyword arguments: - `def greet(title, name) do print("Hiya, {title}. {name}!")` - `greet(name: "Marley", title: "Dr")` prints `Hiya, Dr. Marley!` - `do` keyword for one-line blocks: - `if 2 > 1 do print("Obviously")` - `for x in list do print(x)` - `then` keyword for one-line `if` statements: - `if 2 > 1 then print("Yup!") else if 2 < 1 then print("Impossible.")` - Hatter will add a `` and wrap everything in `` if the first tag in your template is ``. ## Getting Started There are two ways to use Hatter: ### 1. In Your Rust Application Hatter can (primarily) be used as a templating language from within your Rust applications. Simply add Hatter to `Cargo.toml`: ```toml [dependencies] hatter = "0.1" ``` Then create a `hatter::Env`, which represents the top-level Hatter scope for your template, to set variables and render your template: ```rust use hatter::{Args, Env, Value}; let mut env = Env::new(); env.set("name", "Bobby Boucher"); env.set("age", 31); env.render(r#"

      Name: name

      Age: age "#) ``` You can also write functions in Rust and make them available to your HTML templates: ```rust use hatter::prelude::*; fn quote(args: Args) -> Result { let file = std::fs::read_to_string("quotes.txt")?; let list_of_quotes: Vec<_> = file.split('\n').collect(); let line = match args.need_number(0)? as usize { n if n > list_of_quotes.len() => 0, n => n, }; Value::from(list_of_quotes[line]).ok() } fn main() { let mut env = Env::new(); env.set("quote", quote); println!("{}", env.render("

      quote(1)").unwrap()); } ``` For more infomation see the [API Documentation][api-docs]. ### 2. As A Standalone Executable Hatter can be used as a regular command line program to turn `.hat` files into HTML. Just install it using `cargo`: ```bash cargo install hatter ``` Then point it at any `.hat` file: ```bash $ cat test.hat "Testing 1 2 3 {2 + 2}" $ hatter test.hat Testing 1 2 3 4 ``` You can also install Hatter with a readline-powered REPL: ```bash cargo install hatter --features repl ``` To launch it, start `hatter` with no arguments: ```bash $ hatter Hatter v0.0.1 REPL >> 1 + 2 3 ``` ## TODO - [ ] HTMLized error page - [ ] show error location in source text on runtime errors ## Future Features - Define your own tags: - `def do item.text`. - Optional type checking for functions - stdlib - VSCode Extension - luacheck-style tool - LSPc ## License Hatter is licensed under either of the following, at your pleasure: - Apache License, Version 2.0, ([LICENSE-APACHE](LICENSE-APACHE) or ) - MIT License ([LICENSE-MIT](LICENSE-MIT) or ) [Imba] is licensed under the [MIT License](https://github.com/imba/imba/blob/master/LICENSE). [imba]: https://imba.io [vial]: http://github.com/xvxx/vial [api-docs]: https://docs.rs/hatter/