1 """"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""
\r
2 " CssPretty Todd Freed todd.freed@gmail.com
\r
5 " -------------------
\r
6 " Provides functionality to format text as css such that
\r
7 " each selector and declaration is on its own line
\r
10 " -------------------
\r
12 " The entire buffer is formatted as css text
\r
15 " The entire buffer is formatted as css text and returned
\r
16 " as a List of lines
\r
18 " CssPretty(start {, end, {[]}})
\r
19 " The section of the buffer starting on line {start} and
\r
20 " continuing to the end of the buffer, or until line {end}
\r
21 " will be formatted as css text. If the third parameter is
\r
22 " specified, then this is returned as a List of lines and
\r
23 " the buffer is not modified
\r
26 " The {text} parameter is formatted as css text and returned
\r
27 " as a List of lines
\r
29 """"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""
\r
31 " generates whitespace
\r
32 function! Whitespace(indent)
\r
35 return repeat(' ', a:indent * tabstop)
\r
38 " Trim whitespace from beginning and end of val. optionally include other
\r
39 " characters to trim from the beginning and end with 2nd and 3rd params
\r
40 function! Trim(val, ...)
\r
44 let startchars = a:000[0]
\r
47 let endchars = a:000[1]
\r
50 let start = "^[ \t" . startchars . "]*"
\r
51 let end = "[ \t" . endchars . "]*$"
\r
53 let val = substitute(a:val, start, '', '')
\r
54 let val = substitute(val, end, '', '')
\r
59 function! CssPretty(...)
\r
62 if(len(a:000) > 0 && type(a:000[0]) == type(''))
\r
65 let bufnum = bufnr("%")
\r
68 let lastline = len(getbufline(bufnum, 1, "$"))
\r
69 if len(a:000) > 0 && type(a:000[0]) == type(0)
\r
70 let firstline = a:000[0]
\r
72 if len(a:000) > 1 && type(a:000[1]) == type(0)
\r
73 let lastline = a:000[1]
\r
76 let linearray = getbufline(bufnum, firstline, lastline)
\r
78 " Get the buffer into one string
\r
79 for index in range(lastline - firstline + 1)
\r
80 let o = getline(index + firstline)
\r
85 " Generate indexes of all css declarations in the buffer
\r
86 let regex = "\\([^{]*\\){\\([^}]*\\)}"
\r
87 let match = {'start': 0, 'end': 0}
\r
88 let matches = [match]
\r
89 while match['start'] > -1
\r
90 call add(matches, match)
\r
92 let start = match(buf, regex, matches[-1]['end'])
\r
94 let rawmatch = matchlist(buf, regex, matches[-1]['end'])
\r
96 let end = start + len(rawmatch[0])
\r
97 let selector = Trim(rawmatch[1])
\r
98 let contents = Trim(rawmatch[2], '', ';')
\r
100 let declarations = []
\r
101 for o in split(contents, ';')
\r
102 let property = Trim(split(o, ':')[0])
\r
103 let value = Trim(split(o, ':')[1])
\r
105 call add(declarations, {'property': property, 'value': value})
\r
110 let match = {'start': start, 'end': end, 'len': end - start, 'selector': selector, 'declarations': declarations}
\r
113 " remove first entry - it was a dummy
\r
114 call remove(matches, 0, 1)
\r
116 " Generate array of new lines
\r
118 for x in range(len(matches))
\r
119 let match = matches[x]
\r
121 call add(lines, match['selector'])
\r
122 call add(lines, '{')
\r
123 for declaration in match['declarations']
\r
124 call add(lines, Whitespace(1) . declaration['property'] . ": " . declaration['value'] . ';')
\r
126 call add(lines, '}')
\r
129 " just return the lines if requested
\r
130 if len(a:000) > 2 || (len(a:000) > 0 && type(a:000[0]) == type([])) || (len(a:000) > 1 && type(a:000[1]) == type([]))
\r
132 " or if this function was invoked with a string as its first argument
\r
133 elseif len(a:000) > 0 && type(a:000[0]) == type('')
\r
137 " Otherwise, rewrite the buffer by first removing all lines from the buffer in the specified range, inclusive
\r
138 for x in range(lastline - firstline + 1)
\r
139 call setline(x+firstline, '')
\r
141 call cursor(lastline, 1)
\r
142 for x in range(lastline - firstline + 1)
\r
143 exe 'normal ' . "a\b\e"
\r
146 " and appending into the buffer
\r
147 let line = firstline - 1
\r
148 for x in range(len(lines))
\r
149 call append(line, lines[x])
\r
150 let line = line + 1
\r