paul@0 | 1 | # -*- coding: iso-8859-1 -*- |
paul@0 | 2 | """ |
paul@0 | 3 | MoinMoin - MoinShare library |
paul@0 | 4 | |
paul@0 | 5 | @copyright: 2011, 2012 by Paul Boddie <paul@boddie.org.uk> |
paul@0 | 6 | @license: GNU GPL (v2 or later), see COPYING.txt for details. |
paul@0 | 7 | """ |
paul@0 | 8 | |
paul@0 | 9 | from MoinSupport import * |
paul@0 | 10 | from MoinMoin import wikiutil |
paul@0 | 11 | import re |
paul@0 | 12 | |
paul@0 | 13 | escape = wikiutil.escape |
paul@0 | 14 | |
paul@0 | 15 | __version__ = "0.1" |
paul@0 | 16 | |
paul@0 | 17 | # More Moin 1.9 compatibility functions. |
paul@0 | 18 | |
paul@0 | 19 | def has_member(request, groupname, username): |
paul@0 | 20 | if hasattr(request.dicts, "has_member"): |
paul@0 | 21 | return request.dicts.has_member(groupname, username) |
paul@0 | 22 | else: |
paul@0 | 23 | return username in request.dicts.get(groupname, []) |
paul@0 | 24 | |
paul@0 | 25 | # Extraction of shared fragments. |
paul@0 | 26 | |
paul@0 | 27 | marker_regexp_str = r"([{]{3,}|[}]{3,})" |
paul@0 | 28 | marker_regexp = re.compile(marker_regexp_str, re.MULTILINE | re.DOTALL) # {{{... or }}}... |
paul@0 | 29 | |
paul@3 | 30 | # Fragments employ a "moinshare" attribute. |
paul@3 | 31 | |
paul@3 | 32 | fragment_prelude = "#!" |
paul@3 | 33 | fragment_attribute = "moinshare" |
paul@2 | 34 | |
paul@0 | 35 | def getRegions(s): |
paul@0 | 36 | |
paul@0 | 37 | "Parse the string 's', returning a list of shared regions." |
paul@0 | 38 | |
paul@0 | 39 | regions = [] |
paul@0 | 40 | marker = None |
paul@0 | 41 | is_region = True |
paul@0 | 42 | |
paul@0 | 43 | for match_text in marker_regexp.split(s): |
paul@0 | 44 | |
paul@0 | 45 | # Capture section text. |
paul@0 | 46 | |
paul@0 | 47 | if is_region and marker: |
paul@0 | 48 | regions[-1] += match_text |
paul@0 | 49 | |
paul@0 | 50 | # Handle section markers. |
paul@0 | 51 | |
paul@0 | 52 | elif not is_region: |
paul@0 | 53 | |
paul@0 | 54 | # Close any open sections, returning to exposed text regions. |
paul@0 | 55 | |
paul@0 | 56 | if marker: |
paul@0 | 57 | if match_text.startswith("}") and len(marker) == len(match_text): |
paul@0 | 58 | marker = None |
paul@0 | 59 | |
paul@0 | 60 | # Without a current marker, start a section if an appropriate marker |
paul@0 | 61 | # is given. |
paul@0 | 62 | |
paul@0 | 63 | elif match_text.startswith("{"): |
paul@0 | 64 | marker = match_text |
paul@0 | 65 | regions.append("") |
paul@0 | 66 | |
paul@0 | 67 | # Markers and section text are added to the current region. |
paul@0 | 68 | |
paul@0 | 69 | regions[-1] += match_text |
paul@0 | 70 | |
paul@0 | 71 | # Exposed text is ignored. |
paul@0 | 72 | |
paul@0 | 73 | # The match text alternates between text between markers and the markers |
paul@0 | 74 | # themselves. |
paul@0 | 75 | |
paul@0 | 76 | is_region = not is_region |
paul@0 | 77 | |
paul@0 | 78 | return regions |
paul@0 | 79 | |
paul@2 | 80 | def getFragmentsFromRegions(regions): |
paul@2 | 81 | |
paul@2 | 82 | """ |
paul@2 | 83 | Return fragments from the given 'regions', each having the form |
paul@4 | 84 | (format, arguments, body text). |
paul@2 | 85 | """ |
paul@2 | 86 | |
paul@2 | 87 | fragments = [] |
paul@2 | 88 | |
paul@2 | 89 | for region in regions: |
paul@4 | 90 | body = region.lstrip("{").rstrip("}").lstrip() |
paul@2 | 91 | if body.startswith(fragment_prelude): |
paul@2 | 92 | arguments, body = body[len(fragment_prelude):].split("\n", 1) |
paul@4 | 93 | |
paul@4 | 94 | # Get any parser/format declaration. |
paul@4 | 95 | |
paul@4 | 96 | if arguments and not arguments[0].isspace(): |
paul@4 | 97 | format, arguments = arguments.split(None, 1) |
paul@4 | 98 | else: |
paul@4 | 99 | format = None |
paul@4 | 100 | |
paul@4 | 101 | # Get the attributes/arguments for the region. |
paul@4 | 102 | |
paul@3 | 103 | attributes = parseAttributes(arguments, False) |
paul@4 | 104 | |
paul@4 | 105 | # If the format is the MoinShare attribute, move it into the |
paul@4 | 106 | # dictionary. |
paul@4 | 107 | |
paul@4 | 108 | if format.lower() == fragment_attribute: |
paul@4 | 109 | attributes[fragment_attribute] = True |
paul@4 | 110 | format = None |
paul@4 | 111 | |
paul@4 | 112 | # Only collect appropriate regions. |
paul@4 | 113 | |
paul@3 | 114 | if attributes.has_key(fragment_attribute): |
paul@4 | 115 | fragments.append((format, attributes, body)) |
paul@2 | 116 | |
paul@2 | 117 | return fragments |
paul@2 | 118 | |
paul@2 | 119 | def getFragments(s): |
paul@2 | 120 | |
paul@2 | 121 | """ |
paul@2 | 122 | Return fragments for the given string 's', each having the form |
paul@2 | 123 | (arguments, body text). |
paul@2 | 124 | """ |
paul@2 | 125 | |
paul@2 | 126 | return getFragmentsFromRegions(getRegions(s)) |
paul@2 | 127 | |
paul@0 | 128 | # vim: tabstop=4 expandtab shiftwidth=4 |