GEP 18: 1. Source templates as new plugin type

2. EE templates in their own plugin, loading from csv in data


svn: r22611
This commit is contained in:
Benny Malengier 2013-06-25 22:26:56 +00:00
parent 5b6da40866
commit 0a2580e9c5
13 changed files with 1234 additions and 8694 deletions

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,98 @@
#
# Gramps - a GTK+/GNOME based genealogy program
#
# Copyright (C) 2013 Benny Malengier
#
# 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
#
# $Id$
"""
This module parses the evidence csv file and generates the code we need in
Gramps to use the evidence style.
"""
#-------------------------------------------------------------------------
#
# Standard Python modules
#
#-------------------------------------------------------------------------
import csv
#-------------------------------------------------------------------------
#
# Code
#
#-------------------------------------------------------------------------
csvfilename = "evidence_style.csv"
NRCOL = 0
CATCOL = 1
CATTYPECOL = 2
TYPECOL = 3
DESCRCOL= 4
CITETYPECOL = 5
IDENTCOL = 6
LDELCOL = 7 # left delimiter
FIELDCOL = 8
LABELCOL = 9
RDELCOL = 10 # right delimiter
GEDCOMCOL = 11
SHORTERCOL = 12
STYLECOL = 13
PRIVACYCOL = 14
OPTCOL = 15
HINTCOL = 16
TOOLTIPCOL = 17
first = True
trans = {}
with open(csvfilename, 'rb') as csvfile:
reader = csv.reader(csvfile, delimiter=';')
for row in reader:
if first:
first=False
continue
elif row[CATCOL]:
cat = row[CATCOL].strip()
cattype = row[CATTYPECOL].strip()
types = row[TYPECOL].strip()
descr = row[DESCRCOL].strip()
for val in [cat, cattype, types, descr]:
if val and val not in trans:
trans[val] = '_("' + val + '")'
val = row[HINTCOL]
if val and val not in trans:
trans[val] = '_("' + val + '")'
val = row[TOOLTIPCOL]
if val and val not in trans:
trans[val] = '_("' + val + '")'
#now generate the python code we need in source attr types
code = "#following translations are generated with extract_trans_csv.py\n"
code += "if False:\n"
code += " #these translations will only occur when needed first time!\n"
allkeys = sorted(trans.keys())
for field in allkeys:
code += " " + trans[field] + '\n'
with open('csv_trans.py', 'wb') as srcattrfile:
srcattrfile.write(code)

View File

@ -23,6 +23,10 @@
""" """
SrcAttributeBase class for GRAMPS. SrcAttributeBase class for GRAMPS.
""" """
from __future__ import print_function
from ..const import GRAMPS_LOCALE as glocale
_ = glocale.translation.gettext
#------------------------------------------------------------------------- #-------------------------------------------------------------------------
# #
@ -61,26 +65,23 @@ class SrcAttributeBase(AttributeRootBase):
for attr in self.attribute_list: for attr in self.attribute_list:
if int(attr.get_type()) == SrcAttributeType.SRCTEMPLATE: if int(attr.get_type()) == SrcAttributeType.SRCTEMPLATE:
val = attr.get_value() val = attr.get_value()
try: if SrcTemplate.template_defined(val):
templ = SrcTemplate.K2I_SRCTEMPLATEMAP[val] templ = val
except KeyError: else:
# a template not in the predefined list. convert to unknown # a template not in the predefined list. convert to unknown
print ('SrcAttributeBase: Keyerror "', val, print ('Unknown Template: Keyerror "', val,
'"for now UNKNOWN taken, later custom templates?') '"for now UNKNOWN taken.\nDownload required template style!')
break break
try: try:
retval = (templ, SrcTemplate.I2S_SRCTEMPLATEMAP[templ], retval = (templ, SrcTemplate.template_description(templ))
SrcTemplate.I2K_SRCTEMPLATEMAP[templ])
except KeyError: except KeyError:
#templ is not present, return the default GEDCOM value as actual #templ is not present, return the default GEDCOM value as actual
#template #template
templ = SrcTemplate.UNKNOWN templ = SrcTemplate.UNKNOWN
retval = (templ, retval = (templ, _('Unknown'))
SrcTemplate.I2S_SRCTEMPLATEMAP[SrcTemplate.UNKNOWN],
SrcTemplate.I2K_SRCTEMPLATEMAP[SrcTemplate.UNKNOWN])
return retval return retval
def set_source_template(self, tempindex, tempcustom_str): def set_source_template(self, template):
""" """
Set the source template of the source/citation Set the source template of the source/citation
This is the value of the first source template in the attribute list This is the value of the first source template in the attribute list
@ -101,11 +102,8 @@ class SrcAttributeBase(AttributeRootBase):
#we create a new attribute and add it #we create a new attribute and add it
attrtemp = SrcAttribute() attrtemp = SrcAttribute()
self.add_attribute(attrtemp) self.add_attribute(attrtemp)
if tempindex == SrcTemplate.UNKNOWN or \ if template == SrcTemplate.UNKNOWN:
(tempindex == SrcTemplate.CUSTOM and tempcustom_str.strip() == ''):
self.remove_attribute(attrtemp) self.remove_attribute(attrtemp)
elif not (tempindex == SrcTemplate.CUSTOM):
attrtemp.set_value(SrcTemplate.I2K_SRCTEMPLATEMAP[tempindex])
else: else:
#custom key, store string as is #custom key, store string as is
attrtemp.set_value(tempindex) attrtemp.set_value(template)

View File

@ -117,9 +117,9 @@ class SrcAttributeType(GrampsType):
(EVEN_ROLE , _("Role in Event Cited from"), "Role in Event Cited from"), # GEDCOM ROLE_IN_EVENT (EVEN_ROLE , _("Role in Event Cited from"), "Role in Event Cited from"), # GEDCOM ROLE_IN_EVENT
(GEN_BY , _("Generated by"), "Generated by"), # Generated sources on import (GEN_BY , _("Generated by"), "Generated by"), # Generated sources on import
(REPOSITORY, _("Repository"), "Repository"), (REPOSITORY, _("Repository"), "Repository"),
(REPOSITORY_ADDRESS, _("Repository Address"), "Repository Address"), (REPOSITORY_ADDRESS, _("Repository address"), "Repository address"),
(REPOSITORY_SHORT_VERSION, _("Repository (Short)"), "Repository (Short)"), (REPOSITORY_SHORT_VERSION, _("Repository (Short)"), "Repository (Short)"),
(REPOSITORY_CALL_NUMBER, _("Repository Call Number"), "Repository Call Number"), (REPOSITORY_CALL_NUMBER, _("Repository call number"), "Repository call number"),
(DATE, _("Date"), "Date"), (DATE, _("Date"), "Date"),
# possible fields for evidence styles need to be added next # possible fields for evidence styles need to be added next
] ]

File diff suppressed because it is too large Load Diff

View File

@ -386,6 +386,16 @@ class BasePluginManager(object):
""" """
return self.__pgr.sidebar_plugins() return self.__pgr.sidebar_plugins()
def get_reg_srctemplates(self):
""" Return list of registered sidebars. Only non-hidden templates
are returned, as srctemplate plugins can redifine templates of other
plugins. By setting hidden, user can select style he wants
"""
#sr
hidden_plugins = set(config.get('plugin.hiddenplugins'))
return [plg for plg in self.__pgr.srctemplate_plugins()
if plg.id not in hidden_plugins]
def get_external_opt_dict(self): def get_external_opt_dict(self):
""" Return the dictionary of external options. """ """ Return the dictionary of external options. """
return self.__external_opt_dict return self.__external_opt_dict

View File

@ -74,8 +74,9 @@ VIEW = 8
RELCALC = 9 RELCALC = 9
GRAMPLET = 10 GRAMPLET = 10
SIDEBAR = 11 SIDEBAR = 11
SRCTEMPLATE = 12
PTYPE = [REPORT , QUICKREPORT, TOOL, IMPORT, EXPORT, DOCGEN, GENERAL, PTYPE = [REPORT , QUICKREPORT, TOOL, IMPORT, EXPORT, DOCGEN, GENERAL,
MAPSERVICE, VIEW, RELCALC, GRAMPLET, SIDEBAR] MAPSERVICE, VIEW, RELCALC, GRAMPLET, SIDEBAR, SRCTEMPLATE]
PTYPE_STR = { PTYPE_STR = {
REPORT: _('Report') , REPORT: _('Report') ,
QUICKREPORT: _('Quickreport'), QUICKREPORT: _('Quickreport'),
@ -89,6 +90,7 @@ PTYPE_STR = {
RELCALC: _('Relationships'), RELCALC: _('Relationships'),
GRAMPLET: _('Gramplet'), GRAMPLET: _('Gramplet'),
SIDEBAR: _('Sidebar'), SIDEBAR: _('Sidebar'),
SRCTEMPLATE: _('Source Templates'),
} }
#possible report categories #possible report categories
@ -990,6 +992,7 @@ def make_environment(**kwargs):
'RELCALC': RELCALC, 'RELCALC': RELCALC,
'GRAMPLET': GRAMPLET, 'GRAMPLET': GRAMPLET,
'SIDEBAR': SIDEBAR, 'SIDEBAR': SIDEBAR,
'SRCTEMPLATE': SRCTEMPLATE,
'CATEGORY_TEXT': CATEGORY_TEXT, 'CATEGORY_TEXT': CATEGORY_TEXT,
'CATEGORY_DRAW': CATEGORY_DRAW, 'CATEGORY_DRAW': CATEGORY_DRAW,
'CATEGORY_CODE': CATEGORY_CODE, 'CATEGORY_CODE': CATEGORY_CODE,
@ -1262,6 +1265,11 @@ class PluginRegister(object):
""" """
return self.type_plugins(SIDEBAR) return self.type_plugins(SIDEBAR)
def srctemplate_plugins(self):
"""Return a list of PluginData that are of type SRCTEMPLATE
"""
return self.type_plugins(SRCTEMPLATE)
def filter_load_on_reg(self): def filter_load_on_reg(self):
"""Return a list of PluginData that have load_on_reg == True """Return a list of PluginData that have load_on_reg == True
""" """

View File

@ -123,7 +123,7 @@ class SrcTemplateTab(GrampsTab):
:param scrolled: GtkScrolledWindow to which to add treeview with templates :param scrolled: GtkScrolledWindow to which to add treeview with templates
""" """
templ = self.src.get_source_template() templ = self.src.get_source_template()
self.temp_tv = SrcTemplateTreeView(templ[2], self.temp_tv = SrcTemplateTreeView(templ[0],
sel_callback=self.on_template_selected) sel_callback=self.on_template_selected)
scrolled.add(self.temp_tv) scrolled.add(self.temp_tv)
@ -155,15 +155,15 @@ class SrcTemplateTab(GrampsTab):
# which will update the title in the source object # which will update the title in the source object
self.callback_src_changed() self.callback_src_changed()
def on_template_selected(self, index, key): def on_template_selected(self, key):
""" """
Selected template changed, we save this and update interface Selected template changed, we save this and update interface
""" """
self.src.set_source_template(index, key) self.src.set_source_template(key)
self.callback_src_changed(templatechanged=True) self.callback_src_changed(templatechanged=True)
#a predefined template, #a predefined template,
self.tmplfields.reset_template_fields(index) self.tmplfields.reset_template_fields(key)
#------------------------------------------------------------------------- #-------------------------------------------------------------------------
# #
@ -197,15 +197,15 @@ class TemplateFields(object):
self.btns = [] self.btns = []
self.monentry = [] self.monentry = []
def reset_template_fields(self, index): def reset_template_fields(self, key):
""" """
Method that constructs the actual fields where user can enter data. Method that constructs the actual fields where user can enter data.
Template must be the index of the template. Template must be the index of the template.
""" """
#obtain the template of the index #obtain the template of the key
if index in SrcTemplate.EVIDENCETEMPLATES: if SrcTemplate.template_defined(key):
#a predefined template, #a predefined template,
template = SrcTemplate.EVIDENCETEMPLATES[index] template = SrcTemplate.get_template(key)
else: else:
return return
@ -467,45 +467,3 @@ class TemplateFields(object):
foundattr.set_type(srcattrtype) foundattr.set_type(srcattrtype)
foundattr.set_value(value) foundattr.set_value(value)
obj.add_attribute(foundattr) obj.add_attribute(foundattr)
## def setup_autocomp_combobox(self):
## """
## Experimental code to set up a combobox with all templates.
## This is too slow, we use treeview in second attempt
## """
## self.srctempcmb = Gtk.ComboBox(has_entry=True)
## ignore_values = []
## custom_values = []
## srcattr = SrcAttributeType()
## default = srcattr.get_templatevalue_default()
## maptempval = srcattr.get_templatevalue_map().copy()
## if ignore_values :
## for key in list(maptempval.keys()):
## if key in ignore_values and key not in (None, default):
## del map[key]
##
## self.sel = StandardCustomSelector(
## maptempval,
## self.srctempcmb,
## srcattr.get_custom(),
## default,
## additional=custom_values)
##
## templ = self.src.get_source_template()
## self.sel.set_values((templ[0], templ[1]))
## self.srctempcmb.set_sensitive(not self.readonly)
## self.srctempcmb.connect('changed', self.on_change_template)
## srctemphbox.pack_start(self.srctempcmb, False, True, 0)
##
## return topvbox
## def fix_value(self, value):
## if value[0] == SrcAttributeType.CUSTOM:
## return value
## else:
## return (value[0], '')
##
## def on_change_template(self, obj):
## #value = self.fix_value(self.srctempcmb.get_values())
## value = self.sel.get_values()
## self.src.set_source_template(value[0], value[1])

View File

@ -317,4 +317,10 @@ class GuiPluginManager(Callback):
def get_reg_general(self, category=None): def get_reg_general(self, category=None):
return [plg for plg in self.basemgr.get_reg_general(category) return [plg for plg in self.basemgr.get_reg_general(category)
if plg.id not in self.__hidden_plugins] if plg.id not in self.__hidden_plugins]
def get_reg_srctemplates(self):
"""
Obtain registered SrcTemplates
Srctemplates are already filtered on hidden in the base manager
"""
return self.basemgr.get_reg_srctemplates()

View File

@ -78,19 +78,14 @@ class SrcTemplateTreeView(Gtk.TreeView):
""" """
Obtains all templates and stores them in a TreeStore Obtains all templates and stores them in a TreeStore
""" """
srctemp = SrcTemplate()
self.I2Str = srctemp.I2S_SRCTEMPLATEMAP
self.I2Key = srctemp.I2K_SRCTEMPLATEMAP
self.Str2I = srctemp.S2I_SRCTEMPLATEMAP
self.Key2I = srctemp.K2I_SRCTEMPLATEMAP
self.Key2Path = {} self.Key2Path = {}
# store (index, key, src_type) # store (key, src_type)
self.model = Gtk.TreeStore(int, str, str) self.model = Gtk.TreeStore(str, str)
alltexts = sorted(self.Str2I.keys()) alltexts = sorted((SrcTemplate.template_description(x), x) for x in SrcTemplate.all_templates())
parentiter = None parentiter = None
parentiterlev1 = None parentiterlev1 = None
prevstrval = ['', ''] prevstrval = ['', '']
for alltext in alltexts: for alltext, key in alltexts:
vals = alltext.split('-') vals = alltext.split('-')
if len(vals) > 3: if len(vals) > 3:
vals = [vals[0], vals[1], ' - '.join(vals[2:])] vals = [vals[0], vals[1], ' - '.join(vals[2:])]
@ -105,8 +100,7 @@ class SrcTemplateTreeView(Gtk.TreeView):
if len(vals) < 3 : if len(vals) < 3 :
truevals[:len(vals)] = vals[:] truevals[:len(vals)] = vals[:]
vals = truevals vals = truevals
index = self.Str2I[alltext] row = [key, lastval]
row = [index, self.I2Key[index], lastval]
iter = None iter = None
if prevstrval[0] == vals[0] and prevstrval[1] == vals[1]: if prevstrval[0] == vals[0] and prevstrval[1] == vals[1]:
#same parentiter #same parentiter
@ -115,33 +109,33 @@ class SrcTemplateTreeView(Gtk.TreeView):
#up one parentiter, make new sublevel2 if needed #up one parentiter, make new sublevel2 if needed
parentiter = parentiterlev1 parentiter = parentiterlev1
if vals[2]: if vals[2]:
parentiter = self.model.append(parentiter, [-10, '', vals[1]]) parentiter = self.model.append(parentiter, ['', vals[1]])
iter = self.model.append(parentiter, row) iter = self.model.append(parentiter, row)
else: else:
#new value #new value
parentiterlev1 = None parentiterlev1 = None
if vals[2] and vals[1]: if vals[2] and vals[1]:
#new sublevel1 and 2 needed #new sublevel1 and 2 needed
parentiterlev1 = self.model.append(None, [-10, '', vals[0]]) parentiterlev1 = self.model.append(None, ['', vals[0]])
#make sublevel2 #make sublevel2
parentiter= self.model.append(parentiterlev1, [-10, '', vals[1]]) parentiter= self.model.append(parentiterlev1, ['', vals[1]])
iter = self.model.append(parentiter, row) iter = self.model.append(parentiter, row)
elif vals[1]: elif vals[1]:
#only new sublevel1 needed #only new sublevel1 needed
parentiterlev1 = self.model.append(None, [-10, '', vals[0]]) parentiterlev1 = self.model.append(None, ['', vals[0]])
parentiter = parentiterlev1 parentiter = parentiterlev1
iter = self.model.append(parentiter, row) iter = self.model.append(parentiter, row)
else: else:
#only a top level #only a top level
iter = self.model.append(None, row) iter = self.model.append(None, row)
#store key to path #store key to path
self.Key2Path[row[1]] = self.model.get_path(iter) self.Key2Path[row[0]] = self.model.get_path(iter)
prevstrval = [vals[0], vals[1]] prevstrval = [vals[0], vals[1]]
def make_columns(self): def make_columns(self):
#make the column in the treeview #make the column in the treeview
renderer = Gtk.CellRendererText() renderer = Gtk.CellRendererText()
column = Gtk.TreeViewColumn(_("Template"), renderer, text=2) column = Gtk.TreeViewColumn(_("Template"), renderer, text=1)
self.append_column(column) self.append_column(column)
#no headers needed: #no headers needed:
self.set_headers_visible (False) self.set_headers_visible (False)
@ -151,7 +145,6 @@ class SrcTemplateTreeView(Gtk.TreeView):
highlight key in the view highlight key in the view
""" """
#we determine the path of key #we determine the path of key
path = self.Key2Path[key] path = self.Key2Path[key]
iter_ = self.model.get_iter(path) iter_ = self.model.get_iter(path)
if iter_: if iter_:
@ -169,7 +162,7 @@ class SrcTemplateTreeView(Gtk.TreeView):
self.selection.unselect_all() self.selection.unselect_all()
self.selection.select_path(path) self.selection.select_path(path)
self.scroll_to_cell(path, None, 1, 0.5, 0) self.scroll_to_cell(path, None, 1, 0.5, 0)
self.sel_callback(self.Key2I[key], key) self.sel_callback(key)
def get_selected(self): def get_selected(self):
""" """
@ -177,7 +170,7 @@ class SrcTemplateTreeView(Gtk.TreeView):
""" """
(model, node) = self.selection.get_selected() (model, node) = self.selection.get_selected()
if node: if node:
return (model.get_value(node, 0), model.get_value(node,1), node) return (model.get_value(node, 0), node)
return None return None
def _on_button_release(self, obj, event): def _on_button_release(self, obj, event):
@ -186,8 +179,8 @@ class SrcTemplateTreeView(Gtk.TreeView):
""" """
if event.type == Gdk.EventType.BUTTON_RELEASE and event.button == 1: if event.type == Gdk.EventType.BUTTON_RELEASE and event.button == 1:
ref = self.get_selected() ref = self.get_selected()
if ref and ref[0] != -10: if ref and ref[0] != '':
self.sel_callback(ref[0], ref[1]) self.sel_callback(ref[0])
return False return False
def _on_key_press_event(self, widget, event): def _on_key_press_event(self, widget, event):
@ -195,10 +188,10 @@ class SrcTemplateTreeView(Gtk.TreeView):
if event.keyval in (Gdk.KEY_Return, Gdk.KEY_KP_Enter): if event.keyval in (Gdk.KEY_Return, Gdk.KEY_KP_Enter):
ref = self.get_selected() ref = self.get_selected()
if ref: if ref:
if ref[0] != -10: if ref[0] != '':
self.sel_callback(ref[0], ref[1]) self.sel_callback(ref[0])
else: else:
path = self.model.get_path(ref[2]) path = self.model.get_path(ref[0])
if self.row_expanded(path): if self.row_expanded(path):
self.collapse_row(path) self.collapse_row(path)
else: else:

View File

View File

@ -0,0 +1,44 @@
# -*- coding: utf-8 -*-
#
# Gramps - a GTK+/GNOME based genealogy program
#
# Copyright (C) 2013 Benny Malengier
#
# 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
#
# $Id$
"""
Registering srctemplates for GRAMPS.
"""
#
# SrcTemplates distributed with Gramps
#
# EE
plg = newplugin()
plg.id = 'evidence explained styles'
plg.name = _("Evidence Explained Source Templates")
plg.description = _("Defines source templates corresponding with those from the"
" book Evidence Explained.")
plg.version = '1.0'
plg.gramps_target_version = '4.1'
plg.status = STABLE
plg.fname = 'evidenceexplained.py'
plg.ptype = SRCTEMPLATE

View File

@ -0,0 +1,262 @@
# -*- coding: utf-8 -*-
#
# Gramps - a GTK+/GNOME based genealogy program
#
# Copyright (C) 2013 Benny Malengier
#
# 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
#
# $Id$
"""
Registering srctemplates for GRAMPS.
"""
from gramps.gen.const import GRAMPS_LOCALE as glocale
_ = glocale.translation.gettext
import os
from functools import partial
from gramps.gen.const import DATA_DIR
#
# SrcTemplates distributed with Gramps
#
# Add EE styles to the src templates defined
#the csv file with the template definitions
path_csv = partial(os.path.join, DATA_DIR, "evidencestyle")
csvfile = path_csv('evidence_style.csv')
#name of this style
style = 'EE'
#strings to translate
#following translations are generated with extract_trans_csv.py
if False:
#these translations will only occur when needed first time!
_("1790-1840")
_("1850-1860: slaves")
_("1850-1870")
_("1880-1930")
_("Abstracts")
_("Administrative material")
_("Appeals court record books")
_("Application file")
_("Archival preservation copy")
_("Archived Material")
_("Archived in-house")
_("Archived off-site")
_("Archives & Artifacts")
_("Artifact")
_("Audio book")
_("Audio recordings")
_("Basic Format")
_("Blogs")
_("Book")
_("Book:")
_("Bound volume")
_("Broadcasts & Web Miscellanea")
_("Business & institutional Records")
_("CD-ROM publication")
_("CD/DVD")
_("CD/DVD book (text)")
_("CD/DVD publication")
_("Case Reporters")
_("Case files")
_("Cemetery Office Records")
_("Cemetery Records")
_("Cemetery abstracts")
_("Census Records")
_("Church Books")
_("Church Records")
_("Church record book, recopied")
_("Church-issued certificate")
_("Church-records database")
_("Citing volume from title page")
_("Codes & statutes, online")
_("Collection, emphasis on")
_("Congressional Records")
_("Corporate Records")
_("Database")
_("Database online")
_("Databases")
_("Derivatives")
_("Descriptive pamphlet, online")
_("Diary or journal, etc.")
_("Digital Archives")
_("Digital Images")
_("Digitized online")
_("Discussion forums & lists")
_("Document (loose record)")
_("Document, emphasis on")
_("Electronic Publications")
_("Extract supplied by staff")
_("FHL-GSU film")
_("FHL-GSU preservation")
_("FHL-GSU preservation copy")
_("FHL-GSU preservation film")
_("Family Bible Records")
_("Family Chart or Group Sheet")
_("File items")
_("Files moved to state archives")
_("France")
_("Genetic testing")
_("Grave markers")
_("Historic letter")
_("Historical research: corporate")
_("Historical research: online")
_("Image Copies")
_("Images online")
_("In-house film")
_("Interview tape & transcript")
_("Journal articles")
_("LDS records at FHL")
_("Land warrants: loose")
_("Land-grant register")
_("Leaflet")
_("Legal Reference Works")
_("Legal document, unrecorded")
_("Legislative petitions & files")
_("Library of Congress")
_("Lineage-society Records")
_("Local")
_("Local & State Records: Courts & Governance")
_("Local & State Records: Licenses, Registrations, Rolls & Vital Records")
_("Local & State Records: Property & Probates")
_("Local Records")
_("Local copy")
_("Magazine articles")
_("Manuscript Records")
_("Manuscripts")
_("Map")
_("Maps")
_("Markers & Memorials (Originals)")
_("Memorial plaques")
_("Microfilm")
_("Microfilm (U.S.)")
_("Microfilm publication")
_("Miscellaneous file")
_("NARA Style citation")
_("NARA film")
_("Named volume")
_("National Archives")
_("National Archives (Australia)")
_("National Archives (Canada)")
_("National Archives (U.K.)")
_("National Archives (U.S.)")
_("National Archives (U.S.) guides")
_("National Archives copy")
_("National Archives microfilm")
_("National Archives-Regional")
_("National Government Records")
_("Native-American tribal census")
_("Newsletter articles")
_("Newspaper articles")
_("Nonpopulation schedules")
_("Numbered volume")
_("Office records")
_("Online")
_("Online archives")
_("Online archives of print journals")
_("Online commercial site")
_("Online database")
_("Online image")
_("Online images")
_("Online journals")
_("Online publication")
_("Online reprints, random items")
_("Online:")
_("Organizational Records")
_("Original Materials (U.S.)")
_("Original Records")
_("Original manuscripts (U.S.)")
_("Patent & Trademark Office (U.S.)")
_("Periodicals")
_("Personal Bible")
_("Personal correspondence")
_("Personal e-mail")
_("Photographs")
_("Podcasts")
_("Population schedules")
_("Portrait")
_("Preliminary inventory, microfilmed")
_("Preservation Film")
_("Preservation film, FHL-GSU")
_("Print Publications")
_("Print editions")
_("Printed Government Documents")
_("Private Holdings")
_("Professional Reports")
_("Publications Style citation")
_("Publications: Books, CDs, Maps, Leaflets & Videos")
_("Publications: Legal Works & Government Documents")
_("Publications: Periodicals, Broadcasts & Web Miscellanea")
_("Radio & television clips")
_("Railroad Retirement Board")
_("Record Books")
_("Record Books, archived off-site")
_("Registers")
_("Research Report")
_("School Records")
_("Series named for editor")
_("Series, emphasis on")
_("Slip laws:")
_("Social Security Administration")
_("Soundex & Miracode, microfilm")
_("Standardized series")
_("State database")
_("State level")
_("State-level")
_("State-level Records")
_("State-level copies")
_("State-sponsored censuses")
_("Statistical database")
_("Statutes:")
_("Student transcript")
_("Tract book")
_("Tradition, recorded")
_("Traditional academic style")
_("U.K. Wales")
_("U.S. Code")
_("UNC microfilm publication")
_("Unpublished narrative")
_("Vertical file")
_("Video")
_("Vital records, amended")
_("Vital records, delayed")
_("Vital-records certificate")
_("Vital-records register")
_("Website as book")
_("archived off-site")
_("basic format")
_("card file")
_("chapter")
_("edited")
_("federal")
_("federal census")
_("held by church")
_("multivolume set")
_("online")
_("personally used")
_("reprint")
_("revised edition")
_("rural")
_("state")
_("supplied by staff")
_("urban")
_("vertical file")