Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- /*
- Tiny emmet implementation.
- Cleaned and improved fork of: github.com/valleykid/zen-coding
- Supports:
- ">" - childs, "*" - multiplications, "+" - siblings, "()" - grouping, custom attributes, tag names, "#" - id, "." - class attributes
- Usage: let html = emm('div#page>header.hd+(section.sc>div.main-wrap>span*3)+footer.ft>div.a');
- */
- (function(){
- window['emm'] = (s) => {
- let zen = {};
- zen.frags = {};
- zen.fragIndex = 0;
- // each closure
- const _ = (obj, iteratee) => {
- let r = [], k;
- for (k in obj)
- r.push(iteratee(obj[k], k));
- return r;
- };
- const _frag = (s) => {
- let arr = s.split('+'), ret = [];
- _(arr, (v, i) => {
- if(/\{\d+\}/.test(v)){
- if(~v.indexOf('*')){
- v = v.split('*');
- let ss = _getPH(v[0]), sss = '';
- for(let m=0; m<v[1]; m++){ sss+=ss; }
- ret[i] = sss;
- } else {
- ret[i] = _getPH(v);
- }
- } else {
- ret[i] = _getFrag(v);
- }
- });
- return ret;
- }
- const _attrs = (str) => {
- if(!str) return '';
- let arr, sid, clas = [], o = {}, s = [];
- arr = str.match(/(\#[\w\-\d]+)|(\.[\w\-\d]+)|(\[[^\]]+\])/g);
- if(arr){
- _(arr, (me)=>{
- if(me.charAt(0)==='['){
- s.push(me.replace(/\[|\]/g, ''));
- } else if(me.charAt(0)==='.' && o[me]===undefined){
- clas.push(me.slice(1));
- o[me] = true;
- } else {
- sid = sid || me.slice(1); // The first effective
- }
- });
- }
- if(sid) s.push('id="'+sid+'"');
- if(clas.length) s.push('class="'+clas.join(' ')+'"');
- return s.join(' ');
- }
- const _tag = (str) => {
- if(!str) return '';
- if(/\<[^\>]+\>/.test(str)) return str;
- if(/[\+\*\>\{]/.test(str)) return _getFrag(str);
- let tag = str.match(/^[^\W]+/), s,
- attrs = _attrs(str);
- attrs = attrs? ' '+attrs : '';
- if(!tag) tag = 'div';
- s = '<'+tag+attrs+(/img|input|br|hr/i.test(tag)? ' />' : '> </'+tag+'>');
- return s;
- }
- const _sibling = (str) => {
- if(!str) return '';
- let arr = str.split('+'), s = '';
- _(arr, (v) => s += _tag(v));
- return s;
- }
- const _repeat = (str) => {
- if(!str) return '';
- let arr = str.split('*'), s = '';
- for(let i=0; i<(arr[1] || 0); i++){
- s += _tag(arr[0]);
- }
- return s;
- }
- const _stack = (str) => {
- if(!str) return '';
- let arr = str.split('>');
- let s = ' ';
- _(arr, (v) => s = s.replace(/\ /g, _tag(v)));
- return s;
- }
- const _bracket = (str, zen) => {
- if(!str) return '';
- if(!/\([^\(\)]+\)/.test(str)) return str;
- let arr = str.match(/\([^\(\)]+\)/g);
- _(arr, (f) => {
- let key = '{'+zen.fragIndex+'}';
- if(zen.frags[f]===undefined){
- zen.frags[key] = f.replace(/\(|\)/g, '');
- }
- str = str.split(f).join(key);
- zen.fragIndex++;
- });
- if(/\([^\(\)]+\)/.test(str)) return _bracket(str, zen);
- return str;
- }
- const _getStack = (str, zen) => {
- if(!str) return '';
- if(str.indexOf('>')<0) return str;
- let reg = /[^\>\+]+\>[^\>]+$/,
- last = str.match(reg);
- if(last){
- let key = '{'+zen.fragIndex+'}', f = last[0];
- if(zen.frags[f]===undefined){
- zen.frags[key] = f;
- }
- str = str.replace(reg, key);
- zen.fragIndex++;
- }
- if(~str.indexOf('>')) return _getStack(str, zen);
- return str;
- }
- const _getFrag = (str) => {
- if(~str.indexOf('>')) return _stack(str);
- if(~str.indexOf('+')) return _sibling(str);
- if(~str.indexOf('*')) return _repeat(str);
- if(str.indexOf('{')<0) return _tag(str);
- return str;
- }
- const _getPH = (str) => {
- let arr = str.split(/\{|\}/g), ret = [];
- _(arr, (v, i) => {
- if(!v){
- ret[i] = '';
- } else if(!isNaN(v)){
- let ph = zen.frags[v];
- ret[i] = ph? _getPH(ph) : '{'+v+'}';
- } else {
- ret[i] = v;
- }
- });
- return ret.join('');
- }
- let _s = _bracket(s, zen);
- _s = _getStack(_s, zen);
- _(zen.frags, (r, k) => {
- if(!/\{\d+\}/.test(k)) return;
- zen.frags[k.replace(/\{|\}/g, '')] = _getFrag(r);
- });
- return _frag(_s).join('').replace(/(\ )|(\{\s+\})/g, '');
- };
- })();
Add Comment
Please, Sign In to add comment