Improve Bibliography and use it in Narrative Web report as well.
svn: r8760
This commit is contained in:
		@@ -1,3 +1,12 @@
 | 
			
		||||
2007-07-23  Brian Matherly <brian@gramps-project.org>
 | 
			
		||||
	* src/plugins/IndivComplete.py:
 | 
			
		||||
	* src/plugins/DetDescendantReport.py:
 | 
			
		||||
	* src/plugins/DetAncestralReport.py:
 | 
			
		||||
	* src/plugins/NarrativeWeb.py:
 | 
			
		||||
	* src/ReportBase/_Endnotes.py:
 | 
			
		||||
	* src/ReportBase/_Bibliography.py:
 | 
			
		||||
	Improve Bibliography and use it in Narrative Web report as well.
 | 
			
		||||
 | 
			
		||||
2007-07-23  Stephane Charette <stephanecharette@gmail.com>
 | 
			
		||||
	* src/plugins/FamilyLines.py: added FamilyLines to trunk
 | 
			
		||||
	* src/plugins/makefile.am: added FamilyLines
 | 
			
		||||
 
 | 
			
		||||
@@ -22,6 +22,7 @@
 | 
			
		||||
"""
 | 
			
		||||
Contain and organize bibliographic information.
 | 
			
		||||
"""
 | 
			
		||||
import string
 | 
			
		||||
 | 
			
		||||
class Citation:
 | 
			
		||||
    """
 | 
			
		||||
@@ -68,28 +69,43 @@ class Citation:
 | 
			
		||||
 | 
			
		||||
        @param source_ref: Source Reference
 | 
			
		||||
        @type source_ref: L{Relib.SourceRef}
 | 
			
		||||
        @return: The index of the added reference among all the references.
 | 
			
		||||
        @rtype: int
 | 
			
		||||
        @return: The key of the added reference among all the references.
 | 
			
		||||
        @rtype: char
 | 
			
		||||
        """
 | 
			
		||||
        index = 0
 | 
			
		||||
        for ref in self.__ref_list:
 | 
			
		||||
            if _srefs_are_equal(ref,source_ref):
 | 
			
		||||
                # if a reference like this already exists, don't add another one
 | 
			
		||||
                return index
 | 
			
		||||
            index += 1
 | 
			
		||||
        
 | 
			
		||||
        self.__ref_list.append(source_ref)
 | 
			
		||||
        return index
 | 
			
		||||
        key = string.lowercase[ len(self.__ref_list) ]
 | 
			
		||||
        self.__ref_list.append((key,source_ref))
 | 
			
		||||
        return key
 | 
			
		||||
 | 
			
		||||
class Bibliography:
 | 
			
		||||
    """
 | 
			
		||||
    Store and organize multiple citations into a bibliography.
 | 
			
		||||
    """
 | 
			
		||||
    def __init__(self):
 | 
			
		||||
    MODE_DATE = 2**0
 | 
			
		||||
    MODE_PAGE = 2**1
 | 
			
		||||
    MODE_CONF = 2**2
 | 
			
		||||
    MODE_NOTE = 2**3
 | 
			
		||||
    MODE_ALL = MODE_DATE | MODE_PAGE | MODE_CONF | MODE_NOTE
 | 
			
		||||
 | 
			
		||||
    def __init__(self,mode=MODE_ALL):
 | 
			
		||||
        """
 | 
			
		||||
        Initialize members.
 | 
			
		||||
        A bibliography will store citations (sources) and references to those
 | 
			
		||||
        citations (source refs). Duplicate entries will not be added. To change
 | 
			
		||||
        what is considered duplicate, you can tell the bibliography what source
 | 
			
		||||
        ref information you are interested in by passing in the mode.
 | 
			
		||||
        
 | 
			
		||||
        Possible modes include:
 | 
			
		||||
            MODE_DATE
 | 
			
		||||
            MODE_PAGE
 | 
			
		||||
            MODE_CONF
 | 
			
		||||
            MODE_NOTE
 | 
			
		||||
            MODE_ALL
 | 
			
		||||
        
 | 
			
		||||
        If you only care about pages, set "mode=MODE_PAGE".
 | 
			
		||||
        If you only care about dates and pages, set "mode=MODE_DATE|MODE_PAGE".
 | 
			
		||||
        If you care about everything, set "mode=MODE_ALL".
 | 
			
		||||
        """
 | 
			
		||||
        self.__citation_list = []
 | 
			
		||||
        self.mode = mode
 | 
			
		||||
 | 
			
		||||
    def add_reference(self, source_ref):
 | 
			
		||||
        """
 | 
			
		||||
@@ -100,13 +116,13 @@ class Bibliography:
 | 
			
		||||
        @param source_ref: Source Reference
 | 
			
		||||
        @type source_ref: L{Relib.SourceRef}
 | 
			
		||||
        @return: A tuple containing the index of the source among all the 
 | 
			
		||||
        sources and the index of the reference among all the references. If 
 | 
			
		||||
        sources and the key of the reference among all the references. If 
 | 
			
		||||
        there is no reference information, the second element will be None.
 | 
			
		||||
        @rtype: (int,int) or (int,None)
 | 
			
		||||
        @rtype: (int,char) or (int,None)
 | 
			
		||||
        """
 | 
			
		||||
        source_handle = source_ref.get_reference_handle()
 | 
			
		||||
        cindex = 0
 | 
			
		||||
        rindex = None
 | 
			
		||||
        rkey = None
 | 
			
		||||
        citation = None
 | 
			
		||||
        citation_found = False
 | 
			
		||||
        for citation in self.__citation_list:
 | 
			
		||||
@@ -121,10 +137,14 @@ class Bibliography:
 | 
			
		||||
            cindex = len(self.__citation_list)
 | 
			
		||||
            self.__citation_list.append(citation)
 | 
			
		||||
 | 
			
		||||
        if _sref_has_info(source_ref):
 | 
			
		||||
            rindex = citation.add_reference(source_ref)
 | 
			
		||||
        if self.__sref_has_info(source_ref):
 | 
			
		||||
            for key,ref in citation.get_ref_list():
 | 
			
		||||
                if self.__srefs_are_equal(ref,source_ref):
 | 
			
		||||
                    # if a reference like this already exists, don't add another one
 | 
			
		||||
                    return (cindex,key)
 | 
			
		||||
            rkey = citation.add_reference(source_ref)
 | 
			
		||||
        
 | 
			
		||||
        return (cindex,rindex)
 | 
			
		||||
        return (cindex,rkey)
 | 
			
		||||
    
 | 
			
		||||
    def get_citation_count(self):
 | 
			
		||||
        """
 | 
			
		||||
@@ -144,14 +164,45 @@ class Bibliography:
 | 
			
		||||
        """
 | 
			
		||||
        return self.__citation_list
 | 
			
		||||
 | 
			
		||||
def _sref_has_info(source_ref):
 | 
			
		||||
    if source_ref.get_page() == "":
 | 
			
		||||
    def __sref_has_info(self,source_ref):
 | 
			
		||||
        if ( self.mode & self.MODE_PAGE ) == self.MODE_PAGE:
 | 
			
		||||
            if source_ref.get_page() != "":
 | 
			
		||||
                return True
 | 
			
		||||
        if ( self.mode & self.MODE_DATE ) == self.MODE_DATE:
 | 
			
		||||
            if source_ref.get_date_object() != None:
 | 
			
		||||
                return True
 | 
			
		||||
        if ( self.mode & self.MODE_CONF ) == self.MODE_CONF:
 | 
			
		||||
            if source_ref.get_confidence_level() != None:
 | 
			
		||||
                return True
 | 
			
		||||
        if ( self.mode & self.MODE_NOTE ) == self.MODE_NOTE:
 | 
			
		||||
            if len(source_ref.get_note_list()) != 0:
 | 
			
		||||
                return True
 | 
			
		||||
        # Can't find anything interesting.
 | 
			
		||||
        return False
 | 
			
		||||
    else:
 | 
			
		||||
        return True
 | 
			
		||||
    
 | 
			
		||||
def _srefs_are_equal(source_ref1,source_ref2):
 | 
			
		||||
    if source_ref1.get_page() == source_ref2.get_page():
 | 
			
		||||
        return True
 | 
			
		||||
    else:
 | 
			
		||||
        return False
 | 
			
		||||
        
 | 
			
		||||
    def __srefs_are_equal(self,source_ref1,source_ref2):
 | 
			
		||||
        if self.mode == self.MODE_ALL:
 | 
			
		||||
            return source_ref1.is_equal(source_ref2)
 | 
			
		||||
        if ( self.mode & self.MODE_PAGE ) == self.MODE_PAGE:
 | 
			
		||||
            if source_ref1.get_page() != source_ref2.get_page():
 | 
			
		||||
                return False
 | 
			
		||||
        if ( self.mode & self.MODE_DATE ) == self.MODE_DATE:
 | 
			
		||||
            date1 = source_ref1.get_date_object()
 | 
			
		||||
            date2 = source_ref2.get_date_object()
 | 
			
		||||
            if date1.is_equal(date2):
 | 
			
		||||
                return False
 | 
			
		||||
        if ( self.mode & self.MODE_CONF ) == self.MODE_CONF:
 | 
			
		||||
            conf1 = source_ref1.get_confidence_level()
 | 
			
		||||
            conf2 = source_ref2.get_confidence_level()
 | 
			
		||||
            if conf1 != conf2:
 | 
			
		||||
                return False
 | 
			
		||||
        if ( self.mode & self.MODE_NOTE ) == self.MODE_NOTE:
 | 
			
		||||
            nl1 = source_ref1.get_note_list()
 | 
			
		||||
            nl2 = source_ref2.get_note_list()
 | 
			
		||||
            if len(nl1) != len(nl2):
 | 
			
		||||
                return False
 | 
			
		||||
            for notehandle in nl1:
 | 
			
		||||
                if notehandle not in nl2:
 | 
			
		||||
                    return False
 | 
			
		||||
        # Can't find anything different. They must be equal.
 | 
			
		||||
        return True
 | 
			
		||||
@@ -23,7 +23,6 @@
 | 
			
		||||
Provide utilities for printing endnotes in text reports.
 | 
			
		||||
"""
 | 
			
		||||
 | 
			
		||||
import string
 | 
			
		||||
import BaseDoc
 | 
			
		||||
 | 
			
		||||
def add_endnote_styles(style_sheet):
 | 
			
		||||
@@ -74,10 +73,10 @@ def cite_source(bibliography,obj):
 | 
			
		||||
            if not first:
 | 
			
		||||
                txt += ','
 | 
			
		||||
            first = 0
 | 
			
		||||
            (cindex,rindex) = bibliography.add_reference(ref)
 | 
			
		||||
            (cindex,key) = bibliography.add_reference(ref)
 | 
			
		||||
            txt += "%d" % (cindex + 1)
 | 
			
		||||
            if rindex != None:
 | 
			
		||||
                txt += "%s" % string.lowercase[rindex]
 | 
			
		||||
            if key != None:
 | 
			
		||||
                txt += key
 | 
			
		||||
    return txt
 | 
			
		||||
 | 
			
		||||
def write_endnotes(bibliography,database,doc):
 | 
			
		||||
@@ -118,8 +117,8 @@ def write_endnotes(bibliography,database,doc):
 | 
			
		||||
        
 | 
			
		||||
            first = True
 | 
			
		||||
            rindex = 0
 | 
			
		||||
            for ref in ref_list:
 | 
			
		||||
                txt = "%s: %s" % (string.lowercase[rindex],ref.get_page())
 | 
			
		||||
            for key,ref in ref_list:
 | 
			
		||||
                txt = "%s: %s" % (key,ref.get_page())
 | 
			
		||||
                if first:
 | 
			
		||||
                    doc.write_text(txt)
 | 
			
		||||
                    first = False
 | 
			
		||||
 
 | 
			
		||||
@@ -129,7 +129,7 @@ class DetAncestorReport(Report):
 | 
			
		||||
        else:
 | 
			
		||||
            self.EMPTY_PLACE = ""
 | 
			
		||||
 | 
			
		||||
        self.bibli = Bibliography()
 | 
			
		||||
        self.bibli = Bibliography(Bibliography.MODE_PAGE)
 | 
			
		||||
 | 
			
		||||
    def apply_filter(self,person_handle,index):
 | 
			
		||||
        if (not person_handle) or (index >= 2**self.max_generations):
 | 
			
		||||
 
 | 
			
		||||
@@ -137,7 +137,7 @@ class DetDescendantReport(Report):
 | 
			
		||||
        else:
 | 
			
		||||
            self.EMPTY_PLACE = ""
 | 
			
		||||
 | 
			
		||||
        self.bibli = Bibliography()
 | 
			
		||||
        self.bibli = Bibliography(Bibliography.MODE_PAGE)
 | 
			
		||||
 | 
			
		||||
    def apply_filter(self,person_handle,index,pid,cur_gen=1):
 | 
			
		||||
        if (not person_handle) or (cur_gen > self.max_generations):
 | 
			
		||||
 
 | 
			
		||||
@@ -87,7 +87,7 @@ class IndivCompleteReport(Report):
 | 
			
		||||
        filter_num = options_class.handler.options_dict['filter']
 | 
			
		||||
        filters = ReportUtils.get_person_filters(person)
 | 
			
		||||
        self.filter = filters[filter_num]
 | 
			
		||||
        self.bibli = Bibliography()
 | 
			
		||||
        self.bibli = Bibliography(Bibliography.MODE_PAGE)
 | 
			
		||||
 | 
			
		||||
    def write_fact(self,event):
 | 
			
		||||
        if event == None:
 | 
			
		||||
 
 | 
			
		||||
@@ -68,6 +68,7 @@ import Sort
 | 
			
		||||
from PluginUtils import register_report
 | 
			
		||||
from ReportBase import Report, ReportUtils, ReportOptions, \
 | 
			
		||||
     CATEGORY_WEB, MODE_GUI, MODE_CLI
 | 
			
		||||
from ReportBase import Bibliography
 | 
			
		||||
from ReportBase._ReportDialog import ReportDialog
 | 
			
		||||
from ReportBase._CommandLineReport import CommandLineReport
 | 
			
		||||
import Errors
 | 
			
		||||
@@ -1616,7 +1617,7 @@ class IndividualPage(BasePage):
 | 
			
		||||
        self.db = db
 | 
			
		||||
        self.ind_list = ind_list
 | 
			
		||||
        self.src_list = src_list
 | 
			
		||||
        self.src_refs = []
 | 
			
		||||
        self.bibli = Bibliography()
 | 
			
		||||
        self.place_list = place_list
 | 
			
		||||
        self.sort_name = sort_nameof(self.person,self.exclude_private)
 | 
			
		||||
        self.name = sort_nameof(self.person,self.exclude_private)
 | 
			
		||||
@@ -1786,43 +1787,59 @@ class IndividualPage(BasePage):
 | 
			
		||||
            self.draw_tree(of,gen,maxgen,max_size,new_center,m_center,m_handle)
 | 
			
		||||
 | 
			
		||||
    def display_ind_sources(self,of):
 | 
			
		||||
        sreflist = self.src_refs + self.person.get_source_references()
 | 
			
		||||
        if not sreflist or self.restrict:
 | 
			
		||||
        for sref in self.person.get_source_references():
 | 
			
		||||
            self.bibli.add_reference(sref)
 | 
			
		||||
        if self.restrict or self.bibli.get_citation_count() == 0:
 | 
			
		||||
            return
 | 
			
		||||
        of.write('<div id="sourcerefs">\n')
 | 
			
		||||
        of.write('<h4>%s</h4>\n' % _('Source References'))
 | 
			
		||||
        of.write('<table class="infolist">\n')
 | 
			
		||||
 | 
			
		||||
        index = 1
 | 
			
		||||
        for sref in sreflist:
 | 
			
		||||
        cindex = 0
 | 
			
		||||
        for citation in self.bibli.get_citation_list():
 | 
			
		||||
            cindex += 1
 | 
			
		||||
            # Add this source to the global list of sources to be displayed
 | 
			
		||||
            # on each source page.
 | 
			
		||||
            lnk = (self.cur_name, self.page_title, self.gid)
 | 
			
		||||
            shandle = sref.get_reference_handle()
 | 
			
		||||
            if not shandle:
 | 
			
		||||
                continue
 | 
			
		||||
            shandle = citation.get_source_handle()
 | 
			
		||||
            if self.src_list.has_key(shandle):
 | 
			
		||||
                if lnk not in self.src_list[shandle]:
 | 
			
		||||
                    self.src_list[shandle].append(lnk)
 | 
			
		||||
            else:
 | 
			
		||||
                self.src_list[shandle] = [lnk]
 | 
			
		||||
 | 
			
		||||
                
 | 
			
		||||
            # Add this source and its references to the page
 | 
			
		||||
            source = self.db.get_source_from_handle(shandle)
 | 
			
		||||
            title = source.get_title()
 | 
			
		||||
            of.write('<tr><td class="field">')
 | 
			
		||||
            of.write('<a name="sref%d"></a>%d.</td>' % (index,index))
 | 
			
		||||
            of.write('<td class="field">')
 | 
			
		||||
            of.write('<a name="sref%d"></a>%d.</td>' % (cindex,cindex))
 | 
			
		||||
            of.write('<td class="field" colspan=2>')
 | 
			
		||||
            self.source_link(of,source.handle,title,source.gramps_id,True)
 | 
			
		||||
            tmp = []
 | 
			
		||||
            confidence = Utils.confidence.get(sref.confidence, _('Unknown'))
 | 
			
		||||
            for (label,data) in [(_('Date'),_dd.display(sref.date)),
 | 
			
		||||
                                 (_('Page'),sref.page),
 | 
			
		||||
                                 (_('Confidence'),confidence),
 | 
			
		||||
                                 (_('Text'),sref.text)]:
 | 
			
		||||
                if data:
 | 
			
		||||
                    tmp.append("%s: %s" % (label,data))
 | 
			
		||||
            if len(tmp) > 0:
 | 
			
		||||
                of.write('<br />' + '<br />'.join(tmp))
 | 
			
		||||
            of.write('<p/>')
 | 
			
		||||
            of.write('</td></tr>\n')
 | 
			
		||||
            index += 1
 | 
			
		||||
 | 
			
		||||
            for key,sref in citation.get_ref_list():
 | 
			
		||||
                of.write('\t<tr><td></td>')
 | 
			
		||||
                of.write('<td class="field">')
 | 
			
		||||
                of.write('<a name="sref%d%s">' % (cindex,key))
 | 
			
		||||
                of.write('</a>%d%s.</td>' % (cindex,key))
 | 
			
		||||
                of.write('<td>')
 | 
			
		||||
                
 | 
			
		||||
                tmp = []
 | 
			
		||||
                confidence = Utils.confidence.get(sref.confidence, _('Unknown'))
 | 
			
		||||
                for (label,data) in [(_('Date'),_dd.display(sref.date)),
 | 
			
		||||
                                     (_('Page'),sref.page),
 | 
			
		||||
                                     (_('Confidence'),confidence)]:
 | 
			
		||||
                    if data:
 | 
			
		||||
                        tmp.append("%s: %s" % (label,data))
 | 
			
		||||
                notelist = sref.get_note_list()
 | 
			
		||||
                for notehandle in notelist:
 | 
			
		||||
                    note = self.db.get_note_from_handle(notehandle)
 | 
			
		||||
                    tmp.append("%s: %s" % (_('Text'),note.get(True)))
 | 
			
		||||
                if len(tmp) > 0:
 | 
			
		||||
                    of.write('<br />'.join(tmp))
 | 
			
		||||
                of.write('<p/>')
 | 
			
		||||
                of.write('</td></tr>\n')
 | 
			
		||||
        of.write('</table>\n')
 | 
			
		||||
        of.write('</div>\n')
 | 
			
		||||
 | 
			
		||||
@@ -1896,32 +1913,13 @@ class IndividualPage(BasePage):
 | 
			
		||||
        # Names [and their sources]
 | 
			
		||||
        for name in [self.person.get_primary_name(),]+self.person.get_alternate_names():
 | 
			
		||||
            pname = name_nameof(name,self.exclude_private)
 | 
			
		||||
            pname += self.get_citation_links( name.get_source_references() )
 | 
			
		||||
            type = str( name.get_type() )
 | 
			
		||||
            of.write('<tr><td class="field">%s</td>\n' % _(type))
 | 
			
		||||
            of.write('<td class="data">%s' % pname)
 | 
			
		||||
            if not self.restrict:
 | 
			
		||||
                nshl = []
 | 
			
		||||
                for nsref in name.get_source_references():
 | 
			
		||||
                    self.src_refs.append(nsref)
 | 
			
		||||
                    nsh = nsref.get_reference_handle()
 | 
			
		||||
                    lnk = (self.cur_name, self.page_title, self.gid)
 | 
			
		||||
                    if self.src_list.has_key(nsh):
 | 
			
		||||
                        if self.person.handle not in self.src_list[nsh]:
 | 
			
		||||
                            self.src_list[nsh].append(lnk)
 | 
			
		||||
                    else:
 | 
			
		||||
                        self.src_list[nsh] = [lnk]
 | 
			
		||||
                    nshl.append(nsref)
 | 
			
		||||
                if nshl:
 | 
			
		||||
                    of.write( " <sup>")
 | 
			
		||||
                    for nsh in nshl:
 | 
			
		||||
                        index = self.src_refs.index(nsh)+1
 | 
			
		||||
                        of.write(' <a href="#sref%d">%d</a>' % (index,index))
 | 
			
		||||
                    of.write( " </sup>")
 | 
			
		||||
 | 
			
		||||
            of.write('</td>\n</tr>\n')
 | 
			
		||||
 | 
			
		||||
        # Gender
 | 
			
		||||
 | 
			
		||||
        nick = self.person.get_nick_name()
 | 
			
		||||
        if nick:
 | 
			
		||||
            of.write('<tr><td class="field">%s</td>\n' % _('Nickname'))
 | 
			
		||||
@@ -2328,13 +2326,13 @@ class IndividualPage(BasePage):
 | 
			
		||||
                    self.src_list[handle].append(lnk)
 | 
			
		||||
            else:
 | 
			
		||||
                self.src_list[handle] = [lnk]
 | 
			
		||||
            self.src_refs.append(sref)
 | 
			
		||||
            
 | 
			
		||||
        if len(gid_list) > 0:
 | 
			
		||||
            text = text + " <sup>"
 | 
			
		||||
            for ref in gid_list:
 | 
			
		||||
                index = self.src_refs.index(ref)+1
 | 
			
		||||
                text = text + ' <a href="#sref%d">%d</a>' % (index,index)
 | 
			
		||||
                index,key = self.bibli.add_reference(ref)
 | 
			
		||||
                id = "%d%s" % (index+1,key)
 | 
			
		||||
                text = text + ' <a href="#sref%s">%s</a>' % (id,id)
 | 
			
		||||
            text = text + "</sup>"
 | 
			
		||||
 | 
			
		||||
        return text
 | 
			
		||||
 
 | 
			
		||||
		Reference in New Issue
	
	Block a user