Attachment 'highlight.py'

Download

   1 #!/usr/bin/python
   2 # -*- coding: utf-8 -*-
   3 
   4 """
   5     MoinMoin - Pygments Parser
   6 
   7     @copyright: 2008 Radomir Dopieralski <moindev@sheep.art.pl>
   8 
   9     @license: GNU GPL, see COPYING for details.
  10 """
  11 
  12 import re
  13 
  14 from MoinMoin.parser._ParserBase import parse_start_step
  15 from MoinMoin.support.python_compatibility import hash_new
  16 from MoinMoin import config, wikiutil
  17 
  18 import pygments
  19 import pygments.util
  20 import pygments.lexers
  21 import pygments.formatter
  22 from pygments.token import Token
  23 
  24 Dependencies = []
  25 extensions = ['.py']
  26 extension_re = re.compile(r'^\*(\..*$)')
  27 for name, short, patterns, mime in pygments.lexers.get_all_lexers():
  28     for pattern in patterns:
  29         m = extension_re.match(pattern)
  30         if m and m.groups(0):
  31             extensions.extend(m.groups(0))
  32 
  33 class PygmentsFormatter(pygments.formatter.Formatter):
  34     line_re = re.compile(r'(\n)')
  35 
  36     def __init__(self, formatter):
  37         pygments.formatter.Formatter.__init__(self)
  38         self.result = []
  39         self.formatter = formatter
  40 
  41     def get_class(self, ttype):
  42         if ttype in Token.Text:
  43             return None
  44         # Reuse existing MoinMoin's class names
  45         elif ttype in Token.Keyword.Constant:
  46             return 'ConsWord'
  47         elif ttype in Token.Keyword:
  48             return 'ResWord'
  49         elif ttype in Token.Name.Builtin:
  50             return 'ResWord'
  51         elif ttype in Token.Name.Constant:
  52             return 'ConsWord'
  53         elif ttype in Token.String.Char:
  54             return 'Char'
  55         elif ttype in Token.String.Escape:
  56             return 'SPChar'
  57         elif ttype in Token.String:
  58             return 'String'
  59         elif ttype in Token.Number:
  60             return 'Number'
  61         elif ttype in Token.Name:
  62             return 'ID'
  63         elif ttype in Token.Comment:
  64             return 'Comment'
  65         else:
  66             # skip tags that have no class defined
  67             return None
  68             # ... or use the token's name when nothing apropriate
  69             # return str(ttype).replace(".", " ")
  70 
  71     def format(self, tokensource, outfile):
  72         line_ready = False
  73         fmt = self.formatter
  74         result = self.result
  75         for ttype, value in tokensource:
  76             class_ = self.get_class(ttype)
  77             if value:
  78                 for line in self.line_re.split(value):
  79                     if not line_ready:
  80                         result.append(fmt.code_line(1))
  81                         line_ready = True
  82                     if line == '\n':
  83                         result.append(fmt.code_line(0))
  84                         line_ready = False
  85                     else:
  86                         if class_:
  87                             result.append(fmt.code_token(1, class_))
  88                         result.append(fmt.text(line))
  89                         if class_:
  90                             result.append(fmt.code_token(0, class_))
  91         result[-2] = ''
  92         result[-1] = ''
  93 #        if line_ready:
  94 #            result.append(fmt.code_line(0))
  95 
  96 class Parser:
  97     parsername = "highlight"
  98     Dependencies = Dependencies
  99     extensions = extensions
 100 
 101     def __init__(self, raw, request, filename=None, **kw):
 102         self.request = request
 103         self.raw = raw.strip('\n')
 104         self.filename = filename
 105         parts = kw.get('format_args', '').split(None)
 106         if parts:
 107             self.syntax = parts[0]
 108         else:
 109             self.syntax = ''
 110         if len(parts) > 1:
 111             params = ''.join(parts[1:])
 112         else:
 113             params = ''
 114         self.show_nums, self.num_start, self.num_step, attrs = parse_start_step(request, params)
 115 
 116     def format(self, formatter):
 117         fmt = PygmentsFormatter(formatter)
 118         fmt.result.append(formatter.div(1, css_class="highlight %s" % self.syntax))
 119         self._code_id = hash_new('sha1', self.raw.encode(config.charset)).hexdigest()
 120         fmt.result.append(formatter.code_area(1, self._code_id, self.parsername, self.show_nums, self.num_start, self.num_step))
 121         if self.filename is not None:
 122             try:
 123                 lexer = pygments.lexers.get_lexer_for_filename(self.filename)
 124             except pygments.util.ClassNotFound:
 125                 fmt.result.append(formatter.text(self.filename))
 126                 lexer = pygments.lexers.TextLexer()
 127         else:
 128             try:
 129                 lexer = pygments.lexers.get_lexer_by_name(self.syntax)
 130             except pygments.util.ClassNotFound:
 131                 fmt.result.append(formatter.text('#!%s\n' % self.syntax))
 132                 lexer = pygments.lexers.TextLexer()
 133         pygments.highlight(self.raw, lexer, fmt)
 134         fmt.result.append(formatter.code_area(0, self._code_id))
 135         fmt.result.append(formatter.div(0))
 136         self.request.write("".join(fmt.result))

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] (2008-10-11 19:04:20, 4.7 KB) [[attachment:highlight.py]]
 All files | Selected Files: delete move to page copy to page

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