docs: def extract(self, name, example):
          ''' Extract keywords from an example path '''
  
          # if pathlib not available do nothing
          if not pathlib:
              return None
  
          # ensure example is a string
          if isinstance(example, pathlib.Path):
              example = str(example)
          assert isinstance(example, six.string_types), 'example file must be a string'
  
          # get the template
          assert name in self.lookup_names(), '{0} must be a valid template name'.format(name)
          template = self.templates[name]
  
          # expand the environment variable
          template = os.path.expandvars(template)
  
          # handle special functions; perform a drop in replacement
          if re.match('%spectrodir', template):
              template = re.sub('%spectrodir', os.environ['BOSS_SPECTRO_REDUX'], template)
          elif re.search('%platedir', template):
              template = re.sub('%platedir', '(.*)/{plateid:0>6}', template)
          elif re.search('%definitiondir', template):
              template = re.sub('%definitiondir', '{designid:0>6}', template)
          if re.search('%plateid6', template):
              template = re.sub('%plateid6', '{plateid:0>6}', template)
  
          # check if template has any brackets
          haskwargs = re.search('[{}]', template)
          if not haskwargs:
              return None
  
          # escape the envvar $ and any dots
          subtemp = template.replace('$', '\\$').replace('.', '\\.')
          # define search pattern; replace all template keywords with regex "(.*)" group
          research = re.sub('{(.*?)}', '(.*)', subtemp)
          # look for matches in template and example
          pmatch = re.search(research, template)
          tmatch = re.search(research, example)
  
          path_dict = {}
          # if example match extract keys and values from the match groups
          if tmatch:
              values = tmatch.groups(0)
              keys = pmatch.groups(0)
              assert len(keys) == len(values), 'pattern and template matches must have same length'
              parts = zip(keys, values)
              # parse into dictionary
              for part in parts:
                  value = part[1]
                  if re.findall('{(.*?)}', part[0]):
                      # get the key name inside the brackets
                      keys = re.findall('{(.*?)}', part[0])
                      # remove the type : designation
                      keys = [k.split(':')[0] for k in keys]
                      # handle double bracket edge cases; remove this when better solution found
                      if len(keys) > 1:
                          if keys[0] == 'dr':
                              # for {dr}{version}
                              drval = re.match('^DR[1-9][0-9]', value).group(0)
                              otherval = value.split(drval)[-1]
                              pdict = {keys[0]: drval, keys[1]: otherval}
                          elif keys[0] in ['rc', 'br', 'filter', 'camrow']:
                              # for {camrow}{camcol}, {filter}{camcol}, {br}{id}, etc
                              pdict = {keys[0]: value[0], keys[1]: value[1:]}
                          else:
                              raise ValueError('This case has not yet been accounted for.')
                          path_dict.update(pdict)
                      else:
                          path_dict[keys[0]] = value
          return path_dict