Guest User

Untitled

a guest
Jan 23rd, 2018
100
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 4.38 KB | None | 0 0
  1. /*
  2. Tiny emmet implementation.
  3. Cleaned and improved fork of: github.com/valleykid/zen-coding
  4.  
  5. Supports:
  6. ">" - childs, "*" - multiplications, "+" - siblings, "()" - grouping, custom attributes, tag names, "#" - id, "." - class attributes
  7.  
  8. Usage: let html = emm('div#page>header.hd+(section.sc>div.main-wrap>span*3)+footer.ft>div.a');
  9. */
  10.  
  11. (function(){
  12. window['emm'] = (s) => {
  13. let zen = {};
  14. zen.frags = {};
  15. zen.fragIndex = 0;
  16.  
  17. // each closure
  18. const _ = (obj, iteratee) => {
  19. let r = [], k;
  20.  
  21. for (k in obj)
  22. r.push(iteratee(obj[k], k));
  23.  
  24. return r;
  25. };
  26.  
  27. const _frag = (s) => {
  28. let arr = s.split('+'), ret = [];
  29. _(arr, (v, i) => {
  30. if(/\{\d+\}/.test(v)){
  31. if(~v.indexOf('*')){
  32. v = v.split('*');
  33. let ss = _getPH(v[0]), sss = '';
  34. for(let m=0; m<v[1]; m++){ sss+=ss; }
  35. ret[i] = sss;
  36. } else {
  37. ret[i] = _getPH(v);
  38. }
  39. } else {
  40. ret[i] = _getFrag(v);
  41. }
  42. });
  43.  
  44. return ret;
  45. }
  46.  
  47. const _attrs = (str) => {
  48. if(!str) return '';
  49.  
  50. let arr, sid, clas = [], o = {}, s = [];
  51. arr = str.match(/(\#[\w\-\d]+)|(\.[\w\-\d]+)|(\[[^\]]+\])/g);
  52. if(arr){
  53. _(arr, (me)=>{
  54. if(me.charAt(0)==='['){
  55. s.push(me.replace(/\[|\]/g, ''));
  56. } else if(me.charAt(0)==='.' && o[me]===undefined){
  57. clas.push(me.slice(1));
  58. o[me] = true;
  59. } else {
  60. sid = sid || me.slice(1); // The first effective
  61. }
  62. });
  63. }
  64.  
  65. if(sid) s.push('id="'+sid+'"');
  66. if(clas.length) s.push('class="'+clas.join(' ')+'"');
  67. return s.join(' ');
  68. }
  69.  
  70. const _tag = (str) => {
  71. if(!str) return '';
  72. if(/\<[^\>]+\>/.test(str)) return str;
  73. if(/[\+\*\>\{]/.test(str)) return _getFrag(str);
  74.  
  75. let tag = str.match(/^[^\W]+/), s,
  76. attrs = _attrs(str);
  77. attrs = attrs? ' '+attrs : '';
  78. if(!tag) tag = 'div';
  79. s = '<'+tag+attrs+(/img|input|br|hr/i.test(tag)? ' />' : '>&nbsp;</'+tag+'>');
  80. return s;
  81. }
  82.  
  83. const _sibling = (str) => {
  84. if(!str) return '';
  85. let arr = str.split('+'), s = '';
  86. _(arr, (v) => s += _tag(v));
  87. return s;
  88. }
  89.  
  90. const _repeat = (str) => {
  91. if(!str) return '';
  92. let arr = str.split('*'), s = '';
  93. for(let i=0; i<(arr[1] || 0); i++){
  94. s += _tag(arr[0]);
  95. }
  96. return s;
  97. }
  98.  
  99. const _stack = (str) => {
  100. if(!str) return '';
  101. let arr = str.split('>');
  102. let s = '&nbsp;';
  103. _(arr, (v) => s = s.replace(/\&nbsp;/g, _tag(v)));
  104. return s;
  105. }
  106.  
  107. const _bracket = (str, zen) => {
  108. if(!str) return '';
  109. if(!/\([^\(\)]+\)/.test(str)) return str;
  110.  
  111. let arr = str.match(/\([^\(\)]+\)/g);
  112. _(arr, (f) => {
  113. let key = '{'+zen.fragIndex+'}';
  114. if(zen.frags[f]===undefined){
  115. zen.frags[key] = f.replace(/\(|\)/g, '');
  116. }
  117. str = str.split(f).join(key);
  118. zen.fragIndex++;
  119. });
  120.  
  121. if(/\([^\(\)]+\)/.test(str)) return _bracket(str, zen);
  122. return str;
  123. }
  124.  
  125. const _getStack = (str, zen) => {
  126. if(!str) return '';
  127. if(str.indexOf('>')<0) return str;
  128.  
  129. let reg = /[^\>\+]+\>[^\>]+$/,
  130. last = str.match(reg);
  131. if(last){
  132. let key = '{'+zen.fragIndex+'}', f = last[0];
  133. if(zen.frags[f]===undefined){
  134. zen.frags[key] = f;
  135. }
  136. str = str.replace(reg, key);
  137. zen.fragIndex++;
  138. }
  139.  
  140. if(~str.indexOf('>')) return _getStack(str, zen);
  141. return str;
  142. }
  143.  
  144. const _getFrag = (str) => {
  145. if(~str.indexOf('>')) return _stack(str);
  146. if(~str.indexOf('+')) return _sibling(str);
  147. if(~str.indexOf('*')) return _repeat(str);
  148. if(str.indexOf('{')<0) return _tag(str);
  149. return str;
  150. }
  151.  
  152. const _getPH = (str) => {
  153. let arr = str.split(/\{|\}/g), ret = [];
  154.  
  155. _(arr, (v, i) => {
  156. if(!v){
  157. ret[i] = '';
  158. } else if(!isNaN(v)){
  159. let ph = zen.frags[v];
  160. ret[i] = ph? _getPH(ph) : '{'+v+'}';
  161. } else {
  162. ret[i] = v;
  163. }
  164. });
  165. return ret.join('');
  166. }
  167.  
  168. let _s = _bracket(s, zen);
  169. _s = _getStack(_s, zen);
  170.  
  171. _(zen.frags, (r, k) => {
  172. if(!/\{\d+\}/.test(k)) return;
  173. zen.frags[k.replace(/\{|\}/g, '')] = _getFrag(r);
  174. });
  175.  
  176. return _frag(_s).join('').replace(/(\&nbsp;)|(\{\s+\})/g, '');
  177. };
  178. })();
Add Comment
Please, Sign In to add comment