docs: def normalize_pdf(layout, scaler):
      """
      Normalizes pdf object coordinates (bot left) to image
      conventions (top left origin).
      Returns the list of chars and average char size
      """
      chars = []
      mentions = []
      height = scaler * layout.height
      font_size_counter = collections.Counter()
      # Lines longer than this are included in segments
      pts_thres = 2.0 * scaler
      segments = []
      curves = []
      figures = []
  
      def processor(m):
          # Normalizes the coordinate system to be consistent with
          # image library conventions (top left as origin)
          if isinstance(m, LTComponent):
              m.set_bbox(normalize_bbox(m.bbox, height, scaler))
  
              if isinstance(m, LTCurve):
                  m.pts = normalize_pts(m.pts, height, scaler)
                  # Only keep longer lines here
                  if isinstance(m, LTLine) and max(m.width, m.height) > pts_thres:
                      segments.append(m)
                      return
                  # Here we exclude straight lines from curves
                  curves.append(m)
                  return
  
              if isinstance(m, LTFigure):
                  figures.append(m)
                  return
  
              # Collect stats on the chars
              if isinstance(m, LTChar):
                  chars.append(m)
                  # fonts could be rotated 90/270 degrees
                  font_size = _font_size_of(m)
                  font_size_counter[font_size] += 1
                  return
  
              if isinstance(m, LTTextLine):
                  mention_text = keep_allowed_chars(m.get_text()).strip()
                  # Skip empty and invalid lines
                  if mention_text:
                      # TODO: add subscript detection and use latex underscore
                      # or superscript
                      m.clean_text = mention_text
                      m.font_name, m.font_size = _font_of_mention(m)
                      mentions.append(m)
                  return
  
          # Also include non character annotations
          if isinstance(m, LTAnno):
              chars.append(m)
  
      traverse_layout(layout, processor)
  
      # Resets mention y0 to the first y0 of alphanum character instead of
      # considering exotic unicode symbols and sub/superscripts to reflect
      # accurate alignment info
      for m in mentions:
          # best_y1 = min(c.y1 for c in m if isinstance(c, LTChar))
          alphanum_c = next((c for c in m if c.get_text().isalnum()), None)
          if alphanum_c:
              m.set_bbox((m.x0, alphanum_c.y0, m.x1, alphanum_c.y1))
  
          #     mentions.sort(key = lambda m: (m.y0,m.x0))
      elems = PDFElems(mentions, segments, curves, figures, layout, chars)
      return elems, font_size_counter