docs: def process_split_position(data, cgi_input, header, reference, var_only=False):
      """Process CGI var where alleles are reported separately.
  
      Split positions report each allele with one or more lines. To ensure that
      we've read through all lines, we end up reading one line beyond.
  
      This function returns data for this position, then handles the remainder
      line by calling itself or process_full_position (as appropriate).
  
      Returns an array containing tuples with five items each:
          (string) chromosome
          (string) start position (1-based)
          (array of strings) matching dbSNP entries
          (string) reference allele sequence
          (array of strings) the genome's allele sequences
      """
      assert data[2] == "1"
      chrom = data[header['chromosome']]
  
      # Get all lines for each allele. Note that this means we'll end up with
      # data from one line ahead stored in 'next_data'; it will be handled at
      # the end.
      s1_data, s2_data, next_data = get_split_pos_lines(
          data=data, cgi_input=cgi_input, header=header)
  
      # Process all the lines to get concatenated sequences and other data.
      dbsnp_data = []
      a1_seq, ref_seq, start, a1_filters = process_allele(
          allele_data=s1_data, dbsnp_data=dbsnp_data,
          header=header, reference=reference)
      a2_seq, r2_seq, a2_start, a2_filters = process_allele(
          allele_data=s2_data, dbsnp_data=dbsnp_data,
          header=header, reference=reference)
      # clean dbsnp data
      dbsnp_data = [x for x in dbsnp_data if x]
      if (a1_seq or ref_seq) and (a2_seq or r2_seq):
          # Check that reference sequence and positions match.
          assert ref_seq == r2_seq
          assert start == a2_start
          if (a1_seq != '?') or (a2_seq != '?'):
              yield {'chrom': chrom,
                     'start': start,
                     'dbsnp_data': dbsnp_data,
                     'ref_seq': ref_seq,
                     'alleles': [a1_seq, a2_seq],
                     'allele_count': '2',
                     'filters': list(set(a1_filters + a2_filters))}
          else:
              # Handle edge case: because we create full no-calls from partial
              # no-call alleles, we may end up with a full no-call region.
              end = str(int(start) + len(ref_seq))
              yield {'chrom': chrom,
                      'start': start,
                      'dbsnp_data': [],
                      'ref_seq': '=',
                      'alleles': ['?'],
                      'allele_count': '2',
                      'filters': ['NOCALL'],
                      'end': end}
  
      # Handle the remaining line. Could recursively call this function if it's
      # the start of a new split position - very unlikely, though.
      if next_data[2] == "all" or next_data[1] == "1":
          out = process_full_position(
              data=next_data, header=header, var_only=var_only)
      else:
          out = process_split_position(
              data=next_data, cgi_input=cgi_input, header=header,
              reference=reference, var_only=var_only)
      if out:
          for entry in out:
              yield entry