blob: ad33cee1daf3206f43dacf04acfb54980712f81e [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 Moolenaar8e5af3e2011-04-28 19:02:44 +02003" Last Change: 2011 Apr 05
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
Bram Moolenaar8e5af3e2011-04-28 19:02:44 +020019" every system.
Bram Moolenaar166af9b2010-11-16 20:34:40 +010020"
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') &&
Bram Moolenaar8e5af3e2011-04-28 19:02:44 +0200315 \ (((&l:fileencoding=='' || (&l:buftype!='' && &l:buftype!=?'help'))
316 \ && &encoding!=?s:settings.vim_encoding)
317 \ || &l:fileencoding!='' && &l:fileencoding!=?s:settings.vim_encoding)
Bram Moolenaar166af9b2010-11-16 20:34:40 +0100318 echohl WarningMsg
319 echomsg "TOhtml: mismatched file encodings in Diff buffers, using UTF-8"
320 echohl None
321 let s:settings.vim_encoding = 'utf-8'
322 let s:settings.encoding = 'UTF-8'
323 endif
324
325 " set up for diff-mode conversion
Bram Moolenaarb02cbe32010-07-11 22:38:52 +0200326 let g:html_start_line = 1
327 let g:html_end_line = line('$')
Bram Moolenaar349b2fb2010-07-16 20:35:36 +0200328 let g:html_diff_win_num += 1
Bram Moolenaar166af9b2010-11-16 20:34:40 +0100329
330 " convert this file
Bram Moolenaarb02cbe32010-07-11 22:38:52 +0200331 runtime syntax/2html.vim
Bram Moolenaar166af9b2010-11-16 20:34:40 +0100332
333 " remember the HTML buffer for later combination
Bram Moolenaarb02cbe32010-07-11 22:38:52 +0200334 call add(buf_list, bufnr('%'))
335 endfor
Bram Moolenaar349b2fb2010-07-16 20:35:36 +0200336 unlet g:html_diff_win_num
Bram Moolenaarb02cbe32010-07-11 22:38:52 +0200337 call tohtml#Diff2HTML(win_list, buf_list)
Bram Moolenaar166af9b2010-11-16 20:34:40 +0100338 endif "}}}
Bram Moolenaarb02cbe32010-07-11 22:38:52 +0200339
340 unlet g:html_start_line
341 unlet g:html_end_line
Bram Moolenaar076e8b22010-08-05 21:54:00 +0200342 unlet s:settings
Bram Moolenaar166af9b2010-11-16 20:34:40 +0100343endfunc "}}}
Bram Moolenaarb02cbe32010-07-11 22:38:52 +0200344
Bram Moolenaar166af9b2010-11-16 20:34:40 +0100345func! tohtml#Diff2HTML(win_list, buf_list) "{{{
Bram Moolenaarbebca9d2010-08-07 15:47:30 +0200346 let xml_line = ""
347 let tag_close = '>'
348
Bram Moolenaar8df7f882010-08-13 11:30:02 +0200349 let s:old_paste = &paste
350 set paste
351 let s:old_magic = &magic
352 set magic
353
Bram Moolenaarbebca9d2010-08-07 15:47:30 +0200354 if s:settings.use_xhtml
355 if s:settings.encoding != ""
356 let xml_line = "<?xml version=\"1.0\" encoding=\"" . s:settings.encoding . "\"?>"
357 else
358 let xml_line = "<?xml version=\"1.0\"?>"
359 endif
360 let tag_close = ' />'
361 endif
362
363 let style = [s:settings.use_xhtml ? "" : '-->']
Bram Moolenaar8ada2cc2010-07-29 20:43:36 +0200364 let body_line = ''
365
Bram Moolenaarb02cbe32010-07-11 22:38:52 +0200366 let html = []
Bram Moolenaarbebca9d2010-08-07 15:47:30 +0200367 if s:settings.use_xhtml
368 call add(html, xml_line)
369 endif
370 if s:settings.use_xhtml
371 call add(html, "<!DOCTYPE html PUBLIC \"-//W3C//DTD XHTML 1.0 Transitional//EN\" \"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd\">")
372 call add(html, '<html xmlns="http://www.w3.org/1999/xhtml">')
373 elseif s:settings.use_css && !s:settings.no_pre
374 call add(html, "<!DOCTYPE HTML PUBLIC \"-//W3C//DTD HTML 4.01//EN\" \"http://www.w3.org/TR/html4/strict.dtd\">")
375 call add(html, '<html>')
376 else
377 call add(html, '<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"')
378 call add(html, ' "http://www.w3.org/TR/html4/loose.dtd">')
379 call add(html, '<html>')
380 endif
Bram Moolenaarb02cbe32010-07-11 22:38:52 +0200381 call add(html, '<head>')
Bram Moolenaarbebca9d2010-08-07 15:47:30 +0200382
383 " include encoding as close to the top as possible, but only if not already
Bram Moolenaar166af9b2010-11-16 20:34:40 +0100384 " contained in XML information
Bram Moolenaarbebca9d2010-08-07 15:47:30 +0200385 if s:settings.encoding != "" && !s:settings.use_xhtml
386 call add(html, "<meta http-equiv=\"content-type\" content=\"text/html; charset=" . s:settings.encoding . '"' . tag_close)
387 endif
388
Bram Moolenaarb02cbe32010-07-11 22:38:52 +0200389 call add(html, '<title>diff</title>')
Bram Moolenaarbebca9d2010-08-07 15:47:30 +0200390 call add(html, '<meta name="Generator" content="Vim/'.v:version/100.'.'.v:version%100.'"'.tag_close)
391 call add(html, '<meta name="plugin-version" content="'.g:loaded_2html_plugin.'"'.tag_close)
392 call add(html, '<meta name="settings" content="'.
393 \ join(filter(keys(s:settings),'s:settings[v:val]'),',').
394 \ '"'.tag_close)
Bram Moolenaar349b2fb2010-07-16 20:35:36 +0200395
Bram Moolenaarb02cbe32010-07-11 22:38:52 +0200396 call add(html, '</head>')
Bram Moolenaar8ada2cc2010-07-29 20:43:36 +0200397 let body_line_num = len(html)
Bram Moolenaarb02cbe32010-07-11 22:38:52 +0200398 call add(html, '<body>')
399 call add(html, '<table border="1" width="100%">')
Bram Moolenaar349b2fb2010-07-16 20:35:36 +0200400
Bram Moolenaarb02cbe32010-07-11 22:38:52 +0200401 call add(html, '<tr>')
402 for buf in a:win_list
403 call add(html, '<th>'.bufname(buf).'</th>')
404 endfor
405 call add(html, '</tr><tr>')
406
Bram Moolenaar8ada2cc2010-07-29 20:43:36 +0200407 let diff_style_start = 0
408 let insert_index = 0
409
Bram Moolenaarb02cbe32010-07-11 22:38:52 +0200410 for buf in a:buf_list
411 let temp = []
412 exe bufwinnr(buf) . 'wincmd w'
413
Bram Moolenaar349b2fb2010-07-16 20:35:36 +0200414 " If text is folded because of user foldmethod settings, etc. we don't want
415 " to act on everything in a fold by mistake.
416 setlocal nofoldenable
417
Bram Moolenaar8ada2cc2010-07-29 20:43:36 +0200418 " When not using CSS or when using xhtml, the <body> line can be important.
419 " Assume it will be the same for all buffers and grab it from the first
420 " buffer. Similarly, need to grab the body end line as well.
421 if body_line == ''
422 1
423 call search('<body')
424 let body_line = getline('.')
425 $
426 call search('</body>', 'b')
427 let s:body_end_line = getline('.')
428 endif
429
Bram Moolenaar166af9b2010-11-16 20:34:40 +0100430 " Grab the style information. Some of this will be duplicated so only insert
431 " it if it's not already there. {{{
Bram Moolenaarb02cbe32010-07-11 22:38:52 +0200432 1
433 let style_start = search('^<style type="text/css">')
434 1
435 let style_end = search('^</style>')
436 if style_start > 0 && style_end > 0
Bram Moolenaar8ada2cc2010-07-29 20:43:36 +0200437 let buf_styles = getline(style_start + 1, style_end - 1)
438 for a_style in buf_styles
439 if index(style, a_style) == -1
440 if diff_style_start == 0
441 if a_style =~ '\<Diff\(Change\|Text\|Add\|Delete\)'
442 let diff_style_start = len(style)-1
443 endif
444 endif
445 call insert(style, a_style, insert_index)
446 let insert_index += 1
447 endif
448 endfor
Bram Moolenaar166af9b2010-11-16 20:34:40 +0100449 endif " }}}
Bram Moolenaar8ada2cc2010-07-29 20:43:36 +0200450
Bram Moolenaar166af9b2010-11-16 20:34:40 +0100451 " everything new will get added before the diff styles so diff highlight
452 " properly overrides normal highlight
Bram Moolenaar8ada2cc2010-07-29 20:43:36 +0200453 if diff_style_start != 0
454 let insert_index = diff_style_start
Bram Moolenaarb02cbe32010-07-11 22:38:52 +0200455 endif
456
457 " Delete those parts that are not needed so
458 " we can include the rest into the resulting table
459 1,/^<body/d_
460 $
461 ?</body>?,$d_
462 let temp = getline(1,'$')
463 " undo deletion of start and end part
464 " so we can later save the file as valid html
Bram Moolenaar349b2fb2010-07-16 20:35:36 +0200465 " TODO: restore using grabbed lines if undolevel is 1?
Bram Moolenaarb02cbe32010-07-11 22:38:52 +0200466 normal 2u
Bram Moolenaarbebca9d2010-08-07 15:47:30 +0200467 if s:settings.use_css
468 call add(html, '<td valign="top"><div>')
469 elseif s:settings.use_xhtml
470 call add(html, '<td nowrap="nowrap" valign="top"><div>')
471 else
472 call add(html, '<td nowrap valign="top"><div>')
473 endif
Bram Moolenaarb02cbe32010-07-11 22:38:52 +0200474 let html += temp
Bram Moolenaar349b2fb2010-07-16 20:35:36 +0200475 call add(html, '</div></td>')
Bram Moolenaarb02cbe32010-07-11 22:38:52 +0200476
477 " Close this buffer
Bram Moolenaar349b2fb2010-07-16 20:35:36 +0200478 " TODO: the comment above says we're going to allow saving the file
479 " later...but here we discard it?
Bram Moolenaarb02cbe32010-07-11 22:38:52 +0200480 quit!
481 endfor
482
Bram Moolenaar8ada2cc2010-07-29 20:43:36 +0200483 let html[body_line_num] = body_line
484
Bram Moolenaarb02cbe32010-07-11 22:38:52 +0200485 call add(html, '</tr>')
486 call add(html, '</table>')
Bram Moolenaar8ada2cc2010-07-29 20:43:36 +0200487 call add(html, s:body_end_line)
Bram Moolenaarb02cbe32010-07-11 22:38:52 +0200488 call add(html, '</html>')
489
490 let i = 1
Bram Moolenaarbebca9d2010-08-07 15:47:30 +0200491 let name = "Diff" . (s:settings.use_xhtml ? ".xhtml" : ".html")
Bram Moolenaar349b2fb2010-07-16 20:35:36 +0200492 " Find an unused file name if current file name is already in use
Bram Moolenaarb02cbe32010-07-11 22:38:52 +0200493 while filereadable(name)
Bram Moolenaarbebca9d2010-08-07 15:47:30 +0200494 let name = substitute(name, '\d*\.x\?html$', '', '') . i . '.' . fnamemodify(copy(name), ":t:e")
Bram Moolenaarb02cbe32010-07-11 22:38:52 +0200495 let i += 1
Bram Moolenaar349b2fb2010-07-16 20:35:36 +0200496 endwhile
497 exe "topleft new " . name
498 setlocal modifiable
499
500 " just in case some user autocmd creates content in the new buffer, make sure
501 " it is empty before proceeding
502 %d
Bram Moolenaar166af9b2010-11-16 20:34:40 +0100503
504 " set the fileencoding to match the charset we'll be using
505 let &l:fileencoding=s:settings.vim_encoding
506
507 " According to http://www.w3.org/TR/html4/charset.html#doc-char-set, the byte
508 " order mark is highly recommend on the web when using multibyte encodings. But,
509 " it is not a good idea to include it on UTF-8 files. Otherwise, let Vim
510 " determine when it is actually inserted.
511 if s:settings.vim_encoding == 'utf-8'
512 setlocal nobomb
513 else
514 setlocal bomb
515 endif
516
Bram Moolenaarb02cbe32010-07-11 22:38:52 +0200517 call append(0, html)
Bram Moolenaar349b2fb2010-07-16 20:35:36 +0200518
Bram Moolenaarb02cbe32010-07-11 22:38:52 +0200519 if len(style) > 0
520 1
Bram Moolenaar349b2fb2010-07-16 20:35:36 +0200521 let style_start = search('^</head>')-1
522
523 " Insert javascript to toggle matching folds open and closed in all windows,
Bram Moolenaar166af9b2010-11-16 20:34:40 +0100524 " if dynamic folding is active. {{{
Bram Moolenaar076e8b22010-08-05 21:54:00 +0200525 if s:settings.dynamic_folds
Bram Moolenaar349b2fb2010-07-16 20:35:36 +0200526 call append(style_start, [
Bram Moolenaar7c86f4c2010-07-18 14:07:22 +0200527 \ "<script type='text/javascript'>",
Bram Moolenaarbebca9d2010-08-07 15:47:30 +0200528 \ s:settings.use_xhtml ? '//<![CDATA[' : " <!--",
Bram Moolenaar7c86f4c2010-07-18 14:07:22 +0200529 \ " function toggleFold(objID)",
530 \ " {",
531 \ " for (win_num = 1; win_num <= ".len(a:buf_list)."; win_num++)",
532 \ " {",
533 \ " var fold;",
534 \ ' fold = document.getElementById("win"+win_num+objID);',
535 \ " if(fold.className == 'closed-fold')",
536 \ " {",
537 \ " fold.className = 'open-fold';",
538 \ " }",
539 \ " else if (fold.className == 'open-fold')",
540 \ " {",
541 \ " fold.className = 'closed-fold';",
542 \ " }",
543 \ " }",
544 \ " }",
Bram Moolenaarbebca9d2010-08-07 15:47:30 +0200545 \ s:settings.use_xhtml ? '//]]>' : " -->",
Bram Moolenaar7c86f4c2010-07-18 14:07:22 +0200546 \ "</script>"
547 \ ])
Bram Moolenaar166af9b2010-11-16 20:34:40 +0100548 endif "}}}
Bram Moolenaar349b2fb2010-07-16 20:35:36 +0200549
550 " Insert styles from all the generated html documents and additional styles
551 " for the table-based layout of the side-by-side diff. The diff should take
552 " up the full browser window (but not more), and be static in size,
553 " horizontally scrollable when the lines are too long. Otherwise, the diff
Bram Moolenaar166af9b2010-11-16 20:34:40 +0100554 " is pretty useless for really long lines. {{{
Bram Moolenaar076e8b22010-08-05 21:54:00 +0200555 if s:settings.use_css
Bram Moolenaarbebca9d2010-08-07 15:47:30 +0200556 call append(style_start,
557 \ ['<style type="text/css">']+
558 \ style+
559 \ [ s:settings.use_xhtml ? '' : '<!--',
560 \ 'table { table-layout: fixed; }',
561 \ 'html, body, table, tbody { width: 100%; margin: 0; padding: 0; }',
562 \ 'th, td { width: '.printf("%.1f",100.0/len(a:win_list)).'%; }',
563 \ 'td div { overflow: auto; }',
564 \ s:settings.use_xhtml ? '' : '-->',
565 \ '</style>'
Bram Moolenaar166af9b2010-11-16 20:34:40 +0100566 \])
567 endif "}}}
Bram Moolenaarb02cbe32010-07-11 22:38:52 +0200568 endif
Bram Moolenaar8df7f882010-08-13 11:30:02 +0200569
570 let &paste = s:old_paste
571 let &magic = s:old_magic
Bram Moolenaar166af9b2010-11-16 20:34:40 +0100572endfunc "}}}
Bram Moolenaar349b2fb2010-07-16 20:35:36 +0200573
Bram Moolenaar076e8b22010-08-05 21:54:00 +0200574" Gets a single user option and sets it in the passed-in Dict, or gives it the
575" default value if the option doesn't actually exist.
Bram Moolenaar166af9b2010-11-16 20:34:40 +0100576func! tohtml#GetOption(settings, option, default) "{{{
Bram Moolenaar076e8b22010-08-05 21:54:00 +0200577 if exists('g:html_'.a:option)
578 let a:settings[a:option] = g:html_{a:option}
579 else
580 let a:settings[a:option] = a:default
Bram Moolenaar349b2fb2010-07-16 20:35:36 +0200581 endif
Bram Moolenaar166af9b2010-11-16 20:34:40 +0100582endfunc "}}}
Bram Moolenaar349b2fb2010-07-16 20:35:36 +0200583
Bram Moolenaar076e8b22010-08-05 21:54:00 +0200584" returns a Dict containing the values of all user options for 2html, including
585" default values for those not given an explicit value by the user. Discards the
586" html_ prefix of the option for nicer looking code.
Bram Moolenaar166af9b2010-11-16 20:34:40 +0100587func! tohtml#GetUserSettings() "{{{
Bram Moolenaar076e8b22010-08-05 21:54:00 +0200588 if exists('s:settings')
589 " just restore the known options if we've already retrieved them
590 return s:settings
Bram Moolenaar349b2fb2010-07-16 20:35:36 +0200591 else
Bram Moolenaar076e8b22010-08-05 21:54:00 +0200592 " otherwise figure out which options are set
593 let user_settings = {}
594
595 " Define the correct option if the old option name exists and we haven't
596 " already defined the correct one. Maybe I'll put out a warnig message about
597 " this sometime and remove the old option entirely at some even later time,
598 " but for now just silently accept the old option.
599 if exists('g:use_xhtml') && !exists("g:html_use_xhtml")
600 let g:html_use_xhtml = g:use_xhtml
601 endif
602
Bram Moolenaar166af9b2010-11-16 20:34:40 +0100603 " get current option settings with appropriate defaults {{{
Bram Moolenaar2a8a3ec2011-01-08 16:06:37 +0100604 call tohtml#GetOption(user_settings, 'no_progress', !has("statusline") )
605 call tohtml#GetOption(user_settings, 'diff_one_file', 0 )
606 call tohtml#GetOption(user_settings, 'number_lines', &number )
Bram Moolenaar8e5af3e2011-04-28 19:02:44 +0200607 call tohtml#GetOption(user_settings, 'pre_wrap', &wrap )
Bram Moolenaar2a8a3ec2011-01-08 16:06:37 +0100608 call tohtml#GetOption(user_settings, 'use_css', 1 )
609 call tohtml#GetOption(user_settings, 'ignore_conceal', 0 )
610 call tohtml#GetOption(user_settings, 'ignore_folding', 0 )
611 call tohtml#GetOption(user_settings, 'dynamic_folds', 0 )
612 call tohtml#GetOption(user_settings, 'no_foldcolumn', 0 )
613 call tohtml#GetOption(user_settings, 'hover_unfold', 0 )
614 call tohtml#GetOption(user_settings, 'no_pre', 0 )
615 call tohtml#GetOption(user_settings, 'whole_filler', 0 )
616 call tohtml#GetOption(user_settings, 'use_xhtml', 0 )
Bram Moolenaar166af9b2010-11-16 20:34:40 +0100617 " }}}
Bram Moolenaar076e8b22010-08-05 21:54:00 +0200618
Bram Moolenaar166af9b2010-11-16 20:34:40 +0100619 " override those settings that need it {{{
Bram Moolenaar076e8b22010-08-05 21:54:00 +0200620
Bram Moolenaarbebca9d2010-08-07 15:47:30 +0200621 " hover opening implies dynamic folding
622 if user_settings.hover_unfold
623 let user_settings.dynamic_folds = 1
624 endif
625
Bram Moolenaar076e8b22010-08-05 21:54:00 +0200626 " ignore folding overrides dynamic folding
627 if user_settings.ignore_folding && user_settings.dynamic_folds
628 let user_settings.dynamic_folds = 0
629 let user_settings.hover_unfold = 0
630 endif
631
Bram Moolenaar076e8b22010-08-05 21:54:00 +0200632 " dynamic folding with no foldcolumn implies hover opens
633 if user_settings.dynamic_folds && user_settings.no_foldcolumn
634 let user_settings.hover_unfold = 1
635 endif
636
637 " dynamic folding implies css
638 if user_settings.dynamic_folds
639 let user_settings.use_css = 1
640 endif
641
642 " if we're not using CSS we cannot use a pre section because <font> tags
643 " aren't allowed inside a <pre> block
644 if !user_settings.use_css
645 let user_settings.no_pre = 1
Bram Moolenaar8e5af3e2011-04-28 19:02:44 +0200646 endif
647
648 " pre_wrap doesn't do anything if not using pre or not using CSS
649 if user_settings.no_pre || !user_settings.use_css
650 let user_settings.pre_wrap=0
651 endif
652 "}}}
Bram Moolenaar076e8b22010-08-05 21:54:00 +0200653
Bram Moolenaar2a8a3ec2011-01-08 16:06:37 +0100654 " set up expand_tabs option after all the overrides so we know the
655 " appropriate defaults {{{
656 if user_settings.no_pre == 0
657 call tohtml#GetOption(user_settings,
658 \ 'expand_tabs',
659 \ &expandtab || &ts != 8 || user_settings.number_lines ||
660 \ (user_settings.dynamic_folds && !user_settings.no_foldcolumn))
661 else
662 let user_settings.expand_tabs = 1
663 endif
664 " }}}
665
Bram Moolenaar166af9b2010-11-16 20:34:40 +0100666 if exists("g:html_use_encoding") "{{{
667 " user specified the desired MIME charset, figure out proper
668 " 'fileencoding' from it or warn the user if we cannot
Bram Moolenaarbebca9d2010-08-07 15:47:30 +0200669 let user_settings.encoding = g:html_use_encoding
Bram Moolenaar166af9b2010-11-16 20:34:40 +0100670 let user_settings.vim_encoding = tohtml#EncodingFromCharset(g:html_use_encoding)
671 if user_settings.vim_encoding == ''
672 echohl WarningMsg
673 echomsg "TOhtml: file encoding for"
674 \ g:html_use_encoding
675 \ "unknown, please set 'fileencoding'"
676 echohl None
677 endif
Bram Moolenaarbebca9d2010-08-07 15:47:30 +0200678 else
Bram Moolenaar166af9b2010-11-16 20:34:40 +0100679 " Figure out proper MIME charset from 'fileencoding' if possible
Bram Moolenaar8e5af3e2011-04-28 19:02:44 +0200680 if &l:fileencoding != ''
681 " If the buffer is not a "normal" type, the 'fileencoding' value may not
682 " be trusted; since the buffer should not be written the fileencoding is
683 " not intended to be used.
684 if &l:buftype=='' || &l:buftype==?'help'
685 let user_settings.vim_encoding = &l:fileencoding
686 call tohtml#CharsetFromEncoding(user_settings)
687 else
688 let user_settings.encoding = '' " trigger detection using &encoding
689 endif
Bram Moolenaarbebca9d2010-08-07 15:47:30 +0200690 endif
Bram Moolenaar166af9b2010-11-16 20:34:40 +0100691
692 " else from 'encoding' if possible
693 if &l:fileencoding == '' || user_settings.encoding == ''
694 let user_settings.vim_encoding = &encoding
695 call tohtml#CharsetFromEncoding(user_settings)
696 endif
697
698 " else default to UTF-8 and warn user
699 if user_settings.encoding == ''
700 let user_settings.vim_encoding = 'utf-8'
Bram Moolenaarbebca9d2010-08-07 15:47:30 +0200701 let user_settings.encoding = 'UTF-8'
Bram Moolenaar166af9b2010-11-16 20:34:40 +0100702 echohl WarningMsg
703 echomsg "TOhtml: couldn't determine MIME charset, using UTF-8"
704 echohl None
Bram Moolenaarbebca9d2010-08-07 15:47:30 +0200705 endif
Bram Moolenaar166af9b2010-11-16 20:34:40 +0100706 endif "}}}
Bram Moolenaarbebca9d2010-08-07 15:47:30 +0200707
708 " TODO: font
709
Bram Moolenaar076e8b22010-08-05 21:54:00 +0200710 return user_settings
Bram Moolenaar349b2fb2010-07-16 20:35:36 +0200711 endif
Bram Moolenaar166af9b2010-11-16 20:34:40 +0100712endfunc "}}}
713
714" get the proper HTML charset name from a Vim encoding option.
715function! tohtml#CharsetFromEncoding(settings) "{{{
716 let l:vim_encoding = a:settings.vim_encoding
717 if exists('g:html_charset_override') && has_key(g:html_charset_override, l:vim_encoding)
718 let a:settings.encoding = g:html_charset_override[l:vim_encoding]
719 else
720 if l:vim_encoding =~ '^8bit\|^2byte'
721 " 8bit- and 2byte- prefixes are to indicate encodings available on the
722 " system that Vim will convert with iconv(), look up just the encoding name,
723 " not Vim's prefix.
724 let l:vim_encoding = substitute(l:vim_encoding, '^8bit-\|^2byte-', '', '')
725 endif
726 if has_key(g:tohtml#encoding_to_charset, l:vim_encoding)
727 let a:settings.encoding = g:tohtml#encoding_to_charset[l:vim_encoding]
728 else
729 let a:settings.encoding = ""
730 endif
731 endif
732 if a:settings.encoding != ""
733 let l:vim_encoding = tohtml#EncodingFromCharset(a:settings.encoding)
734 if l:vim_encoding != ""
735 " if the Vim encoding to HTML encoding conversion is set up (by default or
736 " by the user) to convert to a different encoding, we need to also change
737 " the Vim encoding of the new buffer
738 let a:settings.vim_encoding = l:vim_encoding
739 endif
740 endif
741endfun "}}}
742
743" Get the proper Vim encoding option setting from an HTML charset name.
744function! tohtml#EncodingFromCharset(encoding) "{{{
745 if exists('g:html_encoding_override') && has_key(g:html_encoding_override, a:encoding)
746 return g:html_encoding_override[a:encoding]
747 elseif has_key(g:tohtml#charset_to_encoding, tolower(a:encoding))
748 return g:tohtml#charset_to_encoding[tolower(a:encoding)]
749 else
750 return ""
751 endif
752endfun "}}}
Bram Moolenaar349b2fb2010-07-16 20:35:36 +0200753
754let &cpo = s:cpo_sav
755unlet s:cpo_sav
756
757" Make sure any patches will probably use consistent indent
Bram Moolenaar166af9b2010-11-16 20:34:40 +0100758" vim: ts=8 sw=2 sts=2 noet fdm=marker