PageRenderTime 36ms CodeModel.GetById 17ms app.highlight 16ms RepoModel.GetById 1ms app.codeStats 0ms

/docs/_ext/literals_to_xrefs.py

https://code.google.com/p/mango-py/
Python | 171 lines | 149 code | 15 blank | 7 comment | 15 complexity | 3d63af0317d3bd0587e6b1e3e2907f3b MD5 | raw file
  1"""
  2Runs through a reST file looking for old-style literals, and helps replace them
  3with new-style references.
  4"""
  5
  6import re
  7import sys
  8import shelve
  9
 10refre = re.compile(r'``([^`\s]+?)``')
 11
 12ROLES = (
 13    'attr',
 14    'class',
 15    "djadmin",
 16    'data',
 17    'exc',
 18    'file',
 19    'func',
 20    'lookup',
 21    'meth',
 22    'mod' ,
 23    "djadminopt",
 24    "ref",
 25    "setting",
 26    "term",
 27    "tfilter",
 28    "ttag",
 29    
 30    # special
 31    "skip"
 32)
 33
 34ALWAYS_SKIP = [
 35    "NULL",
 36    "True",
 37    "False",
 38]
 39
 40def fixliterals(fname):
 41    data = open(fname).read()
 42    
 43    last = 0
 44    new = []
 45    storage = shelve.open("/tmp/literals_to_xref.shelve")
 46    lastvalues = storage.get("lastvalues", {})
 47    
 48    for m in refre.finditer(data):
 49        
 50        new.append(data[last:m.start()])
 51        last = m.end()
 52        
 53        line_start = data.rfind("\n", 0, m.start())
 54        line_end = data.find("\n", m.end())
 55        prev_start = data.rfind("\n", 0, line_start)
 56        next_end = data.find("\n", line_end + 1)
 57        
 58        # Skip always-skip stuff
 59        if m.group(1) in ALWAYS_SKIP:
 60            new.append(m.group(0))
 61            continue
 62            
 63        # skip when the next line is a title
 64        next_line = data[m.end():next_end].strip()
 65        if next_line[0] in "!-/:-@[-`{-~" and all(c == next_line[0] for c in next_line):
 66            new.append(m.group(0))
 67            continue
 68        
 69        sys.stdout.write("\n"+"-"*80+"\n")
 70        sys.stdout.write(data[prev_start+1:m.start()])
 71        sys.stdout.write(colorize(m.group(0), fg="red"))
 72        sys.stdout.write(data[m.end():next_end])
 73        sys.stdout.write("\n\n")
 74        
 75        replace_type = None
 76        while replace_type is None:
 77            replace_type = raw_input(
 78                colorize("Replace role: ", fg="yellow")
 79            ).strip().lower()
 80            if replace_type and replace_type not in ROLES:
 81                replace_type = None
 82        
 83        if replace_type == "":
 84            new.append(m.group(0))
 85            continue
 86            
 87        if replace_type == "skip":
 88            new.append(m.group(0))
 89            ALWAYS_SKIP.append(m.group(1))
 90            continue
 91        
 92        default = lastvalues.get(m.group(1), m.group(1))
 93        if default.endswith("()") and replace_type in ("class", "func", "meth"):
 94            default = default[:-2]        
 95        replace_value = raw_input(
 96            colorize("Text <target> [", fg="yellow") + default + colorize("]: ", fg="yellow")
 97        ).strip()
 98        if not replace_value: 
 99            replace_value = default
100        new.append(":%s:`%s`" % (replace_type, replace_value))
101        lastvalues[m.group(1)] = replace_value
102    
103    new.append(data[last:])
104    open(fname, "w").write("".join(new))
105    
106    storage["lastvalues"] = lastvalues
107    storage.close()
108    
109#
110# The following is taken from django.utils.termcolors and is copied here to
111# avoid the dependancy.
112#
113
114
115def colorize(text='', opts=(), **kwargs):
116    """
117    Returns your text, enclosed in ANSI graphics codes.
118
119    Depends on the keyword arguments 'fg' and 'bg', and the contents of
120    the opts tuple/list.
121
122    Returns the RESET code if no parameters are given.
123
124    Valid colors:
125        'black', 'red', 'green', 'yellow', 'blue', 'magenta', 'cyan', 'white'
126
127    Valid options:
128        'bold'
129        'underscore'
130        'blink'
131        'reverse'
132        'conceal'
133        'noreset' - string will not be auto-terminated with the RESET code
134
135    Examples:
136        colorize('hello', fg='red', bg='blue', opts=('blink',))
137        colorize()
138        colorize('goodbye', opts=('underscore',))
139        print colorize('first line', fg='red', opts=('noreset',))
140        print 'this should be red too'
141        print colorize('and so should this')
142        print 'this should not be red'
143    """
144    color_names = ('black', 'red', 'green', 'yellow', 'blue', 'magenta', 'cyan', 'white')
145    foreground = dict([(color_names[x], '3%s' % x) for x in range(8)])
146    background = dict([(color_names[x], '4%s' % x) for x in range(8)])
147
148    RESET = '0'
149    opt_dict = {'bold': '1', 'underscore': '4', 'blink': '5', 'reverse': '7', 'conceal': '8'}
150
151    text = str(text)
152    code_list = []
153    if text == '' and len(opts) == 1 and opts[0] == 'reset':
154        return '\x1b[%sm' % RESET
155    for k, v in kwargs.iteritems():
156        if k == 'fg':
157            code_list.append(foreground[v])
158        elif k == 'bg':
159            code_list.append(background[v])
160    for o in opts:
161        if o in opt_dict:
162            code_list.append(opt_dict[o])
163    if 'noreset' not in opts:
164        text = text + '\x1b[%sm' % RESET
165    return ('\x1b[%sm' % ';'.join(code_list)) + text
166
167if __name__ == '__main__':
168    try:
169        fixliterals(sys.argv[1])
170    except (KeyboardInterrupt, SystemExit):
171        print