Edgewall Software

MacroBazaar: Image.3.py

File Image.3.py, 4.7 KB (added by eblot, 7 years ago)

!Image macro updated for [1688]

Line 
1"""
2Display image in attachment or repository onto the wiki page.
3You can use this macro in wiki or ticket module.
4First argument is filename (file spec).
5Rest of optional arguments are attribute/style string of IMG element.
6If it is digits and unit, treat as size (ex. 120, 25%) of IMG.
7If it is 'right', 'left', 'top' or 'bottom', treat as align of IMG.
8if it is key=value style, treat as attribute of IMG.
9if it is key:value style, treat as style of IMG.
10
11Ex.
12  [[Image(photo.jpg)]]                          # simplest
13  [[Image(photo.jpg,120px)]]                    # with size
14  [[Image(photo.jpg,right)]]                    # aligned by keyword
15  [[Image(photo.jpg,align=right)]]              # aligned by attribute
16  [[Image(photo.jpg,float:right)]]              # aligned by style
17  [[Image(photo.jpg,border:solid 5px green)]]   # with any style
18
19You can use image from other page, other ticket or other module.
20  [[Image(OtherPage/foo.bmp)]]    # if current module is wiki
21  [[Image(base/sub/bar.bmp)]]     # from hierarchical wiki page
22  [[Image(3/baz.bmp)]]            # if in a ticket, point to #3
23  [[Image(ticket/36/boo.jpg)]]
24  [[Image(file/images/bee.jpg)]]
25 
26"""
27
28import os
29import re
30import string
31
32from  trac.util import escape
33
34def execute(hdf, txt, env):
35    # args will be null if the macro is called without parentesis.
36    if not txt:
37        return ''
38    # parse arguments
39    # we expect 1st arguemnt is filename (filespec)
40    args = txt.split(',')
41    if len(args) == 0:
42        raise Exception("No argument.")
43    file = args[0]
44    size_re = re.compile('^[0-9]+%?$')
45    align_re = re.compile('^(?:left|right|top|bottom)$')
46    keyval_re = re.compile('^([-a-z0-9]+)([=:])(.*)')
47    quoted_re = re.compile("^(?:"|')(.*)(?:"|')$")
48    attr = {}
49    style = {}
50    for arg in args[1:]:
51        arg = arg.strip()
52        if size_re.search(arg):
53            # 'width' keyword
54            attr['width'] = arg
55            continue
56        if align_re.search(arg):
57            # 'align' keyword
58            attr['align'] = arg
59            continue
60        match = keyval_re.search(arg)
61        if match:
62            key = match.group(1)
63            sep = match.group(2)
64            val = match.group(3)
65            m = quoted_re.search(val) # unquote " character "
66            if m:
67                val = m.group(1)
68            if sep == '=':
69                attr[key] = val;
70            elif sep == ':':
71                style[key] = val
72
73    # get current module and id from hdf
74    module = hdf.getValue('args.mode', 'wiki')
75    if module == 'wiki':
76        id = hdf.getValue('args.page', 'WikiStart')
77    elif module == 'ticket':
78        id = hdf['args.id'] # for ticket
79    else:
80        # limit of use
81        raise Exception('Cannot use this macro in %s module' % module)
82    # parse file argument to get module and id if contained.
83    # we allow 'file', 'id/file', 'module/id/file' format.
84    # id can be dir/dir/node.
85    # module can be 'wiki', 'ticket' or 'file'
86    # if for file module id (means path) can be omitted.
87    parts = file.split('/')
88    file = parts.pop() # anyway, last one is filename
89    if 0 < len(parts):
90        if parts[0] in ['wiki', 'ticket', 'file']:
91            # full spec
92            id = string.join(parts[1:], '/')
93            module = parts[0]
94        else:
95            # module name is not speciifed
96            id = string.join(parts, '/')
97    if module == 'file':
98        path = "%s/%s" % (id, file)
99        url = env.href.file(path)
100        raw_url = env.href.file(path, format='raw')
101        desc = file
102    else:
103        url = env.href.attachment(module, id, file)
104        raw_url = env.href.attachment(module, id, file, format='raw')
105        # get description for file from db.
106        cnx = env.get_db_cnx()
107        cursor = cnx.cursor()
108        cursor.execute("SELECT description from attachment where type='%s' and id='%s' and filename='%s'" % (module, id, file))
109        row = cursor.fetchone()
110        if row:
111            desc = row[0]
112        else:
113            raise Exception("Attachment is missed: module=%s, id=%s, file=%s" %(module, id, file))
114
115    for key in ['title', 'alt']:
116        if desc and not attr.has_key(key):
117            attr[key] = desc
118    a_style = 'padding:0; border:none' # style of anchor
119    img_attr = string.join(map(lambda x: '%s="%s"' % x, attr.iteritems()),
120                           ' ')
121    img_style = string.join(map(lambda x: "%s:%s" % x, style.iteritems()),
122                            ' ')
123    return "<a href='%s' style='%s'><img src='%s' %s style=\"%s\" /></a>" % (
124        url, a_style, raw_url, img_attr, img_style)