text: """Render the notebook."""
  import dataclasses
  import pathlib
  import typing
  from dataclasses import InitVar
  from pathlib import Path
  from typing import IO, Any, AnyStr, Iterator, List, Optional, Tuple, Type, Union
  
  import nbformat
  from click.utils import KeepOpenFile
  from nbformat.notebooknode import NotebookNode
  from rich import table
  from rich.console import Console, ConsoleOptions
  from rich.table import Table
  
  from nbpreview import errors
  from nbpreview.component import row
  from nbpreview.component.content.output.result.drawing import ImageDrawing
  
  # terminedia depends on fcntl, which is not present on Windows platforms
  try:
      import terminedia  # noqa: F401
  except ModuleNotFoundError:
      pass
  
  # Fake KeepOpenFile used to avoid non-subscriptable error
  # https://github.com/python/mypy/issues/5264
  if typing.TYPE_CHECKING:  # pragma: no cover
      KeepOpenFileType = KeepOpenFile
  
  else:
  
      class _KeepOpenFile:
          """Fake click's KeepOpenFile for type checking purposes."""
  
          def __getitem__(self, *args: Any) -> Type[KeepOpenFile]:
              """Make the fake class subscriptable."""
              return KeepOpenFile
  
      KeepOpenFileType = _KeepOpenFile()
  
  
  def pick_option(option: Optional[bool], detector: bool) -> bool:
      """Select a render option.
  
      Args:
          option (Optional[bool]): The inputted option which can override
              detections. By default None, which leaves the decision to
              ``detector``.
          detector (bool): A detector based on terminal properties to set
              the option to True. Will be ignored if ``option`` is a
              boolean.
  
      Returns:
          bool: The option value.
      """
      if option is None:
          pick = detector
      else:
          pick = option
  
      return pick
  
  
  def _get_output_pad(plain: bool) -> Tuple[int, int, int, int]:
      """Return the padding for outputs.
  
      Args:
          plain (bool): Only show plain style. No decorations such as
              boxes or execution counts.
  
      Returns:
          Tuple[int, int, int, int]: The padding for outputs.
      """
      if plain:
          return (0, 0, 0, 0)
      else:
          return (0, 0, 0, 1)
  
  
  def _pick_image_drawing(
      option: Union[ImageDrawing, None],
      unicode: bool,
      color: bool,
  ) -> ImageDrawing:
      """Pick an image render option.
  
      Args:
          option (Literal["block", "character", "braille", ImageDrawingEnum, None]):
              The inputted option which can override detections. If None,
              will autodetect.
          unicode (bool): Whether to use unicode characters to
              render the notebook. By default will autodetect.
          color (bool): Whether to use color.
  
      Returns:
          Union[Literal["block", "character", "braille"] ImageDrawingEnum]:
          The image type to render.
      """
      image_render: ImageDrawing
      if option is None:
          # Block is too slow to offer as a sensible default
          # Braille can not do negative space, and most notebook's primary
          # images are plots with light backgrounds
          image_render = "character"
  
      else:
          image_render = option
      return image_render
  
  
  def _render_notebook(
      cells: List[NotebookNode],
      plain: bool,
      unicode: bool,
      hyperlinks: bool,
      theme: str,
      nerd_font: bool,
      files: bool,
      hide_hyperlink_hints: bool,
      hide_output: bool,
      language: str,
      images: bool,
      image_drawing: ImageDrawing,
      color: bool,
      negative_space: bool,
      relative_dir: Path,
      characters: Optional[str] = None,
      line_numbers: bool = False,
      code_wrap: bool = False,
  ) -> Table:
      """Create a table representing a notebook."""
      grid = table.Table.grid(padding=(1, 1, 1, 0))
  
      pad = _get_output_pad(plain)
      if not plain:
          grid.add_column(justify="right")
      grid.add_column()
  
      for cell in cells:
          cell_row = row.render_input_row(
              cell,
              plain=plain,
              pad=pad,
              language=language,
              theme=theme,
              unicode_border=unicode,
              nerd_font=nerd_font,
              unicode=unicode,
              images=images,
              image_drawing=image_drawing,
              color=color,
              negative_space=negative_space,
              hyperlinks=hyperlinks,
              files=files,
              hide_hyperlink_hints=hide_hyperlink_hints,
              characters=characters,
              relative_dir=relative_dir,
              line_numbers=line_numbers,
              code_wrap=code_wrap,
          )
          if cell_row is not None:
              grid.add_row(*cell_row.to_table_row())
  
          outputs = cell.get("outputs")
          if not hide_output and outputs is not None:
              rendered_outputs = row.render_output_row(
                  outputs,
                  plain=plain,
                  pad=pad,
                  unicode=unicode,
                  hyperlinks=hyperlinks,
                  nerd_font=nerd_font,
                  files=files,
                  hide_hyperlink_hints=hide_hyperlink_hints,
                  theme=theme,
                  images=images,
                  image_drawing=image_drawing,
                  color=color,
                  negative_space=negative_space,
                  relative_dir=relative_dir,
              )
              for rendered_output in rendered_outputs:
                  grid.add_row(*rendered_output.to_table_row())
      return grid
  
  
  @dataclasses.dataclass()
  class Notebook:
      """Construct a Notebook object to render Jupyter Notebooks.
  
      Args:
          notebook_node (NotebookNode): A NotebookNode of the notebook to
              render.
          theme (Optional[str]): The theme to use for syntax highlighting.
              May be "ansi_light", "ansi_dark", or any Pygments theme. If
              By default "ansi_dark".
          plain (bool): Only show plain style. No decorations such as
              boxes or execution counts. By default will autodetect.
          unicode (Optional[bool]): Whether to use unicode characters to
              render the notebook. By default will autodetect.
          hide_output (bool): Do not render the notebook outputs. By
              default False.
          nerd_font (bool): Use nerd fonts when appropriate. By default
              False.
          files (bool): Create files when needed to render HTML content.
          hyperlinks (bool): Whether to use hyperlinks. If false will
              explicitly print out path.
          hide_hyperlink_hints (bool): Hide text hints of when content is
              clickable.
          images (Optional[str]): Whether to render images. If None will
              attempt to autodetect. By default None.
          image_drawing (Optional[str]): How to render images. Options are
              "block" or None. If None will attempt to autodetect. By
              default None.
          color (Optional[bool]): Whether to use color. If None will
              attempt to autodetect. By default None.
          relative_dir (Optional[Path]): The directory to prefix relative
              paths to convert them to absolute. If None will assume
              current directory is relative prefix.
          line_numbers (bool): Whether to render line numbers in code
              cells. By default False.
          code_wrap (bool): Whether to wrap code if it does not fit. By
              default False.
      """
  
      notebook_node: NotebookNode
      theme: str = "ansi_dark"
      plain: Optional[bool] = None
      unicode: Optional[bool] = None
      hide_output: bool = False
      nerd_font: bool = False
      files: bool = True
      negative_space: bool = True
      hyperlinks: Optional[bool] = None
      hide_hyperlink_hints: bool = False
      images: Optional[bool] = None
      image_drawing: Optional[ImageDrawing] = None
      color: Optional[bool] = None
      relative_dir: InitVar[Optional[Path]] = None
      line_numbers: bool = False
      code_wrap: bool = False
  
      def __post_init__(self, relative_dir: Optional[Path]) -> None:
          """Constructor."""
          self.cells = self.notebook_node.get("cells", nbformat.from_dict([]))
          self.relative_dir = (
              pathlib.Path().resolve() if relative_dir is None else relative_dir
          )
          try:
              self.language = self.notebook_node.metadata.kernelspec.language
          except AttributeError:
              self.language = "python"
  
      @classmethod
      def from_file(
          cls,
          file: Union[Path, IO[AnyStr], KeepOpenFileType[AnyStr]],
          theme: str = "dark",
          plain: Optional[bool] = None,
          unicode: Optional[bool] = None,
          hide_output: bool = False,
          nerd_font: bool = False,
          files: bool = True,
          negative_space: bool = True,
          hyperlinks: Optional[bool] = None,
          hide_hyperlink_hints: bool = False,
          images: Optional[bool] = None,
          image_drawing: Optional[ImageDrawing] = None,
          color: Optional[bool] = None,
          line_numbers: bool = False,
          code_wrap: bool = False,
      ) -> "Notebook":
          """Create Notebook from notebook file."""
          try:
              notebook_node = nbformat.read(file, as_version=4)
          except (
              AttributeError,
              UnicodeDecodeError,  # Windows failures when reading invalid files
          ) as exception:
              raise errors.InvalidNotebookError from exception
          relative_dir = (
              pathlib.Path.cwd()
              if (file_name := file.name) == "<stdin>"
              else pathlib.Path(file_name).parent
          ).resolve()
          return cls(
              notebook_node,
              theme=theme,
              plain=plain,
              unicode=unicode,
              hide_output=hide_output,
              nerd_font=nerd_font,
              files=files,
              negative_space=negative_space,
              hyperlinks=hyperlinks,
              hide_hyperlink_hints=hide_hyperlink_hints,
              images=images,
              image_drawing=image_drawing,
              color=color,
              relative_dir=relative_dir,
              line_numbers=line_numbers,
              code_wrap=code_wrap,
          )
  
      def __rich_console__(
          self, console: Console, options: ConsoleOptions
      ) -> Iterator[Table]:
          """Render the Notebook to the terminal.
  
          Args:
              console (Console): The Rich Console object.
              options (ConsoleOptions): The Rich Console options.
  
          Yields:
              Iterator[RenderResult]: The
          """
          plain = pick_option(self.plain, detector=not options.is_terminal)
          unicode = pick_option(
              self.unicode, detector=not options.legacy_windows and not options.ascii_only
          )
          hyperlinks = pick_option(
              self.hyperlinks, detector=not options.legacy_windows and options.is_terminal
          )
          color = pick_option(self.color, detector=options.is_terminal)
          images = pick_option(self.images, detector=options.is_terminal and color)
          image_drawing = _pick_image_drawing(
              self.image_drawing, unicode=unicode, color=color
          )
          rendered_notebook = _render_notebook(
              self.cells,
              plain=plain,
              unicode=unicode,
              hyperlinks=hyperlinks,
              theme=self.theme,
              nerd_font=self.nerd_font,
              files=self.files,
              hide_hyperlink_hints=self.hide_hyperlink_hints,
              hide_output=self.hide_output,
              language=self.language,
              images=images,
              image_drawing=image_drawing,
              color=color,
              negative_space=self.negative_space,
              relative_dir=self.relative_dir,
              line_numbers=self.line_numbers,
              code_wrap=self.code_wrap,
          )
          yield rendered_notebook
  