Emmet (formerly known as Zen) spoiled me. Writing a lot of Javascript (and HTML) and I've often thought it would be a lot easier to just use a query selector in reverse. As opposed to innerHTML and document.createElement, just as your Emmet parser does in your favorite IDE.

A while back I wrote a few lines for this purpose. This script uses a subset of Emmet and adds a 'wrapper' function to return an HTMLElement.

Excessive use in a production environment is not really recommended. 23kB minified is a bit much and document.createElement is still the proper way. But it's a nice-to-have for prototyping, testing and small projects that don't require speed.

ps: I named it 'Zen' to prevent collisions with Emmet, and of course: Zen coding sounds way better.


Usage

The function works as follows zen(abbreviation[,content[,returnString]]);.

The abbreviation parameter is similar to a query selector. Emmet really does all the magic so check the Emmet website for documentation on the abbreviation syntax.
So this: zen('h3{zen}'); will return an array with one HTMLElement: <h3>zen</h3>

The optional content parameter is an object which keys replace the values on the resulting emmet string. This is usefull for complex or dynamic content.
So this: zen('h3.emmet{zen}',{emmet:'bert',zen:'ernie'}); will return an array with the following HTMLElement: <h3 class="bert">ernie</h3>

When the object value is an array the result string will be searched for the object key plus the array index (incremented by one).
As such: zen('p*3{foo$}',{foo:['bar','baz','qux']}); will return the following Array: [<p>bar</p>,<p>baz</p>,<p>qux</p>]

When your abbreviations always return a single element the return of an Array might be a bit of a nuisance. Setting zen.firstChild = true; will cause the function to return an HTMLElement instead of an Array if the result is a single element.

In addition there's a tiny jQuery plugin. It has zen.js as a dependency and works in a similar way but returns a jQuery object.

Examples

Zen

Here's a basic example.

zen('ul.test>li{list element $}*3');

Multiple children

This will return an Array with a length of two

zen('div.test{a}+div.test>p>span{b}+em{c}');

Complex or dynamic content

To enable complex or dynamic content you can pass an object as a second argument. This replaces the object key with the object value on the Emmet result string. So use with care.

zen('div.test.myClassname{myContent}',{myClassname:'foo-bar',myContent:'This is content'});

Dynamic content in an array

When the a value in the content object is an array instead of a string it will search for the object key appended with the array position (plus one, since Emmet counts from 1, not 0).

zen('ul.test>li{$: data$}*3',{data:['foo','bar','baz']});

Returning a string

To return a string instead of a list of HTMLElements you can parse a set the third argument to true. You can make this default behaviour by setting zen.returnString to true.

zen('ul.test>li{$: data$}*3',{data:['foo','bar','baz']},true);

jQuery

$.zen('ul.test>li{list element $}*3');

jQuery.html equivalent

$('<ul class="test"></ul>').zen('li{list element $}*3');

Alias

To make your code a bit more aesthetic there's also an alias for $.zen: $zen.

$zen('ul.test>li{list element $}*3');