code: def generate_hocr(
      *,
      input_file: Path,
      output_hocr: Path,
      output_text: Path,
      languages: list[str],
      engine_mode: int,
      tessconfig: list[str],
      timeout: float,
      pagesegmode: int,
      thresholding: int,
      user_words,
      user_patterns,
  ) -> None:
      """Generate a hOCR file, which must be converted to PDF."""
      prefix = output_hocr.with_suffix("")
  
      args_tesseract = tess_base_args(languages, engine_mode)
  
      if pagesegmode is not None:
          args_tesseract.extend(["--psm", str(pagesegmode)])
  
      if thresholding != 0 and has_thresholding():
          args_tesseract.extend(
              ["-c", f"thresholding_method={thresholding}"]
          )
  
      if user_words:
          args_tesseract.extend(["--user-words", user_words])
  
      if user_patterns:
          args_tesseract.extend(["--user-patterns", user_patterns])
  
      # Reminder: test suite tesseract test plugins will break after any changes
      # to the number of order parameters here
      args_tesseract.extend(
          [fspath(input_file), fspath(prefix), "hocr", "txt"]
      )
      args_tesseract.extend(tessconfig)
      try:
          p = run(
              args_tesseract,
              stdout=PIPE,
              stderr=STDOUT,
              timeout=timeout,
              check=True,
          )
          stdout = p.stdout
      except TimeoutExpired:
          # Generate a HOCR file with no recognized text if tesseract times out
          # Temporary workaround to hocrTransform not being able to function if
          # it does not have a valid hOCR file.
          page_timedout(timeout)
          _generate_null_hocr(output_hocr, output_text, input_file)
      except CalledProcessError as e:
          tesseract_log_output(e.output)
          if (
              b"Image too large" in e.output
              or b"Empty page!!" in e.output
          ):
              _generate_null_hocr(output_hocr, output_text, input_file)
              return
  
          raise SubprocessOutputError() from e
      else:
          tesseract_log_output(stdout)
          # The sidecar text file will get the suffix .txt; rename it to
          # whatever caller wants it named
          with suppress(FileNotFoundError):
              prefix.with_suffix(".txt").replace(output_text)
  
imports: from __future__ import annotations
  import logging
  import re
  from contextlib import suppress
  from math import pi
  from os import fspath
  from pathlib import Path
  from subprocess import PIPE, STDOUT, CalledProcessError, TimeoutExpired
  from packaging.version import Version
  from ocrmypdf.exceptions import MissingDependencyError, SubprocessOutputError, TesseractConfigError
  from ocrmypdf.pluginspec import OrientationConfidence
  from ocrmypdf.subprocess import get_version, run
label_desc: Use image node_id 11 for calling a global function with example usage: generate_hocr() without return types