Modified EE-references and GEDCOM generation to use Template data structures. Added support for interface to citeproc for CSL style sheets (not ready for use yet). Modified code to work with Python3.

svn: r22737
This commit is contained in:
Tim G L Lyons 2013-07-25 14:22:48 +00:00
parent 2430607b63
commit c4ecfaafe9
8 changed files with 577 additions and 500 deletions

View File

@ -181,11 +181,19 @@ def deprecated(func):
@functools.wraps(func)
def new_func(*args, **kwargs):
warnings.warn_explicit(
"Call to deprecated function {}.".format(func.__name__),
category=DeprecationWarning,
filename=func.func_code.co_filename,
lineno=func.func_code.co_firstlineno + 1
)
if sys.version_info[0] <3:
warnings.warn_explicit(
"Call to deprecated function {}.".format(func.__name__),
category=DeprecationWarning,
filename=func.func_code.co_filename,
lineno=func.func_code.co_firstlineno + 1
)
else:
warnings.warn_explicit(
"Call to deprecated function {}.".format(func.__name__),
category=DeprecationWarning,
filename=func.__code__.co_filename,
lineno=func.__code__.co_firstlineno + 1
)
return func(*args, **kwargs)
return new_func

View File

@ -26,16 +26,14 @@
SrcTemplate class for GRAMPS.
"""
from __future__ import print_function
#-------------------------------------------------------------------------
#
# Python modules
#
#-------------------------------------------------------------------------
from ..const import GRAMPS_LOCALE as glocale
_ = glocale.translation.gettext
import csv
from __future__ import print_function
from collections import defaultdict, OrderedDict
import sys
#------------------------------------------------------------------------
#
@ -50,6 +48,8 @@ LOG = logging.getLogger('.template')
# GRAMPS modules
#
#-------------------------------------------------------------------------
from ..const import GRAMPS_LOCALE as glocale
_ = glocale.translation.gettext
from .srcattrtype import *
from .date import Date
from .tableobj import TableObject
@ -144,7 +144,7 @@ class SrcTemplate(TableObject):
self.name = ""
self.descr = ""
self.template_element_list = []
self.mapping_list = []
self.mapdict = defaultdict(str)
self.structure = {REF_TYPE_L: [], REF_TYPE_F: [],
REF_TYPE_S: []}
self.empty()
@ -172,7 +172,7 @@ class SrcTemplate(TableObject):
self.name,
self.descr,
[template_element.serialize() for template_element in self.template_element_list],
[mapping.serialize() for mapping in self.mapping_list],
self.mapdict,
)
def to_struct(self):
@ -199,7 +199,7 @@ class SrcTemplate(TableObject):
"name": cuni(self.name),
"descr": cuni(self.descr),
"elements": [e.to_struct() for e in self.template_element_list],
"structure": (("%s: %s" % (s, self.structure[s])) for s in self.structure)
"mapdict" : self.mapdict,
}
def get_name(self):
@ -214,14 +214,19 @@ class SrcTemplate(TableObject):
def set_descr(self, descr):
self.descr = descr
def get_mapping_types_list(self):
return self.mapping_types_list
def get_map_dict(self):
"""Return the map for the template"""
return self.mapdict
def set_mapping_list(self, mapping_list):
self.mapping_list = mapping_list
def set_map_dict(self, templmap):
"""Set the map for the template"""
self.mapdict = templmap
def set_map_element(self, key, value):
self.mapdict[key] = value
def add_mapping(self, mapping):
self.mapping_list.append(mapping)
def get_map_element(self, key):
return self.mapdict[key]
def get_template_element_list(self):
return self.template_element_list
@ -250,83 +255,72 @@ class SrcTemplate(TableObject):
# map is field -> (normal value for ref L,
# normal value for ref F/S, short value ref S)
self.attrmap = {}
self.input_dict = defaultdict(str)
def set_attr_list(self, attr_list, attr_list_citation=None, date_citation=None):
"""
Set the attribute list of this template. Setting once for different
references saves some time.
attr_list should be the source attribute list
If citation given, citation attributes overrule source attributes for
If citation given, citation attrib
utes overrule source attributes for
the Full and Short references
The citation date is not stored as attribute, so pass Date() object via
date_citation if a date is known.
"""
self.empty()
self.attrmap = {}
self.input_dict = defaultdict(str)
self.attr_list = attr_list or []
self.attr_list_cite = attr_list_citation or []
self.date_citation = date_citation
# store attributes in a dict last to first. this overwrites data so first
# attribute will be the one taken if duplicates are present
for attr in self.attr_list[::-1]:
lower = False
typ = attr.get_type()
key = int(typ)
keystr = typ.xml_str().lower()
if keystr.lower().endswith(' (short)'):
#a shorter version, we store with base type
key = int(SrcAttributeType(keystr[:-8]))
lower = True
if key == SrcAttributeType.CUSTOM:
key = str(typ)
if key in self.attrmap:
if lower:
self.attrmap[key] = (self.attrmap[key][0],
self.attrmap[key][0], attr.get_value())
# -----------------------------------------------------------------
# Construct the input dictionary
# First pre-load the dictionary with default settings for citations
if not attr_list_citation:
for te in [x for x in self.get_template_element_list()
if x.get_citation()]:
name = str(SrcAttributeType(te.get_name())).upper().replace(' ', '_')
if te.get_display():
val = te.get_display().upper().replace(' ', '_')
else:
self.attrmap[key] = (attr.get_value(),
attr.get_value(), self.attrmap[key][1])
val = name
self.input_dict[name] = "[" + val + "]"
# Now get the actual attribute values. store attributes in a dict last
# to first. this overwrites data so first attribute will be the one
# taken if duplicates are present
for input_attr in ((attr_list or []) + (attr_list_citation or []))[::-1]:
typ = input_attr.get_type()
if int(typ) == SrcAttributeType.CUSTOM:
name = str(typ).upper().replace(' ', '_')
else:
if lower:
#store also in normal already value of short
self.attrmap[key] = (attr.get_value(),
attr.get_value(), attr.get_value())
else:
self.attrmap[key] = (attr.get_value(),
attr.get_value(), None)
name = typ.xml_str().upper().replace(' ', '_')
self.input_dict[name] = input_attr.get_value()
# if we haven't already got a value for the short attribute, we
# store the long attribute in the short attribute
if not name.endswith("(SHORT)"):
short_name = name + "_(SHORT)"
if self.input_dict.get(short_name) is None or \
(self.input_dict.get(short_name) and \
self.input_dict[short_name] == ("[" + short_name + "]")):
self.input_dict[short_name] = self.input_dict[name]
for attr in self.attr_list_cite[::-1]:
#we do same for citation information, but only update last two
# values of the attrmap
lower = False
typ = attr.get_type()
key = int(typ)
keystr = typ.xml_str().lower()
if keystr.lower().endswith(' (short)'):
#a shorter version, we store with base type
key = int(SrcAttributeType(keystr[:-8]))
lower = True
if key == SrcAttributeType.CUSTOM:
key = str(typ)
if key in self.attrmap:
if lower:
self.attrmap[key] = (self.attrmap[key][0],
self.attrmap[key][2], attr.get_value())
else:
self.attrmap[key] = (self.attrmap[key][0],
attr.get_value(), self.attrmap[key][2])
else:
#field only present in citation.
if lower:
#store also in normal already value of short, keep empty
#string for source fields
self.attrmap[key] = ('', attr.get_value(), attr.get_value())
else:
self.attrmap[key] = ('', attr.get_value(), None)
if self.date_citation:
#we store the date of the citation in attrmap
key = SrcAttributeType.DATE
self.attrmap[key] = (None, self.date_citation, None)
name = SrcAttributeType(SrcAttributeType.DATE).xml_str().upper().replace(' ', '_')
self.input_dict[name] = str(self.date_citation)
short_name = name + "_(SHORT)"
if self.input_dict.get(short_name) is None or \
(self.input_dict.get(short_name) and \
self.input_dict[short_name] == ("[" + short_name + "]")):
self.input_dict[short_name] = self.input_dict[name]
# FIXME: REPOSITORY, REPOSITORY_ADDRESS and REPOSITORY_CALL_NUMBER all
# need to be added to the self.input_dict. See srctemplatetab.py
# _add_repo_entry()
def reference_L(self, attr_list=None):
"""
Return the list reference based on the passed source attribute list
@ -342,7 +336,8 @@ class SrcTemplate(TableObject):
def reference_S(self, attr_list=None, attr_list_citation=None, date_citation=None):
"""
Return the short reference based on the passed source attribute list
If attr_list is None, same list as before is used.
If attr_list is None, same list as
before is used.
"""
if attr_list or attr_list_citation or date_citation:
self.set_attr_list(attr_list, attr_list_citation, date_citation)
@ -363,155 +358,190 @@ class SrcTemplate(TableObject):
self.refF = self._reference(REF_TYPE_F)
return self.refF
def __ged_page_reflist(self):
"""
Construct a derived template reflist for use to construct the gedcom
page field
"""
reflist_F = self.structure[REF_TYPE_F]
reflist_L_fields = [field[1] for field in self.structure[REF_TYPE_L]]
result = []
for entry in reflist_F:
if entry[1] in reflist_L_fields:
continue
if entry[1] == SrcAttributeType.DATE:
continue
result.append(entry)
def _reference(self, reftype, gedcomfield=None):
"""
Compute the reference based on data present.
At the moment no style is applied!
THIS IS UGLY CODE AT THE MOMENT! SHOULD BE ENTIRELY REWRITTEN, FOR
NOW IT JUST GIVES ME SOMETHING TO USE IN THE PROTOTYPE !!
"""
if gedcomfield == GED_PAGE:
self.__ged_page_reflist()
else:
reflist = self.structure[reftype]
# reflist is typically a list like
# [ ('', AUTHOR, '', ',', EMPTY, False, False, EMPTY, EMPTY, None, None),
# ('', TITLE, '', ',', STYLE_QUOTE, False, False, EMPTY, EMPTY, None, None),
# ('', PUB_INFO, '', '.', EMPTY, False, False, EMPTY, EMPTY, None, None),
# ('', DATE, '', ' -', EMPTY, False, False, EMPTY, EMPTY, None, None),
# ('', PAGE, 'Page(s)', '.', EMPTY, False, False, EMPTY, EMPTY, None, None),
# ]
# http://bugs.python.org/issue6081
class DefaultBlank(dict):
def __missing__(self, key):
return ""
class DefaultKey(dict):
def __missing__(self, key):
return "[" + key + "]"
ged_table = {
GED_AUTHOR : "GEDCOM_A",
GED_TITLE : "GEDCOM_T",
GED_PUBINF : "GEDCOM_P",
GED_DATE : "GEDCOM_D",
GED_PAGE : "GEDCOM_PAGE",
}
if gedcomfield:
return (self.get_map_element(ged_table[gedcomfield]) %
DefaultKey(self.input_dict)) or ""
use_CSL = False
try:
import citeproc
if sys.version_info[0] >= 3:
use_CSL = True
except:
pass
if use_CSL:
# -----------------------------------------------------------------
# Construct the standard output-elements
self.output_dict = OrderedDict()
LOG.debug(self.get_map_dict())
LOG.debug("input_attributes \n" +
"".join(("%s: %s\n" % item) for item in list(self.input_dict.items())))
for key, val in list(self.get_map_dict().items()):
if key[0].islower():
try:
self.output_dict[key] = val % DefaultBlank(self.input_dict)
except:
LOG.warn("key error with key %s; val %s; input_dict %s" %
(key, val, self.input_dict))
self.output_dict[key] = ""
LOG.debug("CSL_attributes \n" +
"".join(("%s: %s\n" % item) for item in list(self.output_dict.items())))
# Temporary fix for not implemented yet templates
if len(self.output_dict) == 0:
return ""
# Now fix CSL attributes that need special sub-elements
for name in ["author", "container_author", "some other name"]:
if name in self.output_dict:
self.output_dict[name] = [{"family": self.output_dict[name],
"given": ""}]
# -----------------------------------------------------------------
# Modify the output-elements to allow the standard Chicago style to
# format the citations close to Evidence Style
# literal dates are not specially treated. Date accessed is converted to
# a literal publication date to conform to how ESM formats the accessed
# date
if "accessed" in self.output_dict:
self.output_dict["issued"] = {'literal' : "accessed " + self.output_dict['accessed']}
del self.output_dict['accessed']
# Website is rendered as publisher_place to conform to how ESM renders
# it.
if "url" in self.output_dict:
self.output_dict["publisher_place"] = \
self.output_dict["publisher_place"] if "publisher_place" in self.output_dict \
else "" + self.output_dict["url"]
LOG.debug("self.output_dictibutes modified \n" +
"".join((" %s: %s\n" % item) for item in self.output_dict.items()))
try:
(refF, refS, refL) = self.get_CSL_references(self.output_dict)
if reftype == REF_TYPE_F:
return refF
elif reftype == REF_TYPE_S:
return refS
else:
return refL
except:
print(sys.exc_info()[0], sys.exc_info()[1])
return ""
#set col of attrmap to use:
if reftype == REF_TYPE_L:
COL_NORMAL = 0
COL_SHORT = 2
else:
COL_NORMAL = 1
COL_SHORT = 2
ref = ['']
fieldadded = [False]
for (ldel, field, label, rdel, style, priv, opt, short, gedcom,
hint, tooltip) in reflist:
if not gedcomfield is None and gedcom != gedcomfield:
continue
customshort = False
#left delimiter
if ldel in ['(', '[', '{']:
ref += ['']
fieldadded += [False]
ref[-1] += ldel
ldeltodo = ''
else:
ldeltodo = ldel
val = self.attrmap.get(field)
#field
field = ''
if val is not None:
if reftype == REF_TYPE_S and val[COL_SHORT] is not None:
customshort = True
field = val[COL_SHORT]
else:
field = val[COL_NORMAL]
if short and not customshort:
#we apply the shortening algorithm
## TODO: not implemented yet
pass
#if field is a Date object, we now convert to string
if isinstance(field, Date):
field = str(field)
if field.strip():
fieldadded[-1] = True
ref[-1] += ldeltodo
if len(ref[-1]) and ref[-1][-1] == '.':
ref[-1] += ' ' + field[0].capitalize() + field[1:]
elif len(ref[-1]) and ref[-1][-1] in [',', ':', '-']:
ref[-1] += ' ' + field
elif len(ref[-1]) and ref[-1] != ' ':
ref[-1] += ' ' + field
else:
ref[-1] += field
#right delimiter
nobracket = True
for bracketl, bracketr in [('(', ')'), ('[',']'), ('{','}')]:
if bracketr in rdel:
nobracket = False
if len(ref[-1] [ref[-1].find(bracketl)+1:]) > 0 :
newval = ref[-1] + rdel
ref = ref[:-1]
fieldadded = fieldadded[:-1]
fieldadded[-1] = True
ref[-1] += newval
else:
#no data inside of delimiter, we remove it entirely
ref = ref[:-1]
fieldadded = fieldadded[:-1]
#if . at end of rdel, add it
if rdel[-1] == '.':
if ref[-1] and ref[-1][-1] in [',', '.']:
ref[-1] = ref[-1][:-1]
if ref[-1]:
ref[-1] = ref[-1] + '.'
elif rdel[-1] == ',':
if ref[-1] and ref[-1][-1] in [',', '.']:
pass
elif ref[-1]:
ref[-1] = ref[-1] + ','
if nobracket:
# we add rdel
if not ref[-1]:
#nothing there, don't add delimiter
pass
elif len(rdel) and rdel[0] == '.':
curval = ref[-1]
if len(curval) and curval[-1] == '.':
pass
elif len(curval) and curval[-1] in [',', ';']:
ref[-1] = ref[-1][:-1] + rdel
else:
ref[-1] = ref[-1] + rdel
#we only add delimiters after this if new fields are added
fieldadded[-1] = False
elif len(rdel) and rdel[0] == ',':
curval = ref[-1]
if len(curval) and curval[-1] in ['.', ';']:
pass
elif len(curval) and curval[-1] == ',':
pass
elif fieldadded[-1]:
ref[-1] = ref[-1] + rdel
#we only add delimiters after this if new fields are added
fieldadded[-1] = False
else:
if fieldadded[-1]:
ref[-1] = ref[-1] + rdel
#we only add delimiters after this if new fields are added
fieldadded[-1] = False
ref = ' '.join(ref)
if ref:
ref = ref[0].capitalize() + ref[1:]
ref.replace(' ', ' ')
return ref
else:
return ref
# -----------------------------------------------------------------
# Construct the standard output-elements
ref_table = {
REF_TYPE_L : "EE_L",
REF_TYPE_F : "EE_F",
REF_TYPE_S : "EE_S",
}
return (self.get_map_element(ref_table[reftype]) %
DefaultKey(self.input_dict)) or ""
def get_CSL_references(self, CSL_attributes):
# Import the citeproc-py classes we'll use below.
from citeproc import CitationStylesStyle, CitationStylesBibliography
from citeproc import Citation, CitationItem
from citeproc import formatter, Locator
from citeproc.source.json import CiteProcJSON
# Process the JSON data to generate a citeproc-py BibliographySource.
if 'locator' in CSL_attributes:
loc = Locator("page", CSL_attributes["locator"])
import copy
c1 = copy.deepcopy(CSL_attributes)
c2 = copy.deepcopy(CSL_attributes)
bib_source = {"full": c1, "subs" : c2}
bib_source = {"full": c1}
# for key, entry in bib_source.items():
# print(key)
# for name, value in entry.items():
# print(' {}: {}'.format(name, value))
# load a CSL style (from the current directory)
bib_style = CitationStylesStyle('chicago-fullnote-bibliography-no-ibid.csl')
# Create the citeproc-py bibliography, passing it the:
# * CitationStylesStyle,
# * BibliographySource (CiteProcJSON in this case), and
# * a formatter (plain, html, or you can write a custom formatter)
bibliography = CitationStylesBibliography(bib_style, bib_source, formatter.plain)
# Processing citations in a document need to be done in two passes as for some
# CSL styles, a citation can depend on the order of citations in the
# bibliography and thus on citations following the current one.
# For this reason, we first need to register all citations with the
# CitationStylesBibliography.
if loc:
citation1 = Citation([CitationItem('full', locator=loc)])
citation2 = Citation([CitationItem('subs', locator=loc)])
else:
citation1 = Citation([CitationItem('full')])
citation2 = Citation([CitationItem('subs')])
citation1 = Citation([CitationItem('full')])
bibliography.register(citation1)
bibliography.register(citation2)
# In the second pass, CitationStylesBibliography can generate citations.
# CitationStylesBibliography.cite() requires a callback function to be passed
# along to be called in case a CitationItem's key is not present in the
# bilbiography.
def warn(citation_item):
print("WARNING: Reference with key '{}' not found in the bibliography."
.format(citation_item.key))
print('Citations')
print('---------')
print(bibliography.cite(citation1, warn))
print(bibliography.cite(citation2, warn))
# And finally, the bibliography can be rendered.
print('')
print('Bibliography')
print('------------')
print(bibliography.bibliography())
return(bibliography.cite(citation1, warn),
bibliography.cite(citation2, warn),
bibliography.bibliography())
def author_gedcom(self, attr_list=None):
if attr_list:
self.set_attr_list(attr_list)
@ -576,7 +606,6 @@ class TemplateElement(SecondaryObject):
self.citation = source.citation
self.short - source.short
self.short_alg = source.short_alg
self.template_mapping_list = source.template_mapping_list
else:
self.name = ""
self.display = ""
@ -585,7 +614,6 @@ class TemplateElement(SecondaryObject):
self.citation = False
self.short = False
self.short_alg = ""
self.template_mapping_list = []
def serialize(self):
"""
@ -595,7 +623,9 @@ class TemplateElement(SecondaryObject):
self.display,
self.hint,
self.tooltip,
# [template_mapping.serialize() for template_mapping in self.template_mapping_list]
self.citation,
self.short,
self.short_alg
)
def to_struct(self):
@ -622,13 +652,17 @@ class TemplateElement(SecondaryObject):
"display": cuni(self.display),
"hint": cuni(self.hint),
"tooltip": cuni(self.tooltip),
"citation": cuni(self.citation),
"short": cuni(self.short),
"short_alg": cuni(self.short_alg),
}
def unserialize(self, data):
"""
Convert a serialized tuple of data to an object.
"""
(self.name, self.type) = data
(self.name, self.display, self.hint, self.tooltip, self.citation,
self.short, self.short_alg) = data
return self
def get_name(self):
@ -715,96 +749,3 @@ class TemplateElement(SecondaryObject):
Set the short_alg for the Template element according to the given argument.
"""
self.short_alg = short_alg
def get_template_mapping_list(self):
return self.template_mapping_list
def set_template_mapping_list(self, template_mapping_list):
self.template_mapping_list = template_mapping_list
def add_template_mapping(self, template_mapping):
self.template_mapping_list.append(template_mapping)
class MappingElement(SecondaryObject):
"""
TemplateEelement class.
This class is for keeping information about how each [input] Template
Element is mapped to an Output form.
Mapping:
- Mapping_name - English name of the mapping. One mapping GEDCOM would
always be present. Other mappings are optional, but as we have decided
that (at least initially) we would use the CSL mapping, then this should
also be present). (The mappings should be the same as in the
MappingType).
- map_target - the English interchange-element name onto which this
template-element is mapped. e.g. [WRITER FIRST] is mapped onto Recipient,
so this would contain recipient.
- Mapping_order the sequence number for this mapping. So [WRITER LAST],
[WRITER FIRST] both map to 'Recipient', [WRITER FIRST] is 2, [WRITER
LAST] is 1
- separator - the separator after this element if there is another one
following, e.g.", "
"""
def __init__(self, source=None):
"""
Create a new MappingEelement instance, copying from the source if
present.
"""
if source:
self.name = source.name
self.target = source.target
self.order = source.order
self.separator = source.separator
else:
self.name = ""
self.target = ""
self.order = ""
self.separator = ""
def serialize(self):
"""
Convert the object to a serialized tuple of data.
"""
return (self.name,
self.target,
self.order,
self.separator
)
def unserialize(self, data):
"""
Convert a serialized tuple of data to an object.
"""
(self.name, self.type) = data
return self
def get_name(self):
"""
Return the name for the mapping element.
"""
return self.name
def set_name(self, name):
"""
Set the role according to the given argument.
"""
self.name = name
def get_target(self):
"""
Return the tuple corresponding to the preset role.
"""
return self.target
def set_target(self, target):
"""
Set the role according to the given argument.
"""
self.target = target

View File

@ -33,6 +33,7 @@ from __future__ import print_function
# Python modules
#
#-------------------------------------------------------------------------
import sys
#------------------------------------------------------------------------
#
@ -56,7 +57,14 @@ class Singleton(type):
cls._instances[cls] = super(Singleton, cls).__call__(*args, **kwargs)
return cls._instances[cls]
class SrcTemplateList(object):
# See http://stackoverflow.com/questions/17237857/python3-singleton-metaclass-
# method-not-working the syntax has changed
# http://mikewatkins.ca/2008/11/29/python-2-and-3-metaclasses/
# http://stackoverflow.com/questions/6760685/creating-a-singleton-in-python/17840539
STL = Singleton('STL', (object, ), {})
class SrcTemplateList(STL):
"""
Manages a singleton list of the source templates.
@ -68,7 +76,7 @@ class SrcTemplateList(object):
of keys, and another method to return the Template object for a given key.
In this way it would act like a database table.
"""
__metaclass__ = Singleton
# __metaclass__ = Singleton
def __init__(self):
self.template_list = {}
@ -84,7 +92,7 @@ class SrcTemplateList(object):
gedtempl = None
if name == 'UNKNOWN':
name = 'GEDCOM'
for template in self.template_list.itervalues():
for template in list(self.template_list.values()):
if template.get_name() == name:
return template
if template.get_name() == 'GEDCOM':

View File

@ -537,7 +537,7 @@ class EmbeddedList(ButtonTab):
column = Gtk.TreeViewColumn(name, self.pb_renderer)
column.set_cell_data_func(self.pb_renderer, self.icon_func, pair[1])
else:
raise NotImplementedError, 'Unknown column type'
raise NotImplementedError('Unknown column type')
if col_icon is not None:
image = Gtk.Image()
image.set_from_stock(col_icon, Gtk.IconSize.MENU)

View File

@ -37,6 +37,14 @@ _ = glocale.translation.gettext
from gi.repository import Gdk
from gi.repository import Gtk
#------------------------------------------------------------------------
#
# Set up logging
#
#------------------------------------------------------------------------
import logging
LOG = logging.getLogger('.template')
#-------------------------------------------------------------------------
#
# Gramps libraries
@ -51,6 +59,7 @@ from ...widgets.srctemplatetreeview import SrcTemplateTreeView
from ...widgets import (UndoableEntry, MonitoredEntryIndicator, MonitoredDate,
ValidatableMaskedEntry)
from .grampstab import GrampsTab
from gramps.gen.constfunc import STRTYPE
#-------------------------------------------------------------------------
#
@ -210,6 +219,7 @@ class TemplateFields(object):
template = SrcTemplateList().get_template_from_name(key).get_structure()
telist = SrcTemplateList().get_template_from_name(key).get_template_element_list()
else:
LOG.warn("template not defined %s" % key)
return
# first remove old fields
@ -303,8 +313,8 @@ class TemplateFields(object):
"""
self.gridfields.insert_row(row)
field = srcattrtype
if isinstance(field, basestring):
raise NotImplementedError, "type must be the integer key"
if isinstance(field, STRTYPE):
raise NotImplementedError("type must be the integer key")
#setup label
if alt_label:
label = alt_label

View File

@ -357,15 +357,10 @@ class EditSource(EditPrimary):
#we only construct once the template to use to format information
if self.srctemp is None:
self.srctemp = SrcTemplateList().get_template_from_name(self.obj.get_template())
# FIXME: I am not sure what the code below was doing. The SrcTemplate
# had been set from the name in the Src record, then a check was made as
# to whether the old name from the Src record was the same as the name
# of the template. But since the template was found from its name, this
# must be the case.
# #if source template changed, reinit template
# if self.obj.get_template() != self.srctemp.get_template_key():
# self.srctemp.set_template_key(self.obj.get_template())
#if source template changed, reinit template
if self.obj.get_template() != self.srctemp.get_name():
self.srctemp = SrcTemplateList().get_template_from_name(self.obj.get_template())
#set new attrlist in template
if self.citation_loaded:
citeattr = self.citation.get_attribute_list()
@ -377,15 +372,15 @@ class EditSource(EditPrimary):
citedate)
#set fields with the template
self.refL.set_text(self.srctemp.reference_L())
self.refL.set_markup(self.srctemp.reference_L())
if self.citation_loaded:
self.refF.set_text(self.srctemp.reference_F())
self.refS.set_text(self.srctemp.reference_S())
self.refF.set_markup(self.srctemp.reference_F())
self.refS.set_markup(self.srctemp.reference_S())
else:
self.refF.set_text(_("<no citation loaded>"))
self.refS.set_text(_("<no citation loaded>"))
self.author.set_text(self.srctemp.author_gedcom())
self.pubinfo.set_text(self.srctemp.pubinfo_gedcom())
self.refF.set_markup(_("<no citation loaded>"))
self.refS.set_markup(_("<no citation loaded>"))
self.author.set_markup(self.srctemp.author_gedcom())
self.pubinfo.set_markup(self.srctemp.pubinfo_gedcom())
if self.template_tab and self.template_tab.autoset_title:
title = self.srctemp.title_gedcom()
self.obj.set_name(title)

View File

@ -95,6 +95,146 @@
<object class="GtkVBox" id="vbox">
<property name="visible">True</property>
<property name="can_focus">False</property>
<child>
<object class="GtkExpander" id="expander1">
<property name="visible">True</property>
<property name="can_focus">True</property>
<property name="halign">start</property>
<property name="expanded">True</property>
<child>
<object class="GtkGrid" id="grid2">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="margin_left">5</property>
<property name="margin_right">5</property>
<property name="row_spacing">3</property>
<property name="column_spacing">3</property>
<child>
<object class="GtkLabel" id="label7">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="halign">start</property>
<property name="valign">start</property>
<property name="xalign">0</property>
<property name="yalign">0</property>
<property name="label" translatable="yes">Full footnote:</property>
<property name="justify">center</property>
<property name="ellipsize">start</property>
</object>
<packing>
<property name="left_attach">0</property>
<property name="top_attach">0</property>
<property name="width">1</property>
<property name="height">2</property>
</packing>
</child>
<child>
<object class="GtkLabel" id="label9">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="halign">start</property>
<property name="valign">start</property>
<property name="xalign">0</property>
<property name="yalign">0</property>
<property name="label" translatable="yes">Bibliography:</property>
</object>
<packing>
<property name="left_attach">0</property>
<property name="top_attach">2</property>
<property name="width">1</property>
<property name="height">1</property>
</packing>
</child>
<child>
<object class="GtkLabel" id="refF">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="valign">start</property>
<property name="hexpand">True</property>
<property name="xalign">0.079999998211860657</property>
<property name="yalign">0</property>
<property name="label" translatable="yes">label</property>
<property name="wrap">True</property>
</object>
<packing>
<property name="left_attach">1</property>
<property name="top_attach">0</property>
<property name="width">1</property>
<property name="height">1</property>
</packing>
</child>
<child>
<object class="GtkLabel" id="refS">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="valign">start</property>
<property name="hexpand">True</property>
<property name="xalign">0</property>
<property name="yalign">0</property>
<property name="label" translatable="yes">label</property>
<property name="wrap">True</property>
</object>
<packing>
<property name="left_attach">1</property>
<property name="top_attach">1</property>
<property name="width">1</property>
<property name="height">1</property>
</packing>
</child>
<child>
<object class="GtkLabel" id="refL">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="valign">start</property>
<property name="hexpand">True</property>
<property name="xalign">0</property>
<property name="yalign">0</property>
<property name="label" translatable="yes">label</property>
<property name="wrap">True</property>
</object>
<packing>
<property name="left_attach">1</property>
<property name="top_attach">2</property>
<property name="width">1</property>
<property name="height">1</property>
</packing>
</child>
<child>
<object class="GtkLabel" id="label8">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="halign">start</property>
<property name="valign">start</property>
<property name="xalign">0</property>
<property name="yalign">0.029999999329447746</property>
<property name="label" translatable="yes">Short footnote</property>
</object>
<packing>
<property name="left_attach">0</property>
<property name="top_attach">1</property>
<property name="width">1</property>
<property name="height">1</property>
</packing>
</child>
</object>
</child>
<child type="label">
<object class="GtkLabel" id="label6">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="xalign">0.50999999046325684</property>
<property name="yalign">0.50999999046325684</property>
<property name="label" translatable="yes">&lt;b&gt;Reference Information&lt;/b&gt;</property>
<property name="use_markup">True</property>
</object>
</child>
</object>
<packing>
<property name="expand">False</property>
<property name="fill">True</property>
<property name="position">1</property>
</packing>
</child>
<child>
<object class="GtkLabel" id="cite_info_lbl">
<property name="visible">True</property>
@ -106,7 +246,7 @@
<packing>
<property name="expand">False</property>
<property name="fill">True</property>
<property name="position">0</property>
<property name="position">1</property>
</packing>
</child>
<child>
@ -390,17 +530,14 @@
<property name="height">1</property>
</packing>
</child>
<child>
<placeholder/>
</child>
<child>
<object class="GtkLabel" id="label3">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="xalign">0</property>
<property name="label" translatable="yes">_Name:</property>
<property name="mnemonic_widget">cname</property>
<property name="use_underline">True</property>
<property name="mnemonic_widget">cname</property>
</object>
<packing>
<property name="left_attach">0</property>
@ -424,6 +561,9 @@
<property name="height">1</property>
</packing>
</child>
<child>
<placeholder/>
</child>
</object>
</child>
<child type="tab">
@ -445,7 +585,7 @@
<packing>
<property name="expand">True</property>
<property name="fill">True</property>
<property name="position">1</property>
<property name="position">2</property>
</packing>
</child>
<child>
@ -459,7 +599,7 @@
<packing>
<property name="expand">False</property>
<property name="fill">True</property>
<property name="position">2</property>
<property name="position">3</property>
</packing>
</child>
<child>
@ -671,142 +811,6 @@
<property name="height">1</property>
</packing>
</child>
<child>
<object class="GtkExpander" id="expander1">
<property name="visible">True</property>
<property name="can_focus">True</property>
<property name="expanded">True</property>
<child>
<object class="GtkGrid" id="grid2">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="margin_left">5</property>
<property name="margin_right">5</property>
<property name="row_spacing">3</property>
<property name="column_spacing">3</property>
<child>
<object class="GtkLabel" id="label7">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="halign">start</property>
<property name="valign">start</property>
<property name="xalign">0</property>
<property name="yalign">0</property>
<property name="label" translatable="yes">Listing:</property>
</object>
<packing>
<property name="left_attach">0</property>
<property name="top_attach">0</property>
<property name="width">1</property>
<property name="height">1</property>
</packing>
</child>
<child>
<object class="GtkLabel" id="label9">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="halign">start</property>
<property name="valign">start</property>
<property name="xalign">0</property>
<property name="yalign">0</property>
<property name="label" translatable="yes">Short footnote:</property>
</object>
<packing>
<property name="left_attach">0</property>
<property name="top_attach">2</property>
<property name="width">1</property>
<property name="height">1</property>
</packing>
</child>
<child>
<object class="GtkLabel" id="refL">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="valign">start</property>
<property name="hexpand">True</property>
<property name="xalign">0</property>
<property name="yalign">0</property>
<property name="label" translatable="yes">label</property>
<property name="wrap">True</property>
</object>
<packing>
<property name="left_attach">1</property>
<property name="top_attach">0</property>
<property name="width">1</property>
<property name="height">1</property>
</packing>
</child>
<child>
<object class="GtkLabel" id="refF">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="valign">start</property>
<property name="hexpand">True</property>
<property name="xalign">0</property>
<property name="yalign">0</property>
<property name="label" translatable="yes">label</property>
<property name="wrap">True</property>
</object>
<packing>
<property name="left_attach">1</property>
<property name="top_attach">1</property>
<property name="width">1</property>
<property name="height">1</property>
</packing>
</child>
<child>
<object class="GtkLabel" id="refS">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="valign">start</property>
<property name="hexpand">True</property>
<property name="xalign">0</property>
<property name="yalign">0</property>
<property name="label" translatable="yes">label</property>
<property name="wrap">True</property>
</object>
<packing>
<property name="left_attach">1</property>
<property name="top_attach">2</property>
<property name="width">1</property>
<property name="height">1</property>
</packing>
</child>
<child>
<object class="GtkLabel" id="label8">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="halign">start</property>
<property name="valign">start</property>
<property name="xalign">0</property>
<property name="yalign">0</property>
<property name="label" translatable="yes">Full footnote:</property>
</object>
<packing>
<property name="left_attach">0</property>
<property name="top_attach">1</property>
<property name="width">1</property>
<property name="height">1</property>
</packing>
</child>
</object>
</child>
<child type="label">
<object class="GtkLabel" id="label6">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="label" translatable="yes">&lt;b&gt;Reference Information&lt;/b&gt;</property>
<property name="use_markup">True</property>
</object>
</child>
</object>
<packing>
<property name="left_attach">0</property>
<property name="top_attach">5</property>
<property name="width">4</property>
<property name="height">1</property>
</packing>
</child>
<child>
<object class="GtkExpander" id="expander2">
<property name="visible">True</property>
@ -991,6 +995,30 @@
<child>
<placeholder/>
</child>
<child>
<placeholder/>
</child>
<child>
<placeholder/>
</child>
<child>
<placeholder/>
</child>
<child>
<placeholder/>
</child>
<child>
<placeholder/>
</child>
<child>
<placeholder/>
</child>
<child>
<placeholder/>
</child>
<child>
<placeholder/>
</child>
</object>
</child>
<child type="tab">
@ -1157,7 +1185,7 @@
<packing>
<property name="expand">True</property>
<property name="fill">True</property>
<property name="position">3</property>
<property name="position">4</property>
</packing>
</child>
</object>

View File

@ -37,6 +37,7 @@ from gramps.gen.const import GRAMPS_LOCALE as glocale
_ = glocale.translation.gettext
import csv
import collections
import sys
#-------------------------------------------------------------------------
#
@ -99,8 +100,13 @@ def load_srctemplates_data():
if mod:
csvfilename = mod.csvfile
LOG.debug("**** load_srctemplate_data. Loading csv from %s" % csvfilename)
with open(csvfilename, 'rb') as csvfile:
load_srctemplate_csv(csvfile)
if sys.version_info[0] <3:
with open(csvfilename, 'rb') as csvfile:
load_srctemplate_csv(csvfile)
else:
with open(csvfilename, 'r') as csvfile:
load_srctemplate_csv(csvfile)
LOG.debug("**** load_srctemplate_data. csv data loaded")
def load_srctemplate_gedcom():
@ -158,7 +164,7 @@ def load_srctemplate_gedcom():
tlist = SrcTemplateList()
tlist.add_template(handle, template)
for (cite_type, slist) in TEMPLATES['GEDCOM'].iteritems():
for (cite_type, slist) in list(TEMPLATES['GEDCOM'].items()):
if cite_type != DESCR:
for struct in slist:
if cite_type == REF_TYPE_L or cite_type == REF_TYPE_F:
@ -197,6 +203,16 @@ def load_srctemplate_gedcom():
field_label, rdel, style, private, optional,
shorteralg, gedcommap, hint, tooltip)])
template.set_map_element("GEDCOM_A", "AUTHOR")
template.set_map_element("GEDCOM_T", "TITLE")
template.set_map_element("GEDCOM_P", "PUB_INFO")
template.set_map_element("GEDCOM_D", "DATE")
template.set_map_element("GEDCOM_PAGE", "PAGE")
template.set_map_element("EE_L", "%(AUTHOR)s. %(TITLE)s. %(PUB_INFO)s")
template.set_map_element("EE_F", "%(AUTHOR)s, %(TITLE)s, %(PUB_INFO)s. %(DATE)s - %(PAGE)s")
template.set_map_element("EE_S", "%(AUTHOR_(SHORT))s, %(DATE_(SHORT))s - %(PAGE_(SHORT))s.")
for handle in SrcTemplateList().get_template_list():
template = SrcTemplateList().get_template_from_handle(handle)
LOG.debug("source_type: %s" % template.get_name())
@ -267,10 +283,10 @@ def load_srctemplate_csv(csvfile):
source_descr = '%s - %s - %s' % (_(cat), _(cattype), _(types))
if source_type in TYPE2TEMPLATEMAP:
if not TYPE2TEMPLATEMAP[source_type].get_descr() == source_descr:
raise NotImplementedError, source_type + ' ' + TYPE2TEMPLATEMAP[source_type].get_descr() + ' NOT equal to known description' + source_descr
raise NotImplementedError(source_type + ' ' + TYPE2TEMPLATEMAP[source_type].get_descr() + ' NOT equal to known description' + source_descr)
if newtempl:
#the template is new in this csv, but already defined, probably user error
raise NotImplementedError, 'Source template ' + prevtempl + ' is twice defined in the csv.'
raise NotImplementedError('Source template ' + prevtempl + ' is twice defined in the csv.')
else:
template = SrcTemplate()
template.set_name(source_type)
@ -285,13 +301,13 @@ def load_srctemplate_csv(csvfile):
if row[CITETYPECOL]:
#new citation type,
cite_type = row[CITETYPECOL].strip()
assert cite_type in ['F', 'L', 'S'], str(cite_type)
if cite_type == 'S':
cite_type_text = row[CITETYPECOL].strip()
assert cite_type_text in ['F', 'L', 'S'], str(cite_type_text)
if cite_type_text == 'S':
shortcite = True
else:
shortcite = False
cite_type = CITE_TYPES[cite_type]
cite_type = CITE_TYPES[cite_type_text]
#add field for template to evidence style
field = row[FIELDCOL].strip()
field_type = field.replace('[', '').replace(']','').lower().capitalize()
@ -306,7 +322,7 @@ def load_srctemplate_csv(csvfile):
ifield_type.set_from_xml_str(field_type)
ifield_type = int(SrcAttributeType(ifield_type))
if ifield_type == SrcAttributeType.CUSTOM:
raise NotImplementedError, "field must be a known SrcAttributeType, is " + str(SrcAttributeType(field_type))
raise NotImplementedError("field must be a known SrcAttributeType, is " + str(SrcAttributeType(field_type)))
field_type = ifield_type
#field_descr = field.replace('[', '').replace(']','').lower().capitalize()
field_label = row[LABELCOL].strip()
@ -318,6 +334,7 @@ def load_srctemplate_csv(csvfile):
if row[OPTCOL].strip():
optional = True
shorteralg = SHORTERALG.get(row[SHORTERCOL].strip()) or EMPTY
gedcom_type_text = row[GEDCOMCOL].strip()
gedcommap = GEDCOMFIELDS.get(row[GEDCOMCOL].strip()) or EMPTY
style = STYLES.get(row[STYLECOL].strip()) or EMPTY
@ -361,11 +378,44 @@ def load_srctemplate_csv(csvfile):
_(field_label), row[RDELCOL], style, private, optional,
shorteralg, gedcommap, _(hint), _(tooltip))])
# Setup the mapping. A typical mapping would look like:
# ('EE_Full' : '%(COMPILER)s, "%(TITLE)s", %(TYPE)s, %(WEBSITE CREATOR/OWNER)s, <i>%(WEBSITE)s</i>, (%(URL (DIGITAL LOCATION))s: accessed %(DATE ACCESSED)s), %(ITEM OF INTEREST)s; %(CREDIT LINE)s.')
target = "EE_" + cite_type_text
if te.get_short():
txt = int(SrcAttributeType().short_version(field_type))
else:
txt = field_type
txt = row[LDELCOL] + "%(" + \
SrcAttributeType(txt).xml_str().upper().replace(' ', '_') + \
")s" + row[RDELCOL]
if len(row[RDELCOL]) and row[RDELCOL][-1] in ['.', ',', ':', ';', '-']:
txt += ' '
if style == STYLE_QUOTE:
txt = '"' + txt + '"'
elif style == STYLE_QUOTECONT:
if template.get_map_element(target)[-1] == '"':
template.set_map_element(target, template.get_map_element(target)[:-1])
txt = txt + '"'
else:
txt = '"' + txt + '"'
elif style == STYLE_EMPH:
txt = "<i>" + txt + "</i>"
elif style == STYLE_BOLD:
txt = "<b>" + txt + "</b>"
template.set_map_element(target, template.get_map_element(target) + txt)
# Setup the GEDCOM fields. These are only stored in the L template
if cite_type == REF_TYPE_L and gedcom_type_text:
target = "GEDCOM_" + gedcom_type_text
if style == STYLE_QUOTECONT:
if template.get_map_element(target) and template.get_map_element(target)[-1] == '"':
template.set_map_element(target, template.get_map_element(target)[:-1])
template.set_map_element(target, template.get_map_element(target) + txt)
# Now we adjust some fields that could not be changed till all the data had
# been read in
for source_type in TYPE2FIELDS:
template = TYPE2TEMPLATEMAP[source_type]
LOG.debug("source_type: %s" % source_type)
# First we determine which are citation fields
cite_fields = [field for field in
TYPE2FIELDS[source_type][REF_TYPE_F] +
@ -388,14 +438,51 @@ def load_srctemplate_csv(csvfile):
# sources
if te.get_short() == True:
te.set_name(int(SrcAttributeType().short_version(te.get_name())))
LOG.debug(" name: %s; display: %s; hint: %s; tooltip: %s; "
"citation %s; short %s; short_alg %s" %
(SrcAttributeType(te.get_name()).xml_str(),
te.get_display(), te.get_hint(),
te.get_tooltip(), te.get_citation(),
te.get_short(), te.get_short_alg()
))
# Finally we setup the GEDCOM page fields
for source_type in TYPE2FIELDS:
template = TYPE2TEMPLATEMAP[source_type]
for te in [x for x in template.get_template_element_list()
if x.get_citation() and not x.get_short()]:
target = "GEDCOM_PAGE"
template.set_map_element(target,
", ".join((template.get_map_element(target), txt)))
# Proof of concept for CSL mapping
template = TYPE2TEMPLATEMAP.get('ESM254')
if template:
amap = {
'type' : 'chapter',
'author' : '%(COMPILER)s',
'title' : '%(TITLE)s',
'edition' : '%(TYPE)s',
'container_author' : '%(WEBSITE_CREATOR/OWNER)s',
'container_title' : '%(WEBSITE)s',
'url' : '%(URL_(DIGITAL_LOCATION))s',
'locator' : '%(ITEM_OF_INTEREST)s; %(CREDIT_LINE)s',
'accessed' : '%(DATE_ACCESSED)s',
'page' : '1-7'
}
for key, val in list(amap.items()):
template.set_map_element(key, val)
# for source_type in TYPE2FIELDS:
# LOG.debug("source_type: %s" % source_type)
# template = TYPE2TEMPLATEMAP[source_type]
# for te in template.get_template_element_list():
# LOG.debug(" name: %s; display: %s; hint: %s; tooltip: %s; "
# "citation %s; short %s; short_alg %s" %
# (SrcAttributeType(te.get_name()).xml_str(),
# te.get_display(), te.get_hint(),
# te.get_tooltip(), te.get_citation(),
# te.get_short(), te.get_short_alg()
# ))
# for target in template.get_map_dict():
# LOG.debug("Type %s; target %s; map %s" %
# (source_type, target, template.get_map_element(target)))
# LOG.debug(tlist.get_template_list())
# for handle in tlist.get_template_list():
# LOG.debug(tlist.get_template_from_handle(handle).to_struct())