# Path: neleval/annotation.py
# class Annotation(object):
#     """A name mention and its predicted candidates
# 
#     Parameters
#     ----------
# 
#     Attributes
#     ----------
#     TODO
#     is_first : bool or unset
#         Indicates if this annotation is the first in the document for this
#         eid.
# 
#     * :
#         Other attributes are automatically adopted from the top candidate
#     """
# 
#     __slots__ = ['docid', 'start', 'end', 'candidates', 'is_first']
# 
#     def __init__(self, docid, start, end, candidates=[]):
#         self.docid = docid
#         self.start = start
#         self.end = end
#         self.candidates = candidates
# 
#     def __unicode__(self):
#         return u'{}\t{}\t{}\t{}'.format(
#             self.docid,
#             self.start,
#             self.end,
#             u'\t'.join([unicode(c) for c in self.candidates])
#             )
# 
#     __str__ = __unicode__
# 
#     def __repr__(self):
#         return 'Annotation({!r}, {!r}, {!r}, {!r})'.format(self.docid, self.start, self.end, self.candidates)
# 
#     def __lt__(self, other):
#         assert isinstance(other, Annotation)
#         return (self.start, -self.end) < (other.start, -other.end)
# 
#     def compare_spans(self, other):
#         assert self.start <= self.end, 'End is before start: {!r}'.format(self)
#         assert other.start <= other.end, 'End is before start: {!r}'.format(self)
#         if self.docid != other.docid:
#             return 'different documents'
#         if self.start > other.end or self.end < other.start:
#             return 'non-overlapping'
#         elif self.start == other.start and self.end == other.end:
#             return 'duplicate'
#         elif self.start < other.start and self.end >= other.end:
#             return 'nested'
#         elif self.start >= other.start and self.end < other.end:
#             return 'nested'
#         else:
#             return 'crossing'
# 
#     # Getters
#     @property
#     def span(self):
#         return (self.docid, self.start, self.end)
# 
#     @property
#     def link(self):
#         "Return top candidate"
#         if self.candidates:
#             return self.candidates[0]
# 
#     def __getattr__(self, name):
#         # Generally, return attributes from top candidate
#         # or None if there are no candidates
#         if name.startswith('_'):
#             # AttributeError
#             super(Annotation, self).__getattr__(name)
#         link = self.link
#         if link is not None:
#             return getattr(link, name)
# 
#     # Parsing methods
#     @classmethod
#     def from_string(cls, s):
#         docid, start, end, candidates = None, None, None, []
#         cols = s.rstrip('\n\t').split('\t', 3)
#         if len(cols) < 3:
#             raise SyntaxError('Annotation must have at least 3 columns. Got {!r}'.format(s))
#         if len(cols) >= 3:
#             docid = cols[0]
#             start = int(cols[1])
#             end = int(cols[2])
#         if len(cols) == 4:
#             candidates = sorted(Candidate.from_string(cols[3]), reverse=True)
#         return Annotation(docid, start, end, candidates)
# 
#     @classmethod
#     def list_fields(cls):
#         ann = cls.from_string('a\t0\t1\tabc')
#         return [f for f in dir(ann) + dir(ann.link)
#                 if not f.startswith('_')
#                 and not callable(getattr(ann, f, None))]
# 
# Path: neleval/document.py
# ENC = 'utf8'
# 
# Path: neleval/utils.py
# WIKI_PREFIX = re.compile('^http://[^.]+.wikipedia.org/wiki/')
# def normalise_link(l):
# def utf8_open(path, mode='r'):
# def json_dumps(obj, sort_keys=True, indent=4):
#     def default(o):


from .annotation import Annotation
from .document import ENC
from .utils import unicode
#!/usr/bin/env python

class ToWeak(object):
    """Convert annotations to char-level for weak evaluation

    A better approach is to use measures with partial overlap support.
    """
    def __init__(self, fname):
        self.fname = fname

    def __call__(self):
        return u'\n'.join(unicode(a) for a in self.annotations()).encode(ENC)

    def annotations(self):
        for line in open(self.fname):

# Path: neleval/annotation.py
# class Annotation(object):
#     """A name mention and its predicted candidates
# 
#     Parameters
#     ----------
# 
#     Attributes
#     ----------
#     TODO
#     is_first : bool or unset
#         Indicates if this annotation is the first in the document for this
#         eid.
# 
#     * :
#         Other attributes are automatically adopted from the top candidate
#     """
# 
#     __slots__ = ['docid', 'start', 'end', 'candidates', 'is_first']
# 
#     def __init__(self, docid, start, end, candidates=[]):
#         self.docid = docid
#         self.start = start
#         self.end = end
#         self.candidates = candidates
# 
#     def __unicode__(self):
#         return u'{}\t{}\t{}\t{}'.format(
#             self.docid,
#             self.start,
#             self.end,
#             u'\t'.join([unicode(c) for c in self.candidates])
#             )
# 
#     __str__ = __unicode__
# 
#     def __repr__(self):
#         return 'Annotation({!r}, {!r}, {!r}, {!r})'.format(self.docid, self.start, self.end, self.candidates)
# 
#     def __lt__(self, other):
#         assert isinstance(other, Annotation)
#         return (self.start, -self.end) < (other.start, -other.end)
# 
#     def compare_spans(self, other):
#         assert self.start <= self.end, 'End is before start: {!r}'.format(self)
#         assert other.start <= other.end, 'End is before start: {!r}'.format(self)
#         if self.docid != other.docid:
#             return 'different documents'
#         if self.start > other.end or self.end < other.start:
#             return 'non-overlapping'
#         elif self.start == other.start and self.end == other.end:
#             return 'duplicate'
#         elif self.start < other.start and self.end >= other.end:
#             return 'nested'
#         elif self.start >= other.start and self.end < other.end:
#             return 'nested'
#         else:
#             return 'crossing'
# 
#     # Getters
#     @property
#     def span(self):
#         return (self.docid, self.start, self.end)
# 
#     @property
#     def link(self):
#         "Return top candidate"
#         if self.candidates:
#             return self.candidates[0]
# 
#     def __getattr__(self, name):
#         # Generally, return attributes from top candidate
#         # or None if there are no candidates
#         if name.startswith('_'):
#             # AttributeError
#             super(Annotation, self).__getattr__(name)
#         link = self.link
#         if link is not None:
#             return getattr(link, name)
# 
#     # Parsing methods
#     @classmethod
#     def from_string(cls, s):
#         docid, start, end, candidates = None, None, None, []
#         cols = s.rstrip('\n\t').split('\t', 3)
#         if len(cols) < 3:
#             raise SyntaxError('Annotation must have at least 3 columns. Got {!r}'.format(s))
#         if len(cols) >= 3:
#             docid = cols[0]
#             start = int(cols[1])
#             end = int(cols[2])
#         if len(cols) == 4:
#             candidates = sorted(Candidate.from_string(cols[3]), reverse=True)
#         return Annotation(docid, start, end, candidates)
# 
#     @classmethod
#     def list_fields(cls):
#         ann = cls.from_string('a\t0\t1\tabc')
#         return [f for f in dir(ann) + dir(ann.link)
#                 if not f.startswith('_')
#                 and not callable(getattr(ann, f, None))]
# 
# Path: neleval/document.py
# ENC = 'utf8'
# 
# Path: neleval/utils.py
# WIKI_PREFIX = re.compile('^http://[^.]+.wikipedia.org/wiki/')
# def normalise_link(l):
# def utf8_open(path, mode='r'):
# def json_dumps(obj, sort_keys=True, indent=4):
#     def default(o):


# Path: neleval/weak.py
from .annotation import Annotation
from .document import ENC
from .utils import unicode

#!/usr/bin/env python

class ToWeak(object):
    """Convert annotations to char-level for weak evaluation

    A better approach is to use measures with partial overlap support.
    """
    def __init__(self, fname):
        self.fname = fname

    def __call__(self):
        return u'\n'.join(unicode(a) for a in self.annotations()).encode(ENC)

    def annotations(self):
        for line in open(self.fname):

            a = Annotation.from_string(line.rstrip('\n').decode(ENC))