docs: def preprocess_cell(self, cell, resources, cell_index):
          """Also extracts attachments"""
          from nbformat.notebooknode import NotebookNode
  
          attach_names = []
  
          # Just move the attachment into an output
  
          for k, attach in cell.get('attachments', {}).items():
              for mime_type in self.extract_output_types:
                  if mime_type in attach:
  
                      if not 'outputs' in cell:
                          cell['outputs'] = []
  
                      o = NotebookNode({
                          'data': NotebookNode({mime_type: attach[mime_type]}),
                          'metadata': NotebookNode({
                              'filenames': {mime_type: k}  # Will get re-written
                          }),
                          'output_type': 'display_data'
                      })
  
                      cell['outputs'].append(o)
  
                      attach_names.append((mime_type, k))
  
          nb, resources = super().preprocess_cell(cell, resources, cell_index)
  
          output_names = list(resources.get('outputs', {}).keys())
  
          if attach_names:
              # We're going to assume that attachments are only on Markdown cells, and Markdown cells
              # can't generate output, so all of the outputs wee added.
  
              # reverse + zip matches the last len(attach_names) elements from output_names
  
              for output_name, (mimetype, an) in zip(reversed(output_names), reversed(attach_names)):
                  # We'll post process to set the final output directory
                  cell.source = re.sub('\(attachment:{}\)'.format(an),
                                       '(__IMGDIR__/{})'.format(output_name), cell.source)
  
          return nb, resources