Edgewall Software

MacroBazaar: Image.py

File Image.py, 4.7 KB (added by Shun-ichi Goto <gotoh@…>, 7 years ago)

Macro to display image in attachment/repository onto wiki/ticket

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("^(?:&#34;|')(.*)(?:&#34;|')$")
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 &#34; 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 len(parts) == 0:
90        raise Exception("1st argument is invalid")
91    if parts[0] in ['wiki', 'ticket', 'file']:
92        # full spec
93        id = string.join(parts[1:], '/')
94        module = parts[0]
95    else:
96        # module name is not speciifed
97        id = string.join(parts, '/')
98    if module == 'file':
99        path = "%s/%s" % (id, file)
100        url = env.href.file(path)
101        raw_url = env.href.file(path, format='raw')
102        desc = file
103    else:
104        url = env.href.attachment(module, id, file)
105        raw_url = env.href.attachment(module, id, file, 'raw')
106        # get description for file from db.
107        cnx = env.get_db_cnx()
108        cursor = cnx.cursor()
109        cursor.execute("SELECT description from attachment where type='%s' and id='%s' and filename='%s'" % (module, id, file))
110        row = cursor.fetchone()
111        if row:
112            desc = row[0]
113        else:
114            raise Exception("Attachment is missed: module=%s, id=%s, file=%s" %(module, id, file))
115
116    for key in ['title', 'alt']:
117        if desc and not attr.has_key(key):
118            attr[key] = desc
119    a_style = 'padding:0; border:none' # style of anchor
120    img_attr = string.join(map(lambda x: '%s="%s"' % x, attr.iteritems()),
121                           ' ')
122    img_style = string.join(map(lambda x: "%s:%s" % x, style.iteritems()),
123                            ' ')
124    return "<a href='%s' style='%s'><img src='%s' %s style=\"%s\" /></a>" % (
125        url, a_style, raw_url, img_attr, img_style)