blob: c9dd2f7641de1f44d099329867001013bbca3264 [file] [log] [blame]
Bram Moolenaarb02cbe32010-07-11 22:38:52 +02001" Vim autoload file for the tohtml plugin.
Bram Moolenaar349b2fb2010-07-16 20:35:36 +02002" Maintainer: Ben Fritz <fritzophrenic@gmail.com>
Bram Moolenaar166af9b2010-11-16 20:34:40 +01003" Last Change: 2010 Oct 07
Bram Moolenaarb02cbe32010-07-11 22:38:52 +02004"
Bram Moolenaar349b2fb2010-07-16 20:35:36 +02005" Additional contributors:
6"
Bram Moolenaar7c86f4c2010-07-18 14:07:22 +02007" Original by Bram Moolenaar <Bram@vim.org>
8" Diff2HTML() added by Christian Brabandt <cb@256bit.org>
Bram Moolenaar349b2fb2010-07-16 20:35:36 +02009"
Bram Moolenaar7c86f4c2010-07-18 14:07:22 +020010" See Mercurial change logs for more!
11
Bram Moolenaar349b2fb2010-07-16 20:35:36 +020012" this file uses line continuations
13let s:cpo_sav = &cpo
14set cpo-=C
Bram Moolenaarb02cbe32010-07-11 22:38:52 +020015
Bram Moolenaar166af9b2010-11-16 20:34:40 +010016" Automatically find charsets from all encodings supported natively by Vim. With
17" the 8bit- and 2byte- prefixes, Vim can actually support more encodings than
18" this. Let the user specify these however since they won't be supported on
19" every system. TODO: how? g:html_charsets and g:html_encodings?
20"
21" Note, not all of Vim's supported encodings have a charset to use.
22"
23" Names in this list are from:
24" http://www.iana.org/assignments/character-sets
25" g:tohtml#encoding_to_charset: {{{
26let g:tohtml#encoding_to_charset = {
27 \ 'latin1' : 'ISO-8859-1',
28 \ 'iso-8859-2' : 'ISO-8859-2',
29 \ 'iso-8859-3' : 'ISO-8859-3',
30 \ 'iso-8859-4' : 'ISO-8859-4',
31 \ 'iso-8859-5' : 'ISO-8859-5',
32 \ 'iso-8859-6' : 'ISO-8859-6',
33 \ 'iso-8859-7' : 'ISO-8859-7',
34 \ 'iso-8859-8' : 'ISO-8859-8',
35 \ 'iso-8859-9' : 'ISO-8859-9',
36 \ 'iso-8859-10' : '',
37 \ 'iso-8859-13' : 'ISO-8859-13',
38 \ 'iso-8859-14' : '',
39 \ 'iso-8859-15' : 'ISO-8859-15',
40 \ 'koi8-r' : 'KOI8-R',
41 \ 'koi8-u' : 'KOI8-U',
42 \ 'macroman' : 'macintosh',
43 \ 'cp437' : '',
44 \ 'cp775' : '',
45 \ 'cp850' : '',
46 \ 'cp852' : '',
47 \ 'cp855' : '',
48 \ 'cp857' : '',
49 \ 'cp860' : '',
50 \ 'cp861' : '',
51 \ 'cp862' : '',
52 \ 'cp863' : '',
53 \ 'cp865' : '',
54 \ 'cp866' : 'IBM866',
55 \ 'cp869' : '',
56 \ 'cp874' : '',
57 \ 'cp1250' : 'windows-1250',
58 \ 'cp1251' : 'windows-1251',
59 \ 'cp1253' : 'windows-1253',
60 \ 'cp1254' : 'windows-1254',
61 \ 'cp1255' : 'windows-1255',
62 \ 'cp1256' : 'windows-1256',
63 \ 'cp1257' : 'windows-1257',
64 \ 'cp1258' : 'windows-1258',
65 \ 'euc-jp' : 'EUC-JP',
66 \ 'sjis' : 'Shift_JIS',
67 \ 'cp932' : 'Shift_JIS',
68 \ 'cp949' : '',
69 \ 'euc-kr' : 'EUC-KR',
70 \ 'cp936' : 'GBK',
71 \ 'euc-cn' : 'GB2312',
72 \ 'big5' : 'Big5',
73 \ 'cp950' : 'Big5',
74 \ 'utf-8' : 'UTF-8',
75 \ 'ucs-2' : 'UTF-8',
76 \ 'ucs-2le' : 'UTF-8',
77 \ 'utf-16' : 'UTF-8',
78 \ 'utf-16le' : 'UTF-8',
79 \ 'ucs-4' : 'UTF-8',
80 \ 'ucs-4le' : 'UTF-8',
81 \ }
82lockvar g:tohtml#encoding_to_charset
83" Notes:
84" 1. All UCS/UTF are converted to UTF-8 because it is much better supported
85" 2. Any blank spaces are there because Vim supports it but at least one major
86" web browser does not according to http://wiki.whatwg.org/wiki/Web_Encodings.
87" }}}
88
89" Only automatically find encodings supported natively by Vim, let the user
90" specify the encoding if it's not natively supported. This function is only
91" used when the user specifies the charset, they better know what they are
92" doing!
93"
94" Names in this list are from:
95" http://www.iana.org/assignments/character-sets
96" g:tohtml#charset_to_encoding: {{{
97let g:tohtml#charset_to_encoding = {
98 \ 'iso_8859-1:1987' : 'latin1',
99 \ 'iso-ir-100' : 'latin1',
100 \ 'iso_8859-1' : 'latin1',
101 \ 'iso-8859-1' : 'latin1',
102 \ 'latin1' : 'latin1',
103 \ 'l1' : 'latin1',
104 \ 'ibm819' : 'latin1',
105 \ 'cp819' : 'latin1',
106 \ 'csisolatin1' : 'latin1',
107 \ 'iso_8859-2:1987' : 'iso-8859-2',
108 \ 'iso-ir-101' : 'iso-8859-2',
109 \ 'iso_8859-2' : 'iso-8859-2',
110 \ 'iso-8859-2' : 'iso-8859-2',
111 \ 'latin2' : 'iso-8859-2',
112 \ 'l2' : 'iso-8859-2',
113 \ 'csisolatin2' : 'iso-8859-2',
114 \ 'iso_8859-3:1988' : 'iso-8859-3',
115 \ 'iso-ir-109' : 'iso-8859-3',
116 \ 'iso_8859-3' : 'iso-8859-3',
117 \ 'iso-8859-3' : 'iso-8859-3',
118 \ 'latin3' : 'iso-8859-3',
119 \ 'l3' : 'iso-8859-3',
120 \ 'csisolatin3' : 'iso-8859-3',
121 \ 'iso_8859-4:1988' : 'iso-8859-4',
122 \ 'iso-ir-110' : 'iso-8859-4',
123 \ 'iso_8859-4' : 'iso-8859-4',
124 \ 'iso-8859-4' : 'iso-8859-4',
125 \ 'latin4' : 'iso-8859-4',
126 \ 'l4' : 'iso-8859-4',
127 \ 'csisolatin4' : 'iso-8859-4',
128 \ 'iso_8859-5:1988' : 'iso-8859-5',
129 \ 'iso-ir-144' : 'iso-8859-5',
130 \ 'iso_8859-5' : 'iso-8859-5',
131 \ 'iso-8859-5' : 'iso-8859-5',
132 \ 'cyrillic' : 'iso-8859-5',
133 \ 'csisolatincyrillic' : 'iso-8859-5',
134 \ 'iso_8859-6:1987' : 'iso-8859-6',
135 \ 'iso-ir-127' : 'iso-8859-6',
136 \ 'iso_8859-6' : 'iso-8859-6',
137 \ 'iso-8859-6' : 'iso-8859-6',
138 \ 'ecma-114' : 'iso-8859-6',
139 \ 'asmo-708' : 'iso-8859-6',
140 \ 'arabic' : 'iso-8859-6',
141 \ 'csisolatinarabic' : 'iso-8859-6',
142 \ 'iso_8859-7:1987' : 'iso-8859-7',
143 \ 'iso-ir-126' : 'iso-8859-7',
144 \ 'iso_8859-7' : 'iso-8859-7',
145 \ 'iso-8859-7' : 'iso-8859-7',
146 \ 'elot_928' : 'iso-8859-7',
147 \ 'ecma-118' : 'iso-8859-7',
148 \ 'greek' : 'iso-8859-7',
149 \ 'greek8' : 'iso-8859-7',
150 \ 'csisolatingreek' : 'iso-8859-7',
151 \ 'iso_8859-8:1988' : 'iso-8859-8',
152 \ 'iso-ir-138' : 'iso-8859-8',
153 \ 'iso_8859-8' : 'iso-8859-8',
154 \ 'iso-8859-8' : 'iso-8859-8',
155 \ 'hebrew' : 'iso-8859-8',
156 \ 'csisolatinhebrew' : 'iso-8859-8',
157 \ 'iso_8859-9:1989' : 'iso-8859-9',
158 \ 'iso-ir-148' : 'iso-8859-9',
159 \ 'iso_8859-9' : 'iso-8859-9',
160 \ 'iso-8859-9' : 'iso-8859-9',
161 \ 'latin5' : 'iso-8859-9',
162 \ 'l5' : 'iso-8859-9',
163 \ 'csisolatin5' : 'iso-8859-9',
164 \ 'iso-8859-10' : 'iso-8859-10',
165 \ 'iso-ir-157' : 'iso-8859-10',
166 \ 'l6' : 'iso-8859-10',
167 \ 'iso_8859-10:1992' : 'iso-8859-10',
168 \ 'csisolatin6' : 'iso-8859-10',
169 \ 'latin6' : 'iso-8859-10',
170 \ 'iso-8859-13' : 'iso-8859-13',
171 \ 'iso-8859-14' : 'iso-8859-14',
172 \ 'iso-ir-199' : 'iso-8859-14',
173 \ 'iso_8859-14:1998' : 'iso-8859-14',
174 \ 'iso_8859-14' : 'iso-8859-14',
175 \ 'latin8' : 'iso-8859-14',
176 \ 'iso-celtic' : 'iso-8859-14',
177 \ 'l8' : 'iso-8859-14',
178 \ 'iso-8859-15' : 'iso-8859-15',
179 \ 'iso_8859-15' : 'iso-8859-15',
180 \ 'latin-9' : 'iso-8859-15',
181 \ 'koi8-r' : 'koi8-r',
182 \ 'cskoi8r' : 'koi8-r',
183 \ 'koi8-u' : 'koi8-u',
184 \ 'macintosh' : 'macroman',
185 \ 'mac' : 'macroman',
186 \ 'csmacintosh' : 'macroman',
187 \ 'ibm437' : 'cp437',
188 \ 'cp437' : 'cp437',
189 \ '437' : 'cp437',
190 \ 'cspc8codepage437' : 'cp437',
191 \ 'ibm775' : 'cp775',
192 \ 'cp775' : 'cp775',
193 \ 'cspc775baltic' : 'cp775',
194 \ 'ibm850' : 'cp850',
195 \ 'cp850' : 'cp850',
196 \ '850' : 'cp850',
197 \ 'cspc850multilingual' : 'cp850',
198 \ 'ibm852' : 'cp852',
199 \ 'cp852' : 'cp852',
200 \ '852' : 'cp852',
201 \ 'cspcp852' : 'cp852',
202 \ 'ibm855' : 'cp855',
203 \ 'cp855' : 'cp855',
204 \ '855' : 'cp855',
205 \ 'csibm855' : 'cp855',
206 \ 'ibm857' : 'cp857',
207 \ 'cp857' : 'cp857',
208 \ '857' : 'cp857',
209 \ 'csibm857' : 'cp857',
210 \ 'ibm860' : 'cp860',
211 \ 'cp860' : 'cp860',
212 \ '860' : 'cp860',
213 \ 'csibm860' : 'cp860',
214 \ 'ibm861' : 'cp861',
215 \ 'cp861' : 'cp861',
216 \ '861' : 'cp861',
217 \ 'cp-is' : 'cp861',
218 \ 'csibm861' : 'cp861',
219 \ 'ibm862' : 'cp862',
220 \ 'cp862' : 'cp862',
221 \ '862' : 'cp862',
222 \ 'cspc862latinhebrew' : 'cp862',
223 \ 'ibm863' : 'cp863',
224 \ 'cp863' : 'cp863',
225 \ '863' : 'cp863',
226 \ 'csibm863' : 'cp863',
227 \ 'ibm865' : 'cp865',
228 \ 'cp865' : 'cp865',
229 \ '865' : 'cp865',
230 \ 'csibm865' : 'cp865',
231 \ 'ibm866' : 'cp866',
232 \ 'cp866' : 'cp866',
233 \ '866' : 'cp866',
234 \ 'csibm866' : 'cp866',
235 \ 'ibm869' : 'cp869',
236 \ 'cp869' : 'cp869',
237 \ '869' : 'cp869',
238 \ 'cp-gr' : 'cp869',
239 \ 'csibm869' : 'cp869',
240 \ 'windows-1250' : 'cp1250',
241 \ 'windows-1251' : 'cp1251',
242 \ 'windows-1253' : 'cp1253',
243 \ 'windows-1254' : 'cp1254',
244 \ 'windows-1255' : 'cp1255',
245 \ 'windows-1256' : 'cp1256',
246 \ 'windows-1257' : 'cp1257',
247 \ 'windows-1258' : 'cp1258',
248 \ 'extended_unix_code_packed_format_for_japanese' : 'euc-jp',
249 \ 'cseucpkdfmtjapanese' : 'euc-jp',
250 \ 'euc-jp' : 'euc-jp',
251 \ 'shift_jis' : 'sjis',
252 \ 'ms_kanji' : 'sjis',
253 \ 'sjis' : 'sjis',
254 \ 'csshiftjis' : 'sjis',
255 \ 'ibm-thai' : 'cp874',
256 \ 'csibmthai' : 'cp874',
257 \ 'ks_c_5601-1987' : 'cp949',
258 \ 'iso-ir-149' : 'cp949',
259 \ 'ks_c_5601-1989' : 'cp949',
260 \ 'ksc_5601' : 'cp949',
261 \ 'korean' : 'cp949',
262 \ 'csksc56011987' : 'cp949',
263 \ 'euc-kr' : 'euc-kr',
264 \ 'cseuckr' : 'euc-kr',
265 \ 'gbk' : 'cp936',
266 \ 'cp936' : 'cp936',
267 \ 'ms936' : 'cp936',
268 \ 'windows-936' : 'cp936',
269 \ 'gb_2312-80' : 'euc-cn',
270 \ 'iso-ir-58' : 'euc-cn',
271 \ 'chinese' : 'euc-cn',
272 \ 'csiso58gb231280' : 'euc-cn',
273 \ 'big5' : 'big5',
274 \ 'csbig5' : 'big5',
275 \ 'utf-8' : 'utf-8',
276 \ 'iso-10646-ucs-2' : 'ucs-2',
277 \ 'csunicode' : 'ucs-2',
278 \ 'utf-16' : 'utf-16',
279 \ 'utf-16be' : 'utf-16',
280 \ 'utf-16le' : 'utf-16le',
281 \ 'utf-32' : 'ucs-4',
282 \ 'utf-32be' : 'ucs-4',
283 \ 'utf-32le' : 'ucs-4le',
284 \ 'iso-10646-ucs-4' : 'ucs-4',
285 \ 'csucs4' : 'ucs-4'
286 \ }
287lockvar g:tohtml#charset_to_encoding
288"}}}
289
290func! tohtml#Convert2HTML(line1, line2) "{{{
Bram Moolenaar076e8b22010-08-05 21:54:00 +0200291 let s:settings = tohtml#GetUserSettings()
Bram Moolenaar349b2fb2010-07-16 20:35:36 +0200292
Bram Moolenaar166af9b2010-11-16 20:34:40 +0100293 if !&diff || s:settings.diff_one_file "{{{
Bram Moolenaarb02cbe32010-07-11 22:38:52 +0200294 if a:line2 >= a:line1
295 let g:html_start_line = a:line1
296 let g:html_end_line = a:line2
297 else
298 let g:html_start_line = a:line2
299 let g:html_end_line = a:line1
300 endif
Bram Moolenaar166af9b2010-11-16 20:34:40 +0100301 runtime syntax/2html.vim "}}}
302 else "{{{
Bram Moolenaarb02cbe32010-07-11 22:38:52 +0200303 let win_list = []
304 let buf_list = []
Bram Moolenaar349b2fb2010-07-16 20:35:36 +0200305 windo | if &diff | call add(win_list, winbufnr(0)) | endif
Bram Moolenaar076e8b22010-08-05 21:54:00 +0200306 let s:settings.whole_filler = 1
Bram Moolenaar349b2fb2010-07-16 20:35:36 +0200307 let g:html_diff_win_num = 0
Bram Moolenaarb02cbe32010-07-11 22:38:52 +0200308 for window in win_list
Bram Moolenaar166af9b2010-11-16 20:34:40 +0100309 " switch to the next buffer to convert
Bram Moolenaarb02cbe32010-07-11 22:38:52 +0200310 exe ":" . bufwinnr(window) . "wincmd w"
Bram Moolenaar166af9b2010-11-16 20:34:40 +0100311
312 " figure out whether current charset and encoding will work, if not
313 " default to UTF-8
314 if !exists('g:html_use_encoding') &&
315 \ (&l:fileencoding!='' && &l:fileencoding!=s:settings.vim_encoding ||
316 \ &l:fileencoding=='' && &encoding!=s:settings.vim_encoding)
317 echohl WarningMsg
318 echomsg "TOhtml: mismatched file encodings in Diff buffers, using UTF-8"
319 echohl None
320 let s:settings.vim_encoding = 'utf-8'
321 let s:settings.encoding = 'UTF-8'
322 endif
323
324 " set up for diff-mode conversion
Bram Moolenaarb02cbe32010-07-11 22:38:52 +0200325 let g:html_start_line = 1
326 let g:html_end_line = line('$')
Bram Moolenaar349b2fb2010-07-16 20:35:36 +0200327 let g:html_diff_win_num += 1
Bram Moolenaar166af9b2010-11-16 20:34:40 +0100328
329 " convert this file
Bram Moolenaarb02cbe32010-07-11 22:38:52 +0200330 runtime syntax/2html.vim
Bram Moolenaar166af9b2010-11-16 20:34:40 +0100331
332 " remember the HTML buffer for later combination
Bram Moolenaarb02cbe32010-07-11 22:38:52 +0200333 call add(buf_list, bufnr('%'))
334 endfor
Bram Moolenaar349b2fb2010-07-16 20:35:36 +0200335 unlet g:html_diff_win_num
Bram Moolenaarb02cbe32010-07-11 22:38:52 +0200336 call tohtml#Diff2HTML(win_list, buf_list)
Bram Moolenaar166af9b2010-11-16 20:34:40 +0100337 endif "}}}
Bram Moolenaarb02cbe32010-07-11 22:38:52 +0200338
339 unlet g:html_start_line
340 unlet g:html_end_line
Bram Moolenaar076e8b22010-08-05 21:54:00 +0200341 unlet s:settings
Bram Moolenaar166af9b2010-11-16 20:34:40 +0100342endfunc "}}}
Bram Moolenaarb02cbe32010-07-11 22:38:52 +0200343
Bram Moolenaar166af9b2010-11-16 20:34:40 +0100344func! tohtml#Diff2HTML(win_list, buf_list) "{{{
Bram Moolenaarbebca9d2010-08-07 15:47:30 +0200345 let xml_line = ""
346 let tag_close = '>'
347
Bram Moolenaar8df7f882010-08-13 11:30:02 +0200348 let s:old_paste = &paste
349 set paste
350 let s:old_magic = &magic
351 set magic
352
Bram Moolenaarbebca9d2010-08-07 15:47:30 +0200353 if s:settings.use_xhtml
354 if s:settings.encoding != ""
355 let xml_line = "<?xml version=\"1.0\" encoding=\"" . s:settings.encoding . "\"?>"
356 else
357 let xml_line = "<?xml version=\"1.0\"?>"
358 endif
359 let tag_close = ' />'
360 endif
361
362 let style = [s:settings.use_xhtml ? "" : '-->']
Bram Moolenaar8ada2cc2010-07-29 20:43:36 +0200363 let body_line = ''
364
Bram Moolenaarb02cbe32010-07-11 22:38:52 +0200365 let html = []
Bram Moolenaarbebca9d2010-08-07 15:47:30 +0200366 if s:settings.use_xhtml
367 call add(html, xml_line)
368 endif
369 if s:settings.use_xhtml
370 call add(html, "<!DOCTYPE html PUBLIC \"-//W3C//DTD XHTML 1.0 Transitional//EN\" \"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd\">")
371 call add(html, '<html xmlns="http://www.w3.org/1999/xhtml">')
372 elseif s:settings.use_css && !s:settings.no_pre
373 call add(html, "<!DOCTYPE HTML PUBLIC \"-//W3C//DTD HTML 4.01//EN\" \"http://www.w3.org/TR/html4/strict.dtd\">")
374 call add(html, '<html>')
375 else
376 call add(html, '<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"')
377 call add(html, ' "http://www.w3.org/TR/html4/loose.dtd">')
378 call add(html, '<html>')
379 endif
Bram Moolenaarb02cbe32010-07-11 22:38:52 +0200380 call add(html, '<head>')
Bram Moolenaarbebca9d2010-08-07 15:47:30 +0200381
382 " include encoding as close to the top as possible, but only if not already
Bram Moolenaar166af9b2010-11-16 20:34:40 +0100383 " contained in XML information
Bram Moolenaarbebca9d2010-08-07 15:47:30 +0200384 if s:settings.encoding != "" && !s:settings.use_xhtml
385 call add(html, "<meta http-equiv=\"content-type\" content=\"text/html; charset=" . s:settings.encoding . '"' . tag_close)
386 endif
387
Bram Moolenaarb02cbe32010-07-11 22:38:52 +0200388 call add(html, '<title>diff</title>')
Bram Moolenaarbebca9d2010-08-07 15:47:30 +0200389 call add(html, '<meta name="Generator" content="Vim/'.v:version/100.'.'.v:version%100.'"'.tag_close)
390 call add(html, '<meta name="plugin-version" content="'.g:loaded_2html_plugin.'"'.tag_close)
391 call add(html, '<meta name="settings" content="'.
392 \ join(filter(keys(s:settings),'s:settings[v:val]'),',').
393 \ '"'.tag_close)
Bram Moolenaar349b2fb2010-07-16 20:35:36 +0200394
Bram Moolenaarb02cbe32010-07-11 22:38:52 +0200395 call add(html, '</head>')
Bram Moolenaar8ada2cc2010-07-29 20:43:36 +0200396 let body_line_num = len(html)
Bram Moolenaarb02cbe32010-07-11 22:38:52 +0200397 call add(html, '<body>')
398 call add(html, '<table border="1" width="100%">')
Bram Moolenaar349b2fb2010-07-16 20:35:36 +0200399
Bram Moolenaarb02cbe32010-07-11 22:38:52 +0200400 call add(html, '<tr>')
401 for buf in a:win_list
402 call add(html, '<th>'.bufname(buf).'</th>')
403 endfor
404 call add(html, '</tr><tr>')
405
Bram Moolenaar8ada2cc2010-07-29 20:43:36 +0200406 let diff_style_start = 0
407 let insert_index = 0
408
Bram Moolenaarb02cbe32010-07-11 22:38:52 +0200409 for buf in a:buf_list
410 let temp = []
411 exe bufwinnr(buf) . 'wincmd w'
412
Bram Moolenaar349b2fb2010-07-16 20:35:36 +0200413 " If text is folded because of user foldmethod settings, etc. we don't want
414 " to act on everything in a fold by mistake.
415 setlocal nofoldenable
416
Bram Moolenaar8ada2cc2010-07-29 20:43:36 +0200417 " When not using CSS or when using xhtml, the <body> line can be important.
418 " Assume it will be the same for all buffers and grab it from the first
419 " buffer. Similarly, need to grab the body end line as well.
420 if body_line == ''
421 1
422 call search('<body')
423 let body_line = getline('.')
424 $
425 call search('</body>', 'b')
426 let s:body_end_line = getline('.')
427 endif
428
Bram Moolenaar166af9b2010-11-16 20:34:40 +0100429 " Grab the style information. Some of this will be duplicated so only insert
430 " it if it's not already there. {{{
Bram Moolenaarb02cbe32010-07-11 22:38:52 +0200431 1
432 let style_start = search('^<style type="text/css">')
433 1
434 let style_end = search('^</style>')
435 if style_start > 0 && style_end > 0
Bram Moolenaar8ada2cc2010-07-29 20:43:36 +0200436 let buf_styles = getline(style_start + 1, style_end - 1)
437 for a_style in buf_styles
438 if index(style, a_style) == -1
439 if diff_style_start == 0
440 if a_style =~ '\<Diff\(Change\|Text\|Add\|Delete\)'
441 let diff_style_start = len(style)-1
442 endif
443 endif
444 call insert(style, a_style, insert_index)
445 let insert_index += 1
446 endif
447 endfor
Bram Moolenaar166af9b2010-11-16 20:34:40 +0100448 endif " }}}
Bram Moolenaar8ada2cc2010-07-29 20:43:36 +0200449
Bram Moolenaar166af9b2010-11-16 20:34:40 +0100450 " everything new will get added before the diff styles so diff highlight
451 " properly overrides normal highlight
Bram Moolenaar8ada2cc2010-07-29 20:43:36 +0200452 if diff_style_start != 0
453 let insert_index = diff_style_start
Bram Moolenaarb02cbe32010-07-11 22:38:52 +0200454 endif
455
456 " Delete those parts that are not needed so
457 " we can include the rest into the resulting table
458 1,/^<body/d_
459 $
460 ?</body>?,$d_
461 let temp = getline(1,'$')
462 " undo deletion of start and end part
463 " so we can later save the file as valid html
Bram Moolenaar349b2fb2010-07-16 20:35:36 +0200464 " TODO: restore using grabbed lines if undolevel is 1?
Bram Moolenaarb02cbe32010-07-11 22:38:52 +0200465 normal 2u
Bram Moolenaarbebca9d2010-08-07 15:47:30 +0200466 if s:settings.use_css
467 call add(html, '<td valign="top"><div>')
468 elseif s:settings.use_xhtml
469 call add(html, '<td nowrap="nowrap" valign="top"><div>')
470 else
471 call add(html, '<td nowrap valign="top"><div>')
472 endif
Bram Moolenaarb02cbe32010-07-11 22:38:52 +0200473 let html += temp
Bram Moolenaar349b2fb2010-07-16 20:35:36 +0200474 call add(html, '</div></td>')
Bram Moolenaarb02cbe32010-07-11 22:38:52 +0200475
476 " Close this buffer
Bram Moolenaar349b2fb2010-07-16 20:35:36 +0200477 " TODO: the comment above says we're going to allow saving the file
478 " later...but here we discard it?
Bram Moolenaarb02cbe32010-07-11 22:38:52 +0200479 quit!
480 endfor
481
Bram Moolenaar8ada2cc2010-07-29 20:43:36 +0200482 let html[body_line_num] = body_line
483
Bram Moolenaarb02cbe32010-07-11 22:38:52 +0200484 call add(html, '</tr>')
485 call add(html, '</table>')
Bram Moolenaar8ada2cc2010-07-29 20:43:36 +0200486 call add(html, s:body_end_line)
Bram Moolenaarb02cbe32010-07-11 22:38:52 +0200487 call add(html, '</html>')
488
489 let i = 1
Bram Moolenaarbebca9d2010-08-07 15:47:30 +0200490 let name = "Diff" . (s:settings.use_xhtml ? ".xhtml" : ".html")
Bram Moolenaar349b2fb2010-07-16 20:35:36 +0200491 " Find an unused file name if current file name is already in use
Bram Moolenaarb02cbe32010-07-11 22:38:52 +0200492 while filereadable(name)
Bram Moolenaarbebca9d2010-08-07 15:47:30 +0200493 let name = substitute(name, '\d*\.x\?html$', '', '') . i . '.' . fnamemodify(copy(name), ":t:e")
Bram Moolenaarb02cbe32010-07-11 22:38:52 +0200494 let i += 1
Bram Moolenaar349b2fb2010-07-16 20:35:36 +0200495 endwhile
496 exe "topleft new " . name
497 setlocal modifiable
498
499 " just in case some user autocmd creates content in the new buffer, make sure
500 " it is empty before proceeding
501 %d
Bram Moolenaar166af9b2010-11-16 20:34:40 +0100502
503 " set the fileencoding to match the charset we'll be using
504 let &l:fileencoding=s:settings.vim_encoding
505
506 " According to http://www.w3.org/TR/html4/charset.html#doc-char-set, the byte
507 " order mark is highly recommend on the web when using multibyte encodings. But,
508 " it is not a good idea to include it on UTF-8 files. Otherwise, let Vim
509 " determine when it is actually inserted.
510 if s:settings.vim_encoding == 'utf-8'
511 setlocal nobomb
512 else
513 setlocal bomb
514 endif
515
Bram Moolenaarb02cbe32010-07-11 22:38:52 +0200516 call append(0, html)
Bram Moolenaar349b2fb2010-07-16 20:35:36 +0200517
Bram Moolenaarb02cbe32010-07-11 22:38:52 +0200518 if len(style) > 0
519 1
Bram Moolenaar349b2fb2010-07-16 20:35:36 +0200520 let style_start = search('^</head>')-1
521
522 " Insert javascript to toggle matching folds open and closed in all windows,
Bram Moolenaar166af9b2010-11-16 20:34:40 +0100523 " if dynamic folding is active. {{{
Bram Moolenaar076e8b22010-08-05 21:54:00 +0200524 if s:settings.dynamic_folds
Bram Moolenaar349b2fb2010-07-16 20:35:36 +0200525 call append(style_start, [
Bram Moolenaar7c86f4c2010-07-18 14:07:22 +0200526 \ "<script type='text/javascript'>",
Bram Moolenaarbebca9d2010-08-07 15:47:30 +0200527 \ s:settings.use_xhtml ? '//<![CDATA[' : " <!--",
Bram Moolenaar7c86f4c2010-07-18 14:07:22 +0200528 \ " function toggleFold(objID)",
529 \ " {",
530 \ " for (win_num = 1; win_num <= ".len(a:buf_list)."; win_num++)",
531 \ " {",
532 \ " var fold;",
533 \ ' fold = document.getElementById("win"+win_num+objID);',
534 \ " if(fold.className == 'closed-fold')",
535 \ " {",
536 \ " fold.className = 'open-fold';",
537 \ " }",
538 \ " else if (fold.className == 'open-fold')",
539 \ " {",
540 \ " fold.className = 'closed-fold';",
541 \ " }",
542 \ " }",
543 \ " }",
Bram Moolenaarbebca9d2010-08-07 15:47:30 +0200544 \ s:settings.use_xhtml ? '//]]>' : " -->",
Bram Moolenaar7c86f4c2010-07-18 14:07:22 +0200545 \ "</script>"
546 \ ])
Bram Moolenaar166af9b2010-11-16 20:34:40 +0100547 endif "}}}
Bram Moolenaar349b2fb2010-07-16 20:35:36 +0200548
549 " Insert styles from all the generated html documents and additional styles
550 " for the table-based layout of the side-by-side diff. The diff should take
551 " up the full browser window (but not more), and be static in size,
552 " horizontally scrollable when the lines are too long. Otherwise, the diff
Bram Moolenaar166af9b2010-11-16 20:34:40 +0100553 " is pretty useless for really long lines. {{{
Bram Moolenaar076e8b22010-08-05 21:54:00 +0200554 if s:settings.use_css
Bram Moolenaarbebca9d2010-08-07 15:47:30 +0200555 call append(style_start,
556 \ ['<style type="text/css">']+
557 \ style+
558 \ [ s:settings.use_xhtml ? '' : '<!--',
559 \ 'table { table-layout: fixed; }',
560 \ 'html, body, table, tbody { width: 100%; margin: 0; padding: 0; }',
561 \ 'th, td { width: '.printf("%.1f",100.0/len(a:win_list)).'%; }',
562 \ 'td div { overflow: auto; }',
563 \ s:settings.use_xhtml ? '' : '-->',
564 \ '</style>'
Bram Moolenaar166af9b2010-11-16 20:34:40 +0100565 \])
566 endif "}}}
Bram Moolenaarb02cbe32010-07-11 22:38:52 +0200567 endif
Bram Moolenaar8df7f882010-08-13 11:30:02 +0200568
569 let &paste = s:old_paste
570 let &magic = s:old_magic
Bram Moolenaar166af9b2010-11-16 20:34:40 +0100571endfunc "}}}
Bram Moolenaar349b2fb2010-07-16 20:35:36 +0200572
Bram Moolenaar076e8b22010-08-05 21:54:00 +0200573" Gets a single user option and sets it in the passed-in Dict, or gives it the
574" default value if the option doesn't actually exist.
Bram Moolenaar166af9b2010-11-16 20:34:40 +0100575func! tohtml#GetOption(settings, option, default) "{{{
Bram Moolenaar076e8b22010-08-05 21:54:00 +0200576 if exists('g:html_'.a:option)
577 let a:settings[a:option] = g:html_{a:option}
578 else
579 let a:settings[a:option] = a:default
Bram Moolenaar349b2fb2010-07-16 20:35:36 +0200580 endif
Bram Moolenaar166af9b2010-11-16 20:34:40 +0100581endfunc "}}}
Bram Moolenaar349b2fb2010-07-16 20:35:36 +0200582
Bram Moolenaar076e8b22010-08-05 21:54:00 +0200583" returns a Dict containing the values of all user options for 2html, including
584" default values for those not given an explicit value by the user. Discards the
585" html_ prefix of the option for nicer looking code.
Bram Moolenaar166af9b2010-11-16 20:34:40 +0100586func! tohtml#GetUserSettings() "{{{
Bram Moolenaar076e8b22010-08-05 21:54:00 +0200587 if exists('s:settings')
588 " just restore the known options if we've already retrieved them
589 return s:settings
Bram Moolenaar349b2fb2010-07-16 20:35:36 +0200590 else
Bram Moolenaar076e8b22010-08-05 21:54:00 +0200591 " otherwise figure out which options are set
592 let user_settings = {}
593
594 " Define the correct option if the old option name exists and we haven't
595 " already defined the correct one. Maybe I'll put out a warnig message about
596 " this sometime and remove the old option entirely at some even later time,
597 " but for now just silently accept the old option.
598 if exists('g:use_xhtml') && !exists("g:html_use_xhtml")
599 let g:html_use_xhtml = g:use_xhtml
600 endif
601
Bram Moolenaar166af9b2010-11-16 20:34:40 +0100602 " get current option settings with appropriate defaults {{{
Bram Moolenaar076e8b22010-08-05 21:54:00 +0200603 call tohtml#GetOption(user_settings, 'no_progress', !has("statusline") )
604 call tohtml#GetOption(user_settings, 'diff_one_file', 0 )
605 call tohtml#GetOption(user_settings, 'number_lines', &number )
606 call tohtml#GetOption(user_settings, 'use_css', 1 )
607 call tohtml#GetOption(user_settings, 'ignore_conceal', 0 )
608 call tohtml#GetOption(user_settings, 'ignore_folding', 0 )
609 call tohtml#GetOption(user_settings, 'dynamic_folds', 0 )
610 call tohtml#GetOption(user_settings, 'no_foldcolumn', 0 )
611 call tohtml#GetOption(user_settings, 'hover_unfold', 0 )
612 call tohtml#GetOption(user_settings, 'no_pre', 0 )
613 call tohtml#GetOption(user_settings, 'whole_filler', 0 )
614 call tohtml#GetOption(user_settings, 'use_xhtml', 0 )
Bram Moolenaar166af9b2010-11-16 20:34:40 +0100615 " }}}
Bram Moolenaar076e8b22010-08-05 21:54:00 +0200616
Bram Moolenaar166af9b2010-11-16 20:34:40 +0100617 " override those settings that need it {{{
Bram Moolenaar076e8b22010-08-05 21:54:00 +0200618
Bram Moolenaarbebca9d2010-08-07 15:47:30 +0200619 " hover opening implies dynamic folding
620 if user_settings.hover_unfold
621 let user_settings.dynamic_folds = 1
622 endif
623
Bram Moolenaar076e8b22010-08-05 21:54:00 +0200624 " ignore folding overrides dynamic folding
625 if user_settings.ignore_folding && user_settings.dynamic_folds
626 let user_settings.dynamic_folds = 0
627 let user_settings.hover_unfold = 0
628 endif
629
Bram Moolenaar076e8b22010-08-05 21:54:00 +0200630 " dynamic folding with no foldcolumn implies hover opens
631 if user_settings.dynamic_folds && user_settings.no_foldcolumn
632 let user_settings.hover_unfold = 1
633 endif
634
635 " dynamic folding implies css
636 if user_settings.dynamic_folds
637 let user_settings.use_css = 1
638 endif
639
640 " if we're not using CSS we cannot use a pre section because <font> tags
641 " aren't allowed inside a <pre> block
642 if !user_settings.use_css
643 let user_settings.no_pre = 1
Bram Moolenaar166af9b2010-11-16 20:34:40 +0100644 endif "}}}
Bram Moolenaar076e8b22010-08-05 21:54:00 +0200645
Bram Moolenaar166af9b2010-11-16 20:34:40 +0100646 if exists("g:html_use_encoding") "{{{
647 " user specified the desired MIME charset, figure out proper
648 " 'fileencoding' from it or warn the user if we cannot
Bram Moolenaarbebca9d2010-08-07 15:47:30 +0200649 let user_settings.encoding = g:html_use_encoding
Bram Moolenaar166af9b2010-11-16 20:34:40 +0100650 let user_settings.vim_encoding = tohtml#EncodingFromCharset(g:html_use_encoding)
651 if user_settings.vim_encoding == ''
652 echohl WarningMsg
653 echomsg "TOhtml: file encoding for"
654 \ g:html_use_encoding
655 \ "unknown, please set 'fileencoding'"
656 echohl None
657 endif
Bram Moolenaarbebca9d2010-08-07 15:47:30 +0200658 else
Bram Moolenaar166af9b2010-11-16 20:34:40 +0100659 " Figure out proper MIME charset from 'fileencoding' if possible
660 if &l:fileencoding != ''
661 let user_settings.vim_encoding = &l:fileencoding
662 call tohtml#CharsetFromEncoding(user_settings)
Bram Moolenaarbebca9d2010-08-07 15:47:30 +0200663 endif
Bram Moolenaar166af9b2010-11-16 20:34:40 +0100664
665 " else from 'encoding' if possible
666 if &l:fileencoding == '' || user_settings.encoding == ''
667 let user_settings.vim_encoding = &encoding
668 call tohtml#CharsetFromEncoding(user_settings)
669 endif
670
671 " else default to UTF-8 and warn user
672 if user_settings.encoding == ''
673 let user_settings.vim_encoding = 'utf-8'
Bram Moolenaarbebca9d2010-08-07 15:47:30 +0200674 let user_settings.encoding = 'UTF-8'
Bram Moolenaar166af9b2010-11-16 20:34:40 +0100675 echohl WarningMsg
676 echomsg "TOhtml: couldn't determine MIME charset, using UTF-8"
677 echohl None
Bram Moolenaarbebca9d2010-08-07 15:47:30 +0200678 endif
Bram Moolenaar166af9b2010-11-16 20:34:40 +0100679 endif "}}}
Bram Moolenaarbebca9d2010-08-07 15:47:30 +0200680
681 " TODO: font
682
Bram Moolenaar076e8b22010-08-05 21:54:00 +0200683 return user_settings
Bram Moolenaar349b2fb2010-07-16 20:35:36 +0200684 endif
Bram Moolenaar166af9b2010-11-16 20:34:40 +0100685endfunc "}}}
686
687" get the proper HTML charset name from a Vim encoding option.
688function! tohtml#CharsetFromEncoding(settings) "{{{
689 let l:vim_encoding = a:settings.vim_encoding
690 if exists('g:html_charset_override') && has_key(g:html_charset_override, l:vim_encoding)
691 let a:settings.encoding = g:html_charset_override[l:vim_encoding]
692 else
693 if l:vim_encoding =~ '^8bit\|^2byte'
694 " 8bit- and 2byte- prefixes are to indicate encodings available on the
695 " system that Vim will convert with iconv(), look up just the encoding name,
696 " not Vim's prefix.
697 let l:vim_encoding = substitute(l:vim_encoding, '^8bit-\|^2byte-', '', '')
698 endif
699 if has_key(g:tohtml#encoding_to_charset, l:vim_encoding)
700 let a:settings.encoding = g:tohtml#encoding_to_charset[l:vim_encoding]
701 else
702 let a:settings.encoding = ""
703 endif
704 endif
705 if a:settings.encoding != ""
706 let l:vim_encoding = tohtml#EncodingFromCharset(a:settings.encoding)
707 if l:vim_encoding != ""
708 " if the Vim encoding to HTML encoding conversion is set up (by default or
709 " by the user) to convert to a different encoding, we need to also change
710 " the Vim encoding of the new buffer
711 let a:settings.vim_encoding = l:vim_encoding
712 endif
713 endif
714endfun "}}}
715
716" Get the proper Vim encoding option setting from an HTML charset name.
717function! tohtml#EncodingFromCharset(encoding) "{{{
718 if exists('g:html_encoding_override') && has_key(g:html_encoding_override, a:encoding)
719 return g:html_encoding_override[a:encoding]
720 elseif has_key(g:tohtml#charset_to_encoding, tolower(a:encoding))
721 return g:tohtml#charset_to_encoding[tolower(a:encoding)]
722 else
723 return ""
724 endif
725endfun "}}}
Bram Moolenaar349b2fb2010-07-16 20:35:36 +0200726
727let &cpo = s:cpo_sav
728unlet s:cpo_sav
729
730" Make sure any patches will probably use consistent indent
Bram Moolenaar166af9b2010-11-16 20:34:40 +0100731" vim: ts=8 sw=2 sts=2 noet fdm=marker