Attachment 'header.py'

Download

   1 """
   2 MoinMoin header
   3 ===============
   4 
   5 Header represent wiki page header, which include comments, processing
   6 instructions and pragmas. The header parse text and save all valid
   7 header in the text. Headers are accessed like a dict.
   8 
   9 If you want to add custom handling of certain headers, subclass and
  10 add set_xxx methods. The method will be called by the parser for each
  11 found header with that name. To change the default handling of headers,
  12 override setHeader.
  13 
  14 Usage
  15 -----
  16 ::
  17     header = Header(request, text)
  18     # This will triger parsing of text
  19     language = header['language']
  20 
  21 @copyright: 2005 Nir Soffer <nirs@freeshell.org>
  22 @license: GNU GPL, see COPYING for details.
  23 """
  24 
  25 import re
  26 from MoinMoin import i18n
  27 
  28 
  29 class Header(object):
  30     """ Immutable wiki page header
  31 
  32     Header represent the wiki page header, using # to add comments,
  33     processing instructinos and pragmas.
  34     
  35     Header parsing is done lazily, on the first accessor call.
  36     """
  37     # -----------------------------------------------------------------
  38     # Creation 
  39 
  40     def __init__(self, request, text):
  41         self.request = request
  42         self.text = text
  43         self._headers = None
  44         self._length = None
  45     
  46     # -----------------------------------------------------------------
  47     # Accessing
  48 
  49     # Header is accessed like a dict - save a lot of getter methods.
  50     
  51     def __getitem__(self, key):
  52         """ dict style obj[key] handler """
  53         return self.headers()[key]
  54 
  55     def get(self, key, default=None):
  56         """ dict style obj.get(key) handler """
  57         return self.headers().get(key, default)
  58 
  59     def __contains__(self, key):
  60         """ in obj handler """
  61         return key in self.headers()
  62     
  63     def length(self):
  64         """ Return length of page header - not number of headers
  65 
  66         Calculate by looking for the first character of the body.
  67         
  68         Used internally to do eficient parsing, and may be used by other
  69         to get only the body part of a page text.
  70         """
  71         if self._length is None:
  72             match = self.bodyPattern().search(self.text)
  73             if match:
  74                 self._length = match.start()
  75             else:
  76                 # No body, all header
  77                 self._length = len(self.text)
  78         return self._length
  79 
  80     # -----------------------------------------------------------------
  81     # Private
  82 
  83     # Methods here are private, but does not use the _convetion, becasue
  84     # it is less readable.
  85     
  86     def headers(self):
  87         """ Return headers dict, trigger parsing """
  88         if self._headers is None:
  89             self.parse()
  90         return self._headers
  91 
  92     def parse(self):
  93         """ Start parsing, triggered automatically """
  94         self._headers = {}
  95         for line in self.text[:self.length()].splitlines():
  96             if line.startswith('##'):
  97                 continue
  98             key, value = self.splitTokens(line[1:]) 
  99             setter = getattr(self, 'set_' + key, None)
 100             if setter:
 101                 setter(value)
 102             else:
 103                 self.setHeader(key, value)
 104 
 105     def set_acl(self, value):
 106         """ Save all acl lines in a list """
 107         try:
 108             self._headers['acl'].append(value)
 109         except KeyError:
 110             self._headers['acl'] = [value]
 111     
 112     def set_language(self, value):
 113         """ Save known languages, ignore other """
 114         if value in i18n.wikiLanguages():
 115             self.setHeader('language', value)
 116 
 117     def set_cite(self, value):
 118         """ Save source for blockquote parser """
 119         self.setHeader('cite', value)
 120             
 121     def set_pragma(self, text):
 122         """ Save pragmas, ignore invalid pragmas """
 123         key, value = self.splitTokens(text)
 124         if value:
 125             try:
 126                 self._headers['pragma'][key] = value
 127             except KeyError:
 128                 self._headers['pragma'] = {key: value}
 129                                                                 
 130     def setHeader(self, key, value):
 131         """ Set header value, last value override """
 132         self._headers[key] = value    
 133     
 134     def splitTokens(self, text):
 135         """ Split first two tokens in text by whitespace """
 136         try:
 137             key, value = text.split(None, 1)
 138             value = value.rstrip()
 139             return key, value
 140         except ValueError:
 141             return text, ''
 142 
 143     def bodyPattern(self):
 144         """ Return shared compiled regular expression """
 145         myClass = self.__class__
 146         if not getattr(myClass, '_bodyPattern', False):
 147             # Does not starts with # or empty (invalid) pi
 148             myClass._bodyPattern = re.compile(r"^[^\#]|^\#\s",
 149                                               re.MULTILINE | re.UNICODE)
 150         return myClass._bodyPattern

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] (2007-02-08 23:13:48, 0.7 KB) [[attachment:common.css]]
  • [get | view] (2009-10-12 14:36:42, 4.8 KB) [[attachment:header.py]]
  • [get | view] (2009-10-12 14:36:39, 3.2 KB) [[attachment:quote.py]]
  • [get | view] (2007-02-08 23:13:31, 3.1 KB) [[attachment:quote.zip]]
  • [get | view] (2007-02-08 23:11:02, 57.9 KB) [[attachment:screenshot.jpg]]
 All files | Selected Files: delete move to page copy to page

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