Attachment '03.extract-page-functions.patch'

Download

   1 # HG changeset patch
   2 # User gerg.ward+moin@gmail.com
   3 # Date 1225380804 14400
   4 # Node ID 53ff55dee8f99d6d3e78e73cab1c2c3d6b3df8e4
   5 # Parent  4eae0f3824d2084833ff9397ec48bc6b3a684d61
   6 Factor out functions that work on including a single page.
   7 
   8 diff -r 4eae0f3824d2 -r 53ff55dee8f9 MoinMoin/macro/Include.py
   9 --- a/MoinMoin/macro/Include.py	Thu Oct 30 11:16:34 2008 -0400
  10 +++ b/MoinMoin/macro/Include.py	Thu Oct 30 11:33:24 2008 -0400
  11 @@ -80,6 +80,120 @@
  12      if skipitems:
  13          del pagelist[:int(skipitems)]
  14  
  15 +class NoIncludeError(Exception):
  16 +    def __init__(self, message=None):
  17 +        self.message = message
  18 +
  19 +def check_page(macro, request, this_page, inc_name):
  20 +    """
  21 +    Check if it's OK to include the page named by 'inc_name' and return
  22 +    a Page object corresponding to 'inc_page' if so.  If not, raise
  23 +    NoIncludeError with an untranslated end-user error message.  The
  24 +    NoIncludeError have no message, in which case no error message will
  25 +    be shown to the end user.
  26 +    """
  27 +    if not request.user.may.read(inc_name):
  28 +        raise NoIncludeError()
  29 +    if inc_name in this_page._macroInclude_pagelist:
  30 +        raise NoIncludeError(u'Recursive include of "%s" forbidden' % (inc_name, ))
  31 +    fmt = macro.formatter.__class__(request, is_included=True)
  32 +    fmt._base_depth = macro.formatter._base_depth
  33 +    inc_page = Page(request, inc_name, formatter=fmt)
  34 +    if not inc_page.exists():
  35 +        raise NoIncludeError()
  36 +
  37 +    return inc_page
  38 +
  39 +def trim_page_body(request, inc_page, args, result):
  40 +    _ = request.getText
  41 +    body = inc_page.get_raw_body() + '\n'
  42 +    from_pos = 0
  43 +    to_pos = -1
  44 +    from_re = args.group('from')
  45 +    if from_re:
  46 +        try:
  47 +            from_match = re.compile(from_re, re.M).search(body)
  48 +        except re.error:
  49 +            ##result.append("*** fe=%s ***" % e)
  50 +            from_match = re.compile(re.escape(from_re), re.M).search(body)
  51 +        if from_match:
  52 +            from_pos = from_match.end()
  53 +        else:
  54 +            result.append(_sysmsg % ('warning', 'Include: ' + _('Nothing found for "%s"!')) % from_re)
  55 +    to_re = args.group('to')
  56 +    if to_re:
  57 +        try:
  58 +            to_match = re.compile(to_re, re.M).search(body, from_pos)
  59 +        except re.error:
  60 +            to_match = re.compile(re.escape(to_re), re.M).search(body, from_pos)
  61 +        if to_match:
  62 +            to_pos = to_match.start()
  63 +        else:
  64 +            result.append(_sysmsg % ('warning', 'Include: ' + _('Nothing found for "%s"!')) % to_re)
  65 +
  66 +    trimmed = (from_pos > 0 or to_pos > -1)
  67 +    return (body[from_pos:to_pos], trimmed)
  68 +
  69 +def format_titles(macro, request, title_re, inc_page, body, result):
  70 +    levelstack = []
  71 +    for title, level in extract_titles(body, title_re):
  72 +        if levelstack:
  73 +            if level > levelstack[-1]:
  74 +                result.append(macro.formatter.bullet_list(1))
  75 +                levelstack.append(level)
  76 +            else:
  77 +                while levelstack and level < levelstack[-1]:
  78 +                    result.append(macro.formatter.bullet_list(0))
  79 +                    levelstack.pop()
  80 +                if not levelstack or level != levelstack[-1]:
  81 +                    result.append(macro.formatter.bullet_list(1))
  82 +                    levelstack.append(level)
  83 +        else:
  84 +            result.append(macro.formatter.bullet_list(1))
  85 +            levelstack.append(level)
  86 +        result.append(macro.formatter.listitem(1))
  87 +        result.append(inc_page.link_to(request, title))
  88 +        result.append(macro.formatter.listitem(0))
  89 +    while levelstack:
  90 +        result.append(macro.formatter.bullet_list(0))
  91 +        levelstack.pop()
  92 +
  93 +def add_heading(macro, request, print_mode, inc_page, args, result):
  94 +    level = None
  95 +    if args.group('heading') and args.group('hquote'):
  96 +        # XXX that "or ..." clause is dead code: the arg_heading regex
  97 +        # guarantees that args.group('htext') will return a non-empty
  98 +        # string as long as args.group('hquote') does too.
  99 +        heading = args.group('htext') or inc_page.split_title()
 100 +        level = 1
 101 +        if args.group('level'):
 102 +            level = int(args.group('level'))
 103 +        if print_mode:
 104 +            result.append(macro.formatter.heading(1, level) +
 105 +                          macro.formatter.text(heading) +
 106 +                          macro.formatter.heading(0, level))
 107 +        else:
 108 +            url = inc_page.url(request)
 109 +            result.extend([
 110 +                macro.formatter.heading(1, level, id=heading),
 111 +                macro.formatter.url(1, url, css="include-heading-link"),
 112 +                macro.formatter.text(heading),
 113 +                macro.formatter.url(0),
 114 +                macro.formatter.heading(0, level),
 115 +            ])
 116 +        return True
 117 +    else:
 118 +        return False
 119 +
 120 +def add_editlink(macro, request, inc_name, inc_page, result):
 121 +    _ = request.getText
 122 +    result.extend([
 123 +        macro.formatter.div(1, css_class="include-link"),
 124 +        inc_page.link_to(request, '[%s]' % (inc_name, ), css_class="include-page-link"),
 125 +        inc_page.link_to(request, '[%s]' % (_('edit'), ), css_class="include-edit-link", querystr={'action': 'edit', 'backto': request._Include_backto}),
 126 +        macro.formatter.div(0),
 127 +    ])
 128 +
 129  def execute(macro, text, args_re=re.compile(_args_re_pattern), title_re=re.compile(_title_re, re.M)):
 130      request = macro.request
 131      _ = request.getText
 132 @@ -112,97 +226,31 @@
 133  
 134      # iterate over pages
 135      for inc_name in pagelist:
 136 -        if not request.user.may.read(inc_name):
 137 +        try:
 138 +            inc_page = check_page(macro, request, this_page, inc_name)
 139 +        except NoIncludeError, err:
 140 +            if err.message:
 141 +                result.append(u'<p><strong class="error">%s</strong></p>' % (err.message, ))
 142              continue
 143 -        if inc_name in this_page._macroInclude_pagelist:
 144 -            result.append(u'<p><strong class="error">Recursive include of "%s" forbidden</strong></p>' % (inc_name, ))
 145 -            continue
 146 -        fmt = macro.formatter.__class__(request, is_included=True)
 147 -        fmt._base_depth = macro.formatter._base_depth
 148 -        inc_page = Page(request, inc_name, formatter=fmt)
 149 -        if not inc_page.exists():
 150 -            continue
 151 +
 152          inc_page._macroInclude_pagelist = this_page._macroInclude_pagelist
 153  
 154 -        # check for "from" and "to" arguments (allowing partial includes)
 155 -        body = inc_page.get_raw_body() + '\n'
 156 -        from_pos = 0
 157 -        to_pos = -1
 158 -        from_re = args.group('from')
 159 -        if from_re:
 160 -            try:
 161 -                from_match = re.compile(from_re, re.M).search(body)
 162 -            except re.error:
 163 -                ##result.append("*** fe=%s ***" % e)
 164 -                from_match = re.compile(re.escape(from_re), re.M).search(body)
 165 -            if from_match:
 166 -                from_pos = from_match.end()
 167 -            else:
 168 -                result.append(_sysmsg % ('warning', 'Include: ' + _('Nothing found for "%s"!')) % from_re)
 169 -        to_re = args.group('to')
 170 -        if to_re:
 171 -            try:
 172 -                to_match = re.compile(to_re, re.M).search(body, from_pos)
 173 -            except re.error:
 174 -                to_match = re.compile(re.escape(to_re), re.M).search(body, from_pos)
 175 -            if to_match:
 176 -                to_pos = to_match.start()
 177 -            else:
 178 -                result.append(_sysmsg % ('warning', 'Include: ' + _('Nothing found for "%s"!')) % to_re)
 179 +        # get the body of the included page, applying 'from' and 'to' to trim it
 180 +        # (partial includes)
 181 +        (body, trimmed) = trim_page_body(request, inc_page, args, result)
 182  
 183          if titlesonly:
 184 -            levelstack = []
 185 -            for title, level in extract_titles(body[from_pos:to_pos], title_re):
 186 -                if levelstack:
 187 -                    if level > levelstack[-1]:
 188 -                        result.append(macro.formatter.bullet_list(1))
 189 -                        levelstack.append(level)
 190 -                    else:
 191 -                        while levelstack and level < levelstack[-1]:
 192 -                            result.append(macro.formatter.bullet_list(0))
 193 -                            levelstack.pop()
 194 -                        if not levelstack or level != levelstack[-1]:
 195 -                            result.append(macro.formatter.bullet_list(1))
 196 -                            levelstack.append(level)
 197 -                else:
 198 -                    result.append(macro.formatter.bullet_list(1))
 199 -                    levelstack.append(level)
 200 -                result.append(macro.formatter.listitem(1))
 201 -                result.append(inc_page.link_to(request, title))
 202 -                result.append(macro.formatter.listitem(0))
 203 -            while levelstack:
 204 -                result.append(macro.formatter.bullet_list(0))
 205 -                levelstack.pop()
 206 +            format_titles(macro, request, title_re, inc_page, body, result)
 207              continue
 208  
 209 -        if from_pos or to_pos != -1:
 210 -            inc_page.set_raw_body(body[from_pos:to_pos], modified=True)
 211 -        ##result.append("*** f=%s t=%s ***" % (from_re, to_re))
 212 -        ##result.append("*** f=%d t=%d ***" % (from_pos, to_pos))
 213 +        if trimmed:
 214 +            inc_page.set_raw_body(body, modified=True)
 215  
 216          if not hasattr(request, "_Include_backto"):
 217              request._Include_backto = this_page.page_name
 218  
 219          # do headings
 220 -        level = None
 221 -        if args.group('heading') and args.group('hquote'):
 222 -            heading = args.group('htext') or inc_page.split_title()
 223 -            level = 1
 224 -            if args.group('level'):
 225 -                level = int(args.group('level'))
 226 -            if print_mode:
 227 -                result.append(macro.formatter.heading(1, level) +
 228 -                              macro.formatter.text(heading) +
 229 -                              macro.formatter.heading(0, level))
 230 -            else:
 231 -                url = inc_page.url(request)
 232 -                result.extend([
 233 -                    macro.formatter.heading(1, level, id=heading),
 234 -                    macro.formatter.url(1, url, css="include-heading-link"),
 235 -                    macro.formatter.text(heading),
 236 -                    macro.formatter.url(0),
 237 -                    macro.formatter.heading(0, level),
 238 -                ])
 239 +        added_heading = add_heading(macro, request, print_mode, inc_page, args, result)
 240  
 241          # set or increment include marker
 242          this_page._macroInclude_pagelist[inc_name] = \
 243 @@ -227,13 +275,9 @@
 244              del this_page._macroInclude_pagelist[inc_name]
 245  
 246          # if no heading and not in print mode, then output a helper link
 247 -        if editlink and not (level or print_mode):
 248 -            result.extend([
 249 -                macro.formatter.div(1, css_class="include-link"),
 250 -                inc_page.link_to(request, '[%s]' % (inc_name, ), css_class="include-page-link"),
 251 -                inc_page.link_to(request, '[%s]' % (_('edit'), ), css_class="include-edit-link", querystr={'action': 'edit', 'backto': request._Include_backto}),
 252 -                macro.formatter.div(0),
 253 -            ])
 254 +        if editlink and not (added_heading or print_mode):
 255 +            add_editlink(macro, request, inc_name, inc_page, result)
 256 +
 257          # XXX page.link_to is wrong now, it escapes the edit_icon html as it escapes normal text
 258  
 259      # return include text

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] (2008-10-30 17:01:52, 20.5 KB) [[attachment:01.test-include.patch]]
  • [get | view] (2008-10-30 17:02:07, 3.1 KB) [[attachment:02.extract-setup-functions.patch]]
  • [get | view] (2008-10-30 17:02:17, 11.1 KB) [[attachment:03.extract-page-functions.patch]]
 All files | Selected Files: delete move to page copy to page

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