########################################################################
#
# File Name:   XPtrPart.py
#
# Docs:        http://docs.4suite.org/XPointer/XPtrPart.py.html
#
"""
A Parsed Token that represents a list of XPointers
WWW: http://4suite.org/XPointer        e-mail: support@4suite.org

Copyright (c) 2000-2001 Fourthought Inc, USA.   All Rights Reserved.
See  http://4suite.org/COPYRIGHT  for license and copyright information
"""

import re
from Ft.Xml.XPointer import XPtrContext, XPtrException
from Ft.Xml.Lib.XmlString import XmlStrStrip

import XPtrExprParserc as _exprParser

_replacer = re.compile("\^(.)")
def Scheme(name, expr):
    scheme = Schemes.get(name, UnknownScheme)
    expr = u''.join(expr)
    expr = _replacer.sub(lambda match: match.group(1), expr)
    return scheme(name, expr)

class XPtrExpr:
    def __init__(self, name, expr):
        self.expr = _exprParser.new().parse(expr)

    def evaluate(self, context):
        return self.expr.evaluate(context)

    def pprint(self, indent=''):
        print indent + str(self)
        self.expr.pprint(indent+'  ')

    def __str__(self):
        return '<XPtrExpr at %x: %s>' % (id(self), repr(self))

    def __repr__(self):
        return 'xpointer(%s)' % repr(self.expr)


class XPtrNsDecl:
    def __init__(self, name, decl):
        equals = decl.index('=')
        if equals == -1:
            raise SyntaxError('parse error, expected =')
        self.prefix = XmlStrStrip(decl[:equals])
        if not self.prefix:
            raise SyntaxError('parse error, expected NCName')
        self.uri = XmlStrStrip(decl[equals+1:])
        if not self.uri:
            raise SyntaxError('parse error, expected XPtrNsUri')

    def evaluate(self, context):
        if self.prefix != 'xml':
            context.processorNss[self.prefix] = self.uri
        return []

    def pprint(self, indent=''):
        print indent + str(self)

    def __str__(self):
        return '<XPtrNsDecl at %x: %s>' % (id(self), repr(self))

    def __repr__(self):
        return 'xmlns(%s=%s)' % (self.prefix, self.uri)


class UnknownScheme:
    def __init__(self, name, expr):
        self.name = name
        self.expr = expr

    def evaluate(self, context):
        return []

    def pprint(self, indent=''):
        print indent + str(self)

    def __str__(self):
        return '<UnknownScheme at %x: %s>' % (id(self), repr(self))

    def __repr__(self):
        return '%s(%s)' % (self.name, self.expr)
    

Schemes = {
    'xpointer' : XPtrExpr,
    'xmlns' : XPtrNsDecl,
    }
