function! emmet#lang#css#findTokens(str) abort let tmp = substitute(substitute(a:str, '^.*[;{]\s*', '', ''), '}\s*$', '', '') if tmp =~ '/' && tmp =~ '^[a-zA-Z0-9/_.]\+$' " maybe path or something return '' endif return substitute(substitute(a:str, '^.*[;{]\s*', '', ''), '}\s*$', '', '') endfunction function! emmet#lang#css#parseIntoTree(abbr, type) abort let abbr = a:abbr let type = a:type let prefix = 0 let value = '' let indent = emmet#getIndentation(type) let aliases = emmet#getResource(type, 'aliases', {}) let snippets = emmet#getResource(type, 'snippets', {}) let use_pipe_for_cursor = emmet#getResource(type, 'use_pipe_for_cursor', 1) let root = emmet#newNode() " emmet let tokens = split(abbr, '+\ze[^+)!]') let block = emmet#util#searchRegion('{', '}') if abbr !~# '^@' && emmet#getBaseType(type) ==# 'css' && type !=# 'sass' && type !=# 'styled' && block[0] ==# [0,0] && block[1] ==# [0,0] let current = emmet#newNode() let current.snippet = substitute(abbr, '\s\+$', '', '') . " {\n" . indent . "${cursor}\n}" let current.name = '' call add(root.child, deepcopy(current)) else for n in range(len(tokens)) let token = tokens[n] let prop = matchlist(token, '^\(-\{0,1}[a-zA-Z]\+\|[a-zA-Z0-9]\++\{0,1}\|([a-zA-Z0-9]\++\{0,1})\)\(\%([0-9.-]\+\%(p\|e\|em\|x\|vh\|vw\|re\|rem\|%\)\{0,}-\{0,1}\|-auto\)*\)$') if len(prop) let token = substitute(prop[1], '^(\(.*\))', '\1', '') if token =~# '^-' let prefix = 1 let token = token[1:] endif let value = '' for vt in split(prop[2], '\a\+\zs') let ut = matchstr(vt, '[a-z]\+$') if ut == 'auto' let ut = '' endif for v in split(vt, '\d\zs-') if len(value) > 0 let value .= ' ' endif if v !~ '[a-z]\+$' let v .= ut endif if token =~# '^[z]' " TODO let value .= substitute(v, '[^0-9.]*$', '', '') elseif v =~# 'em$' let value .= v elseif v =~# 'ex$' let value .= v elseif v =~# 'vh$' let value .= v elseif v =~# 'vw$' let value .= v elseif v =~# 'rem$' let value .= v elseif v ==# 'auto' let value .= v elseif v =~# 'p$' let value .= substitute(v, 'p$', '%', '') elseif v =~# '%$' let value .= v elseif v =~# 'e$' let value .= substitute(v, 'e$', 'em', '') elseif v =~# 'x$' let value .= substitute(v, 'x$', 'ex', '') elseif v =~# 're$' let value .= substitute(v, 're$', 'rem', '') elseif v =~# '\.' let value .= v . 'em' elseif v ==# '0' let value .= '0' else let value .= v . 'px' endif endfor endfor endif let tag_name = token if tag_name =~# '.!$' let tag_name = tag_name[:-2] let important = 1 else let important = 0 endif " make default node let current = emmet#newNode() let current.important = important let current.name = tag_name " aliases if has_key(aliases, tag_name) let current.name = aliases[tag_name] endif " snippets if !empty(snippets) let snippet_name = tag_name if !has_key(snippets, snippet_name) let pat = '^' . join(split(tag_name, '\zs'), '\%(\|[^:-]\+-\)') let vv = filter(sort(keys(snippets)), 'snippets[v:val] =~ pat') if len(vv) == 0 let vv = filter(sort(keys(snippets)), 'substitute(v:val, ":", "", "g") == snippet_name') endif if len(vv) > 0 let snippet_name = vv[0] else let pat = '^' . join(split(tag_name, '\zs'), '\%(\|[^:-]\+-*\)') let vv = filter(sort(keys(snippets)), 'snippets[v:val] =~ pat') if len(vv) == 0 let pat = '^' . join(split(tag_name, '\zs'), '[^:]\{-}') let vv = filter(sort(keys(snippets)), 'snippets[v:val] =~ pat') if len(vv) == 0 let pat = '^' . join(split(tag_name, '\zs'), '.\{-}') let vv = filter(sort(keys(snippets)), 'snippets[v:val] =~ pat') endif endif let minl = -1 for vk in vv let vvs = snippets[vk] if minl == -1 || len(vvs) < minl let snippet_name = vk let minl = len(vvs) endif endfor endif endif if has_key(snippets, snippet_name) let snippet = snippets[snippet_name] if use_pipe_for_cursor let snippet = substitute(snippet, '|', '${cursor}', 'g') endif let lines = split(snippet, "\n") call map(lines, 'substitute(v:val, "\\( \\|\\t\\)", escape(indent, "\\\\"), "g")') let current.snippet = join(lines, "\n") let current.name = '' let current.snippet = substitute(current.snippet, ';', value . ';', '') if use_pipe_for_cursor && len(value) > 0 let current.snippet = substitute(current.snippet, '\${cursor}', '', 'g') endif if n < len(tokens) - 1 let current.snippet .= "\n" endif endif endif let current.pos = 0 let lg = matchlist(token, '^\%(linear-gradient\|lg\)(\s*\(\S\+\)\s*,\s*\([^,]\+\)\s*,\s*\([^)]\+\)\s*)$') if len(lg) == 0 let lg = matchlist(token, '^\%(linear-gradient\|lg\)(\s*\(\S\+\)\s*,\s*\([^,]\+\)\s*)$') if len(lg) let [lg[1], lg[2], lg[3]] = ['linear', lg[1], lg[2]] endif endif if len(lg) let current.name = '' let current.snippet = printf("background-image:-webkit-gradient(%s, 0 0, 0 100%, from(%s), to(%s));\n", lg[1], lg[2], lg[3]) call add(root.child, deepcopy(current)) let current.snippet = printf("background-image:-webkit-linear-gradient(%s, %s);\n", lg[2], lg[3]) call add(root.child, deepcopy(current)) let current.snippet = printf("background-image:-moz-linear-gradient(%s, %s);\n", lg[2], lg[3]) call add(root.child, deepcopy(current)) let current.snippet = printf("background-image:-o-linear-gradient(%s, %s);\n", lg[2], lg[3]) call add(root.child, deepcopy(current)) let current.snippet = printf("background-image:linear-gradient(%s, %s);\n", lg[2], lg[3]) call add(root.child, deepcopy(current)) elseif prefix let snippet = current.snippet let current.snippet = '-webkit-' . snippet . "\n" call add(root.child, deepcopy(current)) let current.snippet = '-moz-' . snippet . "\n" call add(root.child, deepcopy(current)) let current.snippet = '-o-' . snippet . "\n" call add(root.child, deepcopy(current)) let current.snippet = '-ms-' . snippet . "\n" call add(root.child, deepcopy(current)) let current.snippet = snippet call add(root.child, current) elseif token =~# '^c#\([0-9a-fA-F]\{3}\|[0-9a-fA-F]\{6}\)\(\.[0-9]\+\)\?' let cs = split(token, '\.') let current.name = '' let [r,g,b] = [0,0,0] if len(cs[0]) == 5 let rgb = matchlist(cs[0], 'c#\(.\)\(.\)\(.\)') let r = eval('0x'.rgb[1].rgb[1]) let g = eval('0x'.rgb[2].rgb[2]) let b = eval('0x'.rgb[3].rgb[3]) elseif len(cs[0]) == 8 let rgb = matchlist(cs[0], 'c#\(..\)\(..\)\(..\)') let r = eval('0x'.rgb[1]) let g = eval('0x'.rgb[2]) let b = eval('0x'.rgb[3]) endif if len(cs) == 1 let current.snippet = printf('color:rgb(%d, %d, %d);', r, g, b) else let current.snippet = printf('color:rgb(%d, %d, %d, %s);', r, g, b, string(str2float('0.'.cs[1]))) endif call add(root.child, current) elseif token =~# '^c#' let current.name = '' let current.snippet = 'color:\${cursor};' call add(root.child, current) else call add(root.child, current) endif endfor endif return root endfunction function! emmet#lang#css#toString(settings, current, type, inline, filters, itemno, indent) abort let current = a:current let value = current.value[1:-2] let tmp = substitute(value, '\${cursor}', '', 'g') if tmp !~ '.*{[ \t\r\n]*}$' if emmet#useFilter(a:filters, 'fc') let value = substitute(value, '\([^:]\+\):\([^;]*\)', '\1: \2', 'g') else let value = substitute(value, '\([^:]\+\):\([^;]*\)', '\1:\2', 'g') endif if current.important let value = substitute(value, ';', ' !important;', '') endif endif return value endfunction function! emmet#lang#css#imageSize() abort let img_region = emmet#util#searchRegion('{', '}') if !emmet#util#regionIsValid(img_region) || !emmet#util#cursorInRegion(img_region) return endif let content = emmet#util#getContent(img_region) let fn = matchstr(content, '\') if len(node) exe "normal ciw\='/* '.node.' */'\" endif endif else if line =~# mx let space = substitute(matchstr(line, mx), mx, '\1', '') let line = substitute(matchstr(line, mx), mx, '\2', '') let line = space . substitute(line, '^\s*\|\s*$', '\1', 'g') else let mx = '^\(\s*\)\(''[^'']*''\|[^'']*\|;\)\s*$' " TODO multi-property "let mx = '^\(\s*\)\(\%(''[^'']*''\|[^'';]\+\)*;\{0,1}\)' let line = substitute(line, mx, '\1/* \2 */', '') endif call setline('.', line) endif endfunction function! emmet#lang#css#balanceTag(flag) range abort if a:flag == -2 || a:flag == 2 let curpos = [0, line("'<"), col("'<"), 0] else let curpos = emmet#util#getcurpos() endif let block = emmet#util#getVisualBlock() if !emmet#util#regionIsValid(block) if a:flag > 0 let block = emmet#util#searchRegion('^', ';') if emmet#util#regionIsValid(block) call emmet#util#selectRegion(block) return endif endif else if a:flag > 0 let content = emmet#util#getContent(block) if content !~# '^{.*}$' let block = emmet#util#searchRegion('{', '}') if emmet#util#regionIsValid(block) call emmet#util#selectRegion(block) return endif endif else let pos = searchpos('.*;', 'nW') if pos[0] != 0 call setpos('.', [0, pos[0], pos[1], 0]) let block = emmet#util#searchRegion('^', ';') if emmet#util#regionIsValid(block) call emmet#util#selectRegion(block) return endif endif endif endif if a:flag == -2 || a:flag == 2 silent! exe 'normal! gv' else call setpos('.', curpos) endif endfunction function! emmet#lang#css#moveNextPrevItem(flag) abort return emmet#lang#css#moveNextPrev(a:flag) endfunction function! emmet#lang#css#moveNextPrev(flag) abort call search('""\|()\|\(:\s*\zs;\{1,0}$\)', a:flag ? 'Wbp' : 'Wp') return '' endfunction function! emmet#lang#css#splitJoinTag() abort " nothing to do endfunction function! emmet#lang#css#removeTag() abort " nothing to do endfunction function! emmet#lang#css#mergeLines() abort " nothing to do endfunction