Ticket #85: ShellExample.py

File ShellExample.py, 2.0 KB (added by goozbach, 8 years ago)

improved ShellExample preprocessor

Line 
1"""Preprocessor Highlight ShellExample."""
2from trac.util import escape
3import re
4
5regex_crlf = re.compile("(\\r\\n|\\r|\\n)")
6regexp_db_qstr = '"[^"\\\\]*(?:\\\\.[^"\\\\]*){0,250}"';
7regexp_si_qstr = '\'[^\'\\\\]*(?:\\\\.[^\'\\\\]*){0,250}\'';
8regexp = re.compile(
9        ('^(?P<path>[^ ]+.*)?(?P<cli>[#$]|&gt; )(?P<input>(?:[^\\\\\n\'"]+|\\\\\n|%s|%s|[\\\\\'"]){0,255})$' % (regexp_db_qstr, regexp_si_qstr)) +
10        '|^(?P<option_space>\s+)(?P<option>-[a-zA-Z0-9]\\b|--[^ \t\n]+)(?P<option_desc>.*)$'
11        '|^(?P<note>\(.*\))$'
12        , re.M)
13regexp_string = re.compile('(?:%s|%s)' % (regexp_db_qstr, regexp_si_qstr))
14def execute(hdf, txt, env):
15    # args will be null if the macro is called without parenthesis.
16    css = ''
17    if hdf:
18        if not hdf.has_key("macro.ShellExample.outputcss"):
19            hdf["macro.ShellExample.outputcss"] = True
20            css = '''<style type="text/css">
21.code-input          {color:blue}
22.code-input          {color:blue}
23.code-root           {color:red;}
24.code-note           {color:#d80000;}
25.code-path, .code-user {color:#449999; font-weight: bold}
26</style>'''
27    txt = txt and regex_crlf.sub("\n", escape(txt).replace('&#34;', '"')) or ''
28    def stringcallback(match):
29        return '<span class="code-string">' + match.group(0) + '</span>'
30
31    def callback(match):
32        m = match.group('cli')
33        if m:
34            path = match.group('path')
35            if path:
36                line = '<span class="code-path">' + path + '</span>'
37            else:
38                line = ''
39
40            input = regexp_string.sub(stringcallback, match.group('input'))
41            input = '<span class="code-input">' + input + '</span>'
42            if m == '# ':
43                line = line + '<span class="code-root">' + m + input + '</span>'
44            else:
45                line = line + '<span class="code-user">' + m + input + '</span>'
46            return line
47        m = match.group('option')
48        if m:
49            space = match.group('option_space')
50            desc  = match.group('option_desc')
51            return space + '<span class="code-func">' + m + '</span>' + desc
52        m = match.group('note')
53        if m:
54            return '<span class="code-note">' + m + '</span>'
55        return match.group(0)
56    return css + '<div class="code"><pre>' + regexp.sub(callback, txt)+ '</pre></div>';