Attachment 'gallery-1.0.py'

Download

   1 #-*- coding: utf-8 -*-
   2 '''
   3 MoinMoin - gallery parser, Version 1.0, 11.10.2018
   4 
   5 A simple parser that reads key:value pairs from a listing of images (attachments) and captions then formats these for display in a gallery (table), with links to view the attachment in a separate window/tab. Defaults to eight column table with captions below centred images. If more than seven key:value pairs are provided, additional rows are added. The user can set options to (1) set the number of columns, (2) change the image height (other than the default of 100px), (3) remove frames and background, and (4) show only the markup for re-use with modifications, if desired, or for debugging purposes.
   6 
   7 The key:value list must be in the form " gallery_file:: caption" with a leading space (as moin dictionary entries). All non-conforming lines are ignored without warning.
   8 
   9 The parser is intended for page section use only. The parser name is followed by a list of keywords separated by spaces to specify any options required.
  10 
  11 Keywords
  12 
  13 c-[1-8] : sets the number of columns between 1 and 8. 
  14 
  15 nnn[px] : requested width of image, where n is digits from 50 to 250; 'px' is optional. If outside this range, the lower or upper defaults is applied without warning. If two or more width options are given, the first takes precedence and others are ignored (even if the first is invalid and the default width applied).
  16 
  17 pdf-[vert|horz]: requests that if the file is a pdf, then adjust height to suit the orientation. 'pdf-vert' is default and takes precedence. This option is best used when the gallery only includes PDFs.
  18 
  19 noframe : request gallery be rendered without frames and backgrounds.
  20 
  21 nospace : request gallery be rendered without spaces between items.
  22 
  23 nolink : request that no click links be inserted on the items. This can be useful if the items are embedded PDFs because the links are not overly effective and can interfere with other functionality. 
  24 
  25 nocaption : request no caption row to be included. If captions are blank or not needed, this make for a more compact gallery, especially if a multi-row gallery.
  26 
  27 caplink : add links in the captions as well. Helpful for Chrome & Firefox where the click on image for embedded PDFs is not so effective.
  28 
  29 markup : shows the markup if you wish to re-use this with modification (assuming the default tabulation does not suit a specific purpose) or for debugging purposes.
  30 
  31 # : inserted at the beginning of the caption requests that captions be inserted as in-line comments.
  32 
  33 & : inserted at the end of the caption requests that link be inserted. This is an alternative to 'caplink', to have links added only to selection cations.
  34 
  35 Defaults are width 100px, eight columns (so no options for these are needed).
  36 
  37 Keywords can appear in any order, other than as indicated above for conflicting choices.
  38 
  39 Usage
  40 
  41 {{{#!gallery [c-[1-8] ][nnn[px] ][pdf-vert|pdf-horz ][noframe ][nospace ][markup ]
  42  gallery_file:: [#]caption
  43  galery_file:: [#]caption
  44  ...
  45 }}}
  46 
  47 History
  48 
  49 Version 1.0 - 11.10.2018: initial version
  50 
  51 Developed with inspiration and code from:
  52 
  53 keyval.py parser - @copyright: 2006 by Matt Cooper <macooper@vt.edu>
  54 sort.py parser - @copyright: 2005 ReimarBauer
  55 
  56 Copyright
  57 
  58 @copyright: 2018 Ian Riley <ian.@riley.asia>
  59 
  60 License
  61 
  62 GNU GPL, see COPYING for details.
  63 '''
  64 
  65 import re
  66 from MoinMoin.parser import text_moin_wiki as wiki
  67 from MoinMoin import wikiutil
  68 
  69 Dependencies = []
  70 
  71 class Parser:
  72     parsername = 'gallery'
  73 
  74     def __init__(self, raw, request, **kw):
  75         self.raw = raw
  76         self.request = request
  77         self.form = request.form
  78         self._ = request.getText
  79         self.args = kw.get('format_args', '')
  80 
  81     def format(self, formatter):
  82         eol = u'\n'
  83         dot = u'.'
  84         sep = u':: '
  85         div = u'/'
  86         ignore = u'#'
  87         space = u' '
  88         ignore = u'#'
  89         add = u'&'
  90         copt = u'c-'
  91         pixels = u'px'
  92         brk = u'<<BR>>'
  93         parsing = (u'{{{', u'}}}', )
  94         commenting = (u' /* ', ' */ ', )
  95         tab = u'||<: tablestyle="width:10%"'
  96         cell = (u'||<: height="%(height)spx" width="%(width)spx" bgcolor="#e8e8e8">',
  97                 u'||<^ style="border:none;">',
  98                 u'||<: height="%(height)spx" width="%(width)spx" style="border:none;">',
  99                 u'||<^ style="border:none;">', )
 100         cellf = u'||\n'
 101         att = u'{{attachment:%(att)s|click for original|height=%(height)s,width=%(width)s}}'
 102         attonly = u'{{attachment:%(att)s|%(attfile)s|height=%(height)s,width=%(width)s}}'
 103         link = u'[[%(attpage)s|%(att)s|target="_blank",&action=AttachFile,&do=get,&target="%(attfile)s"]]'
 104         clink = u' [[attachment:%(att)s|%(atttype)s|target="_blank",&do=get]]'
 105         cap = u'%(cap)s'
 106         pad = (u'||<width="20px" style="border:none;">',
 107                u'||<style="border:none;">', )
 108         options, entries, rows, results = ([], [], [], [], )
 109         frame = ((0, 1, ), (2, 3, ), )
 110         std_cols = 8
 111         std_width = 200 # also used for height
 112         min_width = 50
 113         max_width = std_cols * std_width
 114         req_cols = -1
 115         req_height = -1
 116         req_width = -1
 117 
 118         # set options
 119         options = self.args.split(space)
 120         pdfv = "pdf-vert" in options
 121         pdfh = "pdf-horz" in options
 122         noframe = "noframe" in options
 123         nospace = "nospace" in options
 124         nolink = "nolink" in options
 125         nocaption = "nocaption" in options
 126         caplink = "caplink" in options
 127         markup = "markup" in options
 128         for option in options:
 129             if option.startswith(copt):
 130                 try:
 131                     req_cols = int(option.lstrip(copt)) # will check this value later
 132                 except:
 133                     pass
 134                 break # do not look for any more width options
 135         for option in options:
 136             try:
 137                 req_width = int(option) # will check this value later
 138             except:
 139                 pass
 140             if req_width != -1:
 141                 break # do not look for any more width options
 142             if option.endswith(pixels):
 143                 try:
 144                     req_width = int(option.rstrip(pixels)) # will check this value later
 145                 except:
 146                     pass
 147                 break # do not look for any more width options
 148         del options
 149 
 150         # check requested columns in range or set default
 151         if (req_cols < 1) or (req_cols > std_cols):
 152             req_cols = std_cols
 153         # check requested width in range or set default
 154         if (req_width > max_width):
 155             req_width = max_width
 156         if (req_width < min_width):
 157             req_width = min_width
 158         # dynamically reset requested width depending on requested columns
 159         if (req_cols * req_width) > (std_cols * std_width):
 160             req_width = int(max_width/req_cols)
 161              
 162         # process the lines of text provided
 163         lines = self.raw.split(eol)
 164         for line in lines:
 165             if line:
 166                 # handle gallery lines
 167                 if (line[0] == space) and (sep in line):
 168                     attachment, caption = (line.lstrip(space)).split(sep)
 169                     if (div not in attachment):
 170                         attachment = ignore + div + attachment
 171                     attpage, attfile = (attachment.rsplit(div, 1))
 172                     attpath = attpage
 173                     if (attpage == ignore):
 174                         attpath = ''
 175                     attname, atttype = (attfile.rsplit(dot,1))
 176                     if (caption.startswith(ignore)):
 177                         caption = commenting[0] + caption[1:] + commenting[1]
 178                     entries.append([attpage, attpath, attfile, atttype, caption, ])
 179         del lines
 180 
 181         # construct a list of row column numbers
 182         entry = len(entries)
 183         while entry >= req_cols:
 184            rows.append(req_cols)
 185            entry = entry - req_cols
 186         if entry > 0:
 187            rows.append(entry)
 188 
 189         # construct output for columns in rows
 190         for cols in rows:
 191             pending = ['', '', ]
 192             while cols > 0:
 193                 addlink = False
 194                 entry = entries.pop(0)
 195                 req_height = req_width
 196                 if (entry[3].lower() == 'pdf'):
 197                     if (pdfv):
 198                         req_height = int(req_height * 1.414)
 199                     elif (pdfh):
 200                         req_height = int(req_height / 1.414)
 201 
 202                 if nolink:
 203                     pending[0] = pending[0] + \
 204                          (cell[frame[noframe][0]] % {'height': req_height + 20,
 205                                                      'width': req_width + 20,
 206                                                     }) + \
 207                          (attonly % {'att': entry[1] + div + entry[2],
 208                                      'attfile': entry[2], 
 209                                      'height': req_height, 
 210                                      'width': req_width,
 211                                     })
 212                 else:
 213                     alink = (att % {'att': entry[1] + div + entry[2], 
 214                                     'height': req_height, 
 215                                     'width': req_width,
 216                                    })
 217                     pending[0] = pending[0] + \
 218                          (cell[frame[noframe][0]] % {'height': req_height + 20, 
 219                                                      'width': req_width + 20,
 220                                                     }) + \
 221                          (link % {'attpage': entry[0],
 222                                   'att': alink,
 223                                   'attfile': entry[2],
 224                                  })
 225 
 226                 if (entry[4].endswith(add)):
 227                     addlink = True
 228                     entry[4] = entry[4][:-1]
 229 
 230                 pending[1] = pending[1] + cell[frame[noframe][1]] + \
 231                     (cap % {'cap': entry[4],
 232                            })
 233 
 234                 if (caplink or addlink):
 235                     pending[1] = pending[1] + \
 236                         (clink % {'att': entry[1] + div + entry[2],
 237                                   'atttype': entry[3],
 238                                  })
 239                 cols = cols - 1
 240  
 241                 if ((not nospace) and (cols > 0)):
 242                      pending[0] = pending[0] + pad[0]
 243                      pending[1] = pending[1] + pad[1]
 244 
 245             pending[0] = tab + pending[0][4:] + cellf # insert tablestyle and close table
 246             pending[1] = pending[1] + cellf # close only
 247  
 248             if (nocaption):
 249                 pending[1] = ''
 250 
 251             result = pending[0] + pending[1]
 252             results.append(result)
 253             
 254         del rows, entries
 255 
 256         # escape markup if requested
 257         if markup:
 258             results.insert(0, parsing[0])
 259             results.append(parsing[1])
 260 
 261         wikiizer = wiki.Parser(eol.join(results), self.request)
 262         wikiizer.format(formatter, inhibit_p=True)

You are not allowed to attach a file to this page.