Team Ai
Datasetpublic

codekingpro/portable-devtools

sourceHugging Faceupdated 5mo agoView on Hugging Face
1likes15kdownloads
2html.vim2073 linesDownload Raw Back to syntax
1" Vim syntax support file2" Maintainer: Ben Fritz <fritzophrenic@gmail.com>3" Last Change: 2024 Nov 024"5" Additional contributors:6"7"             Original by Bram Moolenaar <Bram@vim.org>8"             Modified by David Ne\v{c}as (Yeti) <yeti@physics.muni.cz>9"             XHTML support by Panagiotis Issaris <takis@lumumba.luc.ac.be>10"             Made w3 compliant by Edd Barrett <vext01@gmail.com>11"             Added html_font. Edd Barrett <vext01@gmail.com>12"             Progress bar based off code from "progressbar widget" plugin by13"               Andreas Politz, heavily modified:14"               http://www.vim.org/scripts/script.php?script_id=200615"16"             See Mercurial change logs for more!17 18" Transform a file into HTML, using the current syntax highlighting.19 20" this file uses line continuations21let s:cpo_sav = &cpo22let s:ls  = &ls23let s:ei_sav = &eventignore24set cpo&vim25 26" HTML filetype can take a while to load/highlight if the destination file27" already exists.28set eventignore+=FileType29 30let s:end=line('$')31 32" Font33if exists("g:html_font")34  if type(g:html_font) == type([])35    let s:htmlfont = "'".. join(g:html_font,"','") .. "', monospace"36  else37    let s:htmlfont = "'".. g:html_font .. "', monospace"38  endif39else40  let s:htmlfont = "monospace"41endif42 43let s:settings = tohtml#GetUserSettings()44 45if s:settings.use_xhtml46  let s:html5 = 047elseif s:settings.use_css && !s:settings.no_pre48  let s:html5 = 149else50  let s:html5 = 051endif52 53if !exists('s:FOLDED_ID')54  let s:FOLDED_ID  = hlID("Folded")     | lockvar s:FOLDED_ID55  let s:FOLD_C_ID  = hlID("FoldColumn") | lockvar s:FOLD_C_ID56  let s:LINENR_ID  = hlID('LineNr')     | lockvar s:LINENR_ID57  let s:DIFF_D_ID  = hlID("DiffDelete") | lockvar s:DIFF_D_ID58  let s:DIFF_A_ID  = hlID("DiffAdd")    | lockvar s:DIFF_A_ID59  let s:DIFF_C_ID  = hlID("DiffChange") | lockvar s:DIFF_C_ID60  let s:DIFF_T_ID  = hlID("DiffText")   | lockvar s:DIFF_T_ID61  let s:CONCEAL_ID = hlID('Conceal')    | lockvar s:CONCEAL_ID62endif63 64" Whitespace65if s:settings.pre_wrap66  let s:whitespace = "white-space: pre-wrap; "67else68  let s:whitespace = ""69endif70 71if !empty(s:settings.prevent_copy)72  if s:settings.no_invalid73    " User has decided they don't want invalid markup. Still works in74    " OpenOffice, and for text editors, but when pasting into Microsoft Word the75    " input elements get pasted too and they cannot be deleted (at least not76    " easily).77    let s:unselInputType = ""78  else79    " Prevent from copy-pasting the input elements into Microsoft Word where80    " they cannot be deleted easily by deliberately inserting invalid markup.81    let s:unselInputType = " type='invalid_input_type'"82  endif83endif84 85" When gui colors are not supported, we can only guess the colors.86" TODO - is this true anymore? Is there a way to ask the terminal what colors87" each number means or read them from some file?88if &termguicolors || has("gui_running")89  let s:whatterm = "gui"90else91  let s:whatterm = "cterm"92  if &t_Co == 893    let s:cterm_color = {94	    \   0: "#808080", 1: "#ff6060", 2: "#00ff00", 3: "#ffff00",95	    \   4: "#8080ff", 5: "#ff40ff", 6: "#00ffff", 7: "#ffffff"96	    \ }97  else98    let s:cterm_color = {99	    \   0: "#000000", 1: "#c00000", 2: "#008000", 3: "#804000", 100	    \   4: "#0000c0", 5: "#c000c0", 6: "#008080", 7: "#c0c0c0", 101	    \   8: "#808080", 9: "#ff6060", 10: "#00ff00", 11: "#ffff00",102	    \   12: "#8080ff", 13: "#ff40ff", 14: "#00ffff", 15: "#ffffff"103	    \ }104 105    " Colors for 88 and 256 come from xterm.106    if &t_Co == 88107      call extend(s:cterm_color, {108	    \   16: "#000000", 17: "#00008b", 18: "#0000cd", 19: "#0000ff",109	    \   20: "#008b00", 21: "#008b8b", 22: "#008bcd", 23: "#008bff",110	    \   24: "#00cd00", 25: "#00cd8b", 26: "#00cdcd", 27: "#00cdff",111	    \   28: "#00ff00", 29: "#00ff8b", 30: "#00ffcd", 31: "#00ffff",112	    \   32: "#8b0000", 33: "#8b008b", 34: "#8b00cd", 35: "#8b00ff",113	    \   36: "#8b8b00", 37: "#8b8b8b", 38: "#8b8bcd", 39: "#8b8bff",114	    \   40: "#8bcd00", 41: "#8bcd8b", 42: "#8bcdcd", 43: "#8bcdff",115	    \   44: "#8bff00", 45: "#8bff8b", 46: "#8bffcd", 47: "#8bffff",116	    \   48: "#cd0000", 49: "#cd008b", 50: "#cd00cd", 51: "#cd00ff",117	    \   52: "#cd8b00", 53: "#cd8b8b", 54: "#cd8bcd", 55: "#cd8bff",118	    \   56: "#cdcd00", 57: "#cdcd8b", 58: "#cdcdcd", 59: "#cdcdff",119	    \   60: "#cdff00", 61: "#cdff8b", 62: "#cdffcd", 63: "#cdffff",120	    \   64: "#ff0000"121	    \ })122      call extend(s:cterm_color, {123	    \   65: "#ff008b", 66: "#ff00cd", 67: "#ff00ff", 68: "#ff8b00",124	    \   69: "#ff8b8b", 70: "#ff8bcd", 71: "#ff8bff", 72: "#ffcd00",125	    \   73: "#ffcd8b", 74: "#ffcdcd", 75: "#ffcdff", 76: "#ffff00",126	    \   77: "#ffff8b", 78: "#ffffcd", 79: "#ffffff", 80: "#2e2e2e",127	    \   81: "#5c5c5c", 82: "#737373", 83: "#8b8b8b", 84: "#a2a2a2",128	    \   85: "#b9b9b9", 86: "#d0d0d0", 87: "#e7e7e7"129	    \ })130    elseif &t_Co == 256131      call extend(s:cterm_color, {132	    \   16: "#000000", 17: "#00005f", 18: "#000087", 19: "#0000af",133	    \   20: "#0000d7", 21: "#0000ff", 22: "#005f00", 23: "#005f5f",134	    \   24: "#005f87", 25: "#005faf", 26: "#005fd7", 27: "#005fff",135	    \   28: "#008700", 29: "#00875f", 30: "#008787", 31: "#0087af",136	    \   32: "#0087d7", 33: "#0087ff", 34: "#00af00", 35: "#00af5f",137	    \   36: "#00af87", 37: "#00afaf", 38: "#00afd7", 39: "#00afff",138	    \   40: "#00d700", 41: "#00d75f", 42: "#00d787", 43: "#00d7af",139	    \   44: "#00d7d7", 45: "#00d7ff", 46: "#00ff00", 47: "#00ff5f",140	    \   48: "#00ff87", 49: "#00ffaf", 50: "#00ffd7", 51: "#00ffff",141	    \   52: "#5f0000", 53: "#5f005f", 54: "#5f0087", 55: "#5f00af",142	    \   56: "#5f00d7", 57: "#5f00ff", 58: "#5f5f00", 59: "#5f5f5f",143	    \   60: "#5f5f87", 61: "#5f5faf", 62: "#5f5fd7", 63: "#5f5fff",144	    \   64: "#5f8700"145	    \ })146      call extend(s:cterm_color, {147	    \   65: "#5f875f", 66: "#5f8787", 67: "#5f87af", 68: "#5f87d7",148	    \   69: "#5f87ff", 70: "#5faf00", 71: "#5faf5f", 72: "#5faf87",149	    \   73: "#5fafaf", 74: "#5fafd7", 75: "#5fafff", 76: "#5fd700",150	    \   77: "#5fd75f", 78: "#5fd787", 79: "#5fd7af", 80: "#5fd7d7",151	    \   81: "#5fd7ff", 82: "#5fff00", 83: "#5fff5f", 84: "#5fff87",152	    \   85: "#5fffaf", 86: "#5fffd7", 87: "#5fffff", 88: "#870000",153	    \   89: "#87005f", 90: "#870087", 91: "#8700af", 92: "#8700d7",154	    \   93: "#8700ff", 94: "#875f00", 95: "#875f5f", 96: "#875f87",155	    \   97: "#875faf", 98: "#875fd7", 99: "#875fff", 100: "#878700",156	    \   101: "#87875f", 102: "#878787", 103: "#8787af", 104: "#8787d7",157	    \   105: "#8787ff", 106: "#87af00", 107: "#87af5f", 108: "#87af87",158	    \   109: "#87afaf", 110: "#87afd7", 111: "#87afff", 112: "#87d700"159	    \ })160      call extend(s:cterm_color, {161	    \   113: "#87d75f", 114: "#87d787", 115: "#87d7af", 116: "#87d7d7",162	    \   117: "#87d7ff", 118: "#87ff00", 119: "#87ff5f", 120: "#87ff87",163	    \   121: "#87ffaf", 122: "#87ffd7", 123: "#87ffff", 124: "#af0000",164	    \   125: "#af005f", 126: "#af0087", 127: "#af00af", 128: "#af00d7",165	    \   129: "#af00ff", 130: "#af5f00", 131: "#af5f5f", 132: "#af5f87",166	    \   133: "#af5faf", 134: "#af5fd7", 135: "#af5fff", 136: "#af8700",167	    \   137: "#af875f", 138: "#af8787", 139: "#af87af", 140: "#af87d7",168	    \   141: "#af87ff", 142: "#afaf00", 143: "#afaf5f", 144: "#afaf87",169	    \   145: "#afafaf", 146: "#afafd7", 147: "#afafff", 148: "#afd700",170	    \   149: "#afd75f", 150: "#afd787", 151: "#afd7af", 152: "#afd7d7",171	    \   153: "#afd7ff", 154: "#afff00", 155: "#afff5f", 156: "#afff87",172	    \   157: "#afffaf", 158: "#afffd7"173	    \ })174      call extend(s:cterm_color, {175	    \   159: "#afffff", 160: "#d70000", 161: "#d7005f", 162: "#d70087",176	    \   163: "#d700af", 164: "#d700d7", 165: "#d700ff", 166: "#d75f00",177	    \   167: "#d75f5f", 168: "#d75f87", 169: "#d75faf", 170: "#d75fd7",178	    \   171: "#d75fff", 172: "#d78700", 173: "#d7875f", 174: "#d78787",179	    \   175: "#d787af", 176: "#d787d7", 177: "#d787ff", 178: "#d7af00",180	    \   179: "#d7af5f", 180: "#d7af87", 181: "#d7afaf", 182: "#d7afd7",181	    \   183: "#d7afff", 184: "#d7d700", 185: "#d7d75f", 186: "#d7d787",182	    \   187: "#d7d7af", 188: "#d7d7d7", 189: "#d7d7ff", 190: "#d7ff00",183	    \   191: "#d7ff5f", 192: "#d7ff87", 193: "#d7ffaf", 194: "#d7ffd7",184	    \   195: "#d7ffff", 196: "#ff0000", 197: "#ff005f", 198: "#ff0087",185	    \   199: "#ff00af", 200: "#ff00d7", 201: "#ff00ff", 202: "#ff5f00",186	    \   203: "#ff5f5f", 204: "#ff5f87"187	    \ })188      call extend(s:cterm_color, {189	    \   205: "#ff5faf", 206: "#ff5fd7", 207: "#ff5fff", 208: "#ff8700",190	    \   209: "#ff875f", 210: "#ff8787", 211: "#ff87af", 212: "#ff87d7",191	    \   213: "#ff87ff", 214: "#ffaf00", 215: "#ffaf5f", 216: "#ffaf87",192	    \   217: "#ffafaf", 218: "#ffafd7", 219: "#ffafff", 220: "#ffd700",193	    \   221: "#ffd75f", 222: "#ffd787", 223: "#ffd7af", 224: "#ffd7d7",194	    \   225: "#ffd7ff", 226: "#ffff00", 227: "#ffff5f", 228: "#ffff87",195	    \   229: "#ffffaf", 230: "#ffffd7", 231: "#ffffff", 232: "#080808",196	    \   233: "#121212", 234: "#1c1c1c", 235: "#262626", 236: "#303030",197	    \   237: "#3a3a3a", 238: "#444444", 239: "#4e4e4e", 240: "#585858",198	    \   241: "#626262", 242: "#6c6c6c", 243: "#767676", 244: "#808080",199	    \   245: "#8a8a8a", 246: "#949494", 247: "#9e9e9e", 248: "#a8a8a8",200	    \   249: "#b2b2b2", 250: "#bcbcbc", 251: "#c6c6c6", 252: "#d0d0d0",201	    \   253: "#dadada", 254: "#e4e4e4", 255: "#eeeeee"202	    \ })203    endif204  endif205endif206 207" Return good color specification: in GUI no transformation is done, in208" terminal return RGB values of known colors and empty string for unknown209if s:whatterm == "gui"210  function! s:HtmlColor(color)211    return a:color212  endfun213else214  function! s:HtmlColor(color)215    if has_key(s:cterm_color, a:color)216      return s:cterm_color[a:color]217    else218      return ""219    endif220  endfun221endif222 223" Find out the background and foreground color for use later224let s:fgc = s:HtmlColor(synIDattr(hlID("Normal")->synIDtrans(), "fg#", s:whatterm))225let s:bgc = s:HtmlColor(synIDattr(hlID("Normal")->synIDtrans(), "bg#", s:whatterm))226if s:fgc == ""227  let s:fgc = ( &background == "dark" ? "#ffffff" : "#000000" )228endif229if s:bgc == ""230  let s:bgc = ( &background == "dark" ? "#000000" : "#ffffff" )231endif232 233if !s:settings.use_css234  " Return opening HTML tag for given highlight id235  function! s:HtmlOpening(id, extra_attrs)236    let a = ""237    let translated_ID = synIDtrans(a:id)238    if synIDattr(translated_ID, "inverse")239      " For inverse, we always must set both colors (and exchange them)240      let x = s:HtmlColor(synIDattr(translated_ID, "fg#", s:whatterm))241      let a = a .. '<span '..a:extra_attrs..'style="background-color: ' .. ( x != "" ? x : s:fgc ) .. '">'242      let x = s:HtmlColor(synIDattr(translated_ID, "bg#", s:whatterm))243      let a = a .. '<font color="' .. ( x != "" ? x : s:bgc ) .. '">'244    else245      let x = s:HtmlColor(synIDattr(translated_ID, "bg#", s:whatterm))246      if x != ""247	let a = a .. '<span '..a:extra_attrs..'style="background-color: ' .. x .. '">'248      elseif !empty(a:extra_attrs)249	let a = a .. '<span '..a:extra_attrs..'>'250      endif251      let x = s:HtmlColor(synIDattr(translated_ID, "fg#", s:whatterm))252      if x != "" | let a = a .. '<font color="' .. x .. '">' | endif253    endif254    if synIDattr(translated_ID, "bold") | let a = a .. "<b>" | endif255    if synIDattr(translated_ID, "italic") | let a = a .. "<i>" | endif256    if synIDattr(translated_ID, "underline") | let a = a .. "<u>" | endif257    return a258  endfun259 260  " Return closing HTML tag for given highlight id261  function! s:HtmlClosing(id, has_extra_attrs)262    let a = ""263    let translated_ID = synIDtrans(a:id)264    if synIDattr(translated_ID, "underline") | let a = a .. "</u>" | endif265    if synIDattr(translated_ID, "italic") | let a = a .. "</i>" | endif266    if synIDattr(translated_ID, "bold") | let a = a .. "</b>" | endif267    if synIDattr(translated_ID, "inverse")268      let a = a .. '</font></span>'269    else270      let x = s:HtmlColor(synIDattr(translated_ID, "fg#", s:whatterm))271      if x != "" | let a = a .. '</font>' | endif272      let x = s:HtmlColor(synIDattr(translated_ID, "bg#", s:whatterm))273      if x != "" || a:has_extra_attrs | let a = a .. '</span>' | endif274    endif275    return a276  endfun277endif278 279" Use a different function for formatting based on user options. This way we280" can avoid a lot of logic during the actual execution.281"282" Build the function line by line containing only what is needed for the options283" in use for maximum code sharing with minimal branch logic for greater speed.284"285" Note, 'exec' commands do not recognize line continuations, so must concatenate286" lines rather than continue them.287if s:settings.use_css288  " save CSS to a list of rules to add to the output at the end of processing289 290  " first, get the style names we need291  let s:wrapperfunc_lines = []292  call add(s:wrapperfunc_lines, [])293  let s:wrapperfunc_lines[-1] =<< trim ENDLET294	function! s:BuildStyleWrapper(style_id, diff_style_id, extra_attrs, text, make_unselectable, unformatted)295	296	  let l:style_name = synIDattr(a:style_id, "name", s:whatterm)297  ENDLET298  if &diff299    call add(s:wrapperfunc_lines, [])300    let s:wrapperfunc_lines[-1] =<< trim ENDLET301	  let l:diff_style_name = synIDattr(a:diff_style_id, "name", s:whatterm)302    ENDLET303 304    " Add normal groups and diff groups to separate lists so we can order them to305    " allow diff highlight to override normal highlight306 307    " if primary style IS a diff style, grab it from the diff cache instead308    " (always succeeds because we pre-populate it)309    call add(s:wrapperfunc_lines, [])310    let s:wrapperfunc_lines[-1] =<< trim ENDLET311 312	  if a:style_id == s:DIFF_D_ID || a:style_id == s:DIFF_A_ID || a:style_id == s:DIFF_C_ID || a:style_id == s:DIFF_T_ID313	    let l:saved_style = get(s:diffstylelist,a:style_id)314	  else315    ENDLET316  endif317 318  " get primary style info from cache or build it on the fly if not found319  call add(s:wrapperfunc_lines, [])320  let s:wrapperfunc_lines[-1] =<< trim ENDLET321	    let l:saved_style = get(s:stylelist,a:style_id)322	    if type(l:saved_style) == type(0)323	      unlet l:saved_style324	      let l:saved_style = s:CSS1(a:style_id)325	      if l:saved_style != ""326	        let l:saved_style = "." .. l:style_name .. " { " .. l:saved_style .. "}"327	      endif328	      let s:stylelist[a:style_id] = l:saved_style329	    endif330  ENDLET331  if &diff332    call add(s:wrapperfunc_lines, [])333    let s:wrapperfunc_lines[-1] =<< trim ENDLET334	  endif335    ENDLET336  endif337" Ignore this comment, just bypassing a highlighting issue: if338 339  " Build the wrapper tags around the text. It turns out that caching these340  " gives pretty much zero performance gain and adds a lot of logic.341 342  call add(s:wrapperfunc_lines, [])343  let s:wrapperfunc_lines[-1] =<< trim ENDLET344 345	  if l:saved_style == "" && empty(a:extra_attrs)346  ENDLET347  if &diff348    call add(s:wrapperfunc_lines, [])349    let s:wrapperfunc_lines[-1] =<< trim ENDLET350	    if a:diff_style_id <= 0351    ENDLET352  endif353  " no surroundings if neither primary nor diff style has any info354  call add(s:wrapperfunc_lines, [])355  let s:wrapperfunc_lines[-1] =<< trim ENDLET356	      return a:text357  ENDLET358  if &diff359    " no primary style, but diff style360    call add(s:wrapperfunc_lines, [])361    let s:wrapperfunc_lines[-1] =<< trim ENDLET362	    else363	      return '<span class="' ..l:diff_style_name .. '">'..a:text.."</span>"364	    endif365    ENDLET366  endif367  " Ignore this comment, just bypassing a highlighting issue: if368 369  " open tag for non-empty primary style370  call add(s:wrapperfunc_lines, [])371  let s:wrapperfunc_lines[-1] =<< trim ENDLET372	  else373  ENDLET374  " non-empty primary style. handle either empty or non-empty diff style.375  "376  " separate the two classes by a space to apply them both if there is a diff377  " style name, unless the primary style is empty, then just use the diff style378  " name379  let s:diffstyle =380	  \ (&diff ? '(a:diff_style_id <= 0 ? "" : " " .. l:diff_style_name)..'381	  \        : '')382  if s:settings.prevent_copy == ""383    call add(s:wrapperfunc_lines, [])384    let s:wrapperfunc_lines[-1] =<< trim eval ENDLET385	    return "<span "..a:extra_attrs..'class="' .. l:style_name ..{s:diffstyle}'">'..a:text.."</span>"386    ENDLET387  else388 389    " New method: use generated content in the CSS. The only thing needed here390    " is a span with no content, with an attribute holding the desired text.391    "392    " Old method: use an <input> element when text is unsectable. This is still393    " used in conditional comments for Internet Explorer, where the new method394    " doesn't work.395    "396    " Wrap the <input> in a <span> to allow fixing the stupid bug in some fonts397    " which cause browsers to display a 1px gap between lines when these398    " <input>s have a background color (maybe not really a bug, this isn't399    " well-defined)400    "401    " use strwidth, because we care only about how many character boxes are402    " needed to size the input, we don't care how many characters (including403    " separately counted composing chars, from strchars()) or bytes (from404    " len())the string contains. strdisplaywidth() is not needed because none of405    " the unselectable groups can contain tab characters (fold column, fold406    " text, line number).407    "408    " Note, if maxlength property needs to be added in the future, it will need409    " to use strchars(), because HTML specifies that the maxlength parameter410    " uses the number of unique codepoints for its limit.411    call add(s:wrapperfunc_lines, [])412    let s:wrapperfunc_lines[-1] =<< trim eval ENDLET413	    if a:make_unselectable414	      let return_span = "<span "..a:extra_attrs..'class="' .. l:style_name ..{s:diffstyle}'"'415    ENDLET416    if s:settings.use_input_for_pc !=# 'all'417      call add(s:wrapperfunc_lines, [])418      let s:wrapperfunc_lines[-1] =<< trim ENDLET419	      let return_span ..= " data-" .. l:style_name .. '-content="'..a:text..'"'420      ENDLET421    endif422    call add(s:wrapperfunc_lines, [])423    let s:wrapperfunc_lines[-1] =<< trim ENDLET424	      let return_span ..= '>'425    ENDLET426    if s:settings.use_input_for_pc !=# 'none'427      call add(s:wrapperfunc_lines, [])428      let s:wrapperfunc_lines[-1] =<< trim eval ENDLET429	      let return_span ..=   '<input'..s:unselInputType..' class="' .. l:style_name ..{s:diffstyle}'"'430	      let return_span ..=   ' value="'..substitute(a:unformatted,'\s\+$',"","")..'"'431	      let return_span ..=   " onselect='this.blur(); return false;'"432	      let return_span ..=   " onmousedown='this.blur(); return false;'"433	      let return_span ..=   " onclick='this.blur(); return false;'"434	      let return_span ..=   " readonly='readonly'"435	      let return_span ..=   ' size="'..strwidth(a:unformatted)..'"'436	      let return_span ..=   (s:settings.use_xhtml ? '/>' : '>')437      ENDLET438    endif439    call add(s:wrapperfunc_lines, [])440    let s:wrapperfunc_lines[-1] =<< trim eval ENDLET441	      return return_span..'</span>'442	    else443	      return "<span "..a:extra_attrs..'class="' .. l:style_name .. {s:diffstyle}'">'..a:text.."</span>"444	    endif445    ENDLET446  endif447  call add(s:wrapperfunc_lines, [])448  let s:wrapperfunc_lines[-1] =<< trim ENDLET449	  endif450	endfun451  ENDLET452else453  " Non-CSS method just needs the wrapper.454  "455  " Functions used to get opening/closing automatically return null strings if456  " no styles exist.457  if &diff458    let s:wrapperfunc_lines =<< trim ENDLET459	function! s:BuildStyleWrapper(style_id, diff_style_id, extra_attrs, text, unusedarg, unusedarg2)460	  if a:diff_style_id <= 0461	    let l:diff_opening = s:HtmlOpening(a:diff_style_id, "")462	    let l:diff_closing = s:HtmlClosing(a:diff_style_id, 0)463	  else464	    let l:diff_opening = ""465	    let l:diff_closing = ""466	  endif467	  return s:HtmlOpening(a:style_id, a:extra_attrs)..l:diff_opening..a:text..l:diff_closing..s:HtmlClosing(a:style_id, !empty(a:extra_attrs))468	endfun469    ENDLET470  else471    let s:wrapperfunc_lines =<< trim ENDLET472	function! s:BuildStyleWrapper(style_id, diff_style_id, extra_attrs, text, unusedarg, unusedarg2)473	  return s:HtmlOpening(a:style_id, a:extra_attrs)..a:text..s:HtmlClosing(a:style_id, !empty(a:extra_attrs))474	endfun475    ENDLET476  endif477endif478 479" create the function we built line by line above480exec join(flatten(s:wrapperfunc_lines), "\n")481 482let s:diff_mode = &diff483 484" Return HTML valid characters enclosed in a span of class style_name with485" unprintable characters expanded and double spaces replaced as necessary.486"487" TODO: eliminate unneeded logic like done for BuildStyleWrapper488function! s:HtmlFormat(text, style_id, diff_style_id, extra_attrs, make_unselectable)489  " Replace unprintable characters490  let unformatted = strtrans(a:text)491 492  let formatted = unformatted493 494  " Replace the reserved html characters495  let formatted = substitute(formatted, '&', '\&amp;',  'g')496  let formatted = substitute(formatted, '<', '\&lt;',   'g')497  let formatted = substitute(formatted, '>', '\&gt;',   'g')498  let formatted = substitute(formatted, '"', '\&quot;', 'g')499  " &apos; is not valid in HTML but it is in XHTML, so just use the numeric500  " reference for it instead. Needed because it could appear in quotes501  " especially if unselectable regions is turned on.502  let formatted = substitute(formatted, '"', '\&#0039;', 'g')503 504  " Replace a "form feed" character with HTML to do a page break505  " TODO: need to prevent this in unselectable areas? Probably it should never506  " BE in an unselectable area...507  let formatted = substitute(formatted, "\x0c", '<hr class="PAGE-BREAK">', 'g')508 509  " Replace double spaces, leading spaces, and trailing spaces if needed510  if ' ' != s:HtmlSpace511    let formatted = substitute(formatted, '  ', s:HtmlSpace .. s:HtmlSpace, 'g')512    let formatted = substitute(formatted, '^ ', s:HtmlSpace, 'g')513    let formatted = substitute(formatted, ' \+$', s:HtmlSpace, 'g')514  endif515 516  " Enclose in the correct format517  return s:BuildStyleWrapper(a:style_id, a:diff_style_id, a:extra_attrs, formatted, a:make_unselectable, unformatted)518endfun519 520" set up functions to call HtmlFormat in certain ways based on whether the521" element is supposed to be unselectable or not522if s:settings.prevent_copy =~# 'n'523  if s:settings.number_lines524    if s:settings.line_ids525      function! s:HtmlFormat_n(text, style_id, diff_style_id, lnr)526	if a:lnr > 0527	  return s:HtmlFormat(a:text, a:style_id, a:diff_style_id, 'id="'..(exists('g:html_diff_win_num') ? 'W'..g:html_diff_win_num : "")..'L'..a:lnr..s:settings.id_suffix..'" ', 1)528	else529	  return s:HtmlFormat(a:text, a:style_id, a:diff_style_id, "", 1)530	endif531      endfun532    else533      function! s:HtmlFormat_n(text, style_id, diff_style_id, lnr)534	return s:HtmlFormat(a:text, a:style_id, a:diff_style_id, "", 1)535      endfun536    endif537  elseif s:settings.line_ids538    " if lines are not being numbered the only reason this function gets called539    " is to put the line IDs on each line; "text" will be empty but lnr will540    " always be non-zero, however we don't want to use the <input> because that541    " won't work as nice for empty text542    function! s:HtmlFormat_n(text, style_id, diff_style_id, lnr)543      return s:HtmlFormat(a:text, a:style_id, a:diff_style_id, 'id="'..(exists('g:html_diff_win_num') ? 'W'..g:html_diff_win_num : "")..'L'..a:lnr..s:settings.id_suffix..'" ', 0)544    endfun545  endif546else547  if s:settings.line_ids548    function! s:HtmlFormat_n(text, style_id, diff_style_id, lnr)549      if a:lnr > 0550	return s:HtmlFormat(a:text, a:style_id, a:diff_style_id, 'id="'..(exists('g:html_diff_win_num') ? 'W'..g:html_diff_win_num : "")..'L'..a:lnr..s:settings.id_suffix..'" ', 0)551      else552	return s:HtmlFormat(a:text, a:style_id, a:diff_style_id, "", 0)553      endif554    endfun555  else556    function! s:HtmlFormat_n(text, style_id, diff_style_id, lnr)557      return s:HtmlFormat(a:text, a:style_id, a:diff_style_id, "", 0)558    endfun559  endif560endif561if s:settings.prevent_copy =~# 'd'562  function! s:HtmlFormat_d(text, style_id, diff_style_id)563    return s:HtmlFormat(a:text, a:style_id, a:diff_style_id, "", 1)564  endfun565else566  function! s:HtmlFormat_d(text, style_id, diff_style_id)567    return s:HtmlFormat(a:text, a:style_id, a:diff_style_id, "", 0)568  endfun569endif570if s:settings.prevent_copy =~# 'f'571  if s:settings.use_input_for_pc ==# 'none'572    " Simply space-pad to the desired width inside the generated content (note573    " that the FoldColumn definition includes a whitespace:pre rule)574    function! s:FoldColumn_build(char, len, numfill, char2, class, click)575      return "<a href='#' class='"..a:class.."' onclick='"..a:click.."' data-FoldColumn-content='".576	    \ repeat(a:char, a:len)..a:char2..repeat(' ', a:numfill).577	    \ "'></a>"578    endfun579    function! s:FoldColumn_fill()580      return s:HtmlFormat(repeat(' ', s:foldcolumn), s:FOLD_C_ID, 0, "", 1)581    endfun582  else583    " Note the <input> elements for fill spaces will have a single space for584    " content, to allow active cursor CSS selection to work.585    "586    " Wrap the whole thing in a span for the 1px padding workaround for gaps.587    "588    " Build the function line by line containing only what is needed for the589    " options in use for maximum code sharing with minimal branch logic for590    " greater speed.591    "592    " Note, 'exec' commands do not recognize line continuations, so must593    " concatenate lines rather than continue them.594    let s:build_fun_lines = []595    call add(s:build_fun_lines, [])596    let s:build_fun_lines[-1] =<< trim ENDLET597	  function! s:FoldColumn_build(char, len, numfill, char2, class, click)598	    let l:input_open = "<input readonly='readonly'"..s:unselInputType599	    let l:input_open ..= " onselect='this.blur(); return false;'"600	    let l:input_open ..= " onmousedown='this.blur(); "..a:click.." return false;'"601	    let l:input_open ..= " onclick='return false;' size='"602	    let l:input_open ..= string(a:len + (empty(a:char2) ? 0 : 1) + a:numfill) .. "' "603	    let l:common_attrs = "class='FoldColumn' value='"604	    let l:input_close = (s:settings.use_xhtml ? "' />" : "'>")605	    let l:return_span = "<span class='"..a:class.."'>"606	    let l:return_span ..= l:input_open..l:common_attrs..repeat(a:char, a:len)..(a:char2)607	    let l:return_span ..= l:input_close608    ENDLET609    if s:settings.use_input_for_pc ==# 'fallback'610      call add(s:build_fun_lines, [])611      let s:build_fun_lines[-1] =<< trim ENDLET612	    let l:return_span ..= "<a href='#' class='FoldColumn' onclick='"..a:click.."'"613	    let l:return_span ..= " data-FoldColumn-content='"614	    let l:return_span ..= repeat(a:char, a:len)..a:char2..repeat(' ', a:numfill)615	    let l:return_span ..= "'></a>"616      ENDLET617    endif618    call add(s:build_fun_lines, [])619    let s:build_fun_lines[-1] =<< trim ENDLET620	    let l:return_span ..= "</span>"621	    return l:return_span622	  endfun623    ENDLET624    " create the function we built line by line above625    exec join(flatten(s:build_fun_lines), "\n")626 627    function! s:FoldColumn_fill()628      return s:FoldColumn_build(' ', s:foldcolumn, 0, '', 'FoldColumn', '')629    endfun630  endif631else632  " For normal fold columns, simply space-pad to the desired width (note that633  " the FoldColumn definition includes a whitespace:pre rule)634  function! s:FoldColumn_build(char, len, numfill, char2, class, click)635    return "<a href='#' class='"..a:class.."' onclick='"..a:click.."'>".636	  \ repeat(a:char, a:len)..a:char2..repeat(' ', a:numfill).637	  \ "</a>"638  endfun639  function! s:FoldColumn_fill()640    return s:HtmlFormat(repeat(' ', s:foldcolumn), s:FOLD_C_ID, 0, "", 0)641  endfun642endif643if s:settings.prevent_copy =~# 't'644  " put an extra empty span at the end for dynamic folds, so the linebreak can645  " be surrounded. Otherwise do it as normal.646  "647  " TODO: isn't there a better way to do this, than placing it here and using a648  " substitute later?649  if s:settings.dynamic_folds650    function! s:HtmlFormat_t(text, style_id, diff_style_id)651      return s:HtmlFormat(a:text, a:style_id, a:diff_style_id, "", 1) .652	    \ s:HtmlFormat("", a:style_id, 0, "", 0)653    endfun654  else655    function! s:HtmlFormat_t(text, style_id, diff_style_id)656      return s:HtmlFormat(a:text, a:style_id, a:diff_style_id, "", 1)657    endfun658  endif659else660  function! s:HtmlFormat_t(text, style_id, diff_style_id)661    return s:HtmlFormat(a:text, a:style_id, a:diff_style_id, "", 0)662  endfun663endif664 665" Return CSS style describing given highlight id (can be empty)666function! s:CSS1(id)667  let a = ""668  let translated_ID = synIDtrans(a:id)669  if synIDattr(translated_ID, "inverse")670    " For inverse, we always must set both colors (and exchange them)671    let x = s:HtmlColor(synIDattr(translated_ID, "bg#", s:whatterm))672    let a = a .. "color: " .. ( x != "" ? x : s:bgc ) .. "; "673    let x = s:HtmlColor(synIDattr(translated_ID, "fg#", s:whatterm))674    let a = a .. "background-color: " .. ( x != "" ? x : s:fgc ) .. "; "675  else676    let x = s:HtmlColor(synIDattr(translated_ID, "fg#", s:whatterm))677    if x != "" | let a = a .. "color: " .. x .. "; " | endif678    let x = s:HtmlColor(synIDattr(translated_ID, "bg#", s:whatterm))679    if x != ""680      let a = a .. "background-color: " .. x .. "; "681      " stupid hack because almost every browser seems to have at least one font682      " which shows 1px gaps between lines which have background683      let a = a .. "padding-bottom: 1px; "684    elseif (translated_ID == s:FOLDED_ID || translated_ID == s:LINENR_ID || translated_ID == s:FOLD_C_ID) && !empty(s:settings.prevent_copy)685      " input elements default to a different color than the rest of the page686      let a = a .. "background-color: " .. s:bgc .. "; "687    endif688  endif689  if synIDattr(translated_ID, "bold") | let a = a .. "font-weight: bold; " | endif690  if synIDattr(translated_ID, "italic") | let a = a .. "font-style: italic; " | endif691  if synIDattr(translated_ID, "underline") | let a = a .. "text-decoration: underline; " | endif692  return a693endfun694 695if s:settings.dynamic_folds696  " compares two folds as stored in our list of folds697  " A fold is "less" than another if it starts at an earlier line number,698  " or ends at a later line number, ties broken by fold level699  function! s:FoldCompare(f1, f2)700    if a:f1.firstline != a:f2.firstline701      " put it before if it starts earlier702      return a:f1.firstline - a:f2.firstline703    elseif a:f1.lastline != a:f2.lastline704      " put it before if it ends later705      return a:f2.lastline - a:f1.lastline706    else707      " if folds begin and end on the same lines, put lowest fold level first708      return a:f1.level - a:f2.level709    endif710  endfunction711 712endif713 714 715" Set some options to make it work faster.716" Don't report changes for :substitute, there will be many of them.717" Don't change other windows; turn off scroll bind temporarily718let s:old_title = &title719let s:old_icon = &icon720let s:old_et = &l:et721let s:old_bind = &l:scrollbind722let s:old_report = &report723let s:old_search = @/724let s:old_more = &more725set notitle noicon726setlocal et727set nomore728set report=1000000729setlocal noscrollbind730 731if exists(':ownsyntax') && exists('w:current_syntax')732  let s:current_syntax = w:current_syntax733elseif exists('b:current_syntax')734  let s:current_syntax = b:current_syntax735else736  let s:current_syntax = 'none'737endif738 739if s:current_syntax == ''740  let s:current_syntax = 'none'741endif742 743" If the user is sourcing this script directly then the plugin version isn't744" known because the main plugin script didn't load. In the usual case where the745" user still has the full Vim runtime installed, or has this full plugin746" installed in a package or something, then we can extract the version from the747" main plugin file at it's usual spot relative to this file. Otherwise the user748" is assembling their runtime piecemeal and we have no idea what versions of749" other files may be present so don't even try to make a guess or assume the750" presence of other specific files with specific meaning.751"752" We don't want to actually source the main plugin file here because the user753" may have a good reason not to (e.g. they define their own TOhtml command or754" something).755"756" If this seems way too complicated and convoluted, it is. Probably I should757" have put the version information in the autoload file from the start. But the758" version has been in the global variable for so long that changing it could759" break a lot of user scripts.760if exists("g:loaded_2html_plugin")761  let s:pluginversion = g:loaded_2html_plugin762else763  if !exists("g:unloaded_tohtml_plugin")764    let s:main_plugin_path = expand("<sfile>:p:h:h").."/plugin/tohtml.vim"765    if filereadable(s:main_plugin_path)766      let s:lines = readfile(s:main_plugin_path, "", 20)767      call filter(s:lines, 'v:val =~ "loaded_2html_plugin = "')768      if empty(s:lines)769	let g:unloaded_tohtml_plugin = "unknown"770      else771	let g:unloaded_tohtml_plugin = substitute(s:lines[0], '.*loaded_2html_plugin = \([''"]\)\(\%(\1\@!.\)\+\)\1', '\2', '')772      endif773      unlet s:lines774    else775      let g:unloaded_tohtml_plugin = "unknown"776    endif777    unlet s:main_plugin_path778  endif779  let s:pluginversion = g:unloaded_tohtml_plugin780endif781 782" Split window to create a buffer with the HTML file.783let s:orgbufnr = winbufnr(0)784let s:origwin_stl = &l:stl785if expand("%") == ""786  if exists('g:html_diff_win_num')787    exec 'new Untitled_win'..g:html_diff_win_num..'.'.(s:settings.use_xhtml ? 'xhtml' : 'html')788  else789    exec 'new Untitled.'..(s:settings.use_xhtml ? 'xhtml' : 'html')790  endif791else792  exec 'new %.'..(s:settings.use_xhtml ? 'xhtml' : 'html')793endif794 795" Resize the new window to very small in order to make it draw faster796let s:old_winheight = winheight(0)797let s:old_winfixheight = &l:winfixheight798if s:old_winheight > 2799  resize 1 " leave enough room to view one line at a time800  norm! G801  norm! zt802endif803setlocal winfixheight804 805let s:newwin_stl = &l:stl806 807" on the new window, set the least time-consuming fold method808let s:old_fen = &foldenable809setlocal foldmethod=manual810setlocal nofoldenable811 812let s:newwin = winnr()813let s:orgwin = bufwinnr(s:orgbufnr)814 815setlocal modifiable816%d817let s:old_paste = &paste818set paste819let s:old_magic = &magic820set magic821 822" set the fileencoding to match the charset we'll be using823let &l:fileencoding=s:settings.vim_encoding824 825" According to http://www.w3.org/TR/html4/charset.html#doc-char-set, the byte826" order mark is highly recommend on the web when using multibyte encodings. But,827" it is not a good idea to include it on UTF-8 files. Otherwise, let Vim828" determine when it is actually inserted.829if s:settings.vim_encoding == 'utf-8'830  setlocal nobomb831else832  setlocal bomb833endif834 835let s:lines = []836 837if s:settings.use_xhtml838  if s:settings.encoding != ""839    call add(s:lines, "<?xml version=\"1.0\" encoding=\"" .. s:settings.encoding .. "\"?>")840  else841    call add(s:lines, "<?xml version=\"1.0\"?>")842  endif843  let s:tag_close = ' />'844else845  let s:tag_close = '>'846endif847 848let s:HtmlSpace = ' '849let s:LeadingSpace = ' '850let s:HtmlEndline = ''851if s:settings.no_pre852  let s:HtmlEndline = '<br' .. s:tag_close853  let s:LeadingSpace = s:settings.use_xhtml ? '&#160;' : '&nbsp;'854  let s:HtmlSpace = '\' .. s:LeadingSpace855endif856 857" HTML header, with the title and generator ;-). Left free space for the CSS,858" to be filled at the end.859if !s:settings.no_doc860  call extend(s:lines, [861	\ "<html>",862	\ "<head>"])863  " include encoding as close to the top as possible, but only if not already864  " contained in XML information (to avoid haggling over content type)865  if s:settings.encoding != "" && !s:settings.use_xhtml866    if s:html5867      call add(s:lines, '<meta charset="' .. s:settings.encoding .. '"' .. s:tag_close)868    else869      call add(s:lines, "<meta http-equiv=\"content-type\" content=\"text/html; charset=" .. s:settings.encoding .. '"' .. s:tag_close)870    endif871  endif872  call extend(s:lines, [873	\ ("<title>"..expand("%:p:~").."</title>"),874	\ ("<meta name=\"Generator\" content=\"Vim/"..v:version/100.."."..v:version%100..'"'..s:tag_close),875	\ ("<meta name=\"plugin-version\" content=\""..s:pluginversion..'"'..s:tag_close)876	\ ])877  call add(s:lines, '<meta name="syntax" content="'..s:current_syntax..'"'..s:tag_close)878  call add(s:lines, '<meta name="settings" content="'..879	\ join(filter(keys(s:settings),'s:settings[v:val]'),',')..880	\ ',prevent_copy='..s:settings.prevent_copy..881	\ ',use_input_for_pc='..s:settings.use_input_for_pc..882	\ '"'..s:tag_close)883  call add(s:lines, '<meta name="colorscheme" content="'..884	\ (exists('g:colors_name')885	\ ? g:colors_name886	\ : 'none').. '"'..s:tag_close)887 888  if s:settings.use_css889    call extend(s:lines, [890	  \ "<style" .. (s:html5 ? "" : " type=\"text/css\"") .. ">",891	  \ s:settings.use_xhtml ? "" : "<!--"])892    let s:ieonly = []893    if s:settings.dynamic_folds894      if s:settings.hover_unfold895	" if we are doing hover_unfold, use css 2 with css 1 fallback for IE6896	call extend(s:lines, [897	      \ ".FoldColumn { text-decoration: none; white-space: pre; }",898	      \ "",899	      \ "body * { margin: 0; padding: 0; }", "",900	      \ ".open-fold   > span.Folded { display: none;  }",901	      \ ".open-fold   > .fulltext   { display: inline; }",902	      \ ".closed-fold > .fulltext   { display: none;  }",903	      \ ".closed-fold > span.Folded { display: inline; }",904	      \ "",905	      \ ".open-fold   > .toggle-open   { display: none;   }",906	      \ ".open-fold   > .toggle-closed { display: inline; }",907	      \ ".closed-fold > .toggle-open   { display: inline; }",908	      \ ".closed-fold > .toggle-closed { display: none;   }",909	      \ "", "",910	      \ '/* opening a fold while hovering won''t be supported by IE6 and other',911	      \ "similar browsers, but it should fail gracefully. */",912	      \ ".closed-fold:hover > .fulltext      { display: inline; }",913	      \ ".closed-fold:hover > .toggle-filler { display: none; }",914	      \ ".closed-fold:hover > .Folded        { display: none; }"])915	" TODO: IE6 is REALLY old and I can't even test it anymore. Maybe we916	" should remove this? Leave it in for now, it was working at one point,917	" and doesn't affect any modern browsers. Even newer IE versions should918	" support the above code and ignore the following.919	let s:ieonly = [920	      \ "<!--[if lt IE 7]><style type=\"text/css\">",921	      \ ".open-fold   .fulltext      { display: inline; }",922	      \ ".open-fold   span.Folded    { display: none; }",923	      \ ".open-fold   .toggle-open   { display: none; }",924	      \ ".open-fold   .toggle-closed { display: inline; }",925	      \ "",926	      \ ".closed-fold .fulltext      { display: none; }",927	      \ ".closed-fold span.Folded    { display: inline; }",928	      \ ".closed-fold .toggle-open   { display: inline; }",929	      \ ".closed-fold .toggle-closed { display: none; }",930	      \ "</style>",931	      \ "<![endif]-->",932	      \]933      else934	" if we aren't doing hover_unfold, use CSS 1 only935	call extend(s:lines, [936	      \ ".FoldColumn { text-decoration: none; white-space: pre; }",937	      \ ".open-fold   .fulltext      { display: inline; }",938	      \ ".open-fold   span.Folded    { display: none; }",939	      \ ".open-fold   .toggle-open   { display: none; }",940	      \ ".open-fold   .toggle-closed { display: inline; }",941	      \ "",942	      \ ".closed-fold .fulltext      { display: none; }",943	      \ ".closed-fold span.Folded    { display: inline; }",944	      \ ".closed-fold .toggle-open   { display: inline; }",945	      \ ".closed-fold .toggle-closed { display: none; }",946	      \])947      endif948    endif949    " else we aren't doing any dynamic folding, no need for any special rules950 951    call extend(s:lines, [952	    \ s:settings.use_xhtml ? "" : '-->',953	    \ "</style>",954	    \])955    call extend(s:lines, s:ieonly)956    unlet s:ieonly957  endif958 959  let s:uses_script = s:settings.dynamic_folds || s:settings.line_ids960 961  " insert script tag if needed962  if s:uses_script963    call extend(s:lines, [964	  \ "",965	  \ "<script" .. (s:html5 ? "" : " type='text/javascript'") .. ">",966	  \ s:settings.use_xhtml ? '//<![CDATA[' : "<!--"])967  endif968 969  " insert javascript to toggle folds open and closed970  if s:settings.dynamic_folds971    call extend(s:lines, [972	  \ "",973	  \ "function toggleFold(objID)",974	  \ "{",975	  \ "  var fold;",976	  \ "  fold = document.getElementById(objID);",977	  \ "  if (fold.className == 'closed-fold')",978	  \ "  {",979	  \ "    fold.className = 'open-fold';",980	  \ "  }",981	  \ "  else if (fold.className == 'open-fold')",982	  \ "  {",983	  \ "    fold.className = 'closed-fold';",984	  \ "  }",985	  \ "}"986	  \ ])987  endif988 989  if s:settings.line_ids990    " insert javascript to get IDs from line numbers, and to open a fold before991    " jumping to any lines contained therein992    call extend(s:lines, [993	  \ "",994	  \ "/* function to open any folds containing a jumped-to line before jumping to it */",995	  \ "function JumpToLine()",996	  \ "{",997	  \ "  var lineNum;",998	  \ "  lineNum = window.location.hash;",999	  \ "  lineNum = lineNum.substr(1); /* strip off '#' */",1000	  \ "",1001	  \ "  if (lineNum.indexOf('L') == -1) {",1002	  \ "    lineNum = 'L'+lineNum;",1003	  \ "  }",1004	  \ "  var lineElem = document.getElementById(lineNum);"1005	  \ ])1006 1007    if s:settings.dynamic_folds1008      call extend(s:lines, [1009	    \ "",1010	    \ "  /* navigate upwards in the DOM tree to open all folds containing the line */",1011	    \ "  var node = lineElem;",1012	    \ "  while (node && node.id != 'vimCodeElement"..s:settings.id_suffix.."')",1013	    \ "  {",1014	    \ "    if (node.className == 'closed-fold')",1015	    \ "    {",1016	    \ "      node.className = 'open-fold';",1017	    \ "    }",1018	    \ "    node = node.parentNode;",1019	    \ "  }",1020	    \ ])1021    endif1022    call extend(s:lines, [1023	  \ "  /* Always jump to new location even if the line was hidden inside a fold, or",1024	  \ "   * we corrected the raw number to a line ID.",1025	  \ "   */",1026	  \ "  if (lineElem) {",1027	  \ "    lineElem.scrollIntoView(true);",1028	  \ "  }",1029	  \ "  return true;",1030	  \ "}",1031	  \ "if ('onhashchange' in window) {",1032	  \ "  window.onhashchange = JumpToLine;",1033	  \ "}"1034	  \ ])1035  endif1036 1037  " insert script closing tag if needed1038  if s:uses_script1039    call extend(s:lines, [1040	  \ '',1041	  \ s:settings.use_xhtml ? '//]]>' : '-->',1042	  \ "</script>"1043	  \ ])1044  endif1045 1046  call extend(s:lines, ["</head>",1047	\ "<body"..(s:settings.line_ids ? " onload='JumpToLine();'" : "")..">"])1048endif1049 1050if s:settings.no_pre1051  " if we're not using CSS we use a font tag which can't have a div inside1052  if s:settings.use_css1053    call extend(s:lines, ["<div id='vimCodeElement" .. s:settings.id_suffix .. "'>"])1054  endif1055else1056  call extend(s:lines, ["<pre id='vimCodeElement" .. s:settings.id_suffix .. "'>"])1057endif1058 1059exe s:orgwin .. "wincmd w"1060 1061" caches of style data1062" initialize to include line numbers if using them1063if s:settings.number_lines1064  let s:stylelist = { s:LINENR_ID : ".LineNr { " .. s:CSS1( s:LINENR_ID ) .. "}" }1065else1066  let s:stylelist = {}1067endif1068let s:diffstylelist = {1069      \   s:DIFF_A_ID : ".DiffAdd { " .. s:CSS1( s:DIFF_A_ID ) .. "}",1070      \   s:DIFF_C_ID : ".DiffChange { " .. s:CSS1( s:DIFF_C_ID ) .. "}",1071      \   s:DIFF_D_ID : ".DiffDelete { " .. s:CSS1( s:DIFF_D_ID ) .. "}",1072      \   s:DIFF_T_ID : ".DiffText { " .. s:CSS1( s:DIFF_T_ID ) .. "}"1073      \ }1074 1075" set up progress bar in the status line1076if !s:settings.no_progress1077  " ProgressBar Indicator1078  let s:progressbar={}1079 1080  " Progressbar specific functions1081 1082  func! s:SetProgbarColor()1083    if hlID("TOhtmlProgress") != 01084      hi! link TOhtmlProgress_auto TOhtmlProgress1085    elseif hlID("TOhtmlProgress_auto")==0 ||1086       \ !exists("s:last_colors_name") || !exists("g:colors_name") ||1087       \ g:colors_name != s:last_colors_name1088      let s:last_colors_name = exists("g:colors_name") ? g:colors_name : "none"1089 1090      let l:diffatr = synIDattr(hlID("DiffDelete")->synIDtrans(), "reverse", s:whatterm) ? "fg#" : "bg#"1091      let l:stlatr = synIDattr(hlID("StatusLine")->synIDtrans(), "reverse", s:whatterm) ? "fg#" : "bg#"1092 1093      let l:progbar_color = synIDattr(hlID("DiffDelete")->synIDtrans(), l:diffatr, s:whatterm)1094      let l:stl_color = synIDattr(hlID("StatusLine")->synIDtrans(), l:stlatr, s:whatterm)1095 1096      if "" == l:progbar_color1097	let l:progbar_color = synIDattr(hlID("DiffDelete")->synIDtrans(), "reverse", s:whatterm) ? s:fgc : s:bgc1098      endif1099      if "" == l:stl_color1100	let l:stl_color = synIDattr(hlID("StatusLine")->synIDtrans(), "reverse", s:whatterm) ? s:fgc : s:bgc1101      endif1102 1103      if l:progbar_color == l:stl_color1104	if s:whatterm == 'cterm'1105	  if l:progbar_color >= (&t_Co/2)1106	    let l:progbar_color-=11107	  else1108	    let l:progbar_color+=11109	  endif1110	else1111	  let l:rgb = map(matchlist(l:progbar_color, '#\zs\x\x\ze\(\x\x\)\(\x\x\)')[:2], 'str2nr(v:val, 16)')1112	  let l:avg = (l:rgb[0] + l:rgb[1] + l:rgb[2])/31113	  if l:avg >= 1281114	    let l:avg_new = l:avg1115	    while l:avg - l:avg_new < 0x151116	      let l:rgb = map(l:rgb, 'v:val * 3 / 4')1117	      let l:avg_new = (l:rgb[0] + l:rgb[1] + l:rgb[2])/31118	    endwhile1119	  else1120	    let l:avg_new = l:avg1121	    while l:avg_new - l:avg < 0x151122	      let l:rgb = map(l:rgb, 'min([max([v:val, 4]) * 5 / 4, 255])')1123	      let l:avg_new = (l:rgb[0] + l:rgb[1] + l:rgb[2])/31124	    endwhile1125	  endif1126	  let l:progbar_color = printf("#%02x%02x%02x", l:rgb[0], l:rgb[1], l:rgb[2])1127	endif1128	echomsg "diff detected progbar color set to" l:progbar_color1129      endif1130      exe "hi TOhtmlProgress_auto" s:whatterm.."bg="..l:progbar_color1131    endif1132  endfun1133 1134  func! s:ProgressBar(title, max_value, winnr)1135    let pgb=copy(s:progressbar)1136    let pgb.title = a:title..' '1137    let pgb.max_value = a:max_value1138    let pgb.winnr = a:winnr1139    let pgb.cur_value = 01140 1141    let pgb.items = { 'title'   : { 'color' : 'Statusline' },1142	  \'bar'     : { 'color' : 'Statusline' , 'fillcolor' : 'TOhtmlProgress_auto' , 'bg' : 'Statusline' } ,1143	  \'counter' : { 'color' : 'Statusline' } }1144    let pgb.last_value = 01145    let pgb.needs_redraw = 01146    " Note that you must use len(split) instead of len() if you want to use 1147    " unicode in title.1148    "1149    " Subtract 3 for spacing around the title.1150    " Subtract 4 for the percentage display.1151    " Subtract 2 for spacing before this.1152    " Subtract 2 more for the '|' on either side of the progress bar1153    let pgb.subtractedlen=len(split(pgb.title, '\zs'))+3+4+2+21154    let pgb.max_len = 01155    set laststatus=21156    return pgb1157  endfun1158 1159  " Function: progressbar.calculate_ticks() {{{11160  func! s:progressbar.calculate_ticks(pb_len)1161    if a:pb_len<=01162      let pb_len = 1001163    else1164      let pb_len = a:pb_len1165    endif1166    let self.progress_ticks = map(range(pb_len+1), "v:val * self.max_value / pb_len")1167  endfun1168 1169  "Function: progressbar.paint()1170  func! s:progressbar.paint()1171    " Recalculate widths.1172    let max_len = winwidth(self.winnr)1173    let pb_len = 01174    " always true on first call because of initial value of self.max_len1175    if max_len != self.max_len1176      let self.max_len = max_len1177 1178      " Progressbar length1179      let pb_len = max_len - self.subtractedlen1180 1181      call self.calculate_ticks(pb_len)1182 1183      let self.needs_redraw = 11184      let cur_value = 01185      let self.pb_len = pb_len1186    else1187      " start searching at the last found index to make the search for the1188      " appropriate tick value normally take 0 or 1 comparisons1189      let cur_value = self.last_value1190      let pb_len = self.pb_len1191    endif1192 1193    let cur_val_max = pb_len > 0 ? pb_len : 1001194 1195    " find the current progress bar position based on precalculated thresholds1196    while cur_value < cur_val_max && self.cur_value > self.progress_ticks[cur_value]1197      let cur_value += 11198    endwhile1199 1200    " update progress bar

Showing the first 1,200 of 2073 lines. Download the file for the rest.

codekingpro/portable-devtools · Team Ai