From: Matthijs Kooijman <matthijs@stdio.flexvps.nl> Date: Sat, 25 Apr 2009 11:42:12 +0000 (+0200) Subject: Add the ImageMap parser, version 1.2. X-Git-Url: https://git.stderr.nl/gitweb?a=commitdiff_plain;h=309404bf02020d23837e8a0bcc17c3215327305f;p=matthijs%2Fprojects%2Fwipi.git Add the ImageMap parser, version 1.2. --- diff --git a/plugin/parser/ImageMap.py b/plugin/parser/ImageMap.py new file mode 100644 index 0000000..c4c33a8 --- /dev/null +++ b/plugin/parser/ImageMap.py @@ -0,0 +1,198 @@ +# -*- coding: iso-8859-1 -*- +""" + MoinMoin - ImageMap Parser + + This parser is used to create clickable image maps. + + Syntax: + + {{{#!ImageMap + picsrc[;width=".."][;height=".."][;alt=".."][;title=".."] + link_area1;shape="rect|circle|poly";coords="..";alt=".."[;title=".."] + link_area2;shape="rect|circle|poly";coords="..";alt=".."[;title=".."] + }}} + + For a detailed explanation of the syntax see: + http://moinmoin.wikiwikiweb.de/ParserMarket/ImageMap + + Please note: Image maps are not accessible by blind people. Do also have a + look at the best-practise-examples for using image maps + on http://moinmoin.wikiwikiweb.de/ParserMarket/ImageMap. + + Example: + + {{{#!ImageMap + picture.jpg;width="345";height="312";alt="Clickable Organizational Chart" + FrontPage;shape="rect";coords="11,10,59,29";alt="Area1" + http://www.xyz.com/;shape="circle";coords="42,36,96";alt="Area2" + FrontPage/SubPage;shape="poly";coords="48,311,105,248,96,210";alt="Area3" + Another Site in This Wiki;shape="rect";coords="88,10,59,29";alt="Area4" + InterWiki:RemotePage;shape="rect";coords="181,120,59,29";alt="Area5" + }}} + + ImageMap Parser is partly based on ImageLink Macro + ImageLink Macro + @copyright: 2001 by Jeff Kunce, + 2004 by Marcin Zalewski, + 2004-2006 by Reimar Bauer, + 2006 by Thomas Waldmann + @license: GNU GPL, see COPYING for details. + + ImageMap Parser + @copyright: 2006,2007 by Oliver Siemoneit + @license: GNU GPL, see COPYING for details. + + Changes: + + Version 1.1 + * Made code PEP8 compatible. + * Parameter checking and stripping added to prevent inserting of malicious + code in html page via parser call. + + Version 1.2 + * Fixed ouput abstraction violations: on other formatters than html-formatter + just the specified image is output via formatter.image and map information + dropped. + * In case of missing alt texts: "alt" ist set to alt="" (for the whole map) + and to alt="area_url" (for the different clickable areas). + * Now also "title" supported to generate tooltips for the map areas. + * Interwiki links can also be specified in "wiki:MoinMoin/Page" syntax now. + +""" + +import os, random +from MoinMoin import wikiutil, config +from MoinMoin.action import AttachFile + + +def _is_URL(text): + return '://' in text + +def _is_InterWiki(text): + return ':' in text + +def _is_allowed_Para(para, allowed_paras): + found = False + for p in allowed_paras: + if para.startswith(p): + found = True + return found + +def _strip_Para(para): + _para = wikiutil.escape(para) + if para.count('"') < 2: + return _para + shortend_para = _para[0:_para.find('"')+1] + cut_para = _para[_para.find('"')+1:len(_para)] + shortend_para += cut_para[0:cut_para.find('"')+1] + return shortend_para + + +class Parser: + + def __init__(self, raw, request, **kw): + self.raw = raw + self.request = request + + def format(self, formatter): + request = self.request + _ = request.getText + row = self.raw.split('\n') + + # Produce <img ...> html-code stuff + paras = row[0].split(';') + image = wikiutil.escape(paras[0]) + mapname = '%s_%s' % ([image, image[:15]][(len(image) > 14)], str(random.randint(1, 999999))) + + if _is_URL(image): + imgurl = image + elif _is_InterWiki(image): + if image.startswith('wiki:'): + image = image[5:] + wikitag, wikiurl, wikitail, err = wikiutil.resolve_wiki(request, image) + imgurl = wikiutil.join_wiki(wikiurl, wikitail) + else: + pagename, attname = AttachFile.absoluteName(image, formatter.page.page_name) + imgurl = AttachFile.getAttachUrl(pagename, attname, request) + attachment_fname = AttachFile.getFilename(request, pagename, attname) + + if not os.path.exists(attachment_fname): + linktext = _('Upload new attachment "%(filename)s"') + output = wikiutil.link_tag(request, + ('%s?action=AttachFile&rename=%s' % ( + wikiutil.quoteWikinameURL(pagename), + wikiutil.url_quote_plus(attname))), + text=linktext % {'filename': attname}, + formatter=formatter) + request.write(output) + return + + html = ''' +<img src="%s"''' % imgurl + paras.pop(0) + + kw = {} + kw['src'] = imgurl + for p in paras: + # Prevent attacks like: pic.png;height="10" onmouseover="ExecuteBadCode()";alt=".."; + # and: pic.png;height="10" onmouseover="ExecuteBadCode()";alt=".."; + # and: pic.png;height="10" onmouseover="ExecuteBadCode()";alt=".."; + p = _strip_Para(p) + if _is_allowed_Para(p, ['width="', 'height="', 'alt="', 'title="']): + html += ' %s' % p + # Prepare dict for formatter.image if formatter.rawHTML call fails + key, value = p.split('=', 1) + kw[str(key.lower())] = value.strip('"') + + # If there is no alt provided, create one + if not 'alt' in kw: + kw['alt'] = image + html += ' alt=""' + + html += ' usemap="#%s"> ' % mapname + row.pop(0) + + # Produce <map ..> html-code stuff + html += ''' +<map name="%s">''' % mapname + + for p in row: + paras = p.split(';') + paras[0] = wikiutil.escape(paras[0]) + + if _is_URL(paras[0]): + area_url = paras[0] + elif _is_InterWiki(paras[0]): + if paras[0].startswith('wiki:'): + paras[0] = paras[0][5:] + wikitag, wikiurl, wikitail, err = wikiutil.resolve_wiki(request, paras[0]) + area_url = wikiutil.join_wiki(wikiurl, wikitail) + else: + area_url = wikiutil.quoteWikinameURL(paras[0]) + paras.pop(0) + + html += ''' + <area href="%s"''' % area_url + + for i in paras: + # Prevent attacks like: FrontPage;shape="rect" onmouseover="ExecuteBadCode()";coords=".."; + # and: FrontPage;shape="rect" onmouseover="ExecuteBadCode()";coords=".."; + # and: FrontPage;shape="rect" onmouseover="ExecuteBadCode()";coords=".."; + i = _strip_Para(i) + if _is_allowed_Para(i, ['shape="', 'coords="', 'alt="', 'title="']): + html += ' %s' % i + # If there is no alt provided at all, set alt to area_url + if p.lower().find('alt="') == -1: + html += ' alt="%s"' % area_url + + html += '>' + + html += ''' +</map> +''' + # If current formatter is a HTML formatter, output image map with formatter.rawHTML(). + # Otherwise just output image with formatter.image() + try: + request.write(formatter.rawHTML(html)) + except: + request.write(formatter.image(**kw))