text: """
  Module containing a preprocessor that removes cells if they match
  one or more regular expression.
  """
  
  # Copyright (c) IPython Development Team.
  # Distributed under the terms of the Modified BSD License.
  
  from traitlets import Set, Unicode
  from . import ClearOutputPreprocessor
  
  
  class TagRemovePreprocessor(ClearOutputPreprocessor):
      """
      Removes cells from a notebook that have tags that designate they are to be
      removed prior to exporting the notebook.
  
      Traitlets:
      ----------
      remove_cell_tags: removes cells tagged with these values
      remove_all_output_tags: removes entire output areas on cells
                              tagged with these values
      remove_single_output_tags: removes individual output objects on
                                 outputs tagged with these values
  
      """
  
      remove_cell_tags = Set(Unicode, default_value=[],
              help=("Tags indicating which cells are to be removed,"
                    "matches tags in `cell.metadata.tags`.")).tag(config=True)
      remove_all_outputs_tags = Set(Unicode, default_value=[],
              help=("Tags indicating cells for which the outputs are to be removed,"
                    "matches tags in `cell.metadata.tags`.")).tag(config=True)
      remove_single_output_tags = Set(Unicode, default_value=[],
              help=("Tags indicating which individual outputs are to be removed,"
                    "matches output *i* tags in `cell.outputs[i].metadata.tags`.")
              ).tag(config=True)
      remove_input_tags = Set(Unicode, default_value=[],
              help=("Tags indicating cells for which input is to be removed,"
                    "matches tags in `cell.metadata.tags`.")).tag(config=True)
  
  
      def check_cell_conditions(self, cell, resources, index):
          """
          Checks that a cell has a tag that is to be removed
  
          Returns: Boolean.
          True means cell should *not* be removed.
          """
  
          # Return true if any of the tags in the cell are removable.
          return not self.remove_cell_tags.intersection(
                  cell.get('metadata', {}).get('tags', []))
  
      def preprocess(self, nb, resources):
          """
          Preprocessing to apply to each notebook. See base.py for details.
          """
          # Skip preprocessing if the list of patterns is empty
          if not any([self.remove_cell_tags,
                      self.remove_all_outputs_tags,
                      self.remove_single_output_tags,
                      self.remove_input_tags
                      ]):
              return nb, resources
  
          # Filter out cells that meet the conditions
          nb.cells = [self.preprocess_cell(cell, resources, index)[0]
                      for index, cell in enumerate(nb.cells)
                      if self.check_cell_conditions(cell, resources, index)]
  
          return nb, resources
  
      def preprocess_cell(self, cell, resources, cell_index):
          """
          Apply a transformation on each cell. See base.py for details.
          """
          
          if (self.remove_all_outputs_tags.intersection(
              cell.get('metadata', {}).get('tags', []))
              and cell.cell_type == 'code'):
  
              cell.outputs = []
              cell.execution_count = None
              # Remove metadata associated with output
              if 'metadata' in cell:
                  for field in self.remove_metadata_fields:
                      cell.metadata.pop(field, None)
          
          if (self.remove_input_tags.intersection(
                  cell.get('metadata', {}).get('tags', []))):
              cell.transient = {
                  'remove_source': True
                  }
  
          if cell.get('outputs', []):
              cell.outputs = [output
                              for output_index, output in enumerate(cell.outputs)
                              if self.check_output_conditions(output,
                                                              resources,
                                                              cell_index,
                                                              output_index)
                              ]
          return cell, resources
  
      def check_output_conditions(self, output, resources,
                                  cell_index, output_index):
          """
          Checks that an output has a tag that indicates removal.
  
          Returns: Boolean.
          True means output should *not* be removed.
          """
          return not self.remove_single_output_tags.intersection(
                  output.get('metadata', {}).get('tags', []))
  