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 scripting language with HTML templating built 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 an old fashioned web application.
It's like a less powerful, 90s-era PHP. But we're talking PHP/FI, none of that Easy-Bake Oven PHP3 stuff that you could use to build actual sites.
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's what it looks like:
for i, person in people
person
Which turns into:
John
Paul
George
Ringo
Or, a beefier example:
sign in
sign up
for link in nav-links
link.text
<#main.markdown-body>
if logged-in?
Welcome back, name </>!
else
Nice to, uh, see you. Have we met..?
Which, if we're logged in as The Mad Hatter and webview? is
false, will turn into:
sign in
sign up
Hats
Cards
Tea
Welcome back, The Mad Hatter !
Features
- Auto-closing HTML tags and code blocks based on indentation.
- Shorthand for
id,class,type, andnameattributes:<div#id><div.class1.class2><input@form-field-name><input:text>
- Basic types:
bool,int,float,string,list,map,fn()
- Loop over
listandmap:<ul> for page in pages do <li id=page-{page.id}> page.namefor k, v in some-map do <td> k </> <td> v
- if/else statements
if logged_in? then <h2> 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.
- Dynamic values for regular attributes:
<div page-num={page.id}>
- Conditionally set attributes or enable shorthand:
<div .logged-in=logged-in?><div data-map=is-map?>
- String interpolation:
<span.greeting> "Hey there {name}. 2 + 2 is {2 + 2}"
- Shorthand interpolation:
<span #page-{page.id} .is-{page.type}> page.title
- Implicit divs:
<#main>becomes<div id='main'>
- Implicit closing tags:
<i>delicious</>becomes<i>delicious</i>
- Call functions defined in Rust:
<div.name> to-uppercase(name)
- Define your own Hatter functions with strict arity:
def greet(name) do print("Hey there, {name}!")greet("Lydia")printsHey there, Lydia!
- Define your own Hatter operators:
def !!(a, b) do return concat(to-uppercase(a), ' ', to-uppercase(b))
- Easy inline JavaScript:
<li> <a onclick=(alert("Oink!"))> 🐷
- Hatter will add a
<!DOCTYPE>and wrap everything in<html>if the first tag in your template is<head>.
Future Features
- Define your own tags:
def <item(item)> do <li.item data-id={item.id}> item.text.
- Optional type checking for functions
TODO
- HTMLized error page
- def
- show error location when compiling
- repl: tab completion
docs
- design
- layout
- generator
- content
project
- bomb-ass test suite
- stdlib
- VSCode Extension
- VSCode + luacheck-style LSP
- luacheck-style tool
License
Hatter is licensed under the MIT License. Please see COPYING or http://opensource.org/licenses/MIT for details.
Imba is licensed under the MIT License.