summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorfritzophrenic <fritzophrenic@gmail.com>2023-09-08 12:20:01 -0500
committerGitHub <noreply@github.com>2023-09-08 19:20:01 +0200
commit86cfb39030eb557e1a1c7804f9c147556ca5dbf1 (patch)
treee95b65f1ff5e23f3696f21515e19c86fa654984b
parent1bd2cb11694690a77e4141bce2e34d9dfb882f1c (diff)
runtime(tohtml): Update TOhtml to version 9.0v2 (#13050)
Modified behavior: - Change default value of g:html_use_input_for_pc from "fallback" to "none". This means with default settings, only the standards-based method to make special text unselectable is used. The old method relying on unspecified browser behavior for <input> tags is now only used if a user specifically enables it. - Officially deprecate g:use_xhtml option (in favor of g:html_use_xhtml) by issuing a warning message when used. Bugfixes: - Fix issue #8547: LineNr and other special highlight groups did not get proper style rules defined when using "hi link". - Fix that diff filler was not properly added for deleted lines at the end of a buffer. Other: - Refactored function definitions from long lists of strings to use :let-heredoc variable assignment instead. - Corrected deprecated "." string concatenation operator to ".." operator in more places. Signed-off-by: Christian Brabandt <cb@256bit.org>
-rw-r--r--runtime/autoload/tohtml.vim71
-rw-r--r--runtime/doc/syntax.txt2
-rw-r--r--runtime/plugin/tohtml.vim27
-rw-r--r--runtime/syntax/2html.vim663
4 files changed, 428 insertions, 335 deletions
diff --git a/runtime/autoload/tohtml.vim b/runtime/autoload/tohtml.vim
index 1086347473..d2722a4021 100644
--- a/runtime/autoload/tohtml.vim
+++ b/runtime/autoload/tohtml.vim
@@ -1,6 +1,6 @@
" Vim autoload file for the tohtml plugin.
" Maintainer: Ben Fritz <fritzophrenic@gmail.com>
-" Last Change: 2023 Jan 01
+" Last Change: 2023 Sep 03
"
" Additional contributors:
"
@@ -307,7 +307,7 @@ func! tohtml#Convert2HTML(line1, line2) "{{{
let g:html_diff_win_num = 0
for window in win_list
" switch to the next buffer to convert
- exe ":" . bufwinnr(window) . "wincmd w"
+ exe ":" .. bufwinnr(window) .. "wincmd w"
" figure out whether current charset and encoding will work, if not
" default to UTF-8
@@ -355,7 +355,7 @@ func! tohtml#Diff2HTML(win_list, buf_list) "{{{
if !s:settings.no_doc
if s:settings.use_xhtml
if s:settings.encoding != ""
- let xml_line = "<?xml version=\"1.0\" encoding=\"" . s:settings.encoding . "\"?>"
+ let xml_line = "<?xml version=\"1.0\" encoding=\"" .. s:settings.encoding .. "\"?>"
else
let xml_line = "<?xml version=\"1.0\"?>"
endif
@@ -387,34 +387,34 @@ func! tohtml#Diff2HTML(win_list, buf_list) "{{{
" contained in XML information
if s:settings.encoding != "" && !s:settings.use_xhtml
if s:html5
- call add(html, '<meta charset="' . s:settings.encoding . '"' . tag_close)
+ call add(html, '<meta charset="' .. s:settings.encoding .. '"' .. tag_close)
else
- call add(html, "<meta http-equiv=\"content-type\" content=\"text/html; charset=" . s:settings.encoding . '"' . tag_close)
+ call add(html, "<meta http-equiv=\"content-type\" content=\"text/html; charset=" .. s:settings.encoding .. '"' .. tag_close)
endif
endif
call add(html, '<title>diff</title>')
- call add(html, '<meta name="Generator" content="Vim/'.v:version/100.'.'.v:version%100.'"'.tag_close)
- call add(html, '<meta name="plugin-version" content="'.g:loaded_2html_plugin.'"'.tag_close)
+ call add(html, '<meta name="Generator" content="Vim/'..v:version/100..'.'..v:version%100..'"'..tag_close)
+ call add(html, '<meta name="plugin-version" content="'..g:loaded_2html_plugin..'"'..tag_close)
call add(html, '<meta name="settings" content="'.
\ join(filter(keys(s:settings),'s:settings[v:val]'),',').
- \ ',prevent_copy='.s:settings.prevent_copy.
- \ ',use_input_for_pc='.s:settings.use_input_for_pc.
- \ '"'.tag_close)
+ \ ',prevent_copy='..s:settings.prevent_copy.
+ \ ',use_input_for_pc='..s:settings.use_input_for_pc.
+ \ '"'..tag_close)
call add(html, '<meta name="colorscheme" content="'.
\ (exists('g:colors_name')
\ ? g:colors_name
- \ : 'none'). '"'.tag_close)
+ \ : 'none').. '"'..tag_close)
call add(html, '</head>')
let body_line_num = len(html)
- call add(html, '<body'.(s:settings.line_ids ? ' onload="JumpToLine();"' : '').'>')
+ call add(html, '<body'..(s:settings.line_ids ? ' onload="JumpToLine();"' : '')..'>')
endif
- call add(html, "<table ".(s:settings.use_css? "" : "border='1' width='100%' ")."id='vimCodeElement".s:settings.id_suffix."'>")
+ call add(html, "<table "..(s:settings.use_css? "" : "border='1' width='100%' ").."id='vimCodeElement"..s:settings.id_suffix.."'>")
call add(html, '<tr>')
for buf in a:win_list
- call add(html, '<th>'.bufname(buf).'</th>')
+ call add(html, '<th>'..bufname(buf)..'</th>')
endfor
call add(html, '</tr><tr>')
@@ -423,7 +423,7 @@ func! tohtml#Diff2HTML(win_list, buf_list) "{{{
for buf in a:buf_list
let temp = []
- exe bufwinnr(buf) . 'wincmd w'
+ exe bufwinnr(buf) .. 'wincmd w'
" If text is folded because of user foldmethod settings, etc. we don't want
" to act on everything in a fold by mistake.
@@ -526,16 +526,16 @@ func! tohtml#Diff2HTML(win_list, buf_list) "{{{
endif
let i = 1
- let name = "Diff" . (s:settings.use_xhtml ? ".xhtml" : ".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*\.x\?html$', '', '') . i . '.' . fnamemodify(copy(name), ":t:e")
+ let name = substitute(name, '\d*\.x\?html$', '', '') .. i .. '.' .. fnamemodify(copy(name), ":t:e")
let i += 1
endwhile
let s:ei_sav = &eventignore
set eventignore+=FileType
- exe "topleft new " . name
+ exe "topleft new " .. name
let &eventignore=s:ei_sav
unlet s:ei_sav
@@ -601,7 +601,7 @@ func! tohtml#Diff2HTML(win_list, buf_list) "{{{
\ "",
\ " /* navigate upwards in the DOM tree to open all folds containing the line */",
\ " var node = lineElem;",
- \ " while (node && node.id != 'vimCodeElement".s:settings.id_suffix."')",
+ \ " while (node && node.id != 'vimCodeElement"..s:settings.id_suffix.."')",
\ " {",
\ " if (node.className == 'closed-fold')",
\ " {",
@@ -640,7 +640,7 @@ func! tohtml#Diff2HTML(win_list, buf_list) "{{{
call append(style_start, [
\ " function toggleFold(objID)",
\ " {",
- \ " for (win_num = 1; win_num <= ".len(a:buf_list)."; win_num++)",
+ \ " for (win_num = 1; win_num <= "..len(a:buf_list).."; win_num++)",
\ " {",
\ " var fold;",
\ ' fold = document.getElementById("win"+win_num+objID);',
@@ -660,7 +660,7 @@ func! tohtml#Diff2HTML(win_list, buf_list) "{{{
if s:uses_script
" insert script tag if needed
call append(style_start, [
- \ "<script" . (s:html5 ? "" : " type='text/javascript'") . ">",
+ \ "<script" .. (s:html5 ? "" : " type='text/javascript'") .. ">",
\ s:settings.use_xhtml ? '//<![CDATA[' : "<!--"])
endif
@@ -671,14 +671,14 @@ func! tohtml#Diff2HTML(win_list, buf_list) "{{{
" is pretty useless for really long lines. {{{
if s:settings.use_css
call append(style_start,
- \ ['<style' . (s:html5 ? '' : 'type="text/css"') . '>']+
+ \ ['<style' .. (s:html5 ? '' : 'type="text/css"') .. '>']+
\ style+
\ [ s:settings.use_xhtml ? '' : '<!--',
\ 'table { table-layout: fixed; }',
\ 'html, body, table, tbody { width: 100%; margin: 0; padding: 0; }',
\ 'table, td, th { border: 1px solid; }',
\ 'td { vertical-align: top; }',
- \ 'th, td { width: '.printf("%.1f",100.0/len(a:win_list)).'%; }',
+ \ 'th, td { width: '..printf("%.1f",100.0/len(a:win_list))..'%; }',
\ 'td div { overflow: auto; }',
\ s:settings.use_xhtml ? '' : '-->',
\ '</style>'
@@ -694,7 +694,7 @@ endfunc "}}}
" Gets a single user option and sets it in the passed-in Dict, or gives it the
" default value if the option doesn't actually exist.
func! tohtml#GetOption(settings, option, default) "{{{
- if exists('g:html_'.a:option)
+ if exists('g:html_'..a:option)
let a:settings[a:option] = g:html_{a:option}
else
let a:settings[a:option] = a:default
@@ -713,10 +713,11 @@ func! tohtml#GetUserSettings() "{{{
let user_settings = {}
" Define the correct option if the old option name exists and we haven't
- " already defined the correct one. Maybe I'll put out a warning message about
- " this sometime and remove the old option entirely at some even later time,
- " but for now just silently accept the old option.
+ " already defined the correct one.
if exists('g:use_xhtml') && !exists("g:html_use_xhtml")
+ echohl WarningMsg
+ echomsg "Warning: g:use_xhtml is deprecated, use g:html_use_xhtml"
+ echohl None
let g:html_use_xhtml = g:use_xhtml
endif
@@ -739,7 +740,7 @@ func! tohtml#GetUserSettings() "{{{
call tohtml#GetOption(user_settings, 'whole_filler', 0 )
call tohtml#GetOption(user_settings, 'use_xhtml', 0 )
call tohtml#GetOption(user_settings, 'line_ids', user_settings.number_lines )
- call tohtml#GetOption(user_settings, 'use_input_for_pc', 'fallback')
+ call tohtml#GetOption(user_settings, 'use_input_for_pc', 'none')
" }}}
" override those settings that need it {{{
@@ -854,16 +855,16 @@ func! tohtml#GetUserSettings() "{{{
if user_settings.use_css
if exists("g:html_prevent_copy")
if user_settings.dynamic_folds && !user_settings.no_foldcolumn && g:html_prevent_copy =~# 'f'
- let user_settings.prevent_copy .= 'f'
+ let user_settings.prevent_copy ..= 'f'
endif
if user_settings.number_lines && g:html_prevent_copy =~# 'n'
- let user_settings.prevent_copy .= 'n'
+ let user_settings.prevent_copy ..= 'n'
endif
if &diff && g:html_prevent_copy =~# 'd'
- let user_settings.prevent_copy .= 'd'
+ let user_settings.prevent_copy ..= 'd'
endif
if !user_settings.ignore_folding && g:html_prevent_copy =~# 't'
- let user_settings.prevent_copy .= 't'
+ let user_settings.prevent_copy ..= 't'
endif
else
let user_settings.prevent_copy = ""
@@ -875,10 +876,10 @@ func! tohtml#GetUserSettings() "{{{
" enforce valid values for use_input_for_pc
if user_settings.use_input_for_pc !~# 'fallback\|none\|all'
- let user_settings.use_input_for_pc = 'fallback'
+ let user_settings.use_input_for_pc = 'none'
echohl WarningMsg
- echomsg '2html: "' . g:html_use_input_for_pc . '" is not valid for g:html_use_input_for_pc'
- echomsg '2html: defaulting to "' . user_settings.use_input_for_pc . '"'
+ echomsg '2html: "' .. g:html_use_input_for_pc .. '" is not valid for g:html_use_input_for_pc'
+ echomsg '2html: defaulting to "' .. user_settings.use_input_for_pc .. '"'
echohl None
sleep 3
endif
diff --git a/runtime/doc/syntax.txt b/runtime/doc/syntax.txt
index 29a12396d4..6a20734a60 100644
--- a/runtime/doc/syntax.txt
+++ b/runtime/doc/syntax.txt
@@ -596,7 +596,7 @@ The method used to prevent copying in the generated page depends on the value
of |g:html_use_input_for_pc|.
*g:html_use_input_for_pc*
-Default: "fallback"
+Default: "none"
If |g:html_prevent_copy| is non-empty, then:
When "all", read-only <input> elements are used in place of normal text for
diff --git a/runtime/plugin/tohtml.vim b/runtime/plugin/tohtml.vim
index 0369313f08..56eb2c15bf 100644
--- a/runtime/plugin/tohtml.vim
+++ b/runtime/plugin/tohtml.vim
@@ -1,6 +1,6 @@
" Vim plugin for converting a syntax highlighted file to HTML.
" Maintainer: Ben Fritz <fritzophrenic@gmail.com>
-" Last Change: 2023 Jan 01
+" Last Change: 2023 Sep 07
"
" The core of the code is in $VIMRUNTIME/autoload/tohtml.vim and
" $VIMRUNTIME/syntax/2html.vim
@@ -8,11 +8,29 @@
if exists('g:loaded_2html_plugin')
finish
endif
-let g:loaded_2html_plugin = 'vim9.0_v1'
+let g:loaded_2html_plugin = 'vim9.0_v2'
"
" Changelog: {{{
-" 9.0_v1 (this version): - Implement g:html_no_doc and g:html_no_modeline
+" 9.0_v2 (this version): - Warn if using deprecated g:use_xhtml option
+" - Change default g:html_use_input_for_pc to "none"
+" instead of "fallback". All modern browsers support
+" the "user-select: none" and "content:" CSS
+" properties so the older method relying on extra
+" markup and unspecified browser/app clipboard
+" handling is only needed in rare special cases.
+" - Fix SourceForge issue #33: generate diff filler
+" correctly when new lines have been added to or
+" removed from end of buffer.
+" - Fix SourceForge issue #32/Vim Github issue #8547:
+" use translated highlight ID for styling the
+" special-use group names (e.g. LineNr) used
+" directly by name in the 2html processing.
+" - Fix SourceForge issue #26, refactoring to use
+" :let-heredoc style string assignment and
+" additional fixes for ".." vs. "." style string
+" concatenation. Requires Vim v8.1.1354 or higher.
+" 9.0_v1 (Vim 9.0.1275): - Implement g:html_no_doc and g:html_no_modeline
" for diff mode. Add tests.
" (Vim 9.0.1122): NOTE: no version string update for this version!
" - Bugfix for variable name in g:html_no_doc
@@ -21,7 +39,8 @@ let g:loaded_2html_plugin = 'vim9.0_v1'
" and g:html_no_modeline (partially included in Vim
" runtime prior to version string update).
" - Updates for new Vim9 string append style (i.e. use
-" ".." instead of ".")
+" ".." instead of "."). Requires Vim version
+" 8.1.1114 or higher.
"
" 8.1 updates: {{{
" 8.1_v2 (Vim 8.1.2312): - Fix SourceForge issue #19: fix calculation of tab
diff --git a/runtime/syntax/2html.vim b/runtime/syntax/2html.vim
index 69780cffef..f3ce8bed8d 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: 2023 Jan 01
+" Last Change: 2023 Sep 05
"
" Additional contributors:
"
@@ -32,9 +32,9 @@ let s:end=line('$')
" Font
if exists("g:html_font")
if type(g:html_font) == type([])
- let s:htmlfont = "'". join(g:html_font,"','") . "', monospace"
+ let s:htmlfont = "'".. join(g:html_font,"','") .. "', monospace"
else
- let s:htmlfont = "'". g:html_font . "', monospace"
+ let s:htmlfont = "'".. g:html_font .. "', monospace"
endif
else
let s:htmlfont = "monospace"
@@ -221,8 +221,8 @@ else
endif
" Find out the background and foreground color for use later
-let s:fgc = s:HtmlColor(synIDattr(hlID("Normal"), "fg#", s:whatterm))
-let s:bgc = s:HtmlColor(synIDattr(hlID("Normal"), "bg#", s:whatterm))
+let s:fgc = s:HtmlColor(synIDattr(hlID("Normal")->synIDtrans(), "fg#", s:whatterm))
+let s:bgc = s:HtmlColor(synIDattr(hlID("Normal")->synIDtrans(), "bg#", s:whatterm))
if s:fgc == ""
let s:fgc = ( &background == "dark" ? "#ffffff" : "#000000" )
endif
@@ -234,41 +234,43 @@ if !s:settings.use_css
" Return opening HTML tag for given highlight id
function! s:HtmlOpening(id, extra_attrs)
let a = ""
- if synIDattr(a:id, "inverse")
+ let translated_ID = synIDtrans(a:id)
+ if synIDattr(translated_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 '.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 ) . '">'
+ let x = s:HtmlColor(synIDattr(translated_ID, "fg#", s:whatterm))
+ let a = a .. '<span '..a:extra_attrs..'style="background-color: ' .. ( x != "" ? x : s:fgc ) .. '">'
+ let x = s:HtmlColor(synIDattr(translated_ID, "bg#", s:whatterm))
+ let a = a .. '<font color="' .. ( x != "" ? x : s:bgc ) .. '">'
else
- let x = s:HtmlColor(synIDattr(a:id, "bg#", s:whatterm))
+ let x = s:HtmlColor(synIDattr(translated_ID, "bg#", s:whatterm))
if x != ""
- let a = a . '<span '.a:extra_attrs.'style="background-color: ' . x . '">'
+ let a = a .. '<span '..a:extra_attrs..'style="background-color: ' .. x .. '">'
elseif !empty(a:extra_attrs)
- let a = a . '<span '.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
+ let x = s:HtmlColor(synIDattr(translated_ID, "fg#", s:whatterm))
+ if x != "" | let a = a .. '<font color="' .. x .. '">' | endif
endif
- if synIDattr(a:id, "bold") | let a = a . "<b>" | endif
- if synIDattr(a:id, "italic") | let a = a . "<i>" | endif
- if synIDattr(a:id, "underline") | let a = a . "<u>" | endif
+ if synIDattr(translated_ID, "bold") | let a = a .. "<b>" | endif
+ if synIDattr(translated_ID, "italic") | let a = a .. "<i>" | endif
+ if synIDattr(translated_ID, "underline") | let a = a .. "<u>" | endif
return a
endfun
" Return closing HTML tag for given highlight 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
- if synIDattr(a:id, "bold") | let a = a . "</b>" | endif
- if synIDattr(a:id, "inverse")
- let a = a . '</font></span>'
+ let translated_ID = synIDtrans(a:id)
+ if synIDattr(translated_ID, "underline") | let a = a .. "</u>" | endif
+ if synIDattr(translated_ID, "italic") | let a = a .. "</i>" | endif
+ if synIDattr(translated_ID, "bold") | let a = a .. "</b>" | endif
+ if synIDattr(translated_ID, "inverse")
+ let a = a .. '</font></span>'
else
- 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 != "" || a:has_extra_attrs | let a = a . '</span>' | endif
+ let x = s:HtmlColor(synIDattr(translated_ID, "fg#", s:whatterm))
+ if x != "" | let a = a .. '</font>' | endif
+ let x = s:HtmlColor(synIDattr(translated_ID, "bg#", s:whatterm))
+ if x != "" || a:has_extra_attrs | let a = a .. '</span>' | endif
endif
return a
endfun
@@ -286,84 +288,102 @@ if s:settings.use_css
" save CSS to a list of rules to add to the output at the end of processing
" first, get the style names we need
- let wrapperfunc_lines = [
- \ '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)'
- \ ]
+ let s:wrapperfunc_lines = []
+ call add(s:wrapperfunc_lines, [])
+ let s:wrapperfunc_lines[-1] =<< trim ENDLET
+ 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)
+ ENDLET
if &diff
- let wrapperfunc_lines += [
- \ ' let l:diff_style_name = synIDattr(a:diff_style_id, "name", s:whatterm)']
-
- " Add normal groups and diff groups to separate lists so we can order them to
- " allow diff highlight to override normal highlight
-
- " if primary style IS a diff style, grab it from the diff cache instead
- " (always succeeds because we pre-populate it)
- let wrapperfunc_lines += [
- \ '',
- \ ' 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_ID',
- \ ' let l:saved_style = get(s:diffstylelist,a:style_id)',
- \ ' else'
- \ ]
+ call add(s:wrapperfunc_lines, [])
+ let s:wrapperfunc_lines[-1] =<< trim ENDLET
+ let l:diff_style_name = synIDattr(a:diff_style_id, "name", s:whatterm)
+ ENDLET
+
+ " Add normal groups and diff groups to separate lists so we can order them to
+ " allow diff highlight to override normal highlight
+
+ " if primary style IS a diff style, grab it from the diff cache instead
+ " (always succeeds because we pre-populate it)
+ call add(s:wrapperfunc_lines, [])
+ let s:wrapperfunc_lines[-1] =<< trim ENDLET
+
+ 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_ID
+ let l:saved_style = get(s:diffstylelist,a:style_id)
+ else
+ ENDLET
endif
" get primary style info from cache or build it on the fly if not found
- let wrapperfunc_lines += [
- \ ' let l:saved_style = get(s:stylelist,a:style_id)',
- \ ' if type(l:saved_style) == type(0)',
- \ ' unlet l:saved_style',
- \ ' let l:saved_style = s:CSS1(a:style_id)',
- \ ' if l:saved_style != ""',
- \ ' let l:saved_style = "." . l:style_name . " { " . l:saved_style . "}"',
- \ ' endif',
- \ ' let s:stylelist[a:style_id]= l:saved_style',
- \ ' endif'
- \ ]
+ call add(s:wrapperfunc_lines, [])
+ let s:wrapperfunc_lines[-1] =<< trim ENDLET
+ let l:saved_style = get(s:stylelist,a:style_id)
+ if type(l:saved_style) == type(0)
+ unlet l:saved_style
+ let l:saved_style = s:CSS1(a:style_id)
+ if l:saved_style != ""
+ let l:saved_style = "." .. l:style_name .. " { " .. l:saved_style .. "}"
+ endif
+ let s:stylelist[a:style_id] = l:saved_style
+ endif
+ ENDLET
if &diff
- let wrapperfunc_lines += [ ' endif' ]
+ call add(s:wrapperfunc_lines, [])
+ let s:wrapperfunc_lines[-1] =<< trim ENDLET
+ endif
+ ENDLET
endif
+" Ignore this comment, just bypassing a highlighting issue: if
" Build the wrapper tags around the text. It turns out that caching these
" gives pretty much zero performance gain and adds a lot of logic.
- let wrapperfunc_lines += [
- \ '',
- \ ' if l:saved_style == "" && empty(a:extra_attrs)'
- \ ]
+ call add(s:wrapperfunc_lines, [])
+ let s:wrapperfunc_lines[-1] =<< trim ENDLET
+
+ if l:saved_style == "" && empty(a:extra_attrs)
+ ENDLET
if &diff
- let wrapperfunc_lines += [
- \ ' if a:diff_style_id <= 0'
- \ ]
+ call add(s:wrapperfunc_lines, [])
+ let s:wrapperfunc_lines[-1] =<< trim ENDLET
+ if a:diff_style_id <= 0
+ ENDLET
endif
" no surroundings if neither primary nor diff style has any info
- let wrapperfunc_lines += [
- \ ' return a:text'
- \ ]
+ call add(s:wrapperfunc_lines, [])
+ let s:wrapperfunc_lines[-1] =<< trim ENDLET
+ return a:text
+ ENDLET
if &diff
" no primary style, but diff style
- let wrapperfunc_lines += [
- \ ' else',
- \ ' return "<span class=\"" .l:diff_style_name . "\">".a:text."</span>"',
- \ ' endif'
- \ ]
+ call add(s:wrapperfunc_lines, [])
+ let s:wrapperfunc_lines[-1] =<< trim ENDLET
+ else
+ return '<span class="' ..l:diff_style_name .. '">'..a:text.."</span>"
+ endif
+ ENDLET
endif
+ " Ignore this comment, just bypassing a highlighting issue: if
+
" open tag for non-empty primary style
- let wrapperfunc_lines += [
- \ ' else']
+ call add(s:wrapperfunc_lines, [])
+ let s:wrapperfunc_lines[-1] =<< trim ENDLET
+ else
+ ENDLET
" non-empty primary style. handle either empty or non-empty diff style.
"
" separate the two classes by a space to apply them both if there is a diff
" style name, unless the primary style is empty, then just use the diff style
" name
- let diffstyle =
- \ (&diff ? '(a:diff_style_id <= 0 ? "" : " ". l:diff_style_name) .'
- \ : "")
+ let s:diffstyle =
+ \ (&diff ? '(a:diff_style_id <= 0 ? "" : " " .. l:diff_style_name)..'
+ \ : '')
if s:settings.prevent_copy == ""
- let wrapperfunc_lines += [
- \ ' return "<span ".a:extra_attrs."class=\"" . l:style_name .'.diffstyle.'"\">".a:text."</span>"'
- \ ]
+ call add(s:wrapperfunc_lines, [])
+ let s:wrapperfunc_lines[-1] =<< trim eval ENDLET
+ return "<span "..a:extra_attrs..'class="' .. l:style_name ..{s:diffstyle}'">'..a:text.."</span>"
+ ENDLET
else
" New method: use generated content in the CSS. The only thing needed here
@@ -388,59 +408,76 @@ if s:settings.use_css
" Note, if maxlength property needs to be added in the future, it will need
" to use strchars(), because HTML specifies that the maxlength parameter
" uses the number of unique codepoints for its limit.
- let wrapperfunc_lines += [
- \ ' if a:make_unselectable',
- \ ' return "<span ".a:extra_attrs."class=\"" . l:style_name .'.diffstyle.'"\"'
- \ ]
+ call add(s:wrapperfunc_lines, [])
+ let s:wrapperfunc_lines[-1] =<< trim eval ENDLET
+ if a:make_unselectable
+ let return_span = "<span "..a:extra_attrs..'class="' .. l:style_name ..{s:diffstyle}'"'
+ ENDLET
if s:settings.use_input_for_pc !=# 'all'
- let wrapperfunc_lines[-1] .= ' " . "data-" . l:style_name . "-content=\"".a:text."\"'
+ call add(s:wrapperfunc_lines, [])
+ let s:wrapperfunc_lines[-1] =<< trim ENDLET
+ let return_span ..= " data-" .. l:style_name .. '-content="'..a:text..'"'
+ ENDLET
endif
- let wrapperfunc_lines[-1] .= '>'
+ call add(s:wrapperfunc_lines, [])
+ let s:wrapperfunc_lines[-1] =<< trim ENDLET
+ let return_span ..= '>'
+ ENDLET
if s:settings.use_input_for_pc !=# 'none'
- let wrapperfunc_lines[-1] .=
- \ '<input'.s:unselInputType.' class=\"" . l:style_name .'.diffstyle.'"\"'.
- \ ' value=\"".substitute(a:unformatted,''\s\+$'',"","")."\"'.
- \ ' onselect=''this.blur(); return false;'''.
- \ ' onmousedown=''this.blur(); return false;'''.
- \ ' onclick=''this.blur(); return false;'''.
- \ ' readonly=''readonly'''.
- \ ' size=\"".strwidth(a:unformatted)."\"'.
- \ (s:settings.use_xhtml ? '/' : '').'>'
+ call add(s:wrapperfunc_lines, [])
+ let s:wrapperfunc_lines[-1] =<< trim eval ENDLET
+ let return_span ..= '<input'..s:unselInputType..' class="' .. l:style_name ..{s:diffstyle}'"'
+ let return_span ..= ' value="'..substitute(a:unformatted,'\s\+$',"","")..'"'
+ let return_span ..= " onselect='this.blur(); return false;'"
+ let return_span ..= " onmousedown='this.blur(); return false;'"
+ let return_span ..= " onclick='this.blur(); return false;'"
+ let return_span ..= " readonly='readonly'"
+ let return_span ..= ' size="'..strwidth(a:unformatted)..'"'
+ let return_span ..= (s:settings.use_xhtml ? '/>' : '>')
+ ENDLET
endif
- let wrapperfunc_lines[-1] .= '</span>"'
- let wrapperfunc_lines += [
- \ ' else',
- \ ' return "<span ".a:extra_attrs."class=\"" . l:style_name .'. diffstyle .'"\">".a:text."</span>"'
- \ ]
+ call add(s:wrapperfunc_lines, [])
+ let s:wrapperfunc_lines[-1] =<< trim eval ENDLET
+ return return_span..'</span>'
+ else
+ return "<span "..a:extra_attrs..'class="' .. l:style_name .. {s:diffstyle}'">'..a:text.."</span>"
+ endif
+ ENDLET
endif
- let wrapperfunc_lines += [
- \ ' endif',
- \ 'endfun'
- \ ]
+ call add(s:wrapperfunc_lines, [])
+ let s:wrapperfunc_lines[-1] =<< trim ENDLET
+ endif
+ endfun
+ ENDLET
else
" Non-CSS method just needs the wrapper.
"
" Functions used to get opening/closing automatically return null strings if
" no styles exist.
if &diff
- let wrapperfunc_lines = [
- \ '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'
- \ ]
+ let s:wrapperfunc_lines =<< trim ENDLET
+ function! s:BuildStyleWrapper(style_id, diff_style_id, extra_attrs, text, unusedarg, unusedarg2)
+ if a:diff_style_id <= 0
+ let l:diff_opening = s:HtmlOpening(a:diff_style_id, "")
+ let l:diff_closing = s:HtmlClosing(a:diff_style_id, 0)
+ else
+ let l:diff_opening = ""
+ let l:diff_closing = ""
+ endif
+ 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))
+ endfun
+ ENDLET
else
- let wrapperfunc_lines = [
- \ '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'
- \ ]
+ let s:wrapperfunc_lines =<< trim ENDLET
+ 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
+ ENDLET
endif
endif
" create the function we built line by line above
-exec join(wrapperfunc_lines, "\n")
+exec join(flatten(s:wrapperfunc_lines), "\n")
let s:diff_mode = &diff
@@ -471,7 +508,7 @@ function! s:HtmlFormat(text, style_id, diff_style_id, extra_attrs, make_unselect
" Replace double spaces, leading spaces, and trailing spaces if needed
if ' ' != s:HtmlSpace
- let formatted = substitute(formatted, ' ', s:HtmlSpace . s:HtmlSpace, 'g')
+ let formatted = substitute(formatted, ' ', s:HtmlSpace .. s:HtmlSpace, 'g')
let formatted = substitute(formatted, '^ ', s:HtmlSpace, 'g')
let formatted = substitute(formatted, ' \+$', s:HtmlSpace, 'g')
endif
@@ -487,7 +524,7 @@ if s:settings.prevent_copy =~# 'n'
if s:settings.line_ids
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.s:settings.id_suffix.'" ', 1)
+ 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)
else
return s:HtmlFormat(a:text, a:style_id, a:diff_style_id, "", 1)
endif
@@ -503,14 +540,14 @@ if s:settings.prevent_copy =~# 'n'
" 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.s:settings.id_suffix.'" ', 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..s:settings.id_suffix..'" ', 0)
endfun
endif
else
if s:settings.line_ids
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.s:settings.id_suffix.'" ', 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..s:settings.id_suffix..'" ', 0)
else
return s:HtmlFormat(a:text, a:style_id, a:diff_style_id, "", 0)
endif
@@ -535,8 +572,8 @@ if s:settings.prevent_copy =~# 'f'
" Simply space-pad to the desired width inside the generated content (note
" that the FoldColumn definition includes a whitespace:pre rule)
function! s:FoldColumn_build(char, len, numfill, char2, class, click)
- return "<a href='#' class='".a:class."' onclick='".a:click."' data-FoldColumn-content='".
- \ repeat(a:char, a:len).a:char2.repeat(' ', a:numfill).
+ return "<a href='#' class='"..a:class.."' onclick='"..a:click.."' data-FoldColumn-content='".
+ \ repeat(a:char, a:len)..a:char2..repeat(' ', a:numfill).
\ "'></a>"
endfun
function! s:FoldColumn_fill()
@@ -554,35 +591,38 @@ if s:settings.prevent_copy =~# 'f'
"
" Note, 'exec' commands do not recognize line continuations, so must
" concatenate lines rather than continue them.
- let build_fun_lines = [
- \ 'function! s:FoldColumn_build(char, len, numfill, char2, class, click)',
- \ ' let l:input_open = "<input readonly=''readonly''".s:unselInputType.'.
- \ ' " onselect=''this.blur(); return false;''".'.
- \ ' " onmousedown=''this.blur(); ".a:click." return false;''".'.
- \ ' " onclick=''return false;'' size=''".'.
- \ ' string(a:len + (empty(a:char2) ? 0 : 1) + a:numfill) .'.
- \ ' "'' "',
- \ ' let l:common_attrs = "class=''FoldColumn'' value=''"',
- \ ' let l:input_close = (s:settings.use_xhtml ? "'' />" : "''>")'
- \ ]
+ let s:build_fun_lines = []
+ call add(s:build_fun_lines, [])
+ let s:build_fun_lines[-1] =<< trim ENDLET
+ function! s:FoldColumn_build(char, len, numfill, char2, class, click)
+ let l:input_open = "<input readonly='readonly'"..s:unselInputType
+ let l:input_open ..= " onselect='this.blur(); return false;'"
+ let l:input_open ..= " onmousedown='this.blur(); "..a:click.." return false;'"
+ let l:input_open ..= " onclick='return false;' size='"
+ let l:input_open ..= string(a:len + (empty(a:char2) ? 0 : 1) + a:numfill) .. "' "
+ let l:common_attrs = "class='FoldColumn' value='"
+ let l:input_close = (s:settings.use_xhtml ? "' />" : "'>")
+ let l:return_span = "<span class='"..a:class.."'>"
+ let l:return_span ..= l:input_open..l:common_attrs..repeat(a:char, a:len)..(a:char2)
+ let l:return_span ..= l:input_close
+ ENDLET
if s:settings.use_input_for_pc ==# 'fallback'
- let build_fun_lines += [
- \ ' let l:gen_content_link ='.
- \ ' "<a href=''#'' class=''FoldColumn'' onclick=''".a:click."'' data-FoldColumn-content=''".'.
- \ ' repeat(a:char, a:len).a:char2.repeat('' '', a:numfill).'.
- \ ' "''></a>"'
- \ ]
+ call add(s:build_fun_lines, [])
+ let s:build_fun_lines[-1] =<< trim ENDLET
+ let l:return_span ..= "<a href='#' class='FoldColumn' onclick='"..a:click.."'"
+ let l:return_span ..= " data-FoldColumn-content='"
+ let l:return_span ..= repeat(a:char, a:len)..a:char2..repeat(' ', a:numfill)
+ let l:return_span ..= "'></a>"
+ ENDLET
endif
- let build_fun_lines += [
- \ ' return "<span class=''".a:class."''>".'.
- \ ' l:input_open.l:common_attrs.repeat(a:char, a:len).(a:char2).'.
- \ ' l:input_close.'.
- \ (s:settings.use_input_for_pc ==# 'fallback' ? 'l:gen_content_link.' : "").
- \ ' "</span>"',
- \ 'endfun'
- \ ]
+ call add(s:build_fun_lines, [])
+ let s:build_fun_lines[-1] =<< trim ENDLET
+ let l:return_span ..= "</span>"
+ return l:return_span
+ endfun
+ ENDLET
" create the function we built line by line above
- exec join(build_fun_lines, "\n")
+ exec join(flatten(s:build_fun_lines), "\n")
function! s:FoldColumn_fill()
return s:FoldColumn_build(' ', s:foldcolumn, 0, '', 'FoldColumn', '')
@@ -592,8 +632,8 @@ else
" For normal fold columns, simply space-pad to the desired width (note that
" the FoldColumn definition includes a whitespace:pre rule)
function! s:FoldColumn_build(char, len, numfill, char2, class, click)
- return "<a href='#' class='".a:class."' onclick='".a:click."'>".
- \ repeat(a:char, a:len).a:char2.repeat(' ', a:numfill).
+ return "<a href='#' class='"..a:class.."' onclick='"..a:click.."'>".
+ \ repeat(a:char, a:len)..a:char2..repeat(' ', a:numfill).
\ "</a>"
endfun
function! s:FoldColumn_fill()
@@ -625,29 +665,30 @@ endif
" Return CSS style describing given highlight id (can be empty)
function! s:CSS1(id)
let a = ""
- if synIDattr(a:id, "inverse")
+ let translated_ID = synIDtrans(a:id)
+ if synIDattr(translated_ID, "inverse")
" For inverse, we always must set both colors (and exchange them)
- let x = s:HtmlColor(synIDattr(a:id, "bg#", s:whatterm))
- let a = a . "color: " . ( x != "" ? x : s:bgc ) . "; "
- let x = s:HtmlColor(synIDattr(a:id, "fg#", s:whatterm))
- let a = a . "background-color: " . ( x != "" ? x : s:fgc ) . "; "
+ let x = s:HtmlColor(synIDattr(translated_ID, "bg#", s:whatterm))
+ let a = a .. "color: " .. ( x != "" ? x : s:bgc ) .. "; "
+ let x = s:HtmlColor(synIDattr(translated_ID, "fg#", s:whatterm))
+ let a = a .. "background-color: " .. ( x != "" ? x : s:fgc ) .. "; "
else
- let x = s:HtmlColor(synIDattr(a:id, "fg#", s:whatterm))
- if x != "" | let a = a . "color: " . x . "; " | endif
- let x = s:HtmlColor(synIDattr(a:id, "bg#", s:whatterm))
+ let x = s:HtmlColor(synIDattr(translated_ID, "fg#", s:whatterm))
+ if x != "" | let a = a .. "color: " .. x .. "; " | endif
+ let x = s:HtmlColor(synIDattr(translated_ID, "bg#", s:whatterm))
if x != ""
- let a = a . "background-color: " . x . "; "
+ let a = a .. "background-color: " .. x .. "; "
" stupid hack because almost every browser seems to have at least one font
" which shows 1px gaps between lines which have background
- let a = a . "padding-bottom: 1px; "
- elseif (a:id == s:FOLDED_ID || a:id == s:LINENR_ID || a:id == s:FOLD_C_ID) && !empty(s:settings.prevent_copy)
+ let a = a .. "padding-bottom: 1px; "
+ elseif (translated_ID == s:FOLDED_ID || translated_ID == s:LINENR_ID || translated_ID == s:FOLD_C_ID) && !empty(s:settings.prevent_copy)
" input elements default to a different color than the rest of the page
- let a = a . "background-color: " . s:bgc . "; "
+ let a = a .. "background-color: " .. s:bgc .. "; "
endif
endif
- if synIDattr(a:id, "bold") | let a = a . "font-weight: bold; " | endif
- if synIDattr(a:id, "italic") | let a = a . "font-style: italic; " | endif
- if synIDattr(a:id, "underline") | let a = a . "text-decoration: under