docs: def parse(self, s, term_join=None):
          """ Parses search term to
  
          Args:
              s (str): string with search term.
              or_join (callable): function to join 'OR' terms.
  
          Returns:
              dict: all of the terms grouped by marker. Key is a marker, value is a term.
  
          Example:
              >>> SearchTermParser().parse('table2 from 1978 to 1979 in california')
              {'to': 1979, 'about': 'table2', 'from': 1978, 'in': 'california'}
          """
  
          if not term_join:
              term_join = lambda x: '(' + ' OR '.join(x) + ')'
  
          toks = self.scan(s)
  
          # Examples: starting with this query:
          # diabetes from 2014 to 2016 source healthindicators.gov
  
          # Assume the first term is ABOUT, if it is not marked with a marker.
          if toks and toks[0] and (toks[0][0] == self.TERM or toks[0][0] == self.QUOTEDTERM):
              toks = [(self.MARKER, 'about')] + toks
  
  
          # The example query produces this list of tokens:
          #[(3, 'about'),
          # (0, 'diabetes'),
          # (3, 'from'),
          # (4, 2014),
          # (3, 'to'),
          # (4, 2016),
          # (3, 'source'),
          # (0, 'healthindicators.gov')]
  
          # Group the terms by their marker.
  
          bymarker = []
          for t in toks:
              if t[0] == self.MARKER:
                  bymarker.append((t[1], []))
              else:
                  bymarker[-1][1].append(t)
  
  
          # After grouping tokens by their markers
          # [('about', [(0, 'diabetes')]),
          # ('from', [(4, 2014)]),
          # ('to', [(4, 2016)]),
          # ('source', [(0, 'healthindicators.gov')])
          # ]
  
          # Convert some of the markers based on their contents. This just changes the marker type for keywords
          # we'll do more adjustments later.
          comps = []
          for t in bymarker:
  
              t = list(t)
  
              if t[0] == 'in' and len(t[1]) == 1 and isinstance(t[1][0][1], string_types) and self.stem(
                      t[1][0][1]) in self.geograins.keys():
                  t[0] = 'by'
  
              # If the from term isn't an integer, then it is really a source.
              if t[0] == 'from' and len(t[1]) == 1 and t[1][0][0] != self.YEAR:
                  t[0] = 'source'
  
              comps.append(t)
  
          # After conversions
          # [['about', [(0, 'diabetes')]],
          #  ['from', [(4, 2014)]],
          #  ['to', [(4, 2016)]],
          #  ['source', [(0, 'healthindicators.gov')]]]
  
          # Join all of the terms into single marker groups
          groups = {marker: [] for marker, _ in comps}
  
          for marker, terms in comps:
              groups[marker] += [term for marker, term in terms]
  
          # At this point, the groups dict is formed, but it will have a list
          # for each marker that has multiple terms.
  
          # Only a few of the markers should have more than one term, so move
          # extras to the about group
  
          for marker, group in groups.items():
  
              if marker == 'about':
                  continue
  
              if len(group) > 1 and marker not in self.multiterms:
                  groups[marker], extras = [group[0]], group[1:]
  
                  if not 'about' in groups:
                      groups['about'] = extras
                  else:
                      groups['about'] += extras
  
              if marker == 'by':
                  groups['by'] = [ self.geograins.get(self.stem(e)) for e in group]
  
          for marker, terms in iteritems(groups):
  
              if len(terms) > 1:
                  if marker in 'in':
                      groups[marker] = ' '.join(terms)
                  else:
                      groups[marker] = term_join(terms)
              elif len(terms) == 1:
                  groups[marker] = terms[0]
              else:
                  pass
  
          # After grouping:
          # {'to': 2016,
          #  'about': 'diabetes',
          #  'from': 2014,
          #  'source': 'healthindicators.gov'}
  
          # If there were any markers with multiple terms, they would be cast in the or_join form.
  
  
          return groups