1071d4279SBram Moolenaar" Vim syntax support file 2349b2fb0SBram Moolenaar" Maintainer: Ben Fritz <[email protected]> 3*166af9bbSBram Moolenaar" Last Change: 2010 Sep 04 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 76bebca9daSBram 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 1298df7f888SBram Moolenaar " Replace double spaces, leading spaces, and trailing spaces if needed 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') 1338df7f888SBram Moolenaar let formatted = substitute(formatted, ' \+$', s:HtmlSpace, 'g') 13435a9aaabSBram Moolenaar endif 13535a9aaabSBram Moolenaar 13635a9aaabSBram Moolenaar " Enclose in a span of class style_name 1378ada2ccaSBram Moolenaar let formatted = '<span class="' . l:style_name . '">' . formatted . '</span>' 13835a9aaabSBram Moolenaar 1398ada2ccaSBram Moolenaar " Add the class to class list if it's not there yet. 1408ada2ccaSBram Moolenaar " Add normal groups to the beginning so diff groups can override them. 14135a9aaabSBram Moolenaar let s:id = hlID(a:style_name) 1428ada2ccaSBram Moolenaar if index(s:idlist, s:id ) == -1 1438ada2ccaSBram Moolenaar if a:style_name =~ 'Diff\%(Add\|Change\|Delete\|Text\)' 1448ada2ccaSBram Moolenaar call add(s:idlist, s:id) 1458ada2ccaSBram Moolenaar else 1468ada2ccaSBram Moolenaar call insert(s:idlist, s:id) 1478ada2ccaSBram Moolenaar endif 1488ada2ccaSBram Moolenaar endif 1498ada2ccaSBram Moolenaar 1508ada2ccaSBram Moolenaar " Add the diff highlight class to class list if used and it's not there yet. 1518ada2ccaSBram Moolenaar " Add diff groups to the end so they override the other highlighting. 1528ada2ccaSBram Moolenaar if a:diff_style_name != "" 1538ada2ccaSBram Moolenaar let s:diff_id = hlID(a:diff_style_name) 1548ada2ccaSBram Moolenaar if index(s:idlist, s:diff_id) == -1 1558ada2ccaSBram Moolenaar call add(s:idlist, s:diff_id) 1568ada2ccaSBram Moolenaar endif 15735a9aaabSBram Moolenaar endif 15835a9aaabSBram Moolenaar 15935a9aaabSBram Moolenaar return formatted 16035a9aaabSBram Moolenaarendfun 16135a9aaabSBram Moolenaar 162071d4279SBram Moolenaar" Return CSS style describing given highlight id (can be empty) 163071d4279SBram Moolenaarfunction! s:CSS1(id) 164071d4279SBram Moolenaar let a = "" 165071d4279SBram Moolenaar if synIDattr(a:id, "inverse") 166071d4279SBram Moolenaar " For inverse, we always must set both colors (and exchange them) 167071d4279SBram Moolenaar let x = s:HtmlColor(synIDattr(a:id, "bg#", s:whatterm)) 168071d4279SBram Moolenaar let a = a . "color: " . ( x != "" ? x : s:bgc ) . "; " 169071d4279SBram Moolenaar let x = s:HtmlColor(synIDattr(a:id, "fg#", s:whatterm)) 170071d4279SBram Moolenaar let a = a . "background-color: " . ( x != "" ? x : s:fgc ) . "; " 171071d4279SBram Moolenaar else 172071d4279SBram Moolenaar let x = s:HtmlColor(synIDattr(a:id, "fg#", s:whatterm)) 173071d4279SBram Moolenaar if x != "" | let a = a . "color: " . x . "; " | endif 174071d4279SBram Moolenaar let x = s:HtmlColor(synIDattr(a:id, "bg#", s:whatterm)) 175071d4279SBram Moolenaar if x != "" | let a = a . "background-color: " . x . "; " | endif 176071d4279SBram Moolenaar endif 177071d4279SBram Moolenaar if synIDattr(a:id, "bold") | let a = a . "font-weight: bold; " | endif 178071d4279SBram Moolenaar if synIDattr(a:id, "italic") | let a = a . "font-style: italic; " | endif 179071d4279SBram Moolenaar if synIDattr(a:id, "underline") | let a = a . "text-decoration: underline; " | endif 180071d4279SBram Moolenaar return a 181071d4279SBram Moolenaarendfun 182071d4279SBram Moolenaar 183076e8b2aSBram Moolenaarif s:settings.dynamic_folds 1845c73622aSBram Moolenaar " compares two folds as stored in our list of folds 1855c73622aSBram Moolenaar " A fold is "less" than another if it starts at an earlier line number, 1865c73622aSBram Moolenaar " or ends at a later line number, ties broken by fold level 1875c73622aSBram Moolenaar function! s:FoldCompare(f1, f2) 1885c73622aSBram Moolenaar if a:f1.firstline != a:f2.firstline 1895c73622aSBram Moolenaar " put it before if it starts earlier 1905c73622aSBram Moolenaar return a:f1.firstline - a:f2.firstline 1915c73622aSBram Moolenaar elseif a:f1.lastline != a:f2.lastline 1925c73622aSBram Moolenaar " put it before if it ends later 1935c73622aSBram Moolenaar return a:f2.lastline - a:f1.lastline 1945c73622aSBram Moolenaar else 1955c73622aSBram Moolenaar " if folds begin and end on the same lines, put lowest fold level first 1965c73622aSBram Moolenaar return a:f1.level - a:f2.level 1975c73622aSBram Moolenaar endif 1985c73622aSBram Moolenaar endfunction 1995c73622aSBram Moolenaar 2005c73622aSBram Moolenaarendif 2015c73622aSBram Moolenaar 202071d4279SBram Moolenaar 203071d4279SBram Moolenaar" Set some options to make it work faster. 204071d4279SBram Moolenaar" Don't report changes for :substitute, there will be many of them. 2058df7f888SBram Moolenaar" Don't change other windows; turn off scroll bind temporarily 206071d4279SBram Moolenaarlet s:old_title = &title 207071d4279SBram Moolenaarlet s:old_icon = &icon 208071d4279SBram Moolenaarlet s:old_et = &l:et 2098df7f888SBram Moolenaarlet s:old_bind = &l:scrollbind 210071d4279SBram Moolenaarlet s:old_report = &report 211071d4279SBram Moolenaarlet s:old_search = @/ 212349b2fb0SBram Moolenaarlet s:old_more = &more 213071d4279SBram Moolenaarset notitle noicon 214071d4279SBram Moolenaarsetlocal et 215349b2fb0SBram Moolenaarset nomore 216071d4279SBram Moolenaarset report=1000000 2178df7f888SBram Moolenaarsetlocal noscrollbind 218071d4279SBram Moolenaar 2197510fe74SBram Moolenaarif exists(':ownsyntax') && exists('w:current_syntax') 2207510fe74SBram Moolenaar let s:current_syntax = w:current_syntax 2217510fe74SBram Moolenaarelseif exists('b:current_syntax') 2227510fe74SBram Moolenaar let s:current_syntax = b:current_syntax 2237510fe74SBram Moolenaarelse 2247510fe74SBram Moolenaar let s:current_syntax = 'none' 2257510fe74SBram Moolenaarendif 2267510fe74SBram Moolenaar 2277510fe74SBram Moolenaarif s:current_syntax == '' 2287510fe74SBram Moolenaar let s:current_syntax = 'none' 2297510fe74SBram Moolenaarendif 2307510fe74SBram Moolenaar 231071d4279SBram Moolenaar" Split window to create a buffer with the HTML file. 232071d4279SBram Moolenaarlet s:orgbufnr = winbufnr(0) 233349b2fb0SBram Moolenaarlet s:origwin_stl = &l:stl 234071d4279SBram Moolenaarif expand("%") == "" 235076e8b2aSBram Moolenaar exec 'new Untitled.'.(s:settings.use_xhtml ? 'x' : '').'html' 236071d4279SBram Moolenaarelse 237076e8b2aSBram Moolenaar exec 'new %.'.(s:settings.use_xhtml ? 'x' : '').'html' 238071d4279SBram Moolenaarendif 239349b2fb0SBram Moolenaar 240349b2fb0SBram Moolenaar" Resize the new window to very small in order to make it draw faster 241349b2fb0SBram Moolenaarlet s:old_winheight = winheight(0) 242349b2fb0SBram Moolenaarlet s:old_winfixheight = &l:winfixheight 243349b2fb0SBram Moolenaarif s:old_winheight > 2 244349b2fb0SBram Moolenaar resize 1 " leave enough room to view one line at a time 245349b2fb0SBram Moolenaar norm! G 246349b2fb0SBram Moolenaar norm! zt 247349b2fb0SBram Moolenaarendif 248349b2fb0SBram Moolenaarsetlocal winfixheight 249349b2fb0SBram Moolenaar 250349b2fb0SBram Moolenaarlet s:newwin_stl = &l:stl 251349b2fb0SBram Moolenaar 252349b2fb0SBram Moolenaar" on the new window, set the least time-consuming fold method 253349b2fb0SBram Moolenaarlet s:old_fdm = &foldmethod 2548df7f888SBram Moolenaarlet s:old_fen = &foldenable 255349b2fb0SBram Moolenaarsetlocal foldmethod=manual 2568df7f888SBram Moolenaarsetlocal nofoldenable 257349b2fb0SBram Moolenaar 258071d4279SBram Moolenaarlet s:newwin = winnr() 259071d4279SBram Moolenaarlet s:orgwin = bufwinnr(s:orgbufnr) 260071d4279SBram Moolenaar 261349b2fb0SBram Moolenaarsetlocal modifiable 262071d4279SBram Moolenaar%d 263071d4279SBram Moolenaarlet s:old_paste = &paste 264071d4279SBram Moolenaarset paste 265071d4279SBram Moolenaarlet s:old_magic = &magic 266071d4279SBram Moolenaarset magic 267071d4279SBram Moolenaar 268*166af9bbSBram Moolenaar" set the fileencoding to match the charset we'll be using 269*166af9bbSBram Moolenaarlet &l:fileencoding=s:settings.vim_encoding 270*166af9bbSBram Moolenaar 271*166af9bbSBram Moolenaar" According to http://www.w3.org/TR/html4/charset.html#doc-char-set, the byte 272*166af9bbSBram Moolenaar" order mark is highly recommend on the web when using multibyte encodings. But, 273*166af9bbSBram Moolenaar" it is not a good idea to include it on UTF-8 files. Otherwise, let Vim 274*166af9bbSBram Moolenaar" determine when it is actually inserted. 275*166af9bbSBram Moolenaarif s:settings.vim_encoding == 'utf-8' 276*166af9bbSBram Moolenaar setlocal nobomb 277*166af9bbSBram Moolenaarelse 278*166af9bbSBram Moolenaar setlocal bomb 279*166af9bbSBram Moolenaarendif 280*166af9bbSBram Moolenaar 281349b2fb0SBram Moolenaarlet s:lines = [] 282349b2fb0SBram Moolenaar 283076e8b2aSBram Moolenaarif s:settings.use_xhtml 284bebca9daSBram Moolenaar if s:settings.encoding != "" 285bebca9daSBram Moolenaar call add(s:lines, "<?xml version=\"1.0\" encoding=\"" . s:settings.encoding . "\"?>") 2861cd871b5SBram Moolenaar else 287349b2fb0SBram Moolenaar call add(s:lines, "<?xml version=\"1.0\"?>") 2881cd871b5SBram Moolenaar endif 28935a9aaabSBram Moolenaar let s:tag_close = ' />' 290071d4279SBram Moolenaarelse 29135a9aaabSBram Moolenaar let s:tag_close = '>' 29235a9aaabSBram Moolenaarendif 29335a9aaabSBram Moolenaar 29435a9aaabSBram Moolenaarlet s:HtmlSpace = ' ' 295c1e37901SBram Moolenaarlet s:LeadingSpace = ' ' 29635a9aaabSBram Moolenaarlet s:HtmlEndline = '' 297076e8b2aSBram Moolenaarif s:settings.no_pre 29835a9aaabSBram Moolenaar let s:HtmlEndline = '<br' . s:tag_close 299c1e37901SBram Moolenaar let s:LeadingSpace = ' ' 300c1e37901SBram Moolenaar let s:HtmlSpace = '\' . s:LeadingSpace 301071d4279SBram Moolenaarendif 302071d4279SBram Moolenaar 303071d4279SBram Moolenaar" HTML header, with the title and generator ;-). Left free space for the CSS, 304071d4279SBram Moolenaar" to be filled at the end. 305349b2fb0SBram Moolenaarcall extend(s:lines, [ 306349b2fb0SBram Moolenaar \ "<html>", 307bebca9daSBram Moolenaar \ "<head>"]) 308bebca9daSBram Moolenaar" include encoding as close to the top as possible, but only if not already 309bebca9daSBram Moolenaar" contained in XML information (to avoid haggling over content type) 310bebca9daSBram Moolenaarif s:settings.encoding != "" && !s:settings.use_xhtml 311bebca9daSBram Moolenaar call add(s:lines, "<meta http-equiv=\"content-type\" content=\"text/html; charset=" . s:settings.encoding . '"' . s:tag_close) 312bebca9daSBram Moolenaarendif 313bebca9daSBram Moolenaarcall extend(s:lines, [ 314349b2fb0SBram Moolenaar \ ("<title>".expand("%:p:~")."</title>"), 315349b2fb0SBram Moolenaar \ ("<meta name=\"Generator\" content=\"Vim/".v:version/100.".".v:version%100.'"'.s:tag_close), 316bebca9daSBram Moolenaar \ ("<meta name=\"plugin-version\" content=\"".g:loaded_2html_plugin.'"'.s:tag_close) 317349b2fb0SBram Moolenaar \ ]) 3187510fe74SBram Moolenaarcall add(s:lines, '<meta name="syntax" content="'.s:current_syntax.'"'.s:tag_close) 319076e8b2aSBram Moolenaarcall add(s:lines, '<meta name="settings" content="'. 320076e8b2aSBram Moolenaar \ join(filter(keys(s:settings),'s:settings[v:val]'),','). 321076e8b2aSBram Moolenaar \ '"'.s:tag_close) 322313b7237SBram Moolenaar 323076e8b2aSBram Moolenaarif s:settings.use_css 324076e8b2aSBram Moolenaar if s:settings.dynamic_folds 325076e8b2aSBram Moolenaar if s:settings.hover_unfold 3265c73622aSBram Moolenaar " if we are doing hover_unfold, use css 2 with css 1 fallback for IE6 327349b2fb0SBram Moolenaar call extend(s:lines, [ 328349b2fb0SBram Moolenaar \ "<style type=\"text/css\">", 329bebca9daSBram Moolenaar \ s:settings.use_xhtml ? "" : "<!--", 330349b2fb0SBram Moolenaar \ ".FoldColumn { text-decoration: none; white-space: pre; }", 331349b2fb0SBram Moolenaar \ "", 332349b2fb0SBram Moolenaar \ "body * { margin: 0; padding: 0; }", "", 333349b2fb0SBram Moolenaar \ ".open-fold > .Folded { display: none; }", 334349b2fb0SBram Moolenaar \ ".open-fold > .fulltext { display: inline; }", 335349b2fb0SBram Moolenaar \ ".closed-fold > .fulltext { display: none; }", 336349b2fb0SBram Moolenaar \ ".closed-fold > .Folded { display: inline; }", 337349b2fb0SBram Moolenaar \ "", 338349b2fb0SBram Moolenaar \ ".open-fold > .toggle-open { display: none; }", 339349b2fb0SBram Moolenaar \ ".open-fold > .toggle-closed { display: inline; }", 340349b2fb0SBram Moolenaar \ ".closed-fold > .toggle-open { display: inline; }", 341349b2fb0SBram Moolenaar \ ".closed-fold > .toggle-closed { display: none; }", 342349b2fb0SBram Moolenaar \ "", "", 343349b2fb0SBram Moolenaar \ '/* opening a fold while hovering won''t be supported by IE6 and other', 344349b2fb0SBram Moolenaar \ "similar browsers, but it should fail gracefully. */", 345349b2fb0SBram Moolenaar \ ".closed-fold:hover > .fulltext { display: inline; }", 346349b2fb0SBram Moolenaar \ ".closed-fold:hover > .toggle-filler { display: none; }", 347349b2fb0SBram Moolenaar \ ".closed-fold:hover > .Folded { display: none; }", 348bebca9daSBram Moolenaar \ s:settings.use_xhtml ? "" : '-->', 3498df7f888SBram Moolenaar \ '</style>']) 350bebca9daSBram Moolenaar " TODO: IE7 doesn't *actually* support XHTML, maybe we should remove this. 351bebca9daSBram Moolenaar " But if it's served up as tag soup, maybe the following will work, so 352bebca9daSBram Moolenaar " leave it in for now. 353bebca9daSBram Moolenaar call extend(s:lines, [ 354349b2fb0SBram Moolenaar \ "<!--[if lt IE 7]><style type=\"text/css\">", 355349b2fb0SBram Moolenaar \ ".open-fold .Folded { display: none; }", 356349b2fb0SBram Moolenaar \ ".open-fold .fulltext { display: inline; }", 357349b2fb0SBram Moolenaar \ ".open-fold .toggle-open { display: none; }", 358349b2fb0SBram Moolenaar \ ".closed-fold .toggle-closed { display: inline; }", 359349b2fb0SBram Moolenaar \ "", 360349b2fb0SBram Moolenaar \ ".closed-fold .fulltext { display: none; }", 361349b2fb0SBram Moolenaar \ ".closed-fold .Folded { display: inline; }", 362349b2fb0SBram Moolenaar \ ".closed-fold .toggle-open { display: inline; }", 363349b2fb0SBram Moolenaar \ ".closed-fold .toggle-closed { display: none; }", 364349b2fb0SBram Moolenaar \ "</style>", 365349b2fb0SBram Moolenaar \ "<![endif]-->", 366349b2fb0SBram Moolenaar \]) 3675c73622aSBram Moolenaar else 3685c73622aSBram Moolenaar " if we aren't doing hover_unfold, use CSS 1 only 369349b2fb0SBram Moolenaar call extend(s:lines, [ 370349b2fb0SBram Moolenaar \ "<style type=\"text/css\">", 371bebca9daSBram Moolenaar \ s:settings.use_xhtml ? "" :"<!--", 372349b2fb0SBram Moolenaar \ ".FoldColumn { text-decoration: none; white-space: pre; }", 373349b2fb0SBram Moolenaar \ ".open-fold .Folded { display: none; }", 374349b2fb0SBram Moolenaar \ ".open-fold .fulltext { display: inline; }", 375349b2fb0SBram Moolenaar \ ".open-fold .toggle-open { display: none; }", 376349b2fb0SBram Moolenaar \ ".closed-fold .toggle-closed { display: inline; }", 377349b2fb0SBram Moolenaar \ "", 378349b2fb0SBram Moolenaar \ ".closed-fold .fulltext { display: none; }", 379349b2fb0SBram Moolenaar \ ".closed-fold .Folded { display: inline; }", 380349b2fb0SBram Moolenaar \ ".closed-fold .toggle-open { display: inline; }", 381349b2fb0SBram Moolenaar \ ".closed-fold .toggle-closed { display: none; }", 382bebca9daSBram Moolenaar \ s:settings.use_xhtml ? "" : '-->', 383349b2fb0SBram Moolenaar \ '</style>' 384349b2fb0SBram Moolenaar \]) 3855c73622aSBram Moolenaar endif 3865c73622aSBram Moolenaar else 3875c73622aSBram Moolenaar " if we aren't doing any dynamic folding, no need for any special rules 388349b2fb0SBram Moolenaar call extend(s:lines, [ 389349b2fb0SBram Moolenaar \ "<style type=\"text/css\">", 390bebca9daSBram Moolenaar \ s:settings.use_xhtml ? "" : "<!--", 391bebca9daSBram Moolenaar \ s:settings.use_xhtml ? "" : '-->', 392349b2fb0SBram Moolenaar \ "</style>", 393349b2fb0SBram Moolenaar \]) 394071d4279SBram Moolenaar endif 3955c73622aSBram Moolenaarendif 3965c73622aSBram Moolenaar 3975c73622aSBram Moolenaar" insert javascript to toggle folds open and closed 398076e8b2aSBram Moolenaarif s:settings.dynamic_folds 399349b2fb0SBram Moolenaar call extend(s:lines, [ 400349b2fb0SBram Moolenaar \ "", 401349b2fb0SBram Moolenaar \ "<script type='text/javascript'>", 402bebca9daSBram Moolenaar \ s:settings.use_xhtml ? '//<![CDATA[' : "<!--", 403349b2fb0SBram Moolenaar \ "function toggleFold(objID)", 404349b2fb0SBram Moolenaar \ "{", 405349b2fb0SBram Moolenaar \ " var fold;", 406349b2fb0SBram Moolenaar \ " fold = document.getElementById(objID);", 407349b2fb0SBram Moolenaar \ " if(fold.className == 'closed-fold')", 408349b2fb0SBram Moolenaar \ " {", 409349b2fb0SBram Moolenaar \ " fold.className = 'open-fold';", 410349b2fb0SBram Moolenaar \ " }", 411349b2fb0SBram Moolenaar \ " else if (fold.className == 'open-fold')", 412349b2fb0SBram Moolenaar \ " {", 413349b2fb0SBram Moolenaar \ " fold.className = 'closed-fold';", 414349b2fb0SBram Moolenaar \ " }", 415349b2fb0SBram Moolenaar \ "}", 416bebca9daSBram Moolenaar \ s:settings.use_xhtml ? '//]]>' : '-->', 417349b2fb0SBram Moolenaar \ "</script>" 418349b2fb0SBram Moolenaar \]) 4195c73622aSBram Moolenaarendif 4205c73622aSBram Moolenaar 421076e8b2aSBram Moolenaarif s:settings.no_pre 422349b2fb0SBram Moolenaar call extend(s:lines, ["</head>", "<body>"]) 423071d4279SBram Moolenaarelse 424349b2fb0SBram Moolenaar call extend(s:lines, ["</head>", "<body>", "<pre>"]) 425071d4279SBram Moolenaarendif 426071d4279SBram Moolenaar 427071d4279SBram Moolenaarexe s:orgwin . "wincmd w" 428071d4279SBram Moolenaar 429071d4279SBram Moolenaar" List of all id's 4308ada2ccaSBram Moolenaarlet s:idlist = [] 431071d4279SBram Moolenaar 432349b2fb0SBram Moolenaar" set up progress bar in the status line 433076e8b2aSBram Moolenaarif !s:settings.no_progress 434349b2fb0SBram Moolenaar " ProgressBar Indicator 435349b2fb0SBram Moolenaar let s:progressbar={} 436349b2fb0SBram Moolenaar 437349b2fb0SBram Moolenaar " Progessbar specific functions 438349b2fb0SBram Moolenaar func! s:ProgressBar(title, max_value, winnr) 439349b2fb0SBram Moolenaar let pgb=copy(s:progressbar) 440349b2fb0SBram Moolenaar let pgb.title = a:title.' ' 441349b2fb0SBram Moolenaar let pgb.max_value = a:max_value 442349b2fb0SBram Moolenaar let pgb.winnr = a:winnr 443349b2fb0SBram Moolenaar let pgb.cur_value = 0 444349b2fb0SBram Moolenaar let pgb.items = { 'title' : { 'color' : 'Statusline' }, 445349b2fb0SBram Moolenaar \'bar' : { 'color' : 'Statusline' , 'fillcolor' : 'DiffDelete' , 'bg' : 'Statusline' } , 446349b2fb0SBram Moolenaar \'counter' : { 'color' : 'Statusline' } } 447349b2fb0SBram Moolenaar let pgb.last_value = 0 448349b2fb0SBram Moolenaar let pgb.needs_redraw = 0 449349b2fb0SBram Moolenaar " Note that you must use len(split) instead of len() if you want to use 450349b2fb0SBram Moolenaar " unicode in title. 451349b2fb0SBram Moolenaar " 452349b2fb0SBram Moolenaar " Subtract 3 for spacing around the title. 453349b2fb0SBram Moolenaar " Subtract 4 for the percentage display. 454349b2fb0SBram Moolenaar " Subtract 2 for spacing before this. 455349b2fb0SBram Moolenaar " Subtract 2 more for the '|' on either side of the progress bar 456349b2fb0SBram Moolenaar let pgb.subtractedlen=len(split(pgb.title, '\zs'))+3+4+2+2 457349b2fb0SBram Moolenaar let pgb.max_len = 0 458349b2fb0SBram Moolenaar set laststatus=2 459349b2fb0SBram Moolenaar return pgb 460349b2fb0SBram Moolenaar endfun 461349b2fb0SBram Moolenaar 462349b2fb0SBram Moolenaar " Function: progressbar.calculate_ticks() {{{1 463349b2fb0SBram Moolenaar func! s:progressbar.calculate_ticks(pb_len) 464349b2fb0SBram Moolenaar if a:pb_len<=0 465349b2fb0SBram Moolenaar let pb_len = 100 466349b2fb0SBram Moolenaar else 467349b2fb0SBram Moolenaar let pb_len = a:pb_len 468349b2fb0SBram Moolenaar endif 469349b2fb0SBram Moolenaar let self.progress_ticks = map(range(pb_len+1), "v:val * self.max_value / pb_len") 470349b2fb0SBram Moolenaar endfun 471349b2fb0SBram Moolenaar 472349b2fb0SBram Moolenaar "Function: progressbar.paint() 473349b2fb0SBram Moolenaar func! s:progressbar.paint() 474349b2fb0SBram Moolenaar " Recalculate widths. 475349b2fb0SBram Moolenaar let max_len = winwidth(self.winnr) 476349b2fb0SBram Moolenaar let pb_len = 0 477349b2fb0SBram Moolenaar " always true on first call because of initial value of self.max_len 478349b2fb0SBram Moolenaar if max_len != self.max_len 479349b2fb0SBram Moolenaar let self.max_len = max_len 480349b2fb0SBram Moolenaar 481349b2fb0SBram Moolenaar " Progressbar length 482349b2fb0SBram Moolenaar let pb_len = max_len - self.subtractedlen 483349b2fb0SBram Moolenaar 484349b2fb0SBram Moolenaar call self.calculate_ticks(pb_len) 485349b2fb0SBram Moolenaar 486349b2fb0SBram Moolenaar let self.needs_redraw = 1 487349b2fb0SBram Moolenaar let cur_value = 0 488349b2fb0SBram Moolenaar let self.pb_len = pb_len 489349b2fb0SBram Moolenaar else 490349b2fb0SBram Moolenaar " start searching at the last found index to make the search for the 491349b2fb0SBram Moolenaar " appropriate tick value normally take 0 or 1 comparisons 492349b2fb0SBram Moolenaar let cur_value = self.last_value 493349b2fb0SBram Moolenaar let pb_len = self.pb_len 494349b2fb0SBram Moolenaar endif 495349b2fb0SBram Moolenaar 496349b2fb0SBram Moolenaar let cur_val_max = pb_len > 0 ? pb_len : 100 497349b2fb0SBram Moolenaar 498349b2fb0SBram Moolenaar " find the current progress bar position based on precalculated thresholds 499349b2fb0SBram Moolenaar while cur_value < cur_val_max && self.cur_value > self.progress_ticks[cur_value] 500349b2fb0SBram Moolenaar let cur_value += 1 501349b2fb0SBram Moolenaar endwhile 502349b2fb0SBram Moolenaar 503349b2fb0SBram Moolenaar " update progress bar 504349b2fb0SBram Moolenaar if self.last_value != cur_value || self.needs_redraw || self.cur_value == self.max_value 505349b2fb0SBram Moolenaar let self.needs_redraw = 1 506349b2fb0SBram Moolenaar let self.last_value = cur_value 507349b2fb0SBram Moolenaar 508349b2fb0SBram Moolenaar let t_color = self.items.title.color 509349b2fb0SBram Moolenaar let b_fcolor = self.items.bar.fillcolor 510349b2fb0SBram Moolenaar let b_color = self.items.bar.color 511349b2fb0SBram Moolenaar let c_color = self.items.counter.color 512349b2fb0SBram Moolenaar 513349b2fb0SBram Moolenaar let stl = "%#".t_color."#%-( ".self.title." %)". 514349b2fb0SBram Moolenaar \"%#".b_color."#". 515349b2fb0SBram Moolenaar \(pb_len>0 ? 516349b2fb0SBram Moolenaar \ ('|%#'.b_fcolor."#%-(".repeat(" ",cur_value)."%)". 517349b2fb0SBram Moolenaar \ '%#'.b_color."#".repeat(" ",pb_len-cur_value)."|"): 518349b2fb0SBram Moolenaar \ ('')). 519349b2fb0SBram Moolenaar \"%=%#".c_color."#%( ".printf("%3.d ",100*self.cur_value/self.max_value)."%% %)" 520349b2fb0SBram Moolenaar call setwinvar(self.winnr, '&stl', stl) 521349b2fb0SBram Moolenaar endif 522349b2fb0SBram Moolenaar endfun 523349b2fb0SBram Moolenaar 524349b2fb0SBram Moolenaar func! s:progressbar.incr( ... ) 525349b2fb0SBram Moolenaar let self.cur_value += (a:0 ? a:1 : 1) 526349b2fb0SBram Moolenaar " if we were making a general-purpose progress bar, we'd need to limit to a 527349b2fb0SBram Moolenaar " lower limit as well, but since we always increment with a positive value 528349b2fb0SBram Moolenaar " in this script, we only need limit the upper value 529349b2fb0SBram Moolenaar let self.cur_value = (self.cur_value > self.max_value ? self.max_value : self.cur_value) 530349b2fb0SBram Moolenaar call self.paint() 531349b2fb0SBram Moolenaar endfun 532349b2fb0SBram Moolenaar " }}} 533076e8b2aSBram Moolenaar if s:settings.dynamic_folds 534349b2fb0SBram Moolenaar " to process folds we make two passes through each line 535349b2fb0SBram Moolenaar let s:pgb = s:ProgressBar("Processing folds:", line('$')*2, s:orgwin) 536349b2fb0SBram Moolenaar endif 537349b2fb0SBram Moolenaarendif 538349b2fb0SBram Moolenaar 5395c73622aSBram Moolenaar" First do some preprocessing for dynamic folding. Do this for the entire file 5405c73622aSBram Moolenaar" so we don't accidentally start within a closed fold or something. 5415c73622aSBram Moolenaarlet s:allfolds = [] 5425c73622aSBram Moolenaar 543076e8b2aSBram Moolenaarif s:settings.dynamic_folds 5445c73622aSBram Moolenaar let s:lnum = 1 5455c73622aSBram Moolenaar let s:end = line('$') 5465c73622aSBram Moolenaar " save the fold text and set it to the default so we can find fold levels 5475c73622aSBram Moolenaar let s:foldtext_save = &foldtext 548349b2fb0SBram Moolenaar setlocal foldtext& 5495c73622aSBram Moolenaar 5505c73622aSBram Moolenaar " we will set the foldcolumn in the html to the greater of the maximum fold 5515c73622aSBram Moolenaar " level and the current foldcolumn setting 5525c73622aSBram Moolenaar let s:foldcolumn = &foldcolumn 5535c73622aSBram Moolenaar 5545c73622aSBram Moolenaar " get all info needed to describe currently closed folds 555349b2fb0SBram Moolenaar while s:lnum <= s:end 5565c73622aSBram Moolenaar if foldclosed(s:lnum) == s:lnum 5575c73622aSBram Moolenaar " default fold text has '+-' and then a number of dashes equal to fold 5585c73622aSBram Moolenaar " level, so subtract 2 from index of first non-dash after the dashes 5595c73622aSBram Moolenaar " in order to get the fold level of the current fold 5605c73622aSBram Moolenaar let s:level = match(foldtextresult(s:lnum), '+-*\zs[^-]') - 2 5615c73622aSBram Moolenaar if s:level+1 > s:foldcolumn 5625c73622aSBram Moolenaar let s:foldcolumn = s:level+1 5635c73622aSBram Moolenaar endif 5645c73622aSBram Moolenaar " store fold info for later use 5655c73622aSBram Moolenaar let s:newfold = {'firstline': s:lnum, 'lastline': foldclosedend(s:lnum), 'level': s:level,'type': "closed-fold"} 5665c73622aSBram Moolenaar call add(s:allfolds, s:newfold) 5675c73622aSBram Moolenaar " open the fold so we can find any contained folds 5685c73622aSBram Moolenaar execute s:lnum."foldopen" 5695c73622aSBram Moolenaar else 570076e8b2aSBram Moolenaar if !s:settings.no_progress 571349b2fb0SBram Moolenaar call s:pgb.incr() 572349b2fb0SBram Moolenaar if s:pgb.needs_redraw 573349b2fb0SBram Moolenaar redrawstatus 574349b2fb0SBram Moolenaar let s:pgb.needs_redraw = 0 575349b2fb0SBram Moolenaar endif 576349b2fb0SBram Moolenaar endif 5775c73622aSBram Moolenaar let s:lnum = s:lnum + 1 5785c73622aSBram Moolenaar endif 5795c73622aSBram Moolenaar endwhile 5805c73622aSBram Moolenaar 5815c73622aSBram Moolenaar " close all folds to get info for originally open folds 5825c73622aSBram Moolenaar silent! %foldclose! 5835c73622aSBram Moolenaar let s:lnum = 1 5845c73622aSBram Moolenaar 5855c73622aSBram Moolenaar " the originally open folds will be all folds we encounter that aren't 5865c73622aSBram Moolenaar " already in the list of closed folds 587349b2fb0SBram Moolenaar while s:lnum <= s:end 5885c73622aSBram Moolenaar if foldclosed(s:lnum) == s:lnum 5895c73622aSBram Moolenaar " default fold text has '+-' and then a number of dashes equal to fold 5905c73622aSBram Moolenaar " level, so subtract 2 from index of first non-dash after the dashes 5915c73622aSBram Moolenaar " in order to get the fold level of the current fold 5925c73622aSBram Moolenaar let s:level = match(foldtextresult(s:lnum), '+-*\zs[^-]') - 2 5935c73622aSBram Moolenaar if s:level+1 > s:foldcolumn 5945c73622aSBram Moolenaar let s:foldcolumn = s:level+1 5955c73622aSBram Moolenaar endif 5965c73622aSBram Moolenaar let s:newfold = {'firstline': s:lnum, 'lastline': foldclosedend(s:lnum), 'level': s:level,'type': "closed-fold"} 5975c73622aSBram Moolenaar " only add the fold if we don't already have it 5985c73622aSBram Moolenaar if empty(s:allfolds) || index(s:allfolds, s:newfold) == -1 5995c73622aSBram Moolenaar let s:newfold.type = "open-fold" 6005c73622aSBram Moolenaar call add(s:allfolds, s:newfold) 6015c73622aSBram Moolenaar endif 6025c73622aSBram Moolenaar " open the fold so we can find any contained folds 6035c73622aSBram Moolenaar execute s:lnum."foldopen" 6045c73622aSBram Moolenaar else 605076e8b2aSBram Moolenaar if !s:settings.no_progress 606349b2fb0SBram Moolenaar call s:pgb.incr() 607349b2fb0SBram Moolenaar if s:pgb.needs_redraw 608349b2fb0SBram Moolenaar redrawstatus 609349b2fb0SBram Moolenaar let s:pgb.needs_redraw = 0 610349b2fb0SBram Moolenaar endif 611349b2fb0SBram Moolenaar endif 6125c73622aSBram Moolenaar let s:lnum = s:lnum + 1 6135c73622aSBram Moolenaar endif 6145c73622aSBram Moolenaar endwhile 6155c73622aSBram Moolenaar 6165c73622aSBram Moolenaar " sort the folds so that we only ever need to look at the first item in the 6175c73622aSBram Moolenaar " list of folds 6185c73622aSBram Moolenaar call sort(s:allfolds, "s:FoldCompare") 6195c73622aSBram Moolenaar 620349b2fb0SBram Moolenaar let &l:foldtext = s:foldtext_save 6215c73622aSBram Moolenaar unlet s:foldtext_save 6225c73622aSBram Moolenaar 6235c73622aSBram Moolenaar " close all folds again so we can get the fold text as we go 6245c73622aSBram Moolenaar silent! %foldclose! 6255c73622aSBram Moolenaarendif 6265c73622aSBram Moolenaar 6275c73622aSBram Moolenaar" Now loop over all lines in the original text to convert to html. 628071d4279SBram Moolenaar" Use html_start_line and html_end_line if they are set. 629b02cbe34SBram Moolenaarif exists("g:html_start_line") 630071d4279SBram Moolenaar let s:lnum = html_start_line 631071d4279SBram Moolenaar if s:lnum < 1 || s:lnum > line("$") 632071d4279SBram Moolenaar let s:lnum = 1 633071d4279SBram Moolenaar endif 634071d4279SBram Moolenaarelse 635071d4279SBram Moolenaar let s:lnum = 1 636071d4279SBram Moolenaarendif 637b02cbe34SBram Moolenaarif exists("g:html_end_line") 638071d4279SBram Moolenaar let s:end = html_end_line 639071d4279SBram Moolenaar if s:end < s:lnum || s:end > line("$") 640071d4279SBram Moolenaar let s:end = line("$") 641071d4279SBram Moolenaar endif 642071d4279SBram Moolenaarelse 643071d4279SBram Moolenaar let s:end = line("$") 644071d4279SBram Moolenaarendif 645071d4279SBram Moolenaar 6465c73622aSBram Moolenaar" stack to keep track of all the folds containing the current line 6475c73622aSBram Moolenaarlet s:foldstack = [] 6485c73622aSBram Moolenaar 649076e8b2aSBram Moolenaarif !s:settings.no_progress 650349b2fb0SBram Moolenaar let s:pgb = s:ProgressBar("Processing lines:", s:end - s:lnum + 1, s:orgwin) 651349b2fb0SBram Moolenaarendif 652349b2fb0SBram Moolenaar 653076e8b2aSBram Moolenaarif s:settings.number_lines 6545c73622aSBram Moolenaar let s:margin = strlen(s:end) + 1 6555c73622aSBram Moolenaarelse 6565c73622aSBram Moolenaar let s:margin = 0 6575c73622aSBram Moolenaarendif 6585c73622aSBram Moolenaar 659076e8b2aSBram Moolenaarif has('folding') && !s:settings.ignore_folding 66035a9aaabSBram Moolenaar let s:foldfillchar = &fillchars[matchend(&fillchars, 'fold:')] 66135a9aaabSBram Moolenaar if s:foldfillchar == '' 66235a9aaabSBram Moolenaar let s:foldfillchar = '-' 6637b0294cbSBram Moolenaar endif 66435a9aaabSBram Moolenaarendif 66535a9aaabSBram Moolenaarlet s:difffillchar = &fillchars[matchend(&fillchars, 'diff:')] 66635a9aaabSBram Moolenaarif s:difffillchar == '' 66735a9aaabSBram Moolenaar let s:difffillchar = '-' 6687b0294cbSBram Moolenaarendif 6697b0294cbSBram Moolenaar 6705c73622aSBram Moolenaarlet s:foldId = 0 6717b0294cbSBram Moolenaar 672071d4279SBram Moolenaarwhile s:lnum <= s:end 673071d4279SBram Moolenaar 67447136d70SBram Moolenaar " If there are filler lines for diff mode, show these above the line. 67547136d70SBram Moolenaar let s:filler = diff_filler(s:lnum) 67647136d70SBram Moolenaar if s:filler > 0 67747136d70SBram Moolenaar let s:n = s:filler 67847136d70SBram Moolenaar while s:n > 0 67935a9aaabSBram Moolenaar let s:new = repeat(s:difffillchar, 3) 68047136d70SBram Moolenaar 681076e8b2aSBram Moolenaar if s:n > 2 && s:n < s:filler && !s:settings.whole_filler 68235a9aaabSBram Moolenaar let s:new = s:new . " " . s:filler . " inserted lines " 68335a9aaabSBram Moolenaar let s:n = 2 68435a9aaabSBram Moolenaar endif 68535a9aaabSBram Moolenaar 686076e8b2aSBram Moolenaar if !s:settings.no_pre 68735a9aaabSBram Moolenaar " HTML line wrapping is off--go ahead and fill to the margin 6885c73622aSBram Moolenaar let s:new = s:new . repeat(s:difffillchar, &columns - strlen(s:new) - s:margin) 6895c73622aSBram Moolenaar else 6905c73622aSBram Moolenaar let s:new = s:new . repeat(s:difffillchar, 3) 69135a9aaabSBram Moolenaar endif 69235a9aaabSBram Moolenaar 6938ada2ccaSBram Moolenaar let s:new = s:HtmlFormat(s:new, "DiffDelete", "") 694076e8b2aSBram Moolenaar if s:settings.number_lines 6955c73622aSBram Moolenaar " Indent if line numbering is on; must be after escaping. 6965c73622aSBram Moolenaar let s:new = repeat(s:LeadingSpace, s:margin) . s:new 6975c73622aSBram Moolenaar endif 698349b2fb0SBram Moolenaar call add(s:lines, s:new.s:HtmlEndline) 69935a9aaabSBram Moolenaar 70047136d70SBram Moolenaar let s:n = s:n - 1 70147136d70SBram Moolenaar endwhile 70247136d70SBram Moolenaar unlet s:n 70347136d70SBram Moolenaar endif 70447136d70SBram Moolenaar unlet s:filler 70547136d70SBram Moolenaar 70647136d70SBram Moolenaar " Start the line with the line number. 707076e8b2aSBram Moolenaar if s:settings.number_lines 7085c73622aSBram Moolenaar let s:numcol = repeat(' ', s:margin - 1 - strlen(s:lnum)) . s:lnum . ' ' 70947136d70SBram Moolenaar else 7105c73622aSBram Moolenaar let s:numcol = "" 71147136d70SBram Moolenaar endif 71247136d70SBram Moolenaar 7135c73622aSBram Moolenaar let s:new = "" 7145c73622aSBram Moolenaar 715076e8b2aSBram Moolenaar if has('folding') && !s:settings.ignore_folding && foldclosed(s:lnum) > -1 && !s:settings.dynamic_folds 7167b0294cbSBram Moolenaar " 7175c73622aSBram Moolenaar " This is the beginning of a folded block (with no dynamic folding) 7187b0294cbSBram Moolenaar " 7195c73622aSBram Moolenaar let s:new = s:numcol . foldtextresult(s:lnum) 720076e8b2aSBram Moolenaar if !s:settings.no_pre 72135a9aaabSBram Moolenaar " HTML line wrapping is off--go ahead and fill to the margin 72235a9aaabSBram Moolenaar let s:new = s:new . repeat(s:foldfillchar, &columns - strlen(s:new)) 7237b0294cbSBram Moolenaar endif 7247b0294cbSBram Moolenaar 7258ada2ccaSBram Moolenaar let s:new = s:HtmlFormat(s:new, "Folded", "") 7267b0294cbSBram Moolenaar 7277b0294cbSBram Moolenaar " Skip to the end of the fold 728349b2fb0SBram Moolenaar let s:new_lnum = foldclosedend(s:lnum) 729349b2fb0SBram Moolenaar 730076e8b2aSBram Moolenaar if !s:settings.no_progress 731349b2fb0SBram Moolenaar call s:pgb.incr(s:new_lnum - s:lnum) 732349b2fb0SBram Moolenaar endif 733349b2fb0SBram Moolenaar 734349b2fb0SBram Moolenaar let s:lnum = s:new_lnum 7357b0294cbSBram Moolenaar 7367b0294cbSBram Moolenaar else 7377b0294cbSBram Moolenaar " 7385c73622aSBram Moolenaar " A line that is not folded, or doing dynamic folding. 7397b0294cbSBram Moolenaar " 74035a9aaabSBram Moolenaar let s:line = getline(s:lnum) 7417b0294cbSBram Moolenaar let s:len = strlen(s:line) 7427b0294cbSBram Moolenaar 743076e8b2aSBram Moolenaar if s:settings.dynamic_folds 7445c73622aSBram Moolenaar " First insert a closing for any open folds that end on this line 7455c73622aSBram Moolenaar while !empty(s:foldstack) && get(s:foldstack,0).lastline == s:lnum-1 7465c73622aSBram Moolenaar let s:new = s:new."</span></span>" 7475c73622aSBram Moolenaar call remove(s:foldstack, 0) 7485c73622aSBram Moolenaar endwhile 7495c73622aSBram Moolenaar 7505c73622aSBram Moolenaar " Now insert an opening any new folds that start on this line 7515c73622aSBram Moolenaar let s:firstfold = 1 7525c73622aSBram Moolenaar while !empty(s:allfolds) && get(s:allfolds,0).firstline == s:lnum 7535c73622aSBram Moolenaar let s:foldId = s:foldId + 1 754349b2fb0SBram Moolenaar let s:new .= "<span id='" 755349b2fb0SBram Moolenaar let s:new .= (exists('g:html_diff_win_num') ? "win".g:html_diff_win_num : "") 756349b2fb0SBram Moolenaar let s:new .= "fold".s:foldId."' class='".s:allfolds[0].type."'>" 757349b2fb0SBram Moolenaar 7585c73622aSBram Moolenaar 7595c73622aSBram Moolenaar " Unless disabled, add a fold column for the opening line of a fold. 7605c73622aSBram Moolenaar " 7615c73622aSBram Moolenaar " Note that dynamic folds require using css so we just use css to take 7625c73622aSBram Moolenaar " care of the leading spaces rather than using in the case of 7635c73622aSBram Moolenaar " html_no_pre to make it easier 764076e8b2aSBram Moolenaar if !s:settings.no_foldcolumn 7655c73622aSBram Moolenaar " add fold column that can open the new fold 7665c73622aSBram Moolenaar if s:allfolds[0].level > 1 && s:firstfold 7675c73622aSBram Moolenaar let s:new = s:new . "<a class='toggle-open FoldColumn' href='javascript:toggleFold(\"fold".s:foldstack[0].id."\")'>" 7685c73622aSBram Moolenaar let s:new = s:new . repeat('|', s:allfolds[0].level - 1) . "</a>" 7695c73622aSBram Moolenaar endif 7705c73622aSBram Moolenaar let s:new = s:new . "<a class='toggle-open FoldColumn' href='javascript:toggleFold(\"fold".s:foldId."\")'>+</a>" 7715c73622aSBram Moolenaar let s:new = s:new . "<a class='toggle-open " 7725c73622aSBram Moolenaar " If this is not the last fold we're opening on this line, we need 7735c73622aSBram Moolenaar " to keep the filler spaces hidden if the fold is opened by mouse 7745c73622aSBram Moolenaar " hover. If it is the last fold to open in the line, we shouldn't hide 7755c73622aSBram Moolenaar " them, so don't apply the toggle-filler class. 7765c73622aSBram Moolenaar if get(s:allfolds, 1, {'firstline': 0}).firstline == s:lnum 7775c73622aSBram Moolenaar let s:new = s:new . "toggle-filler " 7785c73622aSBram Moolenaar endif 7795c73622aSBram Moolenaar let s:new = s:new . "FoldColumn' href='javascript:toggleFold(\"fold".s:foldId."\")'>" 7805c73622aSBram Moolenaar let s:new = s:new . repeat(" ", s:foldcolumn - s:allfolds[0].level) . "</a>" 7815c73622aSBram Moolenaar 7825c73622aSBram Moolenaar " add fold column that can close the new fold 7835c73622aSBram Moolenaar let s:new = s:new . "<a class='toggle-closed FoldColumn' href='javascript:toggleFold(\"fold".s:foldId."\")'>" 7845c73622aSBram Moolenaar if s:firstfold 7855c73622aSBram Moolenaar let s:new = s:new . repeat('|', s:allfolds[0].level - 1) 7865c73622aSBram Moolenaar endif 7875c73622aSBram Moolenaar let s:new = s:new . "-" 7885c73622aSBram Moolenaar " only add spaces if we aren't opening another fold on the same line 7895c73622aSBram Moolenaar if get(s:allfolds, 1, {'firstline': 0}).firstline != s:lnum 7905c73622aSBram Moolenaar let s:new = s:new . repeat(" ", s:foldcolumn - s:allfolds[0].level) 7915c73622aSBram Moolenaar endif 7925c73622aSBram Moolenaar let s:new = s:new . "</a>" 7935c73622aSBram Moolenaar let s:firstfold = 0 7945c73622aSBram Moolenaar endif 7955c73622aSBram Moolenaar 7965c73622aSBram Moolenaar " add fold text, moving the span ending to the next line so collapsing 7975c73622aSBram Moolenaar " of folds works correctly 7988ada2ccaSBram Moolenaar let s:new = s:new . substitute(s:HtmlFormat(s:numcol . foldtextresult(s:lnum), "Folded", ""), '</span>', s:HtmlEndline.'\n\0', '') 7995c73622aSBram Moolenaar let s:new = s:new . "<span class='fulltext'>" 8005c73622aSBram Moolenaar 8015c73622aSBram Moolenaar " open the fold now that we have the fold text to allow retrieval of 8025c73622aSBram Moolenaar " fold text for subsequent folds 8035c73622aSBram Moolenaar execute s:lnum."foldopen" 8045c73622aSBram Moolenaar call insert(s:foldstack, remove(s:allfolds,0)) 8055c73622aSBram Moolenaar let s:foldstack[0].id = s:foldId 8065c73622aSBram Moolenaar endwhile 8075c73622aSBram Moolenaar 8085c73622aSBram Moolenaar " Unless disabled, add a fold column for other lines. 8095c73622aSBram Moolenaar " 8105c73622aSBram Moolenaar " Note that dynamic folds require using css so we just use css to take 8115c73622aSBram Moolenaar " care of the leading spaces rather than using in the case of 8125c73622aSBram Moolenaar " html_no_pre to make it easier 813076e8b2aSBram Moolenaar if !s:settings.no_foldcolumn 8145c73622aSBram Moolenaar if empty(s:foldstack) 8157510fe74SBram Moolenaar " add the empty foldcolumn for unfolded lines if there is a fold 8167510fe74SBram Moolenaar " column at all 8177510fe74SBram Moolenaar if s:foldcolumn > 0 8188ada2ccaSBram Moolenaar let s:new = s:new . s:HtmlFormat(repeat(' ', s:foldcolumn), "FoldColumn", "") 8197510fe74SBram Moolenaar endif 8205c73622aSBram Moolenaar else 8215c73622aSBram Moolenaar " add the fold column for folds not on the opening line 8225c73622aSBram Moolenaar if get(s:foldstack, 0).firstline < s:lnum 8235c73622aSBram Moolenaar let s:new = s:new . "<a class='FoldColumn' href='javascript:toggleFold(\"fold".s:foldstack[0].id."\")'>" 8245c73622aSBram Moolenaar let s:new = s:new . repeat('|', s:foldstack[0].level) 8255c73622aSBram Moolenaar let s:new = s:new . repeat(' ', s:foldcolumn - s:foldstack[0].level) . "</a>" 8265c73622aSBram Moolenaar endif 8275c73622aSBram Moolenaar endif 8285c73622aSBram Moolenaar endif 8295c73622aSBram Moolenaar endif 8305c73622aSBram Moolenaar 8315c73622aSBram Moolenaar " Now continue with the unfolded line text 832076e8b2aSBram Moolenaar if s:settings.number_lines 8338ada2ccaSBram Moolenaar " TODO: why not use the real highlight name here? 8348ada2ccaSBram Moolenaar let s:new = s:new . s:HtmlFormat(s:numcol, "lnr", "") 835071d4279SBram Moolenaar endif 836071d4279SBram Moolenaar 83747136d70SBram Moolenaar " Get the diff attribute, if any. 83847136d70SBram Moolenaar let s:diffattr = diff_hlID(s:lnum, 1) 83947136d70SBram Moolenaar 8407510fe74SBram Moolenaar " initialize conceal info to act like not concealed, just in case 8417510fe74SBram Moolenaar let s:concealinfo = [0, ''] 8427510fe74SBram Moolenaar 843071d4279SBram Moolenaar " Loop over each character in the line 844071d4279SBram Moolenaar let s:col = 1 8458ada2ccaSBram Moolenaar 8468ada2ccaSBram Moolenaar " most of the time we won't use the diff_id, initialize to zero 8478ada2ccaSBram Moolenaar let s:diff_id = 0 8488ada2ccaSBram Moolenaar let s:diff_id_name = "" 8498ada2ccaSBram Moolenaar 85035a9aaabSBram Moolenaar while s:col <= s:len || (s:col == 1 && s:diffattr) 851071d4279SBram Moolenaar let s:startcol = s:col " The start column for processing text 852076e8b2aSBram Moolenaar if !s:settings.ignore_conceal && has('conceal') 8537510fe74SBram Moolenaar let s:concealinfo = synconcealed(s:lnum, s:col) 8547510fe74SBram Moolenaar endif 855076e8b2aSBram Moolenaar if !s:settings.ignore_conceal && s:concealinfo[0] 8567510fe74SBram Moolenaar let s:col = s:col + 1 8577510fe74SBram Moolenaar " Speed loop (it's small - that's the trick) 8587510fe74SBram Moolenaar " Go along till we find a change in the match sequence number (ending 8597510fe74SBram Moolenaar " the specific concealed region) or until there are no more concealed 8607510fe74SBram Moolenaar " characters. 8617510fe74SBram Moolenaar while s:col <= s:len && s:concealinfo == synconcealed(s:lnum, s:col) | let s:col = s:col + 1 | endwhile 8627510fe74SBram Moolenaar elseif s:diffattr 8638ada2ccaSBram Moolenaar let s:diff_id = diff_hlID(s:lnum, s:col) 8648ada2ccaSBram Moolenaar let s:id = synID(s:lnum, s:col, 1) 86547136d70SBram Moolenaar let s:col = s:col + 1 86647136d70SBram Moolenaar " Speed loop (it's small - that's the trick) 86747136d70SBram Moolenaar " Go along till we find a change in hlID 8688ada2ccaSBram Moolenaar while s:col <= s:len && s:id == synID(s:lnum, s:col, 1) 8698ada2ccaSBram Moolenaar \ && s:diff_id == diff_hlID(s:lnum, s:col) | 8708ada2ccaSBram Moolenaar \ let s:col = s:col + 1 | 8718ada2ccaSBram Moolenaar \ endwhile 872076e8b2aSBram Moolenaar if s:len < &columns && !s:settings.no_pre 8738ada2ccaSBram Moolenaar " Add spaces at the end of the raw text line to extend the changed 8748ada2ccaSBram Moolenaar " line to the full width. 8755c73622aSBram Moolenaar let s:line = s:line . repeat(' ', &columns - virtcol([s:lnum, s:len]) - s:margin) 87635a9aaabSBram Moolenaar let s:len = &columns 87735a9aaabSBram Moolenaar endif 87847136d70SBram Moolenaar else 879071d4279SBram Moolenaar let s:id = synID(s:lnum, s:col, 1) 880071d4279SBram Moolenaar let s:col = s:col + 1 881071d4279SBram Moolenaar " Speed loop (it's small - that's the trick) 882071d4279SBram Moolenaar " Go along till we find a change in synID 883071d4279SBram Moolenaar while s:col <= s:len && s:id == synID(s:lnum, s:col, 1) | let s:col = s:col + 1 | endwhile 88447136d70SBram Moolenaar endif 885071d4279SBram Moolenaar 886076e8b2aSBram Moolenaar if s:settings.ignore_conceal || !s:concealinfo[0] 88735a9aaabSBram Moolenaar " Expand tabs 88835a9aaabSBram Moolenaar let s:expandedtab = strpart(s:line, s:startcol - 1, s:col - s:startcol) 8895c73622aSBram Moolenaar let s:offset = 0 8905c73622aSBram Moolenaar let s:idx = stridx(s:expandedtab, "\t") 8915c73622aSBram Moolenaar while s:idx >= 0 8925c73622aSBram Moolenaar if has("multi_byte_encoding") 8935c73622aSBram Moolenaar if s:startcol + s:idx == 1 8945c73622aSBram Moolenaar let s:i = &ts 8955c73622aSBram Moolenaar else 8965c73622aSBram Moolenaar if s:idx == 0 8975c73622aSBram Moolenaar let s:prevc = matchstr(s:line, '.\%' . (s:startcol + s:idx + s:offset) . 'c') 8985c73622aSBram Moolenaar else 8995c73622aSBram Moolenaar let s:prevc = matchstr(s:expandedtab, '.\%' . (s:idx + 1) . 'c') 9005c73622aSBram Moolenaar endif 9015c73622aSBram Moolenaar let s:vcol = virtcol([s:lnum, s:startcol + s:idx + s:offset - len(s:prevc)]) 9025c73622aSBram Moolenaar let s:i = &ts - (s:vcol % &ts) 9035c73622aSBram Moolenaar endif 9045c73622aSBram Moolenaar let s:offset -= s:i - 1 9055c73622aSBram Moolenaar else 9065c73622aSBram Moolenaar let s:i = &ts - ((s:idx + s:startcol - 1) % &ts) 9075c73622aSBram Moolenaar endif 9085c73622aSBram Moolenaar let s:expandedtab = substitute(s:expandedtab, '\t', repeat(' ', s:i), '') 9095c73622aSBram Moolenaar let s:idx = stridx(s:expandedtab, "\t") 91035a9aaabSBram Moolenaar endwhile 91135a9aaabSBram Moolenaar 9127510fe74SBram Moolenaar " get the highlight group name to use 913071d4279SBram Moolenaar let s:id = synIDtrans(s:id) 914071d4279SBram Moolenaar let s:id_name = synIDattr(s:id, "name", s:whatterm) 9158ada2ccaSBram Moolenaar if s:diff_id 9168ada2ccaSBram Moolenaar let s:diff_id_name = synIDattr(s:diff_id, "name", s:whatterm) 9178ada2ccaSBram Moolenaar endif 9187510fe74SBram Moolenaar else 9197510fe74SBram Moolenaar " use Conceal highlighting for concealed text 9207510fe74SBram Moolenaar let s:id_name = 'Conceal' 9217510fe74SBram Moolenaar let s:expandedtab = s:concealinfo[1] 9227510fe74SBram Moolenaar endif 9237510fe74SBram Moolenaar 9247510fe74SBram Moolenaar " Output the text with the same synID, with class set to {s:id_name}, 9258ada2ccaSBram Moolenaar " unless it has been concealed completely. 9267510fe74SBram Moolenaar if strlen(s:expandedtab) > 0 9278ada2ccaSBram Moolenaar let s:new = s:new . s:HtmlFormat(s:expandedtab, s:id_name, s:diff_id_name) 9287510fe74SBram Moolenaar endif 929071d4279SBram Moolenaar endwhile 9307b0294cbSBram Moolenaar endif 931071d4279SBram Moolenaar 9327510fe74SBram Moolenaar call extend(s:lines, split(s:new.s:HtmlEndline, '\n', 1)) 933076e8b2aSBram Moolenaar if !s:settings.no_progress && s:pgb.needs_redraw 934349b2fb0SBram Moolenaar redrawstatus 935349b2fb0SBram Moolenaar let s:pgb.needs_redraw = 0 936349b2fb0SBram Moolenaar endif 937071d4279SBram Moolenaar let s:lnum = s:lnum + 1 938313b7237SBram Moolenaar 939076e8b2aSBram Moolenaar if !s:settings.no_progress 940349b2fb0SBram Moolenaar call s:pgb.incr() 941349b2fb0SBram Moolenaar endif 942349b2fb0SBram Moolenaarendwhile 943349b2fb0SBram Moolenaar 944076e8b2aSBram Moolenaarif s:settings.dynamic_folds 9455c73622aSBram Moolenaar " finish off any open folds 9465c73622aSBram Moolenaar while !empty(s:foldstack) 947349b2fb0SBram Moolenaar let s:lines[-1].="</span></span>" 9485c73622aSBram Moolenaar call remove(s:foldstack, 0) 9495c73622aSBram Moolenaar endwhile 9505c73622aSBram Moolenaar 9515c73622aSBram Moolenaar " add fold column to the style list if not already there 9525c73622aSBram Moolenaar let s:id = hlID('FoldColumn') 9538ada2ccaSBram Moolenaar if index(s:idlist, s:id) == -1 9548ada2ccaSBram Moolenaar call insert(s:idlist, s:id) 9555c73622aSBram Moolenaar endif 9565c73622aSBram Moolenaarendif 9575c73622aSBram Moolenaar 958076e8b2aSBram Moolenaarif s:settings.no_pre 959076e8b2aSBram Moolenaar if !s:settings.use_css 9608ada2ccaSBram Moolenaar " Close off the font tag that encapsulates the whole <body> 961bebca9daSBram Moolenaar call extend(s:lines, ["</font>", "</body>", "</html>"]) 9628ada2ccaSBram Moolenaar else 963349b2fb0SBram Moolenaar call extend(s:lines, ["</body>", "</html>"]) 9648ada2ccaSBram Moolenaar endif 965071d4279SBram Moolenaarelse 966349b2fb0SBram Moolenaar call extend(s:lines, ["</pre>", "</body>", "</html>"]) 967071d4279SBram Moolenaarendif 968071d4279SBram Moolenaar 969349b2fb0SBram Moolenaarexe s:newwin . "wincmd w" 970349b2fb0SBram Moolenaarcall setline(1, s:lines) 971349b2fb0SBram Moolenaarunlet s:lines 972071d4279SBram Moolenaar 973071d4279SBram Moolenaar" Now, when we finally know which, we define the colors and styles 974076e8b2aSBram Moolenaarif s:settings.use_css 975071d4279SBram Moolenaar 1;/<style type="text/+1 976071d4279SBram Moolenaarendif 977071d4279SBram Moolenaar 978071d4279SBram Moolenaar" Find out the background and foreground color. 979071d4279SBram Moolenaarlet s:fgc = s:HtmlColor(synIDattr(hlID("Normal"), "fg#", s:whatterm)) 980071d4279SBram Moolenaarlet s:bgc = s:HtmlColor(synIDattr(hlID("Normal"), "bg#", s:whatterm)) 981071d4279SBram Moolenaarif s:fgc == "" 982071d4279SBram Moolenaar let s:fgc = ( &background == "dark" ? "#ffffff" : "#000000" ) 983071d4279SBram Moolenaarendif 984071d4279SBram Moolenaarif s:bgc == "" 985071d4279SBram Moolenaar let s:bgc = ( &background == "dark" ? "#000000" : "#ffffff" ) 986071d4279SBram Moolenaarendif 987071d4279SBram Moolenaar 988071d4279SBram Moolenaar" Normal/global attributes 989071d4279SBram Moolenaar" For Netscape 4, set <body> attributes too, though, strictly speaking, it's 990071d4279SBram Moolenaar" incorrect. 991076e8b2aSBram Moolenaarif s:settings.use_css 992076e8b2aSBram Moolenaar if s:settings.no_pre 993313b7237SBram Moolenaar execute "normal! A\nbody { color: " . s:fgc . "; background-color: " . s:bgc . "; font-family: ". s:htmlfont ."; }\e" 994071d4279SBram Moolenaar else 995313b7237SBram Moolenaar execute "normal! A\npre { font-family: ". s:htmlfont ."; color: " . s:fgc . "; background-color: " . s:bgc . "; }\e" 996071d4279SBram Moolenaar yank 997071d4279SBram Moolenaar put 998071d4279SBram Moolenaar execute "normal! ^cwbody\e" 999071d4279SBram Moolenaar endif 1000071d4279SBram Moolenaarelse 1001bebca9daSBram Moolenaar execute '%s:<body>:<body bgcolor="' . s:bgc . '" text="' . s:fgc . '">\r<font face="'. s:htmlfont .'">' 1002071d4279SBram Moolenaarendif 1003071d4279SBram Moolenaar 1004071d4279SBram Moolenaar" Line numbering attributes 1005076e8b2aSBram Moolenaarif s:settings.number_lines 1006076e8b2aSBram Moolenaar if s:settings.use_css 1007071d4279SBram Moolenaar execute "normal! A\n.lnr { " . s:CSS1(hlID("LineNr")) . "}\e" 1008071d4279SBram Moolenaar else 10098424a624SBram Moolenaar execute '%s+^<span class="lnr">\([^<]*\)</span>+' . s:HtmlOpening(hlID("LineNr")) . '\1' . s:HtmlClosing(hlID("LineNr")) . '+g' 1010071d4279SBram Moolenaar endif 1011071d4279SBram Moolenaarendif 1012071d4279SBram Moolenaar 1013071d4279SBram Moolenaar" Gather attributes for all other classes 1014076e8b2aSBram Moolenaarif !s:settings.no_progress && !empty(s:idlist) 1015349b2fb0SBram Moolenaar let s:pgb = s:ProgressBar("Processing classes:", len(s:idlist),s:newwin) 1016349b2fb0SBram Moolenaarendif 1017349b2fb0SBram Moolenaarwhile !empty(s:idlist) 1018071d4279SBram Moolenaar let s:attr = "" 1019349b2fb0SBram Moolenaar let s:id = remove(s:idlist, 0) 1020071d4279SBram Moolenaar let s:attr = s:CSS1(s:id) 1021071d4279SBram Moolenaar let s:id_name = synIDattr(s:id, "name", s:whatterm) 1022349b2fb0SBram Moolenaar 1023071d4279SBram Moolenaar " If the class has some attributes, export the style, otherwise DELETE all 1024071d4279SBram Moolenaar " its occurences to make the HTML shorter 1025071d4279SBram Moolenaar if s:attr != "" 1026076e8b2aSBram Moolenaar if s:settings.use_css 1027071d4279SBram Moolenaar execute "normal! A\n." . s:id_name . " { " . s:attr . "}" 1028071d4279SBram Moolenaar else 10298ada2ccaSBram Moolenaar " replace spans of just this class name with non-CSS style markup 10308ada2ccaSBram Moolenaar execute '%s+<span class="' . s:id_name . '">\([^<]*\)</span>+' . s:HtmlOpening(s:id) . '\1' . s:HtmlClosing(s:id) . '+ge' 10318ada2ccaSBram Moolenaar " Replace spans of this class name AND a diff class with non-CSS style 10328ada2ccaSBram Moolenaar " markup surrounding a span of just the diff class. The diff class will 10338ada2ccaSBram Moolenaar " be handled later because we know that information is at the end. 10348ada2ccaSBram 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' 1035071d4279SBram Moolenaar endif 1036071d4279SBram Moolenaar else 1037313b7237SBram Moolenaar execute '%s+<span class="' . s:id_name . '">\([^<]*\)</span>+\1+ge' 10388ada2ccaSBram Moolenaar execute '%s+<span class="' . s:id_name . ' \(Diff\%(Add\|Change\|Delete\|Text\)\)">\([^<]*\)</span>+<span class="\1">\2</span>+ge' 1039076e8b2aSBram Moolenaar if s:settings.use_css 10408ada2ccaSBram Moolenaar 1;/<\/style>/-2 1041071d4279SBram Moolenaar endif 1042071d4279SBram Moolenaar endif 1043349b2fb0SBram Moolenaar 1044076e8b2aSBram Moolenaar if !s:settings.no_progress 1045349b2fb0SBram Moolenaar call s:pgb.incr() 1046349b2fb0SBram Moolenaar if s:pgb.needs_redraw 1047349b2fb0SBram Moolenaar redrawstatus 1048349b2fb0SBram Moolenaar let s:pgb.needs_redraw = 0 1049bebca9daSBram Moolenaar " TODO: sleep here to show the progress bar, but only if total time spent 1050bebca9daSBram Moolenaar " so far on this step is < 1 second? Too slow for batch runs like the test 1051bebca9daSBram Moolenaar " suite to sleep all the time. Maybe there's no good reason to sleep at 1052bebca9daSBram Moolenaar " all. 1053349b2fb0SBram Moolenaar endif 1054349b2fb0SBram Moolenaar endif 1055071d4279SBram Moolenaarendwhile 1056071d4279SBram Moolenaar 1057071d4279SBram Moolenaar" Add hyperlinks 10581cd871b5SBram Moolenaar%s+\(https\=://\S\{-}\)\(\([.,;:}]\=\(\s\|$\)\)\|[\\"'<>]\|>\|<\|"\)+<a href="\1">\1</a>\2+ge 1059071d4279SBram Moolenaar 1060071d4279SBram Moolenaar" The DTD 1061076e8b2aSBram Moolenaarif s:settings.use_xhtml 1062076e8b2aSBram 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\">" 1063076e8b2aSBram Moolenaarelseif s:settings.use_css && !s:settings.no_pre 1064076e8b2aSBram Moolenaar exe "normal! gg0i<!DOCTYPE HTML PUBLIC \"-//W3C//DTD HTML 4.01//EN\" \"http://www.w3.org/TR/html4/strict.dtd\">\n" 10651cd871b5SBram Moolenaarelse 1066076e8b2aSBram Moolenaar exe "normal! gg0i<!DOCTYPE HTML PUBLIC \"-//W3C//DTD HTML 4.01 Transitional//EN\" \"http://www.w3.org/TR/html4/loose.dtd\">\n" 10671cd871b5SBram Moolenaarendif 10681cd871b5SBram Moolenaar 1069076e8b2aSBram Moolenaarif s:settings.use_xhtml 10701cd871b5SBram Moolenaar exe "normal! gg/<html/e\na xmlns=\"http://www.w3.org/1999/xhtml\"\e" 10711cd871b5SBram Moolenaarendif 1072071d4279SBram Moolenaar 1073071d4279SBram Moolenaar" Cleanup 1074071d4279SBram Moolenaar%s:\s\+$::e 1075071d4279SBram Moolenaar 1076071d4279SBram Moolenaar" Restore old settings 10778df7f888SBram Moolenaarlet &l:foldenable = s:old_fen 1078349b2fb0SBram Moolenaarlet &l:foldmethod = s:old_fdm 1079071d4279SBram Moolenaarlet &report = s:old_report 1080071d4279SBram Moolenaarlet &title = s:old_title 1081071d4279SBram Moolenaarlet &icon = s:old_icon 1082071d4279SBram Moolenaarlet &paste = s:old_paste 1083071d4279SBram Moolenaarlet &magic = s:old_magic 1084071d4279SBram Moolenaarlet @/ = s:old_search 1085349b2fb0SBram Moolenaarlet &more = s:old_more 1086071d4279SBram Moolenaarexe s:orgwin . "wincmd w" 1087*166af9bbSBram Moolenaarlet &l:stl = s:origwin_stl 1088071d4279SBram Moolenaarlet &l:et = s:old_et 10898df7f888SBram Moolenaarlet &l:scrollbind = s:old_bind 1090071d4279SBram Moolenaarexe s:newwin . "wincmd w" 1091*166af9bbSBram Moolenaarlet &l:stl = s:newwin_stl 1092349b2fb0SBram Moolenaarexec 'resize' s:old_winheight 1093349b2fb0SBram Moolenaarlet &l:winfixheight = s:old_winfixheight 1094071d4279SBram Moolenaar 1095349b2fb0SBram Moolenaarlet &ls=s:ls 1096349b2fb0SBram Moolenaar 1097071d4279SBram Moolenaar" Save a little bit of memory (worth doing?) 1098313b7237SBram Moolenaarunlet s:htmlfont 10998df7f888SBram Moolenaarunlet s:old_et s:old_paste s:old_icon s:old_report s:old_title s:old_search 11008df7f888SBram Moolenaarunlet s:old_magic s:old_more s:old_fdm s:old_fen s:old_winheight 11018df7f888SBram Moolenaarunlet s:whatterm s:idlist s:lnum s:end s:margin s:fgc s:bgc s:old_winfixheight 1102076e8b2aSBram Moolenaarunlet! s:col s:id s:attr s:len s:line s:new s:expandedtab s:concealinfo 11038df7f888SBram Moolenaarunlet! s:orgwin s:newwin s:orgbufnr s:idx s:i s:offset s:ls s:origwin_stl 11048df7f888SBram Moolenaarunlet! s:newwin_stl s:current_syntax 110505159a0cSBram Moolenaarif !v:profiling 1106071d4279SBram Moolenaar delfunc s:HtmlColor 110735a9aaabSBram Moolenaar delfunc s:HtmlFormat 1108071d4279SBram Moolenaar delfunc s:CSS1 1109076e8b2aSBram Moolenaar if !s:settings.use_css 1110071d4279SBram Moolenaar delfunc s:HtmlOpening 1111071d4279SBram Moolenaar delfunc s:HtmlClosing 1112071d4279SBram Moolenaar endif 1113076e8b2aSBram Moolenaar if s:settings.dynamic_folds 11145c73622aSBram Moolenaar delfunc s:FoldCompare 11155c73622aSBram Moolenaar endif 11165c73622aSBram Moolenaar 1117076e8b2aSBram Moolenaar if !s:settings.no_progress 1118349b2fb0SBram Moolenaar delfunc s:ProgressBar 1119349b2fb0SBram Moolenaar delfunc s:progressbar.paint 1120349b2fb0SBram Moolenaar delfunc s:progressbar.incr 1121349b2fb0SBram Moolenaar unlet s:pgb s:progressbar 1122349b2fb0SBram Moolenaar endif 1123349b2fb0SBram Moolenaarendif 1124349b2fb0SBram Moolenaar 11258df7f888SBram Moolenaarunlet! s:new_lnum s:diffattr s:difffillchar s:foldfillchar s:HtmlSpace 11268df7f888SBram Moolenaarunlet! s:LeadingSpace s:HtmlEndline s:firstfold s:foldcolumn 1127076e8b2aSBram Moolenaarunlet s:foldstack s:allfolds s:foldId s:numcol s:settings 11285c73622aSBram Moolenaar 11295c73622aSBram Moolenaarlet &cpo = s:cpo_sav 1130349b2fb0SBram Moolenaarunlet! s:cpo_sav 11315c73622aSBram Moolenaar 1132349b2fb0SBram Moolenaar" Make sure any patches will probably use consistent indent 11337c86f4ccSBram Moolenaar" vim: ts=8 sw=2 sts=2 noet 1134