1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305
|
" Vim syntax support file
" Maintainer: Bram Moolenaar <Bram@vim.org>
" Last Change: 2001 Dec 12
" (modified by David Ne\v{c}as (Yeti) <yeti@physics.muni.cz>)
" Transform a file into HTML, using the current syntax highlighting.
" Number lines when explicitely requested or when `number' is set
if exists("html_number_lines")
let s:numblines = html_number_lines
else
let s:numblines = &number
endif
" When not in gui we can only guess the colors.
if has("gui_running")
let s:whatterm = "gui"
else
let s:whatterm = "cterm"
if &t_Co == 8
let s:cterm_color0 = "#808080"
let s:cterm_color1 = "#ff6060"
let s:cterm_color2 = "#00ff00"
let s:cterm_color3 = "#ffff00"
let s:cterm_color4 = "#8080ff"
let s:cterm_color5 = "#ff40ff"
let s:cterm_color6 = "#00ffff"
let s:cterm_color7 = "#ffffff"
else
let s:cterm_color0 = "#000000"
let s:cterm_color1 = "#c00000"
let s:cterm_color2 = "#008000"
let s:cterm_color3 = "#804000"
let s:cterm_color4 = "#0000c0"
let s:cterm_color5 = "#c000c0"
let s:cterm_color6 = "#008080"
let s:cterm_color7 = "#c0c0c0"
let s:cterm_color8 = "#808080"
let s:cterm_color9 = "#ff6060"
let s:cterm_color10 = "#00ff00"
let s:cterm_color11 = "#ffff00"
let s:cterm_color12 = "#8080ff"
let s:cterm_color13 = "#ff40ff"
let s:cterm_color14 = "#00ffff"
let s:cterm_color15 = "#ffffff"
endif
endif
" Return good color specification: in GUI no transformation is done, in
" terminal return RGB values of known colors and empty string on unknown
if s:whatterm == "gui"
function! s:HtmlColor(color)
return a:color
endfun
else
function! s:HtmlColor(color)
if exists("s:cterm_color" . a:color)
execute "return s:cterm_color" . a:color
else
return ""
endif
endfun
endif
if !exists("html_use_css")
" Return opening HTML tag for given highlight id
function! s:HtmlOpening(id)
let a = ""
if synIDattr(a:id, "inverse")
" For inverse, we always must set both colors (and exchange them)
let x = s:HtmlColor(synIDattr(a:id, "fg#", s:whatterm))
let a = a . '<span style="background-color: ' . ( x != "" ? x : s:fgc ) . '">'
let x = s:HtmlColor(synIDattr(a:id, "bg#", s:whatterm))
let a = a . '<font color="' . ( x != "" ? x : s:bgc ) . '">'
else
let x = s:HtmlColor(synIDattr(a:id, "bg#", s:whatterm))
if x != "" | let a = a . '<span style="background-color: ' . x . '">' | endif
let x = s:HtmlColor(synIDattr(a:id, "fg#", s:whatterm))
if x != "" | let a = a . '<font color="' . x . '">' | endif
endif
if synIDattr(a:id, "bold") | let a = a . "<b>" | endif
if synIDattr(a:id, "italic") | let a = a . "<i>" | endif
if synIDattr(a:id, "underline") | let a = a . "<u>" | endif
return a
endfun
" Return closing HTML tag for given highlight id
function s:HtmlClosing(id)
let a = ""
if synIDattr(a:id, "underline") | let a = a . "</u>" | endif
if synIDattr(a:id, "italic") | let a = a . "</i>" | endif
if synIDattr(a:id, "bold") | let a = a . "</b>" | endif
if synIDattr(a:id, "inverse")
let a = a . '</font></span>'
else
let x = s:HtmlColor(synIDattr(a:id, "fg#", s:whatterm))
if x != "" | let a = a . '</font>' | endif
let x = s:HtmlColor(synIDattr(a:id, "bg#", s:whatterm))
if x != "" | let a = a . '</span>' | endif
endif
return a
endfun
endif
" Return CSS style describing given highlight id (can be empty)
function! s:CSS1(id)
let a = ""
if synIDattr(a:id, "inverse")
" For inverse, we always must set both colors (and exchange them)
let x = s:HtmlColor(synIDattr(a:id, "bg#", s:whatterm))
let a = a . "color: " . ( x != "" ? x : s:bgc ) . "; "
let x = s:HtmlColor(synIDattr(a:id, "fg#", s:whatterm))
let a = a . "background-color: " . ( x != "" ? x : s:fgc ) . "; "
else
let x = s:HtmlColor(synIDattr(a:id, "fg#", s:whatterm))
if x != "" | let a = a . "color: " . x . "; " | endif
let x = s:HtmlColor(synIDattr(a:id, "bg#", s:whatterm))
if x != "" | let a = a . "background-color: " . x . "; " | endif
endif
if synIDattr(a:id, "bold") | let a = a . "font-weight: bold; " | endif
if synIDattr(a:id, "italic") | let a = a . "font-style: italic; " | endif
if synIDattr(a:id, "underline") | let a = a . "text-decoration: underline; " | endif
return a
endfun
" Set some options to make it work faster.
" Expand tabs in original buffer to get 'tabstop' correctly used.
" Don't report changes for :substitute, there will be many of them.
let s:old_title = &title
let s:old_icon = &icon
let s:old_et = &l:et
let s:old_report = &report
set notitle noicon
setlocal et
set report=1000000
" Split window to create a buffer with the HTML file.
if expand("%") == ""
new Untitled.html
else
new %.html
endif
set modifiable
%d
let s:old_paste = &paste
set paste
" The DTD
if exists("html_use_css")
exe "normal a<!DOCTYPE HTML PUBLIC \"-//W3C//DTD HTML 4.01//EN\"\n \"http://www.w3.org/TR/html4/strict.dtd\">\n\e"
endif
" HTML header, with the title and generator ;-). Left free space for the CSS,
" to be filled at the end.
exe "normal a<html>\n<head>\n<title>\e"
exe "normal a" . expand("%:p:~") . "</title>\n\e"
exe "normal a<meta name=\"Generator\" content=\"Vim/" . version/100 . "." . version %100 . "\">\n\e"
if exists("html_use_css")
exe "normal a<style type=\"text/css\">\n<!--\n-->\n</style>\n\e"
endif
exe "normal a</head>\n<body>\n<pre>\n\e"
exe "normal \<C-W>p"
" List of all id's
let s:idlist = ","
" Loop over all lines in the original text
let s:end = line("$")
let s:lnum = 1
while s:lnum <= s:end
" Get the current line, with tabs expanded to spaces when needed
" FIXME: What if it changes syntax highlighting?
let s:line = getline(s:lnum)
if stridx(s:line, "\t") >= 0
exe s:lnum . "retab!"
let s:did_retab = 1
let s:line = getline(s:lnum)
else
let s:did_retab = 0
endif
let s:len = strlen(s:line)
let s:new = ""
if s:numblines
let s:new = '<span class="lnr">' . strpart(' ', 0, strlen(line("$")) - strlen(s:lnum)) . s:lnum . '</span> '
endif
" Loop over each character in the line
let s:col = 1
while s:col <= s:len
let s:startcol = s:col " The start column for processing text
let s:id = synID(s:lnum, s:col, 1)
let s:col = s:col + 1
" Speed loop (it's small - that's the trick)
" Go along till we find a change in synID
while s:col <= s:len && s:id == synID(s:lnum, s:col, 1) | let s:col = s:col + 1 | endwhile
" Output the text with the same synID, with class set to c{s:id}
let s:id = synIDtrans(s:id)
let s:new = s:new . '<span class="c' . s:id . '">' . substitute(substitute(substitute(substitute(substitute(strpart(s:line, s:startcol - 1, s:col - s:startcol), '&', '\&', 'g'), '<', '\<', 'g'), '>', '\>', 'g'), '"', '\"', 'g'), "\x0c", '<hr class="PAGE-BREAK">', 'g') . '</span>'
" Add the class to class list if it's not there yet
if stridx(s:idlist, "," . s:id . ",") == -1
let s:idlist = s:idlist . s:id . ","
endif
if s:col > s:len
break
endif
endwhile
if s:did_retab
undo
endif
exe "normal \<C-W>pa" . strtrans(s:new) . "\n\e\<C-W>p"
let s:lnum = s:lnum + 1
+
endwhile
" Finish with the last line
exe "normal \<C-W>pa</pre>\n</body>\n</html>\e"
" Now, when we finally know which, we define the colors and styles
if exists("html_use_css")
8
endif
" Find out the background and foreground color.
let s:fgc = s:HtmlColor(synIDattr(highlightID("Normal"), "fg#", s:whatterm))
let s:bgc = s:HtmlColor(synIDattr(highlightID("Normal"), "bg#", s:whatterm))
if s:fgc == ""
let s:fgc = ( &background == "dark" ? "#ffffff" : "#000000" )
endif
if s:bgc == ""
let s:bgc = ( &background == "dark" ? "#000000" : "#ffffff" )
endif
" Normal/global attributes
" For Netscape 4, set <body> attributes too, though, strictly speaking, it's
" incorrect.
if exists("html_use_css")
execute "normal A\npre { color: " . s:fgc . "; background-color: " . s:bgc . "; }\e"
yank
put
execute "normal ^cwbody\e"
else
execute '%s:<body>:<body ' . 'bgcolor="' . s:bgc . '" text="' . s:fgc . '">'
endif
" Line numbering attributes
if s:numblines
if exists("html_use_css")
execute "normal A\n.lnr { " . s:CSS1(highlightID("LineNr")) . "}\e"
else
execute '%s+<span class="lnr">\([^<]*\)</span>+' . s:HtmlOpening(highlightID("LineNr")) . '\1' . s:HtmlClosing(highlightID("LineNr")) . '+g'
endif
endif
" Gather attributes for all other classes
let s:idlist = strpart(s:idlist, 1)
while s:idlist != ""
let s:attr = ""
let s:col = stridx(s:idlist, ",")
let s:id = strpart(s:idlist, 0, s:col)
let s:idlist = strpart(s:idlist, s:col + 1)
let s:attr = s:CSS1(s:id)
" If the class has some attributes, export the style, otherwise DELETE all
" its occurences to make the HTML shorter
if s:attr != ""
if exists("html_use_css")
execute "normal A\n.c" . s:id . " { " . s:attr . "}"
else
execute '%s+<span class="c' . s:id . '">\([^<]*\)</span>+' . s:HtmlOpening(s:id) . '\1' . s:HtmlClosing(s:id) . '+g'
endif
else
execute '%s+<span class="c' . s:id . '">\([^<]*\)</span>+\1+g'
8
endif
endwhile
" Cleanup (we've already lost last user's pattern match highlighting)
%s:\s\+$::e
if has("extra_search")
nohlsearch
endif
" Restore old settings
let &report = s:old_report
let &title = s:old_title
let &icon = s:old_icon
let &paste = s:old_paste
exe "normal \<C-W>p"
let &l:et = s:old_et
exe "normal \<C-W>p"
" Save a little bit of memory (worths doing?)
unlet s:old_et s:old_paste s:old_icon s:old_report s:old_title
unlet s:whatterm s:idlist s:lnum s:end s:fgc s:bgc
unlet! s:col s:id s:attr s:len s:line s:new s:did_retab s:numblines
delfunc s:HtmlColor
delfunc s:CSS1
if !exists("html_use_css")
delfunc s:HtmlOpening
delfunc s:HtmlClosing
endif
|