docs: def parse_reaction_table_file(path, f, default_compartment):
      """Parse a tab-separated file containing reaction IDs and properties
  
      The reaction properties are parsed according to the header which specifies
      which property is contained in each column.
      """
  
      context = FilePathContext(path)
  
      for lineno, row in enumerate(csv.DictReader(f, delimiter=str('\t'))):
          if 'id' not in row or row['id'].strip() == '':
              raise ParseError('Expected `id` column in table')
  
          props = {key: value for key, value in iteritems(row) if value != ''}
  
          if 'equation' in props:
              props['equation'] = parse_reaction_equation_string(
                  props['equation'], default_compartment)
  
          mark = FileMark(context, lineno + 2, 0)
          yield ReactionEntry(props, mark)