Attachment 'Include2.py'

Download

   1 # -*- coding: iso-8859-1 -*-
   2 """
   3     MoinMoin - Include macro
   4 
   5     This macro includes the formatted content of the given page(s). See
   6 
   7         http://purl.net/wiki/moinmaster/HelpOnMacros/Include
   8 
   9     for detailed docs.
  10     
  11     @copyright: 2000-2004 by Jürgen Hermann <jh@web.de>
  12     @copyright: 2000-2001 by Richard Jones <richard@bizarsoftware.com.au>
  13     @license: GNU GPL, see COPYING for details.
  14 """
  15 
  16 #Dependencies = ["pages"] # included page
  17 Dependencies = ["time"] # works around MoinMoinBugs/TableOfContentsLacksLinks
  18 
  19 import re, StringIO
  20 from MoinMoin import wikiutil
  21 from MoinMoin.Page import Page
  22 from MoinMoin.util import web
  23 
  24 _sysmsg = '<p><strong class="%s">%s</strong></p>'
  25 
  26 ## keep in sync with TableOfContents macro!
  27 _arg_heading = r'(?P<heading>,)\s*(|(?P<hquote>[\'"])(?P<htext>.+?)(?P=hquote))'
  28 _arg_level = r',\s*(?P<level>\d*)'
  29 _arg_from = r'(,\s*from=(?P<fquote>[\'"])(?P<from>.+?)(?P=fquote))?'
  30 _arg_to = r'(,\s*to=(?P<tquote>[\'"])(?P<to>.+?)(?P=tquote))?'
  31 _arg_sort = r'(,\s*sort=(?P<sort>(ascending|descending)))?'
  32 _arg_items = r'(,\s*items=(?P<items>\d+))?'
  33 _arg_skipitems = r'(,\s*skipitems=(?P<skipitems>\d+))?'
  34 _arg_titlesonly = r'(,\s*(?P<titlesonly>titlesonly))?'
  35 _arg_editlink = r'(,\s*(?P<editlink>editlink))?'
  36 _arg_tabulate = r'(,\s*(?P<tabulate>tabulate))?'
  37 _args_re_pattern = r'^(?P<name>[^,]+)(%s(%s)?%s%s%s%s%s%s%s%s)?$' % (
  38     _arg_heading, _arg_level, _arg_from, _arg_to, _arg_sort, _arg_items,
  39     _arg_skipitems, _arg_titlesonly, _arg_editlink, _arg_tabulate)
  40 
  41 _title_re = r"^(?P<heading>\s*(?P<hmarker>=+)\s.*\s(?P=hmarker))$"
  42 
  43 def extract_titles(body, title_re):
  44     titles = []
  45     for title, _ in title_re.findall(body):
  46         h = title.strip()
  47         level = 1
  48         while h[level:level+1] == '=': level = level+1
  49         depth = min(5,level)
  50         title_text = h[level:-level].strip()
  51         titles.append((title_text, level))
  52     return titles
  53 
  54 def execute(macro, text, args_re=re.compile(_args_re_pattern), title_re=re.compile(_title_re, re.M), called_by_toc=0):
  55     request = macro.request
  56     _ = request.getText
  57 
  58     # return immediately if getting links for the current page
  59     if request.mode_getpagelinks:
  60         return ''
  61 
  62     # parse and check arguments
  63     args = args_re.match(text)
  64     if not args:
  65         return (_sysmsg % ('error', _('Invalid include arguments "%s"!')) % (text,))
  66 
  67     # prepare including page
  68     result = []
  69     print_mode = macro.form.has_key('action') and macro.form['action'][0] == "print"
  70     this_page = macro.formatter.page
  71     if not hasattr(this_page, '_macroInclude_pagelist'):
  72         this_page._macroInclude_pagelist = {}
  73 
  74     # get list of pages to include
  75     inc_name = wikiutil.AbsPageName(request, this_page.page_name, args.group('name'))
  76     pagelist = [inc_name]
  77     if inc_name.startswith("^"):
  78         try:
  79             inc_match = re.compile(inc_name)
  80         except re.error:
  81             pass # treat as plain page name
  82         else:
  83             # Get user filtered readable page list
  84             pagelist = request.rootpage.getPageList(filter=inc_match.match)
  85 
  86     # sort and limit page list
  87     pagelist.sort()
  88     sort_dir = args.group('sort')
  89     if sort_dir == 'descending':
  90         pagelist.reverse()
  91     max_items = args.group('items')
  92     if max_items:
  93         pagelist = pagelist[:int(max_items)]
  94 
  95     skipitems = 0
  96     if args.group("skipitems"):
  97         skipitems = int(args.group("skipitems"))
  98     titlesonly = args.group('titlesonly')
  99     editlink = args.group('editlink')
 100     tabulate = args.group('tabulate')
 101 
 102     if tabulate:
 103         result.append('<table class="news">')
 104 
 105     # iterate over pages
 106     for inc_name in pagelist:
 107         if not request.user.may.read(inc_name):
 108             continue
 109         if this_page._macroInclude_pagelist.has_key(inc_name):
 110             result.append(u'<p><strong class="error">Recursive include of "%s" forbidden</strong></p>' % (inc_name,))
 111             continue
 112         if skipitems:
 113             skipitems -= 1
 114             continue
 115         fmt = macro.formatter.__class__(request, is_included=True)
 116         fmt._base_depth = macro.formatter._base_depth
 117         inc_page = Page(request, inc_name, formatter=fmt)
 118         inc_page._macroInclude_pagelist = this_page._macroInclude_pagelist
 119 
 120         # check for "from" and "to" arguments (allowing partial includes)
 121         body = inc_page.get_raw_body() + '\n'
 122         from_pos = 0
 123         to_pos = -1
 124         from_re = args.group('from')
 125         if from_re:
 126             try:
 127                 from_match = re.compile(from_re, re.M).search(body)
 128             except re.error, e:
 129                 ##result.append("*** fe=%s ***" % e)
 130                 from_match = re.compile(re.escape(from_re), re.M).search(body)
 131             if from_match:
 132                 from_pos = from_match.end()
 133             else:
 134                 result.append(_sysmsg % ('warning', 'Include: ' + _('Nothing found for "%s"!')) % from_re)
 135         to_re = args.group('to')
 136         if to_re:
 137             try:
 138                 to_match = re.compile(to_re, re.M).search(body, from_pos)
 139             except re.error:
 140                 to_match = re.compile(re.escape(to_re), re.M).search(body, from_pos)
 141             if to_match:
 142                 to_pos = to_match.start()
 143             else:
 144                 result.append(_sysmsg % ('warning', 'Include: ' + _('Nothing found for "%s"!')) % to_re)
 145 
 146         if titlesonly:
 147             newbody = []
 148             levelstack = []
 149             for title, level in extract_titles(body[from_pos:to_pos], title_re):
 150                 if levelstack:
 151                     if level > levelstack[-1]:
 152                         result.append(macro.formatter.bullet_list(1))
 153                         levelstack.append(level)
 154                     else:
 155                         while levelstack and level < levelstack[-1]:
 156                             result.append(macro.formatter.bullet_list(0))
 157                             levelstack.pop()
 158                         if not levelstack or level != levelstack[-1]:
 159                             result.append(macro.formatter.bullet_list(1))
 160                             levelstack.append(level)
 161                 else:
 162                     result.append(macro.formatter.bullet_list(1))
 163                     levelstack.append(level)
 164                 result.append(macro.formatter.listitem(1))
 165                 result.append(inc_page.link_to(request, title))
 166                 result.append(macro.formatter.listitem(0))
 167             while levelstack:
 168                 result.append(macro.formatter.bullet_list(0))
 169                 levelstack.pop()
 170             continue
 171 
 172         if from_pos or to_pos != -1:
 173             inc_page.set_raw_body(body[from_pos:to_pos], modified=True)
 174         ##result.append("*** f=%s t=%s ***" % (from_re, to_re))
 175         ##result.append("*** f=%d t=%d ***" % (from_pos, to_pos))
 176 
 177         if called_by_toc:
 178             result.extend(inc_page.get_raw_body())
 179             continue
 180 
 181         if not hasattr(request, "_Include_backto"):
 182             request._Include_backto = this_page.page_name
 183         
 184         # do headings
 185         level = None
 186         if args.group('heading') and args.group('hquote'):
 187             heading = args.group('htext') or inc_page.split_title(request)
 188             level = 1
 189             if args.group('level'):
 190                 level = int(args.group('level'))
 191             if print_mode:
 192                 result.append(macro.formatter.heading(1, level) +
 193                               macro.formatter.text(heading) +
 194                               macro.formatter.heading(0, level))
 195             else:
 196                 import sha
 197                 from MoinMoin import config
 198                 # this heading id might produce duplicate ids,
 199                 # if the same page is included multiple times
 200                 # Encode stuf we feed into sha module.
 201                 pntt = (inc_name + heading).encode(config.charset)
 202                 hid = "head-" + sha.new(pntt).hexdigest()
 203                 request._page_headings.setdefault(pntt, 0)
 204                 request._page_headings[pntt] += 1
 205                 if request._page_headings[pntt] > 1:
 206                     hid += '-%d'%(request._page_headings[pntt],)
 207                 result.append(
 208                     #macro.formatter.heading(1, level, hid,
 209                     #    icons=edit_icon.replace('<img ', '<img align="right" ')) +
 210                     macro.formatter.heading(1, level, hid) +
 211                     inc_page.link_to(request, heading, css_class="include-heading-link") +
 212                     macro.formatter.heading(0, level)
 213                 )
 214 
 215         # set or increment include marker
 216         this_page._macroInclude_pagelist[inc_name] = \
 217             this_page._macroInclude_pagelist.get(inc_name, 0) + 1
 218 
 219          # if no heading and not in print mode, then output a helper link
 220         if editlink and not (level or print_mode):
 221             editlink_html = "\n".join([
 222                 '<div class="include-link">',
 223                 inc_page.link_to(request, '[%s]' % (inc_name,), css_class="include-page-link"),
 224                 inc_page.link_to(request, '[%s]' % (_('edit'),), css_class="include-edit-link", querystr={'action': 'edit', 'backto': request._Include_backto}),
 225                 '</div>',
 226             ])
 227         else:
 228             editlink_html = ""
 229         # XXX page.link_to is wrong now, it escapes the edit_icon html as it escapes normal text
 230 
 231         if tabulate:
 232             body = inc_page.get_raw_body()
 233 
 234             mob = re.compile("#date (.*?)\n").match(body)
 235             if mob:
 236                 date = mob.group(1)
 237                 body = body[mob.end():]
 238             else:
 239                 date = inc_name
 240 
 241             mob = re.compile("#heading (.*?)\n").match(body)
 242             if mob:
 243                 heading = mob.group(1)
 244                 body = body[mob.end():]
 245             else:
 246                 heading = "News"
 247 
 248             mob = re.compile("#symbol (.*?)\n").match(body)
 249             if mob:
 250                 symbol = mob.group(1)
 251                 body = body[mob.end():]
 252             else:
 253                 symbol = "http:/pics/allefant.gif"
 254 
 255             inc_page.set_raw_body(body, modified=True)
 256 
 257             result.append('<tr class="heading"><td>%s</td>' % date)
 258             result.append("<td>%s</td><td>%s</td></tr>" % (heading, editlink_html))
 259             result.append('<tr><td><img src="%s" alt="news icon" /></td><td colspan="2">' % symbol)
 260 
 261         # output the included page
 262         strfile = StringIO.StringIO()
 263         request.redirect(strfile)
 264         try:
 265             cid = request.makeUniqueID("Include_%s" % wikiutil.quoteWikinameFS(inc_page.page_name))
 266             inc_page.send_page(request, content_only=1, content_id=cid)
 267             result.append(strfile.getvalue())
 268         finally:
 269             request.redirect()
 270 
 271         # decrement or remove include marker
 272         if this_page._macroInclude_pagelist[inc_name] > 1:
 273             this_page._macroInclude_pagelist[inc_name] = \
 274                 this_page._macroInclude_pagelist[inc_name] - 1
 275         else:
 276             del this_page._macroInclude_pagelist[inc_name]
 277 
 278         if tabulate:
 279             result.append("</td></tr>")
 280 
 281     if tabulate:
 282         result.append("</table>")
 283 
 284     # return include text
 285     return ''.join(result)
 286 
 287 # vim:ts=4:sw=4:et

Attached Files

To refer to attachments on a page, use attachment:filename, as shown below in the list of files. Do NOT use the URL of the [get] link, since this is subject to change and can break easily.
  • [get | view] (2006-03-18 23:20:07, 11.0 KB) [[attachment:Include2.py]]
 All files | Selected Files: delete move to page copy to page

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