Page MenuHomec4science

reference.py
No OneTemporary

File Metadata

Created
Fri, May 3, 23:37

reference.py

#!/usr/bin/env python3
# -*- coding: utf-8 -*-
""" This class can be used to represent a text reference.
"""
# Copyright (C) University of Basel 2019 {{{1
#
# 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 3 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, see <https://www.gnu.org/licenses/> 1}}}
__author__ = "Christian Steiner"
__maintainer__ = __author__
__copyright__ = 'University of Basel'
__email__ = "christian.steiner@unibas.ch"
__status__ = "Development"
__license__ = "GPL v3"
__version__ = "0.0.1"
from lxml import etree as ET
import re
import sys
from .attachable_object import AttachableObject
sys.path.append('py2ttl')
from class_spec import SemanticClass
class Reference(AttachableObject,SemanticClass):
"""
This class represents a text reference.
Args:
id (int): object id
first_line (int) first line of reference
last_line (int) last line of reference
is_uncertain (bool) whether reference is uncertain
title (str) title of reference
page_number (str) page_number of reference
tag (str) xml tag
"""
XML_TAG = 'reference'
intKeys = [ 'first_line', 'last_line']
boolKeys = [ 'is_uncertain' ]
stringKeys = [ 'title', 'page_number' ]
def __init__(self, node=None, id=0, first_line=-1, last_line=-1, is_uncertain=False, title='', page_number='', tag=XML_TAG):
self.intKeys = []
self.intKeys += Reference.intKeys
self.intKeys.append('id')
self.stringKeys = []
self.stringKeys += Reference.stringKeys
self.boolKeys = []
self.boolKeys += Reference.boolKeys
self.id = id
self.first_line = first_line
self.last_line = last_line
self.is_uncertain = is_uncertain
self.title = title
self.page_number = page_number
self.tag = tag
def attach_object_to_tree(self, target_tree):
"""Attach object to tree.
"""
if target_tree.__class__.__name__ == '_ElementTree':
target_tree = target_tree.getroot()
obj_node = target_tree.xpath('.//' + self.tag + '[@id="%s"]' % self.id)[0] \
if(len(target_tree.xpath('.//' + self.tag + '[@id="%s"]' % self.id)) > 0) \
else ET.SubElement(target_tree, self.tag)
for key in self.boolKeys:
if self.__dict__[key] is not None:
obj_node.set(key.replace('_','-'), str(self.__dict__[key]).lower())
for key in self.intKeys:
if self.__dict__[key] is not None and self.__dict__[key] > -1:
obj_node.set(key.replace('_','-'), str(self.__dict__[key]))
for key in self.stringKeys:
if self.__dict__[key] is not None and self.__dict__[key] != '':
obj_node.set(key.replace('_','-'), str(self.__dict__[key]))
@classmethod
def create_cls(cls, node=None, id=0, is_uncertain=False, reference_string='', title='', page_number=''):
"""Creates a Reference from a (lxml.etree.Element) node or a reference_string.
:return: (datatypes.reference) Reference
"""
if node is not None:
instance = cls()
for key in instance.boolKeys:
xml_key = key.replace('_', '-')
if bool(node.get(xml_key)):
instance.__dict__[key] = node.get(xml_key) == 'true'
for key in instance.intKeys:
xml_key = key.replace('_', '-')
if bool(node.get(xml_key)):
instance.__dict__[key] = int(node.get(xml_key))
for key in instance.stringKeys:
xml_key = key.replace('_', '-')
if bool(node.get(xml_key)):
instance.__dict__[key] = node.get(xml_key)
return instance
else:
first_line = -1
last_line = -1
if re.match(r'[0-9]+([a-z]+)*,[0-9]+(-[0-9]+)*', reference_string):
page_number = reference_string.split(',')[0]
line_numbers = reference_string.split(',')[1].split('-')
first_line = int(line_numbers[0])
last_line = int(line_numbers[1]) if len(line_numbers) > 1 else -1
else:
if ',' not in reference_string:
line_numbers = reference_string.split('-')
first_line = int(line_numbers[0])
last_line = int(line_numbers[1]) if len(line_numbers) > 1 else -1
else:
if ' ' not in reference_string:
raise Exception('String "{}" is not a valid reference_string'.format(reference_string))
title = reference_string.split(' ')[0]
return cls.create_cls(id=id, is_uncertain=is_uncertain, reference_string=reference_string[len(title)+1:],\
title=title, page_number=page_number)
return cls(id=id, is_uncertain=is_uncertain, first_line=first_line, last_line=last_line,\
title=title, page_number=page_number)
@classmethod
def get_semantic_dictionary(cls):
""" Creates a semantic dictionary as specified by SemanticClass.
"""
dictionary = {}
class_dict = cls.get_class_dictionary()
properties = {}
properties.update(dict(zip(cls.intKeys, [ (int, 0, '{}/@{}'.format(cls.XML_TAG, i.replace('_','-'))) for i in cls.intKeys])))
properties.update(dict(zip(cls.boolKeys, [ (bool, 1, '{}/@{}'.format(cls.XML_TAG, i.replace('_','-'))) for i in cls.boolKeys])))
properties.update(dict(zip(cls.stringKeys, [ (str, 1, '{}/@{}'.format(cls.XML_TAG, i.replace('_','-'))) for i in cls.stringKeys])))
dictionary.update({'class': class_dict})
dictionary.update({'properties': properties})
return dictionary

Event Timeline