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