text: #!/bin/env python3
  #
  # Take a source file as input and produce a json file.
  #
  #  make_golden.py < golden_source.txt > golden.json
  #
  
  import json
  import re
  import sys
  from collections import OrderedDict
  
  import precis_i18n.codec  # noqa: F401
  
  PROFILES = [
      'UsernameCasePreserved', 'UsernameCaseMapped', 'OpaqueString',
      'NicknameCaseMapped', 'UsernameCaseMapped:ToLower',
      'NicknameCasePreserved', 'NicknameCaseMapped:ToLower', 'FreeFormClass',
      'IdentifierClass', 'UsernameCaseMapped:CaseFold',
      'NicknameCaseMapped:CaseFold'
  ]
  
  _ANY_PROFILE = re.compile(r'.')
  
  EXCEPTIONS = {
      # ToLower difference before Unicode 8.0. The lower case characters weren't
      # added until Unicode 8.0.
      '\u13da\u13a2\u13b5\u13ac\u13a2\u13ac\u13d2':
      [(re.compile(r'.+CaseMapped(:ToLower)?$'), 8.0)],
      # U+1AB6 was introduced in 7.0.
      '\u05d0\u1ab6\u05d1': [(_ANY_PROFILE, 7.0)],
      # U+0111C9 changed to PVALID in 11.0. It was introduced in 8.0.
      '\U000111c9': [(re.compile(r'^(?:Username.*|IdentifierClass)$'), 11.0),
                     (_ANY_PROFILE, 8.0)],
  
      # U+05EF was introduced in 11.0.
      '\u05EF\u05f3': [(_ANY_PROFILE, 11.0)],
  
      # U+088E, U+0886 were introduced in 14.0.
      '\U00010D00\u200c\u088E': [(_ANY_PROFILE, 14.0)],
      '\U00010D00\u07fd\u200c\u07fd\u088E': [(_ANY_PROFILE, 14.0)],
      '\u0886\u200c\u0886': [(_ANY_PROFILE, 14.0)],
  }
  
  
  def _unescape(value):
      """ Unescape escapes in a python string.
  
      Examples:   \xFF \uFFFF \U0010FFFF \\ \n \t \r
      """
      return value.encode('ascii').decode('unicode_escape')
  
  
  def main():
      """ Produce golden.json file from list of inputs.
      """
  
      # Read list of inputs from ASCII file, and unescape them.
      inputs = ['', '#']
      for line in sys.stdin:
          data = _unescape(line.strip())
          if not data or data[0] == '#':
              continue
          inputs.append(data)
  
      # For each profile, test all the inputs and produce a list of result
      # objects.
      results = []
      for profile in PROFILES:
          for data in inputs:
              unicode_version = None
              # Skip this profile for certain exceptions.
              if data in EXCEPTIONS:
                  for excl in EXCEPTIONS[data]:
                      if excl[0].match(profile):
                          unicode_version = excl[1]
                          break
              try:
                  output = data.encode(profile).decode('utf-8')
                  reason = None
              except UnicodeEncodeError as ex:
                  output = None
                  reason = ex.reason
              elem = OrderedDict([('profile', profile), ('input', data),
                                  ('output', output), ('error', reason)])
              if unicode_version is not None:
                  elem['unicode_version'] = unicode_version
              results.append(elem)
  
      # Save results as an ASCII JSON file. Make sure file ends with LF.
      json.dump(results, sys.stdout, indent=2, ensure_ascii=True)
      sys.stdout.write('\n')
  
  
  if __name__ == '__main__':
      main()
  