Package Pyblio :: Package Cite :: Module Citator
[hide private]
[frames] | no frames]

Source Code for Module Pyblio.Cite.Citator

  1  # -*- coding: utf-8 -*- 
  2  # This file is part of pybliographer 
  3  #  
  4  # Copyright (C) 1998-2006 Frederic GOBRY 
  5  # Email : gobry@pybliographer.org 
  6  #           
  7  # This program is free software; you can redistribute it and/or 
  8  # modify it under the terms of the GNU General Public License 
  9  # as published by the Free Software Foundation; either version 2  
 10  # of the License, or (at your option) any later version. 
 11  #    
 12  # This program is distributed in the hope that it will be useful, 
 13  # but WITHOUT ANY WARRANTY; without even the implied warranty of 
 14  # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the 
 15  # GNU General Public License for more details.  
 16  #  
 17  # You should have received a copy of the GNU General Public License 
 18  # along with this program; if not, write to the Free Software 
 19  # Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA. 
 20  #  
 21   
 22  """ 
 23  Defines the Citator, a class that glues together every aspect related 
 24  to citations. It reads and stores this information from an XML file, 
 25  making it easy to distribute per-journal citation styles for instance. 
 26   
 27  WARNING: this object loads python modules by their name. It might do 
 28  nasty things if the file comes from untrusted sources. 
 29  """ 
 30   
 31   
 32  import logging 
 33  from Pyblio import Compat 
 34  from gettext import gettext as _ 
 35   
 36  from Pyblio.Exceptions import ParserError 
 37   
 38  log = logging.getLogger('pyblio.cite.citator') 
 39   
40 -class Citator(object):
41 """ """ 42
43 - def __init__(self):
44 pass
45
46 - def xmlload(self, fd):
47 tree = Compat.ElementTree.ElementTree(file=fd) 48 root = tree.getroot() 49 if root.tag != 'pyblio-citator': 50 raise ParserError(_("file is not a Citator XML file")) 51 52 self.name = root.find('./name').text 53 54 def get_last(name): 55 name = root.find(name).text.strip() 56 idx = name.rfind('.') 57 return name[:idx], name[idx+1:]
58 59 self.style = get_last('./citation-style') 60 self.keys = get_last('./key-style') 61 self.order = get_last('./bibliography-order') 62 return
63
64 - def prepare(self, db, wp, extra_info=None):
65 """Link the citator with a specific database and word 66 processor. @extra_info is an optional function that will 67 return a string to store along with the entry, if the word 68 processor allows it. 69 70 Args: 71 db: Pyblio.Store.Database 72 wp: Pyblio.Cite.WP.IWordProcessor 73 extra_info: str = fn(Pyblio.Store.Key, Pyblio.Store.Database) or None 74 """ 75 76 def load(path): 77 mod = __import__(path[0], {}, {}, [path[1]]) 78 return getattr(mod, path[1])
79 80 self.m_style = load(self.style) 81 self.m_keys = load(self.keys) 82 self.m_order = load(self.order) 83 84 self.db = db 85 self.wp = wp 86 self.extra_info = extra_info or (lambda key, db: None) 87 88 # formatter is the compiled citation formatter 89 self.formatter = self.m_style(self.db) 90 91 # keygen will generate the new keys 92 self.keygen = self.m_keys(self.db) 93
94 - def update(self):
95 """ Force an update of keys and bibliography content """ 96 97 # We need to resynchronize the local state with the remote 98 # info. Fetch the list of known references from the current 99 # document 100 known = self.wp.fetch() 101 log.info('fetched keys from document: %r' % known) 102 103 if known is not None: 104 # Regenerate the keys, and update the ones that changed. 105 # We need to restart the key generator, to ensure it 106 # provides them in a coherent order. 107 self.keygen = self.m_keys(self.db) 108 109 to_update = {} 110 for uid, key, extra in known: 111 newkey = self.keygen.make_key(uid) 112 if newkey != key: 113 to_update[uid] = newkey 114 115 known = self.wp.update_keys(to_update) 116 117 # update the biblio itself 118 insert = self.wp.update_biblio() 119 120 insert.begin_biblio() 121 for uid, key in self.m_order(known): 122 insert.begin_reference(key) 123 insert(self.formatter(self.db[uid])) 124 insert.end_reference(key) 125 insert.end_biblio() 126 return
127
128 - def cite(self, uids):
129 """ Insert the specified record identifiers in the current 130 document""" 131 132 keys = [(ref, 133 self.keygen.make_key(ref), 134 self.extra_info(ref, self.db)) for ref in uids] 135 self.wp.cite(keys, self.db) 136 return
137