text: """
  Runs through a reST file looking for old-style literals, and helps replace them
  with new-style references.
  """
  
  import re
  import sys
  import shelve
  
  refre = re.compile(r'``([^`\s]+?)``')
  
  ROLES = (
      'attr',
      'class',
      "djadmin",
      'data',
      'exc',
      'file',
      'func',
      'lookup',
      'meth',
      'mod' ,
      "djadminopt",
      "ref",
      "setting",
      "term",
      "tfilter",
      "ttag",
      
      # special
      "skip"
  )
  
  ALWAYS_SKIP = [
      "NULL",
      "True",
      "False",
  ]
  
  def fixliterals(fname):
      data = open(fname).read()
      
      last = 0
      new = []
      storage = shelve.open("/tmp/literals_to_xref.shelve")
      lastvalues = storage.get("lastvalues", {})
      
      for m in refre.finditer(data):
          
          new.append(data[last:m.start()])
          last = m.end()
          
          line_start = data.rfind("\n", 0, m.start())
          line_end = data.find("\n", m.end())
          prev_start = data.rfind("\n", 0, line_start)
          next_end = data.find("\n", line_end + 1)
          
          # Skip always-skip stuff
          if m.group(1) in ALWAYS_SKIP:
              new.append(m.group(0))
              continue
              
          # skip when the next line is a title
          next_line = data[m.end():next_end].strip()
          if next_line[0] in "!-/:-@[-`{-~" and all(c == next_line[0] for c in next_line):
              new.append(m.group(0))
              continue
          
          sys.stdout.write("\n"+"-"*80+"\n")
          sys.stdout.write(data[prev_start+1:m.start()])
          sys.stdout.write(colorize(m.group(0), fg="red"))
          sys.stdout.write(data[m.end():next_end])
          sys.stdout.write("\n\n")
          
          replace_type = None
          while replace_type is None:
              replace_type = raw_input(
                  colorize("Replace role: ", fg="yellow")
              ).strip().lower()
              if replace_type and replace_type not in ROLES:
                  replace_type = None
          
          if replace_type == "":
              new.append(m.group(0))
              continue
              
          if replace_type == "skip":
              new.append(m.group(0))
              ALWAYS_SKIP.append(m.group(1))
              continue
          
          default = lastvalues.get(m.group(1), m.group(1))
          if default.endswith("()") and replace_type in ("class", "func", "meth"):
              default = default[:-2]        
          replace_value = raw_input(
              colorize("Text <target> [", fg="yellow") + default + colorize("]: ", fg="yellow")
          ).strip()
          if not replace_value: 
              replace_value = default
          new.append(":%s:`%s`" % (replace_type, replace_value))
          lastvalues[m.group(1)] = replace_value
      
      new.append(data[last:])
      open(fname, "w").write("".join(new))
      
      storage["lastvalues"] = lastvalues
      storage.close()
      
  #
  # The following is taken from django.utils.termcolors and is copied here to
  # avoid the dependancy.
  #
  
  
  def colorize(text='', opts=(), **kwargs):
      """
      Returns your text, enclosed in ANSI graphics codes.
  
      Depends on the keyword arguments 'fg' and 'bg', and the contents of
      the opts tuple/list.
  
      Returns the RESET code if no parameters are given.
  
      Valid colors:
          'black', 'red', 'green', 'yellow', 'blue', 'magenta', 'cyan', 'white'
  
      Valid options:
          'bold'
          'underscore'
          'blink'
          'reverse'
          'conceal'
          'noreset' - string will not be auto-terminated with the RESET code
  
      Examples:
          colorize('hello', fg='red', bg='blue', opts=('blink',))
          colorize()
          colorize('goodbye', opts=('underscore',))
          print colorize('first line', fg='red', opts=('noreset',))
          print 'this should be red too'
          print colorize('and so should this')
          print 'this should not be red'
      """
      color_names = ('black', 'red', 'green', 'yellow', 'blue', 'magenta', 'cyan', 'white')
      foreground = dict([(color_names[x], '3%s' % x) for x in range(8)])
      background = dict([(color_names[x], '4%s' % x) for x in range(8)])
  
      RESET = '0'
      opt_dict = {'bold': '1', 'underscore': '4', 'blink': '5', 'reverse': '7', 'conceal': '8'}
  
      text = str(text)
      code_list = []
      if text == '' and len(opts) == 1 and opts[0] == 'reset':
          return '\x1b[%sm' % RESET
      for k, v in kwargs.iteritems():
          if k == 'fg':
              code_list.append(foreground[v])
          elif k == 'bg':
              code_list.append(background[v])
      for o in opts:
          if o in opt_dict:
              code_list.append(opt_dict[o])
      if 'noreset' not in opts:
          text = text + '\x1b[%sm' % RESET
      return ('\x1b[%sm' % ';'.join(code_list)) + text
  
  if __name__ == '__main__':
      try:
          fixliterals(sys.argv[1])
      except (KeyboardInterrupt, SystemExit):
          print