#-*- coding: utf-8 -*- # (c) 2012 Anders Andersen # See http://www.cs.uit.no/~aa/dist/tools/py/COPYING for details import sys import json # Read from stdin mypubl = json.load(sys.stdin) # The common data about publications: commonmap = { "tittel": "title", "person": {"author": {"pre": "", "val": "%(fornavn)s %(etternavn)s", "sep": " and ", "post": ""}}, ("person",): {"ref": {"pre": "", "val": "%(etternavn)s", "sep": ":", "post": ""}}, "ar": "year", ("kategori","hovedkategori","navnEngelsk") : "mcat", ("kategori","underkategori","navnEngelsk") : "scat", } # The different type of publications (identified so far): catmap = { "mediebidrag": { "medium": "url", }, "foredragPoster": { ("arrangement", "tittel") : "booktitle", ("arrangement", "sted") : "address", ("arrangement", "arrangor") : "organizer", }, "bokRapport": { ("utgiver", "navn"): "booktitle", ("utgiver", "sted"): "address", ("forlag", "navn"): "booktitle", ("forlag", "sted"): "address", "isbn": "isbn", }, "bokRapportDel": { ("delAv", "forskningsresultat", "fellesdata", "tittel") : "chaptitle", ("delAv", "forskningsresultat", "kategoridata", "bokRapport") : "bokRapport", }, "tidsskriftsartikkel": { ("tidsskrift", "navn"): "journal", ("tidsskrift", "issn"): "issn", "volum": "volume", "hefte": "number", "sideangivelse": {"pages": {"pre": "", "val": "%(sideFra)s--%(sideTil)s", "sep": "", "post": ""}} }, } # Type of publication tmap = { # (cat, mcat, scat) ("mediebidrag", "Media contribution", "Interview"): "Misc", ("", "Information material(s)", "Website (informational material)"): "Misc", ("foredragPoster", "Conference lecture and academic presentation", "Popular scientific lecture"): "Misc", ("foredragPoster", "Conference lecture and academic presentation", "Poster"): "InProceedings", ("foredragPoster", "Conference lecture and academic presentation", "Academic lecture"): "InProceedings", ("tidsskriftsartikkel", "Journal publication", "Academic article"): "Article", ("bokRapport", "Report/thesis", "Report"): "TechReport", ("bokRapport", "Report/thesis", "Masters thesis"): "MastersThesis", ("bokRapport", "Report/thesis", "Doctoral dissertation"): "PhdThesis", ("bokRapport", "Report/thesis", "Thesis at a second degree level"): "MastersThesis", ("bokRapportDel", "Part of a book/report", "Academic chapter/article"): "InCollection" } bibentry = '''@%(category)s{%(ref)s, %(bibfields)s} ''' bibfields = ' %(key)s = %(val)s,\n' ignorefields = ["mcat", "scat", "ref"] def info2bibentry(skel, info): bibf = "" for k in info: if not k in ignorefields: if info[k].isnumeric(): val = info[k] else: val = '"%s"' % (info[k],) bibf += bibfields % {"key": k, "val": val} skel["bibfields"] = bibf return bibentry % skel txtmap = { 'Æ': '{\\AE}', 'Ø': '{\\O}', 'Å': '{\\AA}', 'æ': '{\\ae}', 'ø': '{\\o}', 'å': '{\\aa}', '�': ' ', } def cleanit(txt): for i, j in txtmap.items(): txt = txt.replace(i, j) return txt def warning(msg, pre="Warning: "): sys.stderr.write("%s%s\n" % (pre, msg)) sys.stderr.flush() def stripit(txt): if len(txt) > 0: if txt[-1] in (',', '.'): return txt[:-1] return txt # Fetch data from indata based on map def getit(indata, map): # Returns a ditionary with selected info outdata = {} # The map is the info we searching for for k in map: # Go to correct level in indata for this info if type(k) is tuple: v = indata for kk in k: if kk in v: v = v[kk] else: v = None; break # Upper level is OK elif k in indata: v = indata[k] # Key k not used in this document (no error) else: v = None # warning("No %s in this publication" % (repr(k))) # Then map the data if v: # A single element if type(map[k]) is str: # Recursive, the element is another category if map[k] in catmap: outdata.update(getit(v, catmap[map[k]])) # A simple get str value from indata with new key else: outdata[map[k]] = stripit(v) # A more complex mapping elif type(map[k]) is dict: # Only one iteration of this loop (fetch the new key for the list) for kk in map[k]: # If indata is not a list, make it a list (with one element) if type(v) is list: alist = v else: alist = [v] # Produce list vdict = map[k][kk] outdata[kk] = vdict["pre"] + vdict["val"] % alist[0] for n in alist[1:]: outdata[kk] += vdict["sep"] + vdict["val"] % n outdata[kk] += vdict["post"] # Unknown else: warning("unknown key type %s" % (str(type(map[k])))) # No match (no error) else: pass # warning("%s not in data" % (k,)) # Return selected info return outdata # Do produce the output refset = set() for publ in mypubl["forskningsresultat"]: # publ is a dict with "fellesdata" and "kategoridata" (possibly empty) info = {} skel = {} # "fellesdata" includes authors, category and title info.update(getit(publ["fellesdata"], commonmap)) # "kategoridata" includes information about where/how kd = publ["kategoridata"] if type (kd) is dict and len(kd) == 1: cat = list(kd.keys())[0] info.update(getit(publ["kategoridata"][cat], catmap[cat])) else: warning("No where/how: %s" % (info["title"],)) cat = "" # mcat or scat? if "mcat" in info: mscat = "%s: %s -> %s" % (repr(cat), repr(info["mcat"]), repr(info["scat"])) if (cat, info["mcat"], info["scat"]) in tmap: skel["category"] = tmap[(cat, info["mcat"], info["scat"])] else: warning("Unknown category: (%s, %s, %s)" % (cat, info["mcat"], info["scat"])) else: warning("No category set: " + info["title"]) if "ref" in info: if "year" in info: tmpref = info["ref"].split(":", 1)[0].lower() + info["year"] else: tmpref = info["ref"].split(":", 1)[0].lower() for i in range(ord('a'), ord('z')): c = chr(i) if tmpref + c in refset: continue else: tmpref += c refset.add(tmpref) break warning("No unique ref genrated: " + info["title"]) skel["ref"] = tmpref else: warning("No ref generated: " + info["title"]) # Produce and print entry entry = cleanit(info2bibentry(skel, info).encode('ascii', 'xmlcharrefreplace').decode('ascii')) print(entry)