paul@0 | 1 | # -*- coding: iso-8859-1 -*- |
paul@0 | 2 | """ |
paul@0 | 3 | MoinMoin - MoinContentSupport library |
paul@0 | 4 | |
paul@8 | 5 | @copyright: 2008, 2009, 2010, 2011, 2013 by Paul Boddie <paul@boddie.org.uk> |
paul@0 | 6 | @copyright: 2000-2004 Juergen Hermann <jh@web.de>, |
paul@0 | 7 | 2005-2008 MoinMoin:ThomasWaldmann. |
paul@0 | 8 | @license: GNU GPL (v2 or later), see COPYING.txt for details. |
paul@0 | 9 | """ |
paul@0 | 10 | |
paul@8 | 11 | from MoinSupport import heading_regexp_str |
paul@3 | 12 | from MoinMoin.wikiutil import escape |
paul@3 | 13 | import re |
paul@3 | 14 | |
paul@0 | 15 | __version__ = "0.1" |
paul@0 | 16 | |
paul@3 | 17 | # Regular expressions. |
paul@3 | 18 | |
paul@7 | 19 | hrule_regexp_str = r"^----$" |
paul@7 | 20 | include_regexp_str = r"^\s*<<Include.*?>>$" |
paul@7 | 21 | section_regexp_str = "(" + heading_regexp_str + "|" + hrule_regexp_str + "|" + include_regexp_str + ")" |
paul@7 | 22 | section_regexp = re.compile(section_regexp_str, re.UNICODE | re.MULTILINE) |
paul@6 | 23 | |
paul@8 | 24 | # NOTE: This overlaps with EventAggregator. |
paul@8 | 25 | |
paul@6 | 26 | category_membership_str = ur"^\s*(?:(Category\S+)(?:\s+(Category\S+))*)\s*$" |
paul@6 | 27 | category_membership_regexp = re.compile(category_membership_str, re.MULTILINE | re.UNICODE) |
paul@6 | 28 | category_declarations_regexp = re.compile("^----$\s*" + category_membership_str, re.MULTILINE | re.UNICODE) |
paul@3 | 29 | |
paul@7 | 30 | def getSectionDetails(body, min_level=None, max_level=None): |
paul@3 | 31 | |
paul@3 | 32 | """ |
paul@7 | 33 | Return section details from the given 'body' for headings with the given |
paul@3 | 34 | 'min_level' to 'max_level' range. Specifying None or omitting 'max_level' or |
paul@3 | 35 | 'min_level' removes the appropriate constraint on the range. |
paul@3 | 36 | |
paul@7 | 37 | A list of tuples is returned for each section divider. For headings, the |
paul@7 | 38 | heading text and level number are returned as the first and second elements |
paul@7 | 39 | of each tuple, whereas other section dividers (typically indicating the end |
paul@7 | 40 | of a section) employ None as the first and second elements. The span (start |
paul@7 | 41 | offset and end offset of the divider) is provided as a tuple in the third |
paul@7 | 42 | element of each result tuple. |
paul@3 | 43 | """ |
paul@3 | 44 | |
paul@3 | 45 | headings = [] |
paul@3 | 46 | |
paul@7 | 47 | for match in section_regexp.finditer(body): |
paul@7 | 48 | level = match.group("level") |
paul@7 | 49 | level = level and len(match.group("level")) |
paul@3 | 50 | |
paul@3 | 51 | if (min_level is None or min_level <= level) and \ |
paul@7 | 52 | (max_level is None or level <= max_level) or \ |
paul@7 | 53 | level is None: |
paul@3 | 54 | |
paul@3 | 55 | headings.append((match.group("heading"), level, match.span())) |
paul@3 | 56 | |
paul@3 | 57 | return headings |
paul@3 | 58 | |
paul@4 | 59 | def getCategoryMembership(body): |
paul@4 | 60 | |
paul@4 | 61 | "From the given 'body', return the categories the page belongs to." |
paul@4 | 62 | |
paul@4 | 63 | match = category_membership_regexp.search(body) |
paul@4 | 64 | if match: |
paul@4 | 65 | return [x for x in match.groups() if x] |
paul@4 | 66 | else: |
paul@4 | 67 | return [] |
paul@4 | 68 | |
paul@6 | 69 | def getCategoryDeclarations(body): |
paul@6 | 70 | |
paul@6 | 71 | """ |
paul@6 | 72 | From the given 'body', return the category declaration sections in the page |
paul@6 | 73 | in the form of a list of tuples, each containing a list of categories, the |
paul@6 | 74 | start of the declaration region and the end of the region. |
paul@6 | 75 | """ |
paul@6 | 76 | |
paul@6 | 77 | return [([x for x in match.groups() if x], match.span()) for match in category_declarations_regexp.finditer(body)] |
paul@6 | 78 | |
paul@6 | 79 | def makeCategoryDeclaration(categories): |
paul@4 | 80 | |
paul@4 | 81 | "Return a category declaration string for the given 'categories'." |
paul@4 | 82 | |
paul@4 | 83 | return "\n----\n%s\n" % " ".join(categories) |
paul@4 | 84 | |
paul@0 | 85 | # vim: tabstop=4 expandtab shiftwidth=4 |