2013-10-05 07:53:42 -04:00
|
|
|
" {{{1 latex#toc#init
|
|
|
|
function! latex#toc#init(initialized)
|
2013-10-10 15:48:52 -04:00
|
|
|
if g:latex_mappings_enabled && g:latex_toc_enabled
|
2013-10-05 07:53:42 -04:00
|
|
|
nnoremap <silent><buffer> <LocalLeader>lt :call latex#toc#open()<cr>
|
|
|
|
nnoremap <silent><buffer> <LocalLeader>lT :call latex#toc#toggle()<cr>
|
|
|
|
endif
|
|
|
|
endfunction
|
|
|
|
|
|
|
|
" {{{1 latex#toc#open
|
|
|
|
function! latex#toc#open()
|
2014-07-04 14:15:28 -04:00
|
|
|
" Go to TOC if it already exists
|
2013-10-05 07:53:42 -04:00
|
|
|
let winnr = bufwinnr(bufnr('LaTeX TOC'))
|
|
|
|
if winnr >= 0
|
|
|
|
silent execute winnr . 'wincmd w'
|
|
|
|
return
|
|
|
|
endif
|
|
|
|
|
2014-07-04 14:15:28 -04:00
|
|
|
" Store current buffer number and position
|
2013-10-05 07:53:42 -04:00
|
|
|
let calling_buf = bufnr('%')
|
|
|
|
let calling_file = expand('%:p')
|
2014-07-04 14:15:28 -04:00
|
|
|
let calling_line = line('.')
|
2014-07-01 16:34:26 -04:00
|
|
|
|
2014-07-04 14:15:28 -04:00
|
|
|
" Parse tex files for TOC data
|
2014-07-08 06:32:41 -04:00
|
|
|
let toc = s:parse_file(g:latex#data[b:latex.id].tex, 1)
|
2014-07-04 14:15:28 -04:00
|
|
|
|
|
|
|
" Resize vim session if wanted, then create TOC window
|
2013-10-05 07:53:42 -04:00
|
|
|
if g:latex_toc_resize
|
|
|
|
silent exe "set columns+=" . g:latex_toc_width
|
|
|
|
endif
|
2014-07-01 16:34:26 -04:00
|
|
|
silent exe g:latex_toc_split_side g:latex_toc_width . 'vnew LaTeX\ TOC'
|
2014-07-04 14:15:28 -04:00
|
|
|
|
|
|
|
" Set buffer local variables
|
2014-07-01 16:34:26 -04:00
|
|
|
let b:toc = toc
|
|
|
|
let b:toc_numbers = 1
|
|
|
|
let b:calling_win = bufwinnr(calling_buf)
|
|
|
|
|
2014-07-04 14:15:28 -04:00
|
|
|
" Add TOC entries (keep track of closest index)
|
|
|
|
let index = 0
|
|
|
|
let closest_index = 0
|
2014-07-01 16:34:26 -04:00
|
|
|
for entry in toc
|
2014-07-04 14:15:28 -04:00
|
|
|
call append('$', entry.number . "\t" . entry.title)
|
|
|
|
let index += 1
|
|
|
|
if closest_index == 0
|
|
|
|
if calling_file == entry.file && calling_line > entry.line
|
|
|
|
let closest_index = index
|
|
|
|
endif
|
|
|
|
endif
|
2014-07-01 16:34:26 -04:00
|
|
|
endfor
|
2013-10-05 07:53:42 -04:00
|
|
|
|
2014-07-04 14:15:28 -04:00
|
|
|
" Add help info (if desired)
|
2013-10-05 07:53:42 -04:00
|
|
|
if !g:latex_toc_hide_help
|
|
|
|
call append('$', "")
|
|
|
|
call append('$', "<Esc>/q: close")
|
|
|
|
call append('$', "<Space>: jump")
|
|
|
|
call append('$', "<Enter>: jump and close")
|
|
|
|
call append('$', "s: hide numbering")
|
|
|
|
endif
|
|
|
|
|
2014-07-04 14:15:28 -04:00
|
|
|
" Delete empty first line and jump to the closest section
|
|
|
|
0delete _
|
|
|
|
call setpos('.', [0, closest_index, 0, 0])
|
2013-10-23 15:00:20 -04:00
|
|
|
|
2013-10-05 07:53:42 -04:00
|
|
|
" Set filetype and lock buffer
|
|
|
|
setlocal filetype=latextoc
|
|
|
|
setlocal nomodifiable
|
|
|
|
endfunction
|
|
|
|
|
|
|
|
" {{{1 latex#toc#toggle
|
|
|
|
function! latex#toc#toggle()
|
|
|
|
if bufwinnr(bufnr('LaTeX TOC')) >= 0
|
|
|
|
if g:latex_toc_resize
|
|
|
|
silent exe "set columns-=" . g:latex_toc_width
|
|
|
|
endif
|
|
|
|
silent execute 'bwipeout' . bufnr('LaTeX TOC')
|
|
|
|
else
|
|
|
|
call latex#toc#open()
|
|
|
|
silent execute 'wincmd w'
|
|
|
|
endif
|
|
|
|
endfunction
|
|
|
|
" }}}1
|
|
|
|
|
2014-07-04 14:15:28 -04:00
|
|
|
" {{{1 s:parse_file
|
2014-07-08 06:32:41 -04:00
|
|
|
function! s:parse_file(file, ...)
|
2014-07-04 14:15:28 -04:00
|
|
|
" Parses tex file for TOC entries
|
|
|
|
"
|
|
|
|
" The function returns a list of entries. Each entry is a dictionary:
|
|
|
|
"
|
|
|
|
" entry = {
|
|
|
|
" title : "Some title",
|
|
|
|
" number : "3.1.2",
|
|
|
|
" file : /path/to/file.tex,
|
|
|
|
" line : 142,
|
|
|
|
" }
|
|
|
|
|
|
|
|
" Test if file is readable
|
|
|
|
if ! filereadable(a:file)
|
|
|
|
echoerr "Error in latex#toc s:parse_file:"
|
|
|
|
echoerr "File not readable: " . a:file
|
|
|
|
return []
|
2013-10-05 07:53:42 -04:00
|
|
|
endif
|
|
|
|
|
2014-07-08 06:32:41 -04:00
|
|
|
" Set limits for TOC numbering (only for the first call)
|
|
|
|
if a:0 > 0
|
|
|
|
let s:number = {}
|
|
|
|
endif
|
|
|
|
|
2014-07-04 14:15:28 -04:00
|
|
|
let toc = []
|
|
|
|
|
|
|
|
let lnum = 0
|
|
|
|
for line in readfile(a:file)
|
2014-07-01 16:34:26 -04:00
|
|
|
let lnum += 1
|
2014-07-04 14:15:28 -04:00
|
|
|
|
2014-07-08 06:32:41 -04:00
|
|
|
" 1. Parse inputs or includes
|
|
|
|
if line =~# s:re_input
|
2014-07-04 14:15:28 -04:00
|
|
|
call extend(toc, s:parse_file(s:parse_line_input(line)))
|
|
|
|
continue
|
|
|
|
endif
|
|
|
|
|
2014-07-08 06:32:41 -04:00
|
|
|
" 2. Parse chapters, sections, and subsections
|
|
|
|
if line =~# s:re_sec
|
2014-07-04 14:15:28 -04:00
|
|
|
call add(toc, s:parse_line_sec(a:file, lnum, line))
|
|
|
|
continue
|
|
|
|
endif
|
2014-07-01 16:34:26 -04:00
|
|
|
endfor
|
2013-10-05 07:53:42 -04:00
|
|
|
|
2014-07-01 16:34:26 -04:00
|
|
|
return toc
|
|
|
|
endfunction
|
2013-10-05 07:53:42 -04:00
|
|
|
|
2014-07-04 14:15:28 -04:00
|
|
|
"}}}1
|
|
|
|
" {{{1 s:parse_line_input
|
2014-07-08 06:32:41 -04:00
|
|
|
let s:re_input = '\v^\s*\\%(input|include)\s*\{'
|
|
|
|
let s:re_input_file = s:re_input . '\zs[^\}]+\ze}'
|
|
|
|
|
2014-07-04 14:15:28 -04:00
|
|
|
function! s:parse_line_input(line)
|
2014-07-08 06:32:41 -04:00
|
|
|
let l:file = matchstr(a:line, s:re_input_file)
|
2014-07-04 14:15:28 -04:00
|
|
|
if l:file !~# '.tex$'
|
|
|
|
let l:file .= '.tex'
|
2013-10-05 07:53:42 -04:00
|
|
|
endif
|
2014-07-04 14:15:28 -04:00
|
|
|
return fnamemodify(l:file, ':p')
|
|
|
|
endfunction
|
|
|
|
|
|
|
|
" }}}1
|
|
|
|
" {{{1 s:parse_line_sec
|
2014-07-08 06:32:41 -04:00
|
|
|
let s:re_sec = '\v^\s*\\%(chapter|%(sub)*section)\*?\s*\{'
|
|
|
|
let s:re_sec_level = '\v^\s*\\\zs%(chapter|%(sub)*section)\*?'
|
|
|
|
let s:re_sec_title = s:re_sec . '\zs.{-}\ze\}?$'
|
|
|
|
|
2014-07-04 14:15:28 -04:00
|
|
|
function! s:parse_line_sec(file, lnum, line)
|
2014-07-08 06:32:41 -04:00
|
|
|
let title = matchstr(a:line, s:re_sec_title)
|
|
|
|
let level = matchstr(a:line, s:re_sec_level)
|
2014-07-04 14:15:28 -04:00
|
|
|
|
|
|
|
return {
|
2014-07-08 06:32:41 -04:00
|
|
|
\ 'title' : title,
|
|
|
|
\ 'number' : s:get_number(level),
|
2014-07-04 14:15:28 -04:00
|
|
|
\ 'file' : a:file,
|
|
|
|
\ 'line' : a:lnum,
|
|
|
|
\ }
|
2013-10-05 07:53:42 -04:00
|
|
|
endfunction
|
|
|
|
|
2014-07-08 06:32:41 -04:00
|
|
|
function! s:get_number(level)
|
|
|
|
if a:level =~# '\v%(part|chapter|(sub)*section)$'
|
|
|
|
if has_key(s:number, a:level)
|
|
|
|
let s:number.a:level += 1
|
|
|
|
else
|
|
|
|
let s:number.a:level = 1
|
|
|
|
endif
|
|
|
|
else
|
|
|
|
return ''
|
|
|
|
endif
|
2013-10-05 07:53:42 -04:00
|
|
|
|
2014-07-08 06:32:41 -04:00
|
|
|
return PP(s:number)
|
2014-07-04 14:15:28 -04:00
|
|
|
endfunction
|
2014-07-08 06:32:41 -04:00
|
|
|
|
2014-07-04 14:15:28 -04:00
|
|
|
" }}}1
|
|
|
|
|
2014-02-10 08:21:43 -05:00
|
|
|
" vim: fdm=marker
|