1071d4279SBram Moolenaar" Vim syntax support file 2349b2fb0SBram Moolenaar" Maintainer: Ben Fritz <[email protected]> 3*bebca9daSBram Moolenaar" Last Change: 2010 Aug 07 4349b2fb0SBram Moolenaar" 5349b2fb0SBram Moolenaar" Additional contributors: 6349b2fb0SBram Moolenaar" 7349b2fb0SBram Moolenaar" Original by Bram Moolenaar <[email protected]> 8349b2fb0SBram Moolenaar" Modified by David Ne\v{c}as (Yeti) <[email protected]> 9349b2fb0SBram Moolenaar" XHTML support by Panagiotis Issaris <[email protected]> 10349b2fb0SBram Moolenaar" Made w3 compliant by Edd Barrett <[email protected]> 11349b2fb0SBram Moolenaar" Added html_font. Edd Barrett <[email protected]> 12349b2fb0SBram Moolenaar" Progress bar based off code from "progressbar widget" plugin by 13349b2fb0SBram Moolenaar" Andreas Politz, heavily modified: 14349b2fb0SBram Moolenaar" http://www.vim.org/scripts/script.php?script_id=2006 15349b2fb0SBram Moolenaar" 16349b2fb0SBram Moolenaar" See Mercurial change logs for more! 17071d4279SBram Moolenaar 18071d4279SBram Moolenaar" Transform a file into HTML, using the current syntax highlighting. 19071d4279SBram Moolenaar 205c73622aSBram Moolenaar" this file uses line continuations 215c73622aSBram Moolenaarlet s:cpo_sav = &cpo 22349b2fb0SBram Moolenaarlet s:ls = &ls 235c73622aSBram Moolenaarset cpo-=C 245c73622aSBram Moolenaar 25349b2fb0SBram Moolenaarlet s:end=line('$') 26349b2fb0SBram Moolenaar 27313b7237SBram Moolenaar" Font 28b02cbe34SBram Moolenaarif exists("g:html_font") 29076e8b2aSBram Moolenaar let s:htmlfont = "'". g:html_font . "', monospace" 30313b7237SBram Moolenaarelse 31313b7237SBram Moolenaar let s:htmlfont = "monospace" 32313b7237SBram Moolenaarendif 33313b7237SBram Moolenaar 34076e8b2aSBram Moolenaarlet s:settings = tohtml#GetUserSettings() 355c73622aSBram Moolenaar 36071d4279SBram Moolenaar" When not in gui we can only guess the colors. 37071d4279SBram Moolenaarif has("gui_running") 38071d4279SBram Moolenaar let s:whatterm = "gui" 39071d4279SBram Moolenaarelse 40071d4279SBram Moolenaar let s:whatterm = "cterm" 41071d4279SBram Moolenaar if &t_Co == 8 42313b7237SBram Moolenaar let s:cterm_color = {0: "#808080", 1: "#ff6060", 2: "#00ff00", 3: "#ffff00", 4: "#8080ff", 5: "#ff40ff", 6: "#00ffff", 7: "#ffffff"} 43071d4279SBram Moolenaar else 44313b7237SBram Moolenaar let s:cterm_color = {0: "#000000", 1: "#c00000", 2: "#008000", 3: "#804000", 4: "#0000c0", 5: "#c000c0", 6: "#008080", 7: "#c0c0c0", 8: "#808080", 9: "#ff6060", 10: "#00ff00", 11: "#ffff00", 12: "#8080ff", 13: "#ff40ff", 14: "#00ffff", 15: "#ffffff"} 45313b7237SBram Moolenaar 46313b7237SBram Moolenaar " Colors for 88 and 256 come from xterm. 47313b7237SBram Moolenaar if &t_Co == 88 48313b7237SBram Moolenaar call extend(s:cterm_color, {16: "#000000", 17: "#00008b", 18: "#0000cd", 19: "#0000ff", 20: "#008b00", 21: "#008b8b", 22: "#008bcd", 23: "#008bff", 24: "#00cd00", 25: "#00cd8b", 26: "#00cdcd", 27: "#00cdff", 28: "#00ff00", 29: "#00ff8b", 30: "#00ffcd", 31: "#00ffff", 32: "#8b0000", 33: "#8b008b", 34: "#8b00cd", 35: "#8b00ff", 36: "#8b8b00", 37: "#8b8b8b", 38: "#8b8bcd", 39: "#8b8bff", 40: "#8bcd00", 41: "#8bcd8b", 42: "#8bcdcd", 43: "#8bcdff", 44: "#8bff00", 45: "#8bff8b", 46: "#8bffcd", 47: "#8bffff", 48: "#cd0000", 49: "#cd008b", 50: "#cd00cd", 51: "#cd00ff", 52: "#cd8b00", 53: "#cd8b8b", 54: "#cd8bcd", 55: "#cd8bff", 56: "#cdcd00", 57: "#cdcd8b", 58: "#cdcdcd", 59: "#cdcdff", 60: "#cdff00", 61: "#cdff8b", 62: "#cdffcd", 63: "#cdffff", 64: "#ff0000"}) 49313b7237SBram Moolenaar call extend(s:cterm_color, {65: "#ff008b", 66: "#ff00cd", 67: "#ff00ff", 68: "#ff8b00", 69: "#ff8b8b", 70: "#ff8bcd", 71: "#ff8bff", 72: "#ffcd00", 73: "#ffcd8b", 74: "#ffcdcd", 75: "#ffcdff", 76: "#ffff00", 77: "#ffff8b", 78: "#ffffcd", 79: "#ffffff", 80: "#2e2e2e", 81: "#5c5c5c", 82: "#737373", 83: "#8b8b8b", 84: "#a2a2a2", 85: "#b9b9b9", 86: "#d0d0d0", 87: "#e7e7e7"}) 50313b7237SBram Moolenaar elseif &t_Co == 256 51313b7237SBram Moolenaar call extend(s:cterm_color, {16: "#000000", 17: "#00005f", 18: "#000087", 19: "#0000af", 20: "#0000d7", 21: "#0000ff", 22: "#005f00", 23: "#005f5f", 24: "#005f87", 25: "#005faf", 26: "#005fd7", 27: "#005fff", 28: "#008700", 29: "#00875f", 30: "#008787", 31: "#0087af", 32: "#0087d7", 33: "#0087ff", 34: "#00af00", 35: "#00af5f", 36: "#00af87", 37: "#00afaf", 38: "#00afd7", 39: "#00afff", 40: "#00d700", 41: "#00d75f", 42: "#00d787", 43: "#00d7af", 44: "#00d7d7", 45: "#00d7ff", 46: "#00ff00", 47: "#00ff5f", 48: "#00ff87", 49: "#00ffaf", 50: "#00ffd7", 51: "#00ffff", 52: "#5f0000", 53: "#5f005f", 54: "#5f0087", 55: "#5f00af", 56: "#5f00d7", 57: "#5f00ff", 58: "#5f5f00", 59: "#5f5f5f", 60: "#5f5f87", 61: "#5f5faf", 62: "#5f5fd7", 63: "#5f5fff", 64: "#5f8700"}) 52313b7237SBram Moolenaar call extend(s:cterm_color, {65: "#5f875f", 66: "#5f8787", 67: "#5f87af", 68: "#5f87d7", 69: "#5f87ff", 70: "#5faf00", 71: "#5faf5f", 72: "#5faf87", 73: "#5fafaf", 74: "#5fafd7", 75: "#5fafff", 76: "#5fd700", 77: "#5fd75f", 78: "#5fd787", 79: "#5fd7af", 80: "#5fd7d7", 81: "#5fd7ff", 82: "#5fff00", 83: "#5fff5f", 84: "#5fff87", 85: "#5fffaf", 86: "#5fffd7", 87: "#5fffff", 88: "#870000", 89: "#87005f", 90: "#870087", 91: "#8700af", 92: "#8700d7", 93: "#8700ff", 94: "#875f00", 95: "#875f5f", 96: "#875f87", 97: "#875faf", 98: "#875fd7", 99: "#875fff", 100: "#878700", 101: "#87875f", 102: "#878787", 103: "#8787af", 104: "#8787d7", 105: "#8787ff", 106: "#87af00", 107: "#87af5f", 108: "#87af87", 109: "#87afaf", 110: "#87afd7", 111: "#87afff", 112: "#87d700"}) 53313b7237SBram Moolenaar call extend(s:cterm_color, {113: "#87d75f", 114: "#87d787", 115: "#87d7af", 116: "#87d7d7", 117: "#87d7ff", 118: "#87ff00", 119: "#87ff5f", 120: "#87ff87", 121: "#87ffaf", 122: "#87ffd7", 123: "#87ffff", 124: "#af0000", 125: "#af005f", 126: "#af0087", 127: "#af00af", 128: "#af00d7", 129: "#af00ff", 130: "#af5f00", 131: "#af5f5f", 132: "#af5f87", 133: "#af5faf", 134: "#af5fd7", 135: "#af5fff", 136: "#af8700", 137: "#af875f", 138: "#af8787", 139: "#af87af", 140: "#af87d7", 141: "#af87ff", 142: "#afaf00", 143: "#afaf5f", 144: "#afaf87", 145: "#afafaf", 146: "#afafd7", 147: "#afafff", 148: "#afd700", 149: "#afd75f", 150: "#afd787", 151: "#afd7af", 152: "#afd7d7", 153: "#afd7ff", 154: "#afff00", 155: "#afff5f", 156: "#afff87", 157: "#afffaf", 158: "#afffd7"}) 54313b7237SBram Moolenaar call extend(s:cterm_color, {159: "#afffff", 160: "#d70000", 161: "#d7005f", 162: "#d70087", 163: "#d700af", 164: "#d700d7", 165: "#d700ff", 166: "#d75f00", 167: "#d75f5f", 168: "#d75f87", 169: "#d75faf", 170: "#d75fd7", 171: "#d75fff", 172: "#d78700", 173: "#d7875f", 174: "#d78787", 175: "#d787af", 176: "#d787d7", 177: "#d787ff", 178: "#d7af00", 179: "#d7af5f", 180: "#d7af87", 181: "#d7afaf", 182: "#d7afd7", 183: "#d7afff", 184: "#d7d700", 185: "#d7d75f", 186: "#d7d787", 187: "#d7d7af", 188: "#d7d7d7", 189: "#d7d7ff", 190: "#d7ff00", 191: "#d7ff5f", 192: "#d7ff87", 193: "#d7ffaf", 194: "#d7ffd7", 195: "#d7ffff", 196: "#ff0000", 197: "#ff005f", 198: "#ff0087", 199: "#ff00af", 200: "#ff00d7", 201: "#ff00ff", 202: "#ff5f00", 203: "#ff5f5f", 204: "#ff5f87"}) 55313b7237SBram Moolenaar call extend(s:cterm_color, {205: "#ff5faf", 206: "#ff5fd7", 207: "#ff5fff", 208: "#ff8700", 209: "#ff875f", 210: "#ff8787", 211: "#ff87af", 212: "#ff87d7", 213: "#ff87ff", 214: "#ffaf00", 215: "#ffaf5f", 216: "#ffaf87", 217: "#ffafaf", 218: "#ffafd7", 219: "#ffafff", 220: "#ffd700", 221: "#ffd75f", 222: "#ffd787", 223: "#ffd7af", 224: "#ffd7d7", 225: "#ffd7ff", 226: "#ffff00", 227: "#ffff5f", 228: "#ffff87", 229: "#ffffaf", 230: "#ffffd7", 231: "#ffffff", 232: "#080808", 233: "#121212", 234: "#1c1c1c", 235: "#262626", 236: "#303030", 237: "#3a3a3a", 238: "#444444", 239: "#4e4e4e", 240: "#585858", 241: "#626262", 242: "#6c6c6c", 243: "#767676", 244: "#808080", 245: "#8a8a8a", 246: "#949494", 247: "#9e9e9e", 248: "#a8a8a8", 249: "#b2b2b2", 250: "#bcbcbc", 251: "#c6c6c6", 252: "#d0d0d0", 253: "#dadada", 254: "#e4e4e4", 255: "#eeeeee"}) 56313b7237SBram Moolenaar endif 57071d4279SBram Moolenaar endif 58071d4279SBram Moolenaarendif 59071d4279SBram Moolenaar 60071d4279SBram Moolenaar" Return good color specification: in GUI no transformation is done, in 61313b7237SBram Moolenaar" terminal return RGB values of known colors and empty string for unknown 62071d4279SBram Moolenaarif s:whatterm == "gui" 63071d4279SBram Moolenaar function! s:HtmlColor(color) 64071d4279SBram Moolenaar return a:color 65071d4279SBram Moolenaar endfun 66071d4279SBram Moolenaarelse 67071d4279SBram Moolenaar function! s:HtmlColor(color) 68313b7237SBram Moolenaar if has_key(s:cterm_color, a:color) 69313b7237SBram Moolenaar return s:cterm_color[a:color] 70071d4279SBram Moolenaar else 71071d4279SBram Moolenaar return "" 72071d4279SBram Moolenaar endif 73071d4279SBram Moolenaar endfun 74071d4279SBram Moolenaarendif 75071d4279SBram Moolenaar 76*bebca9daSBram Moolenaarif !s:settings.use_css 77071d4279SBram Moolenaar " Return opening HTML tag for given highlight id 78071d4279SBram Moolenaar function! s:HtmlOpening(id) 79071d4279SBram Moolenaar let a = "" 80071d4279SBram Moolenaar if synIDattr(a:id, "inverse") 81071d4279SBram Moolenaar " For inverse, we always must set both colors (and exchange them) 82071d4279SBram Moolenaar let x = s:HtmlColor(synIDattr(a:id, "fg#", s:whatterm)) 83071d4279SBram Moolenaar let a = a . '<span style="background-color: ' . ( x != "" ? x : s:fgc ) . '">' 84071d4279SBram Moolenaar let x = s:HtmlColor(synIDattr(a:id, "bg#", s:whatterm)) 85071d4279SBram Moolenaar let a = a . '<font color="' . ( x != "" ? x : s:bgc ) . '">' 86071d4279SBram Moolenaar else 87071d4279SBram Moolenaar let x = s:HtmlColor(synIDattr(a:id, "bg#", s:whatterm)) 88071d4279SBram Moolenaar if x != "" | let a = a . '<span style="background-color: ' . x . '">' | endif 89071d4279SBram Moolenaar let x = s:HtmlColor(synIDattr(a:id, "fg#", s:whatterm)) 90071d4279SBram Moolenaar if x != "" | let a = a . '<font color="' . x . '">' | endif 91071d4279SBram Moolenaar endif 92071d4279SBram Moolenaar if synIDattr(a:id, "bold") | let a = a . "<b>" | endif 93071d4279SBram Moolenaar if synIDattr(a:id, "italic") | let a = a . "<i>" | endif 94071d4279SBram Moolenaar if synIDattr(a:id, "underline") | let a = a . "<u>" | endif 95071d4279SBram Moolenaar return a 96071d4279SBram Moolenaar endfun 97071d4279SBram Moolenaar 98071d4279SBram Moolenaar " Return closing HTML tag for given highlight id 99349b2fb0SBram Moolenaar function! s:HtmlClosing(id) 100071d4279SBram Moolenaar let a = "" 101071d4279SBram Moolenaar if synIDattr(a:id, "underline") | let a = a . "</u>" | endif 102071d4279SBram Moolenaar if synIDattr(a:id, "italic") | let a = a . "</i>" | endif 103071d4279SBram Moolenaar if synIDattr(a:id, "bold") | let a = a . "</b>" | endif 104071d4279SBram Moolenaar if synIDattr(a:id, "inverse") 105071d4279SBram Moolenaar let a = a . '</font></span>' 106071d4279SBram Moolenaar else 107071d4279SBram Moolenaar let x = s:HtmlColor(synIDattr(a:id, "fg#", s:whatterm)) 108071d4279SBram Moolenaar if x != "" | let a = a . '</font>' | endif 109071d4279SBram Moolenaar let x = s:HtmlColor(synIDattr(a:id, "bg#", s:whatterm)) 110071d4279SBram Moolenaar if x != "" | let a = a . '</span>' | endif 111071d4279SBram Moolenaar endif 112071d4279SBram Moolenaar return a 113071d4279SBram Moolenaar endfun 114071d4279SBram Moolenaarendif 115071d4279SBram Moolenaar 11635a9aaabSBram Moolenaar" Return HTML valid characters enclosed in a span of class style_name with 11735a9aaabSBram Moolenaar" unprintable characters expanded and double spaces replaced as necessary. 1188ada2ccaSBram Moolenaarfunction! s:HtmlFormat(text, style_name, diff_style_name) 11935a9aaabSBram Moolenaar " Replace unprintable characters 12035a9aaabSBram Moolenaar let formatted = strtrans(a:text) 12135a9aaabSBram Moolenaar 1228ada2ccaSBram Moolenaar " separate the two classes by a space to apply them both if there is a diff 1238ada2ccaSBram Moolenaar " style name 1248ada2ccaSBram Moolenaar let l:style_name = a:style_name . (a:diff_style_name == '' ? '' : ' ') . a:diff_style_name 1258ada2ccaSBram Moolenaar 12635a9aaabSBram Moolenaar " Replace the reserved html characters 12735a9aaabSBram Moolenaar let formatted = substitute(substitute(substitute(substitute(substitute(formatted, '&', '\&', 'g'), '<', '\<', 'g'), '>', '\>', 'g'), '"', '\"', 'g'), "\x0c", '<hr class="PAGE-BREAK">', 'g') 12835a9aaabSBram Moolenaar 1298424a624SBram Moolenaar " Replace double spaces and leading spaces 13035a9aaabSBram Moolenaar if ' ' != s:HtmlSpace 13135a9aaabSBram Moolenaar let formatted = substitute(formatted, ' ', s:HtmlSpace . s:HtmlSpace, 'g') 1328424a624SBram Moolenaar let formatted = substitute(formatted, '^ ', s:HtmlSpace, 'g') 13335a9aaabSBram Moolenaar endif 13435a9aaabSBram Moolenaar 13535a9aaabSBram Moolenaar " Enclose in a span of class style_name 1368ada2ccaSBram Moolenaar let formatted = '<span class="' . l:style_name . '">' . formatted . '</span>' 13735a9aaabSBram Moolenaar 1388ada2ccaSBram Moolenaar " Add the class to class list if it's not there yet. 1398ada2ccaSBram Moolenaar " Add normal groups to the beginning so diff groups can override them. 14035a9aaabSBram Moolenaar let s:id = hlID(a:style_name) 1418ada2ccaSBram Moolenaar if index(s:idlist, s:id ) == -1 1428ada2ccaSBram Moolenaar if a:style_name =~ 'Diff\%(Add\|Change\|Delete\|Text\)' 1438ada2ccaSBram Moolenaar call add(s:idlist, s:id) 1448ada2ccaSBram Moolenaar else 1458ada2ccaSBram Moolenaar call insert(s:idlist, s:id) 1468ada2ccaSBram Moolenaar endif 1478ada2ccaSBram Moolenaar endif 1488ada2ccaSBram Moolenaar 1498ada2ccaSBram Moolenaar " Add the diff highlight class to class list if used and it's not there yet. 1508ada2ccaSBram Moolenaar " Add diff groups to the end so they override the other highlighting. 1518ada2ccaSBram Moolenaar if a:diff_style_name != "" 1528ada2ccaSBram Moolenaar let s:diff_id = hlID(a:diff_style_name) 1538ada2ccaSBram Moolenaar if index(s:idlist, s:diff_id) == -1 1548ada2ccaSBram Moolenaar call add(s:idlist, s:diff_id) 1558ada2ccaSBram Moolenaar endif 15635a9aaabSBram Moolenaar endif 15735a9aaabSBram Moolenaar 15835a9aaabSBram Moolenaar return formatted 15935a9aaabSBram Moolenaarendfun 16035a9aaabSBram Moolenaar 161071d4279SBram Moolenaar" Return CSS style describing given highlight id (can be empty) 162071d4279SBram Moolenaarfunction! s:CSS1(id) 163071d4279SBram Moolenaar let a = "" 164071d4279SBram Moolenaar if synIDattr(a:id, "inverse") 165071d4279SBram Moolenaar " For inverse, we always must set both colors (and exchange them) 166071d4279SBram Moolenaar let x = s:HtmlColor(synIDattr(a:id, "bg#", s:whatterm)) 167071d4279SBram Moolenaar let a = a . "color: " . ( x != "" ? x : s:bgc ) . "; " 168071d4279SBram Moolenaar let x = s:HtmlColor(synIDattr(a:id, "fg#", s:whatterm)) 169071d4279SBram Moolenaar let a = a . "background-color: " . ( x != "" ? x : s:fgc ) . "; " 170071d4279SBram Moolenaar else 171071d4279SBram Moolenaar let x = s:HtmlColor(synIDattr(a:id, "fg#", s:whatterm)) 172071d4279SBram Moolenaar if x != "" | let a = a . "color: " . x . "; " | endif 173071d4279SBram Moolenaar let x = s:HtmlColor(synIDattr(a:id, "bg#", s:whatterm)) 174071d4279SBram Moolenaar if x != "" | let a = a . "background-color: " . x . "; " | endif 175071d4279SBram Moolenaar endif 176071d4279SBram Moolenaar if synIDattr(a:id, "bold") | let a = a . "font-weight: bold; " | endif 177071d4279SBram Moolenaar if synIDattr(a:id, "italic") | let a = a . "font-style: italic; " | endif 178071d4279SBram Moolenaar if synIDattr(a:id, "underline") | let a = a . "text-decoration: underline; " | endif 179071d4279SBram Moolenaar return a 180071d4279SBram Moolenaarendfun 181071d4279SBram Moolenaar 182076e8b2aSBram Moolenaarif s:settings.dynamic_folds 1835c73622aSBram Moolenaar " compares two folds as stored in our list of folds 1845c73622aSBram Moolenaar " A fold is "less" than another if it starts at an earlier line number, 1855c73622aSBram Moolenaar " or ends at a later line number, ties broken by fold level 1865c73622aSBram Moolenaar function! s:FoldCompare(f1, f2) 1875c73622aSBram Moolenaar if a:f1.firstline != a:f2.firstline 1885c73622aSBram Moolenaar " put it before if it starts earlier 1895c73622aSBram Moolenaar return a:f1.firstline - a:f2.firstline 1905c73622aSBram Moolenaar elseif a:f1.lastline != a:f2.lastline 1915c73622aSBram Moolenaar " put it before if it ends later 1925c73622aSBram Moolenaar return a:f2.lastline - a:f1.lastline 1935c73622aSBram Moolenaar else 1945c73622aSBram Moolenaar " if folds begin and end on the same lines, put lowest fold level first 1955c73622aSBram Moolenaar return a:f1.level - a:f2.level 1965c73622aSBram Moolenaar endif 1975c73622aSBram Moolenaar endfunction 1985c73622aSBram Moolenaar 1995c73622aSBram Moolenaarendif 2005c73622aSBram Moolenaar 201071d4279SBram Moolenaar 202071d4279SBram Moolenaar" Set some options to make it work faster. 203071d4279SBram Moolenaar" Don't report changes for :substitute, there will be many of them. 204071d4279SBram Moolenaarlet s:old_title = &title 205071d4279SBram Moolenaarlet s:old_icon = &icon 206071d4279SBram Moolenaarlet s:old_et = &l:et 207071d4279SBram Moolenaarlet s:old_report = &report 208071d4279SBram Moolenaarlet s:old_search = @/ 209349b2fb0SBram Moolenaarlet s:old_more = &more 210071d4279SBram Moolenaarset notitle noicon 211071d4279SBram Moolenaarsetlocal et 212349b2fb0SBram Moolenaarset nomore 213071d4279SBram Moolenaarset report=1000000 214071d4279SBram Moolenaar 2157510fe74SBram Moolenaarif exists(':ownsyntax') && exists('w:current_syntax') 2167510fe74SBram Moolenaar let s:current_syntax = w:current_syntax 2177510fe74SBram Moolenaarelseif exists('b:current_syntax') 2187510fe74SBram Moolenaar let s:current_syntax = b:current_syntax 2197510fe74SBram Moolenaarelse 2207510fe74SBram Moolenaar let s:current_syntax = 'none' 2217510fe74SBram Moolenaarendif 2227510fe74SBram Moolenaar 2237510fe74SBram Moolenaarif s:current_syntax == '' 2247510fe74SBram Moolenaar let s:current_syntax = 'none' 2257510fe74SBram Moolenaarendif 2267510fe74SBram Moolenaar 227071d4279SBram Moolenaar" Split window to create a buffer with the HTML file. 228071d4279SBram Moolenaarlet s:orgbufnr = winbufnr(0) 229349b2fb0SBram Moolenaarlet s:origwin_stl = &l:stl 230071d4279SBram Moolenaarif expand("%") == "" 231076e8b2aSBram Moolenaar exec 'new Untitled.'.(s:settings.use_xhtml ? 'x' : '').'html' 232071d4279SBram Moolenaarelse 233076e8b2aSBram Moolenaar exec 'new %.'.(s:settings.use_xhtml ? 'x' : '').'html' 234071d4279SBram Moolenaarendif 235349b2fb0SBram Moolenaar 236349b2fb0SBram Moolenaar" Resize the new window to very small in order to make it draw faster 237349b2fb0SBram Moolenaarlet s:old_winheight = winheight(0) 238349b2fb0SBram Moolenaarlet s:old_winfixheight = &l:winfixheight 239349b2fb0SBram Moolenaarif s:old_winheight > 2 240349b2fb0SBram Moolenaar resize 1 " leave enough room to view one line at a time 241349b2fb0SBram Moolenaar norm! G 242349b2fb0SBram Moolenaar norm! zt 243349b2fb0SBram Moolenaarendif 244349b2fb0SBram Moolenaarsetlocal winfixheight 245349b2fb0SBram Moolenaar 246349b2fb0SBram Moolenaarlet s:newwin_stl = &l:stl 247349b2fb0SBram Moolenaar 248349b2fb0SBram Moolenaar" on the new window, set the least time-consuming fold method 249349b2fb0SBram Moolenaarlet s:old_fdm = &foldmethod 250349b2fb0SBram Moolenaarsetlocal foldmethod=manual 251349b2fb0SBram Moolenaar 252071d4279SBram Moolenaarlet s:newwin = winnr() 253071d4279SBram Moolenaarlet s:orgwin = bufwinnr(s:orgbufnr) 254071d4279SBram Moolenaar 255349b2fb0SBram Moolenaarsetlocal modifiable 256071d4279SBram Moolenaar%d 257071d4279SBram Moolenaarlet s:old_paste = &paste 258071d4279SBram Moolenaarset paste 259071d4279SBram Moolenaarlet s:old_magic = &magic 260071d4279SBram Moolenaarset magic 261071d4279SBram Moolenaar 262349b2fb0SBram Moolenaarlet s:lines = [] 263349b2fb0SBram Moolenaar 264076e8b2aSBram Moolenaarif s:settings.use_xhtml 265*bebca9daSBram Moolenaar if s:settings.encoding != "" 266*bebca9daSBram Moolenaar call add(s:lines, "<?xml version=\"1.0\" encoding=\"" . s:settings.encoding . "\"?>") 2671cd871b5SBram Moolenaar else 268349b2fb0SBram Moolenaar call add(s:lines, "<?xml version=\"1.0\"?>") 2691cd871b5SBram Moolenaar endif 27035a9aaabSBram Moolenaar let s:tag_close = ' />' 271071d4279SBram Moolenaarelse 27235a9aaabSBram Moolenaar let s:tag_close = '>' 27335a9aaabSBram Moolenaarendif 27435a9aaabSBram Moolenaar 27535a9aaabSBram Moolenaarlet s:HtmlSpace = ' ' 276c1e37901SBram Moolenaarlet s:LeadingSpace = ' ' 27735a9aaabSBram Moolenaarlet s:HtmlEndline = '' 278076e8b2aSBram Moolenaarif s:settings.no_pre 27935a9aaabSBram Moolenaar let s:HtmlEndline = '<br' . s:tag_close 280c1e37901SBram Moolenaar let s:LeadingSpace = ' ' 281c1e37901SBram Moolenaar let s:HtmlSpace = '\' . s:LeadingSpace 282071d4279SBram Moolenaarendif 283071d4279SBram Moolenaar 284071d4279SBram Moolenaar" HTML header, with the title and generator ;-). Left free space for the CSS, 285071d4279SBram Moolenaar" to be filled at the end. 286349b2fb0SBram Moolenaarcall extend(s:lines, [ 287349b2fb0SBram Moolenaar \ "<html>", 288*bebca9daSBram Moolenaar \ "<head>"]) 289*bebca9daSBram Moolenaar" include encoding as close to the top as possible, but only if not already 290*bebca9daSBram Moolenaar" contained in XML information (to avoid haggling over content type) 291*bebca9daSBram Moolenaarif s:settings.encoding != "" && !s:settings.use_xhtml 292*bebca9daSBram Moolenaar call add(s:lines, "<meta http-equiv=\"content-type\" content=\"text/html; charset=" . s:settings.encoding . '"' . s:tag_close) 293*bebca9daSBram Moolenaarendif 294*bebca9daSBram Moolenaarcall extend(s:lines, [ 295349b2fb0SBram Moolenaar \ ("<title>".expand("%:p:~")."</title>"), 296349b2fb0SBram Moolenaar \ ("<meta name=\"Generator\" content=\"Vim/".v:version/100.".".v:version%100.'"'.s:tag_close), 297*bebca9daSBram Moolenaar \ ("<meta name=\"plugin-version\" content=\"".g:loaded_2html_plugin.'"'.s:tag_close) 298349b2fb0SBram Moolenaar \ ]) 2997510fe74SBram Moolenaarcall add(s:lines, '<meta name="syntax" content="'.s:current_syntax.'"'.s:tag_close) 300076e8b2aSBram Moolenaarcall add(s:lines, '<meta name="settings" content="'. 301076e8b2aSBram Moolenaar \ join(filter(keys(s:settings),'s:settings[v:val]'),','). 302076e8b2aSBram Moolenaar \ '"'.s:tag_close) 303313b7237SBram Moolenaar 304076e8b2aSBram Moolenaarif s:settings.use_css 305076e8b2aSBram Moolenaar if s:settings.dynamic_folds 306076e8b2aSBram Moolenaar if s:settings.hover_unfold 3075c73622aSBram Moolenaar " if we are doing hover_unfold, use css 2 with css 1 fallback for IE6 308349b2fb0SBram Moolenaar call extend(s:lines, [ 309349b2fb0SBram Moolenaar \ "<style type=\"text/css\">", 310*bebca9daSBram Moolenaar \ s:settings.use_xhtml ? "" : "<!--", 311349b2fb0SBram Moolenaar \ ".FoldColumn { text-decoration: none; white-space: pre; }", 312349b2fb0SBram Moolenaar \ "", 313349b2fb0SBram Moolenaar \ "body * { margin: 0; padding: 0; }", "", 314349b2fb0SBram Moolenaar \ ".open-fold > .Folded { display: none; }", 315349b2fb0SBram Moolenaar \ ".open-fold > .fulltext { display: inline; }", 316349b2fb0SBram Moolenaar \ ".closed-fold > .fulltext { display: none; }", 317349b2fb0SBram Moolenaar \ ".closed-fold > .Folded { display: inline; }", 318349b2fb0SBram Moolenaar \ "", 319349b2fb0SBram Moolenaar \ ".open-fold > .toggle-open { display: none; }", 320349b2fb0SBram Moolenaar \ ".open-fold > .toggle-closed { display: inline; }", 321349b2fb0SBram Moolenaar \ ".closed-fold > .toggle-open { display: inline; }", 322349b2fb0SBram Moolenaar \ ".closed-fold > .toggle-closed { display: none; }", 323349b2fb0SBram Moolenaar \ "", "", 324349b2fb0SBram Moolenaar \ '/* opening a fold while hovering won''t be supported by IE6 and other', 325349b2fb0SBram Moolenaar \ "similar browsers, but it should fail gracefully. */", 326349b2fb0SBram Moolenaar \ ".closed-fold:hover > .fulltext { display: inline; }", 327349b2fb0SBram Moolenaar \ ".closed-fold:hover > .toggle-filler { display: none; }", 328349b2fb0SBram Moolenaar \ ".closed-fold:hover > .Folded { display: none; }", 329*bebca9daSBram Moolenaar \ s:settings.use_xhtml ? "" : '-->', 330*bebca9daSBram Moolenaar \ '<style>']) 331*bebca9daSBram Moolenaar " TODO: IE7 doesn't *actually* support XHTML, maybe we should remove this. 332*bebca9daSBram Moolenaar " But if it's served up as tag soup, maybe the following will work, so 333*bebca9daSBram Moolenaar " leave it in for now. 334*bebca9daSBram Moolenaar call extend(s:lines, [ 335349b2fb0SBram Moolenaar \ "<!--[if lt IE 7]><style type=\"text/css\">", 336349b2fb0SBram Moolenaar \ ".open-fold .Folded { display: none; }", 337349b2fb0SBram Moolenaar \ ".open-fold .fulltext { display: inline; }", 338349b2fb0SBram Moolenaar \ ".open-fold .toggle-open { display: none; }", 339349b2fb0SBram Moolenaar \ ".closed-fold .toggle-closed { display: inline; }", 340349b2fb0SBram Moolenaar \ "", 341349b2fb0SBram Moolenaar \ ".closed-fold .fulltext { display: none; }", 342349b2fb0SBram Moolenaar \ ".closed-fold .Folded { display: inline; }", 343349b2fb0SBram Moolenaar \ ".closed-fold .toggle-open { display: inline; }", 344349b2fb0SBram Moolenaar \ ".closed-fold .toggle-closed { display: none; }", 345349b2fb0SBram Moolenaar \ "</style>", 346349b2fb0SBram Moolenaar \ "<![endif]-->", 347349b2fb0SBram Moolenaar \]) 3485c73622aSBram Moolenaar else 3495c73622aSBram Moolenaar " if we aren't doing hover_unfold, use CSS 1 only 350349b2fb0SBram Moolenaar call extend(s:lines, [ 351349b2fb0SBram Moolenaar \ "<style type=\"text/css\">", 352*bebca9daSBram Moolenaar \ s:settings.use_xhtml ? "" :"<!--", 353349b2fb0SBram Moolenaar \ ".FoldColumn { text-decoration: none; white-space: pre; }", 354349b2fb0SBram Moolenaar \ ".open-fold .Folded { display: none; }", 355349b2fb0SBram Moolenaar \ ".open-fold .fulltext { display: inline; }", 356349b2fb0SBram Moolenaar \ ".open-fold .toggle-open { display: none; }", 357349b2fb0SBram Moolenaar \ ".closed-fold .toggle-closed { display: inline; }", 358349b2fb0SBram Moolenaar \ "", 359349b2fb0SBram Moolenaar \ ".closed-fold .fulltext { display: none; }", 360349b2fb0SBram Moolenaar \ ".closed-fold .Folded { display: inline; }", 361349b2fb0SBram Moolenaar \ ".closed-fold .toggle-open { display: inline; }", 362349b2fb0SBram Moolenaar \ ".closed-fold .toggle-closed { display: none; }", 363*bebca9daSBram Moolenaar \ s:settings.use_xhtml ? "" : '-->', 364349b2fb0SBram Moolenaar \ '</style>' 365349b2fb0SBram Moolenaar \]) 3665c73622aSBram Moolenaar endif 3675c73622aSBram Moolenaar else 3685c73622aSBram Moolenaar " if we aren't doing any dynamic folding, no need for any special rules 369349b2fb0SBram Moolenaar call extend(s:lines, [ 370349b2fb0SBram Moolenaar \ "<style type=\"text/css\">", 371*bebca9daSBram Moolenaar \ s:settings.use_xhtml ? "" : "<!--", 372*bebca9daSBram Moolenaar \ s:settings.use_xhtml ? "" : '-->', 373349b2fb0SBram Moolenaar \ "</style>", 374349b2fb0SBram Moolenaar \]) 375071d4279SBram Moolenaar endif 3765c73622aSBram Moolenaarendif 3775c73622aSBram Moolenaar 3785c73622aSBram Moolenaar" insert javascript to toggle folds open and closed 379076e8b2aSBram Moolenaarif s:settings.dynamic_folds 380349b2fb0SBram Moolenaar call extend(s:lines, [ 381349b2fb0SBram Moolenaar \ "", 382349b2fb0SBram Moolenaar \ "<script type='text/javascript'>", 383*bebca9daSBram Moolenaar \ s:settings.use_xhtml ? '//<![CDATA[' : "<!--", 384349b2fb0SBram Moolenaar \ "function toggleFold(objID)", 385349b2fb0SBram Moolenaar \ "{", 386349b2fb0SBram Moolenaar \ " var fold;", 387349b2fb0SBram Moolenaar \ " fold = document.getElementById(objID);", 388349b2fb0SBram Moolenaar \ " if(fold.className == 'closed-fold')", 389349b2fb0SBram Moolenaar \ " {", 390349b2fb0SBram Moolenaar \ " fold.className = 'open-fold';", 391349b2fb0SBram Moolenaar \ " }", 392349b2fb0SBram Moolenaar \ " else if (fold.className == 'open-fold')", 393349b2fb0SBram Moolenaar \ " {", 394349b2fb0SBram Moolenaar \ " fold.className = 'closed-fold';", 395349b2fb0SBram Moolenaar \ " }", 396349b2fb0SBram Moolenaar \ "}", 397*bebca9daSBram Moolenaar \ s:settings.use_xhtml ? '//]]>' : '-->', 398349b2fb0SBram Moolenaar \ "</script>" 399349b2fb0SBram Moolenaar \]) 4005c73622aSBram Moolenaarendif 4015c73622aSBram Moolenaar 402076e8b2aSBram Moolenaarif s:settings.no_pre 403349b2fb0SBram Moolenaar call extend(s:lines, ["</head>", "<body>"]) 404071d4279SBram Moolenaarelse 405349b2fb0SBram Moolenaar call extend(s:lines, ["</head>", "<body>", "<pre>"]) 406071d4279SBram Moolenaarendif 407071d4279SBram Moolenaar 408071d4279SBram Moolenaarexe s:orgwin . "wincmd w" 409071d4279SBram Moolenaar 410071d4279SBram Moolenaar" List of all id's 4118ada2ccaSBram Moolenaarlet s:idlist = [] 412071d4279SBram Moolenaar 413349b2fb0SBram Moolenaar" set up progress bar in the status line 414076e8b2aSBram Moolenaarif !s:settings.no_progress 415349b2fb0SBram Moolenaar " ProgressBar Indicator 416349b2fb0SBram Moolenaar let s:progressbar={} 417349b2fb0SBram Moolenaar 418349b2fb0SBram Moolenaar " Progessbar specific functions 419349b2fb0SBram Moolenaar func! s:ProgressBar(title, max_value, winnr) 420349b2fb0SBram Moolenaar let pgb=copy(s:progressbar) 421349b2fb0SBram Moolenaar let pgb.title = a:title.' ' 422349b2fb0SBram Moolenaar let pgb.max_value = a:max_value 423349b2fb0SBram Moolenaar let pgb.winnr = a:winnr 424349b2fb0SBram Moolenaar let pgb.cur_value = 0 425349b2fb0SBram Moolenaar let pgb.items = { 'title' : { 'color' : 'Statusline' }, 426349b2fb0SBram Moolenaar \'bar' : { 'color' : 'Statusline' , 'fillcolor' : 'DiffDelete' , 'bg' : 'Statusline' } , 427349b2fb0SBram Moolenaar \'counter' : { 'color' : 'Statusline' } } 428349b2fb0SBram Moolenaar let pgb.last_value = 0 429349b2fb0SBram Moolenaar let pgb.needs_redraw = 0 430349b2fb0SBram Moolenaar " Note that you must use len(split) instead of len() if you want to use 431349b2fb0SBram Moolenaar " unicode in title. 432349b2fb0SBram Moolenaar " 433349b2fb0SBram Moolenaar " Subtract 3 for spacing around the title. 434349b2fb0SBram Moolenaar " Subtract 4 for the percentage display. 435349b2fb0SBram Moolenaar " Subtract 2 for spacing before this. 436349b2fb0SBram Moolenaar " Subtract 2 more for the '|' on either side of the progress bar 437349b2fb0SBram Moolenaar let pgb.subtractedlen=len(split(pgb.title, '\zs'))+3+4+2+2 438349b2fb0SBram Moolenaar let pgb.max_len = 0 439349b2fb0SBram Moolenaar set laststatus=2 440349b2fb0SBram Moolenaar return pgb 441349b2fb0SBram Moolenaar endfun 442349b2fb0SBram Moolenaar 443349b2fb0SBram Moolenaar " Function: progressbar.calculate_ticks() {{{1 444349b2fb0SBram Moolenaar func! s:progressbar.calculate_ticks(pb_len) 445349b2fb0SBram Moolenaar if a:pb_len<=0 446349b2fb0SBram Moolenaar let pb_len = 100 447349b2fb0SBram Moolenaar else 448349b2fb0SBram Moolenaar let pb_len = a:pb_len 449349b2fb0SBram Moolenaar endif 450349b2fb0SBram Moolenaar let self.progress_ticks = map(range(pb_len+1), "v:val * self.max_value / pb_len") 451349b2fb0SBram Moolenaar endfun 452349b2fb0SBram Moolenaar 453349b2fb0SBram Moolenaar "Function: progressbar.paint() 454349b2fb0SBram Moolenaar func! s:progressbar.paint() 455349b2fb0SBram Moolenaar " Recalculate widths. 456349b2fb0SBram Moolenaar let max_len = winwidth(self.winnr) 457349b2fb0SBram Moolenaar let pb_len = 0 458349b2fb0SBram Moolenaar " always true on first call because of initial value of self.max_len 459349b2fb0SBram Moolenaar if max_len != self.max_len 460349b2fb0SBram Moolenaar let self.max_len = max_len 461349b2fb0SBram Moolenaar 462349b2fb0SBram Moolenaar " Progressbar length 463349b2fb0SBram Moolenaar let pb_len = max_len - self.subtractedlen 464349b2fb0SBram Moolenaar 465349b2fb0SBram Moolenaar call self.calculate_ticks(pb_len) 466349b2fb0SBram Moolenaar 467349b2fb0SBram Moolenaar let self.needs_redraw = 1 468349b2fb0SBram Moolenaar let cur_value = 0 469349b2fb0SBram Moolenaar let self.pb_len = pb_len 470349b2fb0SBram Moolenaar else 471349b2fb0SBram Moolenaar " start searching at the last found index to make the search for the 472349b2fb0SBram Moolenaar " appropriate tick value normally take 0 or 1 comparisons 473349b2fb0SBram Moolenaar let cur_value = self.last_value 474349b2fb0SBram Moolenaar let pb_len = self.pb_len 475349b2fb0SBram Moolenaar endif 476349b2fb0SBram Moolenaar 477349b2fb0SBram Moolenaar let cur_val_max = pb_len > 0 ? pb_len : 100 478349b2fb0SBram Moolenaar 479349b2fb0SBram Moolenaar " find the current progress bar position based on precalculated thresholds 480349b2fb0SBram Moolenaar while cur_value < cur_val_max && self.cur_value > self.progress_ticks[cur_value] 481349b2fb0SBram Moolenaar let cur_value += 1 482349b2fb0SBram Moolenaar endwhile 483349b2fb0SBram Moolenaar 484349b2fb0SBram Moolenaar " update progress bar 485349b2fb0SBram Moolenaar if self.last_value != cur_value || self.needs_redraw || self.cur_value == self.max_value 486349b2fb0SBram Moolenaar let self.needs_redraw = 1 487349b2fb0SBram Moolenaar let self.last_value = cur_value 488349b2fb0SBram Moolenaar 489349b2fb0SBram Moolenaar let t_color = self.items.title.color 490349b2fb0SBram Moolenaar let b_fcolor = self.items.bar.fillcolor 491349b2fb0SBram Moolenaar let b_color = self.items.bar.color 492349b2fb0SBram Moolenaar let c_color = self.items.counter.color 493349b2fb0SBram Moolenaar 494349b2fb0SBram Moolenaar let stl = "%#".t_color."#%-( ".self.title." %)". 495349b2fb0SBram Moolenaar \"%#".b_color."#". 496349b2fb0SBram Moolenaar \(pb_len>0 ? 497349b2fb0SBram Moolenaar \ ('|%#'.b_fcolor."#%-(".repeat(" ",cur_value)."%)". 498349b2fb0SBram Moolenaar \ '%#'.b_color."#".repeat(" ",pb_len-cur_value)."|"): 499349b2fb0SBram Moolenaar \ ('')). 500349b2fb0SBram Moolenaar \"%=%#".c_color."#%( ".printf("%3.d ",100*self.cur_value/self.max_value)."%% %)" 501349b2fb0SBram Moolenaar call setwinvar(self.winnr, '&stl', stl) 502349b2fb0SBram Moolenaar endif 503349b2fb0SBram Moolenaar endfun 504349b2fb0SBram Moolenaar 505349b2fb0SBram Moolenaar func! s:progressbar.incr( ... ) 506349b2fb0SBram Moolenaar let self.cur_value += (a:0 ? a:1 : 1) 507349b2fb0SBram Moolenaar " if we were making a general-purpose progress bar, we'd need to limit to a 508349b2fb0SBram Moolenaar " lower limit as well, but since we always increment with a positive value 509349b2fb0SBram Moolenaar " in this script, we only need limit the upper value 510349b2fb0SBram Moolenaar let self.cur_value = (self.cur_value > self.max_value ? self.max_value : self.cur_value) 511349b2fb0SBram Moolenaar call self.paint() 512349b2fb0SBram Moolenaar endfun 513349b2fb0SBram Moolenaar " }}} 514076e8b2aSBram Moolenaar if s:settings.dynamic_folds 515349b2fb0SBram Moolenaar " to process folds we make two passes through each line 516349b2fb0SBram Moolenaar let s:pgb = s:ProgressBar("Processing folds:", line('$')*2, s:orgwin) 517349b2fb0SBram Moolenaar endif 518349b2fb0SBram Moolenaarendif 519349b2fb0SBram Moolenaar 5205c73622aSBram Moolenaar" First do some preprocessing for dynamic folding. Do this for the entire file 5215c73622aSBram Moolenaar" so we don't accidentally start within a closed fold or something. 5225c73622aSBram Moolenaarlet s:allfolds = [] 5235c73622aSBram Moolenaar 524076e8b2aSBram Moolenaarif s:settings.dynamic_folds 5255c73622aSBram Moolenaar let s:lnum = 1 5265c73622aSBram Moolenaar let s:end = line('$') 5275c73622aSBram Moolenaar " save the fold text and set it to the default so we can find fold levels 5285c73622aSBram Moolenaar let s:foldtext_save = &foldtext 529349b2fb0SBram Moolenaar setlocal foldtext& 5305c73622aSBram Moolenaar 5315c73622aSBram Moolenaar " we will set the foldcolumn in the html to the greater of the maximum fold 5325c73622aSBram Moolenaar " level and the current foldcolumn setting 5335c73622aSBram Moolenaar let s:foldcolumn = &foldcolumn 5345c73622aSBram Moolenaar 5355c73622aSBram Moolenaar " get all info needed to describe currently closed folds 536349b2fb0SBram Moolenaar while s:lnum <= s:end 5375c73622aSBram Moolenaar if foldclosed(s:lnum) == s:lnum 5385c73622aSBram Moolenaar " default fold text has '+-' and then a number of dashes equal to fold 5395c73622aSBram Moolenaar " level, so subtract 2 from index of first non-dash after the dashes 5405c73622aSBram Moolenaar " in order to get the fold level of the current fold 5415c73622aSBram Moolenaar let s:level = match(foldtextresult(s:lnum), '+-*\zs[^-]') - 2 5425c73622aSBram Moolenaar if s:level+1 > s:foldcolumn 5435c73622aSBram Moolenaar let s:foldcolumn = s:level+1 5445c73622aSBram Moolenaar endif 5455c73622aSBram Moolenaar " store fold info for later use 5465c73622aSBram Moolenaar let s:newfold = {'firstline': s:lnum, 'lastline': foldclosedend(s:lnum), 'level': s:level,'type': "closed-fold"} 5475c73622aSBram Moolenaar call add(s:allfolds, s:newfold) 5485c73622aSBram Moolenaar " open the fold so we can find any contained folds 5495c73622aSBram Moolenaar execute s:lnum."foldopen" 5505c73622aSBram Moolenaar else 551076e8b2aSBram Moolenaar if !s:settings.no_progress 552349b2fb0SBram Moolenaar call s:pgb.incr() 553349b2fb0SBram Moolenaar if s:pgb.needs_redraw 554349b2fb0SBram Moolenaar redrawstatus 555349b2fb0SBram Moolenaar let s:pgb.needs_redraw = 0 556349b2fb0SBram Moolenaar endif 557349b2fb0SBram Moolenaar endif 5585c73622aSBram Moolenaar let s:lnum = s:lnum + 1 5595c73622aSBram Moolenaar endif 5605c73622aSBram Moolenaar endwhile 5615c73622aSBram Moolenaar 5625c73622aSBram Moolenaar " close all folds to get info for originally open folds 5635c73622aSBram Moolenaar silent! %foldclose! 5645c73622aSBram Moolenaar let s:lnum = 1 5655c73622aSBram Moolenaar 5665c73622aSBram Moolenaar " the originally open folds will be all folds we encounter that aren't 5675c73622aSBram Moolenaar " already in the list of closed folds 568349b2fb0SBram Moolenaar while s:lnum <= s:end 5695c73622aSBram Moolenaar if foldclosed(s:lnum) == s:lnum 5705c73622aSBram Moolenaar " default fold text has '+-' and then a number of dashes equal to fold 5715c73622aSBram Moolenaar " level, so subtract 2 from index of first non-dash after the dashes 5725c73622aSBram Moolenaar " in order to get the fold level of the current fold 5735c73622aSBram Moolenaar let s:level = match(foldtextresult(s:lnum), '+-*\zs[^-]') - 2 5745c73622aSBram Moolenaar if s:level+1 > s:foldcolumn 5755c73622aSBram Moolenaar let s:foldcolumn = s:level+1 5765c73622aSBram Moolenaar endif 5775c73622aSBram Moolenaar let s:newfold = {'firstline': s:lnum, 'lastline': foldclosedend(s:lnum), 'level': s:level,'type': "closed-fold"} 5785c73622aSBram Moolenaar " only add the fold if we don't already have it 5795c73622aSBram Moolenaar if empty(s:allfolds) || index(s:allfolds, s:newfold) == -1 5805c73622aSBram Moolenaar let s:newfold.type = "open-fold" 5815c73622aSBram Moolenaar call add(s:allfolds, s:newfold) 5825c73622aSBram Moolenaar endif 5835c73622aSBram Moolenaar " open the fold so we can find any contained folds 5845c73622aSBram Moolenaar execute s:lnum."foldopen" 5855c73622aSBram Moolenaar else 586076e8b2aSBram Moolenaar if !s:settings.no_progress 587349b2fb0SBram Moolenaar call s:pgb.incr() 588349b2fb0SBram Moolenaar if s:pgb.needs_redraw 589349b2fb0SBram Moolenaar redrawstatus 590349b2fb0SBram Moolenaar let s:pgb.needs_redraw = 0 591349b2fb0SBram Moolenaar endif 592349b2fb0SBram Moolenaar endif 5935c73622aSBram Moolenaar let s:lnum = s:lnum + 1 5945c73622aSBram Moolenaar endif 5955c73622aSBram Moolenaar endwhile 5965c73622aSBram Moolenaar 5975c73622aSBram Moolenaar " sort the folds so that we only ever need to look at the first item in the 5985c73622aSBram Moolenaar " list of folds 5995c73622aSBram Moolenaar call sort(s:allfolds, "s:FoldCompare") 6005c73622aSBram Moolenaar 601349b2fb0SBram Moolenaar let &l:foldtext = s:foldtext_save 6025c73622aSBram Moolenaar unlet s:foldtext_save 6035c73622aSBram Moolenaar 6045c73622aSBram Moolenaar " close all folds again so we can get the fold text as we go 6055c73622aSBram Moolenaar silent! %foldclose! 6065c73622aSBram Moolenaarendif 6075c73622aSBram Moolenaar 6085c73622aSBram Moolenaar" Now loop over all lines in the original text to convert to html. 609071d4279SBram Moolenaar" Use html_start_line and html_end_line if they are set. 610b02cbe34SBram Moolenaarif exists("g:html_start_line") 611071d4279SBram Moolenaar let s:lnum = html_start_line 612071d4279SBram Moolenaar if s:lnum < 1 || s:lnum > line("$") 613071d4279SBram Moolenaar let s:lnum = 1 614071d4279SBram Moolenaar endif 615071d4279SBram Moolenaarelse 616071d4279SBram Moolenaar let s:lnum = 1 617071d4279SBram Moolenaarendif 618b02cbe34SBram Moolenaarif exists("g:html_end_line") 619071d4279SBram Moolenaar let s:end = html_end_line 620071d4279SBram Moolenaar if s:end < s:lnum || s:end > line("$") 621071d4279SBram Moolenaar let s:end = line("$") 622071d4279SBram Moolenaar endif 623071d4279SBram Moolenaarelse 624071d4279SBram Moolenaar let s:end = line("$") 625071d4279SBram Moolenaarendif 626071d4279SBram Moolenaar 6275c73622aSBram Moolenaar" stack to keep track of all the folds containing the current line 6285c73622aSBram Moolenaarlet s:foldstack = [] 6295c73622aSBram Moolenaar 630076e8b2aSBram Moolenaarif !s:settings.no_progress 631349b2fb0SBram Moolenaar let s:pgb = s:ProgressBar("Processing lines:", s:end - s:lnum + 1, s:orgwin) 632349b2fb0SBram Moolenaarendif 633349b2fb0SBram Moolenaar 634076e8b2aSBram Moolenaarif s:settings.number_lines 6355c73622aSBram Moolenaar let s:margin = strlen(s:end) + 1 6365c73622aSBram Moolenaarelse 6375c73622aSBram Moolenaar let s:margin = 0 6385c73622aSBram Moolenaarendif 6395c73622aSBram Moolenaar 640076e8b2aSBram Moolenaarif has('folding') && !s:settings.ignore_folding 64135a9aaabSBram Moolenaar let s:foldfillchar = &fillchars[matchend(&fillchars, 'fold:')] 64235a9aaabSBram Moolenaar if s:foldfillchar == '' 64335a9aaabSBram Moolenaar let s:foldfillchar = '-' 6447b0294cbSBram Moolenaar endif 64535a9aaabSBram Moolenaarendif 64635a9aaabSBram Moolenaarlet s:difffillchar = &fillchars[matchend(&fillchars, 'diff:')] 64735a9aaabSBram Moolenaarif s:difffillchar == '' 64835a9aaabSBram Moolenaar let s:difffillchar = '-' 6497b0294cbSBram Moolenaarendif 6507b0294cbSBram Moolenaar 6515c73622aSBram Moolenaarlet s:foldId = 0 6527b0294cbSBram Moolenaar 653071d4279SBram Moolenaarwhile s:lnum <= s:end 654071d4279SBram Moolenaar 65547136d70SBram Moolenaar " If there are filler lines for diff mode, show these above the line. 65647136d70SBram Moolenaar let s:filler = diff_filler(s:lnum) 65747136d70SBram Moolenaar if s:filler > 0 65847136d70SBram Moolenaar let s:n = s:filler 65947136d70SBram Moolenaar while s:n > 0 66035a9aaabSBram Moolenaar let s:new = repeat(s:difffillchar, 3) 66147136d70SBram Moolenaar 662076e8b2aSBram Moolenaar if s:n > 2 && s:n < s:filler && !s:settings.whole_filler 66335a9aaabSBram Moolenaar let s:new = s:new . " " . s:filler . " inserted lines " 66435a9aaabSBram Moolenaar let s:n = 2 66535a9aaabSBram Moolenaar endif 66635a9aaabSBram Moolenaar 667076e8b2aSBram Moolenaar if !s:settings.no_pre 66835a9aaabSBram Moolenaar " HTML line wrapping is off--go ahead and fill to the margin 6695c73622aSBram Moolenaar let s:new = s:new . repeat(s:difffillchar, &columns - strlen(s:new) - s:margin) 6705c73622aSBram Moolenaar else 6715c73622aSBram Moolenaar let s:new = s:new . repeat(s:difffillchar, 3) 67235a9aaabSBram Moolenaar endif 67335a9aaabSBram Moolenaar 6748ada2ccaSBram Moolenaar let s:new = s:HtmlFormat(s:new, "DiffDelete", "") 675076e8b2aSBram Moolenaar if s:settings.number_lines 6765c73622aSBram Moolenaar " Indent if line numbering is on; must be after escaping. 6775c73622aSBram Moolenaar let s:new = repeat(s:LeadingSpace, s:margin) . s:new 6785c73622aSBram Moolenaar endif 679349b2fb0SBram Moolenaar call add(s:lines, s:new.s:HtmlEndline) 68035a9aaabSBram Moolenaar 68147136d70SBram Moolenaar let s:n = s:n - 1 68247136d70SBram Moolenaar endwhile 68347136d70SBram Moolenaar unlet s:n 68447136d70SBram Moolenaar endif 68547136d70SBram Moolenaar unlet s:filler 68647136d70SBram Moolenaar 68747136d70SBram Moolenaar " Start the line with the line number. 688076e8b2aSBram Moolenaar if s:settings.number_lines 6895c73622aSBram Moolenaar let s:numcol = repeat(' ', s:margin - 1 - strlen(s:lnum)) . s:lnum . ' ' 69047136d70SBram Moolenaar else 6915c73622aSBram Moolenaar let s:numcol = "" 69247136d70SBram Moolenaar endif 69347136d70SBram Moolenaar 6945c73622aSBram Moolenaar let s:new = "" 6955c73622aSBram Moolenaar 696076e8b2aSBram Moolenaar if has('folding') && !s:settings.ignore_folding && foldclosed(s:lnum) > -1 && !s:settings.dynamic_folds 6977b0294cbSBram Moolenaar " 6985c73622aSBram Moolenaar " This is the beginning of a folded block (with no dynamic folding) 6997b0294cbSBram Moolenaar " 7005c73622aSBram Moolenaar let s:new = s:numcol . foldtextresult(s:lnum) 701076e8b2aSBram Moolenaar if !s:settings.no_pre 70235a9aaabSBram Moolenaar " HTML line wrapping is off--go ahead and fill to the margin 70335a9aaabSBram Moolenaar let s:new = s:new . repeat(s:foldfillchar, &columns - strlen(s:new)) 7047b0294cbSBram Moolenaar endif 7057b0294cbSBram Moolenaar 7068ada2ccaSBram Moolenaar let s:new = s:HtmlFormat(s:new, "Folded", "") 7077b0294cbSBram Moolenaar 7087b0294cbSBram Moolenaar " Skip to the end of the fold 709349b2fb0SBram Moolenaar let s:new_lnum = foldclosedend(s:lnum) 710349b2fb0SBram Moolenaar 711076e8b2aSBram Moolenaar if !s:settings.no_progress 712349b2fb0SBram Moolenaar call s:pgb.incr(s:new_lnum - s:lnum) 713349b2fb0SBram Moolenaar endif 714349b2fb0SBram Moolenaar 715349b2fb0SBram Moolenaar let s:lnum = s:new_lnum 7167b0294cbSBram Moolenaar 7177b0294cbSBram Moolenaar else 7187b0294cbSBram Moolenaar " 7195c73622aSBram Moolenaar " A line that is not folded, or doing dynamic folding. 7207b0294cbSBram Moolenaar " 72135a9aaabSBram Moolenaar let s:line = getline(s:lnum) 7227b0294cbSBram Moolenaar let s:len = strlen(s:line) 7237b0294cbSBram Moolenaar 724076e8b2aSBram Moolenaar if s:settings.dynamic_folds 7255c73622aSBram Moolenaar " First insert a closing for any open folds that end on this line 7265c73622aSBram Moolenaar while !empty(s:foldstack) && get(s:foldstack,0).lastline == s:lnum-1 7275c73622aSBram Moolenaar let s:new = s:new."</span></span>" 7285c73622aSBram Moolenaar call remove(s:foldstack, 0) 7295c73622aSBram Moolenaar endwhile 7305c73622aSBram Moolenaar 7315c73622aSBram Moolenaar " Now insert an opening any new folds that start on this line 7325c73622aSBram Moolenaar let s:firstfold = 1 7335c73622aSBram Moolenaar while !empty(s:allfolds) && get(s:allfolds,0).firstline == s:lnum 7345c73622aSBram Moolenaar let s:foldId = s:foldId + 1 735349b2fb0SBram Moolenaar let s:new .= "<span id='" 736349b2fb0SBram Moolenaar let s:new .= (exists('g:html_diff_win_num') ? "win".g:html_diff_win_num : "") 737349b2fb0SBram Moolenaar let s:new .= "fold".s:foldId."' class='".s:allfolds[0].type."'>" 738349b2fb0SBram Moolenaar 7395c73622aSBram Moolenaar 7405c73622aSBram Moolenaar " Unless disabled, add a fold column for the opening line of a fold. 7415c73622aSBram Moolenaar " 7425c73622aSBram Moolenaar " Note that dynamic folds require using css so we just use css to take 7435c73622aSBram Moolenaar " care of the leading spaces rather than using in the case of 7445c73622aSBram Moolenaar " html_no_pre to make it easier 745076e8b2aSBram Moolenaar if !s:settings.no_foldcolumn 7465c73622aSBram Moolenaar " add fold column that can open the new fold 7475c73622aSBram Moolenaar if s:allfolds[0].level > 1 && s:firstfold 7485c73622aSBram Moolenaar let s:new = s:new . "<a class='toggle-open FoldColumn' href='javascript:toggleFold(\"fold".s:foldstack[0].id."\")'>" 7495c73622aSBram Moolenaar let s:new = s:new . repeat('|', s:allfolds[0].level - 1) . "</a>" 7505c73622aSBram Moolenaar endif 7515c73622aSBram Moolenaar let s:new = s:new . "<a class='toggle-open FoldColumn' href='javascript:toggleFold(\"fold".s:foldId."\")'>+</a>" 7525c73622aSBram Moolenaar let s:new = s:new . "<a class='toggle-open " 7535c73622aSBram Moolenaar " If this is not the last fold we're opening on this line, we need 7545c73622aSBram Moolenaar " to keep the filler spaces hidden if the fold is opened by mouse 7555c73622aSBram Moolenaar " hover. If it is the last fold to open in the line, we shouldn't hide 7565c73622aSBram Moolenaar " them, so don't apply the toggle-filler class. 7575c73622aSBram Moolenaar if get(s:allfolds, 1, {'firstline': 0}).firstline == s:lnum 7585c73622aSBram Moolenaar let s:new = s:new . "toggle-filler " 7595c73622aSBram Moolenaar endif 7605c73622aSBram Moolenaar let s:new = s:new . "FoldColumn' href='javascript:toggleFold(\"fold".s:foldId."\")'>" 7615c73622aSBram Moolenaar let s:new = s:new . repeat(" ", s:foldcolumn - s:allfolds[0].level) . "</a>" 7625c73622aSBram Moolenaar 7635c73622aSBram Moolenaar " add fold column that can close the new fold 7645c73622aSBram Moolenaar let s:new = s:new . "<a class='toggle-closed FoldColumn' href='javascript:toggleFold(\"fold".s:foldId."\")'>" 7655c73622aSBram Moolenaar if s:firstfold 7665c73622aSBram Moolenaar let s:new = s:new . repeat('|', s:allfolds[0].level - 1) 7675c73622aSBram Moolenaar endif 7685c73622aSBram Moolenaar let s:new = s:new . "-" 7695c73622aSBram Moolenaar " only add spaces if we aren't opening another fold on the same line 7705c73622aSBram Moolenaar if get(s:allfolds, 1, {'firstline': 0}).firstline != s:lnum 7715c73622aSBram Moolenaar let s:new = s:new . repeat(" ", s:foldcolumn - s:allfolds[0].level) 7725c73622aSBram Moolenaar endif 7735c73622aSBram Moolenaar let s:new = s:new . "</a>" 7745c73622aSBram Moolenaar let s:firstfold = 0 7755c73622aSBram Moolenaar endif 7765c73622aSBram Moolenaar 7775c73622aSBram Moolenaar " add fold text, moving the span ending to the next line so collapsing 7785c73622aSBram Moolenaar " of folds works correctly 7798ada2ccaSBram Moolenaar let s:new = s:new . substitute(s:HtmlFormat(s:numcol . foldtextresult(s:lnum), "Folded", ""), '</span>', s:HtmlEndline.'\n\0', '') 7805c73622aSBram Moolenaar let s:new = s:new . "<span class='fulltext'>" 7815c73622aSBram Moolenaar 7825c73622aSBram Moolenaar " open the fold now that we have the fold text to allow retrieval of 7835c73622aSBram Moolenaar " fold text for subsequent folds 7845c73622aSBram Moolenaar execute s:lnum."foldopen" 7855c73622aSBram Moolenaar call insert(s:foldstack, remove(s:allfolds,0)) 7865c73622aSBram Moolenaar let s:foldstack[0].id = s:foldId 7875c73622aSBram Moolenaar endwhile 7885c73622aSBram Moolenaar 7895c73622aSBram Moolenaar " Unless disabled, add a fold column for other lines. 7905c73622aSBram Moolenaar " 7915c73622aSBram Moolenaar " Note that dynamic folds require using css so we just use css to take 7925c73622aSBram Moolenaar " care of the leading spaces rather than using in the case of 7935c73622aSBram Moolenaar " html_no_pre to make it easier 794076e8b2aSBram Moolenaar if !s:settings.no_foldcolumn 7955c73622aSBram Moolenaar if empty(s:foldstack) 7967510fe74SBram Moolenaar " add the empty foldcolumn for unfolded lines if there is a fold 7977510fe74SBram Moolenaar " column at all 7987510fe74SBram Moolenaar if s:foldcolumn > 0 7998ada2ccaSBram Moolenaar let s:new = s:new . s:HtmlFormat(repeat(' ', s:foldcolumn), "FoldColumn", "") 8007510fe74SBram Moolenaar endif 8015c73622aSBram Moolenaar else 8025c73622aSBram Moolenaar " add the fold column for folds not on the opening line 8035c73622aSBram Moolenaar if get(s:foldstack, 0).firstline < s:lnum 8045c73622aSBram Moolenaar let s:new = s:new . "<a class='FoldColumn' href='javascript:toggleFold(\"fold".s:foldstack[0].id."\")'>" 8055c73622aSBram Moolenaar let s:new = s:new . repeat('|', s:foldstack[0].level) 8065c73622aSBram Moolenaar let s:new = s:new . repeat(' ', s:foldcolumn - s:foldstack[0].level) . "</a>" 8075c73622aSBram Moolenaar endif 8085c73622aSBram Moolenaar endif 8095c73622aSBram Moolenaar endif 8105c73622aSBram Moolenaar endif 8115c73622aSBram Moolenaar 8125c73622aSBram Moolenaar " Now continue with the unfolded line text 813076e8b2aSBram Moolenaar if s:settings.number_lines 8148ada2ccaSBram Moolenaar " TODO: why not use the real highlight name here? 8158ada2ccaSBram Moolenaar let s:new = s:new . s:HtmlFormat(s:numcol, "lnr", "") 816071d4279SBram Moolenaar endif 817071d4279SBram Moolenaar 81847136d70SBram Moolenaar " Get the diff attribute, if any. 81947136d70SBram Moolenaar let s:diffattr = diff_hlID(s:lnum, 1) 82047136d70SBram Moolenaar 8217510fe74SBram Moolenaar " initialize conceal info to act like not concealed, just in case 8227510fe74SBram Moolenaar let s:concealinfo = [0, ''] 8237510fe74SBram Moolenaar 824071d4279SBram Moolenaar " Loop over each character in the line 825071d4279SBram Moolenaar let s:col = 1 8268ada2ccaSBram Moolenaar 8278ada2ccaSBram Moolenaar " most of the time we won't use the diff_id, initialize to zero 8288ada2ccaSBram Moolenaar let s:diff_id = 0 8298ada2ccaSBram Moolenaar let s:diff_id_name = "" 8308ada2ccaSBram Moolenaar 83135a9aaabSBram Moolenaar while s:col <= s:len || (s:col == 1 && s:diffattr) 832071d4279SBram Moolenaar let s:startcol = s:col " The start column for processing text 833076e8b2aSBram Moolenaar if !s:settings.ignore_conceal && has('conceal') 8347510fe74SBram Moolenaar let s:concealinfo = synconcealed(s:lnum, s:col) 8357510fe74SBram Moolenaar endif 836076e8b2aSBram Moolenaar if !s:settings.ignore_conceal && s:concealinfo[0] 8377510fe74SBram Moolenaar let s:col = s:col + 1 8387510fe74SBram Moolenaar " Speed loop (it's small - that's the trick) 8397510fe74SBram Moolenaar " Go along till we find a change in the match sequence number (ending 8407510fe74SBram Moolenaar " the specific concealed region) or until there are no more concealed 8417510fe74SBram Moolenaar " characters. 8427510fe74SBram Moolenaar while s:col <= s:len && s:concealinfo == synconcealed(s:lnum, s:col) | let s:col = s:col + 1 | endwhile 8437510fe74SBram Moolenaar elseif s:diffattr 8448ada2ccaSBram Moolenaar let s:diff_id = diff_hlID(s:lnum, s:col) 8458ada2ccaSBram Moolenaar let s:id = synID(s:lnum, s:col, 1) 84647136d70SBram Moolenaar let s:col = s:col + 1 84747136d70SBram Moolenaar " Speed loop (it's small - that's the trick) 84847136d70SBram Moolenaar " Go along till we find a change in hlID 8498ada2ccaSBram Moolenaar while s:col <= s:len && s:id == synID(s:lnum, s:col, 1) 8508ada2ccaSBram Moolenaar \ && s:diff_id == diff_hlID(s:lnum, s:col) | 8518ada2ccaSBram Moolenaar \ let s:col = s:col + 1 | 8528ada2ccaSBram Moolenaar \ endwhile 853076e8b2aSBram Moolenaar if s:len < &columns && !s:settings.no_pre 8548ada2ccaSBram Moolenaar " Add spaces at the end of the raw text line to extend the changed 8558ada2ccaSBram Moolenaar " line to the full width. 8565c73622aSBram Moolenaar let s:line = s:line . repeat(' ', &columns - virtcol([s:lnum, s:len]) - s:margin) 85735a9aaabSBram Moolenaar let s:len = &columns 85835a9aaabSBram Moolenaar endif 85947136d70SBram Moolenaar else 860071d4279SBram Moolenaar let s:id = synID(s:lnum, s:col, 1) 861071d4279SBram Moolenaar let s:col = s:col + 1 862071d4279SBram Moolenaar " Speed loop (it's small - that's the trick) 863071d4279SBram Moolenaar " Go along till we find a change in synID 864071d4279SBram Moolenaar while s:col <= s:len && s:id == synID(s:lnum, s:col, 1) | let s:col = s:col + 1 | endwhile 86547136d70SBram Moolenaar endif 866071d4279SBram Moolenaar 867076e8b2aSBram Moolenaar if s:settings.ignore_conceal || !s:concealinfo[0] 86835a9aaabSBram Moolenaar " Expand tabs 86935a9aaabSBram Moolenaar let s:expandedtab = strpart(s:line, s:startcol - 1, s:col - s:startcol) 8705c73622aSBram Moolenaar let s:offset = 0 8715c73622aSBram Moolenaar let s:idx = stridx(s:expandedtab, "\t") 8725c73622aSBram Moolenaar while s:idx >= 0 8735c73622aSBram Moolenaar if has("multi_byte_encoding") 8745c73622aSBram Moolenaar if s:startcol + s:idx == 1 8755c73622aSBram Moolenaar let s:i = &ts 8765c73622aSBram Moolenaar else 8775c73622aSBram Moolenaar if s:idx == 0 8785c73622aSBram Moolenaar let s:prevc = matchstr(s:line, '.\%' . (s:startcol + s:idx + s:offset) . 'c') 8795c73622aSBram Moolenaar else 8805c73622aSBram Moolenaar let s:prevc = matchstr(s:expandedtab, '.\%' . (s:idx + 1) . 'c') 8815c73622aSBram Moolenaar endif 8825c73622aSBram Moolenaar let s:vcol = virtcol([s:lnum, s:startcol + s:idx + s:offset - len(s:prevc)]) 8835c73622aSBram Moolenaar let s:i = &ts - (s:vcol % &ts) 8845c73622aSBram Moolenaar endif 8855c73622aSBram Moolenaar let s:offset -= s:i - 1 8865c73622aSBram Moolenaar else 8875c73622aSBram Moolenaar let s:i = &ts - ((s:idx + s:startcol - 1) % &ts) 8885c73622aSBram Moolenaar endif 8895c73622aSBram Moolenaar let s:expandedtab = substitute(s:expandedtab, '\t', repeat(' ', s:i), '') 8905c73622aSBram Moolenaar let s:idx = stridx(s:expandedtab, "\t") 89135a9aaabSBram Moolenaar endwhile 89235a9aaabSBram Moolenaar 8937510fe74SBram Moolenaar " get the highlight group name to use 894071d4279SBram Moolenaar let s:id = synIDtrans(s:id) 895071d4279SBram Moolenaar let s:id_name = synIDattr(s:id, "name", s:whatterm) 8968ada2ccaSBram Moolenaar if s:diff_id 8978ada2ccaSBram Moolenaar let s:diff_id_name = synIDattr(s:diff_id, "name", s:whatterm) 8988ada2ccaSBram Moolenaar endif 8997510fe74SBram Moolenaar else 9007510fe74SBram Moolenaar " use Conceal highlighting for concealed text 9017510fe74SBram Moolenaar let s:id_name = 'Conceal' 9027510fe74SBram Moolenaar let s:expandedtab = s:concealinfo[1] 9037510fe74SBram Moolenaar endif 9047510fe74SBram Moolenaar 9057510fe74SBram Moolenaar " Output the text with the same synID, with class set to {s:id_name}, 9068ada2ccaSBram Moolenaar " unless it has been concealed completely. 9077510fe74SBram Moolenaar if strlen(s:expandedtab) > 0 9088ada2ccaSBram Moolenaar let s:new = s:new . s:HtmlFormat(s:expandedtab, s:id_name, s:diff_id_name) 9097510fe74SBram Moolenaar endif 910071d4279SBram Moolenaar endwhile 9117b0294cbSBram Moolenaar endif 912071d4279SBram Moolenaar 9137510fe74SBram Moolenaar call extend(s:lines, split(s:new.s:HtmlEndline, '\n', 1)) 914076e8b2aSBram Moolenaar if !s:settings.no_progress && s:pgb.needs_redraw 915349b2fb0SBram Moolenaar redrawstatus 916349b2fb0SBram Moolenaar let s:pgb.needs_redraw = 0 917349b2fb0SBram Moolenaar endif 918071d4279SBram Moolenaar let s:lnum = s:lnum + 1 919313b7237SBram Moolenaar 920076e8b2aSBram Moolenaar if !s:settings.no_progress 921349b2fb0SBram Moolenaar call s:pgb.incr() 922349b2fb0SBram Moolenaar endif 923349b2fb0SBram Moolenaarendwhile 924349b2fb0SBram Moolenaar 925076e8b2aSBram Moolenaarif s:settings.dynamic_folds 9265c73622aSBram Moolenaar " finish off any open folds 9275c73622aSBram Moolenaar while !empty(s:foldstack) 928349b2fb0SBram Moolenaar let s:lines[-1].="</span></span>" 9295c73622aSBram Moolenaar call remove(s:foldstack, 0) 9305c73622aSBram Moolenaar endwhile 9315c73622aSBram Moolenaar 9325c73622aSBram Moolenaar " add fold column to the style list if not already there 9335c73622aSBram Moolenaar let s:id = hlID('FoldColumn') 9348ada2ccaSBram Moolenaar if index(s:idlist, s:id) == -1 9358ada2ccaSBram Moolenaar call insert(s:idlist, s:id) 9365c73622aSBram Moolenaar endif 9375c73622aSBram Moolenaarendif 9385c73622aSBram Moolenaar 939076e8b2aSBram Moolenaarif s:settings.no_pre 940076e8b2aSBram Moolenaar if !s:settings.use_css 9418ada2ccaSBram Moolenaar " Close off the font tag that encapsulates the whole <body> 942*bebca9daSBram Moolenaar call extend(s:lines, ["</font>", "</body>", "</html>"]) 9438ada2ccaSBram Moolenaar else 944349b2fb0SBram Moolenaar call extend(s:lines, ["</body>", "</html>"]) 9458ada2ccaSBram Moolenaar endif 946071d4279SBram Moolenaarelse 947349b2fb0SBram Moolenaar call extend(s:lines, ["</pre>", "</body>", "</html>"]) 948071d4279SBram Moolenaarendif 949071d4279SBram Moolenaar 950349b2fb0SBram Moolenaarexe s:newwin . "wincmd w" 951349b2fb0SBram Moolenaarcall setline(1, s:lines) 952349b2fb0SBram Moolenaarunlet s:lines 953071d4279SBram Moolenaar 954071d4279SBram Moolenaar" Now, when we finally know which, we define the colors and styles 955076e8b2aSBram Moolenaarif s:settings.use_css 956071d4279SBram Moolenaar 1;/<style type="text/+1 957071d4279SBram Moolenaarendif 958071d4279SBram Moolenaar 959071d4279SBram Moolenaar" Find out the background and foreground color. 960071d4279SBram Moolenaarlet s:fgc = s:HtmlColor(synIDattr(hlID("Normal"), "fg#", s:whatterm)) 961071d4279SBram Moolenaarlet s:bgc = s:HtmlColor(synIDattr(hlID("Normal"), "bg#", s:whatterm)) 962071d4279SBram Moolenaarif s:fgc == "" 963071d4279SBram Moolenaar let s:fgc = ( &background == "dark" ? "#ffffff" : "#000000" ) 964071d4279SBram Moolenaarendif 965071d4279SBram Moolenaarif s:bgc == "" 966071d4279SBram Moolenaar let s:bgc = ( &background == "dark" ? "#000000" : "#ffffff" ) 967071d4279SBram Moolenaarendif 968071d4279SBram Moolenaar 969071d4279SBram Moolenaar" Normal/global attributes 970071d4279SBram Moolenaar" For Netscape 4, set <body> attributes too, though, strictly speaking, it's 971071d4279SBram Moolenaar" incorrect. 972076e8b2aSBram Moolenaarif s:settings.use_css 973076e8b2aSBram Moolenaar if s:settings.no_pre 974313b7237SBram Moolenaar execute "normal! A\nbody { color: " . s:fgc . "; background-color: " . s:bgc . "; font-family: ". s:htmlfont ."; }\e" 975071d4279SBram Moolenaar else 976313b7237SBram Moolenaar execute "normal! A\npre { font-family: ". s:htmlfont ."; color: " . s:fgc . "; background-color: " . s:bgc . "; }\e" 977071d4279SBram Moolenaar yank 978071d4279SBram Moolenaar put 979071d4279SBram Moolenaar execute "normal! ^cwbody\e" 980071d4279SBram Moolenaar endif 981071d4279SBram Moolenaarelse 982*bebca9daSBram Moolenaar execute '%s:<body>:<body bgcolor="' . s:bgc . '" text="' . s:fgc . '">\r<font face="'. s:htmlfont .'">' 983071d4279SBram Moolenaarendif 984071d4279SBram Moolenaar 985071d4279SBram Moolenaar" Line numbering attributes 986076e8b2aSBram Moolenaarif s:settings.number_lines 987076e8b2aSBram Moolenaar if s:settings.use_css 988071d4279SBram Moolenaar execute "normal! A\n.lnr { " . s:CSS1(hlID("LineNr")) . "}\e" 989071d4279SBram Moolenaar else 9908424a624SBram Moolenaar execute '%s+^<span class="lnr">\([^<]*\)</span>+' . s:HtmlOpening(hlID("LineNr")) . '\1' . s:HtmlClosing(hlID("LineNr")) . '+g' 991071d4279SBram Moolenaar endif 992071d4279SBram Moolenaarendif 993071d4279SBram Moolenaar 994071d4279SBram Moolenaar" Gather attributes for all other classes 995076e8b2aSBram Moolenaarif !s:settings.no_progress && !empty(s:idlist) 996349b2fb0SBram Moolenaar let s:pgb = s:ProgressBar("Processing classes:", len(s:idlist),s:newwin) 997349b2fb0SBram Moolenaarendif 998349b2fb0SBram Moolenaarwhile !empty(s:idlist) 999071d4279SBram Moolenaar let s:attr = "" 1000349b2fb0SBram Moolenaar let s:id = remove(s:idlist, 0) 1001071d4279SBram Moolenaar let s:attr = s:CSS1(s:id) 1002071d4279SBram Moolenaar let s:id_name = synIDattr(s:id, "name", s:whatterm) 1003349b2fb0SBram Moolenaar 1004071d4279SBram Moolenaar " If the class has some attributes, export the style, otherwise DELETE all 1005071d4279SBram Moolenaar " its occurences to make the HTML shorter 1006071d4279SBram Moolenaar if s:attr != "" 1007076e8b2aSBram Moolenaar if s:settings.use_css 1008071d4279SBram Moolenaar execute "normal! A\n." . s:id_name . " { " . s:attr . "}" 1009071d4279SBram Moolenaar else 10108ada2ccaSBram Moolenaar " replace spans of just this class name with non-CSS style markup 10118ada2ccaSBram Moolenaar execute '%s+<span class="' . s:id_name . '">\([^<]*\)</span>+' . s:HtmlOpening(s:id) . '\1' . s:HtmlClosing(s:id) . '+ge' 10128ada2ccaSBram Moolenaar " Replace spans of this class name AND a diff class with non-CSS style 10138ada2ccaSBram Moolenaar " markup surrounding a span of just the diff class. The diff class will 10148ada2ccaSBram Moolenaar " be handled later because we know that information is at the end. 10158ada2ccaSBram Moolenaar execute '%s+<span class="' . s:id_name . ' \(Diff\%(Add\|Change\|Delete\|Text\)\)">\([^<]*\)</span>+' . s:HtmlOpening(s:id) . '<span class="\1">\2</span>' . s:HtmlClosing(s:id) . '+ge' 1016071d4279SBram Moolenaar endif 1017071d4279SBram Moolenaar else 1018313b7237SBram Moolenaar execute '%s+<span class="' . s:id_name . '">\([^<]*\)</span>+\1+ge' 10198ada2ccaSBram Moolenaar execute '%s+<span class="' . s:id_name . ' \(Diff\%(Add\|Change\|Delete\|Text\)\)">\([^<]*\)</span>+<span class="\1">\2</span>+ge' 1020076e8b2aSBram Moolenaar if s:settings.use_css 10218ada2ccaSBram Moolenaar 1;/<\/style>/-2 1022071d4279SBram Moolenaar endif 1023071d4279SBram Moolenaar endif 1024349b2fb0SBram Moolenaar 1025076e8b2aSBram Moolenaar if !s:settings.no_progress 1026349b2fb0SBram Moolenaar call s:pgb.incr() 1027349b2fb0SBram Moolenaar if s:pgb.needs_redraw 1028349b2fb0SBram Moolenaar redrawstatus 1029349b2fb0SBram Moolenaar let s:pgb.needs_redraw = 0 1030*bebca9daSBram Moolenaar " TODO: sleep here to show the progress bar, but only if total time spent 1031*bebca9daSBram Moolenaar " so far on this step is < 1 second? Too slow for batch runs like the test 1032*bebca9daSBram Moolenaar " suite to sleep all the time. Maybe there's no good reason to sleep at 1033*bebca9daSBram Moolenaar " all. 1034349b2fb0SBram Moolenaar endif 1035349b2fb0SBram Moolenaar endif 1036071d4279SBram Moolenaarendwhile 1037071d4279SBram Moolenaar 1038071d4279SBram Moolenaar" Add hyperlinks 10391cd871b5SBram Moolenaar%s+\(https\=://\S\{-}\)\(\([.,;:}]\=\(\s\|$\)\)\|[\\"'<>]\|>\|<\|"\)+<a href="\1">\1</a>\2+ge 1040071d4279SBram Moolenaar 1041071d4279SBram Moolenaar" The DTD 1042076e8b2aSBram Moolenaarif s:settings.use_xhtml 1043076e8b2aSBram Moolenaar exe "normal! gg$a\n<!DOCTYPE html PUBLIC \"-//W3C//DTD XHTML 1.0 Transitional//EN\" \"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd\">" 1044076e8b2aSBram Moolenaarelseif s:settings.use_css && !s:settings.no_pre 1045076e8b2aSBram Moolenaar exe "normal! gg0i<!DOCTYPE HTML PUBLIC \"-//W3C//DTD HTML 4.01//EN\" \"http://www.w3.org/TR/html4/strict.dtd\">\n" 10461cd871b5SBram Moolenaarelse 1047076e8b2aSBram Moolenaar exe "normal! gg0i<!DOCTYPE HTML PUBLIC \"-//W3C//DTD HTML 4.01 Transitional//EN\" \"http://www.w3.org/TR/html4/loose.dtd\">\n" 10481cd871b5SBram Moolenaarendif 10491cd871b5SBram Moolenaar 1050076e8b2aSBram Moolenaarif s:settings.use_xhtml 10511cd871b5SBram Moolenaar exe "normal! gg/<html/e\na xmlns=\"http://www.w3.org/1999/xhtml\"\e" 10521cd871b5SBram Moolenaarendif 1053071d4279SBram Moolenaar 1054071d4279SBram Moolenaar" Cleanup 1055071d4279SBram Moolenaar%s:\s\+$::e 1056071d4279SBram Moolenaar 1057071d4279SBram Moolenaar" Restore old settings 1058349b2fb0SBram Moolenaarlet &l:foldmethod = s:old_fdm 1059071d4279SBram Moolenaarlet &report = s:old_report 1060071d4279SBram Moolenaarlet &title = s:old_title 1061071d4279SBram Moolenaarlet &icon = s:old_icon 1062071d4279SBram Moolenaarlet &paste = s:old_paste 1063071d4279SBram Moolenaarlet &magic = s:old_magic 1064071d4279SBram Moolenaarlet @/ = s:old_search 1065349b2fb0SBram Moolenaarlet &more = s:old_more 1066071d4279SBram Moolenaarexe s:orgwin . "wincmd w" 1067071d4279SBram Moolenaarlet &l:et = s:old_et 1068071d4279SBram Moolenaarexe s:newwin . "wincmd w" 1069349b2fb0SBram Moolenaarexec 'resize' s:old_winheight 1070349b2fb0SBram Moolenaarlet &l:winfixheight = s:old_winfixheight 1071071d4279SBram Moolenaar 1072349b2fb0SBram Moolenaarcall setwinvar(s:orgwin,'&stl', s:origwin_stl) 1073349b2fb0SBram Moolenaarcall setwinvar(s:newwin,'&stl', s:newwin_stl) 1074349b2fb0SBram Moolenaarlet &ls=s:ls 1075349b2fb0SBram Moolenaar 1076071d4279SBram Moolenaar" Save a little bit of memory (worth doing?) 1077313b7237SBram Moolenaarunlet s:htmlfont 1078349b2fb0SBram Moolenaarunlet s:old_et s:old_paste s:old_icon s:old_report s:old_title s:old_search s:old_magic s:old_more s:old_fdm s:old_winheight s:old_winfixheight 1079349b2fb0SBram Moolenaarunlet s:whatterm s:idlist s:lnum s:end s:margin s:fgc s:bgc 1080076e8b2aSBram Moolenaarunlet! s:col s:id s:attr s:len s:line s:new s:expandedtab s:concealinfo 10817510fe74SBram Moolenaarunlet! s:orgwin s:newwin s:orgbufnr s:idx s:i s:offset s:ls s:origwin_stl s:newwin_stl s:current_syntax 108205159a0cSBram Moolenaarif !v:profiling 1083071d4279SBram Moolenaar delfunc s:HtmlColor 108435a9aaabSBram Moolenaar delfunc s:HtmlFormat 1085071d4279SBram Moolenaar delfunc s:CSS1 1086076e8b2aSBram Moolenaar if !s:settings.use_css 1087071d4279SBram Moolenaar delfunc s:HtmlOpening 1088071d4279SBram Moolenaar delfunc s:HtmlClosing 1089071d4279SBram Moolenaar endif 1090076e8b2aSBram Moolenaar if s:settings.dynamic_folds 10915c73622aSBram Moolenaar delfunc s:FoldCompare 10925c73622aSBram Moolenaar endif 10935c73622aSBram Moolenaar 1094076e8b2aSBram Moolenaar if !s:settings.no_progress 1095349b2fb0SBram Moolenaar delfunc s:ProgressBar 1096349b2fb0SBram Moolenaar delfunc s:progressbar.paint 1097349b2fb0SBram Moolenaar delfunc s:progressbar.incr 1098349b2fb0SBram Moolenaar unlet s:pgb s:progressbar 1099349b2fb0SBram Moolenaar endif 1100349b2fb0SBram Moolenaarendif 1101349b2fb0SBram Moolenaar 1102349b2fb0SBram Moolenaarunlet! s:new_lnum s:diffattr s:difffillchar s:foldfillchar s:HtmlSpace s:LeadingSpace s:HtmlEndline s:firstfold s:foldcolumn 1103076e8b2aSBram Moolenaarunlet s:foldstack s:allfolds s:foldId s:numcol s:settings 11045c73622aSBram Moolenaar 11055c73622aSBram Moolenaarlet &cpo = s:cpo_sav 1106349b2fb0SBram Moolenaarunlet! s:cpo_sav 11075c73622aSBram Moolenaar 1108349b2fb0SBram Moolenaar" Make sure any patches will probably use consistent indent 11097c86f4ccSBram Moolenaar" vim: ts=8 sw=2 sts=2 noet 1110