vendor/emmet.js
function makePossibleRangesHTML(source, tokens, offset) {
		offset = offset || 0;
		var range = require('range');
		var result = [];
		var attrStart = -1, attrName = '', attrValue = '', attrValueRange, tagName;
		_.each(tokens, function(tok) {
			switch (tok.type) {
				case 'tag':
					tagName = source.substring(tok.start, tok.end);
					if (/^<[\w\:\-]/.test(tagName)) {
						// add tag name
						result.push(range.create({
							start: tok.start + 1, 
							end: tok.end
						}));
					}
					break;
				case 'attribute':
					attrStart = tok.start;
					attrName = source.substring(tok.start, tok.end);
					break;
					
				case 'string':
					// attribute value
					// push full attribute first
					 result.push(range.create(attrStart, tok.end - attrStart));
					 
					 attrValueRange = range.create(tok);
					 attrValue = attrValueRange.substring(source);
					 
					 // is this a quoted attribute?
					 if (isQuote(attrValue.charAt(0)))
						 attrValueRange.start++;
					 
					 if (isQuote(attrValue.charAt(attrValue.length - 1)))
						 attrValueRange.end--;
					 
					 result.push(attrValueRange);
					 
					 if (attrName == 'class') {
						 result = result.concat(classNameRanges(attrValueRange.substring(source), attrValueRange.start));
					 }
					 
					break;
			}
		});
		
		// offset ranges
		_.each(result, function(r) {
			r.shift(offset);
		});
		
		return _.chain(result)
			.filter(function(item) {        // remove empty
				return !!item.length();
			})
			.uniq(false, function(item) {   // remove duplicates
				return item.toString();
			})
			.value();
	}
function makePossibleRangesHTML(source, tokens, offset) {
		offset = offset || 0;
		var range = require('range');
		var result = [];
		var attrStart = -1, attrName = '', attrValue = '', attrValueRange, tagName;
		_.each(tokens, function(tok) {
			switch (tok.type) {
				case 'tag':
					tagName = source.substring(tok.start, tok.end);
					if (/^<[\w\:\-]/.test(tagName)) {
						// add tag name
						result.push(range.create({
							start: tok.start + 1, 
							end: tok.end
						}));
					}
					break;
				case 'attribute':
					attrStart = tok.start;
					attrName = source.substring(tok.start, tok.end);
					break;
					
				case 'string':
					// attribute value
					// push full attribute first
					 result.push(range.create(attrStart, tok.end - attrStart));
					 
					 attrValueRange = range.create(tok);
					 attrValue = attrValueRange.substring(source);
					 
					 // is this a quoted attribute?
					 if (isQuote(attrValue.charAt(0)))
						 attrValueRange.start++;
					 
					 if (isQuote(attrValue.charAt(attrValue.length - 1)))
						 attrValueRange.end--;
					 
					 result.push(attrValueRange);
					 
					 if (attrName == 'class') {
						 result = result.concat(classNameRanges(attrValueRange.substring(source), attrValueRange.start));
					 }
					 
					break;
			}
		});
		
		// offset ranges
		_.each(result, function(r) {
			r.shift(offset);
		});
		
		return _.chain(result)
			.filter(function(item) {        // remove empty
				return !!item.length();
			})
			.uniq(false, function(item) {   // remove duplicates
				return item.toString();
			})
			.value();
	}
Creates possible selection ranges for HTML tag
@param {String} source Original HTML source for tokens
@param {Array} tokens List of HTML tokens
@returns {Array}