# HG changeset patch # User Bram Moolenaar # Date 1343231350 -7200 # Node ID 9910cbff5f1639a496ff44da7af141922770556e # Parent a0b8a8a9867d1e99c8941e254f051c96ca012453 Updated runtime files. diff --git a/runtime/autoload/tohtml.vim b/runtime/autoload/tohtml.vim --- a/runtime/autoload/tohtml.vim +++ b/runtime/autoload/tohtml.vim @@ -1,6 +1,6 @@ " Vim autoload file for the tohtml plugin. " Maintainer: Ben Fritz -" Last Change: 2011 Apr 05 +" Last Change: 2012 Jun 30 " " Additional contributors: " @@ -11,7 +11,7 @@ " this file uses line continuations let s:cpo_sav = &cpo -set cpo-=C +set cpo&vim " Automatically find charsets from all encodings supported natively by Vim. With " the 8bit- and 2byte- prefixes, Vim can actually support more encodings than @@ -391,12 +391,25 @@ func! tohtml#Diff2HTML(win_list, buf_lis call add(html, '') let body_line_num = len(html) - call add(html, '') - call add(html, '') + if !empty(s:settings.prevent_copy) + call add(html, "") + call add(html, "") + call add(html, "
0
") + call add(html, "
") + call add(html, "
") + else + call add(html, '') + endif + call add(html, "
") call add(html, '') for buf in a:win_list @@ -454,16 +467,19 @@ func! tohtml#Diff2HTML(win_list, buf_lis let insert_index = diff_style_start endif - " Delete those parts that are not needed so - " we can include the rest into the resulting table - 1,/^\_s\+.*id='oneCharWidth'.*\_s\+.*id='oneInputWidth'.*\_s\+.*id='oneEmWidth'\)\?\zs/d_ $ ??,$d_ let temp = getline(1,'$') + " clean out id on the main content container because we already set it on + " the table + let temp[0] = substitute(temp[0], " id='vimCodeElement'", "", "") " undo deletion of start and end part " so we can later save the file as valid html " TODO: restore using grabbed lines if undolevel is 1? - normal 2u + normal! 2u if s:settings.use_css call add(html, '
') elseif s:settings.use_xhtml @@ -520,12 +536,47 @@ func! tohtml#Diff2HTML(win_list, buf_lis 1 let style_start = search('^')-1 + " add required javascript in reverse order so we can just call append again + " and again without adjusting {{{ + + " insert script closing tag if any javascript is needed + if s:settings.dynamic_folds || !empty(s:settings.prevent_copy) + call append(style_start, [ + \ '', + \ s:settings.use_xhtml ? '//]]>' : '-->', + \ "" + \ ]) + endif + + " insert script which corrects the size of small input elements in + " prevent_copy mode. See 2html.vim for details on why this is needed and how + " it works. + if !empty(s:settings.prevent_copy) + call append(style_start, [ + \ '', + \ '/* simulate a "ch" unit by asking the browser how big a zero character is */', + \ 'function FixCharWidth() {', + \ ' /* get the hidden element which gives the width of a single character */', + \ ' var goodWidth = document.getElementById("oneCharWidth").clientWidth;', + \ ' /* get all input elements, we''ll filter on class later */', + \ ' var inputTags = document.getElementsByTagName("input");', + \ ' var ratio = 5;', + \ ' var inputWidth = document.getElementById("oneInputWidth").clientWidth;', + \ ' var emWidth = document.getElementById("oneEmWidth").clientWidth;', + \ ' if (inputWidth > goodWidth) {', + \ ' while (ratio < 100*goodWidth/emWidth && ratio < 100) {', + \ ' ratio += 5;', + \ ' }', + \ ' document.getElementById("vimCodeElement").className = "em"+ratio;', + \ ' }', + \ '}' + \ ]) + endif + " Insert javascript to toggle matching folds open and closed in all windows, - " if dynamic folding is active. {{{ + " if dynamic folding is active. if s:settings.dynamic_folds call append(style_start, [ - \ "" \ ]) + endif + + " insert script tag if any javascript is needed + if s:settings.dynamic_folds || s:settings.prevent_copy != "" + call append(style_start, [ + \ "" + \ "}" \]) endif +" Small text columns like the foldcolumn and line number column need a weird +" hack to work around Webkit's and (in versions prior to 9) IE's lack of support +" for the 'ch' unit without messing up Opera, which also doesn't support it but +" works anyway. +" +" The problem is that without the 'ch' unit, it is not possible to specify a +" size of an in terms of character widths. Only Opera seems to do the +" "sensible" thing and make the sized to fit exactly as many characters +" as specified by its "size" attribute, but the spec actually says "at least +" wide enough to fit 'size' characters", so the other browsers are technically +" correct as well. +" +" Anyway, this leads to two diffculties: +" 1. The foldcolumn is made up of multiple elements side-by-side with +" different sizes, each of which has their own extra padding added. Thus, a +" column made up of one item of size 1 and another of size 2 would not +" necessarily be equal in size to another line's foldcolumn with a single +" item of size 3. +" 2. The extra padding added to the elements adds up to make the +" foldcolumn and line number column too wide, especially in Webkit +" browsers. +" +" So, the full workaround is: +" 1. Define a default size in em, equal to the number of characters in the +" input element, in case javascript is disabled and the browser does not +" support the 'ch' unit. Unfortunately this makes Opera no longer work +" properly without javascript. 1em per character is much too wide but it +" looks better in webkit browsers than unaligned columns. +" 2. Insert the following javascript to run at page load, which checks for the +" width of a single character (in an extraneous page element inserted +" before the page title, and set to hidden) and compares it to the width of +" another extra element with only one character. If the width +" matches, the script does nothing more, but if not, it will figure out the +" fraction of an em unit which would correspond with a ch unit if there +" were one, and set the containing element (
 or 
) to a class with +" pre-defined rules which is closest to that fraction of an em. Rules are +" defined from 0.05 em to 1em per ch. +if !empty(s:settings.prevent_copy) + call extend(s:lines, [ + \ '', + \ '/* simulate a "ch" unit by asking the browser how big a zero character is */', + \ 'function FixCharWidth() {', + \ ' /* get the hidden element which gives the width of a single character */', + \ ' var goodWidth = document.getElementById("oneCharWidth").clientWidth;', + \ ' /* get all input elements, we''ll filter on class later */', + \ ' var inputTags = document.getElementsByTagName("input");', + \ ' var ratio = 5;', + \ ' var inputWidth = document.getElementById("oneInputWidth").clientWidth;', + \ ' var emWidth = document.getElementById("oneEmWidth").clientWidth;', + \ ' if (inputWidth > goodWidth) {', + \ ' while (ratio < 100*goodWidth/emWidth && ratio < 100) {', + \ ' ratio += 5;', + \ ' }', + \ ' document.getElementById("vimCodeElement").className = "em"+ratio;', + \ ' }', + \ '}' + \ ]) +endif + +" insert script closing tag if any javascript is needed +if s:settings.dynamic_folds || s:settings.prevent_copy != "" + call extend(s:lines, [ + \ '', + \ s:settings.use_xhtml ? '//]]>' : '-->', + \ "" + \ ]) +endif + +call extend(s:lines, [""]) +if !empty(s:settings.prevent_copy) + call extend(s:lines, + \ ["", + \ "", + \ "
0
", + \ "
", + \ "
" + \ ]) +else + call extend(s:lines, [""]) +endif if s:settings.no_pre - call extend(s:lines, ["", ""]) + " if we're not using CSS we use a font tag which can't have a div inside + if s:settings.use_css + call extend(s:lines, ["
"]) + endif else - call extend(s:lines, ["", "", "
"])
+  call extend(s:lines, ["
"])
 endif
 
 exe s:orgwin . "wincmd w"
 
-" List of all id's
-let s:idlist = []
+" caches of style data
+" initialize to include line numbers if using them
+if s:settings.number_lines
+  let s:stylelist = { s:LINENR_ID : ".LineNr { " . s:CSS1( s:LINENR_ID ) . "}" }
+else
+  let s:stylelist = {}
+endif
+let s:diffstylelist = {
+      \   s:DIFF_A_ID : ".DiffAdd { " . s:CSS1( s:DIFF_A_ID ) . "}",
+      \   s:DIFF_C_ID : ".DiffChange { " . s:CSS1( s:DIFF_C_ID ) . "}",
+      \   s:DIFF_D_ID : ".DiffDelete { " . s:CSS1( s:DIFF_D_ID ) . "}",
+      \   s:DIFF_T_ID : ".DiffText { " . s:CSS1( s:DIFF_T_ID ) . "}"
+      \ }
 
 " set up progress bar in the status line
 if !s:settings.no_progress
@@ -772,15 +1232,22 @@ while s:lnum <= s:end
 
       if !s:settings.no_pre
 	" HTML line wrapping is off--go ahead and fill to the margin
+	" TODO: what about when CSS wrapping is turned on?
 	let s:new = s:new . repeat(s:difffillchar, &columns - strlen(s:new) - s:margin)
       else
 	let s:new = s:new . repeat(s:difffillchar, 3)
       endif
 
-      let s:new = s:HtmlFormat(s:new, "DiffDelete", "")
+      let s:new = s:HtmlFormat_d(s:new, s:DIFF_D_ID, 0)
       if s:settings.number_lines
-	" Indent if line numbering is on; must be after escaping.
-	let s:new = repeat(s:LeadingSpace, s:margin) . s:new
+	" Indent if line numbering is on. Indent gets style of line number
+	" column.
+	let s:new = s:HtmlFormat_n(repeat(' ', s:margin), s:LINENR_ID, 0) . s:new
+      endif
+      if s:settings.dynamic_folds && !s:settings.no_foldcolumn && s:foldcolumn > 0
+	" Indent for foldcolumn if there is one. Assume it's empty, there should
+	" not be a fold for deleted lines in diff mode.
+	let s:new = s:FoldColumn_fill() . s:new
       endif
       call add(s:lines, s:new.s:HtmlEndline)
 
@@ -793,8 +1260,6 @@ while s:lnum <= s:end
   " Start the line with the line number.
   if s:settings.number_lines
     let s:numcol = repeat(' ', s:margin - 1 - strlen(s:lnum)) . s:lnum . ' '
-  else
-    let s:numcol = ""
   endif
 
   let s:new = ""
@@ -802,14 +1267,14 @@ while s:lnum <= s:end
   if has('folding') && !s:settings.ignore_folding && foldclosed(s:lnum) > -1 && !s:settings.dynamic_folds
     "
     " This is the beginning of a folded block (with no dynamic folding)
-    "
-    let s:new = s:numcol . foldtextresult(s:lnum)
+    let s:new = foldtextresult(s:lnum)
     if !s:settings.no_pre
       " HTML line wrapping is off--go ahead and fill to the margin
       let s:new = s:new . repeat(s:foldfillchar, &columns - strlen(s:new))
     endif
 
-    let s:new = s:HtmlFormat(s:new, "Folded", "")
+    " put numcol in a separate group for sake of unselectable text
+    let s:new = (s:settings.number_lines ? s:HtmlFormat_n(s:numcol, s:FOLDED_ID, 0): "") . s:HtmlFormat_t(s:new, s:FOLDED_ID, 0)
 
     " Skip to the end of the fold
     let s:new_lnum = foldclosedend(s:lnum)
@@ -851,38 +1316,46 @@ while s:lnum <= s:end
 	if !s:settings.no_foldcolumn
 	  " add fold column that can open the new fold
 	  if s:allfolds[0].level > 1 && s:firstfold
-	    let s:new = s:new . ""
-	    let s:new = s:new . repeat('|', s:allfolds[0].level - 1) . ""
+	    let s:new = s:new . s:FoldColumn_build('|', s:allfolds[0].level - 1, 0, "",
+		  \ 'toggle-open FoldColumn','javascript:toggleFold("fold'.s:foldstack[0].id.'");')
 	  endif
-	  let s:new = s:new . "+"
-	  let s:new = s:new . ""
+	  let s:new = s:new . s:FoldColumn_build(" ", 1, s:foldcolumn - s:allfolds[0].level - 1, "",
+		\ 'toggle-open FoldColumn'. (get(s:allfolds, 1, {'firstline': 0}).firstline == s:lnum ?" toggle-filler" :""),
+		\ 'javascript:toggleFold("fold'.s:foldId.'");')
 
 	  " add fold column that can close the new fold
-	  let s:new = s:new . ""
-	  if s:firstfold
-	    let s:new = s:new . repeat('|', s:allfolds[0].level - 1)
+	  " only add extra blank space if we aren't opening another fold on the
+	  " same line
+	  if get(s:allfolds, 1, {'firstline': 0}).firstline != s:lnum
+	    let s:extra_space = s:foldcolumn - s:allfolds[0].level
+	  else
+	    let s:extra_space = 0
 	  endif
-	  let s:new = s:new . "-"
-	  " only add spaces if we aren't opening another fold on the same line
-	  if get(s:allfolds, 1, {'firstline': 0}).firstline != s:lnum
-	    let s:new = s:new . repeat(" ", s:foldcolumn - s:allfolds[0].level)
+	  if s:firstfold
+	    " the first fold in a line has '|' characters from folds opened in
+	    " previous lines, before the '-' for this fold
+	    let s:new .= s:FoldColumn_build('|', s:allfolds[0].level - 1, s:extra_space, '-',
+		  \ 'toggle-closed FoldColumn', 'javascript:toggleFold("fold'.s:foldId.'");')
+	  else
+	    " any subsequent folds in the line only add a single '-'
+	    let s:new = s:new . s:FoldColumn_build("-", 1, s:extra_space, "",
+		  \ 'toggle-closed FoldColumn', 'javascript:toggleFold("fold'.s:foldId.'");')
 	  endif
-	  let s:new = s:new . ""
 	  let s:firstfold = 0
 	endif
 
-	" add fold text, moving the span ending to the next line so collapsing
-	" of folds works correctly
-	let s:new = s:new . substitute(s:HtmlFormat(s:numcol . foldtextresult(s:lnum), "Folded", ""), '', s:HtmlEndline.'\n\0', '')
+	" Add fold text, moving the span ending to the next line so collapsing
+	" of folds works correctly.
+	" Put numcol in a separate group for sake of unselectable text.
+	let s:new = s:new . (s:settings.number_lines ? s:HtmlFormat_n(s:numcol, s:FOLDED_ID, 0) : "") . substitute(s:HtmlFormat_t(foldtextresult(s:lnum), s:FOLDED_ID, 0), '', s:HtmlEndline.'\n\0', '')
 	let s:new = s:new . ""
 
 	" open the fold now that we have the fold text to allow retrieval of
@@ -902,14 +1375,13 @@ while s:lnum <= s:end
 	  " add the empty foldcolumn for unfolded lines if there is a fold
 	  " column at all
 	  if s:foldcolumn > 0
-	    let s:new = s:new . s:HtmlFormat(repeat(' ', s:foldcolumn), "FoldColumn", "")
+	    let s:new = s:new . s:FoldColumn_fill()
 	  endif
 	else
 	  " add the fold column for folds not on the opening line
 	  if get(s:foldstack, 0).firstline < s:lnum
-	    let s:new = s:new . ""
-	    let s:new = s:new . repeat('|', s:foldstack[0].level)
-	    let s:new = s:new . repeat(' ', s:foldcolumn - s:foldstack[0].level) . ""
+	    let s:new = s:new . s:FoldColumn_build('|', s:foldstack[0].level, s:foldcolumn - s:foldstack[0].level, "",
+		  \ 'FoldColumn', 'javascript:toggleFold("fold'.s:foldstack[0].id.'");')
 	  endif
 	endif
       endif
@@ -917,8 +1389,7 @@ while s:lnum <= s:end
 
     " Now continue with the unfolded line text
     if s:settings.number_lines
-      " TODO: why not use the real highlight name here?
-      let s:new = s:new . s:HtmlFormat(s:numcol, "lnr", "")
+      let s:new = s:new . s:HtmlFormat_n(s:numcol, s:LINENR_ID, 0)
     endif
 
     " Get the diff attribute, if any.
@@ -932,7 +1403,6 @@ while s:lnum <= s:end
 
     " most of the time we won't use the diff_id, initialize to zero
     let s:diff_id = 0
-    let s:diff_id_name = ""
 
     while s:col <= s:len || (s:col == 1 && s:diffattr)
       let s:startcol = s:col " The start column for processing text
@@ -1000,20 +1470,16 @@ while s:lnum <= s:end
 
 	" get the highlight group name to use
 	let s:id = synIDtrans(s:id)
-	let s:id_name = synIDattr(s:id, "name", s:whatterm)
-	if s:diff_id
-	  let s:diff_id_name = synIDattr(s:diff_id, "name", s:whatterm)
-	endif
       else
 	" use Conceal highlighting for concealed text
-	let s:id_name = 'Conceal'
+	let s:id = s:CONCEAL_ID
 	let s:expandedtab = s:concealinfo[1]
       endif
 
-      " Output the text with the same synID, with class set to {s:id_name},
-      " unless it has been concealed completely.
+      " Output the text with the same synID, with class set to the highlight ID
+      " name, unless it has been concealed completely.
       if strlen(s:expandedtab) > 0
-	let s:new = s:new . s:HtmlFormat(s:expandedtab,  s:id_name, s:diff_id_name)
+	let s:new = s:new . s:HtmlFormat(s:expandedtab,  s:id, s:diff_id, 0)
       endif
     endwhile
   endif
@@ -1038,9 +1504,9 @@ if s:settings.dynamic_folds
   endwhile
 
   " add fold column to the style list if not already there
-  let s:id = hlID('FoldColumn')
-  if index(s:idlist, s:id) == -1
-    call insert(s:idlist, s:id)
+  let s:id = s:FOLD_C_ID
+  if !has_key(s:stylelist, s:id)
+    let s:stylelist[s:id] = '.FoldColumn { ' . s:CSS1(s:id) . '}'
   endif
 endif
 
@@ -1049,7 +1515,7 @@ if s:settings.no_pre
     " Close off the font tag that encapsulates the whole 
     call extend(s:lines, ["", "", ""])
   else
-    call extend(s:lines, ["", ""])
+    call extend(s:lines, ["
", "", ""]) endif else call extend(s:lines, ["
", "", ""]) @@ -1059,29 +1525,27 @@ exe s:newwin . "wincmd w" call setline(1, s:lines) unlet s:lines +" Mangle modelines so Vim doesn't try to use HTML text as a modeline if editing +" this file in the future; need to do this after generating all the text in case +" the modeline text has different highlight groups which all turn out to be +" stripped from the final output. +%s!\v(%(^|\s+)%(vim?|ex)):!\1\:!ge + " Now, when we finally know which, we define the colors and styles if s:settings.use_css 1;/