# -*- 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>,
“<span class='title'>%(title)s</span>,”
%(pubinfo)s.
</p>
''',
techreport = '''<p id='%(citekey)s' class='ref'>
<span class='author'>%(author)s</span>,
<span class='date'>%(year)s</span>,
“<span class='title'>%(title)s</span>,”
%(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