code: def page_get_textblocks(infile, pageno, xmltext, height):
      
  
      root = xmltext
      if not hasattr(xmltext, 'findall'):
          return []
  
      def blocks():
          for span in root.findall('.//span'):
              bbox_str = span.attrib['bbox']
              font_size = span.attrib['size']
              pts = [int(pt) for pt in bbox_str.split()]
              pts[1] = pts[1] - int(float(font_size) + 0.5)
              bbox_topdown = tuple(pts)
              bb = bbox_topdown
              bbox_bottomup = (bb[0], height - bb[3], bb[2], height - bb[1])
              yield bbox_bottomup
  
      def joined_blocks():
          prev = None
          for bbox in blocks():
              if prev is None:
                  prev = bbox
              if bbox[1] == prev[1] and bbox[3] == prev[3]:
                  gap = prev[2] - bbox[0]
                  height = abs(bbox[3] - bbox[1])
                  if gap < height:
                      # Join boxes
                      prev = (prev[0], prev[1], bbox[2], bbox[3])
                      continue
              # yield previously joined bboxes and start anew
              yield prev
              prev = bbox
          if prev is not None:
              yield prev
  
      return [block for block in joined_blocks()]
docs: Get text boxes out of Ghostscript txtwrite xml