')
+    if s:settings.use_css
+      call add(html, '
')
+    elseif s:settings.use_xhtml
+      call add(html, ' ')
+    else
+      call add(html, ' ')
+    endif
     let html += temp
     call add(html, ' | ')
 
@@ -150,10 +186,10 @@ func! tohtml#Diff2HTML(win_list, buf_list)
   call add(html, '')
 
   let i = 1
-  let name = "Diff" . ".html"
+  let name = "Diff" . (s:settings.use_xhtml ? ".xhtml" : ".html")
   " Find an unused file name if current file name is already in use
   while filereadable(name)
-    let name = substitute(name, '\d*\.html$', '', '') . i . ".html"
+    let name = substitute(name, '\d*\.x\?html$', '', '') . i . '.' . fnamemodify(copy(name), ":t:e")
     let i += 1
   endwhile
   exe "topleft new " . name
@@ -173,7 +209,7 @@ func! tohtml#Diff2HTML(win_list, buf_list)
     if s:settings.dynamic_folds
       call append(style_start, [
 	    \  ""
 	    \ ])
     endif
@@ -201,16 +237,16 @@ func! tohtml#Diff2HTML(win_list, buf_list)
     " horizontally scrollable when the lines are too long. Otherwise, the diff
     " is pretty useless for really long lines.
     if s:settings.use_css
-      call append(style_start, [
-	    \ ''
+      call append(style_start,
+	    \ [''
 	    \ ])
     endif
   endif
@@ -259,21 +295,19 @@ func! tohtml#GetUserSettings()
     call tohtml#GetOption(user_settings,   'whole_filler',  0 )
     call tohtml#GetOption(user_settings,      'use_xhtml',  0 )
     
-    " TODO: encoding? font? These are string options that require more parsing.
-
     " override those settings that need it
 
+    " hover opening implies dynamic folding
+    if user_settings.hover_unfold
+      let user_settings.dynamic_folds = 1
+    endif
+
     " ignore folding overrides dynamic folding
     if user_settings.ignore_folding && user_settings.dynamic_folds
       let user_settings.dynamic_folds = 0
       let user_settings.hover_unfold = 0
     endif
 
-    " hover opening implies dynamic folding
-    if user_settings.hover_unfold
-      let user_settings.dynamic_folds = 1
-    endif
-
     " dynamic folding with no foldcolumn implies hover opens
     if user_settings.dynamic_folds && user_settings.no_foldcolumn
       let user_settings.hover_unfold = 1
@@ -290,6 +324,41 @@ func! tohtml#GetUserSettings()
       let user_settings.no_pre = 1
     endif
 
+    " Figure out proper MIME charset from the 'encoding' option.
+    if exists("g:html_use_encoding")
+      let user_settings.encoding = g:html_use_encoding
+    else
+      let vim_encoding = &encoding
+      if vim_encoding =~ '^8bit\|^2byte'
+	let vim_encoding = substitute(vim_encoding, '^8bit-\|^2byte-', '', '')
+      endif
+      if vim_encoding == 'latin1'
+	let user_settings.encoding = 'iso-8859-1'
+      elseif vim_encoding =~ "^cp12"
+	let user_settings.encoding = substitute(vim_encoding, 'cp', 'windows-', '')
+      elseif vim_encoding == 'sjis' || vim_encoding == 'cp932'
+	let user_settings.encoding = 'Shift_JIS'
+      elseif vim_encoding == 'big5' || vim_encoding == 'cp950'
+	let user_settings.encoding = "Big5"
+      elseif vim_encoding == 'euc-cn'
+	let user_settings.encoding = 'GB_2312-80'
+      elseif vim_encoding == 'euc-tw'
+	let user_settings.encoding = ""
+      elseif vim_encoding =~ '^euc\|^iso\|^koi'
+	let user_settings.encoding = substitute(vim_encoding, '.*', '\U\0', '')
+      elseif vim_encoding == 'cp949'
+	let user_settings.encoding = 'KS_C_5601-1987'
+      elseif vim_encoding == 'cp936'
+	let user_settings.encoding = 'GBK'
+      elseif vim_encoding =~ '^ucs\|^utf'
+	let user_settings.encoding = 'UTF-8'
+      else
+	let user_settings.encoding = ""
+      endif
+    endif
+
+    " TODO: font
+
     return user_settings
   endif
 endfunc
diff --git a/runtime/plugin/tohtml.vim b/runtime/plugin/tohtml.vim
index df72895160..433242fe1c 100644
--- a/runtime/plugin/tohtml.vim
+++ b/runtime/plugin/tohtml.vim
@@ -1,24 +1,22 @@
 " Vim plugin for converting a syntax highlighted file to HTML.
 " Maintainer: Ben Fritz -" Last Change: 2010 Aug 02
+" Last Change: 2010 Aug 07
 "
 " The core of the code is in $VIMRUNTIME/autoload/tohtml.vim and
 " $VIMRUNTIME/syntax/2html.vim
 "
 " TODO:
 "   * Bug: error thrown when nowrapscan is set
-"   * Diff mode with xhtml gives invalid markup
-"   * Diff mode does not determine encoding
 "   * Line number column has one character too few on empty lines
 "     without CSS.
 "   * Add extra meta info (generation time, etc.)
-"   * Fix strict doctype for other options?
+"   * Tidy up so we can use strict doctype more?
 "   * TODO comments for code cleanup scattered throughout
 
 if exists('g:loaded_2html_plugin')
   finish
 endif
-let g:loaded_2html_plugin = 'vim7.3_v3'
+let g:loaded_2html_plugin = 'vim7.3_v4'
 
 " Define the :TOhtml command when:
 " - 'compatible' is not set
diff --git a/runtime/syntax/2html.vim b/runtime/syntax/2html.vim
index 300425372a..77e037b6ca 100644
--- a/runtime/syntax/2html.vim
+++ b/runtime/syntax/2html.vim
@@ -1,6 +1,6 @@
 " Vim syntax support file
 " Maintainer: Ben Fritz 
-" Last Change: 2010 Aug 05
+" Last Change: 2010 Aug 07
 "
 " Additional contributors:
 "
@@ -73,7 +73,7 @@ else
   endfun
 endif
 
-if s:settings.use_css
+if !s:settings.use_css
   " Return opening HTML tag for given highlight id
   function! s:HtmlOpening(id)
     let a = ""
@@ -198,39 +198,6 @@ if s:settings.dynamic_folds
 
 endif
 
-" Figure out proper MIME charset from the 'encoding' option.
-if exists("g:html_use_encoding")
-  let s:html_encoding = g:html_use_encoding
-else
-  let s:vim_encoding = &encoding
-  if s:vim_encoding =~ '^8bit\|^2byte'
-    let s:vim_encoding = substitute(s:vim_encoding, '^8bit-\|^2byte-', '', '')
-  endif
-  if s:vim_encoding == 'latin1'
-    let s:html_encoding = 'iso-8859-1'
-  elseif s:vim_encoding =~ "^cp12"
-    let s:html_encoding = substitute(s:vim_encoding, 'cp', 'windows-', '')
-  elseif s:vim_encoding == 'sjis' || s:vim_encoding == 'cp932'
-    let s:html_encoding = 'Shift_JIS'
-  elseif s:vim_encoding == 'big5' || s:vim_encoding == 'cp950'
-    let s:html_encoding = "Big5"
-  elseif s:vim_encoding == 'euc-cn'
-    let s:html_encoding = 'GB_2312-80'
-  elseif s:vim_encoding == 'euc-tw'
-    let s:html_encoding = ""
-  elseif s:vim_encoding =~ '^euc\|^iso\|^koi'
-    let s:html_encoding = substitute(s:vim_encoding, '.*', '\U\0', '')
-  elseif s:vim_encoding == 'cp949'
-    let s:html_encoding = 'KS_C_5601-1987'
-  elseif s:vim_encoding == 'cp936'
-    let s:html_encoding = 'GBK'
-  elseif s:vim_encoding =~ '^ucs\|^utf'
-    let s:html_encoding = 'UTF-8'
-  else
-    let s:html_encoding = ""
-  endif
-endif
-
 
 " Set some options to make it work faster.
 " Don't report changes for :substitute, there will be many of them.
@@ -295,8 +262,8 @@ set magic
 let s:lines = []
 
 if s:settings.use_xhtml
-  if s:html_encoding != ""
-    call add(s:lines, "")
+  if s:settings.encoding != ""
+    call add(s:lines, "")
   else
     call add(s:lines, "")
   endif
@@ -317,15 +284,18 @@ endif
 " HTML header, with the title and generator ;-). Left free space for the CSS,
 " to be filled at the end.
 call extend(s:lines, [
-      \"",
-      \"",
-      \("".expand("%:p:~").""),
-      \("",
+      \ ""])
+" include encoding as close to the top as possible, but only if not already
+" contained in XML information (to avoid haggling over content type)
+if s:settings.encoding != "" && !s:settings.use_xhtml
+  call add(s:lines, "".expand("%:p:~").""),
+      \ ("",
-	    \ "',
-	    \ ''
 	    \])
     endif
@@ -394,8 +368,8 @@ if s:settings.use_css
     " if we aren't doing any dynamic folding, no need for any special rules
     call extend(s:lines, [
 	  \ "",
 	  \])
   endif
@@ -406,7 +380,7 @@ if s:settings.dynamic_folds
   call extend(s:lines, [
 	\ "",
 	\ ""
 	\])
 endif
@@ -965,7 +939,7 @@ endif
 if s:settings.no_pre
   if !s:settings.use_css
     " Close off the font tag that encapsulates the whole 
-    call extend(s:lines, ["", ""])
+    call extend(s:lines, ["", "", ""])
   else
     call extend(s:lines, ["", ""])
   endif
@@ -1005,7 +979,7 @@ if s:settings.use_css
     execute "normal! ^cwbody\e"
   endif
 else
-  execute '%s::'
+  execute '%s::\r'
 endif
 
 " Line numbering attributes
@@ -1053,7 +1027,10 @@ while !empty(s:idlist)
     if s:pgb.needs_redraw
       redrawstatus
       let s:pgb.needs_redraw = 0
-      sleep 50m
+      " TODO: sleep here to show the progress bar, but only if total time spent
+      " so far on this step is < 1 second? Too slow for batch runs like the test
+      " suite to sleep all the time. Maybe there's no good reason to sleep at
+      " all.
     endif
   endif
 endwhile |  |