mirror of
https://github.com/haml/haml.git
synced 2022-11-09 12:33:31 -05:00
Write document
This commit is contained in:
parent
4bfe24b9bd
commit
018a81abdf
2 changed files with 361 additions and 2 deletions
152
README.md
152
README.md
|
@ -1,7 +1,155 @@
|
||||||
# Hamlit
|
# Hamlit
|
||||||
|
|
||||||
High Performance Haml Implementation
|
Hamlit is a high performance [Haml](https://github.com/haml/haml) implementation.
|
||||||
|
|
||||||
|
## Introduction
|
||||||
|
|
||||||
|
### What is Hamlit?
|
||||||
|
Hamlit is another implementation of [Haml](https://github.com/haml/haml) and designed to make Haml language faster than
|
||||||
|
[Slim](https://github.com/slim-template/slim). With some [limitations](REFERENCE.md#limitations) by
|
||||||
|
design for performance, Hamlit is **7.16x times faster** than original haml gem in
|
||||||
|
this benchmark, which is an HTML-escaped version of slim-template/slim's one for fairness.
|
||||||
|
|
||||||
|

|
||||||
|
|
||||||
|
### Why is Hamlit faster?
|
||||||
|
|
||||||
|
#### Less string concatenation by design
|
||||||
|
As written in [limitations](REFERENCE.md#limitations), Hamlit drops some not-so-important features which require
|
||||||
|
works on runtime. With the optimized language design, we can reduce the string concatenation
|
||||||
|
to build attributes.
|
||||||
|
|
||||||
|
#### Temple optimizers
|
||||||
|
Hamlit is built with [Temple](https://github.com/judofyr/temple), which is a framework to build
|
||||||
|
template engines and also used in Slim. By using the framework and its optimizers, Hamlit can
|
||||||
|
reduce string allocation and concatenation easily.
|
||||||
|
|
||||||
|
#### Static analyzer
|
||||||
|
Hamlit analyzes Ruby expressions with Ripper and render it on compilation if the expression
|
||||||
|
is static.
|
||||||
|
|
||||||
|
#### C extension to build attributes
|
||||||
|
While Hamlit has static analyzer and static attributes are rendered on compilation,
|
||||||
|
dynamic attributes should be rendered on runtime. So Hamlit optimizes rendering on runtime
|
||||||
|
with C extension.
|
||||||
|
|
||||||
|
## Usage
|
||||||
|
|
||||||
|
See [REFERENCE.md](REFERENCE.md) for detail features of Hamlit.
|
||||||
|
|
||||||
|
### Rails
|
||||||
|
|
||||||
|
Add this line to your application's Gemfile or just replace `gem "haml"` with `gem "hamlit"`.
|
||||||
|
It enables rendering by Hamlit for \*.haml automatically.
|
||||||
|
|
||||||
|
```rb
|
||||||
|
gem 'hamlit'
|
||||||
|
```
|
||||||
|
|
||||||
|
If you want to use view generator, consider using [hamlit-rails](https://github.com/mfung/hamlit-rails).
|
||||||
|
|
||||||
|
### Sinatra
|
||||||
|
|
||||||
|
Replace `gem "haml"` with `gem "hamlit"` in Gemfile, and require "hamlit".
|
||||||
|
See [sample/sinatra](sample/sinatra) for working sample.
|
||||||
|
|
||||||
|
While Haml disables `escape_html` option by default, Hamlit enables it for security.
|
||||||
|
If you want to disable it, please write:
|
||||||
|
|
||||||
|
```rb
|
||||||
|
set :haml, { escape_html: false }
|
||||||
|
```
|
||||||
|
|
||||||
|
|
||||||
|
## Command line interface
|
||||||
|
|
||||||
|
'hamlit' command is available if you install thor gem with `gem install thor`.
|
||||||
|
|
||||||
|
```bash
|
||||||
|
$ gem install hamlit thor
|
||||||
|
$ hamlit --help
|
||||||
|
Commands:
|
||||||
|
hamlit compile HAML # Show compile result
|
||||||
|
hamlit help [COMMAND] # Describe available commands or one specific command
|
||||||
|
hamlit parse HAML # Show parse result
|
||||||
|
hamlit render HAML # Render haml template
|
||||||
|
|
||||||
|
$ cat in.haml
|
||||||
|
.foo#bar
|
||||||
|
|
||||||
|
# Show compiled code
|
||||||
|
$ hamlit compile in.haml
|
||||||
|
_buf = "<div class='foo' id='bar'></div>\n"
|
||||||
|
|
||||||
|
# Render html
|
||||||
|
$ hamlit render in.haml
|
||||||
|
<div class='foo' id='bar'></div>
|
||||||
|
```
|
||||||
|
|
||||||
|
## Contributing
|
||||||
|
|
||||||
|
### Development
|
||||||
|
|
||||||
|
Contributions are welcomed.
|
||||||
|
|
||||||
|
```bash
|
||||||
|
$ git clone https://github.com/k0kubun/hamlit
|
||||||
|
$ cd hamlit
|
||||||
|
$ bundle install
|
||||||
|
|
||||||
|
# Run all tests
|
||||||
|
$ bundle exec rake test
|
||||||
|
|
||||||
|
# Run one test
|
||||||
|
$ bundle exec ruby -Ilib:test -rtest_helper test/hamlit/line_number_test.rb -l 12
|
||||||
|
|
||||||
|
# Show compiling/rendering result of some template
|
||||||
|
$ bundle exec exe/hamlit compile in.haml
|
||||||
|
$ bundle exec exe/hamlit render in.haml
|
||||||
|
|
||||||
|
# Use rails app to debug Hamlit
|
||||||
|
$ cd sample/rails
|
||||||
|
$ bundle install
|
||||||
|
$ bundle exec rails s
|
||||||
|
```
|
||||||
|
|
||||||
|
### Reporting an issue
|
||||||
|
|
||||||
|
Please report an issue with following information:
|
||||||
|
|
||||||
|
- Full error backtrace
|
||||||
|
- Haml template
|
||||||
|
- Ruby version
|
||||||
|
- Hamlit version
|
||||||
|
- Rails/Sinatra version
|
||||||
|
|
||||||
## License
|
## License
|
||||||
|
|
||||||
The gem is available as open source under the terms of the [MIT License](http://opensource.org/licenses/MIT).
|
MIT License
|
||||||
|
|
||||||
|
Copyright (c) 2015 Takashi Kokubun
|
||||||
|
|
||||||
|
### Parser and Haml tests
|
||||||
|
|
||||||
|
lib/hamlit/parser/\*.rb and test/haml/\* are:
|
||||||
|
|
||||||
|
Copyright (c) 2006-2009 Hampton Catlin and Natalie Weizenbaum
|
||||||
|
|
||||||
|
Permission is hereby granted, free of charge, to any person obtaining
|
||||||
|
a copy of this software and associated documentation files (the
|
||||||
|
"Software"), to deal in the Software without restriction, including
|
||||||
|
without limitation the rights to use, copy, modify, merge, publish,
|
||||||
|
distribute, sublicense, and/or sell copies of the Software, and to
|
||||||
|
permit persons to whom the Software is furnished to do so, subject to
|
||||||
|
the following conditions:
|
||||||
|
|
||||||
|
The above copyright notice and this permission notice shall be
|
||||||
|
included in all copies or substantial portions of the Software.
|
||||||
|
|
||||||
|
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
||||||
|
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||||
|
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
||||||
|
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
||||||
|
LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
||||||
|
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
||||||
|
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||||
|
|
211
REFERENCE.md
Normal file
211
REFERENCE.md
Normal file
|
@ -0,0 +1,211 @@
|
||||||
|
# Hamlit
|
||||||
|
|
||||||
|
Basically Hamlit is the same as Haml.
|
||||||
|
See [Haml's tutorial](http://haml.info/tutorial.html) if you are not familiar with Haml's syntax.
|
||||||
|
|
||||||
|
[REFERENCE - Haml Documentation](http://haml.info/docs/yardoc/file.REFERENCE.html)
|
||||||
|
|
||||||
|
## Supported features
|
||||||
|
|
||||||
|
See [Haml's reference](http://haml.info/docs/yardoc/file.REFERENCE.html)
|
||||||
|
for full features in original implementation.
|
||||||
|
|
||||||
|
- [x] Using Haml
|
||||||
|
- [x] Rails XSS Protection
|
||||||
|
- [x] Ruby Module
|
||||||
|
- [x] Options
|
||||||
|
- [ ] Encodings
|
||||||
|
- [x] Plain Text
|
||||||
|
- [x] Escaping: \
|
||||||
|
- [x] HTML Elements
|
||||||
|
- [x] Element Name: %
|
||||||
|
- [x] Attributes: `
|
||||||
|
- [x] :class and :id Attributes
|
||||||
|
- [x] HTML-style Attributes: ()
|
||||||
|
- [x] Ruby 1.9-style Hashes
|
||||||
|
- [ ] Attribute Methods
|
||||||
|
- [x] Boolean Attributes
|
||||||
|
- [x] HTML5 Custom Data Attributes
|
||||||
|
- [x] Class and ID: . and #
|
||||||
|
- Implicit Div Elements
|
||||||
|
- [x] Empty (void) Tags: /
|
||||||
|
- [x] Whitespace Removal: > and <
|
||||||
|
- [x] Object Reference: []
|
||||||
|
- [x] Doctype: !!!
|
||||||
|
- [x] Comments
|
||||||
|
- [x] HTML Comments: /
|
||||||
|
- [x] Conditional Comments: /[]
|
||||||
|
- [x] Haml Comments: -#
|
||||||
|
- [x] Ruby Evaluation
|
||||||
|
- [x] Inserting Ruby: =
|
||||||
|
- [x] Running Ruby: -
|
||||||
|
- [x] Ruby Blocks
|
||||||
|
- [x] Whitespace Preservation: ~
|
||||||
|
- [x] Ruby Interpolation: #{}
|
||||||
|
- [x] Escaping HTML: &=
|
||||||
|
- [x] Unescaping HTML: !=
|
||||||
|
- [x] Filters
|
||||||
|
- [ ] :cdata
|
||||||
|
- [x] :coffee
|
||||||
|
- [x] :css
|
||||||
|
- [x] :erb
|
||||||
|
- [x] :escaped
|
||||||
|
- [x] :javascript
|
||||||
|
- [x] :less
|
||||||
|
- [x] :markdown
|
||||||
|
- [ ] :maruku
|
||||||
|
- [x] :plain
|
||||||
|
- [x] :preserve
|
||||||
|
- [x] :ruby
|
||||||
|
- [x] :sass
|
||||||
|
- [x] :scss
|
||||||
|
- [ ] :textile
|
||||||
|
- [ ] Custom Filters
|
||||||
|
- [ ] Helper Methods
|
||||||
|
- [x] surround
|
||||||
|
- [x] precede
|
||||||
|
- [x] succeed
|
||||||
|
- [x] Multiline: |
|
||||||
|
- [x] Whitespace Preservation
|
||||||
|
- [ ] Helpers
|
||||||
|
|
||||||
|
|
||||||
|
## Limitations
|
||||||
|
|
||||||
|
### No pretty mode
|
||||||
|
Haml has :pretty mode and :ugly mode. :pretty mode is used on development and indented beautifully.
|
||||||
|
On production environemnt, :ugly mode is used and Hamlit currently supports only this mode.
|
||||||
|
|
||||||
|
So you'll see difference rendering result on development environment, but it'll be the same on production.
|
||||||
|
|
||||||
|
### No Haml buffer
|
||||||
|
Hamlit uses Array as buffer for performance. So you can't touch Haml::Buffer from template when using Hamlit.
|
||||||
|
|
||||||
|
### Haml helpers are still in development
|
||||||
|
At the same time, because some methods in Haml::Buffer requires Haml::Buffer, they are not supported now.
|
||||||
|
But some helpers are supported on Rails. Some of them are planned to be supported.
|
||||||
|
|
||||||
|
### Limited attributes hyphenation
|
||||||
|
In Haml, `%a{ foo: { bar: 'baz' } }` is rendered as `<a foo-bar='baz'></a>`, whatever foo is.
|
||||||
|
In Hamlit, this feature is supported only for data attribute. Hamlit renders `%a{ data: { foo: 'bar' } }`
|
||||||
|
as `<a data-foo='bar'></a>` because it's data attribute.
|
||||||
|
|
||||||
|
This design allows us to reduce work on runtime and is originally in [Faml](https://github.com/eagletmt/faml).
|
||||||
|
|
||||||
|
### Limited boolean attributes
|
||||||
|
In Haml, `%a{ foo: false }` is rendered as `<a></a>`, whatever foo is.
|
||||||
|
In Hamlit, this feature is supported for only boolean attributes, which is in
|
||||||
|
http://www.w3.org/TR/xhtml1/guidelines.html https://html.spec.whatwg.org/.
|
||||||
|
The list is the same as `ActionView::Helpers::TagHelper::BOOLEAN_ATTRIBUTES`.
|
||||||
|
|
||||||
|
Since foo is not boolean attribute, `%a{ foo: false }` is rendered as `<a foo='false'></a>`.
|
||||||
|
This is the same behavior as not Haml but Rails helpers.
|
||||||
|
|
||||||
|
For nil, while Haml and Rails remove the attribute entirely if the value is nil,
|
||||||
|
Hamlit does not remove non-boolean attributes and render `<a foo=''></a>`.
|
||||||
|
This design allows us to reduce String concatenation.
|
||||||
|
|
||||||
|
This is the largest difference between Hamlit and Faml.
|
||||||
|
|
||||||
|
## 5 Types of Attributes
|
||||||
|
|
||||||
|
Haml has 3 types of attributes: id, class and others.
|
||||||
|
In addition, Hamlit treats data and boolean attributes specially.
|
||||||
|
So there are 5 types of attributes in Hamlit.
|
||||||
|
|
||||||
|
### id attribute
|
||||||
|
Almost the same behavior as Haml, except no hyphenation and boolean support.
|
||||||
|
Multiple id specification results in `_`-concatenation.
|
||||||
|
|
||||||
|
```rb
|
||||||
|
# Input
|
||||||
|
%div{ id: %w[foo bar] }
|
||||||
|
#foo{ id: 'bar' }
|
||||||
|
|
||||||
|
# Output
|
||||||
|
<div id='foo_bar'></span>
|
||||||
|
<div id='foo_bar'></span>
|
||||||
|
```
|
||||||
|
|
||||||
|
### class attribute
|
||||||
|
Almost the same behavior as Haml, except no hyphenation and boolean support.
|
||||||
|
Multiple class specification results in unique alphabetical sort.
|
||||||
|
|
||||||
|
```rb
|
||||||
|
# Input
|
||||||
|
%div{ class: 'd c b a' }
|
||||||
|
.d.a(class='b c'){ class: 'c a' }
|
||||||
|
|
||||||
|
# Output
|
||||||
|
<div class='d c b a'></div>
|
||||||
|
<div class='a b c d'></div>
|
||||||
|
```
|
||||||
|
|
||||||
|
### data attribute
|
||||||
|
Hyphenation is supported but boolean support is for only `data-#{boolean attribute}`.
|
||||||
|
|
||||||
|
```rb
|
||||||
|
# Input
|
||||||
|
%div{ data: { disabled: true } }
|
||||||
|
%div{ data: { foo: 'bar' } }
|
||||||
|
|
||||||
|
# Output
|
||||||
|
<div data-disabled></div>
|
||||||
|
<div data-foo='bar'></div>
|
||||||
|
```
|
||||||
|
|
||||||
|
### boolean attributes
|
||||||
|
No hyphenation but complete boolean support.
|
||||||
|
|
||||||
|
```rb
|
||||||
|
# Input
|
||||||
|
%div{ disabled: true }
|
||||||
|
%div{ disabled: false }
|
||||||
|
|
||||||
|
# Output
|
||||||
|
<div disabled></div>
|
||||||
|
<div></div>
|
||||||
|
```
|
||||||
|
|
||||||
|
List of boolean attributes is:
|
||||||
|
|
||||||
|
```
|
||||||
|
disabled readonly multiple checked autobuffer autoplay controls loop selected hidden scoped async
|
||||||
|
defer reversed ismap seamless muted required autofocus novalidate formnovalidate open pubdate
|
||||||
|
itemscope allowfullscreen default inert sortable truespeed typemustmatch
|
||||||
|
```
|
||||||
|
|
||||||
|
### other attributes
|
||||||
|
No hyphenation and boolean support.
|
||||||
|
|
||||||
|
```rb
|
||||||
|
# Input
|
||||||
|
%input{ value: true }
|
||||||
|
%input{ value: false }
|
||||||
|
|
||||||
|
# Output
|
||||||
|
<input value='true'>
|
||||||
|
<input value='false'>
|
||||||
|
```
|
||||||
|
|
||||||
|
## Engine options
|
||||||
|
|
||||||
|
| Option | Default | Feature |
|
||||||
|
|:-------|:--------|:--------|
|
||||||
|
| escape\_html | true | HTML-escape for Ruby script and interpolation. This is false in Haml. |
|
||||||
|
| escape\_attrs | true | HTML-escape for Html attributes. |
|
||||||
|
| format | :html | You can set :xhtml to change boolean attribute's format. |
|
||||||
|
| attr\_quote | `'` | You can change attribute's wrapper to `"` or something. |
|
||||||
|
|
||||||
|
### Set options for Rails
|
||||||
|
|
||||||
|
```rb
|
||||||
|
# config/initializers/hamlit.rb or somewhere
|
||||||
|
Hamlit::RailsTemplate.set_options attr_quote: '"'
|
||||||
|
```
|
||||||
|
|
||||||
|
### Set options for Sinatra
|
||||||
|
|
||||||
|
```rb
|
||||||
|
set :haml, { attr_quote: '"' }
|
||||||
|
```
|
Loading…
Add table
Reference in a new issue