From ae2d88eed8ce9cff5087591c788b1b07e3b41ff8 Mon Sep 17 00:00:00 2001 From: mattn Date: Wed, 30 May 2012 20:17:19 +0900 Subject: [PATCH] imageSize for slim --- autoload/zencoding.vim | 86 +++----------------------------- autoload/zencoding/lang/html.vim | 50 +++++++++++++++++++ autoload/zencoding/lang/slim.vim | 48 +++++++++++++++++- autoload/zencoding/util.vim | 29 +++++++++++ 4 files changed, 134 insertions(+), 79 deletions(-) diff --git a/autoload/zencoding.vim b/autoload/zencoding.vim index 2815ddc..0ac59c9 100644 --- a/autoload/zencoding.vim +++ b/autoload/zencoding.vim @@ -54,27 +54,6 @@ function! zencoding#parseIntoTree(abbr, type) return zencoding#lang#{rtype}#parseIntoTree(abbr, type) endfunction -function! s:parseTag(tag) - let current = { 'name': '', 'attr': {}, 'child': [], 'snippet': '', 'multiplier': 1, 'parent': {}, 'value': '', 'pos': 0 } - let mx = '<\([a-zA-Z][a-zA-Z0-9]*\)\(\%(\s[a-zA-Z][a-zA-Z0-9]\+=\%([^"'' \t]\+\|"[^"]\{-}"\|''[^'']\{-}''\)\s*\)*\)\(/\{0,1}\)>' - let match = matchstr(a:tag, mx) - let current.name = substitute(match, mx, '\1', 'i') - let attrs = substitute(match, mx, '\2', 'i') - let mx = '\([a-zA-Z0-9]\+\)=\%(\([^"'' \t]\+\)\|"\([^"]\{-}\)"\|''\([^'']\{-}\)''\)' - while len(attrs) > 0 - let match = matchstr(attrs, mx) - if len(match) == 0 - break - endif - let attr_match = matchlist(match, mx) - let name = attr_match[1] - let value = len(attr_match[2]) ? attr_match[2] : attr_match[3] - let current.attr[name] = value - let attrs = attrs[stridx(attrs, match) + len(match):] - endwhile - return current -endfunction - function! s:mergeConfig(lhs, rhs) if type(a:lhs) == 3 && type(a:rhs) == 3 let a:lhs += a:rhs @@ -431,58 +410,9 @@ function! zencoding#moveNextPrev(flag) endif endfunction -function! zencoding#getImageSize(fn) - let fn = a:fn - if filereadable(fn) - let hex = substitute(system('xxd -p "'.fn.'"'), '\n', '', 'g') - else - let hex = substitute(system(g:zencoding_curl_command.' "'.fn.'" | xxd -p'), '\n', '', 'g') - endif - - let [type, width, height] = ['', -1, -1] - if hex =~ '^89504e470d0a1a0a' - let type = 'png' - let width = eval('0x'.hex[32:39]) - let height = eval('0x'.hex[40:47]) - endif - if hex =~ '^ffd8' - let pos = match(hex, 'ffc[02]') - let type = 'jpg' - let height = eval('0x'.hex[pos+10:pos+11])*256 + eval('0x'.hex[pos+12:pos+13]) - let width = eval('0x'.hex[pos+14:pos+15])*256 + eval('0x'.hex[pos+16:pos+17]) - endif - if hex =~ '^47494638' - let type = 'gif' - let width = eval('0x'.hex[14:15].hex[12:13]) - let height = eval('0x'.hex[18:19].hex[16:17]) - endif - - return [width, height] -endfunction - function! zencoding#imageSize() - let img_region = zencoding#util#search_region('') - if !zencoding#util#region_is_valid(img_region) || !zencoding#util#cursor_in_region(img_region) - return - endif - let content = zencoding#util#get_content(img_region) - if content !~ '^<]\+>$' - return - endif - let current = s:parseTag(content) - let fn = current.attr.src - if fn !~ '^\(/\|http\)' - let fn = simplify(expand('%:h') . '/' . fn) - endif - - let [width, height] = zencoding#getImageSize(fn) - if width == -1 && height == -1 - return - endif - let current.attr.width = width - let current.attr.height = height - let html = zencoding#toString(current, 'html', 1) - call zencoding#util#change_content(img_region, html) + let rtype = len(globpath(&rtp, 'autoload/zencoding/lang/'.&ft.'.vim')) ? &ft : 'html' + return zencoding#lang#{rtype}#imageSize() endfunction function! zencoding#toggleComment() @@ -747,7 +677,7 @@ function! zencoding#anchorizeURL(flag) let title = matchstr(content, mx) if a:flag == 0 - let a = s:parseTag('') + let a = zencoding#lang#html#parseTag('') let a.attr.href = url let a.value = '{' . title . '}' let expand = zencoding#toString(a, 'html', 0, []) @@ -756,16 +686,16 @@ function! zencoding#anchorizeURL(flag) let body = zencoding#util#get_text_from_html(content) let body = '{' . substitute(body, '^\(.\{0,100}\).*', '\1', '') . '...}' - let blockquote = s:parseTag('
') - let a = s:parseTag('') + let blockquote = zencoding#lang#html#parseTag('
') + let a = zencoding#lang#html#parseTag('') let a.attr.href = url let a.value = '{' . title . '}' call add(blockquote.child, a) - call add(blockquote.child, s:parseTag('
')) - let p = s:parseTag('

') + call add(blockquote.child, zencoding#lang#html#parseTag('
')) + let p = zencoding#lang#html#parseTag('

') let p.value = body call add(blockquote.child, p) - let cite = s:parseTag('') + let cite = zencoding#lang#html#parseTag('') let cite.value = '{' . url . '}' call add(blockquote.child, cite) let expand = zencoding#toString(blockquote, 'html', 0, []) diff --git a/autoload/zencoding/lang/html.vim b/autoload/zencoding/lang/html.vim index e9b0856..c0e321b 100644 --- a/autoload/zencoding/lang/html.vim +++ b/autoload/zencoding/lang/html.vim @@ -382,3 +382,53 @@ function! zencoding#lang#html#toString(settings, current, type, inline, filters, endif return str endfunction + +function! zencoding#lang#html#imageSize() + let img_region = zencoding#util#search_region('') + if !zencoding#util#region_is_valid(img_region) || !zencoding#util#cursor_in_region(img_region) + return + endif + let content = zencoding#util#get_content(img_region) + if content !~ '^<]\+>$' + return + endif + let current = zencoding#lang#html#parseTag(content) + if empty(current) || !has_key(current.attr, 'src') + return + endif + let fn = current.attr.src + if fn !~ '^\(/\|http\)' + let fn = simplify(expand('%:h') . '/' . fn) + endif + + let [width, height] = zencoding#util#getImageSize(fn) + if width == -1 && height == -1 + return + endif + let current.attr.width = width + let current.attr.height = height + let html = zencoding#toString(current, 'html', 1) + call zencoding#util#change_content(img_region, html) +endfunction + +function! zencoding#lang#html#parseTag(tag) + let current = { 'name': '', 'attr': {}, 'child': [], 'snippet': '', 'multiplier': 1, 'parent': {}, 'value': '', 'pos': 0 } + let mx = '<\([a-zA-Z][a-zA-Z0-9]*\)\(\%(\s[a-zA-Z][a-zA-Z0-9]\+=\%([^"'' \t]\+\|"[^"]\{-}"\|''[^'']\{-}''\)\s*\)*\)\(/\{0,1}\)>' + let match = matchstr(a:tag, mx) + let current.name = substitute(match, mx, '\1', 'i') + let attrs = substitute(match, mx, '\2', 'i') + let mx = '\([a-zA-Z0-9]\+\)=\%(\([^"'' \t]\+\)\|"\([^"]\{-}\)"\|''\([^'']\{-}\)''\)' + while len(attrs) > 0 + let match = matchstr(attrs, mx) + if len(match) == 0 + break + endif + let attr_match = matchlist(match, mx) + let name = attr_match[1] + let value = len(attr_match[2]) ? attr_match[2] : attr_match[3] + let current.attr[name] = value + let attrs = attrs[stridx(attrs, match) + len(match):] + endwhile + return current +endfunction + diff --git a/autoload/zencoding/lang/slim.vim b/autoload/zencoding/lang/slim.vim index b6d6c95..c9cc151 100644 --- a/autoload/zencoding/lang/slim.vim +++ b/autoload/zencoding/lang/slim.vim @@ -28,7 +28,11 @@ function! zencoding#lang#slim#toString(settings, current, type, inline, filters, let val = substitute(val, '\(\$\+\)\([^{]\|$\)', '\=printf("%0".len(submatch(1))."d", itemno+1).submatch(2)', 'g') endwhile let attr = substitute(attr, '\$$', itemno+1, '') - let str .= ' ' . attr . '="' . val . '"' + if val =~ '\s' + let str .= ' ' . attr . '="' . val . '"' + else + let str .= ' ' . attr . '=' . val + endif endfor let inner = '' @@ -57,3 +61,45 @@ function! zencoding#lang#slim#toString(settings, current, type, inline, filters, endif return str endfunction + +function! zencoding#lang#slim#imageSize() + let line = getline('.') + let current = zencoding#lang#slim#parseTag(line) + if empty(current) || !has_key(current.attr, 'src') + return + endif + let fn = current.attr.src + if fn !~ '^\(/\|http\)' + let fn = simplify(expand('%:h') . '/' . fn) + endif + + let [width, height] = zencoding#util#getImageSize(fn) + if width == -1 && height == -1 + return + endif + let current.attr.width = width + let current.attr.height = height + let slim = zencoding#toString(current, 'slim', 1) + call setline('.', substitute(matchstr(line, '^\s*') . slim, "\n", "", "g")) +endfunction + +function! zencoding#lang#slim#parseTag(tag) + let current = { 'name': '', 'attr': {}, 'child': [], 'snippet': '', 'multiplier': 1, 'parent': {}, 'value': '', 'pos': 0 } + let mx = '\([a-zA-Z][a-zA-Z0-9]*\)\s\+\(.*\)' + let match = matchstr(a:tag, mx) + let current.name = substitute(match, mx, '\1', 'i') + let attrs = substitute(match, mx, '\2', 'i') + let mx = '\([a-zA-Z0-9]\+\)=\%(\([^"'' \t]\+\)\|"\([^"]\{-}\)"\|''\([^'']\{-}\)''\)' + while len(attrs) > 0 + let match = matchstr(attrs, mx) + if len(match) == 0 + break + endif + let attr_match = matchlist(match, mx) + let name = attr_match[1] + let value = len(attr_match[2]) ? attr_match[2] : attr_match[3] + let current.attr[name] = value + let attrs = attrs[stridx(attrs, match) + len(match):] + endwhile + return current +endfunction diff --git a/autoload/zencoding/util.vim b/autoload/zencoding/util.vim index 3432554..fc5ebfd 100644 --- a/autoload/zencoding/util.vim +++ b/autoload/zencoding/util.vim @@ -193,3 +193,32 @@ function! zencoding#util#get_text_from_html(buf) return res endfunction +function! zencoding#util#getImageSize(fn) + let fn = a:fn + if filereadable(fn) + let hex = substitute(system('xxd -p "'.fn.'"'), '\n', '', 'g') + else + let hex = substitute(system(g:zencoding_curl_command.' "'.fn.'" | xxd -p'), '\n', '', 'g') + endif + + let [type, width, height] = ['', -1, -1] + if hex =~ '^89504e470d0a1a0a' + let type = 'png' + let width = eval('0x'.hex[32:39]) + let height = eval('0x'.hex[40:47]) + endif + if hex =~ '^ffd8' + let pos = match(hex, 'ffc[02]') + let type = 'jpg' + let height = eval('0x'.hex[pos+10:pos+11])*256 + eval('0x'.hex[pos+12:pos+13]) + let width = eval('0x'.hex[pos+14:pos+15])*256 + eval('0x'.hex[pos+16:pos+17]) + endif + if hex =~ '^47494638' + let type = 'gif' + let width = eval('0x'.hex[14:15].hex[12:13]) + let height = eval('0x'.hex[18:19].hex[16:17]) + endif + + return [width, height] +endfunction +