class_docstr: Text-editing task.
  
  Attributes:
      source_tokens: Tokens of the source texts concatenated into a single list.
      first_tokens: The indices of the first tokens of each source text.
class_docstr_tok: ["Text-editing","task",".","Attributes",":","source_tokens",":","Tokens","of","the","source","texts","concatenated","into","a","single","list",".","first_tokens",":","The","indices","of","the","first","tokens","of","each","source","text","."]
docstr: Realize output text based on the source tokens and predicted tags.
  
  Args:
      tags: Predicted tags (one for each token in `self.source_tokens`).
      semiotic_labels: Predicted semiotic labels (one for each token in `self.source_tokens`).
  
  Returns:
      The realizer output text.
  
  Raises:
      ValueError: If the number of tags doesn't match the number of source
          tokens.
docstr_tok: ["Realize","output","text","based","on","the","source","tokens","and","predicted","tags",".","Args",":","tags",":","Predicted","tags","(","one","for","each","token","in","`","self.source_tokens","`",")",".","semiotic_labels",":","Predicted","semiotic","labels","(","one","for","each","token","in","`","self.source_tokens","`",")",".","Returns",":","The","realizer","output","text",".","Raises",":","ValueError",":","If","the","number","of","tags","does","n't","match","the","number","of","source","tokens","."]
code: def realize_output(
      self, tags: List[Tag], semiotic_labels: List[str]
  ) -> Tuple[str, str, str, str]:
      """Realize output text based on the source tokens and predicted tags.
  
      Args:
          tags: Predicted tags (one for each token in `self.source_tokens`).
          semiotic_labels: Predicted semiotic labels (one for each token in `self.source_tokens`).
  
      Returns:
          The realizer output text.
  
      Raises:
          ValueError: If the number of tags doesn't match the number of source
              tokens.
      """
      if len(tags) != len(self.source_tokens) or len(tags) != len(
          semiotic_labels
      ):
          raise ValueError(
              "The number of tags ({}) should match the number of "
              "source tokens ({}) and semiotic labels({})".format(
                  len(tags),
                  len(self.source_tokens),
                  len(semiotic_labels),
              )
          )
  
      sequence = []
      for inp_token, tag in zip(self.source_tokens, tags):
          if tag.added_phrase:
              sequence.append(
                  Token(inp_token, tag.added_phrase, tag.added_phrase)
              )
          elif tag.tag_type == TagType.KEEP:
              sequence.append(Token(inp_token, "<SELF>", inp_token))
          else:
              sequence.append(Token(inp_token, "<DELETE>", ""))
      if len(sequence) != len(semiotic_labels):
          raise ValueError(
              "Length mismatch: len(sequence)="
              + str(len(sequence))
              + "; len(semiotic_labels)="
              + str(len(semiotic_labels))
          )
      out_tokens_with_swap = [t.out for t in sequence]
      out_tags_with_swap = [t.tag for t in sequence]
      out_tags_without_swap = [t.tag for t in sequence]
      previous_semiotic_label_end = -1
      current_semiotic_label = ""
      for i in range(len(sequence)):
          if (
              sequence[i].swap == SwapType.SHORT_LEFT
              or sequence[i - 1].swap == SwapType.SHORT_RIGHT
          ):
              out_tokens_with_swap[i - 1], out_tokens_with_swap[i] = (
                  out_tokens_with_swap[i],
                  out_tokens_with_swap[i - 1],
              )
              out_tags_with_swap[i - 1], out_tags_with_swap[i] = (
                  out_tags_with_swap[i],
                  out_tags_with_swap[i - 1],
              )
          if semiotic_labels[i] != current_semiotic_label:
              previous_semiotic_label_end = i - 1
              current_semiotic_label = semiotic_labels[i]
          if sequence[i].swap == SwapType.LONG_LEFT:
              token = out_tokens_with_swap.pop(i)
              tag = out_tags_with_swap.pop(i)
              out_tokens_with_swap.insert(
                  previous_semiotic_label_end + 1, token
              )
              out_tags_with_swap.insert(
                  previous_semiotic_label_end + 1, tag
              )
  
      # detokenize
      output_tokens_str = (
          " ".join(out_tokens_with_swap)
          .replace("<", "")
          .replace(">", "")
      )
      output_tags_with_swap_str = " ".join(out_tags_with_swap)
      frags = re.split(r"(_[^ ][^_]+[^ ]_)", output_tokens_str)
      output_tokens = []
      for frag in frags:
          if frag.startswith("_") and frag.endswith("_"):
              output_tokens.append(
                  frag.replace(" ", "").replace("_", "")
              )
          else:
              output_tokens.append(frag.strip().replace("_", ""))
      output_str = " ".join(output_tokens)
      output_str = re.sub(r" +", " ", output_str)
      return (
          output_str,
          " ".join(self.source_tokens),
          " ".join(out_tags_without_swap),
          output_tags_with_swap_str,
      )
  
imports: import re
  from enum import Enum
  from typing import List, Tuple
  import nemo.collections.nlp.data.text_normalization_as_tagging.utils
label_desc: Use image node_id 2 for calling the EditingTask obj's underlying member method code with example usage: obj.realize_output(tags, semiotic_labels) and returns: output_str,  str,  str,  output_tags_with_swap_str