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:])
 | |
| 
 |