+# -*- 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))