parts/django/docs/_ext/literals_to_xrefs.py
changeset 69 c6bca38c1cbf
equal deleted inserted replaced
68:5ff1fc726848 69:c6bca38c1cbf
       
     1 """
       
     2 Runs through a reST file looking for old-style literals, and helps replace them
       
     3 with new-style references.
       
     4 """
       
     5 
       
     6 import re
       
     7 import sys
       
     8 import shelve
       
     9 
       
    10 refre = re.compile(r'``([^`\s]+?)``')
       
    11 
       
    12 ROLES = (
       
    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 
       
    34 ALWAYS_SKIP = [
       
    35     "NULL",
       
    36     "True",
       
    37     "False",
       
    38 ]
       
    39 
       
    40 def 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 
       
   115 def 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 
       
   167 if __name__ == '__main__':
       
   168     try:
       
   169         fixliterals(sys.argv[1])
       
   170     except (KeyboardInterrupt, SystemExit):
       
   171         print