Updated runtime files and translations.
diff --git a/runtime/syntax/2html.vim b/runtime/syntax/2html.vim
index fdee1ea..461b47f 100644
--- a/runtime/syntax/2html.vim
+++ b/runtime/syntax/2html.vim
@@ -1,6 +1,6 @@
 " Vim syntax support file
 " Maintainer: Ben Fritz <fritzophrenic@gmail.com>
-" Last Change: 2012 Jun 30
+" Last Change: 2013 May 31
 "
 " Additional contributors:
 "
@@ -214,17 +214,21 @@
 
 if !s:settings.use_css
   " Return opening HTML tag for given highlight id
-  function! s:HtmlOpening(id)
+  function! s:HtmlOpening(id, extra_attrs)
     let a = ""
     if synIDattr(a:id, "inverse")
       " For inverse, we always must set both colors (and exchange them)
       let x = s:HtmlColor(synIDattr(a:id, "fg#", s:whatterm))
-      let a = a . '<span style="background-color: ' . ( x != "" ? x : s:fgc ) . '">'
+      let a = a . '<span '.a:extra_attrs.'style="background-color: ' . ( x != "" ? x : s:fgc ) . '">'
       let x = s:HtmlColor(synIDattr(a:id, "bg#", s:whatterm))
       let a = a . '<font color="' . ( x != "" ? x : s:bgc ) . '">'
     else
       let x = s:HtmlColor(synIDattr(a:id, "bg#", s:whatterm))
-      if x != "" | let a = a . '<span style="background-color: ' . x . '">' | endif
+      if x != ""
+	let a = a . '<span '.a:extra_attrs.'style="background-color: ' . x . '">'
+      elseif !empty(a:extra_attrs)
+	let a = a . '<span '.a:extra_attrs.'>'
+      endif
       let x = s:HtmlColor(synIDattr(a:id, "fg#", s:whatterm))
       if x != "" | let a = a . '<font color="' . x . '">' | endif
     endif
@@ -235,7 +239,7 @@
   endfun
 
   " Return closing HTML tag for given highlight id
-  function! s:HtmlClosing(id)
+  function! s:HtmlClosing(id, has_extra_attrs)
     let a = ""
     if synIDattr(a:id, "underline") | let a = a . "</u>" | endif
     if synIDattr(a:id, "italic") | let a = a . "</i>" | endif
@@ -246,7 +250,7 @@
       let x = s:HtmlColor(synIDattr(a:id, "fg#", s:whatterm))
       if x != "" | let a = a . '</font>' | endif
       let x = s:HtmlColor(synIDattr(a:id, "bg#", s:whatterm))
-      if x != "" | let a = a . '</span>' | endif
+      if x != "" || a:has_extra_attrs | let a = a . '</span>' | endif
     endif
     return a
   endfun
@@ -265,7 +269,7 @@
 
   " first, get the style names we need
   let wrapperfunc_lines = [
-	\ 'function! s:BuildStyleWrapper(style_id, diff_style_id, text, make_unselectable, unformatted)',
+	\ 'function! s:BuildStyleWrapper(style_id, diff_style_id, extra_attrs, text, make_unselectable, unformatted)',
 	\ '',
 	\ '  let l:style_name = synIDattr(a:style_id, "name", s:whatterm)'
 	\ ]
@@ -308,7 +312,7 @@
 
   let wrapperfunc_lines += [
 	\ '',
-	\ '  if l:saved_style == ""'
+	\ '  if l:saved_style == "" && empty(a:extra_attrs)'
 	\ ]
   if &diff
     let wrapperfunc_lines += [
@@ -340,7 +344,7 @@
 	  \        : "")
   if s:settings.prevent_copy == ""
     let wrapperfunc_lines += [
-	  \ '    return "<span class=\"" . l:style_name .'.diffstyle.'"\">".a:text."</span>"'
+	  \ '    return "<span ".a:extra_attrs."class=\"" . l:style_name .'.diffstyle.'"\">".a:text."</span>"'
 	  \ ]
   else
 
@@ -362,7 +366,7 @@
     " uses the number of unique codepoints for its limit.
     let wrapperfunc_lines += [
 	  \ '    if a:make_unselectable',
-	  \ '      return "<span class=\"" . l:style_name .'.diffstyle.'"\">'.
+	  \ '      return "<span ".a:extra_attrs."class=\"" . l:style_name .'.diffstyle.'"\">'.
 	  \                '<input'.s:unselInputType.' class=\"" . l:style_name .'.diffstyle.'"\"'.
 	  \                 ' value=\"".substitute(a:unformatted,''\s\+$'',"","")."\"'.
 	  \                 ' onselect=''this.blur(); return false;'''.
@@ -372,17 +376,9 @@
 	  \                 ' size=\"".strwidth(a:unformatted)."\"'.
 	  \                 (s:settings.use_xhtml ? '/' : '').'></span>"',
 	  \ '    else',
-	  \ '      return "<span class=\"" . l:style_name .'. diffstyle .'"\">".a:text."</span>"'
+	  \ '      return "<span ".a:extra_attrs."class=\"" . l:style_name .'. diffstyle .'"\">".a:text."</span>"'
 	  \ ]
   endif
-  " close off tag for non-empty primary style
-  if s:settings.prevent_copy == ""
-    let wrapperfunc_lines[-1] .=
-	  \ '                     "\">".a:text."</span>"'
-  else
-    let wrapperfunc_lines[-1] .=
-	  \ '                     "\">".a:text."</span>"'
-  endif
   let wrapperfunc_lines += [
 	\ '  endif',
 	\ 'endfun'
@@ -394,16 +390,16 @@
   " no styles exist.
   if &diff
     let wrapperfunc_lines = [
-	  \ 'function! s:BuildStyleWrapper(style_id, diff_style_id, text, unusedarg, unusedarg2)',
-	  \ '  return s:HtmlOpening(a:style_id).(a:diff_style_id <= 0 ? "" :'.
-	  \                                     's:HtmlOpening(a:diff_style_id)).a:text.'.
-	  \   '(a:diff_style_id <= 0 ? "" : s:HtmlClosing(a:diff_style_id)).s:HtmlClosing(a:style_id)',
+	  \ 'function! s:BuildStyleWrapper(style_id, diff_style_id, extra_attrs, text, unusedarg, unusedarg2)',
+	  \ '  return s:HtmlOpening(a:style_id, a:extra_attrs).(a:diff_style_id <= 0 ? "" :'.
+	  \                                     's:HtmlOpening(a:diff_style_id, "")).a:text.'.
+	  \   '(a:diff_style_id <= 0 ? "" : s:HtmlClosing(a:diff_style_id, 0)).s:HtmlClosing(a:style_id, !empty(a:extra_attrs))',
 	  \ 'endfun'
 	  \ ]
   else
     let wrapperfunc_lines = [
-	  \ 'function! s:BuildStyleWrapper(style_id, diff_style_id, text, unusedarg, unusedarg2)',
-	  \ '  return s:HtmlOpening(a:style_id).a:text.s:HtmlClosing(a:style_id)',
+	  \ 'function! s:BuildStyleWrapper(style_id, diff_style_id, extra_attrs, text, unusedarg, unusedarg2)',
+	  \ '  return s:HtmlOpening(a:style_id, a:extra_attrs).a:text.s:HtmlClosing(a:style_id, !empty(a:extra_attrs))',
 	  \ 'endfun'
 	  \ ]
   endif
@@ -418,7 +414,7 @@
 " unprintable characters expanded and double spaces replaced as necessary.
 "
 " TODO: eliminate unneeded logic like done for BuildStyleWrapper
-function! s:HtmlFormat(text, style_id, diff_style_id, make_unselectable)
+function! s:HtmlFormat(text, style_id, diff_style_id, extra_attrs, make_unselectable)
   " Replace unprintable characters
   let unformatted = strtrans(a:text)
 
@@ -447,27 +443,45 @@
   endif
 
   " Enclose in the correct format
-  return s:BuildStyleWrapper(a:style_id, a:diff_style_id, formatted, a:make_unselectable, unformatted)
+  return s:BuildStyleWrapper(a:style_id, a:diff_style_id, a:extra_attrs, formatted, a:make_unselectable, unformatted)
 endfun
 
 " set up functions to call HtmlFormat in certain ways based on whether the
 " element is supposed to be unselectable or not
 if s:settings.prevent_copy =~# 'n'
-  function! s:HtmlFormat_n(text, style_id, diff_style_id)
-    return s:HtmlFormat(a:text, a:style_id, a:diff_style_id, 1)
-  endfun
+  if s:settings.number_lines
+    function! s:HtmlFormat_n(text, style_id, diff_style_id, lnr)
+      if a:lnr > 0
+	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.'" ', 1)
+      else
+	return s:HtmlFormat(a:text, a:style_id, a:diff_style_id, "", 1)
+      endif
+    endfun
+  else
+    " if lines are not being numbered the only reason this function gets called
+    " is to put the line IDs on each line; "text" will be emtpy but lnr will
+    " always be non-zero, however we don't want to use the <input> because that
+    " won't work as nice for empty text
+    function! s:HtmlFormat_n(text, style_id, diff_style_id, lnr)
+      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.'" ', 0)
+    endfun
+  endif
 else
-  function! s:HtmlFormat_n(text, style_id, diff_style_id)
-    return s:HtmlFormat(a:text, a:style_id, a:diff_style_id, 0)
+  function! s:HtmlFormat_n(text, style_id, diff_style_id, lnr)
+    if a:lnr > 0
+      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.'" ', 0)
+    else
+      return s:HtmlFormat(a:text, a:style_id, a:diff_style_id, "", 0)
+    endif
   endfun
 endif
 if s:settings.prevent_copy =~# 'd'
   function! s:HtmlFormat_d(text, style_id, diff_style_id)
-    return s:HtmlFormat(a:text, a:style_id, a:diff_style_id, 1)
+    return s:HtmlFormat(a:text, a:style_id, a:diff_style_id, "", 1)
   endfun
 else
   function! s:HtmlFormat_d(text, style_id, diff_style_id)
-    return s:HtmlFormat(a:text, a:style_id, a:diff_style_id, 0)
+    return s:HtmlFormat(a:text, a:style_id, a:diff_style_id, "", 0)
   endfun
 endif
 if s:settings.prevent_copy =~# 'f'
@@ -501,7 +515,7 @@
 	  \ "</a>"
   endfun
   function! s:FoldColumn_fill()
-    return s:HtmlFormat(repeat(' ', s:foldcolumn), s:FOLD_C_ID, 0, 0)
+    return s:HtmlFormat(repeat(' ', s:foldcolumn), s:FOLD_C_ID, 0, "", 0)
   endfun
 endif
 if s:settings.prevent_copy =~# 't'
@@ -512,17 +526,17 @@
   " substitute later?
   if s:settings.dynamic_folds
     function! s:HtmlFormat_t(text, style_id, diff_style_id)
-      return s:HtmlFormat(a:text, a:style_id, a:diff_style_id, 1) .
-	    \ s:HtmlFormat("", a:style_id, 0, 0)
+      return s:HtmlFormat(a:text, a:style_id, a:diff_style_id, "", 1) .
+	    \ s:HtmlFormat("", a:style_id, 0, "", 0)
     endfun
   else
     function! s:HtmlFormat_t(text, style_id, diff_style_id)
-      return s:HtmlFormat(a:text, a:style_id, a:diff_style_id, 1)
+      return s:HtmlFormat(a:text, a:style_id, a:diff_style_id, "", 1)
     endfun
   endif
 else
   function! s:HtmlFormat_t(text, style_id, diff_style_id)
-    return s:HtmlFormat(a:text, a:style_id, a:diff_style_id, 0)
+    return s:HtmlFormat(a:text, a:style_id, a:diff_style_id, "", 0)
   endfun
 endif
 
@@ -607,7 +621,11 @@
 let s:orgbufnr = winbufnr(0)
 let s:origwin_stl = &l:stl
 if expand("%") == ""
-  exec 'new Untitled.'.(s:settings.use_xhtml ? 'x' : '').'html'
+  if exists('g:html_diff_win_num')
+    exec 'new Untitled_win'.g:html_diff_win_num.'.'.(s:settings.use_xhtml ? 'x' : '').'html'
+  else
+    exec 'new Untitled.'.(s:settings.use_xhtml ? 'x' : '').'html'
+  endif
 else
   exec 'new %.'.(s:settings.use_xhtml ? 'x' : '').'html'
 endif
@@ -625,7 +643,6 @@
 let s:newwin_stl = &l:stl
 
 " on the new window, set the least time-consuming fold method
-let s:old_fdm = &foldmethod
 let s:old_fen = &foldenable
 setlocal foldmethod=manual
 setlocal nofoldenable
@@ -671,7 +688,7 @@
 let s:HtmlEndline = ''
 if s:settings.no_pre
   let s:HtmlEndline = '<br' . s:tag_close
-  let s:LeadingSpace = '&nbsp;'
+  let s:LeadingSpace = s:settings.use_xhtml ? '&#160;' : '&nbsp;'
   let s:HtmlSpace = '\' . s:LeadingSpace
 endif
 
@@ -774,13 +791,12 @@
   endif
 endif
 
-" insert script tag if any javascript is needed
-if s:settings.dynamic_folds || s:settings.prevent_copy != ""
-  call extend(s:lines, [
-	\ "",
-	\ "<script type='text/javascript'>",
-	\ s:settings.use_xhtml ? '//<![CDATA[' : "<!--"])
-endif
+" insert script tag; javascript is always needed for the line number
+" normalization for URL hashes
+call extend(s:lines, [
+      \ "",
+      \ "<script type='text/javascript'>",
+      \ s:settings.use_xhtml ? '//<![CDATA[' : "<!--"])
 
 " insert javascript to toggle folds open and closed
 if s:settings.dynamic_folds
@@ -799,9 +815,54 @@
 	\ "    fold.className = 'closed-fold';",
 	\ "  }",
 	\ "}"
-	\])
+	\ ])
 endif
 
+" insert javascript to get IDs from line numbers, and to open a fold before
+" jumping to any lines contained therein
+call extend(s:lines, [
+      \ "",
+      \ "/* function to open any folds containing a jumped-to line before jumping to it */",
+      \ "function JumpToLine()",
+      \ "{",
+      \ "  var lineNum;",
+      \ "  lineNum = window.location.hash;",
+      \ "  lineNum = lineNum.substr(1); /* strip off '#' */",
+      \ "",
+      \ "  if (lineNum.indexOf('L') == -1) {",
+      \ "    lineNum = 'L'+lineNum;",
+      \ "  }",
+      \ "  lineElem = document.getElementById(lineNum);"
+      \ ])
+if s:settings.dynamic_folds
+  call extend(s:lines, [
+	\ "",
+	\ "  /* navigate upwards in the DOM tree to open all folds containing the line */",
+	\ "  var node = lineElem;",
+	\ "  while (node && node.id != 'vimCodeElement')",
+	\ "  {",
+	\ "    if (node.className == 'closed-fold')",
+	\ "    {",
+	\ "      node.className = 'open-fold';",
+	\ "    }",
+	\ "    node = node.parentNode;",
+	\ "  }",
+	\ ])
+endif
+call extend(s:lines, [
+      \ "  /* Always jump to new location even if the line was hidden inside a fold, or",
+      \ "   * we corrected the raw number to a line ID.",
+      \ "   */",
+      \ "  if (lineElem) {",
+      \ "    lineElem.scrollIntoView(true);",
+      \ "  }",
+      \ "  return true;",
+      \ "}",
+      \ "if ('onhashchange' in window) {",
+      \ "  window.onhashchange = JumpToLine;",
+      \ "}"
+      \ ])
+
 " 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
@@ -861,26 +922,24 @@
 	\ ])
 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 ? '//]]>' : '-->',
-	\ "</script>"
-	\ ])
-endif
+" insert script closing tag
+call extend(s:lines, [
+      \ '',
+      \ s:settings.use_xhtml ? '//]]>' : '-->',
+      \ "</script>"
+      \ ])
 
 call extend(s:lines, ["</head>"])
 if !empty(s:settings.prevent_copy)
   call extend(s:lines,
-	\ ["<body onload='FixCharWidth();'>",
+	\ ["<body onload='FixCharWidth(); JumpToLine();'>",
 	\ "<!-- hidden divs used by javascript to get the width of a char -->",
 	\ "<div id='oneCharWidth'>0</div>",
 	\ "<div id='oneInputWidth'><input size='1' value='0'".s:tag_close."</div>",
 	\ "<div id='oneEmWidth' style='width: 1em;'></div>"
 	\ ])
 else
-  call extend(s:lines, ["<body>"])
+  call extend(s:lines, ["<body onload='JumpToLine();'>"])
 endif
 if s:settings.no_pre
   " if we're not using CSS we use a font tag which can't have a div inside
@@ -1242,7 +1301,7 @@
       if s:settings.number_lines
 	" 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
+	let s:new = s:HtmlFormat_n(repeat(' ', s:margin), s:LINENR_ID, 0, 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
@@ -1274,7 +1333,7 @@
     endif
 
     " 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)
+    let s:new = (s:settings.number_lines ? s:HtmlFormat_n(s:numcol, s:FOLDED_ID, 0, s:lnum): "") . s:HtmlFormat_t(s:new, s:FOLDED_ID, 0)
 
     " Skip to the end of the fold
     let s:new_lnum = foldclosedend(s:lnum)
@@ -1355,7 +1414,7 @@
 	" 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), '</span>', s:HtmlEndline.'\n\0', '')
+	let s:new = s:new . (s:settings.number_lines ? s:HtmlFormat_n(s:numcol, s:FOLDED_ID, 0, 0) : "") . substitute(s:HtmlFormat_t(foldtextresult(s:lnum), s:FOLDED_ID, 0), '</span>', s:HtmlEndline.'\n\0', '')
 	let s:new = s:new . "<span class='fulltext'>"
 
 	" open the fold now that we have the fold text to allow retrieval of
@@ -1389,7 +1448,9 @@
 
     " Now continue with the unfolded line text
     if s:settings.number_lines
-      let s:new = s:new . s:HtmlFormat_n(s:numcol, s:LINENR_ID, 0)
+      let s:new = s:new . s:HtmlFormat_n(s:numcol, s:LINENR_ID, 0, s:lnum)
+    else
+      let s:new = s:new . s:HtmlFormat_n("", s:LINENR_ID, 0, s:lnum)
     endif
 
     " Get the diff attribute, if any.
@@ -1479,7 +1540,7 @@
       " 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, s:diff_id, 0)
+	let s:new = s:new . s:HtmlFormat(s:expandedtab,  s:id, s:diff_id, "", 0)
       endif
     endwhile
   endif
@@ -1531,6 +1592,11 @@
 " stripped from the final output.
 %s!\v(%(^|\s+)%(vim?|ex)):!\1\&#0058;!ge
 
+" The generated HTML is admittedly ugly and takes a LONG time to fold.
+" Make sure the user doesn't do syntax folding when loading a generated file,
+" using a modeline.
+call append(line('$'), "<!-- vim: set foldmethod=manual : -->")
+
 " Now, when we finally know which, we define the colors and styles
 if s:settings.use_css
   1;/<style type="text/+1
@@ -1616,7 +1682,7 @@
     endif
   endif
 else
-  execute '%s:<body>:<body bgcolor="' . s:bgc . '" text="' . s:fgc . '">\r<font face="'. s:htmlfont .'">'
+  execute '%s:<body\([^>]*\):<body bgcolor="' . s:bgc . '" text="' . s:fgc . '"\1>\r<font face="'. s:htmlfont .'"'
 endif
 
 " Gather attributes for all other classes. Do diff first so that normal
@@ -1652,8 +1718,10 @@
 %s:\s\+$::e
 
 " Restore old settings (new window first)
+"
+" Don't bother restoring foldmethod in case it was syntax because the markup is
+" so weirdly formatted it can take a LONG time.
 let &l:foldenable = s:old_fen
-let &l:foldmethod = s:old_fdm
 let &report = s:old_report
 let &title = s:old_title
 let &icon = s:old_icon
@@ -1684,7 +1752,7 @@
 " Save a little bit of memory (worth doing?)
 unlet s:htmlfont s:whitespace
 unlet s:old_et s:old_paste s:old_icon s:old_report s:old_title s:old_search
-unlet s:old_magic s:old_more s:old_fdm s:old_fen s:old_winheight
+unlet s:old_magic s:old_more s:old_fen s:old_winheight
 unlet! s:old_isprint
 unlet s:whatterm s:stylelist s:diffstylelist s:lnum s:end s:margin s:fgc s:bgc s:old_winfixheight
 unlet! s:col s:id s:attr s:len s:line s:new s:expandedtab s:concealinfo s:diff_mode