code: def main():
      parser = argparse.ArgumentParser(
          description="Validates that the descriptions in notebooks follow the expected format, so that the notebooks read consistently and render nicely."
      )
      parser.add_argument(
          "locations",
          nargs="+",
          help="Paths(s) to search for Jupyter notebooks to check",
      )
  
      args = parser.parse_args()
  
      # Find all Jupyter notebook files in the specified directory
      all_files = []
      for p in args.locations:
          path = Path(p)
          if path.is_dir():
              all_files.extend(path.glob("**/*.ipynb"))
          elif path.is_file():
              all_files.append(path)
          else:
              raise ValueError(
                  f"Specified location not '{path}'a file or directory."
              )
  
      all_errors = []
      for file_loc in all_files:
          # Skip checkpoints
          if ".ipynb_checkpoint" in str(file_loc):
              continue
  
          print(f"{YELLOW_BOLD}Checking file {file_loc}{RESET}")
          notebook = nbformat.read(str(file_loc), as_version=4)
          cells = parse_markdown_cells(notebook)
  
          this_errors = []
          for checker in CHECKERS:
              try:
                  checker(cells)
              except FormattingError as exc:
                  for e in exc.errors:
                      print(f"{LIGHT_RED_BOLD}error{RESET}: {e}\n")
                  this_errors.extend(exc.errors)
  
          if this_errors:
              all_errors.append((file_loc, this_errors))
  
      if all_errors:
          # there was at least one problem!
  
          # try to annotate the build on buildkite with markdown
          def list_element(s):
              indented = textwrap.indent(s, "  ")
              # remove the indentation from the first line
              return f"- {indented[2:]}"
  
          def render_path(path):
              text = f"**`{path}`**"
  
              # if the commit for the build is known, include a link to that exact rendered notebook,
              # for convenience
              try:
                  commit = os.environ["BUILDKITE_COMMIT"]
              except KeyError:
                  pass
              else:
                  url = f"https://nbviewer.jupyter.org/github/stellargraph/stellargraph/blob/{commit}/{path}"
                  text = f"{text} ([rendered notebook]({url}))"
  
              return text
  
          def file_list(path, errors):
              whole_list = "\n".join(
                  list_element(error) for error in errors
              )
              return f"{render_path(path)}:\n\n{whole_list}"
  
          file_lists = "\n\n".join(
              file_list(path, errors) for path, errors in all_errors
          )
  
          command = f"python {__file__} demos/"
          formatted = f"""\
  Found some notebooks with inconsistent formatting. These notebooks may be less clear or render incorrectly on Read the Docs. Please adjust them.
  
  {file_lists}
  
  This check can be run locally, via `{command}`."""
  
          if "GITHUB_ACTIONS" in os.environ:
              for path, errors in all_errors:
                  whole_list = "\n".join(errors)
                  message = f"Notebook failed text check:\n{whole_list}"
                  escaped = message.replace("\n", "%0A")
                  print(f"::error file={path}::{escaped}")
  
          try:
              subprocess.run(
                  [
                      "buildkite-agent",
                      "annotate",
                      "--style=error",
                      "--context=notebook_text_checker",
                      formatted,
                  ]
              )
          except FileNotFoundError:
              # no agent, so probably not on buildkite, and so silently continue without an annotation
              pass
  
          sys.exit(1)
  
imports: import argparse
  import commonmark
  import nbformat
  import os
  import re
  import subprocess
  import sys
  import textwrap
  from pathlib import Path
label_desc: Use image node_id 22 for calling a global function with example usage: main() and returns: str, indented, text, render_path, str, whole_list