Add support for CITE plugins

Provide a single default plugin that replicates the existing
functionality.
This commit is contained in:
Nick Hall 2022-10-24 22:56:55 +01:00
parent f72e2e44b6
commit 65a79c7dd8
11 changed files with 264 additions and 63 deletions

View File

@ -289,6 +289,7 @@ register('preferences.last-views', [])
register('preferences.family-relation-type', 3) # UNKNOWN
register('preferences.age-display-precision', 1)
register('preferences.age-after-death', True)
register('preferences.cite-plugin', 'cite-default')
register('colors.scheme', 0)
register('colors.male-alive', ['#b8cee6', '#1f344a'])

View File

@ -458,6 +458,11 @@ class BasePluginManager:
"""
return self.__pgr.thumbnailer_plugins()
def get_reg_cite(self):
""" Return list of registered cite plugins.
"""
return self.__pgr.cite_plugins()
def get_external_opt_dict(self):
""" Return the dictionary of external options. """
return self.__external_opt_dict

View File

@ -90,9 +90,10 @@ SIDEBAR = 11
DATABASE = 12
RULE = 13
THUMBNAILER = 14
CITE = 15
PTYPE = [REPORT, QUICKREPORT, TOOL, IMPORT, EXPORT, DOCGEN, GENERAL,
MAPSERVICE, VIEW, RELCALC, GRAMPLET, SIDEBAR, DATABASE, RULE,
THUMBNAILER]
THUMBNAILER, CITE]
PTYPE_STR = {
REPORT: _('Report') ,
QUICKREPORT: _('Quickreport'),
@ -109,6 +110,7 @@ PTYPE_STR = {
DATABASE: _('Database'),
RULE: _('Rule'),
THUMBNAILER: _('Thumbnailer'),
CITE: _('Citation formatter'),
}
#possible report categories
@ -1201,6 +1203,7 @@ def make_environment(**kwargs):
'GRAMPLET': GRAMPLET,
'SIDEBAR': SIDEBAR,
'THUMBNAILER': THUMBNAILER,
'CITE': CITE,
'CATEGORY_TEXT': CATEGORY_TEXT,
'CATEGORY_DRAW': CATEGORY_DRAW,
'CATEGORY_CODE': CATEGORY_CODE,
@ -1529,6 +1532,12 @@ class PluginRegister:
"""
return self.type_plugins(THUMBNAILER)
def cite_plugins(self):
"""
Return a list of :class:`PluginData` that are of type CITE
"""
return self.type_plugins(CITE)
def filter_load_on_reg(self):
"""
Return a list of :class:`PluginData` that have load_on_reg == True

View File

@ -43,6 +43,8 @@ _ = glocale.translation.gettext
from ..docgen import FontStyle, ParagraphStyle, FONT_SANS_SERIF
from ...lib import NoteType, Citation
from ...utils.string import conf_strings
from ...config import config
from ..utils import get_cite
def add_endnote_styles(style_sheet):
"""
@ -157,85 +159,28 @@ def write_endnotes(bibliography, database, doc, printnotes=False, links=False,
doc.end_paragraph()
cindex = 0
for citation in bibliography.get_citation_list():
cite = get_cite()
for citation in cite.format(bibliography, database, elocale):
cindex += 1
source = database.get_source_from_handle(citation.get_source_handle())
first = True
doc.start_paragraph('Endnotes-Source', "%d." % cindex)
doc.write_text(_format_source_text(source, elocale), links=links)
doc.write_text(citation[0], links=links)
doc.end_paragraph()
if printnotes:
_print_notes(source, database, doc,
'Endnotes-Source-Notes', links)
for key, ref in citation.get_ref_list():
for key, ref in citation[1]:
# Translators: needed for French, ignore otherwise
doc.start_paragraph('Endnotes-Ref', trans_text('%s:') % key)
doc.write_text(_format_ref_text(ref, key, elocale), links=links)
doc.write_text(ref, links=links)
doc.end_paragraph()
if printnotes:
_print_notes(ref, database, doc,
'Endnotes-Ref-Notes', links)
def _format_source_text(source, elocale):
if not source: return ""
trans_text = elocale.translation.gettext
# trans_text is a defined keyword (see po/update_po.py, po/genpot.sh)
src_txt = ""
if source.get_author():
src_txt += source.get_author()
if source.get_title():
if src_txt:
# Translators: needed for Arabic, ignore otherwise
src_txt += trans_text(', ')
# Translators: used in French+Russian, ignore otherwise
src_txt += trans_text('"%s"') % source.get_title()
if source.get_publication_info():
if src_txt:
# Translators: needed for Arabic, ignore otherwise
src_txt += trans_text(', ')
src_txt += source.get_publication_info()
if source.get_abbreviation():
if src_txt:
# Translators: needed for Arabic, ignore otherwise
src_txt += trans_text(', ')
src_txt += "(%s)" % source.get_abbreviation()
return src_txt
def _format_ref_text(ref, key, elocale):
if not ref: return ""
ref_txt = ""
datepresent = False
date = ref.get_date_object()
if date is not None and not date.is_empty():
datepresent = True
if datepresent:
if ref.get_page():
ref_txt = "%s - %s" % (ref.get_page(), elocale.get_date(date))
else:
ref_txt = elocale.get_date(date)
else:
ref_txt = ref.get_page()
# Print only confidence level if it is not Normal
if ref.get_confidence_level() != Citation.CONF_NORMAL:
ref_txt += " [" + elocale.translation.gettext(
conf_strings[ref.get_confidence_level()]) + "]"
return ref_txt
def _print_notes(obj, db, doc, style, links):
note_list = obj.get_note_list()
ind = 1

View File

@ -454,3 +454,24 @@ class OpenFileOrStdin:
if self.filename != '-':
self.filehandle.close()
return False
#-------------------------------------------------------------------------
#
# get_cite function
#
#-------------------------------------------------------------------------
def get_cite():
"""
Function that returns the active cite plugin.
"""
plugman = BasePluginManager.get_instance()
for pdata in plugman.get_reg_cite():
if pdata.id != config.get('preferences.cite-plugin'):
continue
module = plugman.load_plugin(pdata)
if not module:
print("Error loading formatter '%s': skipping content"
% pdata.name)
continue
cite = getattr(module, 'Formatter')()
return cite

View File

@ -1420,6 +1420,12 @@ class GrampsPreferences(ConfigureDialog):
grid.attach(lwidget, 1, row, 1, 1)
grid.attach(obox, 2, row, 2, 1)
row += 1
lwidget = BasicLabel(_("%s: ") % _('Citation formatter'))
grid.attach(lwidget, 1, row, 1, 1)
obox = self.__create_cite_combo()
grid.attach(obox, 2, row, 2, 1)
row += 1
label = self.add_text(
grid, _("\nInput Options"), row,
@ -1796,6 +1802,15 @@ class GrampsPreferences(ConfigureDialog):
else:
widget.set_sensitive(True)
def cite_changed(self, obj):
"""
Update Database Backend.
"""
the_list = obj.get_model()
the_iter = obj.get_active_iter()
cite_choice = the_list.get_value(the_iter, 2)
config.set('preferences.cite-plugin', cite_choice)
def add_famtree_panel(self, configdialog):
"""
Config tab for family tree, backup and Media path settings.
@ -1967,6 +1982,33 @@ class GrampsPreferences(ConfigureDialog):
obox.connect('changed', self.database_backend_changed)
return obox
def __create_cite_combo(self):
"""
Create cite selection widget.
"""
backend_plugins = self.uistate.viewmanager._pmgr.get_reg_cite()
obox = Gtk.ComboBox()
cell = Gtk.CellRendererText()
obox.pack_start(cell, True)
obox.add_attribute(cell, 'text', 1)
# Build model:
model = Gtk.ListStore(GObject.TYPE_INT,
GObject.TYPE_STRING,
GObject.TYPE_STRING)
count = 0
active = 0
default = config.get('preferences.cite-plugin')
for plugin in sorted(backend_plugins, key=lambda plugin: plugin.name):
if plugin.id == default:
active = count
model.append(row=[count, plugin.name, plugin.id])
count += 1
obox.set_model(model)
# set the default value as active in the combo
obox.set_active(active)
obox.connect('changed', self.cite_changed)
return obox
def set_mediapath(self, *obj):
if self.path_entry.get_text().strip():
self.dbstate.db.set_mediapath(self.path_entry.get_text())

View File

View File

@ -0,0 +1,43 @@
#
# Gramps - a GTK+/GNOME based genealogy program
#
# Copyright (C) 2022 Nick Hall
#
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation; either version 2 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program; if not, write to the Free Software
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
#
from gramps.gen.const import GRAMPS_LOCALE as glocale
_ = glocale.translation.gettext
MODULE_VERSION = "5.2"
#------------------------------------------------------------------------
#
# Default citation formatters for Gramps
#
#------------------------------------------------------------------------
register(
CITE,
id="cite-default",
name=_("Default"),
description=_("Default citation formatter"),
version="1.0",
gramps_target_version=MODULE_VERSION,
status=STABLE,
fname="default.py",
authors=["The Gramps project"],
authors_email=["http://gramps-project.org"],
)

View File

@ -0,0 +1,129 @@
#
# Gramps - a GTK+/GNOME based genealogy program
#
# Copyright (C) 2022 Nick Hall
#
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation; either version 2 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program; if not, write to the Free Software
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
#
"""
A ciation formatter that implements the current functionality.
"""
#-------------------------------------------------------------------------
#
# Standard python modules
#
#-------------------------------------------------------------------------
import logging
#-------------------------------------------------------------------------
#
# GTK/Gnome modules
#
#-------------------------------------------------------------------------
#-------------------------------------------------------------------------
#
# Gramps modules
#
#-------------------------------------------------------------------------
from gramps.gen.lib import Citation
from gramps.gen.utils.string import conf_strings
#-------------------------------------------------------------------------
#
# Constants
#
#-------------------------------------------------------------------------
LOG = logging.getLogger(".cite")
class Formatter():
def __init__(self):
pass
def format(self, bibliography, db, elocale):
result = []
for citation in bibliography.get_citation_list():
source = db.get_source_from_handle(citation.get_source_handle())
src = _format_source_text(source, elocale)
refs = []
for key, ref in citation.get_ref_list():
ref = _format_ref_text(ref, key, elocale)
refs.append([key, ref])
result.append([src, refs])
return result
def _format_source_text(source, elocale):
if not source: return ""
trans_text = elocale.translation.gettext
# trans_text is a defined keyword (see po/update_po.py, po/genpot.sh)
src_txt = ""
if source.get_author():
src_txt += source.get_author()
if source.get_title():
if src_txt:
# Translators: needed for Arabic, ignore otherwise
src_txt += trans_text(', ')
# Translators: used in French+Russian, ignore otherwise
src_txt += trans_text('"%s"') % source.get_title()
if source.get_publication_info():
if src_txt:
# Translators: needed for Arabic, ignore otherwise
src_txt += trans_text(', ')
src_txt += source.get_publication_info()
if source.get_abbreviation():
if src_txt:
# Translators: needed for Arabic, ignore otherwise
src_txt += trans_text(', ')
src_txt += "(%s)" % source.get_abbreviation()
return src_txt
def _format_ref_text(ref, key, elocale):
if not ref: return ""
ref_txt = ""
datepresent = False
date = ref.get_date_object()
if date is not None and not date.is_empty():
datepresent = True
if datepresent:
if ref.get_page():
ref_txt = "%s - %s" % (ref.get_page(), elocale.get_date(date))
else:
ref_txt = elocale.get_date(date)
else:
ref_txt = ref.get_page()
# Print only confidence level if it is not Normal
if ref.get_confidence_level() != Citation.CONF_NORMAL:
ref_txt += " [" + elocale.translation.gettext(
conf_strings[ref.get_confidence_level()]) + "]"
return ref_txt

View File

@ -578,6 +578,8 @@ gramps/gui/widgets/reorderfam.py
gramps/gui/widgets/styledtextbuffer.py
gramps/gui/widgets/styledtexteditor.py
gramps/gui/widgets/validatedmaskedentry.py
gramps/plugins/cite/cite.gpr.py
gramps/plugins/cite/default.py
gramps/plugins/db/bsddb/bsddb.gpr.py
gramps/plugins/db/dbapi/sqlite.gpr.py
gramps/plugins/db/dbapi/sqlite.py

View File

@ -457,6 +457,10 @@ gramps/gui/widgets/validatedcomboentry.py
#
gramps/plugins/__init__.py
#
# plugins/cite directory
#
gramps/plugins/cite/__init__.py
#
# plugins/db/bsddb directory
#
gramps/plugins/db/bsddb/__init__.py