def _render_icon(self, formatter, name, size): if not name: return size = size.upper()[0] if size else 'S' name = name.lower() if any(x in name for x in ['*', '?']): #noinspection PyArgumentList return ShowIcons(self.env)._render(formatter, 2, name, size, True, self.icon_limit) else: loc = self.icon_location(size) return tag.img(src=formatter.href.chrome(loc[0], '%s.png' % name), alt=name, style="vertical-align: text-bottom")
def _format_smiley(self, formatter, match, fullmatch=None): #noinspection PyArgumentList loc = Icons(self.env).icon_location() return tag.img(src=formatter.href.chrome(loc[0], self.smileys[match]), alt=match, style="vertical-align: text-bottom")
def render(self, context, mimetype, content, filename=None, url=None): if url: return tag.div(tag.img(src=url, alt=filename), class_='image-file')
def expand_macro(self, formatter, name, content): args = None if content: content = stripws(content) # parse arguments # we expect the 1st argument to be a filename (filespec) args = [ stripws(arg) for arg in self._split_args_re.split(content)[1::2] ] if not args: return '' # strip unicode white-spaces and ZWSPs are copied from attachments # section (#10668) filespec = args.pop(0) # style information attr = {} style = {} link = '' # helper for the special case `source:` # from trac.versioncontrol.web_ui import BrowserModule # FIXME: somehow use ResourceSystem.get_known_realms() # ... or directly trac.wiki.extract_link try: browser_links = [ res[0] for res in BrowserModule(self.env).get_link_resolvers() ] except Exception: browser_links = [] while args: arg = args.pop(0) if self._size_re.match(arg): # 'width' keyword attr['width'] = arg elif arg == 'nolink': link = None elif arg.startswith('link='): val = arg.split('=', 1)[1] elt = extract_link(self.env, formatter.context, val.strip()) elt = find_element(elt, 'href') link = None if elt is not None: link = elt.attrib.get('href') elif arg in ('left', 'right'): style['float'] = arg elif arg == 'center': style['margin-left'] = style['margin-right'] = 'auto' style['display'] = 'block' style.pop('margin', '') elif arg in ('top', 'bottom', 'middle'): style['vertical-align'] = arg else: match = self._attr_re.match(arg) if match: key, val = match.groups() if (key == 'align' and val in ('left', 'right', 'center')) or \ (key == 'valign' and val in ('top', 'middle', 'bottom')): args.append(val) elif key in ('margin-top', 'margin-bottom'): style[key] = ' %dpx' % _arg_as_int(val, key, min=1) elif key in ('margin', 'margin-left', 'margin-right') \ and 'display' not in style: style[key] = ' %dpx' % _arg_as_int(val, key, min=1) elif key == 'border': style['border'] = ' %dpx solid' % _arg_as_int(val, key) else: m = self._quoted_re.search( val) # unquote "..." and '...' if m: val = m.group(1) attr[str(key)] = val # will be used as a __call__ kwd if self._quoted_re.match(filespec): filespec = filespec.strip('\'"') # parse filespec argument to get realm and id if contained. parts = [ i.strip('\'"') for i in self._split_filespec_re.split(filespec)[1::2] ] realm = parts[0] if parts else None url = raw_url = desc = None attachment = None interwikimap = InterWikiMap(self.env) if realm in ('http', 'https', 'ftp', 'data'): # absolute raw_url = url = filespec desc = url.rsplit('?')[0] elif realm in interwikimap: url, desc = interwikimap.url(realm, ':'.join(parts[1:])) raw_url = url elif filespec.startswith('//'): # server-relative raw_url = url = filespec[1:] desc = url.rsplit('?')[0] elif filespec.startswith('/'): # project-relative params = '' if '?' in filespec: filespec, params = filespec.rsplit('?', 1) url = formatter.href(filespec) if params: url += '?' + params raw_url, desc = url, filespec elif len(parts) == 3: # realm:id:attachment-filename # # or intertrac:realm:id realm, id, filename = parts intertrac_target = "%s:%s" % (id, filename) it = formatter.get_intertrac_url(realm, intertrac_target) if it: url, desc = it raw_url = url + unicode_quote('?format=raw') else: attachment = Resource(realm, id).child('attachment', filename) elif len(parts) == 2: realm, filename = parts if realm in browser_links: # source:path # TODO: use context here as well rev = None if '@' in filename: filename, rev = filename.rsplit('@', 1) url = formatter.href.browser(filename, rev=rev) raw_url = formatter.href.browser(filename, rev=rev, format='raw') desc = filespec else: # #ticket:attachment or WikiPage:attachment # FIXME: do something generic about shorthand forms... realm = None id, filename = parts if id and id[0] == '#': realm = 'ticket' id = id[1:] elif id == 'htdocs': raw_url = url = formatter.href.chrome('site', filename) desc = os.path.basename(filename) elif id == 'shared': raw_url = url = formatter.href.chrome('shared', filename) desc = os.path.basename(filename) else: realm = 'wiki' if realm: attachment = Resource(realm, id).child('attachment', filename) elif len(parts) == 1: # it's an attachment of the current resource attachment = formatter.resource.child('attachment', filespec) else: return system_message(_("No filespec given")) if attachment: try: desc = get_resource_summary(self.env, attachment) except ResourceNotFound: link = None raw_url = chrome_resource_path(formatter.context.req, 'common/attachment.png') desc = _('No image "%(id)s" attached to %(parent)s', id=attachment.id, parent=get_resource_name(self.env, attachment.parent)) else: if 'ATTACHMENT_VIEW' in formatter.perm(attachment): url = get_resource_url(self.env, attachment, formatter.href) raw_url = get_resource_url(self.env, attachment, formatter.href, format='raw') for key in ('title', 'alt'): if desc and key not in attr: attr[key] = desc if style: attr['style'] = '; '.join('%s:%s' % (k, escape(v)) for k, v in style.iteritems()) if not WikiSystem(self.env).is_safe_origin(raw_url, formatter.context.req): attr['crossorigin'] = 'anonymous' # avoid password prompt result = tag.img(src=raw_url, **attr) if link is not None: result = tag.a(result, href=link or url, style='padding:0; border:none') return result
def _render_needslock(self, context): url = chrome_resource_path(context.req, 'common/lock-locked.png') return tag.img(src=url, alt=_("needs lock"), title=_("needs lock"))
def expand_macro(self, formatter_or_context, name, content): """Return the HTML output of the macro. :param formatter_or_context: a Formatter when called as a macro, a RenderingContext when called by `GraphvizPlugin.render` :param name: Wiki macro command that resulted in this method being called. In this case, it should be 'graphviz', followed (or not) by the processor name, then by an output format, as following: graphviz.<processor>/<format> Valid processor names are: dot, neato, twopi, circo, and fdp. The default is dot. Valid output formats are: jpg, png, gif, svg and svgz. The default is the value specified in the out_format configuration parameter. If out_format is not specified in the configuration, then the default is png. examples: graphviz.dot/png -> dot png graphviz.neato/jpg -> neato jpg graphviz.circo -> circo png graphviz/svg -> dot svg :param content: The text the user entered for the macro to process. """ # check and load the configuration errmsg = self._load_config() if errmsg: return self._error_div(errmsg) ## Extract processor and format from name processor = out_format = None # first try with the RegExp engine try: m = re.match('graphviz\.?([a-z]*)\/?([a-z]*)', name) (processor, out_format) = m.group(1, 2) # or use the string.split method except: (d_sp, s_sp) = (name.split('.'), name.split('/')) if len(d_sp) > 1: s_sp = d_sp[1].split('/') if len(s_sp) > 1: out_format = s_sp[1] processor = s_sp[0] elif len(s_sp) > 1: out_format = s_sp[1] # assign default values, if instance ones are empty if not out_format: out_format = self.out_format if not processor: processor = self.processor if processor in Graphviz.Processors: proc_cmd = self.cmds[processor] else: self.log.error('render_macro: requested processor (%s) not found.', processor) return self._error_div('requested processor (%s) not found.' % processor) if out_format not in Graphviz.Formats: self.log.error('render_macro: requested format (%s) not found.', out_format) return self._error_div( tag.p( _( "Graphviz macro processor error: " "requested format (%(fmt)s) not valid.", fmt=out_format))) encoded_cmd = (processor + str(self.processor_options)) \ .encode(self.encoding) encoded_content = content.encode(self.encoding) sha_key = hashlib.sha256(encoded_cmd + encoded_content + ( b'S' if self.sanitizer else b'')).hexdigest() img_name = '%s.%s.%s' % (sha_key, processor, out_format) # cache: hash.<dot>.<png> img_path = os.path.join(self.cache_dir, img_name) map_name = '%s.%s.map' % (sha_key, processor) # cache: hash.<dot>.map map_path = os.path.join(self.cache_dir, map_name) # Check for URL="" presence in graph code URL_in_graph = 'URL=' in content or 'href=' in content # Create image if not in cache if not os.path.exists(img_path): self._clean_cache() if self.sanitizer: content = self._sanitize_html_labels(content) if URL_in_graph: # translate wiki TracLinks in URL if isinstance(formatter_or_context, RenderingContext): context = formatter_or_context else: context = formatter_or_context.context content = self._expand_wiki_links(context, out_format, content) encoded_content = content.encode(self.encoding) # Antialias PNGs with rsvg, if requested if out_format == 'png' and self.png_anti_alias == True: # 1. SVG output failure, errmsg = self._launch(encoded_content, proc_cmd, '-Tsvg', '-o%s.svg' % img_path, *self.processor_options) if failure: return self._error_div(errmsg) # 2. SVG to PNG rasterization failure, errmsg = self._launch(None, self.rsvg_path, '--dpi-x=%d' % self.dpi, '--dpi-y=%d' % self.dpi, '%s.svg' % img_path, img_path) if failure: return self._error_div(errmsg) else: # Render other image formats failure, errmsg = self._launch(encoded_content, proc_cmd, '-T%s' % out_format, '-o%s' % img_path, *self.processor_options) if failure: return self._error_div(errmsg) # Generate a map file for binary formats if URL_in_graph and out_format in Graphviz.Bitmap_Formats: # Create the map if not in cache if not os.path.exists(map_path): failure, errmsg = self._launch(encoded_content, proc_cmd, '-Tcmap', '-o%s' % map_path, *self.processor_options) if failure: return self._error_div(errmsg) if errmsg: # there was a warning. Ideally we should be able to use # `add_warning` here, but that's not possible as the warnings # are already emitted at this point in the template processing return self._error_div(errmsg) # Generate HTML output img_url = formatter_or_context.href.graphviz(img_name) # for SVG(z) if out_format in Graphviz.Vector_Formats: try: # try to get SVG dimensions f = open(img_path, 'r') svg = f.readlines(1024) # don't read all f.close() svg = "".join(svg).replace('\n', '') w = re.search('width="([0-9]+)(.*?)" ', svg) h = re.search('height="([0-9]+)(.*?)"', svg) (w_val, w_unit) = w.group(1, 2) (h_val, h_unit) = h.group(1, 2) # Graphviz seems to underestimate height/width for SVG images, # so we have to adjust them. # The correction factor seems to be constant. w_val, h_val = [1.35 * float(x) for x in (w_val, h_val)] width = str(w_val) + w_unit height = str(h_val) + h_unit except ValueError: width = height = '100%' # insert SVG, IE compatibility return tag.object(tag.embed(src=img_url, type="image/svg+xml", width=width, height=height), data=img_url, type="image/svg+xml", width=width, height=height) # for binary formats, add map elif URL_in_graph and os.path.exists(map_path): f = open(map_path, 'r') map = f.readlines() f.close() map = "".join(map).replace('\n', '') return tag( tag.map(Markup(to_unicode(map)), id='G' + sha_key, name='G' + sha_key), tag.img(src=img_url, usemap="#G" + sha_key, alt=_("GraphViz image"))) else: return tag.img(src=img_url, alt=_("GraphViz image"))