class_docstr: Process Paragraph blocks. 
class_docstr_tok: ["Process","Paragraph","blocks","."]
code: def run(self, parent: etree.Element, blocks: list[str]) -> None:
      block = blocks.pop(0)
      if block.strip():
          # Not a blank block. Add to parent, otherwise throw it away.
          if self.parser.state.isstate("list"):
              # The parent is a tight-list.
              #
              # Check for any children. This will likely only happen in a
              # tight-list when a header isn't followed by a blank line.
              # For example:
              #
              #     * # Header
              #     Line 2 of list item - not part of header.
              sibling = self.lastChild(parent)
              if sibling is not None:
                  # Insert after sibling.
                  if sibling.tail:
                      sibling.tail = "{}\n{}".format(
                          sibling.tail, block
                      )
                  else:
                      sibling.tail = "\n%s" % block
              else:
                  # Append to parent.text
                  if parent.text:
                      parent.text = "{}\n{}".format(parent.text, block)
                  else:
                      parent.text = block.lstrip()
          else:
              # Create a regular paragraph
              p = etree.SubElement(parent, "p")
              p.text = block.lstrip()
  
imports: from __future__ import annotations
  import logging
  import re
  import xml.etree.ElementTree
  from typing import TYPE_CHECKING, Any
  from .None import util
  from .blockparser import BlockParser
label_desc: Use image node_id 2 for calling the ParagraphProcessor obj's underlying member method code with example usage: obj.run(parent, blocks) without return types