1.1 --- a/MoinContentSupport.py Sat Feb 26 21:45:56 2011 +0100
1.2 +++ b/MoinContentSupport.py Sun Sep 11 18:50:16 2011 +0200
1.3 @@ -16,30 +16,40 @@
1.4 # Regular expressions.
1.5 # NOTE: These overlap with ImprovedMoinSearch and EventAggregator.
1.6
1.7 -heading_regexp = re.compile(r"^(?P<level>=+)\s*(?P<heading>.*?)\s*(?P=level)$", re.UNICODE | re.MULTILINE)
1.8 +heading_regexp_str = r"^(?P<level>=+)\s*(?P<heading>.*?)\s*(?P=level)$"
1.9 +hrule_regexp_str = r"^----$"
1.10 +include_regexp_str = r"^\s*<<Include.*?>>$"
1.11 +section_regexp_str = "(" + heading_regexp_str + "|" + hrule_regexp_str + "|" + include_regexp_str + ")"
1.12 +section_regexp = re.compile(section_regexp_str, re.UNICODE | re.MULTILINE)
1.13
1.14 category_membership_str = ur"^\s*(?:(Category\S+)(?:\s+(Category\S+))*)\s*$"
1.15 category_membership_regexp = re.compile(category_membership_str, re.MULTILINE | re.UNICODE)
1.16 category_declarations_regexp = re.compile("^----$\s*" + category_membership_str, re.MULTILINE | re.UNICODE)
1.17
1.18 -def getHeadingDetails(body, min_level=None, max_level=None):
1.19 +def getSectionDetails(body, min_level=None, max_level=None):
1.20
1.21 """
1.22 - Return heading details from the given 'body' for headings with the given
1.23 + Return section details from the given 'body' for headings with the given
1.24 'min_level' to 'max_level' range. Specifying None or omitting 'max_level' or
1.25 'min_level' removes the appropriate constraint on the range.
1.26
1.27 - A list of tuples containing the heading, the level, and the span (the start
1.28 - offset and the end offset as a tuple) is returned.
1.29 + A list of tuples is returned for each section divider. For headings, the
1.30 + heading text and level number are returned as the first and second elements
1.31 + of each tuple, whereas other section dividers (typically indicating the end
1.32 + of a section) employ None as the first and second elements. The span (start
1.33 + offset and end offset of the divider) is provided as a tuple in the third
1.34 + element of each result tuple.
1.35 """
1.36
1.37 headings = []
1.38
1.39 - for match in heading_regexp.finditer(body):
1.40 - level = len(match.group("level"))
1.41 + for match in section_regexp.finditer(body):
1.42 + level = match.group("level")
1.43 + level = level and len(match.group("level"))
1.44
1.45 if (min_level is None or min_level <= level) and \
1.46 - (max_level is None or level <= max_level):
1.47 + (max_level is None or level <= max_level) or \
1.48 + level is None:
1.49
1.50 headings.append((match.group("heading"), level, match.span()))
1.51
2.1 --- a/actions/SectionBreakout.py Sat Feb 26 21:45:56 2011 +0100
2.2 +++ b/actions/SectionBreakout.py Sun Sep 11 18:50:16 2011 +0200
2.3 @@ -33,7 +33,7 @@
2.4 # Acquire heading details from the page.
2.5
2.6 body = page.get_raw_body()
2.7 - heading_details = getHeadingDetails(body, level, level)
2.8 + heading_details = getSectionDetails(body, level, level)
2.9
2.10 d = {
2.11 "buttons_html" : buttons_html,
2.12 @@ -55,7 +55,8 @@
2.13 <td>''' % d
2.14
2.15 for heading, level, span in heading_details:
2.16 - html += "%s<br />" % heading
2.17 + if heading is not None:
2.18 + html += "%s<br />" % escape(heading)
2.19
2.20 html += '''
2.21 </td>
2.22 @@ -122,25 +123,36 @@
2.23 regions = []
2.24 current_region_start = None
2.25
2.26 - for heading, found_level, (start, end) in getHeadingDetails(page_body):
2.27 + for heading, found_level, (start, end) in getSectionDetails(page_body):
2.28
2.29 - # Upon finding a suitable heading, begin a new region to be broken
2.30 - # out.
2.31 + # Where a heading is provided, consider starting a section.
2.32 +
2.33 + if found_level is not None:
2.34
2.35 - if current_region_start is None and found_level >= level:
2.36 - current_region_start = heading, start
2.37 + # Upon finding a suitable heading, begin a new region to be broken
2.38 + # out.
2.39
2.40 - # Upon finding a higher-level heading, end any open region.
2.41 + if current_region_start is None and found_level >= level:
2.42 + current_region_start = heading, start
2.43 +
2.44 + # Upon finding a same-level or higher-level heading, end any open
2.45 + # region.
2.46
2.47 - elif current_region_start is not None and found_level <= level:
2.48 - regions.append(current_region_start + (start,))
2.49 + elif current_region_start is not None and found_level <= level:
2.50 + regions.append(current_region_start + (start,))
2.51
2.52 - # For headings at the requested level, open a new region.
2.53 + # For headings at the requested level, open a new region.
2.54
2.55 - if found_level == level:
2.56 - current_region_start = heading, start
2.57 - else:
2.58 - current_region_start = None
2.59 + if found_level == level:
2.60 + current_region_start = heading, start
2.61 + else:
2.62 + current_region_start = None
2.63 +
2.64 + # Where no heading is provided, end the section.
2.65 +
2.66 + elif current_region_start is not None:
2.67 + regions.append(current_region_start + (start,))
2.68 + current_region_start = None
2.69
2.70 # End any open region.
2.71