Source code for bibstuff.bibadd

# -*- coding: latin-1 -*-
'''
:mod:`bibstuff.bibadd`: Add entries to .bib file
------------------------------------------------

:WARNING: works but currently *very* crude and rough!  (no special characters; macros alpha-lower only)
:copyright: 2006 by Alan Isaac, see AUTHORS
:license: MIT, see LICENSE
:TODO: add checking for unique key
:TODO: allow multiple entries
:TODO: allow correcting entries
:TODO: use style file for HTML formatting
:TODO: check for macros against @string defs in .bib file
:TODO: macro handling (journals)
:TODO: add crossreferencing as option for inbook and incollection
:TODO: change default format to legal HTML names

'''
__docformat__ = "restructuredtext en"
__authors__  =    ['Alan G. Isaac', 'Dylan W. Schwilk']
__version__ =    '0.3.2'
__needs__ = '2.4'


###################  IMPORTS  ##################################################
# import from standard library
import logging
logging.basicConfig(format='\n%(levelname)s:\n%(message)s\n')
bibadd_logger = logging.getLogger('bibstuff_logger')

# bibstuff imports
from . import bibfile
from . import bibstyles
################################################################################

entry_types = ("article","booklet","book","conference","inbook","incollection","inproceedings","manual","mastersthesis","misc","phdthesis","proceedings","techreport","unpublished")
valid_fields = dict(
)

"""
author or editor (Æ), author(A), address(a), booktitle(b), chapter(c), crossref(x), edition(e), editor(E), howpublished(h), institution(I), isbn(i), journal(j), key(k), month(m), note(z), number(n), organization(O), pages(p), publisher(P), school(S), series(s), title(T), type(t), url(u), volume(v), year(y), unused(fgl)

Currently will not provide the crossref field since crossrefs must be prepended. (Just warn?)
"""

article = dict(
required = 'ATjY',
optional1 = 'vnpm',
optional2 = 'z',
extras = 'kiu'
)
book = dict(
required = 'ÆTPY',
optional1 = 'ae',
optional2 = 'vnszi',
extras = 'kmu'
)
booklet = dict(
required = 'T',
optional1 = 'AhY',
optional2 = 'amz',
)
inbook = dict(
required = 'ÆTcpPY',
optional1 = 'a',
optional2 = 'vnsuemz',
extras = 'kiu'
)
incollection = dict(
required = 'ATbPY',
optional1 = 'Ecpa',
optional2 = 'vnsuemz',
extras = 'kiu'
)
inproceedings = dict(
required = 'ATbY',
optional1 = 'EpaOP',
optional2 = 'vnsmz',
extras = 'kiu'
)
manual = dict(
required = 'T',
optional1 = 'Oa',
optional2 = 'AemYz',
)
mastersthesis = dict(
required = 'ATSY',
optional1 = 'a',
optional2 = 'umz',
)
misc = dict(
required = '',
optional1 = 'AThY',
optional2 = 'mz',
)
phdthesis = dict(
required = 'ATSY',
optional1 = 'a',
optional2 = 'umz',
)
proceedings = dict(
required = 'TY',
optional1 = 'EaO',
optional2 = 'vnsmPz',
)
techreport = dict(
required = 'ATIY',
optional1 = 'tuna',
optional2 = 'mz',
)
unpublished = dict(
required = 'ATz',
optional1 = 'Y',
optional2 = 'm',
)

[docs]def make_entry(choosetype='', options=False, extras=False, raw_input = raw_input): """ Create a bibtex entry by prompting the user for input :todo: Should this be moved to a script? """ entry = bibfile.BibEntry() while not choosetype in entry_types: choosetype=raw_input("From\n"+", ".join(entry_types)+"\nchoose type: ") entry.entry_type = choosetype field_dict = eval(choosetype) #:TODO: test cite key against existing keys citekey = raw_input("Press return for autogenerated citekey.\nOr enter citekey (e.g., jones02aer): ") entry.citekey = citekey fields = field_dict['required'] + field_dict['optional1'] if options or extras: fields = fields + field_dict['optional2'] if extras: fields = fields + field_dict['extras'] if 'A' in fields or 'Æ' in fields: entry['author'] = raw_input("author(s)? ").strip() if 'E' in fields or 'Æ' in fields: entry['editor'] = raw_input("editor(s)? ").strip() if 'Y' in fields: entry['year'] = raw_input("year? ").strip() if 'T' in fields: entry['title'] = raw_input("title? ").strip() if 'b' in fields: entry['booktitle'] = raw_input("booktitle? ").strip() if 'e' in fields: entry['edition'] = raw_input("edition? (E.g., 2nd) ").strip() if 'c' in fields: entry['chapter'] = raw_input("chapter? ").strip() if 'j' in fields: #:TODO: journal key handling (all lower only?) entry['journal'] = raw_input("journal name? ").strip() if 'v' in fields: entry['volume'] = raw_input("volume? ").strip() if 'n' in fields: entry['number'] = raw_input("number? ").strip() if 'm' in fields: #:TODO: macro handling entry['month'] = raw_input("month? ").strip() if 'p' in fields: entry['pages'] = raw_input("pages? ").strip() if 'P' in fields: entry['publisher'] = raw_input("Publisher? ").strip() if 'a' in fields: entry['address'] = raw_input("address? ").strip() if 'h' in fields: entry['howpublished'] = raw_input("howpublished? ").strip() if 'I' in fields: entry['institution'] = raw_input("Institution? ").strip() if 'O' in fields: entry['organization'] = raw_input("Organization? ").strip() if 'S' in fields: entry['school'] = raw_input("School? ").strip() if 's' in fields: entry['series'] = raw_input("series? ").strip() if 't' in fields: entry['type'] = raw_input("type? (E.g., Working Paper) ").strip() if 'i' in fields: entry['isbn'] = raw_input("isbn? ").strip() if 'u' in fields: entry['url'] = raw_input("url? ").strip() if 'k' in fields: entry['key'] = raw_input("key (*not* citekey)? ").strip() if not citekey: citekey = entry.make_citekey([]) entry.citekey = citekey return entry ########### HTML formatting ########################
html_templates = dict( journal = '''<p id='%(citekey)s' class='ref'> <span class='author'>%(author)s</span>, <span class='date'>%(year)s</span>, &ldquo;<span class='title'>%(title)s</span>,&rdquo; %(pubinfo)s. </p> ''', techreport = '''<p id='%(citekey)s' class='ref'> <span class='author'>%(author)s</span>, <span class='date'>%(year)s</span>, &ldquo;<span class='title'>%(title)s</span>,&rdquo; %(pubinfo)s. </p> ''', book = '''<p id='%(citekey)s' class='ref'> <span class='author'>%(auted)s</span>, %(year)s, <span class='booktitle'>%(booktitle)s</span>, %(pubinfo)s. </p> ''', incollection = '''<p id='%(citekey)s' class='ref'> <span class='author'>%(auted)s</span>, %(year)s, <em>%(title)s</em>, in <span class='booktitle'>%(booktitle)s</span>, %(pubinfo)s. </p> ''', ) text_templates = dict( journal = '''%(author)s, %(year)s, "%(title)s" %(pubinfo)s. ''', techreport = '''%(author)s, %(year)s, "%(title)s" %(pubinfo)s. ''', book = '''%(auted)s, %(year)s, %(booktitle)s (%(address)s: %(publisher)s) isbn: %(isbn)s ''', incollection = '''%(author)s, %(year)s, %(title)s, in %(booktitle)s, %(pubinfo)s. (%(address)s: %(publisher)s) isbn: %(isbn)s ''', )
[docs]def is_macro(s): """Return bool, a crude guess if this is a macro. TODO: rethink this.""" oneword = not (' ' in s ) return oneword and (s.islower() or s.isupper())
[docs]def text_format(entry): from collections import defaultdict info = defaultdict(str) info.update(entry) entry_type = entry.entry_type.lower() bibadd_logger.info("entry_type = %s"%(entry_type)) if entry_type == "article": info['journal'] = get_journal(entry) pubinfo = get_volnum(entry) pages = entry['pages'] if pages: pubinfo += pages info['pubinfo'] = pubinfo #TODO move into template if entry_type == "techreport": institution = entry['institution'] type = entry['type'] number = entry['number'] pubinfo= "%s %s, %s"%(type, number, institution) info['pubinfo'] = pubinfo #TODO move into template elif entry_type in ["incollection","book"]: if entry_type == "book": info['booktitle'] = info['title'] author = info['author'] editor = info['editor'] if author: auted = author elif editor: auted = editor + " (ed)" else: auted = "unknown" info['auted'] = auted else: #-> entry_type == "incollection": if info['editor']: info['auted'] = "%(author)s, in %(editor)s (ed)" % info result = text_templates[entry_type] % info return result
[docs]def get_journal(entry, jrnl_lst=None): #TODO: extract fr journal list """Return string representation of journal, allowing opportunity to provide name to replace macro. TODO: automate macro substitution.""" #if jrnlkey =~ "{.\+}", let journal=substitute(jrnlkey,'[{}]','','g') journal = entry['journal'] #might be a macro if is_macro(journal): if journal.islower(): journal = journal.upper() jrnl = raw_input("Journal? (no braces) (Press enter to use '%s') "%(journal) ) if jrnl: journal = jrnl return journal
[docs]def get_volnum(entry): volume = entry['volume'] number = entry['number'] if volume: volnum = str(volume) if number: volnum = str(volume) + "(" + str(number) + ")" elif number: volnum = str(number) else: volnum = "" return volnum
[docs]def get_pages(entry,dash='--',pagespref=('p. ','pp. ')): pages = entry['pages'] if pages: if '--' in pages: pages = pagespref[1] + dash.join(pages.split("--")) elif '-' in pages: pages = pagespref[1] + dash.join("-".split(pages)) else: pages = pagespref[0] + pages return pages
[docs]def html_format(entry): from collections import defaultdict entry_type = entry.entry_type.lower() info = defaultdict(str) info.update(entry) bibadd_logger.info("entry_type: %s"%(entry_type)) #next we aggregate the publication information and apply formatting template if entry_type == "article": #journal may be a macro; ask to replace info['journal'] = get_journal(entry) pubinfo="<span class='journal'>" + info['journal'] + "</span>" number = entry['number'] volnum = get_volnum(entry) if volnum: pubinfo += " " + volnum pages = get_pages(entry,'&ndash;') if pages: pubinfo += pages #result = html_templates['journal']%dict(citekey=citekey,author=author,year=year,title=title,pubinfo=pubinfo) info['pubinfo'] = pubinfo if entry_type == "techreport": institution = entry['institution'] type = entry['type'] number = entry['number'] pubinfo= "%s %s, %s"%(type, number, institution) info['pubinfo'] = pubinfo elif entry_type in ["incollection","book"]: if entry_type == "book": info['booktitle'] = info['title'] author = info['author'] editor = info['editor'] if author: auted = author elif editor: auted = editor + " (ed)" else: auted = "unknown" info['auted'] = auted else: #-> entry_type == "incollection": if info['editor']: info['auted'] = "%(author)s, in %(editor)s (ed)"%(info) info['titleinfo']="<em>%(title)s</em>, in <span class='booktitle'>%(booktitle)s</span>,"%(entry) info['pubinfo']="(%(address)s: %(publisher)s)\nisbn: %(isbn)s"%(info) #apply template to aggregated information result = html_templates[entry_type] % info return result