########################################################################
#
# 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 string, re
from Ft.XPointer import XPtrContext, XPtrException
try:
    import XPtrExprParserc
    _exprParser = XPtrExprParserc
except:
    import XPtrExprParser
    _exprParser = XPtrExprParser

_replacer = re.compile("\^(.)")
def Scheme(name, expr):
    scheme = Schemes.get(name, UnknownScheme)
    expr = string.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 = string.index(decl, '=')
        if equals == -1:
            raise SyntaxError('parse error, expected =')
        self.prefix = string.strip(decl[:equals])
        if not self.prefix:
            raise SyntaxError('parse error, expected NCName')
        self.uri = string.strip(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,
    }
