code: def main():
      """Define command configurations."""
      parser = argparse.ArgumentParser(
          prog="fitz",
          description=mycenter("Basic PyMuPDF Functions"),
      )
      subps = parser.add_subparsers(
          title="Subcommands",
          help="Enter 'command -h' for subcommand specific help",
      )
  
      # -------------------------------------------------------------------------
      # 'show' command
      # -------------------------------------------------------------------------
      ps_show = subps.add_parser(
          "show", description=mycenter("display PDF information")
      )
      ps_show.add_argument("input", type=str, help="PDF filename")
      ps_show.add_argument("-password", help="password")
      ps_show.add_argument(
          "-catalog", action="store_true", help="show PDF catalog"
      )
      ps_show.add_argument(
          "-trailer", action="store_true", help="show PDF trailer"
      )
      ps_show.add_argument(
          "-metadata", action="store_true", help="show PDF metadata"
      )
      ps_show.add_argument(
          "-xrefs",
          type=str,
          help="show selected objects, format: 1,5-7,N",
      )
      ps_show.add_argument(
          "-pages",
          type=str,
          help="show selected pages, format: 1,5-7,50-N",
      )
      ps_show.set_defaults(func=show)
  
      # -------------------------------------------------------------------------
      # 'clean' command
      # -------------------------------------------------------------------------
      ps_clean = subps.add_parser(
          "clean",
          description=mycenter(
              "optimize PDF, or create sub-PDF if pages given"
          ),
      )
      ps_clean.add_argument("input", type=str, help="PDF filename")
      ps_clean.add_argument(
          "output", type=str, help="output PDF filename"
      )
      ps_clean.add_argument("-password", help="password")
  
      ps_clean.add_argument(
          "-encryption",
          help="encryption method",
          choices=(
              "keep",
              "none",
              "rc4-40",
              "rc4-128",
              "aes-128",
              "aes-256",
          ),
          default="none",
      )
  
      ps_clean.add_argument("-owner", type=str, help="owner password")
      ps_clean.add_argument("-user", type=str, help="user password")
  
      ps_clean.add_argument(
          "-garbage",
          type=int,
          help="garbage collection level",
          choices=range(5),
          default=0,
      )
  
      ps_clean.add_argument(
          "-compress",
          action="store_true",
          default=False,
          help="compress (deflate) output",
      )
  
      ps_clean.add_argument(
          "-ascii",
          action="store_true",
          default=False,
          help="ASCII encode binary data",
      )
  
      ps_clean.add_argument(
          "-linear",
          action="store_true",
          default=False,
          help="format for fast web display",
      )
  
      ps_clean.add_argument(
          "-permission",
          type=int,
          default=-1,
          help="integer with permission levels",
      )
  
      ps_clean.add_argument(
          "-sanitize",
          action="store_true",
          default=False,
          help="sanitize / clean contents",
      )
      ps_clean.add_argument(
          "-pretty",
          action="store_true",
          default=False,
          help="prettify PDF structure",
      )
      ps_clean.add_argument(
          "-pages",
          help="output selected pages pages, format: 1,5-7,50-N",
      )
      ps_clean.set_defaults(func=clean)
  
      # -------------------------------------------------------------------------
      # 'join' command
      # -------------------------------------------------------------------------
      ps_join = subps.add_parser(
          "join",
          description=mycenter("join PDF documents"),
          epilog="specify each input as 'filename[,password[,pages]]'",
      )
      ps_join.add_argument("input", nargs="*", help="input filenames")
      ps_join.add_argument(
          "-output", required=True, help="output filename"
      )
      ps_join.set_defaults(func=doc_join)
  
      # -------------------------------------------------------------------------
      # 'extract' command
      # -------------------------------------------------------------------------
      ps_extract = subps.add_parser(
          "extract",
          description=mycenter("extract images and fonts to disk"),
      )
      ps_extract.add_argument("input", type=str, help="PDF filename")
      ps_extract.add_argument(
          "-images", action="store_true", help="extract images"
      )
      ps_extract.add_argument(
          "-fonts", action="store_true", help="extract fonts"
      )
      ps_extract.add_argument(
          "-output",
          help="folder to receive output, defaults to current",
      )
      ps_extract.add_argument("-password", help="password")
      ps_extract.add_argument(
          "-pages",
          type=str,
          help="consider these pages only, format: 1,5-7,50-N",
      )
      ps_extract.set_defaults(func=extract_objects)
  
      # -------------------------------------------------------------------------
      # 'embed-info'
      # -------------------------------------------------------------------------
      ps_show = subps.add_parser(
          "embed-info", description=mycenter("list embedded files")
      )
      ps_show.add_argument("input", help="PDF filename")
      ps_show.add_argument(
          "-name", help="if given, report only this one"
      )
      ps_show.add_argument(
          "-detail", action="store_true", help="detail information"
      )
      ps_show.add_argument("-password", help="password")
      ps_show.set_defaults(func=embedded_list)
  
      # -------------------------------------------------------------------------
      # 'embed-add' command
      # -------------------------------------------------------------------------
      ps_embed_add = subps.add_parser(
          "embed-add", description=mycenter("add embedded file")
      )
      ps_embed_add.add_argument("input", help="PDF filename")
      ps_embed_add.add_argument("-password", help="password")
      ps_embed_add.add_argument(
          "-output",
          help="output PDF filename, incremental save if none",
      )
      ps_embed_add.add_argument(
          "-name", required=True, help="name of new entry"
      )
      ps_embed_add.add_argument(
          "-path", required=True, help="path to data for new entry"
      )
      ps_embed_add.add_argument(
          "-desc", help="description of new entry"
      )
      ps_embed_add.set_defaults(func=embedded_add)
  
      # -------------------------------------------------------------------------
      # 'embed-del' command
      # -------------------------------------------------------------------------
      ps_embed_del = subps.add_parser(
          "embed-del", description=mycenter("delete embedded file")
      )
      ps_embed_del.add_argument("input", help="PDF filename")
      ps_embed_del.add_argument("-password", help="password")
      ps_embed_del.add_argument(
          "-output",
          help="output PDF filename, incremental save if none",
      )
      ps_embed_del.add_argument(
          "-name", required=True, help="name of entry to delete"
      )
      ps_embed_del.set_defaults(func=embedded_del)
  
      # -------------------------------------------------------------------------
      # 'embed-upd' command
      # -------------------------------------------------------------------------
      ps_embed_upd = subps.add_parser(
          "embed-upd",
          description=mycenter("update embedded file"),
          epilog="except '-name' all parameters are optional",
      )
      ps_embed_upd.add_argument("input", help="PDF filename")
      ps_embed_upd.add_argument(
          "-name", required=True, help="name of entry"
      )
      ps_embed_upd.add_argument("-password", help="password")
      ps_embed_upd.add_argument(
          "-output",
          help="Output PDF filename, incremental save if none",
      )
      ps_embed_upd.add_argument(
          "-path", help="path to new data for entry"
      )
      ps_embed_upd.add_argument(
          "-filename", help="new filename to store in entry"
      )
      ps_embed_upd.add_argument(
          "-ufilename", help="new unicode filename to store in entry"
      )
      ps_embed_upd.add_argument(
          "-desc", help="new description to store in entry"
      )
      ps_embed_upd.set_defaults(func=embedded_upd)
  
      # -------------------------------------------------------------------------
      # 'embed-extract' command
      # -------------------------------------------------------------------------
      ps_embed_extract = subps.add_parser(
          "embed-extract",
          description=mycenter("extract embedded file to disk"),
      )
      ps_embed_extract.add_argument(
          "input", type=str, help="PDF filename"
      )
      ps_embed_extract.add_argument(
          "-name", required=True, help="name of entry"
      )
      ps_embed_extract.add_argument("-password", help="password")
      ps_embed_extract.add_argument(
          "-output", help="output filename, default is stored name"
      )
      ps_embed_extract.set_defaults(func=embedded_get)
  
      # -------------------------------------------------------------------------
      # 'embed-copy' command
      # -------------------------------------------------------------------------
      ps_embed_copy = subps.add_parser(
          "embed-copy",
          description=mycenter("copy embedded files between PDFs"),
      )
      ps_embed_copy.add_argument(
          "input", type=str, help="PDF to receive embedded files"
      )
      ps_embed_copy.add_argument("-password", help="password of input")
      ps_embed_copy.add_argument(
          "-output",
          help="output PDF, incremental save to 'input' if omitted",
      )
      ps_embed_copy.add_argument(
          "-source", required=True, help="copy embedded files from here"
      )
      ps_embed_copy.add_argument(
          "-pwdsource", help="password of 'source' PDF"
      )
      ps_embed_copy.add_argument(
          "-name", nargs="*", help="restrict copy to these entries"
      )
      ps_embed_copy.set_defaults(func=embedded_copy)
  
      # -------------------------------------------------------------------------
      # 'textlayout' command
      # -------------------------------------------------------------------------
      ps_gettext = subps.add_parser(
          "gettext",
          description=mycenter(
              "extract text in various formatting modes"
          ),
      )
      ps_gettext.add_argument(
          "input", type=str, help="input document filename"
      )
      ps_gettext.add_argument(
          "-password", help="password for input document"
      )
      ps_gettext.add_argument(
          "-mode",
          type=str,
          help="mode: simple, block sort, or layout (default)",
          choices=("simple", "blocks", "layout"),
          default="layout",
      )
      ps_gettext.add_argument(
          "-pages",
          type=str,
          help="select pages, format: 1,5-7,50-N",
          default="1-N",
      )
      ps_gettext.add_argument(
          "-noligatures",
          action="store_true",
          help="expand ligature characters (default False)",
          default=False,
      )
      ps_gettext.add_argument(
          "-convert-white",
          action="store_true",
          help="convert whitespace characters to white (default False)",
          default=False,
      )
      ps_gettext.add_argument(
          "-extra-spaces",
          action="store_true",
          help="fill gaps with spaces (default False)",
          default=False,
      )
      ps_gettext.add_argument(
          "-noformfeed",
          action="store_true",
          help="write linefeeds, no formfeeds (default False)",
          default=False,
      )
      ps_gettext.add_argument(
          "-skip-empty",
          action="store_true",
          help="suppress pages with no text (default False)",
          default=False,
      )
      ps_gettext.add_argument(
          "-output",
          help="store text in this file (default inputfilename.txt)",
      )
      ps_gettext.add_argument(
          "-grid",
          type=float,
          help="merge lines if closer than this (default 2)",
          default=2,
      )
      ps_gettext.add_argument(
          "-fontsize",
          type=float,
          help="only include text with a larger fontsize (default 3)",
          default=3,
      )
      ps_gettext.set_defaults(func=gettext)
  
      # -------------------------------------------------------------------------
      # start program
      # -------------------------------------------------------------------------
      args = parser.parse_args()  # create parameter arguments class
      if not hasattr(args, "func"):  # no function selected
          parser.print_help()  # so print top level help
      else:
          args.func(args)
  
imports: import argparse
  import bisect
  import os
  import sys
  import statistics
  from typing import Dict, List, Set, Tuple
  import fitz
  from fitz.fitz import TEXT_INHIBIT_SPACES, TEXT_PRESERVE_LIGATURES, TEXT_PRESERVE_WHITESPACE
label_desc: Use image node_id 20 for calling a global function with example usage: main() without return types