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.
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.
Here's a basic example.
zen('ul.test>li{list element $}*3');
This will return an Array with a length of two
zen('div.test{a}+div.test>p>span{b}+em{c}');
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'});
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']});
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);
$.zen('ul.test>li{list element $}*3');
$('<ul class="test"></ul>').zen('li{list element $}*3');
To make your code a bit more aesthetic there's also an alias for $.zen: $zen.
$zen('ul.test>li{list element $}*3');