Version 0.9.9
* NEW: Diary. Help in making daily notes. See ':h vimwiki-diary'. Now you can really easy add information into vimwiki that should be sorted out later. * NEW: Tables are redesigned. Syntax is changed. Now they are auto-formattable. You can navigate them with <tab> and <cr> in insert mode. See 'vimwiki-syntax-tables' and 'vimwiki-tables' for more details. * NEW: Keyword STARTED: is added. * NEW: Words TODO:, DONE:, STARTED:, XXX:, FIXME:, FIXED: are highlighed inside headers. * FIX: Export to html external links with 'file://' protocol. Ex: '[file:///home/user1/book.pdf my book]'. * FIX: Menu is corrupted if wiki's path contains spaces. * FIX: Settings 'wrap' and 'linebreak' are removed from ftplugin. Add them into your personal settings file '.vim/after/ftplugin/vimwiki.vim' if needed. * NEW: Headers are highlighted in different colors by default. See ':h g:vimwiki_hl_headers' to turn it off. * FIX: Issue 40: Links with russian subdirs don't work. * NEW: It is now possible to generate HTML files automatically on page save. See ':h vimwiki-option-auto_export'.
This commit is contained in:
@ -23,10 +23,17 @@ function! s:chomp_slash(str) "{{{
|
||||
return substitute(a:str, '[/\\]\+$', '', '')
|
||||
endfunction "}}}
|
||||
|
||||
function! s:is_windows()
|
||||
return has("win32") || has("win64") || has("win95") || has("win16")
|
||||
endfunction
|
||||
|
||||
function! vimwiki#mkdir(path) "{{{
|
||||
let path = expand(a:path)
|
||||
if !isdirectory(path) && exists("*mkdir")
|
||||
let path = s:chomp_slash(path)
|
||||
if s:is_windows() && !empty(g:vimwiki_w32_dir_enc)
|
||||
let path = iconv(path, &enc, g:vimwiki_w32_dir_enc)
|
||||
endif
|
||||
call mkdir(path, "p")
|
||||
endif
|
||||
endfunction
|
||||
@ -62,6 +69,25 @@ function! vimwiki#current_subdir()"{{{
|
||||
return vimwiki#subdir(VimwikiGet('path'), expand('%:p'))
|
||||
endfunction"}}}
|
||||
|
||||
function! vimwiki#open_link(cmd, link, ...) "{{{
|
||||
if s:is_link_to_non_wiki_file(a:link)
|
||||
call s:edit_file(a:cmd, a:link)
|
||||
else
|
||||
if a:0
|
||||
let vimwiki_prev_link = [a:1, []]
|
||||
elseif &ft == 'vimwiki'
|
||||
let vimwiki_prev_link = [expand('%:p'), getpos('.')]
|
||||
endif
|
||||
|
||||
call s:edit_file(a:cmd, VimwikiGet('path').a:link.VimwikiGet('ext'))
|
||||
|
||||
if exists('vimwiki_prev_link')
|
||||
let b:vimwiki_prev_link = vimwiki_prev_link
|
||||
endif
|
||||
endif
|
||||
endfunction
|
||||
" }}}
|
||||
|
||||
function! s:filename(link) "{{{
|
||||
let result = vimwiki#safe_link(a:link)
|
||||
if a:link =~ '|'
|
||||
@ -165,11 +191,13 @@ function! s:print_wiki_list() "{{{
|
||||
endfunction
|
||||
" }}}
|
||||
|
||||
function! s:wiki_select(wnum)"{{{
|
||||
function! vimwiki#select(wnum)"{{{
|
||||
if a:wnum < 1 || a:wnum > len(g:vimwiki_list)
|
||||
return
|
||||
endif
|
||||
let b:vimwiki_idx = g:vimwiki_current_idx
|
||||
if &ft == 'vimwiki'
|
||||
let b:vimwiki_idx = g:vimwiki_current_idx
|
||||
endif
|
||||
let g:vimwiki_current_idx = a:wnum - 1
|
||||
endfunction
|
||||
" }}}
|
||||
@ -260,7 +288,7 @@ function! s:get_wiki_buffers() "{{{
|
||||
if bufexists(bcount)
|
||||
let bname = fnamemodify(bufname(bcount), ":p")
|
||||
if bname =~ VimwikiGet('ext')."$"
|
||||
let bitem = [bname, getbufvar(bname, "vimwiki_prev_word")]
|
||||
let bitem = [bname, getbufvar(bname, "vimwiki_prev_link")]
|
||||
call add(blist, bitem)
|
||||
endif
|
||||
endif
|
||||
@ -273,7 +301,7 @@ endfunction
|
||||
function! s:open_wiki_buffer(item) "{{{
|
||||
call s:edit_file('e', a:item[0])
|
||||
if !empty(a:item[1])
|
||||
call setbufvar(a:item[0], "vimwiki_prev_word", a:item[1])
|
||||
call setbufvar(a:item[0], "vimwiki_prev_link", a:item[1])
|
||||
endif
|
||||
endfunction
|
||||
" }}}
|
||||
@ -388,8 +416,8 @@ function! vimwiki#WikiFollowWord(split) "{{{
|
||||
let cmd = ":e "
|
||||
endif
|
||||
|
||||
let word = s:strip_word(s:get_word_at_cursor(g:vimwiki_rxWikiWord))
|
||||
if word == ""
|
||||
let link = s:strip_word(s:get_word_at_cursor(g:vimwiki_rxWikiWord))
|
||||
if link == ""
|
||||
let weblink = s:strip_word(s:get_word_at_cursor(g:vimwiki_rxWeblink))
|
||||
if weblink != ""
|
||||
call VimwikiWeblinkHandler(weblink)
|
||||
@ -399,21 +427,16 @@ function! vimwiki#WikiFollowWord(split) "{{{
|
||||
return
|
||||
endif
|
||||
|
||||
if s:is_link_to_non_wiki_file(word)
|
||||
call s:edit_file(cmd, word)
|
||||
else
|
||||
let vimwiki_prev_word = [expand('%:p'), getpos('.')]
|
||||
let subdir = vimwiki#current_subdir()
|
||||
call s:edit_file(cmd, VimwikiGet('path').subdir.word.VimwikiGet('ext'))
|
||||
let b:vimwiki_prev_word = vimwiki_prev_word
|
||||
endif
|
||||
let subdir = vimwiki#current_subdir()
|
||||
call vimwiki#open_link(cmd, subdir.link)
|
||||
|
||||
endfunction
|
||||
" }}}
|
||||
|
||||
function! vimwiki#WikiGoBackWord() "{{{
|
||||
if exists("b:vimwiki_prev_word")
|
||||
if exists("b:vimwiki_prev_link")
|
||||
" go back to saved WikiWord
|
||||
let prev_word = b:vimwiki_prev_word
|
||||
let prev_word = b:vimwiki_prev_link
|
||||
execute ":e ".substitute(prev_word[0], '\s', '\\\0', 'g')
|
||||
call setpos('.', prev_word[1])
|
||||
endif
|
||||
@ -421,7 +444,7 @@ endfunction
|
||||
" }}}
|
||||
|
||||
function! vimwiki#WikiGoHome(index) "{{{
|
||||
call s:wiki_select(a:index)
|
||||
call vimwiki#select(a:index)
|
||||
call vimwiki#mkdir(VimwikiGet('path'))
|
||||
|
||||
try
|
||||
@ -523,7 +546,7 @@ function! vimwiki#WikiRenameWord() "{{{
|
||||
let &buftype="nofile"
|
||||
|
||||
let cur_buffer = [expand('%:p'),
|
||||
\getbufvar(expand('%:p'), "vimwiki_prev_word")]
|
||||
\getbufvar(expand('%:p'), "vimwiki_prev_link")]
|
||||
|
||||
let blist = s:get_wiki_buffers()
|
||||
|
||||
|
216
autoload/vimwiki_diary.vim
Normal file
216
autoload/vimwiki_diary.vim
Normal file
@ -0,0 +1,216 @@
|
||||
" Vimwiki autoload plugin file
|
||||
" Desc: Handle diary notes
|
||||
" Author: Maxim Kim <habamax@gmail.com>
|
||||
" Home: http://code.google.com/p/vimwiki/
|
||||
|
||||
" Load only once {{{
|
||||
if exists("g:loaded_vimwiki_diary_auto") || &cp
|
||||
finish
|
||||
endif
|
||||
let g:loaded_vimwiki_diary_auto = 1
|
||||
"}}}
|
||||
|
||||
function! s:prefix_zero(num) "{{{
|
||||
if a:num < 10
|
||||
return '0'.a:num
|
||||
endif
|
||||
return a:num
|
||||
endfunction "}}}
|
||||
|
||||
function! s:desc(d1, d2) "{{{
|
||||
return a:d1 == a:d2 ? 0 : a:d1 < a:d2 ? 1 : -1
|
||||
endfunction "}}}
|
||||
|
||||
function! s:get_date_link(fmt) "{{{
|
||||
return strftime(a:fmt)
|
||||
endfunction "}}}
|
||||
|
||||
function! s:link_exists(lines, link) "{{{
|
||||
let link_exists = 0
|
||||
for line in a:lines
|
||||
if line =~ escape(a:link, '[]\')
|
||||
let link_exists = 1
|
||||
break
|
||||
endif
|
||||
endfor
|
||||
return link_exists
|
||||
endfunction "}}}
|
||||
|
||||
function! s:diary_path() "{{{
|
||||
return VimwikiGet('path').VimwikiGet('diary_rel_path')
|
||||
endfunction "}}}
|
||||
|
||||
function! s:diary_index() "{{{
|
||||
return s:diary_path().VimwikiGet('diary_index').VimwikiGet('ext')
|
||||
endfunction "}}}
|
||||
|
||||
function! s:get_diary_range(lines, header) "{{{
|
||||
let rx = '\[\[\d\{4}-\d\d-\d\d\]\]'
|
||||
let idx = 0
|
||||
let ln_start = -1
|
||||
let ln_end = -1
|
||||
for line in a:lines
|
||||
if ln_start != -1
|
||||
if line =~ '^\s*\(=\)\+.*\1\s*$' || (line !~ rx && line !~ '^\s*$')
|
||||
break
|
||||
endif
|
||||
endif
|
||||
if line =~ '^\s*\(=\)\+\s*'.a:header.'\s*\1\s*$'
|
||||
let ln_start = idx + 1
|
||||
endif
|
||||
let idx += 1
|
||||
endfor
|
||||
|
||||
let ln_end = idx - 1
|
||||
return [ln_start, ln_end]
|
||||
endfunction "}}}
|
||||
|
||||
function! s:diary_date_link() "{{{
|
||||
return s:get_date_link(VimwikiGet('diary_link_fmt'))
|
||||
endfunction "}}}
|
||||
|
||||
function! s:get_file_contents(file_name) "{{{
|
||||
let lines = []
|
||||
let bufnr = bufnr(expand(a:file_name))
|
||||
if bufnr != -1
|
||||
let lines = getbufline(bufnr, 1, '$')
|
||||
else
|
||||
try
|
||||
let lines = readfile(expand(a:file_name))
|
||||
catch
|
||||
endtry
|
||||
endif
|
||||
return [lines, bufnr]
|
||||
endfunction "}}}
|
||||
|
||||
function! s:get_links() "{{{
|
||||
let rx = '\d\{4}-\d\d-\d\d'
|
||||
let s_links = glob(VimwikiGet('path').VimwikiGet('diary_rel_path').'*.wiki')
|
||||
|
||||
"let s_links = substitute(s_links, '\'.VimwikiGet('ext'), "", "g")
|
||||
let s_links = substitute(s_links, '\.wiki', "", "g")
|
||||
let links = split(s_links, '\n')
|
||||
|
||||
" remove backup files (.wiki~)
|
||||
call filter(links, 'v:val !~ ''.*\~$''')
|
||||
|
||||
" remove paths
|
||||
call map(links, 'fnamemodify(v:val, ":t")')
|
||||
|
||||
call filter(links, 'v:val =~ "'.escape(rx, '\').'"')
|
||||
call map(links, '"[[".v:val."]]"')
|
||||
return links
|
||||
endfunction "}}}
|
||||
|
||||
function! s:format_links(links) "{{{
|
||||
let lines = []
|
||||
let line = '| '
|
||||
let idx = 0
|
||||
let trigger = 0
|
||||
while idx < len(a:links)
|
||||
if idx/VimwikiGet('diary_link_count') > trigger
|
||||
let trigger = idx/VimwikiGet('diary_link_count')
|
||||
call add(lines, substitute(line, '\s\+$', '', ''))
|
||||
let line = '| '
|
||||
endif
|
||||
let line .= a:links[idx].' | '
|
||||
let idx += 1
|
||||
endwhile
|
||||
call add(lines, substitute(line, '\s\+$', '', ''))
|
||||
call extend(lines, [''])
|
||||
|
||||
return lines
|
||||
endfunction "}}}
|
||||
|
||||
function! s:add_link(page, header, link) "{{{
|
||||
let [lines, bufnr] = s:get_file_contents(a:page)
|
||||
|
||||
let [ln_start, ln_end] = s:get_diary_range(lines, a:header)
|
||||
|
||||
let link = '[['.a:link.']]'
|
||||
|
||||
let link_exists = s:link_exists(lines[ln_start : ln_end], link)
|
||||
|
||||
if !link_exists
|
||||
|
||||
if ln_start == -1
|
||||
call insert(lines, '= '.a:header.' =')
|
||||
let ln_start = 1
|
||||
endif
|
||||
|
||||
" removing 'old' links
|
||||
let idx = ln_end - ln_start
|
||||
while idx > 0
|
||||
call remove(lines, ln_start)
|
||||
let idx -= 1
|
||||
endwhile
|
||||
|
||||
" get all diary links from filesystem
|
||||
let links = s:get_links()
|
||||
|
||||
" add current link
|
||||
if index(links, link) == -1
|
||||
call add(links, link)
|
||||
endif
|
||||
|
||||
let links = sort(links, 's:desc')
|
||||
call extend(lines, s:format_links(links), ln_start)
|
||||
|
||||
if bufnr != -1
|
||||
exe 'buffer '.bufnr
|
||||
if !&readonly
|
||||
1,$delete _
|
||||
call append(1, lines)
|
||||
1,1delete _
|
||||
endif
|
||||
else
|
||||
call writefile(lines, expand(a:page))
|
||||
endif
|
||||
endif
|
||||
endfunction "}}}
|
||||
|
||||
function! s:make_date_link(...) "{{{
|
||||
if a:0
|
||||
let link = a:1
|
||||
else
|
||||
let link = s:diary_date_link()
|
||||
endif
|
||||
let header = VimwikiGet('diary_header')
|
||||
call s:add_link(s:diary_index(), header, link)
|
||||
return VimwikiGet('diary_rel_path').link
|
||||
endfunction "}}}
|
||||
|
||||
function! vimwiki_diary#make_note(index, ...) "{{{
|
||||
call vimwiki#select(a:index)
|
||||
call vimwiki#mkdir(VimwikiGet('path').VimwikiGet('diary_rel_path'))
|
||||
if a:0
|
||||
let link = s:make_date_link(a:1)
|
||||
else
|
||||
let link = s:make_date_link()
|
||||
endif
|
||||
call vimwiki#open_link(':e ', link, s:diary_index())
|
||||
endfunction "}}}
|
||||
|
||||
" Calendar.vim callback.
|
||||
function! vimwiki_diary#calendar_action(day, month, year, week, dir) "{{{
|
||||
let day = s:prefix_zero(a:day)
|
||||
let month = s:prefix_zero(a:month)
|
||||
|
||||
let link = a:year.'-'.month.'-'.day
|
||||
if winnr('#') == 0
|
||||
if a:dir == 'V'
|
||||
vsplit
|
||||
else
|
||||
split
|
||||
endif
|
||||
else
|
||||
wincmd p
|
||||
if !&hidden && &modified
|
||||
new
|
||||
endif
|
||||
endif
|
||||
|
||||
" Create diary note for a selected date in default wiki.
|
||||
call vimwiki_diary#make_note(1, link)
|
||||
endfunction
|
||||
|
@ -3,6 +3,8 @@
|
||||
" Author: Maxim Kim <habamax@gmail.com>
|
||||
" Home: http://code.google.com/p/vimwiki/
|
||||
|
||||
" XXX: This file should be refactored!
|
||||
|
||||
" Load only once {{{
|
||||
if exists("g:loaded_vimwiki_html_auto") || &cp
|
||||
finish
|
||||
@ -32,7 +34,7 @@ function! s:remove_blank_lines(lines) " {{{
|
||||
endfunction "}}}
|
||||
|
||||
function! s:is_web_link(lnk) "{{{
|
||||
if a:lnk =~ '^\%(https://\|http://\|www.\|ftp://\)'
|
||||
if a:lnk =~ '^\%(https://\|http://\|www.\|ftp://\|file://\)'
|
||||
return 1
|
||||
endif
|
||||
return 0
|
||||
@ -83,7 +85,8 @@ function! s:create_default_CSS(path) " {{{
|
||||
call add(lines, 'img {border: none;}')
|
||||
call add(lines, 'pre {border-left: 1px solid #ccc; margin-left: 2em; padding-left: 0.5em;}')
|
||||
call add(lines, 'blockquote {padding: 0.4em; background-color: #f6f5eb;}')
|
||||
call add(lines, 'td {border: 1px solid #ccc; padding: 0.3em;}')
|
||||
call add(lines, 'th, td {border: 1px solid #ccc; padding: 0.3em;}')
|
||||
call add(lines, 'th {background-color: #f0f0f0;}')
|
||||
call add(lines, 'hr {border: none; border-top: 1px solid #ccc; width: 100%;}')
|
||||
call add(lines, 'del {text-decoration: line-through; color: #777777;}')
|
||||
call add(lines, '.toc li {list-style-type: none;}')
|
||||
@ -515,9 +518,9 @@ function! s:close_tag_para(para, ldest) "{{{
|
||||
endfunction "}}}
|
||||
|
||||
function! s:close_tag_table(table, ldest) "{{{
|
||||
if a:table
|
||||
if len(a:table)
|
||||
call insert(a:ldest, "</table>")
|
||||
return 0
|
||||
return []
|
||||
endif
|
||||
return a:table
|
||||
endfunction "}}}
|
||||
@ -774,45 +777,54 @@ function! s:process_tag_hr(line) "{{{
|
||||
endfunction "}}}
|
||||
|
||||
function! s:process_tag_table(line, table) "{{{
|
||||
" XXX: This should be refactored!!!
|
||||
let table = a:table
|
||||
let lines = []
|
||||
let processed = 0
|
||||
if a:line =~ '^||.\+||.*'
|
||||
if !table
|
||||
call add(lines, "<table>")
|
||||
let table = 1
|
||||
|
||||
if a:line =~ '^\s*|[-+]\+|\s*$' && len(table)
|
||||
call add(table, [])
|
||||
let processed = 1
|
||||
elseif a:line =~ '^\s*|.\+|\s*$'
|
||||
if empty(table)
|
||||
let table = [[]]
|
||||
else
|
||||
call add(table, [])
|
||||
endif
|
||||
let processed = 1
|
||||
|
||||
call add(lines, "<tr>")
|
||||
let pos1 = 0
|
||||
let pos2 = 0
|
||||
let done = 0
|
||||
while !done
|
||||
let pos1 = stridx(a:line, '||', pos2)
|
||||
let pos2 = stridx(a:line, '||', pos1+2)
|
||||
if pos1==-1 || pos2==-1
|
||||
let done = 1
|
||||
let pos2 = len(a:line)
|
||||
endif
|
||||
let line = strpart(a:line, pos1+2, pos2-pos1-2)
|
||||
if line == ''
|
||||
continue
|
||||
endif
|
||||
if strpart(line, 0, 1) == ' ' &&
|
||||
\ strpart(line, len(line) - 1, 1) == ' '
|
||||
call add(lines, '<td class="justcenter">'.line.'</td>')
|
||||
elseif strpart(line, 0, 1) == ' '
|
||||
call add(lines, '<td class="justright">'.line.'</td>')
|
||||
else
|
||||
call add(lines, '<td class="justleft">'.line.'</td>')
|
||||
endif
|
||||
endwhile
|
||||
call add(lines, "</tr>")
|
||||
call extend(table[-1], split(a:line, '\s*|\s*'))
|
||||
|
||||
elseif table
|
||||
elseif len(table)
|
||||
call add(lines, "<table>")
|
||||
|
||||
let head = 0
|
||||
for idx in range(len(table))
|
||||
if empty(table[idx])
|
||||
let head = idx
|
||||
break
|
||||
endif
|
||||
endfor
|
||||
if head > 0
|
||||
for row in table[: head-1]
|
||||
call add(lines, '<tr>')
|
||||
call extend(lines, map(row, '"<th>".v:val."</th>"'))
|
||||
call add(lines, '</tr>')
|
||||
endfor
|
||||
for row in table[head+1 :]
|
||||
call add(lines, '<tr>')
|
||||
call extend(lines, map(row, '"<td>".v:val."</td>"'))
|
||||
call add(lines, '</tr>')
|
||||
endfor
|
||||
else
|
||||
for row in table
|
||||
call add(lines, '<tr>')
|
||||
call extend(lines, map(row, '"<td>".v:val."</td>"'))
|
||||
call add(lines, '</tr>')
|
||||
endfor
|
||||
endif
|
||||
call add(lines, "</table>")
|
||||
let table = 0
|
||||
let table = []
|
||||
endif
|
||||
return [processed, lines, table]
|
||||
endfunction "}}}
|
||||
@ -820,12 +832,12 @@ endfunction "}}}
|
||||
"}}}
|
||||
|
||||
" WIKI2HTML "{{{
|
||||
function! s:wiki2html(line, state) " {{{
|
||||
function! s:parse_line(line, state) " {{{
|
||||
let state = {}
|
||||
let state.para = a:state.para
|
||||
let state.quote = a:state.quote
|
||||
let state.pre = a:state.pre
|
||||
let state.table = a:state.table
|
||||
let state.table = a:state.table[:]
|
||||
let state.lists = a:state.lists[:]
|
||||
let state.deflist = a:state.deflist
|
||||
let state.placeholder = a:state.placeholder
|
||||
@ -838,7 +850,7 @@ function! s:wiki2html(line, state) " {{{
|
||||
|
||||
let processed = 0
|
||||
|
||||
" toc -- placeholder
|
||||
" toc -- placeholder "{{{
|
||||
if !processed
|
||||
if line =~ '^\s*%toc'
|
||||
let processed = 1
|
||||
@ -846,14 +858,15 @@ function! s:wiki2html(line, state) " {{{
|
||||
let state.placeholder = ['toc', param]
|
||||
endif
|
||||
endif
|
||||
"}}}
|
||||
|
||||
" pres
|
||||
" pres "{{{
|
||||
if !processed
|
||||
let [processed, lines, state.pre] = s:process_tag_pre(line, state.pre)
|
||||
if processed && len(state.lists)
|
||||
call s:close_tag_list(state.lists, lines)
|
||||
endif
|
||||
if processed && state.table
|
||||
if processed && len(state.table)
|
||||
let state.table = s:close_tag_table(state.table, lines)
|
||||
endif
|
||||
if processed && state.deflist
|
||||
@ -867,8 +880,9 @@ function! s:wiki2html(line, state) " {{{
|
||||
endif
|
||||
call extend(res_lines, lines)
|
||||
endif
|
||||
"}}}
|
||||
|
||||
" lists
|
||||
" lists "{{{
|
||||
if !processed
|
||||
let [processed, lines] = s:process_tag_list(line, state.lists)
|
||||
if processed && state.quote
|
||||
@ -877,7 +891,7 @@ function! s:wiki2html(line, state) " {{{
|
||||
if processed && state.pre
|
||||
let state.pre = s:close_tag_pre(state.pre, lines)
|
||||
endif
|
||||
if processed && state.table
|
||||
if processed && len(state.table)
|
||||
let state.table = s:close_tag_table(state.table, lines)
|
||||
endif
|
||||
if processed && state.deflist
|
||||
@ -891,8 +905,9 @@ function! s:wiki2html(line, state) " {{{
|
||||
|
||||
call extend(res_lines, lines)
|
||||
endif
|
||||
"}}}
|
||||
|
||||
" headers
|
||||
" headers "{{{
|
||||
if !processed
|
||||
let [processed, line, h_level, h_text, h_id] = s:process_tag_h(line, state.toc_id)
|
||||
if processed
|
||||
@ -900,6 +915,9 @@ function! s:wiki2html(line, state) " {{{
|
||||
let state.table = s:close_tag_table(state.table, res_lines)
|
||||
let state.pre = s:close_tag_pre(state.pre, res_lines)
|
||||
let state.quote = s:close_tag_quote(state.quote, res_lines)
|
||||
|
||||
let line = s:make_tag(line, g:vimwiki_rxTodo, 's:tag_todo')
|
||||
|
||||
call add(res_lines, line)
|
||||
|
||||
" gather information for table of contents
|
||||
@ -907,8 +925,9 @@ function! s:wiki2html(line, state) " {{{
|
||||
let state.toc_id += 1
|
||||
endif
|
||||
endif
|
||||
"}}}
|
||||
|
||||
" quotes
|
||||
" quotes "{{{
|
||||
if !processed
|
||||
let [processed, lines, state.quote] = s:process_tag_quote(line, state.quote)
|
||||
if processed && len(state.lists)
|
||||
@ -917,7 +936,7 @@ function! s:wiki2html(line, state) " {{{
|
||||
if processed && state.deflist
|
||||
let state.deflist = s:close_tag_def_list(state.deflist, lines)
|
||||
endif
|
||||
if processed && state.table
|
||||
if processed && len(state.table)
|
||||
let state.table = s:close_tag_table(state.table, lines)
|
||||
endif
|
||||
if processed && state.pre
|
||||
@ -931,17 +950,9 @@ function! s:wiki2html(line, state) " {{{
|
||||
|
||||
call extend(res_lines, lines)
|
||||
endif
|
||||
"}}}
|
||||
|
||||
" definition lists
|
||||
if !processed
|
||||
let [processed, lines, state.deflist] = s:process_tag_def_list(line, state.deflist)
|
||||
|
||||
call map(lines, 's:process_inline_tags(v:val)')
|
||||
|
||||
call extend(res_lines, lines)
|
||||
endif
|
||||
|
||||
" tables
|
||||
" tables "{{{
|
||||
if !processed
|
||||
let [processed, lines, state.table] = s:process_tag_table(line, state.table)
|
||||
|
||||
@ -949,8 +960,9 @@ function! s:wiki2html(line, state) " {{{
|
||||
|
||||
call extend(res_lines, lines)
|
||||
endif
|
||||
"}}}
|
||||
|
||||
" horizontal lines
|
||||
" horizontal rules "{{{
|
||||
if !processed
|
||||
let [processed, line] = s:process_tag_hr(line)
|
||||
if processed
|
||||
@ -960,8 +972,19 @@ function! s:wiki2html(line, state) " {{{
|
||||
call add(res_lines, line)
|
||||
endif
|
||||
endif
|
||||
"}}}
|
||||
|
||||
"" P
|
||||
" definition lists "{{{
|
||||
if !processed
|
||||
let [processed, lines, state.deflist] = s:process_tag_def_list(line, state.deflist)
|
||||
|
||||
call map(lines, 's:process_inline_tags(v:val)')
|
||||
|
||||
call extend(res_lines, lines)
|
||||
endif
|
||||
"}}}
|
||||
|
||||
"" P "{{{
|
||||
if !processed
|
||||
let [processed, lines, state.para] = s:process_tag_para(line, state.para)
|
||||
if processed && len(state.lists)
|
||||
@ -973,7 +996,7 @@ function! s:wiki2html(line, state) " {{{
|
||||
if processed && state.pre
|
||||
let state.pre = s:close_tag_pre(state.pre, res_lines)
|
||||
endif
|
||||
if processed && state.table
|
||||
if processed && len(state.table)
|
||||
let state.table = s:close_tag_table(state.table, res_lines)
|
||||
endif
|
||||
|
||||
@ -981,6 +1004,7 @@ function! s:wiki2html(line, state) " {{{
|
||||
|
||||
call extend(res_lines, lines)
|
||||
endif
|
||||
"}}}
|
||||
|
||||
"" add the rest
|
||||
if !processed
|
||||
@ -1015,7 +1039,7 @@ function! vimwiki_html#Wiki2HTML(path, wikifile) "{{{
|
||||
let state.para = 0
|
||||
let state.quote = 0
|
||||
let state.pre = 0
|
||||
let state.table = 0
|
||||
let state.table = []
|
||||
let state.deflist = 0
|
||||
let state.lists = []
|
||||
let state.placeholder = []
|
||||
@ -1024,7 +1048,7 @@ function! vimwiki_html#Wiki2HTML(path, wikifile) "{{{
|
||||
|
||||
for line in lsource
|
||||
let oldquote = state.quote
|
||||
let [lines, state] = s:wiki2html(line, state)
|
||||
let [lines, state] = s:parse_line(line, state)
|
||||
|
||||
" Hack: There could be a lot of empty strings before s:process_tag_quote
|
||||
" find out `quote` is over. So we should delete them all. Think of the way
|
||||
|
335
autoload/vimwiki_tbl.vim
Normal file
335
autoload/vimwiki_tbl.vim
Normal file
@ -0,0 +1,335 @@
|
||||
" Vimwiki autoload plugin file
|
||||
" Desc: Tables
|
||||
" | Easily | manageable | text | tables | ! |
|
||||
" |--------+------------+-------+--------+---------|
|
||||
" | Have | fun! | Drink | tea | Period. |
|
||||
"
|
||||
" Author: Maxim Kim <habamax@gmail.com>
|
||||
" Home: http://code.google.com/p/vimwiki/
|
||||
|
||||
" Load only once {{{
|
||||
if exists("g:loaded_vimwiki_tbl_auto") || &cp
|
||||
finish
|
||||
endif
|
||||
let g:loaded_vimwiki_tbl_auto = 1
|
||||
"}}}
|
||||
|
||||
let s:textwidth = &tw
|
||||
|
||||
" Misc functions {{{
|
||||
function! s:wide_len(str) "{{{
|
||||
return strlen(substitute(a:str, '.', 'x', 'g'))
|
||||
endfunction "}}}
|
||||
|
||||
function! s:is_table(line) "{{{
|
||||
return a:line =~ '^\s*\%(|[^|]\+\)\+|\s*$' || s:is_separator(a:line)
|
||||
endfunction "}}}
|
||||
|
||||
function! s:is_separator(line) "{{{
|
||||
return a:line =~ '^\s*|\s*-\+'
|
||||
endfunction "}}}
|
||||
|
||||
function! s:is_last_column(lnum, cnum) "{{{
|
||||
return strpart(getline(a:lnum), a:cnum - 1) =~ '^[^|]*|\s*$'
|
||||
endfunction "}}}
|
||||
|
||||
function! s:count_separators(lnum) "{{{
|
||||
let lnum = a:lnum + 1
|
||||
while lnum < line('$')
|
||||
if !s:is_separator(getline(lnum))
|
||||
break
|
||||
endif
|
||||
let lnum += 1
|
||||
endwhile
|
||||
|
||||
return (lnum-a:lnum)
|
||||
endfunction "}}}
|
||||
|
||||
function! s:create_empty_row(cols) "{{{
|
||||
let first_cell = "| |"
|
||||
let cell = " |"
|
||||
let row = first_cell
|
||||
|
||||
for c in range(a:cols - 1)
|
||||
let row .= cell
|
||||
endfor
|
||||
|
||||
return row
|
||||
endfunction "}}}
|
||||
|
||||
function! s:create_row_sep(cols) "{{{
|
||||
let first_cell = "|---+"
|
||||
let cell = "---+"
|
||||
let last_cell = "---|"
|
||||
|
||||
if a:cols < 2
|
||||
return "|---|"
|
||||
endif
|
||||
|
||||
let row = first_cell
|
||||
|
||||
for c in range(a:cols - 2)
|
||||
let row .= cell
|
||||
endfor
|
||||
|
||||
let row .= last_cell
|
||||
|
||||
return row
|
||||
endfunction "}}}
|
||||
|
||||
function! s:get_values(line) "{{{
|
||||
let cells = []
|
||||
let cnt = 0
|
||||
let idx = 0
|
||||
while idx != -1 && idx < strlen(a:line) - 1
|
||||
let cell = matchstr(a:line, '|\zs[^|]\+\ze|', idx)
|
||||
let cell = substitute(cell, '^\s*\(.\{-}\)\s*$', '\1', 'g')
|
||||
call add(cells, [cnt, cell])
|
||||
let cnt += 1
|
||||
let idx = matchend(a:line, '|\zs[^|]\+\ze|', idx)
|
||||
endwhile
|
||||
return cells
|
||||
endfunction "}}}
|
||||
|
||||
function! s:get_rows(lnum) "{{{
|
||||
if !s:is_table(getline(a:lnum))
|
||||
return
|
||||
endif
|
||||
|
||||
let upper_rows = []
|
||||
let lower_rows = []
|
||||
|
||||
let lnum = a:lnum - 1
|
||||
while lnum > 1
|
||||
let line = getline(lnum)
|
||||
if s:is_table(line)
|
||||
call add(upper_rows, [lnum, line])
|
||||
else
|
||||
break
|
||||
endif
|
||||
let lnum -= 1
|
||||
endwhile
|
||||
call reverse(upper_rows)
|
||||
|
||||
let lnum = a:lnum
|
||||
while lnum <= line('$')
|
||||
let line = getline(lnum)
|
||||
if s:is_table(line)
|
||||
call add(lower_rows, [lnum, line])
|
||||
else
|
||||
break
|
||||
endif
|
||||
let lnum += 1
|
||||
endwhile
|
||||
|
||||
return upper_rows + lower_rows
|
||||
endfunction "}}}
|
||||
|
||||
function! s:get_cell_max_lens(lnum) "{{{
|
||||
let max_lens = {}
|
||||
for [lnum, row] in s:get_rows(a:lnum)
|
||||
if s:is_separator(row)
|
||||
continue
|
||||
endif
|
||||
for [idx, cell] in s:get_values(row)
|
||||
if has_key(max_lens, idx)
|
||||
let max_lens[idx] = max([s:wide_len(cell), max_lens[idx]])
|
||||
else
|
||||
let max_lens[idx] = s:wide_len(cell)
|
||||
endif
|
||||
endfor
|
||||
endfor
|
||||
return max_lens
|
||||
endfunction "}}}
|
||||
|
||||
function! s:get_aligned_rows(lnum, max_lens) "{{{
|
||||
let rows = []
|
||||
for [lnum, row] in s:get_rows(a:lnum)
|
||||
if s:is_separator(row)
|
||||
let new_row = s:fmt_sep(a:max_lens)
|
||||
else
|
||||
let new_row = s:fmt_row(row, a:max_lens)
|
||||
endif
|
||||
call add(rows, [lnum, new_row])
|
||||
endfor
|
||||
return rows
|
||||
endfunction "}}}
|
||||
" }}}
|
||||
|
||||
" Format functions {{{
|
||||
function! s:fmt_cell(cell, max_len) "{{{
|
||||
let cell = ' '.a:cell.' '
|
||||
|
||||
let diff = a:max_len - s:wide_len(a:cell)
|
||||
if diff == 0 && empty(a:cell)
|
||||
let diff = 1
|
||||
endif
|
||||
|
||||
let cell .= repeat(' ', diff)
|
||||
return cell
|
||||
endfunction "}}}
|
||||
|
||||
function! s:fmt_row(line, max_lens) "{{{
|
||||
let new_line = '|'
|
||||
let values = s:get_values(a:line)
|
||||
for [idx, cell] in values
|
||||
let new_line .= s:fmt_cell(cell, a:max_lens[idx]).'|'
|
||||
endfor
|
||||
|
||||
let idx = len(values)
|
||||
while idx < len(a:max_lens)
|
||||
let new_line .= s:fmt_cell('', a:max_lens[idx]).'|'
|
||||
let idx += 1
|
||||
endwhile
|
||||
return new_line
|
||||
endfunction "}}}
|
||||
|
||||
function! s:fmt_cell_sep(max_len) "{{{
|
||||
if a:max_len == 0
|
||||
return repeat('-', 3)
|
||||
else
|
||||
return repeat('-', a:max_len+2)
|
||||
endif
|
||||
endfunction "}}}
|
||||
|
||||
function! s:fmt_sep(max_lens) "{{{
|
||||
let sep = '|'
|
||||
for idx in range(len(a:max_lens))
|
||||
let sep .= s:fmt_cell_sep(a:max_lens[idx]).'+'
|
||||
endfor
|
||||
let sep = substitute(sep, '+$', '|', '')
|
||||
return sep
|
||||
endfunction "}}}
|
||||
"}}}
|
||||
|
||||
" Keyboard functions "{{{
|
||||
function! s:kbd_create_new_row(cols, goto_first) "{{{
|
||||
let cmd = "\<ESC>o".s:create_empty_row(a:cols)
|
||||
let cmd .= "\<ESC>:call vimwiki_tbl#format(line('.'))\<CR>"
|
||||
if a:goto_first
|
||||
let cmd .= "0f|T|a"
|
||||
else
|
||||
let cmd .= "0".(col('.')-1)."lT|a"
|
||||
endif
|
||||
return cmd
|
||||
endfunction "}}}
|
||||
|
||||
function! s:kbd_goto_next_row() "{{{
|
||||
let cmd = "\<ESC>jt|T|a"
|
||||
return cmd
|
||||
endfunction "}}}
|
||||
|
||||
function! s:kbd_goto_next_col(last) "{{{
|
||||
if col('.') == 1
|
||||
let cmd = "\<ESC>la"
|
||||
else
|
||||
if a:last
|
||||
let seps = s:count_separators(line('.'))
|
||||
let cmd = "\<ESC>".seps."j0f|F|la"
|
||||
else
|
||||
let cmd = "\<ESC>f|la"
|
||||
endif
|
||||
endif
|
||||
return cmd
|
||||
endfunction "}}}
|
||||
|
||||
"}}}
|
||||
|
||||
" Global functions {{{
|
||||
function! vimwiki_tbl#kbd_cr() "{{{
|
||||
let lnum = line('.')
|
||||
if !s:is_table(getline(lnum))
|
||||
return "\<CR>"
|
||||
endif
|
||||
|
||||
if s:is_separator(getline(lnum+1)) || !s:is_table(getline(lnum+1))
|
||||
let cols = len(s:get_values(getline(lnum)))
|
||||
return s:kbd_create_new_row(cols, 0)
|
||||
else
|
||||
return s:kbd_goto_next_row()
|
||||
endif
|
||||
endfunction "}}}
|
||||
|
||||
function! vimwiki_tbl#kbd_tab() "{{{
|
||||
let lnum = line('.')
|
||||
if !s:is_table(getline(lnum))
|
||||
return "\<Tab>"
|
||||
endif
|
||||
|
||||
let last = s:is_last_column(lnum, col('.'))
|
||||
if last && !s:is_table(getline(lnum+1))
|
||||
let cols = len(s:get_values(getline(lnum)))
|
||||
return s:kbd_create_new_row(cols, 1)
|
||||
endif
|
||||
return s:kbd_goto_next_col(last)
|
||||
endfunction "}}}
|
||||
|
||||
function! vimwiki_tbl#format(lnum) "{{{
|
||||
let line = getline(a:lnum)
|
||||
if !s:is_table(line)
|
||||
return
|
||||
endif
|
||||
|
||||
let max_lens = s:get_cell_max_lens(a:lnum)
|
||||
|
||||
for [lnum, row] in s:get_aligned_rows(a:lnum, max_lens)
|
||||
call setline(lnum, row)
|
||||
endfor
|
||||
|
||||
let &tw = s:textwidth
|
||||
endfunction "}}}
|
||||
|
||||
function! vimwiki_tbl#create(...) "{{{
|
||||
if a:0 > 1
|
||||
let cols = a:1
|
||||
let rows = a:2
|
||||
elseif a:0 == 1
|
||||
let cols = a:1
|
||||
let rows = 2
|
||||
elseif a:0 == 0
|
||||
let cols = 5
|
||||
let rows = 2
|
||||
endif
|
||||
|
||||
if cols < 1
|
||||
let cols = 5
|
||||
endif
|
||||
|
||||
if rows < 1
|
||||
let rows = 2
|
||||
endif
|
||||
|
||||
let lines = []
|
||||
let row = s:create_empty_row(cols)
|
||||
|
||||
call add(lines, row)
|
||||
if rows > 1
|
||||
call add(lines, s:create_row_sep(cols))
|
||||
endif
|
||||
|
||||
for r in range(rows - 1)
|
||||
call add(lines, row)
|
||||
endfor
|
||||
|
||||
call append(line('.'), lines)
|
||||
endfunction "}}}
|
||||
|
||||
function! vimwiki_tbl#align_or_cmd(cmd) "{{{
|
||||
if s:is_table(getline('.'))
|
||||
call vimwiki_tbl#format(line('.'))
|
||||
else
|
||||
exe 'normal! '.a:cmd
|
||||
endif
|
||||
endfunction "}}}
|
||||
|
||||
function! vimwiki_tbl#reset_tw(lnum) "{{{
|
||||
let line = getline(a:lnum)
|
||||
if !s:is_table(line)
|
||||
return
|
||||
endif
|
||||
|
||||
let s:textwidth = &tw
|
||||
let &tw = 0
|
||||
endfunction "}}}
|
||||
|
||||
"}}}
|
Reference in New Issue
Block a user