summaryrefslogtreecommitdiffstats
path: root/autoload/vimtex/parser/bib.vim
diff options
context:
space:
mode:
Diffstat (limited to 'autoload/vimtex/parser/bib.vim')
-rw-r--r--autoload/vimtex/parser/bib.vim370
1 files changed, 0 insertions, 370 deletions
diff --git a/autoload/vimtex/parser/bib.vim b/autoload/vimtex/parser/bib.vim
deleted file mode 100644
index 7ea2c238..00000000
--- a/autoload/vimtex/parser/bib.vim
+++ /dev/null
@@ -1,370 +0,0 @@
-if !exists('g:polyglot_disabled') || index(g:polyglot_disabled, 'latex') == -1
-
-" vimtex - LaTeX plugin for Vim
-"
-" Maintainer: Karl Yngve LervÄg
-" Email: karl.yngve@gmail.com
-"
-
-function! vimtex#parser#bib#parse(file, opts) abort " {{{1
- if !filereadable(a:file) | return [] | endif
-
- let l:backend = get(a:opts, 'backend', g:vimtex_parser_bib_backend)
-
- if l:backend ==# 'bibtex'
- if !executable('bibtex') | let l:backend = 'vim' | endif
- elseif l:backend ==# 'bibparse'
- if !executable('bibparse') | let l:backend = 'vim' | endif
- else
- let l:backend = 'vim'
- endif
-
- return s:parse_with_{l:backend}(a:file)
-endfunction
-
-" }}}1
-
-
-function! s:parse_with_bibtex(file) abort " {{{1
- call s:parse_with_bibtex_init()
- if s:bibtex_not_executable | return [] | endif
-
- " Define temporary files
- let tmp = {
- \ 'aux' : 'tmpfile.aux',
- \ 'bbl' : 'tmpfile.bbl',
- \ 'blg' : 'tmpfile.blg',
- \ }
-
- " Write temporary aux file
- call writefile([
- \ '\citation{*}',
- \ '\bibstyle{' . s:bibtex_bstfile . '}',
- \ '\bibdata{' . fnamemodify(a:file, ':r') . '}',
- \ ], tmp.aux)
-
- " Create the temporary bbl file
- call vimtex#process#run('bibtex -terse ' . fnameescape(tmp.aux), {
- \ 'background' : 0,
- \ 'silent' : 1,
- \})
-
- " Parse temporary bbl file
- let lines = join(readfile(tmp.bbl), "\n")
- let lines = substitute(lines, '\n\n\@!\(\s\=\)\s*\|{\|}', '\1', 'g')
- let lines = vimtex#util#tex2unicode(lines)
- let lines = split(lines, "\n")
-
- let l:entries = []
- for line in lines
- let matches = split(line, '||')
- if empty(matches) || empty(matches[0]) | continue | endif
-
- let l:entry = {
- \ 'key': matches[0],
- \ 'type': matches[1],
- \}
-
- if !empty(matches[2])
- let l:entry.author = matches[2]
- endif
- if !empty(matches[3])
- let l:entry.year = matches[3]
- endif
- if !empty(get(matches, 4, ''))
- let l:entry.title = get(matches, 4, '')
- endif
-
- call add(l:entries, l:entry)
- endfor
-
- " Clean up
- call delete(tmp.aux)
- call delete(tmp.bbl)
- call delete(tmp.blg)
-
- return l:entries
-endfunction
-
-" }}}1
-function! s:parse_with_bibtex_init() abort " {{{1
- if exists('s:bibtex_init_done') | return | endif
-
- " Check if bibtex is executable
- let s:bibtex_not_executable = !executable('bibtex')
- if s:bibtex_not_executable
- call vimtex#log#warning(
- \ 'bibtex is not executable and may not be used to parse bib files!')
- endif
-
- " Check if bstfile contains whitespace (not handled by vimtex)
- if stridx(s:bibtex_bstfile, ' ') >= 0
- let l:oldbst = s:bibtex_bstfile . '.bst'
- let s:bibtex_bstfile = tempname()
- call writefile(readfile(l:oldbst), s:bibtex_bstfile . '.bst')
- endif
-
- let s:bibtex_init_done = 1
-endfunction
-
-let s:bibtex_bstfile = expand('<sfile>:p:h') . '/vimcomplete'
-
-" }}}1
-
-function! s:parse_with_bibparse(file) abort " {{{1
- call s:parse_with_bibparse_init()
- if s:bibparse_not_executable | return [] | endif
-
- call vimtex#process#run('bibparse ' . fnameescape(a:file)
- \ . ' >_vimtex_bibparsed.log', {'background' : 0, 'silent' : 1})
- let l:lines = readfile('_vimtex_bibparsed.log')
- call delete('_vimtex_bibparsed.log')
-
- let l:current = {}
- let l:entries = []
- for l:line in l:lines
- if l:line[0] ==# '@'
- if !empty(l:current)
- call add(l:entries, l:current)
- let l:current = {}
- endif
-
- let l:index = stridx(l:line, ' ')
- if l:index > 0
- let l:type = l:line[1:l:index-1]
- let l:current.type = l:type
- let l:current.key = l:line[l:index+1:]
- endif
- elseif !empty(l:current)
- let l:index = stridx(l:line, '=')
- if l:index < 0 | continue | endif
-
- let l:key = l:line[:l:index-1]
- let l:value = l:line[l:index+1:]
- let l:current[tolower(l:key)] = l:value
- endif
- endfor
-
- if !empty(l:current)
- call add(l:entries, l:current)
- endif
-
- return l:entries
-endfunction
-
-" }}}1
-function! s:parse_with_bibparse_init() abort " {{{1
- if exists('s:bibparse_init_done') | return | endif
-
- " Check if bibtex is executable
- let s:bibparse_not_executable = !executable('bibparse')
- if s:bibparse_not_executable
- call vimtex#log#warning(
- \ 'bibparse is not executable and may not be used to parse bib files!')
- endif
-
- let s:bibparse_init_done = 1
-endfunction
-
-" }}}1
-
-function! s:parse_with_vim(file) abort " {{{1
- " Adheres to the format description found here:
- " http://www.bibtex.org/Format/
-
- if !filereadable(a:file)
- return []
- endif
-
- let l:current = {}
- let l:strings = {}
- let l:entries = []
- for l:line in filter(readfile(a:file), 'v:val !~# ''^\s*\%(%\|$\)''')
- if empty(l:current)
- if s:parse_type(l:line, l:current, l:strings)
- let l:current = {}
- endif
- continue
- endif
-
- if l:current.type ==# 'string'
- if s:parse_string(l:line, l:current, l:strings)
- let l:current = {}
- endif
- else
- if s:parse_entry(l:line, l:current, l:entries)
- let l:current = {}
- endif
- endif
- endfor
-
- return map(l:entries, 's:parse_entry_body(v:val, l:strings)')
-endfunction
-
-" }}}1
-
-function! s:parse_type(line, current, strings) abort " {{{1
- let l:matches = matchlist(a:line, '\v^\@(\w+)\s*\{\s*(.*)')
- if empty(l:matches) | return 0 | endif
-
- let l:type = tolower(l:matches[1])
- if index(['preamble', 'comment'], l:type) >= 0 | return 0 | endif
-
- let a:current.level = 1
- let a:current.body = ''
-
- if l:type ==# 'string'
- return s:parse_string(l:matches[2], a:current, a:strings)
- else
- let a:current.type = l:type
- let a:current.key = matchstr(l:matches[2], '.*\ze,\s*')
- return 0
- endif
-endfunction
-
-" }}}1
-function! s:parse_string(line, string, strings) abort " {{{1
- let a:string.level += s:count(a:line, '{') - s:count(a:line, '}')
- if a:string.level > 0
- let a:string.body .= a:line
- return 0
- endif
-
- let a:string.body .= matchstr(a:line, '.*\ze}')
-
- let l:matches = matchlist(a:string.body, '\v^\s*(\w+)\s*\=\s*"(.*)"\s*$')
- if !empty(l:matches) && !empty(l:matches[1])
- let a:strings[l:matches[1]] = l:matches[2]
- endif
-
- return 1
-endfunction
-
-" }}}1
-function! s:parse_entry(line, entry, entries) abort " {{{1
- let a:entry.level += s:count(a:line, '{') - s:count(a:line, '}')
- if a:entry.level > 0
- let a:entry.body .= a:line
- return 0
- endif
-
- let a:entry.body .= matchstr(a:line, '.*\ze}')
-
- call add(a:entries, a:entry)
- return 1
-endfunction
-
-" }}}1
-
-function! s:parse_entry_body(entry, strings) abort " {{{1
- unlet a:entry.level
-
- let l:key = ''
- let l:pos = matchend(a:entry.body, '^\s*')
- while l:pos >= 0
- if empty(l:key)
- let [l:key, l:pos] = s:get_key(a:entry.body, l:pos)
- else
- let [l:value, l:pos] = s:get_value(a:entry.body, l:pos, a:strings)
- let a:entry[l:key] = l:value
- let l:key = ''
- endif
- endwhile
-
- unlet a:entry.body
- return a:entry
-endfunction
-
-" }}}1
-function! s:get_key(body, head) abort " {{{1
- " Parse the key part of a bib entry tag.
- " Assumption: a:body is left trimmed and either empty or starts with a key.
- " Returns: The key and the remaining part of the entry body.
-
- let l:matches = matchlist(a:body, '^\v(\w+)\s*\=\s*', a:head)
- return empty(l:matches)
- \ ? ['', -1]
- \ : [tolower(l:matches[1]), a:head + strlen(l:matches[0])]
-endfunction
-
-" }}}1
-function! s:get_value(body, head, strings) abort " {{{1
- " Parse the value part of a bib entry tag, until separating comma or end.
- " Assumption: a:body is left trimmed and either empty or starts with a value.
- " Returns: The value and the remaining part of the entry body.
- "
- " A bib entry value is either
- " 1. A number.
- " 2. A concatenation (with #s) of double quoted strings, curlied strings,
- " and/or bibvariables,
- "
- if a:body[a:head] =~# '\d'
- let l:value = matchstr(a:body, '^\d\+', a:head)
- let l:head = matchend(a:body, '^\s*,\s*', a:head + len(l:value))
- return [l:value, l:head]
- else
- return s:get_value_string(a:body, a:head, a:strings)
- endif
-
- return ['s:get_value failed', -1]
-endfunction
-
-" }}}1
-function! s:get_value_string(body, head, strings) abort " {{{1
- if a:body[a:head] ==# '{'
- let l:sum = 1
- let l:i1 = a:head + 1
- let l:i0 = l:i1
-
- while l:sum > 0
- let [l:match, l:_, l:i1] = matchstrpos(a:body, '[{}]', l:i1)
- if l:i1 < 0 | break | endif
-
- let l:i0 = l:i1
- let l:sum += l:match ==# '{' ? 1 : -1
- endwhile
-
- let l:value = a:body[a:head+1:l:i0-2]
- let l:head = matchend(a:body, '^\s*', l:i0)
- elseif a:body[a:head] ==# '"'
- let l:index = match(a:body, '\\\@<!"', a:head+1)
- if l:index < 0
- return ['s:get_value_string failed', '']
- endif
-
- let l:value = a:body[a:head+1:l:index-1]
- let l:head = matchend(a:body, '^\s*', l:index+1)
- return [l:value, l:head]
- elseif a:body[a:head:] =~# '^\w'
- let l:value = matchstr(a:body, '^\w\+', a:head)
- let l:head = matchend(a:body, '^\s*', a:head + strlen(l:value))
- let l:value = get(a:strings, l:value, '@(' . l:value . ')')
- else
- let l:head = a:head
- endif
-
- if a:body[l:head] ==# '#'
- let l:head = matchend(a:body, '^\s*', l:head + 1)
- let [l:vadd, l:head] = s:get_value_string(a:body, l:head, a:strings)
- let l:value .= l:vadd
- endif
-
- return [l:value, matchend(a:body, '^,\s*', l:head)]
-endfunction
-
-" }}}1
-
-function! s:count(container, item) abort " {{{1
- " Necessary because in old Vim versions, count() does not work for strings
- try
- let l:count = count(a:container, a:item)
- catch /E712/
- let l:count = count(split(a:container, '\zs'), a:item)
- endtry
-
- return l:count
-endfunction
-
-" }}}1
-
-endif