def optimizeStartTag(self, collect, name, attrlist, end): # return true if the tag can be converted to plain text if not attrlist: collect.append("<%s%s" % (name, end)) return 1 opt = 1 new = ["<" + name] for i in range(len(attrlist)): item = attrlist[i] if len(item) > 2: opt = 0 name, value, action = item[:3] attrlist[i] = (name, value, action) + item[3:] else: if item[1] is None: s = item[0] else: s = '%s="%s"' % (item[0], taldefs.attrEscape(item[1])) attrlist[i] = item[0], s new.append(" " + s) # if no non-optimizable attributes were found, convert to plain text if opt: new.append(end) collect.extend(new) return opt
def getPathLinksForObject(obj, root_url=''): """Given an object, this function returns HTML code with links to documentation. The object must provide a string representation like 'foo.blah object at 0x9999999'. Returned is then a string, where 'foo' and 'blah' are embedded in HTML links to docgrok documentation for foo and foo.blah. The (optional) ``root_url`` is used to create the links to docgrok documentation. It is expected to be the URL, which can generate docgrok documentation by appending '/docgrok' to the URL. We can use ObjectInfo objects to check this: >>> from grok.admin.objectinfo import ObjectInfo >>> obj = ObjectInfo(None) >>> obj <grok.admin.objectinfo.ObjectInfo object at ...> Obviously we have a string representation of the required form here. So we can get HTML with links to the documentation for ``grok``, ``grok.admin`` and so on. >>> from grok.admin.utilities import getPathLinksForObject >>> link = getPathLinksForObject(obj) >>> link "<<a href='/docgrok/grok/'>grok</a>... object at ..." We got a link to the ``grok`` documentation. Also links to ``grok.admin``, ``grok.admin.objectinfo`` and ``grok.admin.objectinfo.ObjectInfo`` are provided: >>> link "<...<a href='/docgrok/grok/admin/'>admin</a>... object at ..." If we provide a root_url, we will find it in the links: >>> link = getPathLinksForObject(obj, 'http://localhost:8080') >>> link "<<a href='http://localhost:8080/docgrok/grok/'>grok</a>..." If no dotted path is included in objects strings representation, a simple string without links is returned: >>> getPathLinksForObject(None) "'None'" HTML entities should be encoded. We set up a site-manager to get an 'illegal' object representation including regular expression chars ('+') and no dotted path: >>> from zope.app.folder import rootFolder >>> root = rootFolder() >>> from zope.app.component import site >>> sm = site.LocalSiteManager(root) >>> root.setSiteManager(sm) >>> sm <LocalSiteManager ++etc++site> This is a strange object identifier. Anyway: >>> getPathLinksForObject(sm) "'<LocalSiteManager ++etc++site>'" """ r_exp = re.compile("'<(.+)( object at .*)>'") raw = ` str(obj) ` match = r_exp.match(raw) if match is None: return attrEscape(raw) result = "<" url = root_url + '/docgrok/' for part in match.group(1).split('.'): url = url + part + '/' result += "<a href='%s'>%s</a>." % (url, part) if len(result) and result[-1] == '.': result = "%s%s>" % (result[:-1], match.group(2)) return result return raw
def getPathLinksForClass(klass, root_url=''): """Given a class or classlike object, this function returns HTML code with links to documentation. The klass object must provide a string representation like '<class foo.Bar>'. Returned is then a string, where 'foo' and 'Bar' are embedded in HTML links to docgrok documentation for foo and foo.Bar. The (optional) ``root_url`` is used to create the links to docgrok documentation. It is expected to be the URL, which can generate docgrok documentation by appending '/docgrok' to the URL. We can use class ObjectInfo to check this: >>> from grok.admin.objectinfo import ObjectInfo >>> ObjectInfo <class 'grok.admin.objectinfo.ObjectInfo'> >>> from grok.admin.utilities import getPathLinksForClass >>> htmlcode = getPathLinksForClass(ObjectInfo) >>> htmlcode "<class '<a href='/docgrok/grok/'>grok</a>...'>" When we provide a root_url the link will include it in the href-attribute: >>> getPathLinksForClass(ObjectInfo, 'http://localhost') "<class '<a href='http://localhost/docgrok/grok/'>grok</a>...'>" If the class does not provide an appropriate string representation, we will get the representation without any links: >>> getPathLinksForClass(None, 'http://localhost') "'None'" This also works with 'class-like' objects, for instance interfaces and their interface-classes: >>> from zope.app.folder import rootFolder >>> from zope.interface import providedBy >>> root = rootFolder() >>> iface = list(providedBy(root))[0] >>> iface <InterfaceClass zope.app.folder.interfaces.IRootFolder> >>> getPathLinksForClass(iface) "<InterfaceClass '<a href='/docgrok/zope/'>zope</a>...'>" HTML entities should be encoded. We set up a site-manager to get an 'illegal' object representation including regular expression chars ('+') and no dotted path: >>> from zope.app.folder import rootFolder >>> root = rootFolder() >>> from zope.app.component import site >>> sm = site.LocalSiteManager(root) >>> root.setSiteManager(sm) >>> sm <LocalSiteManager ++etc++site> This is a strange object identifier. Anyway: >>> getPathLinksForClass(sm) "<LocalSiteManager '<a href='/docgrok/++etc++site/'>...</a>'>" """ r_exp = re.compile(".*<(.*) '?(.+)'?(.*)>.*") raw = ` str(klass) ` match = r_exp.match(raw) if match is None: return attrEscape(raw) result = "<%s '" % (match.group(1), ) url = root_url + '/docgrok/' for part in match.group(2).split('.'): url = "%s%s/" % (url, part) result += "<a href='%s'>%s</a>." % (url, part) if len(result) and result[-1] == '.': result = "%s'%s>" % (result[:-1], match.group(3)) return result return raw
def update(self, show_private=False, *args, **kw): obj = self.context if isinstance(self.context, ZopeObjectInfo): # When the docgrok-object traverser delivers content, then # we get a wrapped context: the meant object is wrapped # into a ZopeObjectInfo. obj = self.context.obj self.ob_info = ZopeObjectInfo(obj) ob_info = self.ob_info self.show_private = show_private root_url = self.root_url() parent = ob_info.getParent() parent = { 'class_link': parent and getPathLinksForObject(parent) or '', 'obj_link': getItemLink('', getParentURL(self.url(''))), 'obj': parent } bases = [getPathLinksForClass(x) for x in ob_info.getBases()] bases.sort() ifaces = [ getPathLinksForClass(x) for x in ob_info.getProvidedInterfaces() ] ifaces.sort() methods = [ x for x in list(ob_info.getMethods()) if self.show_private or not x['name'].startswith('_') ] for method in methods: if method['interface']: method['interface'] = getPathLinksForDottedName( method['interface'], root_url) if method['doc']: method['doc'] = renderText(method['doc'], getattr(obj, '__module__', None)) attrs = [ x for x in list(ob_info.getAttributes()) if self.show_private or not x['name'].startswith('_') ] for attr in attrs: if '.' in str(attr['type']): attr['type'] = getPathLinksForClass(attr['type'], root_url) else: attr['type'] = attrEscape(str(attr['type'])) if attr['interface']: attr['interface'] = getPathLinksForDottedName( attr['interface'], root_url) attr['obj'] = getattr(obj, attr['name'], None) attr['docgrok_link'] = getItemLink(attr['name'], self.url('')) attrs.sort(lambda x, y: x['name'] > y['name']) seqitems = ob_info.getSequenceItems() or [] for item in seqitems: if '.' in str(item['value_type']): item['value_type'] = getPathLinksForClass( item['value_type'], root_url) else: item['value_type'] = attrEscape(str(item['value_type'])) item['obj'] = obj[item['index']] item['docgrok_link'] = getItemLink(item['index'], self.url('')) seqitems.sort() mapitems = [ x for x in ob_info.getMappingItems() if self.show_private or not x['key'].startswith('_') ] for item in mapitems: if '.' in str(item['value_type']): item['value_type'] = getPathLinksForClass( item['value_type'], root_url) else: item['value_type'] = attrEscape(str(item['value_type'])) item['obj'] = obj[item['key']] item['docgrok_link'] = getItemLink(item['key'], self.url('')) mapitems.sort(lambda x, y: x['key'] > y['key']) annotations = [ x for x in ob_info.getAnnotationsInfo() if self.show_private or not x['key'].startswith('_') ] for item in annotations: if '.' in str(item['value_type']): item['value_type'] = getPathLinksForClass( item['value_type'], root_url) else: item['value_type'] = attrEscape(str(item['value_type'])) item['docgrok_link'] = getItemLink(item['key'], self.url('')) annotations.sort(lambda x, y: x['key'] > y['key']) self.info = { 'name': ob_info.getId() or u'<unnamed object>', 'type': getPathLinksForClass( (getattr(obj, '__class__', None) or type(obj)), root_url), 'obj_link': getPathLinksForObject(obj, root_url), 'moduleinfo': ob_info.getmoduleinfo(), 'modulename': ob_info.getmodulename(), 'ismodule': ob_info.ismodule(), 'isclass': ob_info.isclass(), 'ismethod': ob_info.ismethod(), 'isfunction': ob_info.isfunction(), 'iscode': ob_info.iscode(), 'isbuiltin': ob_info.isbuiltin(), 'isroutine': ob_info.isroutine(), 'issequence': ob_info.isSequence(), 'ismapping': ob_info.isMapping(), 'isannotatable': ob_info.isAnnotatable(), 'doc': renderText(ob_info.getdoc(), None), 'comments': ob_info.getcomments(), 'module': ob_info.getmodule(), 'sourcefile': ob_info.getsourcefile(), 'source': ob_info.getsource(), 'parent': parent, 'dotted_path': ob_info.getPythonPath(), 'provided_interfaces': ob_info.getDirectlyProvidedInterfaces(), 'interfaces': ifaces, 'bases': bases, 'attributes': attrs, 'methods': methods, 'sequenceitems': seqitems, 'mappingitems': mapitems, 'annotations': annotations }