SIML is the Simplified Markup Language. It is a conceptual hybrid strongly inspired by the simplicity of CSS selectors and SASS-style nesting.
- This project was originally a personal exploration into the world of language parsing
- Writing HTML isn't the worst thing in the world. But it takes time. And as a programmer, I'm lazy.
- I enjoy the expressive power of tiny expressions (hence my love of Perl and RegExps)
No, SIML isn't a templating language. It doesn't currently provide constructs for including data, controlling flow or looping. Reasoning behind this:
- Feature bloat
- People still write plain ol' HTML
- Pure DOM templates are on the rise. See AngularJS or Knockout.
SIML allows you to write HTML with more ease and less cruft. "SIML" is the name of the language, and also the utility for converting the language to HTML.
You can specify your elements through CSS selectors:
div -> <div></div>
p.foo[baz] -> <p class="foo" baz></p>
div#x.ace -> <div id="x" class="ace"></div>
em > span -> <em><span></span></em>
em 'Ok then' -> <em>Ok then</em>
Ok, the last one wasn't a CSS selector, it included a string. But it makes sense, right?
SIML allows nesting with curlies, just like Sassy CSS:
section.body {
h1#title {
'Title'
}
}
Or significant whitespace (i.e. indent to nest):
section.body
h1#title
'Title'
But you're not forced to build hierarchies with nesting; you can do one-liners instead:
section.body > h1#title 'Title'
That'll give you:
<section class="body">
<h1 id="title">
Title
</h1>
</section>
As shown, SIML gives you the expressive power of CSS selectors. It also supports Attributes, Text and Directives.
section { // Selector
class: body // Attribute
' foo blah ' // Text directive
text: 'foo' // Custom Text Attribute
@foo(1,2,3) // Custom directive
}
Note: You can extend SIML to support your own attributes, directives and psuedo-classes. For an example see generators/angular.js
SIML allows you to express more with less effort and, perhaps, more clarity:
section.contact > form
h2 'Enter contact details'
label[for=name]
'Your name?'
input#name
label[for=human]
'Are you human?'
input:checkbox#human
input:submit 'Submit form...'
That would give you:
<section class="contact">
<form>
<h2>
Enter contact details
</h2>
<label for="name">
Your name?
<input id="name"/>
</label>
<label for="human">
Are you human?
<input type="checkbox" id="human"/>
</label>
<input type="submit"/>
</form>
</section>
Nope. SIML has some hidden gems. Some are still being tweaked.
For example, you can use the syntax (.../.../...)
to form an ExclusiveGroup which will make SIML expand a hierarchy to conform to the alternates you specify:
a (b/c) // <a><b></b></a><a><c></c></a>
The above would be the same as writing:
a b
a c
A more useful example:
ul li ('wow'/'this'/'is'/'cool')
Becomes:
<ul>
<li>wow</li>
<li>this</li>
<li>is</li>
<li>cool</li>
</ul>
Another cool feature is multipliers (looks like a numeric psuedo class):
div a:3
Becomes:
<div>
<a></a>
<a></a>
<a></a>
</div>
SIML allows you to make your own SIML generator by configuring:
- Attribute handlers
- Directive handlers
- Pseudo-class handlers
This means, with a bit of configuration, you can write custom markup for your bespoke need. E.g.
This uses the angular generator which converts directives and undefined pseudo-classes to ng-
attributes.
ul#todo-list > li
@repeat( todo in todos | filter:statusFilter )
@class({
completed: todo.completed,
editing: todo == editedTodo
})
This would become:
<ul id="todo-list">
<li
ng-repeat="todo in todos | filter:statusFilter"
ng-class="{ completed: todo.completed, editing: todo == editedTodo }"
></li>
</ul>
More info on AngularJS in SIML
dist/siml.js
: This is the default generator. No fancy stuff. Not eveninput:checkbox
support.dist/siml.html5.js
: For now, this includes small things likedoctype()
support andinput:type
suppport.dist/siml.angular.js
: This is the angular generator, which makes it easier to writeng-...
attributes with directives/pseudo-classes. (Example here). Currently also includesinput:type
support.dist/siml.all.js
: This includes html5 and angular.
<script src="dist/siml.all.min.js"></script>
<script>
siml.html5.parse('a.foo#blah{span "ok"}', {
curly: false, // [default=false] pass true if you're using curlies for hierarchy
pretty: false, // [default=true] Will give you pretty HTML
indent: '....' // [default=' '] Use custom indentation when pretty=true
});
// Generates:
// <a id="blah" class="foo">
// ....<span>
// ........ok
// ....</span>
// </a>
</script>
npm install siml
var siml = require('siml');
// Using the html5 generator (e.g. to support :checkbox)
siml.html5.parse('input:checkbox'); // => '<input type="checkbox" />'
More to come...
- 0.2.0 Introduced single line macro-type selectors and quick-tags (vowelless) as part of the HTML5 generator, e.g.
html hd{meta[charset=utf-8]+title{'Cool'}} bdy
- 0.2.1 Various features added
- 0.3.0
- Many optimisations to prevent pointless backtracking in the parser
- Refactor of parser components.
- Introduction of ExclusiveGroups (
(a/b)
) and InclusiveGroups (a+b,d
) - Improvement of specs
- 0.3.1
- Using Object.create shim (not exposed though)
- Changed naming of customisable Parsers to "Generators" (makes more sense)
- 0.3.2
- Directives can now have children. See new feature specs.
- Selector Prototypes. See Issue #2
- 0.3.3
- Break-out feature. See Issue #3
- Support for here-doc style text (escaped) and HTML strings
- 0.3.4
- Fixed issue where attribute/directive values did not support backtick (no-escape) quotes. See Issue #4
- 0.3.5
- Fixed using quoted strings in 'heredoc' blocks. See Issue #5
- 0.3.6
- Fixed issue where singular tags would not multiply (
selector:n
). See Issue #6 - Fixed issue where backtick quotes within regular quotes would get parsed and result in
%HTML_TOKEN%
tokens in the output.