File: bib.vim

package info (click to toggle)
vim-vimtex 2.16-3
  • links: PTS, VCS
  • area: main
  • in suites: sid
  • size: 8,660 kB
  • sloc: makefile: 367; python: 103
file content (125 lines) | stat: -rw-r--r-- 3,741 bytes parent folder | download
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
" VimTeX - LaTeX plugin for Vim
"
" Maintainer: Karl Yngve LervÄg
" Email:      karl.yngve@gmail.com
"

function! vimtex#bib#files() abort " {{{1
  if !exists('b:vimtex') | return [] | endif

  if has_key(b:vimtex, 'compiler')
    if has_key(b:vimtex.packages, 'biblatex')
      let l:file = b:vimtex.compiler.get_file('bcf')
      if filereadable(l:file)
        let l:bibs = map(
              \ filter(readfile(l:file), "v:val =~# 'bcf:datasource'"),
              \ {_, x -> matchstr(x, '<[^>]*>\zs[^<]*')})
        for l:f in filter(copy(l:bibs), {_, x -> x =~# '[*?{[]' })
          let l:bibs += glob(l:f, 0, 1)
        endfor
        if !empty(l:bibs) | return s:validate(l:bibs) | endif
      endif
    endif

    let l:file = b:vimtex.compiler.get_file('blg')
    if filereadable(l:file)
      let l:bibs = map(
            \ filter(readfile(l:file), 'v:val =~# ''^Database file #\d'''),
            \ {_, x -> matchstr(x, '#\d\+: \zs.*\ze\.bib$')})

      " Ignore '{name}-blx.bib' file (created by biblatex)
      if has_key(b:vimtex.packages, 'biblatex')
        call filter(l:bibs, 'v:val !~# ''-blx$''')
      endif

      " Ignore '{name}Notes.bib' file (created by revtex4)
      if b:vimtex.documentclass =~# '^revtex4'
        call filter(l:bibs, 'v:val !~# ''.Notes$''')
      endif

      if !empty(l:bibs) | return s:validate(l:bibs) | endif
    endif
  endif

  return s:validate(s:files_manual())
endfunction

" }}}1

function! s:validate(files) abort " {{{1
  call filter(a:files, {_, x -> !empty(x)})
  call map(a:files, {_, x -> substitute(x, '\%(\.bib\)\?$', '.bib', '')})
  call map(a:files, {_, x -> filereadable(x) ? x : vimtex#kpsewhich#find(x)})
  call filter(a:files, {_, x -> filereadable(x)})

  return a:files
endfunction

" }}}1
function! s:files_manual() abort " {{{1
  "
  " Search for bibliography files by parsing the source code
  " * Parse commands such as \bibliography{file1,file2.bib,...}
  "

  let l:cache = vimtex#cache#open('bibfiles', {
        \ 'local': 1,
        \ 'default': {'files': [], 'ftime': -1}
        \})

  " Handle local file editing (e.g. subfiles package)
  let l:id = get(get(b:, 'vimtex_local', {'main_id' : b:vimtex_id}), 'main_id')
  let l:vimtex = vimtex#state#get(l:id)

  let l:bibfiles = []
  for l:file in map(l:vimtex.get_sources(), 'l:vimtex.root . ''/'' . v:val')
    let l:current = l:cache.get(l:file)

    let l:ftime = getftime(l:file)
    if l:ftime > l:current.ftime
      let l:cache.modified = 1
      let l:current.ftime = l:ftime
      let l:current.files = []

      for l:entry in map(
            \ filter(readfile(l:file), {_, x -> x =~# s:bib_re}),
            \ {_, x -> matchstr(x, s:bib_re)})
        " Interpolate the \jobname command
        let l:entry = substitute(l:entry, '\\jobname', b:vimtex.name, 'g')

        " Assume comma separated list of files
        let l:files = split(l:entry, ',')

        " But also add the unmodified entry for consideration, as the comma may
        " be part of the filename or part of a globbing expression.
        if len(l:files) > 1
          let l:files += [l:entry]
        endif

        " Now attempt to apply globbing where applicable
        for l:exp in filter(copy(l:files), {_, x -> x =~# '[*?{[]'})
          try
            let l:globbed = glob(l:exp, 0, 1)
            let l:files += l:globbed
          catch /E220/
          endtry
        endfor

        let l:current.files += l:files
      endfor
    endif

    let l:bibfiles += l:current.files
  endfor

  " Write cache to file
  call l:cache.write()

  return uniq(l:bibfiles)
endfunction

" }}}1

let s:bib_re = g:vimtex#re#not_comment . '\\('
      \ . join(g:vimtex_bibliography_commands, '|')
      \ . ')\s*\{\zs.+\ze}'