Update of /cvsroot/vim-latex/vimfiles/ftplugin/latex-suite
In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv7574
Modified Files:
texviewer.vim texrc
Added Files:
bibtools.py
Log Message:
New: A major new addition to latex-suite. It basically allows for
significantly better \cite completion:
- a better formatted list of all the entries instead of just dumping
the whole bibtex entry.
- allows for filtering the results.
- allows for sorting the results.
--- NEW FILE: bibtools.py ---
import re
class Bibliography(dict):
def __init__(self, txt, macros={}):
"""
txt:
a string which represents the entire bibtex entry. A typical
entry is of the form:
@ARTICLE{ellington:84:part3,
author = {Ellington, C P},
title = {The Aerodynamics of Hovering Insect Flight. III. Kinematics},
journal = {Philosophical Transactions of the Royal Society of London. Series B, Biological Sciences},
year = {1984},
volume = {305},
pages = {41-78},
number = {1122},
owner = {Srinath},
pdf = {C:\srinath\research\papers\Ellington-3-Kinematics.pdf},
timestamp = {2006.01.02},
}
"""
if macros:
for k, v in macros.iteritems():
txt = txt.replace(k, '{'+v+'}')
m = re.match(r'\s*@(\w+){((\S+),)?(.*)}\s*', txt, re.MULTILINE | re.DOTALL)
if not m:
return None
self['bibtype'] = m.group(1).capitalize()
self['key'] = m.group(3)
self['body'] = m.group(4)
body = self['body']
self['bodytext'] = ''
while 1:
m = re.search(r'(\S+?)\s*=\s*(.)', body)
if not m:
break
field = m.group(1)
body = body[(m.start(2)+1):]
if m.group(2) == '{':
# search for the next closing brace. This is not simply a
# matter of searching for the next closing brace since
# braces can be nested. The following code basically goes
# to the next } which has not already been closed by a
# following {.
mniter = re.finditer(r'{|}', body)
count = 1
while 1:
try:
mn = mniter.next()
except StopIteration:
return None
if mn.group(0) == '{':
count += 1
else:
count -= 1
if count == 0:
value = body[:(mn.start(0))]
break
elif m.group(2) == '"':
# search for the next unquoted double-quote. To be more
# precise, a double quote which is preceded by an even
# number of double quotes.
mn = re.search(r'(?!\\)(\\\\)*"', body)
if not mn:
return None
value = body[:(mn.start(0))]
else:
mn = re.match(r'\d+', body)
if not mn:
raise "Only completely numeral fields can be left unquoted"
value = m.group(2) + mn.group(0)
self[field] = re.sub(r'\s+', ' ', value)
body = body[(mn.start(0)+1):]
self['bodytext'] += (' %s: %s\n' % (field, value))
if self['bibtype'].lower() == 'string':
self['macro'] = {field: value}
self['bodytext'] = self['bodytext'].rstrip()
def __getitem__(self, key):
try:
return dict.__getitem__(self, key)
except KeyError:
return ''
def __str__(self):
if self['bibtype'].lower() == 'string':
return 'String: %(macro)s' % self
elif self['bibtype'].lower() == 'article':
return ('Article [%(key)s]\n' +
'TI "%(title)s"\n' +
'AU %(author)s\n' +
'IN In %(journal)s, %(year)s') % self
elif self['bibtype'].lower() == 'conference':
return ('Conference [%(key)s]\n' +
'TI "%(title)s"\n' +
'AU %(author)s\n' +
'IN In %(booktitle)s, %(year)s') % self
elif self['bibtype'].lower() == 'mastersthesis':
return ('Masters [%(key)s]\n' +
'TI "%(title)s"\n' +
'AU %(author)s\n' +
'IN In %(school)s, %(year)s') % self
elif self['bibtype'].lower() == 'phdthesis':
return ('PhD [%(key)s]\n' +
'TI "%(title)s"\n' +
'AU %(author)s\n' +
'IN In %(school)s, %(year)s') % self
elif self['bibtype'].lower() == 'book':
return ('Book [%(key)s]\n' +
'TI "%(title)s"\n' +
'AU %(author)s\n' +
'IN %(publisher)s, %(year)s') % self
else:
s = '%(bibtype)s [%(key)s]\n' % self
if self['title']:
s += 'TI "%(title)s"\n' % self
if self['author']:
s += 'AU %(author)s\n' % self
for k, v in self.iteritems():
if k not in ['title', 'author', 'bibtype', 'key', 'id', 'file', 'body', 'bodytext']:
s += 'MI %s: %s\n' % (k, v)
return s.rstrip()
def satisfies(self, filters):
for field, regexp in filters:
if not re.search(regexp, self[field], re.I):
return False
return True
class BibFile:
def __init__(self, filelist=''):
self.bibentries = []
self.filters = []
self.macros = {}
self.sortfields = []
if filelist:
for f in filelist.splitlines():
self.addfile(f)
def addfile(self, file):
fields = open(file).read().split('@')
for f in fields:
if not (f and re.match('string', f, re.I)):
continue
b = Bibliography('@' + f)
self.macros.update(b['macro'])
for f in fields:
if not f or re.match('string', f, re.I):
continue
b = Bibliography('@' + f, self.macros)
if b:
b['file'] = file
b['id'] = len(self.bibentries)
self.bibentries += [b]
def addfilter(self, filterspec):
self.filters += [filterspec.split()]
def rmfilters(self):
self.filters = []
def __str__(self):
s = ''
for b in self.bibentries:
if b['key'] and b.satisfies(self.filters):
s += '%s\n\n' % b
return s
def addsortfield(self, field):
self.sortfields += [field]
def rmsortfields(self):
self.sortfields = []
def sort(self):
def cmpfun(b1, b2):
for f in self.sortfields:
c = cmp(b1[f], b2[f])
if c:
return c
return 0
self.bibentries.sort(cmp=cmpfun)
if __name__ == "__main__":
import sys
bf = BibFile(sys.argv[1])
print bf
Index: texviewer.vim
===================================================================
RCS file: /cvsroot/vim-latex/vimfiles/ftplugin/latex-suite/texviewer.vim,v
retrieving revision 1.14
retrieving revision 1.15
diff -C2 -d -r1.14 -r1.15
*** texviewer.vim 3 Jan 2006 19:30:38 -0000 1.14
--- texviewer.vim 3 Mar 2006 01:10:32 -0000 1.15
***************
*** 60,64 ****
" What to do after <F9> depending on context
let s:curfile = expand("%:p")
! let s:curline = strpart(getline('.'), col('.') - 40, 40)
let s:prefix = matchstr(s:curline, '.*{\zs.\{-}\(}\|$\)')
" a command is of the type
--- 60,64 ----
" What to do after <F9> depending on context
let s:curfile = expand("%:p")
! let s:curline = strpart(getline('.'), 0, col('.'))
let s:prefix = matchstr(s:curline, '.*{\zs.\{-}\(}\|$\)')
" a command is of the type
***************
*** 105,109 ****
elseif exists("s:type") && s:type =~ 'cite'
! if Tex_GetVarValue('Tex_UseJabref') == 1
call Tex_CD(s:origdir)
let g:Remote_WaitingForCite = 1
--- 105,119 ----
elseif exists("s:type") && s:type =~ 'cite'
! let s:prefix = matchstr(s:prefix, '\([^,]\+,\)*\zs\([^,]\+\)\ze$')
! call Tex_Debug(":Tex_Complete: using s:prefix = ".s:prefix, "view")
!
! if has('python') && Tex_GetVarValue('Tex_UsePython')
! \ && Tex_GetVarValue('Tex_UseCiteCompletionVer2') == 1
!
! call Tex_CD(s:origdir)
! silent! call Tex_StartCiteCompletion()
!
! elseif Tex_GetVarValue('Tex_UseJabref') == 1
!
call Tex_CD(s:origdir)
let g:Remote_WaitingForCite = 1
***************
*** 118,122 ****
" TODO: Is there a way to clear the search-history w/o making a
" useless, inefficient search?
- let s:prefix = matchstr(s:prefix, '\([^,]\+,\)*\zs\([^,]\+\)\ze$')
silent! grep! ____HIGHLY_IMPROBABLE___ %
if g:Tex_RememberCiteSearch && exists('s:citeSearchHistory')
--- 128,131 ----
***************
*** 548,552 ****
call Tex_Debug('trying to search through ['.bibnames.']', 'view')
!
let &path = '.,'.g:Tex_BIBINPUTS
--- 557,561 ----
call Tex_Debug('trying to search through ['.bibnames.']', 'view')
!
let &path = '.,'.g:Tex_BIBINPUTS
***************
*** 823,826 ****
--- 832,1065 ----
endfunction " }}}
+ " ==============================================================================
+ " Functions for presenting a nicer list of bibtex entries
+ " ==============================================================================
+ " Tex_FindBibFiles: finds all .bib files used by the main file {{{
+ " Description:
+ function! Tex_FindBibFiles()
+
+ let mainfname = Tex_GetMainFileName(':p')
+ wincmd n
+ exec ':e '.mainfname
+
+ if search('\\\(no\)\?bibliography{', 'w')
+
+ call Tex_Debug('Tex_FindBibFiles: found bibliography command in '.bufname('%'), 'view')
+
+ " extract the bibliography filenames from the command.
+ let bibnames = matchstr(getline('.'), '\\\(no\)\?bibliography{\zs.\{-}\ze}')
+ let bibnames = substitute(bibnames, '\s', '', 'g')
+
+ call Tex_Debug(':Tex_FindBibFiles: trying to search through ['.bibnames.']', 'view')
+
+ let _path = &path
+ let &path = '.,'.g:Tex_BIBINPUTS
+
+ let bibfiles = ''
+ let i = 1
+ while Tex_Strntok(bibnames, ',', i) != ''
+ " split a new window so we do not screw with the current buffer.
+ split
+ let thisbufnum = bufnr('%')
+
+ call Tex_Debug(':Tex_FindBibFiles: silent! find '.Tex_Strntok(bibnames, ',', i).'.bib', 'view')
+ exec 'silent! find '.Tex_Strntok(bibnames, ',', i).'.bib'
+ if bufnr('%') != thisbufnum
+ call Tex_Debug(':Tex_FindBibFiles: finding .bib file ['.bufname('%').']', 'view')
+ " use the appropriate syntax for the .bib file.
+ let bibfiles = bibfiles.expand('%:p')."\n"
+ endif
+
+ q
+
+ let i = i + 1
+ endwhile
+
+ call Tex_Debug(":Tex_FindBibFiles: returning [".bibfiles."]", "view")
+ let &path = _path
+ q
+ return bibfiles
+
+ else
+ q
+ return ''
+ endif
+
+ endfunction " }}}
+ " Tex_StartBibtexOutline: sets up an outline window {{{
+
+ " get the place where this plugin resides for setting cpt and dict options.
+ " these lines need to be outside the function.
+ if has('python') && Tex_GetVarValue('Tex_UsePython')
+ python import sys, re
+ exec "python sys.path += [r'". s:path . "']"
+ python import bibtools
+ endif
+
+ function! Tex_StartCiteCompletion()
+ let mainfname = Tex_GetMainFileName(':p')
+ let bibfiles = Tex_FindBibFiles()
+
+ bot split __OUTLINE__
+ exec Tex_GetVarValue('Tex_OutlineWindowHeight', 15).' wincmd _'
+
+ exec 'python Tex_BibFile = bibtools.BibFile("""'.bibfiles.'""")'
+ exec 'python Tex_BibFile.addfilter("key ^'.s:prefix.'")'
+ call Tex_DisplayBibList()
+
+ nnoremap <Plug>Tex_JumpToNextBibEntry :call search('^\S.*\]$', 'W')<CR>:call Tex_EchoBibShortcuts()<CR>z.
+ nnoremap <Plug>Tex_JumpToPrevBibEntry :call search('^\S.*\]$', 'bW')<CR>:call Tex_EchoBibShortcuts()<CR>z.
+ nnoremap <Plug>Tex_FilterBibEntries :call Tex_HandleBibShortcuts('filter')<CR>
+ nnoremap <Plug>Tex_RemoveBibFilters :call Tex_HandleBibShortcuts('remove_filters')<CR>
+ nnoremap <Plug>Tex_SortBibEntries :call Tex_HandleBibShortcuts('sort')<CR>
+ nnoremap <Plug>Tex_CompleteCiteEntry :call Tex_CompleteCiteEntry()<CR>
+
+ nmap <buffer> <silent> n <Plug>Tex_JumpToNextBibEntry
+ nmap <buffer> <silent> p <Plug>Tex_JumpToPrevBibEntry
+ nmap <buffer> <silent> f <Plug>Tex_FilterBibEntries
+ nmap <buffer> <silent> s <Plug>Tex_SortBibEntries
+ nmap <buffer> <silent> a <Plug>Tex_RemoveBibFilters
+ nmap <buffer> <silent> q :close<CR>
+ nmap <buffer> <silent> <CR> <Plug>Tex_CompleteCiteEntry
+
+ endfunction " }}}
+ " Tex_DisplayBibList: displays the list of bibtex entries {{{
+ " Description:
+ function! Tex_DisplayBibList()
+ " open the buffer
+ let _report = &report
+ let _cmdheight=&cmdheight
+ let _lazyredraw = &lazyredraw
+ set report=1000
+ set cmdheight=1
+ set lazyredraw
+
+ setlocal modifiable
+ setlocal noswapfile
+ setlocal buftype=nowrite
+ setlocal bufhidden=delete
+ setlocal nowrap
+ setlocal foldmethod=marker
+ setlocal foldmarker=<<<,>>>
+
+
+ " delete everything in it to the blackhole
+ % d _
+
+ exec 'python Tex_CurBuf = vim.current.buffer'
+ exec 'python Tex_CurBuf[:] = str(Tex_BibFile).splitlines()'
+
+ call Tex_SetupBibSyntax()
+
+ 0
+ call Tex_EchoBibShortcuts()
+
+ " once the buffer is initialized, go back to the original settings.
+ setlocal nomodifiable
+ setlocal nomodified
+ let &report = _report
+ let &cmdheight = _cmdheight
+ let &lazyredraw = _lazyredraw
+
+ endfunction " }}}
+ " Tex_EchoBibShortcuts: echos all the shortcuts in the status line {{{
+ " Description:
+ function! Tex_EchoBibShortcuts()
+ echomsg '(a) all (f) filter (s) sort (n) next (p) previous (q) quit (<CR>) choose'
+ endfunction " }}}
+ " Tex_SetupBibSyntax: sets up the syntax items for the outline {{{
+ " Description:
+ function! Tex_SetupBibSyntax()
+ syn match BibTitleHeader "^TI" contained
+ syn match BibAuthorHeader "^AU" contained
+ syn match BibLocationHeader "^IN" contained
+ syn match BibMiscHeader "^MI" contained
+
+ syn match BibKeyLine '^\S.*\]$' contains=BibKey
+ syn match BibTitle "^TI .*" contains=BibTitleHeader
+ syn match BibAuthor "^AU .*" contains=BibAuthorHeader
+ syn match BibLocation "^IN .*" contains=BibLocationHeader
+ syn match BibMisc "^MI .*" contains=BibMiscHeader
+
+ hi def link BibTitleHeader Ignore
+ hi def link BibAuthorHeader Ignore
+ hi def link BibLocationHeader Ignore
+ hi def link BibMiscHeader Ignore
+
+ hi def link BibKeyLine Visual
+ hi def link BibTitle Type
+ hi def link BibAuthor Special
+ hi def link BibLocation Comment
+ hi def link BibMisc Comment
+ endfunction " }}}
+ " Tex_HandleBibShortcuts: handles user keypresses {{{
+ " Description:
+ function! Tex_HandleBibShortcuts(command)
+
+ if a:command == 'filter' || a:command == 'sort'
+
+ let fieldprompt =
+ \ "Field acronyms: (`:let g:Tex_EchoBibFields = 0` to avoid this message)\n" .
+ \ " [t] title [a] author [b] booktitle \n" .
+ \ " [j] journal [y] year [p] bibtype \n" .
+ \ " (you can also enter the complete field name) \n"
+
+ let fieldprompt = Tex_GetVarValue('Tex_BibFieldPrompt', fieldprompt)
+
+ if Tex_GetVarValue('Tex_EchoBibFields', 1) == 1
+ echo fieldprompt
+ endif
+
+ let inp = input('Enter '.a:command.' criterion [field<space>value]: ')
+
+ if inp != ''
+ " If the field is specified as a single character, then replace
+ " it with the corresponding 'full form'.
+ if inp =~ '^[a-z]\>'
+ if Tex_GetVarValue('Tex_BibAcronym_'.inp[0]) != ''
+ let inp = substitute(inp, '.', Tex_GetVarValue('Tex_BibAcronym_'.inp[0]), '')
+ elseif fieldprompt =~ '\['.inp[0].'\]'
+ let full = matchstr(fieldprompt, '\['.inp[0].'\] \zs\w\+\ze')
+ let inp = substitute(inp, '.', full, '')
+ endif
+ endif
+ call Tex_Debug(":Tex_HandleBibShortcuts: using inp = [".inp."]", "view")
+ if a:command == 'filter'
+ exec 'python Tex_BibFile.addfilter("'.inp.'")'
+ elseif a:command == 'sort'
+ exec "python Tex_BibFile.addsortfield(\"".inp."\")"
+ exec 'python Tex_BibFile.sort()'
+ endif
+ call Tex_DisplayBibList()
+ endif
+
+ elseif a:command == 'remove_filters'
+
+ exec 'python Tex_BibFile.rmfilters()'
+ exec 'python Tex_BibFile.addfilter("key '.s:prefix.'")'
+ call Tex_DisplayBibList()
+
+ endif
+
+ endfunction " }}}
+ " Tex_CompleteCiteEntry: completes cite entry {{{
+ " Description:
+ function! Tex_CompleteCiteEntry()
+ normal! 0
+ call search('\[\S\+\]$', 'W')
+ if getline('.') !~ '\[\S\+\]$'
+ call search('\[\S\+\]$', 'bW')
+ endif
+
+ if getline('.') !~ '\[\S\+\]$'
+ return
+ endif
+
+ let ref = matchstr(getline('.'), '\[\zs\S\+\ze\]$')
+ close
+ call Tex_Debug(":Tex_CompleteCiteEntry: completing with ".ref, "view")
+ call Tex_CompleteWord(strpart(ref, strlen(s:prefix)))
+ endfunction " }}}
+
com! -nargs=0 TClearCiteHist unlet! s:citeSearchHistory
Index: texrc
===================================================================
RCS file: /cvsroot/vim-latex/vimfiles/ftplugin/latex-suite/texrc,v
retrieving revision 1.47
retrieving revision 1.48
diff -C2 -d -r1.47 -r1.48
*** texrc 18 Jun 2004 23:59:48 -0000 1.47
--- texrc 3 Mar 2006 01:10:32 -0000 1.48
***************
*** 551,572 ****
" ==============================================================================
" TeX Completion: {{{
! "
! " Options for preview window for ref/cite completion.
" Height of cwindow
- " Default: 5
TexLet g:Tex_ViewerCwindowHeight = 5
" Height of preview window
- " Default: 10
TexLet g:Tex_ViewerPreviewHeight = 10
" Options for explorer completion.
" Height of explorer window
- " Default: 10
TexLet g:Tex_ExplorerHeight = 10
" Directory for images. Read |latex-completion-explorer| before changing
- " Default: ''
TexLet g:Tex_ImageDir = ''
" whether or not searches for \cite's are cached.
TexLet g:Tex_RememberCiteSearch = 0
--- 551,642 ----
" ==============================================================================
" TeX Completion: {{{
!
! " Options for controlling the window sizes of the completion windows {{{
!
! " The height of the window which contains the \label's (when completing a
! " \ref) or bibtex entries (when completing a \cite). This option is used in
! " the newer methods of completing \ref's and \cite's.
! TexLet g:Tex_OutlineWindowHeight = 15
!
! " Options for preview window for ref/cite completion. The next two options
! " are used only when g:Tex_UseOutlineCompletion = 0 or
! " g:Tex_UseCiteCompletionVer2 = 0, i.e, when we use a classic method of
! " completing \refs and \cites.
" Height of cwindow
TexLet g:Tex_ViewerCwindowHeight = 5
" Height of preview window
TexLet g:Tex_ViewerPreviewHeight = 10
" Options for explorer completion.
" Height of explorer window
TexLet g:Tex_ExplorerHeight = 10
" Directory for images. Read |latex-completion-explorer| before changing
TexLet g:Tex_ImageDir = ''
+ " }}}
+ " Options for completing a \ref {{{
+
+ " Whether to use the "outline mode" for displaying the \label's while doing
+ " \ref completion. In this mode, each label is displayed within the
+ " document element it resides in. The entire thing is folded to ease
+ " navigation. Should be easier/faster than the classical mode.
+ TexLet g:Tex_UseOutlineCompletion = 1
+
+ " This option should be set via the .latexmain file. It should be a newline
+ " seperated list of files which make up all the "source" files in the
+ " current project. This enables latex-suite to skip the more complicated
+ " algorithm of finding the source files by recursively searching for
+ " \input'ed files from the |latex-master-file|.
+ "
+ " Only used when g:Tex_UseOutlineCompletion = 0.
+ TexLet g:Tex_ProjectSourceFiles = ''
+
+ " Whether latex-suite simply searches for \\label's in all the .tex file
+ " found in the current directory or whether it will use a more complex
+ " algorithm. This is used only g:Tex_UseOutlineCompletion = 0 and
+ " g:Tex_ProjectSourceFiles = ''.
+ " See
+ " :help Tex_UseSimpleLabelSearch
+ " for more information
+ TexLet g:Tex_UseSimpleLabelSearch = 0
+
+ " }}}
+ " Options for completing a \cite'ation {{{
+
+ " If set to 1, then the newer way of presenting the bibtex entries is used.
+ " Instead of a |cwindow| showing just the keys and a synced |preview|
+ " window beneath, show a single window containing a nicely formatted list
+ " of bibtex entries. This should be faster and easier to use than the
+ " classic mode
+ TexLet g:Tex_UseCiteCompletionVer2 = 1
+
+ " This is a string which is displayed to the user when he wants to sort or
+ " filter the bibtex entries. This string also serves to define acronyms for
+ " the various fields of a bibtex entry.
+ TexLet g:Tex_BibFieldPrompt =
+ \ "Field acronyms: (`:let g:Tex_EchoBibFields = 0` to avoid this message)\n" .
+ \ " [t] title [a] author [b] booktitle \n" .
+ \ " [j] journal [y] year [p] bibtype \n" .
+ \ " (you can also enter the complete field name) \n"
+
+ " Whether or not to display the string above to aid the user in choosing
+ " the field to filter/sort with.
+ TexLet g:Tex_EchoBibFields = 1
+
+ " A setting of this form defines the letter 'a' as standing for the field
+ " 'author'. Thus when the user types
+ " a ellington
+ " when asked to enter a filter, it is equivalent to the user specifying the
+ " filter
+ " author ellington
+ " TexLet g:Tex_BibAcronym_a = 'author'
+
+ " Whether or not to use Jabref to complete citations
+ " See
+ " :help latex-suite-jabref
+ " for more infomration
+ TexLet g:Tex_UseJabref = 0
+
" whether or not searches for \cite's are cached.
TexLet g:Tex_RememberCiteSearch = 0
***************
*** 575,584 ****
TexLet g:Tex_TEXINPUTS = ''
! " Whether latex-suite simply searches for \\label's in all the .tex file found
! " in the current directory or whether it will use a more complex algorithm.
! " See
! " :help Tex_UseSimpleLabelSearch
! " for more information
! TexLet g:Tex_UseSimpleLabelSearch = 0
" }}}
--- 645,649 ----
TexLet g:Tex_TEXINPUTS = ''
! " }}}
" }}}
|