class_docstr: Augmenter that apply target word replacement for augmentation.
  Can also be used to generate all possible combinations.
  :param float aug_p: Percentage of word will be augmented. 
  :param int aug_min: Minimum number of word will be augmented.
  :param int aug_max: Maximum number of word will be augmented. If None is passed, number of augmentation is
      calculated via aup_p. If calculated result from aug_p is smaller than aug_max, will use calculated result from
      aug_p. Otherwise, using aug_max.
  :param list reserved_tokens: A list of swappable tokens (a list of list). For example, "FWD", "Fwd" and "FW" 
      are referring to "foward" in email communcation while "Sincerely" and "Best Regards" treated as same 
      meaning. The input should be [["FWD", "Fwd", "FW"], ["Sincerely", "Best Regards"]]. 
  :param bool case_sensitive: Default is True. If True, it will only replace alternative token if all cases are same.
  :param bool generate_all_combinations: Default is False. If True, all the possible combinations of sentences
      possible with reserved_tokens will be returned. 
  :param func tokenizer: Customize tokenization process
  :param func reverse_tokenizer: Customize reverse of tokenization process
  :param str name: Name of this augmenter
  >>> import nlpaug.augmenter.word as naw
  >>> aug = naw.ReservedAug()
code: def substitute(self, data):
      if not data or not data.strip():
          return data
  
      change_seq = 0
      preprocessed_data = self.preprocess(data)
      doc = Doc(preprocessed_data, self.tokenizer(preprocessed_data))
  
      data_lower = data.lower()
  
      aug_idxes = self._get_aug_idxes(doc.get_original_tokens())
      aug_idxes.sort(reverse=True)
  
      tokens = doc.get_original_tokens()
  
      if not aug_idxes:
          if self.include_detail:
              return data, []
          return data
  
      if self.generate_all_combinations:
          assert (
              self.aug_p == 1
          ), "Augmentation probability has to be 1 to genenerate all combinations. Set aug_p=1 in constructor."
  
          candidate_token_list = []
  
          for aug_idx in aug_idxes:
              original_token = doc.get_token(aug_idx).orig_token.token
              if not self.case_sensitive:
                  original_token = original_token.lower()
  
              if original_token in self.reserved_token_dict:
                  candidate_tokens = []
                  for t in self.reserved_tokens[
                      self.reserved_token_dict[original_token]
                  ]:
                      candidate_tokens.append(t)
              elif original_token in self.reserved_phrase_concats:
                  candidate_tokens = []
                  for t in self.reserved_tokens[
                      self.reserved_phrase_dict[original_token]
                  ]:
                      candidate_tokens.append(t)
  
              change_seq += 1
              candidate_token_list.append(
                  (aug_idx, change_seq, candidate_tokens)
              )
  
          generated_combinations = []
          for tokens in self.generate_combinations(
              candidate_token_list
          ):
              inp_doc = doc
              for token in tokens:
                  aug_idx, seq, new_token = token
                  if aug_idx == 0:
                      new_token = self.align_capitalization(
                          original_token, new_token
                      )
                  inp_doc.add_change_log(
                      aug_idx,
                      new_token=new_token,
                      action=Action.SUBSTITUTE,
                      change_seq=self.parent_change_seq + seq,
                  )
  
              augmented_text = self.reverse_tokenizer(
                  doc.get_augmented_tokens()
              )
  
              same_as_original = False
              if self.case_sensitive:
                  same_as_original = augmented_text == data
              else:
                  same_as_original = (
                      augmented_text.lower() == data_lower
                  )
  
              if not same_as_original:
                  if self.include_detail:
                      generated_combinations.append(
                          (augmented_text, doc.get_change_logs())
                      )
                  else:
                      generated_combinations.append(augmented_text)
  
          return generated_combinations
          # return sorted(generated_combinations) # not sorting to speed up
  
      else:
          for aug_idx in aug_idxes:
              original_token = doc.get_token(aug_idx).orig_token.token
              if not self.case_sensitive:
                  original_token = original_token.lower()
  
              if original_token in self.reserved_token_dict:
                  candidate_tokens = []
                  for t in self.reserved_tokens[
                      self.reserved_token_dict[original_token]
                  ]:
                      compare_token = (
                          t.lower() if not self.case_sensitive else t
                      )
                      if compare_token != original_token:
                          candidate_tokens.append(t)
              elif original_token in self.reserved_phrase_concats:
                  candidate_tokens = []
                  for t in self.reserved_tokens[
                      self.reserved_phrase_dict[original_token]
                  ]:
                      compare_token = t.replace(" ", self.CONNECT_TOKEN)
                      compare_token = (
                          compare_token.lower()
                          if not self.case_sensitive
                          else compare_token
                      )
                      if compare_token != original_token:
                          candidate_tokens.append(t)
  
              new_token = self.sample(candidate_tokens, 1)[0]
              if aug_idx == 0:
                  new_token = self.align_capitalization(
                      original_token, new_token
                  )
  
              change_seq += 1
              doc.add_change_log(
                  aug_idx,
                  new_token=new_token,
                  action=Action.SUBSTITUTE,
                  change_seq=self.parent_change_seq + change_seq,
              )
  
          if self.include_detail:
              return (
                  self.reverse_tokenizer(doc.get_augmented_tokens()),
                  doc.get_change_logs(),
              )
          else:
              return self.reverse_tokenizer(doc.get_augmented_tokens())
  
file_path: nlpaug/nlpaug/augmenter/word/reserved.py
imports: import re
  from collections import defaultdict
  from nlpaug.augmenter.word import WordAugmenter
  from nlpaug.util import Action, Doc
label_desc: Use image node_id 5 for calling the ReservedAug obj's underlying member method code with example usage: obj.substitute(data) and returns: data, data, generated_combinations, data,  list, self,  doc, self