docs: def main(args):
      '''
      surface_to_rubbon.main(args) can be given a list of arguments, such as sys.argv[1:]; these
      arguments may include any options and must include exactly one subject id and one output
      filename. Additionally one or two surface input filenames must be given. The surface files are
      projected into the ribbon and written to the output filename. For more information see the
      string stored in surface_to_image.info.
      '''
      # Parse the arguments
      (args, opts) = _surface_to_ribbon_parser(args)
      # First, help?
      if opts['help']:
          print(info, file=sys.stdout)
          return 1
      # and if we are verbose, lets setup a note function
      verbose = opts['verbose']
      def note(s):
          if verbose: print(s, file=sys.stdout)
          return verbose
      # Add the subjects directory, if there is one
      if 'subjects_dir' in opts and opts['subjects_dir'] is not None:
          add_subject_path(opts['subjects_dir'])
      # figure out our arguments:
      (lhfl, rhfl) = (opts['lh_file'], opts['rh_file'])
      if len(args) == 0:
        raise ValueError('Not enough arguments provided!')
      elif len(args) == 1:
        # must be that the subject is in the env?
        sub = find_subject_path(os.getenv('SUBJECT'))
        outfl = args[0]
      elif len(args) == 2:
        sbpth = find_subject_path(args[0])
        if sbpth is not None:
          sub = sbpth
        else:
          sub = find_subject_path(os.getenv('SUBJECT'))
          if lhfl is not None: rhfl = args[0]
          elif rhfl is not None: lhfl = args[0]
          else: raise ValueError('Given arg is not a subject: %s' % args[0])
        outfl = args[1]
      elif len(args) == 3:
        sbpth0 = find_subject_path(args[0])
        sbpth1 = find_subject_path(args[1])
        if sbpth0 is not None:
          sub = sbpth0
          if lhfl is not None: rhfl = args[1]
          elif rhfl is not None: lhfl = args[1]
          else: raise ValueError('Too many arguments given: %s' % args[1])
        elif sbpth1 is not None:
          sub = sbpth1
          if lhfl is not None: rhfl = args[0]
          elif rhfl is not None: lhfl = args[0]
          else: raise ValueError('Too many arguments given: %s' % args[0])
        else:
          sub = find_subject_path(os.getenv('SUBJECT'))
          if lhfl is not None or rhfl is not None:
            raise ValueError('Too many arguments and no subject given')
          (lhfl, rhfl) = args
        outfl = args[2]
      elif len(args) == 4:
        if lhfl is not None or rhfl is not None:
            raise ValueError('Too many arguments and no subject given')
        subidx = next((i for (i,a) in enumerate(args) if find_subject_path(a) is not None), None)
        if subidx is None: raise ValueError('No subject given')
        sub = find_subject_path(args[subidx])
        del args[subidx]
        (lhfl, rhfl, outfl) = args
      else:
        raise ValueError('Too many arguments provided!')
      if sub is None: raise ValueError('No subject specified or found in $SUBJECT')
      if lhfl is None and rhfl is None: raise ValueError('No surfaces provided')
      # check the method
      method = opts['method'].lower()
      if method not in ['linear', 'lines', 'nearest', 'auto']:
          raise ValueError('Unsupported method: %s' % method)
      # and the datatype
      if opts['dtype'] is None: dtyp = None
      elif opts['dtype'].lower() == 'float': dtyp = np.float32
      elif opts['dtype'].lower() == 'int': dtyp = np.int32
      else: raise ValueError('Type argument must be float or int')
      if method == 'auto':
        if dtyp is np.float32: method = 'linear'
        elif dtyp is np.int32: method = 'nearest'
        else: method = 'linear'
      # Now, load the data:
      note('Reading surfaces...')
      (lhdat, rhdat) = (None, None)
      if lhfl is not None:
          note('   - Reading LH file: %s' % lhfl)
          lhdat = read_surf_file(lhfl)
      if rhfl is not None:
          note('   - Reading RH file: %s' % rhfl)
          rhdat = read_surf_file(rhfl)
      (dat, hemi) = (rhdat, 'rh') if lhdat is None else \
                    (lhdat, 'lh') if rhdat is None else \
                    ((lhdat, rhdat), None)
      sub = subject(sub)
      # okay, make the volume...
      note('Generating volume...')
      vol = sub.cortex_to_image(dat, hemi=hemi, method=method, fill=opts['fill'], dtype=dtyp)
      # and write out the file
      note('Exporting volume file: %s' % outfl)
      save(outfl, vol, affine=sub.voxel_to_native_matrix)
      note('surface_to_image complete!')
      return 0