1071d4279SBram Moolenaar" Vim syntax support file 2349b2fb0SBram Moolenaar" Maintainer: Ben Fritz <[email protected]> 3*2a8a3ecbSBram Moolenaar" Last Change: 2011 Jan 06 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 127*2a8a3ecbSBram Moolenaar let formatted = substitute(formatted, '&', '\&', 'g') 128*2a8a3ecbSBram Moolenaar let formatted = substitute(formatted, '<', '\<', 'g') 129*2a8a3ecbSBram Moolenaar let formatted = substitute(formatted, '>', '\>', 'g') 130*2a8a3ecbSBram Moolenaar let formatted = substitute(formatted, '"', '\"', 'g') 131*2a8a3ecbSBram Moolenaar " TODO: Use ' for "'"? 132*2a8a3ecbSBram Moolenaar 133*2a8a3ecbSBram Moolenaar " Replace a "form feed" character with HTML to do a page break 134*2a8a3ecbSBram Moolenaar let formatted = substitute(formatted, "\x0c", '<hr class="PAGE-BREAK">', 'g') 135*2a8a3ecbSBram Moolenaar 136*2a8a3ecbSBram Moolenaar " Mangle modelines so Vim doesn't try to use HTML text as a modeline if 137*2a8a3ecbSBram Moolenaar " editing this file in the future 138*2a8a3ecbSBram Moolenaar let formatted = substitute(formatted, '\v(\s+%(vim?|ex)):', '\1\:', 'g') 13935a9aaabSBram Moolenaar 1408df7f888SBram Moolenaar " Replace double spaces, leading spaces, and trailing spaces if needed 14135a9aaabSBram Moolenaar if ' ' != s:HtmlSpace 14235a9aaabSBram Moolenaar let formatted = substitute(formatted, ' ', s:HtmlSpace . s:HtmlSpace, 'g') 1438424a624SBram Moolenaar let formatted = substitute(formatted, '^ ', s:HtmlSpace, 'g') 1448df7f888SBram Moolenaar let formatted = substitute(formatted, ' \+$', s:HtmlSpace, 'g') 14535a9aaabSBram Moolenaar endif 14635a9aaabSBram Moolenaar 14735a9aaabSBram Moolenaar " Enclose in a span of class style_name 1488ada2ccaSBram Moolenaar let formatted = '<span class="' . l:style_name . '">' . formatted . '</span>' 14935a9aaabSBram Moolenaar 1508ada2ccaSBram Moolenaar " Add the class to class list if it's not there yet. 1518ada2ccaSBram Moolenaar " Add normal groups to the beginning so diff groups can override them. 15235a9aaabSBram Moolenaar let s:id = hlID(a:style_name) 1538ada2ccaSBram Moolenaar if index(s:idlist, s:id ) == -1 1548ada2ccaSBram Moolenaar if a:style_name =~ 'Diff\%(Add\|Change\|Delete\|Text\)' 1558ada2ccaSBram Moolenaar call add(s:idlist, s:id) 1568ada2ccaSBram Moolenaar else 1578ada2ccaSBram Moolenaar call insert(s:idlist, s:id) 1588ada2ccaSBram Moolenaar endif 1598ada2ccaSBram Moolenaar endif 1608ada2ccaSBram Moolenaar 1618ada2ccaSBram Moolenaar " Add the diff highlight class to class list if used and it's not there yet. 1628ada2ccaSBram Moolenaar " Add diff groups to the end so they override the other highlighting. 1638ada2ccaSBram Moolenaar if a:diff_style_name != "" 1648ada2ccaSBram Moolenaar let s:diff_id = hlID(a:diff_style_name) 1658ada2ccaSBram Moolenaar if index(s:idlist, s:diff_id) == -1 1668ada2ccaSBram Moolenaar call add(s:idlist, s:diff_id) 1678ada2ccaSBram Moolenaar endif 16835a9aaabSBram Moolenaar endif 16935a9aaabSBram Moolenaar 17035a9aaabSBram Moolenaar return formatted 17135a9aaabSBram Moolenaarendfun 17235a9aaabSBram Moolenaar 173071d4279SBram Moolenaar" Return CSS style describing given highlight id (can be empty) 174071d4279SBram Moolenaarfunction! s:CSS1(id) 175071d4279SBram Moolenaar let a = "" 176071d4279SBram Moolenaar if synIDattr(a:id, "inverse") 177071d4279SBram Moolenaar " For inverse, we always must set both colors (and exchange them) 178071d4279SBram Moolenaar let x = s:HtmlColor(synIDattr(a:id, "bg#", s:whatterm)) 179071d4279SBram Moolenaar let a = a . "color: " . ( x != "" ? x : s:bgc ) . "; " 180071d4279SBram Moolenaar let x = s:HtmlColor(synIDattr(a:id, "fg#", s:whatterm)) 181071d4279SBram Moolenaar let a = a . "background-color: " . ( x != "" ? x : s:fgc ) . "; " 182071d4279SBram Moolenaar else 183071d4279SBram Moolenaar let x = s:HtmlColor(synIDattr(a:id, "fg#", s:whatterm)) 184071d4279SBram Moolenaar if x != "" | let a = a . "color: " . x . "; " | endif 185071d4279SBram Moolenaar let x = s:HtmlColor(synIDattr(a:id, "bg#", s:whatterm)) 186071d4279SBram Moolenaar if x != "" | let a = a . "background-color: " . x . "; " | endif 187071d4279SBram Moolenaar endif 188071d4279SBram Moolenaar if synIDattr(a:id, "bold") | let a = a . "font-weight: bold; " | endif 189071d4279SBram Moolenaar if synIDattr(a:id, "italic") | let a = a . "font-style: italic; " | endif 190071d4279SBram Moolenaar if synIDattr(a:id, "underline") | let a = a . "text-decoration: underline; " | endif 191071d4279SBram Moolenaar return a 192071d4279SBram Moolenaarendfun 193071d4279SBram Moolenaar 194076e8b2aSBram Moolenaarif s:settings.dynamic_folds 1955c73622aSBram Moolenaar " compares two folds as stored in our list of folds 1965c73622aSBram Moolenaar " A fold is "less" than another if it starts at an earlier line number, 1975c73622aSBram Moolenaar " or ends at a later line number, ties broken by fold level 1985c73622aSBram Moolenaar function! s:FoldCompare(f1, f2) 1995c73622aSBram Moolenaar if a:f1.firstline != a:f2.firstline 2005c73622aSBram Moolenaar " put it before if it starts earlier 2015c73622aSBram Moolenaar return a:f1.firstline - a:f2.firstline 2025c73622aSBram Moolenaar elseif a:f1.lastline != a:f2.lastline 2035c73622aSBram Moolenaar " put it before if it ends later 2045c73622aSBram Moolenaar return a:f2.lastline - a:f1.lastline 2055c73622aSBram Moolenaar else 2065c73622aSBram Moolenaar " if folds begin and end on the same lines, put lowest fold level first 2075c73622aSBram Moolenaar return a:f1.level - a:f2.level 2085c73622aSBram Moolenaar endif 2095c73622aSBram Moolenaar endfunction 2105c73622aSBram Moolenaar 2115c73622aSBram Moolenaarendif 2125c73622aSBram Moolenaar 213071d4279SBram Moolenaar 214071d4279SBram Moolenaar" Set some options to make it work faster. 215071d4279SBram Moolenaar" Don't report changes for :substitute, there will be many of them. 2168df7f888SBram Moolenaar" Don't change other windows; turn off scroll bind temporarily 217071d4279SBram Moolenaarlet s:old_title = &title 218071d4279SBram Moolenaarlet s:old_icon = &icon 219071d4279SBram Moolenaarlet s:old_et = &l:et 2208df7f888SBram Moolenaarlet s:old_bind = &l:scrollbind 221071d4279SBram Moolenaarlet s:old_report = &report 222071d4279SBram Moolenaarlet s:old_search = @/ 223349b2fb0SBram Moolenaarlet s:old_more = &more 224071d4279SBram Moolenaarset notitle noicon 225071d4279SBram Moolenaarsetlocal et 226349b2fb0SBram Moolenaarset nomore 227071d4279SBram Moolenaarset report=1000000 2288df7f888SBram Moolenaarsetlocal noscrollbind 229071d4279SBram Moolenaar 2307510fe74SBram Moolenaarif exists(':ownsyntax') && exists('w:current_syntax') 2317510fe74SBram Moolenaar let s:current_syntax = w:current_syntax 2327510fe74SBram Moolenaarelseif exists('b:current_syntax') 2337510fe74SBram Moolenaar let s:current_syntax = b:current_syntax 2347510fe74SBram Moolenaarelse 2357510fe74SBram Moolenaar let s:current_syntax = 'none' 2367510fe74SBram Moolenaarendif 2377510fe74SBram Moolenaar 2387510fe74SBram Moolenaarif s:current_syntax == '' 2397510fe74SBram Moolenaar let s:current_syntax = 'none' 2407510fe74SBram Moolenaarendif 2417510fe74SBram Moolenaar 242071d4279SBram Moolenaar" Split window to create a buffer with the HTML file. 243071d4279SBram Moolenaarlet s:orgbufnr = winbufnr(0) 244349b2fb0SBram Moolenaarlet s:origwin_stl = &l:stl 245071d4279SBram Moolenaarif expand("%") == "" 246076e8b2aSBram Moolenaar exec 'new Untitled.'.(s:settings.use_xhtml ? 'x' : '').'html' 247071d4279SBram Moolenaarelse 248076e8b2aSBram Moolenaar exec 'new %.'.(s:settings.use_xhtml ? 'x' : '').'html' 249071d4279SBram Moolenaarendif 250349b2fb0SBram Moolenaar 251349b2fb0SBram Moolenaar" Resize the new window to very small in order to make it draw faster 252349b2fb0SBram Moolenaarlet s:old_winheight = winheight(0) 253349b2fb0SBram Moolenaarlet s:old_winfixheight = &l:winfixheight 254349b2fb0SBram Moolenaarif s:old_winheight > 2 255349b2fb0SBram Moolenaar resize 1 " leave enough room to view one line at a time 256349b2fb0SBram Moolenaar norm! G 257349b2fb0SBram Moolenaar norm! zt 258349b2fb0SBram Moolenaarendif 259349b2fb0SBram Moolenaarsetlocal winfixheight 260349b2fb0SBram Moolenaar 261349b2fb0SBram Moolenaarlet s:newwin_stl = &l:stl 262349b2fb0SBram Moolenaar 263349b2fb0SBram Moolenaar" on the new window, set the least time-consuming fold method 264349b2fb0SBram Moolenaarlet s:old_fdm = &foldmethod 2658df7f888SBram Moolenaarlet s:old_fen = &foldenable 266349b2fb0SBram Moolenaarsetlocal foldmethod=manual 2678df7f888SBram Moolenaarsetlocal nofoldenable 268349b2fb0SBram Moolenaar 269071d4279SBram Moolenaarlet s:newwin = winnr() 270071d4279SBram Moolenaarlet s:orgwin = bufwinnr(s:orgbufnr) 271071d4279SBram Moolenaar 272349b2fb0SBram Moolenaarsetlocal modifiable 273071d4279SBram Moolenaar%d 274071d4279SBram Moolenaarlet s:old_paste = &paste 275071d4279SBram Moolenaarset paste 276071d4279SBram Moolenaarlet s:old_magic = &magic 277071d4279SBram Moolenaarset magic 278071d4279SBram Moolenaar 279166af9bbSBram Moolenaar" set the fileencoding to match the charset we'll be using 280166af9bbSBram Moolenaarlet &l:fileencoding=s:settings.vim_encoding 281166af9bbSBram Moolenaar 282166af9bbSBram Moolenaar" According to http://www.w3.org/TR/html4/charset.html#doc-char-set, the byte 283166af9bbSBram Moolenaar" order mark is highly recommend on the web when using multibyte encodings. But, 284166af9bbSBram Moolenaar" it is not a good idea to include it on UTF-8 files. Otherwise, let Vim 285166af9bbSBram Moolenaar" determine when it is actually inserted. 286166af9bbSBram Moolenaarif s:settings.vim_encoding == 'utf-8' 287166af9bbSBram Moolenaar setlocal nobomb 288166af9bbSBram Moolenaarelse 289166af9bbSBram Moolenaar setlocal bomb 290166af9bbSBram Moolenaarendif 291166af9bbSBram Moolenaar 292349b2fb0SBram Moolenaarlet s:lines = [] 293349b2fb0SBram Moolenaar 294076e8b2aSBram Moolenaarif s:settings.use_xhtml 295bebca9daSBram Moolenaar if s:settings.encoding != "" 296bebca9daSBram Moolenaar call add(s:lines, "<?xml version=\"1.0\" encoding=\"" . s:settings.encoding . "\"?>") 2971cd871b5SBram Moolenaar else 298349b2fb0SBram Moolenaar call add(s:lines, "<?xml version=\"1.0\"?>") 2991cd871b5SBram Moolenaar endif 30035a9aaabSBram Moolenaar let s:tag_close = ' />' 301071d4279SBram Moolenaarelse 30235a9aaabSBram Moolenaar let s:tag_close = '>' 30335a9aaabSBram Moolenaarendif 30435a9aaabSBram Moolenaar 30535a9aaabSBram Moolenaarlet s:HtmlSpace = ' ' 306c1e37901SBram Moolenaarlet s:LeadingSpace = ' ' 30735a9aaabSBram Moolenaarlet s:HtmlEndline = '' 308076e8b2aSBram Moolenaarif s:settings.no_pre 30935a9aaabSBram Moolenaar let s:HtmlEndline = '<br' . s:tag_close 310c1e37901SBram Moolenaar let s:LeadingSpace = ' ' 311c1e37901SBram Moolenaar let s:HtmlSpace = '\' . s:LeadingSpace 312071d4279SBram Moolenaarendif 313071d4279SBram Moolenaar 314071d4279SBram Moolenaar" HTML header, with the title and generator ;-). Left free space for the CSS, 315071d4279SBram Moolenaar" to be filled at the end. 316349b2fb0SBram Moolenaarcall extend(s:lines, [ 317349b2fb0SBram Moolenaar \ "<html>", 318bebca9daSBram Moolenaar \ "<head>"]) 319bebca9daSBram Moolenaar" include encoding as close to the top as possible, but only if not already 320bebca9daSBram Moolenaar" contained in XML information (to avoid haggling over content type) 321bebca9daSBram Moolenaarif s:settings.encoding != "" && !s:settings.use_xhtml 322bebca9daSBram Moolenaar call add(s:lines, "<meta http-equiv=\"content-type\" content=\"text/html; charset=" . s:settings.encoding . '"' . s:tag_close) 323bebca9daSBram Moolenaarendif 324bebca9daSBram Moolenaarcall extend(s:lines, [ 325349b2fb0SBram Moolenaar \ ("<title>".expand("%:p:~")."</title>"), 326349b2fb0SBram Moolenaar \ ("<meta name=\"Generator\" content=\"Vim/".v:version/100.".".v:version%100.'"'.s:tag_close), 327bebca9daSBram Moolenaar \ ("<meta name=\"plugin-version\" content=\"".g:loaded_2html_plugin.'"'.s:tag_close) 328349b2fb0SBram Moolenaar \ ]) 3297510fe74SBram Moolenaarcall add(s:lines, '<meta name="syntax" content="'.s:current_syntax.'"'.s:tag_close) 330076e8b2aSBram Moolenaarcall add(s:lines, '<meta name="settings" content="'. 331076e8b2aSBram Moolenaar \ join(filter(keys(s:settings),'s:settings[v:val]'),','). 332076e8b2aSBram Moolenaar \ '"'.s:tag_close) 333313b7237SBram Moolenaar 334076e8b2aSBram Moolenaarif s:settings.use_css 335076e8b2aSBram Moolenaar if s:settings.dynamic_folds 336076e8b2aSBram Moolenaar if s:settings.hover_unfold 3375c73622aSBram Moolenaar " if we are doing hover_unfold, use css 2 with css 1 fallback for IE6 338349b2fb0SBram Moolenaar call extend(s:lines, [ 339349b2fb0SBram Moolenaar \ "<style type=\"text/css\">", 340bebca9daSBram Moolenaar \ s:settings.use_xhtml ? "" : "<!--", 341349b2fb0SBram Moolenaar \ ".FoldColumn { text-decoration: none; white-space: pre; }", 342349b2fb0SBram Moolenaar \ "", 343349b2fb0SBram Moolenaar \ "body * { margin: 0; padding: 0; }", "", 344349b2fb0SBram Moolenaar \ ".open-fold > .Folded { display: none; }", 345349b2fb0SBram Moolenaar \ ".open-fold > .fulltext { display: inline; }", 346349b2fb0SBram Moolenaar \ ".closed-fold > .fulltext { display: none; }", 347349b2fb0SBram Moolenaar \ ".closed-fold > .Folded { display: inline; }", 348349b2fb0SBram Moolenaar \ "", 349349b2fb0SBram Moolenaar \ ".open-fold > .toggle-open { display: none; }", 350349b2fb0SBram Moolenaar \ ".open-fold > .toggle-closed { display: inline; }", 351349b2fb0SBram Moolenaar \ ".closed-fold > .toggle-open { display: inline; }", 352349b2fb0SBram Moolenaar \ ".closed-fold > .toggle-closed { display: none; }", 353349b2fb0SBram Moolenaar \ "", "", 354349b2fb0SBram Moolenaar \ '/* opening a fold while hovering won''t be supported by IE6 and other', 355349b2fb0SBram Moolenaar \ "similar browsers, but it should fail gracefully. */", 356349b2fb0SBram Moolenaar \ ".closed-fold:hover > .fulltext { display: inline; }", 357349b2fb0SBram Moolenaar \ ".closed-fold:hover > .toggle-filler { display: none; }", 358349b2fb0SBram Moolenaar \ ".closed-fold:hover > .Folded { display: none; }", 359bebca9daSBram Moolenaar \ s:settings.use_xhtml ? "" : '-->', 3608df7f888SBram Moolenaar \ '</style>']) 361bebca9daSBram Moolenaar " TODO: IE7 doesn't *actually* support XHTML, maybe we should remove this. 362bebca9daSBram Moolenaar " But if it's served up as tag soup, maybe the following will work, so 363bebca9daSBram Moolenaar " leave it in for now. 364bebca9daSBram Moolenaar call extend(s:lines, [ 365349b2fb0SBram Moolenaar \ "<!--[if lt IE 7]><style type=\"text/css\">", 366349b2fb0SBram Moolenaar \ ".open-fold .Folded { display: none; }", 367349b2fb0SBram Moolenaar \ ".open-fold .fulltext { display: inline; }", 368349b2fb0SBram Moolenaar \ ".open-fold .toggle-open { display: none; }", 369349b2fb0SBram Moolenaar \ ".closed-fold .toggle-closed { display: inline; }", 370349b2fb0SBram Moolenaar \ "", 371349b2fb0SBram Moolenaar \ ".closed-fold .fulltext { display: none; }", 372349b2fb0SBram Moolenaar \ ".closed-fold .Folded { display: inline; }", 373349b2fb0SBram Moolenaar \ ".closed-fold .toggle-open { display: inline; }", 374349b2fb0SBram Moolenaar \ ".closed-fold .toggle-closed { display: none; }", 375349b2fb0SBram Moolenaar \ "</style>", 376349b2fb0SBram Moolenaar \ "<![endif]-->", 377349b2fb0SBram Moolenaar \]) 3785c73622aSBram Moolenaar else 3795c73622aSBram Moolenaar " if we aren't doing hover_unfold, use CSS 1 only 380349b2fb0SBram Moolenaar call extend(s:lines, [ 381349b2fb0SBram Moolenaar \ "<style type=\"text/css\">", 382bebca9daSBram Moolenaar \ s:settings.use_xhtml ? "" :"<!--", 383349b2fb0SBram Moolenaar \ ".FoldColumn { text-decoration: none; white-space: pre; }", 384349b2fb0SBram Moolenaar \ ".open-fold .Folded { display: none; }", 385349b2fb0SBram Moolenaar \ ".open-fold .fulltext { display: inline; }", 386349b2fb0SBram Moolenaar \ ".open-fold .toggle-open { display: none; }", 387349b2fb0SBram Moolenaar \ ".closed-fold .toggle-closed { display: inline; }", 388349b2fb0SBram Moolenaar \ "", 389349b2fb0SBram Moolenaar \ ".closed-fold .fulltext { display: none; }", 390349b2fb0SBram Moolenaar \ ".closed-fold .Folded { display: inline; }", 391349b2fb0SBram Moolenaar \ ".closed-fold .toggle-open { display: inline; }", 392349b2fb0SBram Moolenaar \ ".closed-fold .toggle-closed { display: none; }", 393bebca9daSBram Moolenaar \ s:settings.use_xhtml ? "" : '-->', 394349b2fb0SBram Moolenaar \ '</style>' 395349b2fb0SBram Moolenaar \]) 3965c73622aSBram Moolenaar endif 3975c73622aSBram Moolenaar else 3985c73622aSBram Moolenaar " if we aren't doing any dynamic folding, no need for any special rules 399349b2fb0SBram Moolenaar call extend(s:lines, [ 400349b2fb0SBram Moolenaar \ "<style type=\"text/css\">", 401bebca9daSBram Moolenaar \ s:settings.use_xhtml ? "" : "<!--", 402bebca9daSBram Moolenaar \ s:settings.use_xhtml ? "" : '-->', 403349b2fb0SBram Moolenaar \ "</style>", 404349b2fb0SBram Moolenaar \]) 405071d4279SBram Moolenaar endif 4065c73622aSBram Moolenaarendif 4075c73622aSBram Moolenaar 4085c73622aSBram Moolenaar" insert javascript to toggle folds open and closed 409076e8b2aSBram Moolenaarif s:settings.dynamic_folds 410349b2fb0SBram Moolenaar call extend(s:lines, [ 411349b2fb0SBram Moolenaar \ "", 412349b2fb0SBram Moolenaar \ "<script type='text/javascript'>", 413bebca9daSBram Moolenaar \ s:settings.use_xhtml ? '//<![CDATA[' : "<!--", 414349b2fb0SBram Moolenaar \ "function toggleFold(objID)", 415349b2fb0SBram Moolenaar \ "{", 416349b2fb0SBram Moolenaar \ " var fold;", 417349b2fb0SBram Moolenaar \ " fold = document.getElementById(objID);", 418349b2fb0SBram Moolenaar \ " if(fold.className == 'closed-fold')", 419349b2fb0SBram Moolenaar \ " {", 420349b2fb0SBram Moolenaar \ " fold.className = 'open-fold';", 421349b2fb0SBram Moolenaar \ " }", 422349b2fb0SBram Moolenaar \ " else if (fold.className == 'open-fold')", 423349b2fb0SBram Moolenaar \ " {", 424349b2fb0SBram Moolenaar \ " fold.className = 'closed-fold';", 425349b2fb0SBram Moolenaar \ " }", 426349b2fb0SBram Moolenaar \ "}", 427bebca9daSBram Moolenaar \ s:settings.use_xhtml ? '//]]>' : '-->', 428349b2fb0SBram Moolenaar \ "</script>" 429349b2fb0SBram Moolenaar \]) 4305c73622aSBram Moolenaarendif 4315c73622aSBram Moolenaar 432076e8b2aSBram Moolenaarif s:settings.no_pre 433349b2fb0SBram Moolenaar call extend(s:lines, ["</head>", "<body>"]) 434071d4279SBram Moolenaarelse 435349b2fb0SBram Moolenaar call extend(s:lines, ["</head>", "<body>", "<pre>"]) 436071d4279SBram Moolenaarendif 437071d4279SBram Moolenaar 438071d4279SBram Moolenaarexe s:orgwin . "wincmd w" 439071d4279SBram Moolenaar 440071d4279SBram Moolenaar" List of all id's 4418ada2ccaSBram Moolenaarlet s:idlist = [] 442071d4279SBram Moolenaar 443349b2fb0SBram Moolenaar" set up progress bar in the status line 444076e8b2aSBram Moolenaarif !s:settings.no_progress 445349b2fb0SBram Moolenaar " ProgressBar Indicator 446349b2fb0SBram Moolenaar let s:progressbar={} 447349b2fb0SBram Moolenaar 448349b2fb0SBram Moolenaar " Progessbar specific functions 449349b2fb0SBram Moolenaar func! s:ProgressBar(title, max_value, winnr) 450349b2fb0SBram Moolenaar let pgb=copy(s:progressbar) 451349b2fb0SBram Moolenaar let pgb.title = a:title.' ' 452349b2fb0SBram Moolenaar let pgb.max_value = a:max_value 453349b2fb0SBram Moolenaar let pgb.winnr = a:winnr 454349b2fb0SBram Moolenaar let pgb.cur_value = 0 455349b2fb0SBram Moolenaar let pgb.items = { 'title' : { 'color' : 'Statusline' }, 456349b2fb0SBram Moolenaar \'bar' : { 'color' : 'Statusline' , 'fillcolor' : 'DiffDelete' , 'bg' : 'Statusline' } , 457349b2fb0SBram Moolenaar \'counter' : { 'color' : 'Statusline' } } 458349b2fb0SBram Moolenaar let pgb.last_value = 0 459349b2fb0SBram Moolenaar let pgb.needs_redraw = 0 460349b2fb0SBram Moolenaar " Note that you must use len(split) instead of len() if you want to use 461349b2fb0SBram Moolenaar " unicode in title. 462349b2fb0SBram Moolenaar " 463349b2fb0SBram Moolenaar " Subtract 3 for spacing around the title. 464349b2fb0SBram Moolenaar " Subtract 4 for the percentage display. 465349b2fb0SBram Moolenaar " Subtract 2 for spacing before this. 466349b2fb0SBram Moolenaar " Subtract 2 more for the '|' on either side of the progress bar 467349b2fb0SBram Moolenaar let pgb.subtractedlen=len(split(pgb.title, '\zs'))+3+4+2+2 468349b2fb0SBram Moolenaar let pgb.max_len = 0 469349b2fb0SBram Moolenaar set laststatus=2 470349b2fb0SBram Moolenaar return pgb 471349b2fb0SBram Moolenaar endfun 472349b2fb0SBram Moolenaar 473349b2fb0SBram Moolenaar " Function: progressbar.calculate_ticks() {{{1 474349b2fb0SBram Moolenaar func! s:progressbar.calculate_ticks(pb_len) 475349b2fb0SBram Moolenaar if a:pb_len<=0 476349b2fb0SBram Moolenaar let pb_len = 100 477349b2fb0SBram Moolenaar else 478349b2fb0SBram Moolenaar let pb_len = a:pb_len 479349b2fb0SBram Moolenaar endif 480349b2fb0SBram Moolenaar let self.progress_ticks = map(range(pb_len+1), "v:val * self.max_value / pb_len") 481349b2fb0SBram Moolenaar endfun 482349b2fb0SBram Moolenaar 483349b2fb0SBram Moolenaar "Function: progressbar.paint() 484349b2fb0SBram Moolenaar func! s:progressbar.paint() 485349b2fb0SBram Moolenaar " Recalculate widths. 486349b2fb0SBram Moolenaar let max_len = winwidth(self.winnr) 487349b2fb0SBram Moolenaar let pb_len = 0 488349b2fb0SBram Moolenaar " always true on first call because of initial value of self.max_len 489349b2fb0SBram Moolenaar if max_len != self.max_len 490349b2fb0SBram Moolenaar let self.max_len = max_len 491349b2fb0SBram Moolenaar 492349b2fb0SBram Moolenaar " Progressbar length 493349b2fb0SBram Moolenaar let pb_len = max_len - self.subtractedlen 494349b2fb0SBram Moolenaar 495349b2fb0SBram Moolenaar call self.calculate_ticks(pb_len) 496349b2fb0SBram Moolenaar 497349b2fb0SBram Moolenaar let self.needs_redraw = 1 498349b2fb0SBram Moolenaar let cur_value = 0 499349b2fb0SBram Moolenaar let self.pb_len = pb_len 500349b2fb0SBram Moolenaar else 501349b2fb0SBram Moolenaar " start searching at the last found index to make the search for the 502349b2fb0SBram Moolenaar " appropriate tick value normally take 0 or 1 comparisons 503349b2fb0SBram Moolenaar let cur_value = self.last_value 504349b2fb0SBram Moolenaar let pb_len = self.pb_len 505349b2fb0SBram Moolenaar endif 506349b2fb0SBram Moolenaar 507349b2fb0SBram Moolenaar let cur_val_max = pb_len > 0 ? pb_len : 100 508349b2fb0SBram Moolenaar 509349b2fb0SBram Moolenaar " find the current progress bar position based on precalculated thresholds 510349b2fb0SBram Moolenaar while cur_value < cur_val_max && self.cur_value > self.progress_ticks[cur_value] 511349b2fb0SBram Moolenaar let cur_value += 1 512349b2fb0SBram Moolenaar endwhile 513349b2fb0SBram Moolenaar 514349b2fb0SBram Moolenaar " update progress bar 515349b2fb0SBram Moolenaar if self.last_value != cur_value || self.needs_redraw || self.cur_value == self.max_value 516349b2fb0SBram Moolenaar let self.needs_redraw = 1 517349b2fb0SBram Moolenaar let self.last_value = cur_value 518349b2fb0SBram Moolenaar 519349b2fb0SBram Moolenaar let t_color = self.items.title.color 520349b2fb0SBram Moolenaar let b_fcolor = self.items.bar.fillcolor 521349b2fb0SBram Moolenaar let b_color = self.items.bar.color 522349b2fb0SBram Moolenaar let c_color = self.items.counter.color 523349b2fb0SBram Moolenaar 524349b2fb0SBram Moolenaar let stl = "%#".t_color."#%-( ".self.title." %)". 525349b2fb0SBram Moolenaar \"%#".b_color."#". 526349b2fb0SBram Moolenaar \(pb_len>0 ? 527349b2fb0SBram Moolenaar \ ('|%#'.b_fcolor."#%-(".repeat(" ",cur_value)."%)". 528349b2fb0SBram Moolenaar \ '%#'.b_color."#".repeat(" ",pb_len-cur_value)."|"): 529349b2fb0SBram Moolenaar \ ('')). 530349b2fb0SBram Moolenaar \"%=%#".c_color."#%( ".printf("%3.d ",100*self.cur_value/self.max_value)."%% %)" 531349b2fb0SBram Moolenaar call setwinvar(self.winnr, '&stl', stl) 532349b2fb0SBram Moolenaar endif 533349b2fb0SBram Moolenaar endfun 534349b2fb0SBram Moolenaar 535349b2fb0SBram Moolenaar func! s:progressbar.incr( ... ) 536349b2fb0SBram Moolenaar let self.cur_value += (a:0 ? a:1 : 1) 537349b2fb0SBram Moolenaar " if we were making a general-purpose progress bar, we'd need to limit to a 538349b2fb0SBram Moolenaar " lower limit as well, but since we always increment with a positive value 539349b2fb0SBram Moolenaar " in this script, we only need limit the upper value 540349b2fb0SBram Moolenaar let self.cur_value = (self.cur_value > self.max_value ? self.max_value : self.cur_value) 541349b2fb0SBram Moolenaar call self.paint() 542349b2fb0SBram Moolenaar endfun 543349b2fb0SBram Moolenaar " }}} 544076e8b2aSBram Moolenaar if s:settings.dynamic_folds 545349b2fb0SBram Moolenaar " to process folds we make two passes through each line 546349b2fb0SBram Moolenaar let s:pgb = s:ProgressBar("Processing folds:", line('$')*2, s:orgwin) 547349b2fb0SBram Moolenaar endif 548349b2fb0SBram Moolenaarendif 549349b2fb0SBram Moolenaar 5505c73622aSBram Moolenaar" First do some preprocessing for dynamic folding. Do this for the entire file 5515c73622aSBram Moolenaar" so we don't accidentally start within a closed fold or something. 5525c73622aSBram Moolenaarlet s:allfolds = [] 5535c73622aSBram Moolenaar 554076e8b2aSBram Moolenaarif s:settings.dynamic_folds 5555c73622aSBram Moolenaar let s:lnum = 1 5565c73622aSBram Moolenaar let s:end = line('$') 5575c73622aSBram Moolenaar " save the fold text and set it to the default so we can find fold levels 5585c73622aSBram Moolenaar let s:foldtext_save = &foldtext 559349b2fb0SBram Moolenaar setlocal foldtext& 5605c73622aSBram Moolenaar 5615c73622aSBram Moolenaar " we will set the foldcolumn in the html to the greater of the maximum fold 5625c73622aSBram Moolenaar " level and the current foldcolumn setting 5635c73622aSBram Moolenaar let s:foldcolumn = &foldcolumn 5645c73622aSBram Moolenaar 5655c73622aSBram Moolenaar " get all info needed to describe currently closed folds 566349b2fb0SBram Moolenaar while s:lnum <= s:end 5675c73622aSBram Moolenaar if foldclosed(s:lnum) == s:lnum 5685c73622aSBram Moolenaar " default fold text has '+-' and then a number of dashes equal to fold 5695c73622aSBram Moolenaar " level, so subtract 2 from index of first non-dash after the dashes 5705c73622aSBram Moolenaar " in order to get the fold level of the current fold 5715c73622aSBram Moolenaar let s:level = match(foldtextresult(s:lnum), '+-*\zs[^-]') - 2 5725c73622aSBram Moolenaar " store fold info for later use 5735c73622aSBram Moolenaar let s:newfold = {'firstline': s:lnum, 'lastline': foldclosedend(s:lnum), 'level': s:level,'type': "closed-fold"} 5745c73622aSBram Moolenaar call add(s:allfolds, s:newfold) 5755c73622aSBram Moolenaar " open the fold so we can find any contained folds 5765c73622aSBram Moolenaar execute s:lnum."foldopen" 5775c73622aSBram Moolenaar else 578076e8b2aSBram Moolenaar if !s:settings.no_progress 579349b2fb0SBram Moolenaar call s:pgb.incr() 580349b2fb0SBram Moolenaar if s:pgb.needs_redraw 581349b2fb0SBram Moolenaar redrawstatus 582349b2fb0SBram Moolenaar let s:pgb.needs_redraw = 0 583349b2fb0SBram Moolenaar endif 584349b2fb0SBram Moolenaar endif 5855c73622aSBram Moolenaar let s:lnum = s:lnum + 1 5865c73622aSBram Moolenaar endif 5875c73622aSBram Moolenaar endwhile 5885c73622aSBram Moolenaar 5895c73622aSBram Moolenaar " close all folds to get info for originally open folds 5905c73622aSBram Moolenaar silent! %foldclose! 5915c73622aSBram Moolenaar let s:lnum = 1 5925c73622aSBram Moolenaar 5935c73622aSBram Moolenaar " the originally open folds will be all folds we encounter that aren't 5945c73622aSBram Moolenaar " already in the list of closed folds 595349b2fb0SBram Moolenaar while s:lnum <= s:end 5965c73622aSBram Moolenaar if foldclosed(s:lnum) == s:lnum 5975c73622aSBram Moolenaar " default fold text has '+-' and then a number of dashes equal to fold 5985c73622aSBram Moolenaar " level, so subtract 2 from index of first non-dash after the dashes 5995c73622aSBram Moolenaar " in order to get the fold level of the current fold 6005c73622aSBram Moolenaar let s:level = match(foldtextresult(s:lnum), '+-*\zs[^-]') - 2 6015c73622aSBram Moolenaar let s:newfold = {'firstline': s:lnum, 'lastline': foldclosedend(s:lnum), 'level': s:level,'type': "closed-fold"} 6025c73622aSBram Moolenaar " only add the fold if we don't already have it 6035c73622aSBram Moolenaar if empty(s:allfolds) || index(s:allfolds, s:newfold) == -1 6045c73622aSBram Moolenaar let s:newfold.type = "open-fold" 6055c73622aSBram Moolenaar call add(s:allfolds, s:newfold) 6065c73622aSBram Moolenaar endif 6075c73622aSBram Moolenaar " open the fold so we can find any contained folds 6085c73622aSBram Moolenaar execute s:lnum."foldopen" 6095c73622aSBram Moolenaar else 610076e8b2aSBram Moolenaar if !s:settings.no_progress 611349b2fb0SBram Moolenaar call s:pgb.incr() 612349b2fb0SBram Moolenaar if s:pgb.needs_redraw 613349b2fb0SBram Moolenaar redrawstatus 614349b2fb0SBram Moolenaar let s:pgb.needs_redraw = 0 615349b2fb0SBram Moolenaar endif 616349b2fb0SBram Moolenaar endif 6175c73622aSBram Moolenaar let s:lnum = s:lnum + 1 6185c73622aSBram Moolenaar endif 6195c73622aSBram Moolenaar endwhile 6205c73622aSBram Moolenaar 6215c73622aSBram Moolenaar " sort the folds so that we only ever need to look at the first item in the 6225c73622aSBram Moolenaar " list of folds 6235c73622aSBram Moolenaar call sort(s:allfolds, "s:FoldCompare") 6245c73622aSBram Moolenaar 625349b2fb0SBram Moolenaar let &l:foldtext = s:foldtext_save 6265c73622aSBram Moolenaar unlet s:foldtext_save 6275c73622aSBram Moolenaar 6285c73622aSBram Moolenaar " close all folds again so we can get the fold text as we go 6295c73622aSBram Moolenaar silent! %foldclose! 630*2a8a3ecbSBram Moolenaar 631*2a8a3ecbSBram Moolenaar for afold in s:allfolds 632*2a8a3ecbSBram Moolenaar let removed = 0 633*2a8a3ecbSBram Moolenaar if exists("g:html_start_line") && exists("g:html_end_line") 634*2a8a3ecbSBram Moolenaar if afold.firstline < g:html_start_line 635*2a8a3ecbSBram Moolenaar if afold.lastline < g:html_end_line && afold.lastline > g:html_start_line 636*2a8a3ecbSBram Moolenaar " if a fold starts before the range to convert but stops within the 637*2a8a3ecbSBram Moolenaar " range, we need to include it. Make it start on the first converted 638*2a8a3ecbSBram Moolenaar " line. 639*2a8a3ecbSBram Moolenaar let afold.firstline = g:html_start_line 640*2a8a3ecbSBram Moolenaar else 641*2a8a3ecbSBram Moolenaar " if the fold lies outside the range or the start and stop enclose 642*2a8a3ecbSBram Moolenaar " the entire range, don't bother parsing it 643*2a8a3ecbSBram Moolenaar call remove(s:allfolds, index(s:allfolds, afold)) 644*2a8a3ecbSBram Moolenaar let removed = 1 645*2a8a3ecbSBram Moolenaar endif 646*2a8a3ecbSBram Moolenaar elseif afold.firstline > g:html_end_line 647*2a8a3ecbSBram Moolenaar " If the entire fold lies outside the range we need to remove it. 648*2a8a3ecbSBram Moolenaar call remove(s:allfolds, index(s:allfolds, afold)) 649*2a8a3ecbSBram Moolenaar let removed = 1 650*2a8a3ecbSBram Moolenaar endif 651*2a8a3ecbSBram Moolenaar elseif exists("g:html_start_line") 652*2a8a3ecbSBram Moolenaar if afold.firstline < g:html_start_line 653*2a8a3ecbSBram Moolenaar " if there is no last line, but there is a first line, the end of the 654*2a8a3ecbSBram Moolenaar " fold will always lie within the region of interest, so keep it 655*2a8a3ecbSBram Moolenaar let afold.firstline = g:html_start_line 656*2a8a3ecbSBram Moolenaar endif 657*2a8a3ecbSBram Moolenaar elseif exists("g:html_end_line") 658*2a8a3ecbSBram Moolenaar " if there is no first line we default to the first line in the buffer so 659*2a8a3ecbSBram Moolenaar " the fold start will always be included if the fold itself is included. 660*2a8a3ecbSBram Moolenaar " If however the entire fold lies outside the range we need to remove it. 661*2a8a3ecbSBram Moolenaar if afold.firstline > g:html_end_line 662*2a8a3ecbSBram Moolenaar call remove(s:allfolds, index(s:allfolds, afold)) 663*2a8a3ecbSBram Moolenaar let removed = 1 664*2a8a3ecbSBram Moolenaar endif 665*2a8a3ecbSBram Moolenaar endif 666*2a8a3ecbSBram Moolenaar if !removed 667*2a8a3ecbSBram Moolenaar if afold.level+1 > s:foldcolumn 668*2a8a3ecbSBram Moolenaar let s:foldcolumn = afold.level+1 669*2a8a3ecbSBram Moolenaar endif 670*2a8a3ecbSBram Moolenaar endif 671*2a8a3ecbSBram Moolenaar endfor 6725c73622aSBram Moolenaarendif 6735c73622aSBram Moolenaar 6745c73622aSBram Moolenaar" Now loop over all lines in the original text to convert to html. 675071d4279SBram Moolenaar" Use html_start_line and html_end_line if they are set. 676b02cbe34SBram Moolenaarif exists("g:html_start_line") 677071d4279SBram Moolenaar let s:lnum = html_start_line 678071d4279SBram Moolenaar if s:lnum < 1 || s:lnum > line("$") 679071d4279SBram Moolenaar let s:lnum = 1 680071d4279SBram Moolenaar endif 681071d4279SBram Moolenaarelse 682071d4279SBram Moolenaar let s:lnum = 1 683071d4279SBram Moolenaarendif 684b02cbe34SBram Moolenaarif exists("g:html_end_line") 685071d4279SBram Moolenaar let s:end = html_end_line 686071d4279SBram Moolenaar if s:end < s:lnum || s:end > line("$") 687071d4279SBram Moolenaar let s:end = line("$") 688071d4279SBram Moolenaar endif 689071d4279SBram Moolenaarelse 690071d4279SBram Moolenaar let s:end = line("$") 691071d4279SBram Moolenaarendif 692071d4279SBram Moolenaar 6935c73622aSBram Moolenaar" stack to keep track of all the folds containing the current line 6945c73622aSBram Moolenaarlet s:foldstack = [] 6955c73622aSBram Moolenaar 696076e8b2aSBram Moolenaarif !s:settings.no_progress 697349b2fb0SBram Moolenaar let s:pgb = s:ProgressBar("Processing lines:", s:end - s:lnum + 1, s:orgwin) 698349b2fb0SBram Moolenaarendif 699349b2fb0SBram Moolenaar 700076e8b2aSBram Moolenaarif s:settings.number_lines 7015c73622aSBram Moolenaar let s:margin = strlen(s:end) + 1 7025c73622aSBram Moolenaarelse 7035c73622aSBram Moolenaar let s:margin = 0 7045c73622aSBram Moolenaarendif 7055c73622aSBram Moolenaar 706076e8b2aSBram Moolenaarif has('folding') && !s:settings.ignore_folding 70735a9aaabSBram Moolenaar let s:foldfillchar = &fillchars[matchend(&fillchars, 'fold:')] 70835a9aaabSBram Moolenaar if s:foldfillchar == '' 70935a9aaabSBram Moolenaar let s:foldfillchar = '-' 7107b0294cbSBram Moolenaar endif 71135a9aaabSBram Moolenaarendif 71235a9aaabSBram Moolenaarlet s:difffillchar = &fillchars[matchend(&fillchars, 'diff:')] 71335a9aaabSBram Moolenaarif s:difffillchar == '' 71435a9aaabSBram Moolenaar let s:difffillchar = '-' 7157b0294cbSBram Moolenaarendif 7167b0294cbSBram Moolenaar 7175c73622aSBram Moolenaarlet s:foldId = 0 7187b0294cbSBram Moolenaar 719*2a8a3ecbSBram Moolenaarif !s:settings.expand_tabs 720*2a8a3ecbSBram Moolenaar " If keeping tabs, add them to printable characters so we keep them when 721*2a8a3ecbSBram Moolenaar " formatting text (strtrans() doesn't replace printable chars) 722*2a8a3ecbSBram Moolenaar let s:old_isprint = &isprint 723*2a8a3ecbSBram Moolenaar setlocal isprint+=9 724*2a8a3ecbSBram Moolenaarendif 725*2a8a3ecbSBram Moolenaar 726071d4279SBram Moolenaarwhile s:lnum <= s:end 727071d4279SBram Moolenaar 72847136d70SBram Moolenaar " If there are filler lines for diff mode, show these above the line. 72947136d70SBram Moolenaar let s:filler = diff_filler(s:lnum) 73047136d70SBram Moolenaar if s:filler > 0 73147136d70SBram Moolenaar let s:n = s:filler 73247136d70SBram Moolenaar while s:n > 0 73335a9aaabSBram Moolenaar let s:new = repeat(s:difffillchar, 3) 73447136d70SBram Moolenaar 735076e8b2aSBram Moolenaar if s:n > 2 && s:n < s:filler && !s:settings.whole_filler 73635a9aaabSBram Moolenaar let s:new = s:new . " " . s:filler . " inserted lines " 73735a9aaabSBram Moolenaar let s:n = 2 73835a9aaabSBram Moolenaar endif 73935a9aaabSBram Moolenaar 740076e8b2aSBram Moolenaar if !s:settings.no_pre 74135a9aaabSBram Moolenaar " HTML line wrapping is off--go ahead and fill to the margin 7425c73622aSBram Moolenaar let s:new = s:new . repeat(s:difffillchar, &columns - strlen(s:new) - s:margin) 7435c73622aSBram Moolenaar else 7445c73622aSBram Moolenaar let s:new = s:new . repeat(s:difffillchar, 3) 74535a9aaabSBram Moolenaar endif 74635a9aaabSBram Moolenaar 7478ada2ccaSBram Moolenaar let s:new = s:HtmlFormat(s:new, "DiffDelete", "") 748076e8b2aSBram Moolenaar if s:settings.number_lines 7495c73622aSBram Moolenaar " Indent if line numbering is on; must be after escaping. 7505c73622aSBram Moolenaar let s:new = repeat(s:LeadingSpace, s:margin) . s:new 7515c73622aSBram Moolenaar endif 752349b2fb0SBram Moolenaar call add(s:lines, s:new.s:HtmlEndline) 75335a9aaabSBram Moolenaar 75447136d70SBram Moolenaar let s:n = s:n - 1 75547136d70SBram Moolenaar endwhile 75647136d70SBram Moolenaar unlet s:n 75747136d70SBram Moolenaar endif 75847136d70SBram Moolenaar unlet s:filler 75947136d70SBram Moolenaar 76047136d70SBram Moolenaar " Start the line with the line number. 761076e8b2aSBram Moolenaar if s:settings.number_lines 7625c73622aSBram Moolenaar let s:numcol = repeat(' ', s:margin - 1 - strlen(s:lnum)) . s:lnum . ' ' 76347136d70SBram Moolenaar else 7645c73622aSBram Moolenaar let s:numcol = "" 76547136d70SBram Moolenaar endif 76647136d70SBram Moolenaar 7675c73622aSBram Moolenaar let s:new = "" 7685c73622aSBram Moolenaar 769076e8b2aSBram Moolenaar if has('folding') && !s:settings.ignore_folding && foldclosed(s:lnum) > -1 && !s:settings.dynamic_folds 7707b0294cbSBram Moolenaar " 7715c73622aSBram Moolenaar " This is the beginning of a folded block (with no dynamic folding) 7727b0294cbSBram Moolenaar " 7735c73622aSBram Moolenaar let s:new = s:numcol . foldtextresult(s:lnum) 774076e8b2aSBram Moolenaar if !s:settings.no_pre 77535a9aaabSBram Moolenaar " HTML line wrapping is off--go ahead and fill to the margin 77635a9aaabSBram Moolenaar let s:new = s:new . repeat(s:foldfillchar, &columns - strlen(s:new)) 7777b0294cbSBram Moolenaar endif 7787b0294cbSBram Moolenaar 7798ada2ccaSBram Moolenaar let s:new = s:HtmlFormat(s:new, "Folded", "") 7807b0294cbSBram Moolenaar 7817b0294cbSBram Moolenaar " Skip to the end of the fold 782349b2fb0SBram Moolenaar let s:new_lnum = foldclosedend(s:lnum) 783349b2fb0SBram Moolenaar 784076e8b2aSBram Moolenaar if !s:settings.no_progress 785349b2fb0SBram Moolenaar call s:pgb.incr(s:new_lnum - s:lnum) 786349b2fb0SBram Moolenaar endif 787349b2fb0SBram Moolenaar 788349b2fb0SBram Moolenaar let s:lnum = s:new_lnum 7897b0294cbSBram Moolenaar 7907b0294cbSBram Moolenaar else 7917b0294cbSBram Moolenaar " 7925c73622aSBram Moolenaar " A line that is not folded, or doing dynamic folding. 7937b0294cbSBram Moolenaar " 79435a9aaabSBram Moolenaar let s:line = getline(s:lnum) 7957b0294cbSBram Moolenaar let s:len = strlen(s:line) 7967b0294cbSBram Moolenaar 797076e8b2aSBram Moolenaar if s:settings.dynamic_folds 7985c73622aSBram Moolenaar " First insert a closing for any open folds that end on this line 7995c73622aSBram Moolenaar while !empty(s:foldstack) && get(s:foldstack,0).lastline == s:lnum-1 8005c73622aSBram Moolenaar let s:new = s:new."</span></span>" 8015c73622aSBram Moolenaar call remove(s:foldstack, 0) 8025c73622aSBram Moolenaar endwhile 8035c73622aSBram Moolenaar 804*2a8a3ecbSBram Moolenaar " Now insert an opening for any new folds that start on this line 8055c73622aSBram Moolenaar let s:firstfold = 1 8065c73622aSBram Moolenaar while !empty(s:allfolds) && get(s:allfolds,0).firstline == s:lnum 8075c73622aSBram Moolenaar let s:foldId = s:foldId + 1 808349b2fb0SBram Moolenaar let s:new .= "<span id='" 809349b2fb0SBram Moolenaar let s:new .= (exists('g:html_diff_win_num') ? "win".g:html_diff_win_num : "") 810349b2fb0SBram Moolenaar let s:new .= "fold".s:foldId."' class='".s:allfolds[0].type."'>" 811349b2fb0SBram Moolenaar 8125c73622aSBram Moolenaar 8135c73622aSBram Moolenaar " Unless disabled, add a fold column for the opening line of a fold. 8145c73622aSBram Moolenaar " 8155c73622aSBram Moolenaar " Note that dynamic folds require using css so we just use css to take 8165c73622aSBram Moolenaar " care of the leading spaces rather than using in the case of 8175c73622aSBram Moolenaar " html_no_pre to make it easier 818076e8b2aSBram Moolenaar if !s:settings.no_foldcolumn 8195c73622aSBram Moolenaar " add fold column that can open the new fold 8205c73622aSBram Moolenaar if s:allfolds[0].level > 1 && s:firstfold 8215c73622aSBram Moolenaar let s:new = s:new . "<a class='toggle-open FoldColumn' href='javascript:toggleFold(\"fold".s:foldstack[0].id."\")'>" 8225c73622aSBram Moolenaar let s:new = s:new . repeat('|', s:allfolds[0].level - 1) . "</a>" 8235c73622aSBram Moolenaar endif 8245c73622aSBram Moolenaar let s:new = s:new . "<a class='toggle-open FoldColumn' href='javascript:toggleFold(\"fold".s:foldId."\")'>+</a>" 8255c73622aSBram Moolenaar let s:new = s:new . "<a class='toggle-open " 8265c73622aSBram Moolenaar " If this is not the last fold we're opening on this line, we need 8275c73622aSBram Moolenaar " to keep the filler spaces hidden if the fold is opened by mouse 8285c73622aSBram Moolenaar " hover. If it is the last fold to open in the line, we shouldn't hide 8295c73622aSBram Moolenaar " them, so don't apply the toggle-filler class. 8305c73622aSBram Moolenaar if get(s:allfolds, 1, {'firstline': 0}).firstline == s:lnum 8315c73622aSBram Moolenaar let s:new = s:new . "toggle-filler " 8325c73622aSBram Moolenaar endif 8335c73622aSBram Moolenaar let s:new = s:new . "FoldColumn' href='javascript:toggleFold(\"fold".s:foldId."\")'>" 8345c73622aSBram Moolenaar let s:new = s:new . repeat(" ", s:foldcolumn - s:allfolds[0].level) . "</a>" 8355c73622aSBram Moolenaar 8365c73622aSBram Moolenaar " add fold column that can close the new fold 8375c73622aSBram Moolenaar let s:new = s:new . "<a class='toggle-closed FoldColumn' href='javascript:toggleFold(\"fold".s:foldId."\")'>" 8385c73622aSBram Moolenaar if s:firstfold 8395c73622aSBram Moolenaar let s:new = s:new . repeat('|', s:allfolds[0].level - 1) 8405c73622aSBram Moolenaar endif 8415c73622aSBram Moolenaar let s:new = s:new . "-" 8425c73622aSBram Moolenaar " only add spaces if we aren't opening another fold on the same line 8435c73622aSBram Moolenaar if get(s:allfolds, 1, {'firstline': 0}).firstline != s:lnum 8445c73622aSBram Moolenaar let s:new = s:new . repeat(" ", s:foldcolumn - s:allfolds[0].level) 8455c73622aSBram Moolenaar endif 8465c73622aSBram Moolenaar let s:new = s:new . "</a>" 8475c73622aSBram Moolenaar let s:firstfold = 0 8485c73622aSBram Moolenaar endif 8495c73622aSBram Moolenaar 8505c73622aSBram Moolenaar " add fold text, moving the span ending to the next line so collapsing 8515c73622aSBram Moolenaar " of folds works correctly 8528ada2ccaSBram Moolenaar let s:new = s:new . substitute(s:HtmlFormat(s:numcol . foldtextresult(s:lnum), "Folded", ""), '</span>', s:HtmlEndline.'\n\0', '') 8535c73622aSBram Moolenaar let s:new = s:new . "<span class='fulltext'>" 8545c73622aSBram Moolenaar 8555c73622aSBram Moolenaar " open the fold now that we have the fold text to allow retrieval of 8565c73622aSBram Moolenaar " fold text for subsequent folds 8575c73622aSBram Moolenaar execute s:lnum."foldopen" 8585c73622aSBram Moolenaar call insert(s:foldstack, remove(s:allfolds,0)) 8595c73622aSBram Moolenaar let s:foldstack[0].id = s:foldId 8605c73622aSBram Moolenaar endwhile 8615c73622aSBram Moolenaar 8625c73622aSBram Moolenaar " Unless disabled, add a fold column for other lines. 8635c73622aSBram Moolenaar " 8645c73622aSBram Moolenaar " Note that dynamic folds require using css so we just use css to take 8655c73622aSBram Moolenaar " care of the leading spaces rather than using in the case of 8665c73622aSBram Moolenaar " html_no_pre to make it easier 867076e8b2aSBram Moolenaar if !s:settings.no_foldcolumn 8685c73622aSBram Moolenaar if empty(s:foldstack) 8697510fe74SBram Moolenaar " add the empty foldcolumn for unfolded lines if there is a fold 8707510fe74SBram Moolenaar " column at all 8717510fe74SBram Moolenaar if s:foldcolumn > 0 8728ada2ccaSBram Moolenaar let s:new = s:new . s:HtmlFormat(repeat(' ', s:foldcolumn), "FoldColumn", "") 8737510fe74SBram Moolenaar endif 8745c73622aSBram Moolenaar else 8755c73622aSBram Moolenaar " add the fold column for folds not on the opening line 8765c73622aSBram Moolenaar if get(s:foldstack, 0).firstline < s:lnum 8775c73622aSBram Moolenaar let s:new = s:new . "<a class='FoldColumn' href='javascript:toggleFold(\"fold".s:foldstack[0].id."\")'>" 8785c73622aSBram Moolenaar let s:new = s:new . repeat('|', s:foldstack[0].level) 8795c73622aSBram Moolenaar let s:new = s:new . repeat(' ', s:foldcolumn - s:foldstack[0].level) . "</a>" 8805c73622aSBram Moolenaar endif 8815c73622aSBram Moolenaar endif 8825c73622aSBram Moolenaar endif 8835c73622aSBram Moolenaar endif 8845c73622aSBram Moolenaar 8855c73622aSBram Moolenaar " Now continue with the unfolded line text 886076e8b2aSBram Moolenaar if s:settings.number_lines 8878ada2ccaSBram Moolenaar " TODO: why not use the real highlight name here? 8888ada2ccaSBram Moolenaar let s:new = s:new . s:HtmlFormat(s:numcol, "lnr", "") 889071d4279SBram Moolenaar endif 890071d4279SBram Moolenaar 89147136d70SBram Moolenaar " Get the diff attribute, if any. 89247136d70SBram Moolenaar let s:diffattr = diff_hlID(s:lnum, 1) 89347136d70SBram Moolenaar 8947510fe74SBram Moolenaar " initialize conceal info to act like not concealed, just in case 8957510fe74SBram Moolenaar let s:concealinfo = [0, ''] 8967510fe74SBram Moolenaar 897071d4279SBram Moolenaar " Loop over each character in the line 898071d4279SBram Moolenaar let s:col = 1 8998ada2ccaSBram Moolenaar 9008ada2ccaSBram Moolenaar " most of the time we won't use the diff_id, initialize to zero 9018ada2ccaSBram Moolenaar let s:diff_id = 0 9028ada2ccaSBram Moolenaar let s:diff_id_name = "" 9038ada2ccaSBram Moolenaar 90435a9aaabSBram Moolenaar while s:col <= s:len || (s:col == 1 && s:diffattr) 905071d4279SBram Moolenaar let s:startcol = s:col " The start column for processing text 906076e8b2aSBram Moolenaar if !s:settings.ignore_conceal && has('conceal') 9077510fe74SBram Moolenaar let s:concealinfo = synconcealed(s:lnum, s:col) 9087510fe74SBram Moolenaar endif 909076e8b2aSBram Moolenaar if !s:settings.ignore_conceal && s:concealinfo[0] 9107510fe74SBram Moolenaar let s:col = s:col + 1 9117510fe74SBram Moolenaar " Speed loop (it's small - that's the trick) 9127510fe74SBram Moolenaar " Go along till we find a change in the match sequence number (ending 9137510fe74SBram Moolenaar " the specific concealed region) or until there are no more concealed 9147510fe74SBram Moolenaar " characters. 9157510fe74SBram Moolenaar while s:col <= s:len && s:concealinfo == synconcealed(s:lnum, s:col) | let s:col = s:col + 1 | endwhile 9167510fe74SBram Moolenaar elseif s:diffattr 9178ada2ccaSBram Moolenaar let s:diff_id = diff_hlID(s:lnum, s:col) 9188ada2ccaSBram Moolenaar let s:id = synID(s:lnum, s:col, 1) 91947136d70SBram Moolenaar let s:col = s:col + 1 92047136d70SBram Moolenaar " Speed loop (it's small - that's the trick) 92147136d70SBram Moolenaar " Go along till we find a change in hlID 9228ada2ccaSBram Moolenaar while s:col <= s:len && s:id == synID(s:lnum, s:col, 1) 9238ada2ccaSBram Moolenaar \ && s:diff_id == diff_hlID(s:lnum, s:col) | 9248ada2ccaSBram Moolenaar \ let s:col = s:col + 1 | 9258ada2ccaSBram Moolenaar \ endwhile 926076e8b2aSBram Moolenaar if s:len < &columns && !s:settings.no_pre 9278ada2ccaSBram Moolenaar " Add spaces at the end of the raw text line to extend the changed 9288ada2ccaSBram Moolenaar " line to the full width. 9295c73622aSBram Moolenaar let s:line = s:line . repeat(' ', &columns - virtcol([s:lnum, s:len]) - s:margin) 93035a9aaabSBram Moolenaar let s:len = &columns 93135a9aaabSBram Moolenaar endif 93247136d70SBram Moolenaar else 933071d4279SBram Moolenaar let s:id = synID(s:lnum, s:col, 1) 934071d4279SBram Moolenaar let s:col = s:col + 1 935071d4279SBram Moolenaar " Speed loop (it's small - that's the trick) 936071d4279SBram Moolenaar " Go along till we find a change in synID 937071d4279SBram Moolenaar while s:col <= s:len && s:id == synID(s:lnum, s:col, 1) | let s:col = s:col + 1 | endwhile 93847136d70SBram Moolenaar endif 939071d4279SBram Moolenaar 940076e8b2aSBram Moolenaar if s:settings.ignore_conceal || !s:concealinfo[0] 941*2a8a3ecbSBram Moolenaar " Expand tabs if needed 94235a9aaabSBram Moolenaar let s:expandedtab = strpart(s:line, s:startcol - 1, s:col - s:startcol) 943*2a8a3ecbSBram Moolenaar if s:settings.expand_tabs 9445c73622aSBram Moolenaar let s:offset = 0 9455c73622aSBram Moolenaar let s:idx = stridx(s:expandedtab, "\t") 9465c73622aSBram Moolenaar while s:idx >= 0 9475c73622aSBram Moolenaar if has("multi_byte_encoding") 9485c73622aSBram Moolenaar if s:startcol + s:idx == 1 9495c73622aSBram Moolenaar let s:i = &ts 9505c73622aSBram Moolenaar else 9515c73622aSBram Moolenaar if s:idx == 0 9525c73622aSBram Moolenaar let s:prevc = matchstr(s:line, '.\%' . (s:startcol + s:idx + s:offset) . 'c') 9535c73622aSBram Moolenaar else 9545c73622aSBram Moolenaar let s:prevc = matchstr(s:expandedtab, '.\%' . (s:idx + 1) . 'c') 9555c73622aSBram Moolenaar endif 9565c73622aSBram Moolenaar let s:vcol = virtcol([s:lnum, s:startcol + s:idx + s:offset - len(s:prevc)]) 9575c73622aSBram Moolenaar let s:i = &ts - (s:vcol % &ts) 9585c73622aSBram Moolenaar endif 9595c73622aSBram Moolenaar let s:offset -= s:i - 1 9605c73622aSBram Moolenaar else 9615c73622aSBram Moolenaar let s:i = &ts - ((s:idx + s:startcol - 1) % &ts) 9625c73622aSBram Moolenaar endif 9635c73622aSBram Moolenaar let s:expandedtab = substitute(s:expandedtab, '\t', repeat(' ', s:i), '') 9645c73622aSBram Moolenaar let s:idx = stridx(s:expandedtab, "\t") 96535a9aaabSBram Moolenaar endwhile 966*2a8a3ecbSBram Moolenaar end 96735a9aaabSBram Moolenaar 9687510fe74SBram Moolenaar " get the highlight group name to use 969071d4279SBram Moolenaar let s:id = synIDtrans(s:id) 970071d4279SBram Moolenaar let s:id_name = synIDattr(s:id, "name", s:whatterm) 9718ada2ccaSBram Moolenaar if s:diff_id 9728ada2ccaSBram Moolenaar let s:diff_id_name = synIDattr(s:diff_id, "name", s:whatterm) 9738ada2ccaSBram Moolenaar endif 9747510fe74SBram Moolenaar else 9757510fe74SBram Moolenaar " use Conceal highlighting for concealed text 9767510fe74SBram Moolenaar let s:id_name = 'Conceal' 9777510fe74SBram Moolenaar let s:expandedtab = s:concealinfo[1] 9787510fe74SBram Moolenaar endif 9797510fe74SBram Moolenaar 9807510fe74SBram Moolenaar " Output the text with the same synID, with class set to {s:id_name}, 9818ada2ccaSBram Moolenaar " unless it has been concealed completely. 9827510fe74SBram Moolenaar if strlen(s:expandedtab) > 0 9838ada2ccaSBram Moolenaar let s:new = s:new . s:HtmlFormat(s:expandedtab, s:id_name, s:diff_id_name) 9847510fe74SBram Moolenaar endif 985071d4279SBram Moolenaar endwhile 9867b0294cbSBram Moolenaar endif 987071d4279SBram Moolenaar 9887510fe74SBram Moolenaar call extend(s:lines, split(s:new.s:HtmlEndline, '\n', 1)) 989076e8b2aSBram Moolenaar if !s:settings.no_progress && s:pgb.needs_redraw 990349b2fb0SBram Moolenaar redrawstatus 991349b2fb0SBram Moolenaar let s:pgb.needs_redraw = 0 992349b2fb0SBram Moolenaar endif 993071d4279SBram Moolenaar let s:lnum = s:lnum + 1 994313b7237SBram Moolenaar 995076e8b2aSBram Moolenaar if !s:settings.no_progress 996349b2fb0SBram Moolenaar call s:pgb.incr() 997349b2fb0SBram Moolenaar endif 998349b2fb0SBram Moolenaarendwhile 999349b2fb0SBram Moolenaar 1000076e8b2aSBram Moolenaarif s:settings.dynamic_folds 10015c73622aSBram Moolenaar " finish off any open folds 10025c73622aSBram Moolenaar while !empty(s:foldstack) 1003349b2fb0SBram Moolenaar let s:lines[-1].="</span></span>" 10045c73622aSBram Moolenaar call remove(s:foldstack, 0) 10055c73622aSBram Moolenaar endwhile 10065c73622aSBram Moolenaar 10075c73622aSBram Moolenaar " add fold column to the style list if not already there 10085c73622aSBram Moolenaar let s:id = hlID('FoldColumn') 10098ada2ccaSBram Moolenaar if index(s:idlist, s:id) == -1 10108ada2ccaSBram Moolenaar call insert(s:idlist, s:id) 10115c73622aSBram Moolenaar endif 10125c73622aSBram Moolenaarendif 10135c73622aSBram Moolenaar 1014076e8b2aSBram Moolenaarif s:settings.no_pre 1015076e8b2aSBram Moolenaar if !s:settings.use_css 10168ada2ccaSBram Moolenaar " Close off the font tag that encapsulates the whole <body> 1017bebca9daSBram Moolenaar call extend(s:lines, ["</font>", "</body>", "</html>"]) 10188ada2ccaSBram Moolenaar else 1019349b2fb0SBram Moolenaar call extend(s:lines, ["</body>", "</html>"]) 10208ada2ccaSBram Moolenaar endif 1021071d4279SBram Moolenaarelse 1022349b2fb0SBram Moolenaar call extend(s:lines, ["</pre>", "</body>", "</html>"]) 1023071d4279SBram Moolenaarendif 1024071d4279SBram Moolenaar 1025349b2fb0SBram Moolenaarexe s:newwin . "wincmd w" 1026349b2fb0SBram Moolenaarcall setline(1, s:lines) 1027349b2fb0SBram Moolenaarunlet s:lines 1028071d4279SBram Moolenaar 1029071d4279SBram Moolenaar" Now, when we finally know which, we define the colors and styles 1030076e8b2aSBram Moolenaarif s:settings.use_css 1031071d4279SBram Moolenaar 1;/<style type="text/+1 1032071d4279SBram Moolenaarendif 1033071d4279SBram Moolenaar 1034071d4279SBram Moolenaar" Find out the background and foreground color. 1035071d4279SBram Moolenaarlet s:fgc = s:HtmlColor(synIDattr(hlID("Normal"), "fg#", s:whatterm)) 1036071d4279SBram Moolenaarlet s:bgc = s:HtmlColor(synIDattr(hlID("Normal"), "bg#", s:whatterm)) 1037071d4279SBram Moolenaarif s:fgc == "" 1038071d4279SBram Moolenaar let s:fgc = ( &background == "dark" ? "#ffffff" : "#000000" ) 1039071d4279SBram Moolenaarendif 1040071d4279SBram Moolenaarif s:bgc == "" 1041071d4279SBram Moolenaar let s:bgc = ( &background == "dark" ? "#000000" : "#ffffff" ) 1042071d4279SBram Moolenaarendif 1043071d4279SBram Moolenaar 1044071d4279SBram Moolenaar" Normal/global attributes 1045071d4279SBram Moolenaar" For Netscape 4, set <body> attributes too, though, strictly speaking, it's 1046071d4279SBram Moolenaar" incorrect. 1047076e8b2aSBram Moolenaarif s:settings.use_css 1048076e8b2aSBram Moolenaar if s:settings.no_pre 1049313b7237SBram Moolenaar execute "normal! A\nbody { color: " . s:fgc . "; background-color: " . s:bgc . "; font-family: ". s:htmlfont ."; }\e" 1050071d4279SBram Moolenaar else 1051313b7237SBram Moolenaar execute "normal! A\npre { font-family: ". s:htmlfont ."; color: " . s:fgc . "; background-color: " . s:bgc . "; }\e" 1052071d4279SBram Moolenaar yank 1053071d4279SBram Moolenaar put 1054071d4279SBram Moolenaar execute "normal! ^cwbody\e" 1055071d4279SBram Moolenaar endif 1056071d4279SBram Moolenaarelse 1057bebca9daSBram Moolenaar execute '%s:<body>:<body bgcolor="' . s:bgc . '" text="' . s:fgc . '">\r<font face="'. s:htmlfont .'">' 1058071d4279SBram Moolenaarendif 1059071d4279SBram Moolenaar 1060071d4279SBram Moolenaar" Line numbering attributes 1061076e8b2aSBram Moolenaarif s:settings.number_lines 1062076e8b2aSBram Moolenaar if s:settings.use_css 1063071d4279SBram Moolenaar execute "normal! A\n.lnr { " . s:CSS1(hlID("LineNr")) . "}\e" 1064071d4279SBram Moolenaar else 10658424a624SBram Moolenaar execute '%s+^<span class="lnr">\([^<]*\)</span>+' . s:HtmlOpening(hlID("LineNr")) . '\1' . s:HtmlClosing(hlID("LineNr")) . '+g' 1066071d4279SBram Moolenaar endif 1067071d4279SBram Moolenaarendif 1068071d4279SBram Moolenaar 1069071d4279SBram Moolenaar" Gather attributes for all other classes 1070076e8b2aSBram Moolenaarif !s:settings.no_progress && !empty(s:idlist) 1071349b2fb0SBram Moolenaar let s:pgb = s:ProgressBar("Processing classes:", len(s:idlist),s:newwin) 1072349b2fb0SBram Moolenaarendif 1073349b2fb0SBram Moolenaarwhile !empty(s:idlist) 1074071d4279SBram Moolenaar let s:attr = "" 1075349b2fb0SBram Moolenaar let s:id = remove(s:idlist, 0) 1076071d4279SBram Moolenaar let s:attr = s:CSS1(s:id) 1077071d4279SBram Moolenaar let s:id_name = synIDattr(s:id, "name", s:whatterm) 1078349b2fb0SBram Moolenaar 1079071d4279SBram Moolenaar " If the class has some attributes, export the style, otherwise DELETE all 1080071d4279SBram Moolenaar " its occurences to make the HTML shorter 1081071d4279SBram Moolenaar if s:attr != "" 1082076e8b2aSBram Moolenaar if s:settings.use_css 1083071d4279SBram Moolenaar execute "normal! A\n." . s:id_name . " { " . s:attr . "}" 1084071d4279SBram Moolenaar else 10858ada2ccaSBram Moolenaar " replace spans of just this class name with non-CSS style markup 10868ada2ccaSBram Moolenaar execute '%s+<span class="' . s:id_name . '">\([^<]*\)</span>+' . s:HtmlOpening(s:id) . '\1' . s:HtmlClosing(s:id) . '+ge' 10878ada2ccaSBram Moolenaar " Replace spans of this class name AND a diff class with non-CSS style 10888ada2ccaSBram Moolenaar " markup surrounding a span of just the diff class. The diff class will 10898ada2ccaSBram Moolenaar " be handled later because we know that information is at the end. 10908ada2ccaSBram 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' 1091071d4279SBram Moolenaar endif 1092071d4279SBram Moolenaar else 1093313b7237SBram Moolenaar execute '%s+<span class="' . s:id_name . '">\([^<]*\)</span>+\1+ge' 10948ada2ccaSBram Moolenaar execute '%s+<span class="' . s:id_name . ' \(Diff\%(Add\|Change\|Delete\|Text\)\)">\([^<]*\)</span>+<span class="\1">\2</span>+ge' 1095076e8b2aSBram Moolenaar if s:settings.use_css 10968ada2ccaSBram Moolenaar 1;/<\/style>/-2 1097071d4279SBram Moolenaar endif 1098071d4279SBram Moolenaar endif 1099349b2fb0SBram Moolenaar 1100076e8b2aSBram Moolenaar if !s:settings.no_progress 1101349b2fb0SBram Moolenaar call s:pgb.incr() 1102349b2fb0SBram Moolenaar if s:pgb.needs_redraw 1103349b2fb0SBram Moolenaar redrawstatus 1104349b2fb0SBram Moolenaar let s:pgb.needs_redraw = 0 1105bebca9daSBram Moolenaar " TODO: sleep here to show the progress bar, but only if total time spent 1106bebca9daSBram Moolenaar " so far on this step is < 1 second? Too slow for batch runs like the test 1107bebca9daSBram Moolenaar " suite to sleep all the time. Maybe there's no good reason to sleep at 1108bebca9daSBram Moolenaar " all. 1109349b2fb0SBram Moolenaar endif 1110349b2fb0SBram Moolenaar endif 1111071d4279SBram Moolenaarendwhile 1112071d4279SBram Moolenaar 1113071d4279SBram Moolenaar" Add hyperlinks 11141cd871b5SBram Moolenaar%s+\(https\=://\S\{-}\)\(\([.,;:}]\=\(\s\|$\)\)\|[\\"'<>]\|>\|<\|"\)+<a href="\1">\1</a>\2+ge 1115071d4279SBram Moolenaar 1116071d4279SBram Moolenaar" The DTD 1117076e8b2aSBram Moolenaarif s:settings.use_xhtml 1118076e8b2aSBram 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\">" 1119076e8b2aSBram Moolenaarelseif s:settings.use_css && !s:settings.no_pre 1120076e8b2aSBram Moolenaar exe "normal! gg0i<!DOCTYPE HTML PUBLIC \"-//W3C//DTD HTML 4.01//EN\" \"http://www.w3.org/TR/html4/strict.dtd\">\n" 11211cd871b5SBram Moolenaarelse 1122076e8b2aSBram Moolenaar exe "normal! gg0i<!DOCTYPE HTML PUBLIC \"-//W3C//DTD HTML 4.01 Transitional//EN\" \"http://www.w3.org/TR/html4/loose.dtd\">\n" 11231cd871b5SBram Moolenaarendif 11241cd871b5SBram Moolenaar 1125076e8b2aSBram Moolenaarif s:settings.use_xhtml 11261cd871b5SBram Moolenaar exe "normal! gg/<html/e\na xmlns=\"http://www.w3.org/1999/xhtml\"\e" 11271cd871b5SBram Moolenaarendif 1128071d4279SBram Moolenaar 1129071d4279SBram Moolenaar" Cleanup 1130071d4279SBram Moolenaar%s:\s\+$::e 1131071d4279SBram Moolenaar 1132*2a8a3ecbSBram Moolenaar" Restore old settings (new window first) 11338df7f888SBram Moolenaarlet &l:foldenable = s:old_fen 1134349b2fb0SBram Moolenaarlet &l:foldmethod = s:old_fdm 1135071d4279SBram Moolenaarlet &report = s:old_report 1136071d4279SBram Moolenaarlet &title = s:old_title 1137071d4279SBram Moolenaarlet &icon = s:old_icon 1138071d4279SBram Moolenaarlet &paste = s:old_paste 1139071d4279SBram Moolenaarlet &magic = s:old_magic 1140071d4279SBram Moolenaarlet @/ = s:old_search 1141349b2fb0SBram Moolenaarlet &more = s:old_more 1142*2a8a3ecbSBram Moolenaar 1143*2a8a3ecbSBram Moolenaar" switch to original window to restore those settings 1144071d4279SBram Moolenaarexe s:orgwin . "wincmd w" 1145*2a8a3ecbSBram Moolenaar 1146*2a8a3ecbSBram Moolenaarif !s:settings.expand_tabs 1147*2a8a3ecbSBram Moolenaar let &l:isprint = s:old_isprint 1148*2a8a3ecbSBram Moolenaarendif 1149166af9bbSBram Moolenaarlet &l:stl = s:origwin_stl 1150071d4279SBram Moolenaarlet &l:et = s:old_et 11518df7f888SBram Moolenaarlet &l:scrollbind = s:old_bind 1152*2a8a3ecbSBram Moolenaar 1153*2a8a3ecbSBram Moolenaar" and back to the new window again to end there 1154071d4279SBram Moolenaarexe s:newwin . "wincmd w" 1155*2a8a3ecbSBram Moolenaar 1156166af9bbSBram Moolenaarlet &l:stl = s:newwin_stl 1157349b2fb0SBram Moolenaarexec 'resize' s:old_winheight 1158349b2fb0SBram Moolenaarlet &l:winfixheight = s:old_winfixheight 1159071d4279SBram Moolenaar 1160349b2fb0SBram Moolenaarlet &ls=s:ls 1161349b2fb0SBram Moolenaar 1162071d4279SBram Moolenaar" Save a little bit of memory (worth doing?) 1163313b7237SBram Moolenaarunlet s:htmlfont 11648df7f888SBram Moolenaarunlet s:old_et s:old_paste s:old_icon s:old_report s:old_title s:old_search 11658df7f888SBram Moolenaarunlet s:old_magic s:old_more s:old_fdm s:old_fen s:old_winheight 1166*2a8a3ecbSBram Moolenaarunlet! s:old_isprint 11678df7f888SBram Moolenaarunlet s:whatterm s:idlist s:lnum s:end s:margin s:fgc s:bgc s:old_winfixheight 1168076e8b2aSBram Moolenaarunlet! s:col s:id s:attr s:len s:line s:new s:expandedtab s:concealinfo 11698df7f888SBram Moolenaarunlet! s:orgwin s:newwin s:orgbufnr s:idx s:i s:offset s:ls s:origwin_stl 11708df7f888SBram Moolenaarunlet! s:newwin_stl s:current_syntax 117105159a0cSBram Moolenaarif !v:profiling 1172071d4279SBram Moolenaar delfunc s:HtmlColor 117335a9aaabSBram Moolenaar delfunc s:HtmlFormat 1174071d4279SBram Moolenaar delfunc s:CSS1 1175076e8b2aSBram Moolenaar if !s:settings.use_css 1176071d4279SBram Moolenaar delfunc s:HtmlOpening 1177071d4279SBram Moolenaar delfunc s:HtmlClosing 1178071d4279SBram Moolenaar endif 1179076e8b2aSBram Moolenaar if s:settings.dynamic_folds 11805c73622aSBram Moolenaar delfunc s:FoldCompare 11815c73622aSBram Moolenaar endif 11825c73622aSBram Moolenaar 1183076e8b2aSBram Moolenaar if !s:settings.no_progress 1184349b2fb0SBram Moolenaar delfunc s:ProgressBar 1185349b2fb0SBram Moolenaar delfunc s:progressbar.paint 1186349b2fb0SBram Moolenaar delfunc s:progressbar.incr 1187349b2fb0SBram Moolenaar unlet s:pgb s:progressbar 1188349b2fb0SBram Moolenaar endif 1189349b2fb0SBram Moolenaarendif 1190349b2fb0SBram Moolenaar 11918df7f888SBram Moolenaarunlet! s:new_lnum s:diffattr s:difffillchar s:foldfillchar s:HtmlSpace 11928df7f888SBram Moolenaarunlet! s:LeadingSpace s:HtmlEndline s:firstfold s:foldcolumn 1193076e8b2aSBram Moolenaarunlet s:foldstack s:allfolds s:foldId s:numcol s:settings 11945c73622aSBram Moolenaar 11955c73622aSBram Moolenaarlet &cpo = s:cpo_sav 1196349b2fb0SBram Moolenaarunlet! s:cpo_sav 11975c73622aSBram Moolenaar 1198349b2fb0SBram Moolenaar" Make sure any patches will probably use consistent indent 11997c86f4ccSBram Moolenaar" vim: ts=8 sw=2 sts=2 noet 1200