| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142 |
- import os
- import vim
- from glob import glob
- from itertools import chain
- from subprocess import check_output
- bib_extensions = ["bib",
- "bibtex",
- "ris",
- "json",
- "enl",
- "wos",
- "medline",
- "copac",
- "xml"]
- class SourceCollator():
- def __init__(self, fname=None, query=None, sources="bcg", extra_sources=([], []), **extra_args):
- # nvim's python host doesn't change the directory the same way vim does
- if vim.eval('has("nvim")') == '1':
- os.chdir(vim.eval('expand("%:p:h")'))
- self.fname = fname
- self.query = query
- self.sources = sources
- self.extra_sources = extra_sources
- self.extra_args = extra_args
- def find_bibfiles(self):
- def curdir_by_name_search():
- """
- Search for bibiographies with the same name as the current file in the
- current dir.
- """
- if self.fname in (None, ""): return []
- file_name_prefix = os.path.splitext(self.fname)[0]
- search_paths = [file_name_prefix + "." + f for f in bib_extensions]
- bibfiles = [os.path.abspath(f) for f in search_paths if os.path.exists(f)]
- return bibfiles
- def curdir_all_search():
- """
- Search for any other bibliographies in the current dir.
- Note: This does not stop bibliographies picked up in b_search() from being found.
- """
- relative_bibfiles = []
- for ext in bib_extensions:
- relative_bibfiles.extend(glob("*."+ext))
- bibfiles = [os.path.abspath(f) for f in relative_bibfiles]
- return bibfiles
- def git_search():
- """
- Search for any bibliographies in the git repository.
- """
- try:
- root_dir = check_output(['git', 'rev-parse', '--show-toplevel']).decode().strip()
- except:
- return []
- git_files = check_output(['git', 'ls-tree',
- '-r', '--full-tree', '--name-only',
- 'HEAD']).decode().split('\n')
- relpaths = []
- for f in git_files:
- ext = os.path.splitext(f)[1]
- if ext != '' and ext[1:] in bib_extensions:
- relpaths.append(f)
- bibfiles = [os.path.join(root_dir, f) for f in relpaths]
- return bibfiles
- def pandoc_local_search():
- """
- Search for bibliographies in the pandoc data dirs.
- """
- if os.path.exists(os.path.expandvars("$HOME/.pandoc/")):
- b = os.path.expandvars("$HOME/.pandoc/")
- elif os.path.exists(os.path.expandvars("%APPDATA%/pandoc/")):
- b = os.path.expandvars("%APPDATA%/pandoc/")
- else:
- return []
- search_paths = [b + "default." + f for f in bib_extensions]
- bibfiles = [os.path.abspath(f) for f in search_paths if os.path.exists(f)]
- return bibfiles
- def texmf_search():
- """
- Search for bibliographies in the texmf data dirs.
- """
- texmf = check_output(["kpsewhich", "-var-value", "TEXMFHOME"]).rstrip()
- if os.path.exists(texmf):
- search_paths = (texmf.decode() + "/**/*." + f for f in bib_extensions)
- relative_bibfiles = (glob(f, recursive=True) for f in search_paths)
- bibfiles = [os.path.abspath(f) for f in chain.from_iterable(relative_bibfiles)]
- return bibfiles
- return []
- def explicit_global_search():
- """
- Add bibliographies defined in pandoc#biblio#bibs,
- passed to the collator through the extra_sources argument
- """
- return self.extra_sources[0]
- search_methods = {"b": curdir_by_name_search,
- "c": curdir_all_search,
- "l": pandoc_local_search,
- "t": texmf_search,
- "g": explicit_global_search,
- "G": git_search}
- bibfiles = []
- for f in self.sources:
- bibfiles.extend(search_methods.get(f, list)())
- # add buffer-local bibliographies, defined in b:pandoc_biblio_bibs,
- # passed to the collator through the extra_sources argument
- bibfiles.extend(self.extra_sources[1])
- # check if the items in bibfiles are readable and not directories
- # also, ensure items are unique
- if bibfiles != []:
- bibfiles = list(set(filter(lambda f : os.access(f, os.R_OK) and not os.path.isdir(f), bibfiles)))
- return bibfiles
- def collate(self):
- """
- Retrieves the data from the sources.
- Should be overriden by sub-classes.
- """
- pass
|