76 lines
2.0 KiB
Python
76 lines
2.0 KiB
Python
|
import py
|
||
|
html = py.xml.html
|
||
|
|
||
|
def getrelfspath(dotted_name):
|
||
|
# XXX need to make sure its imported on non-py lib
|
||
|
return eval(dotted_name, {"py": py})
|
||
|
|
||
|
class LazyHref(object):
|
||
|
def __init__(self, linker, linkid):
|
||
|
self._linker = linker
|
||
|
self._linkid = linkid
|
||
|
|
||
|
def __unicode__(self):
|
||
|
return unicode(self._linker.get_target(self._linkid))
|
||
|
|
||
|
class Linker(object):
|
||
|
fromlocation = None
|
||
|
|
||
|
def __init__(self):
|
||
|
self._linkid2target = {}
|
||
|
|
||
|
def get_lazyhref(self, linkid):
|
||
|
return LazyHref(self, linkid)
|
||
|
|
||
|
def set_link(self, linkid, target):
|
||
|
assert (linkid not in self._linkid2target,
|
||
|
'linkid %r already used' % (linkid,))
|
||
|
self._linkid2target[linkid] = target
|
||
|
|
||
|
def get_target(self, linkid):
|
||
|
linktarget = self._linkid2target[linkid]
|
||
|
if self.fromlocation is not None:
|
||
|
linktarget = relpath(self.fromlocation, linktarget)
|
||
|
return linktarget
|
||
|
|
||
|
def call_withbase(self, base, func, *args, **kwargs):
|
||
|
assert self.fromlocation is None
|
||
|
self.fromlocation = base
|
||
|
try:
|
||
|
return func(*args, **kwargs)
|
||
|
finally:
|
||
|
del self.fromlocation
|
||
|
|
||
|
def relpath(p1, p2, sep='/', back='..'):
|
||
|
if (p1.startswith(sep) ^ p2.startswith(sep)):
|
||
|
raise ValueError("mixed absolute relative path: %r -> %r" %(p1, p2))
|
||
|
fromlist = p1.split(sep)
|
||
|
tolist = p2.split(sep)
|
||
|
|
||
|
# AA
|
||
|
# AA BB -> AA/BB
|
||
|
#
|
||
|
# AA BB
|
||
|
# AA CC -> CC
|
||
|
#
|
||
|
# AA BB
|
||
|
# AA -> ../AA
|
||
|
|
||
|
diffindex = 0
|
||
|
for x1, x2 in zip(fromlist, tolist):
|
||
|
if x1 != x2:
|
||
|
break
|
||
|
diffindex += 1
|
||
|
commonindex = diffindex - 1
|
||
|
|
||
|
fromlist_diff = fromlist[diffindex:]
|
||
|
tolist_diff = tolist[diffindex:]
|
||
|
|
||
|
if not fromlist_diff:
|
||
|
return sep.join(tolist[commonindex:])
|
||
|
backcount = len(fromlist_diff)
|
||
|
if tolist_diff:
|
||
|
return sep.join([back,]*(backcount-1) + tolist_diff)
|
||
|
return sep.join([back,]*(backcount) + tolist[commonindex:])
|
||
|
|