class_docstr: A class that can read or write a Jupyter notebook as text
class_docstr_tok: ["A","class","that","can","read","or","write","a","Jupyter","notebook","as","text"]
docstr: Return the text representation of the notebook
docstr_tok: ["Return","the","text","representation","of","the","notebook"]
code: def writes(self, nb, metadata=None, **kwargs):
      """Return the text representation of the notebook"""
      if self.fmt.get("format_name") == "pandoc":
          return notebook_to_md(self.filter_notebook(nb, metadata))
      if self.fmt.get("format_name") == "quarto" or self.ext == ".qmd":
          return notebook_to_qmd(self.filter_notebook(nb, metadata))
      if self.fmt.get(
          "format_name"
      ) == MYST_FORMAT_NAME or self.ext in myst_extensions(no_md=True):
          pygments_lexer = metadata.get("language_info", {}).get(
              "pygments_lexer", None
          )
          return notebook_to_myst(
              self.filter_notebook(nb, metadata),
              default_lexer=pygments_lexer,
          )
  
      # Copy the notebook, in order to be sure we do not modify the original notebook
      nb = NotebookNode(
          nbformat=nb.nbformat,
          nbformat_minor=nb.nbformat_minor,
          metadata=deepcopy(metadata or nb.metadata),
          cells=nb.cells,
      )
  
      metadata = nb.metadata
      default_language = (
          default_language_from_metadata_and_ext(
              metadata, self.implementation.extension, True
          )
          or "python"
      )
      self.update_fmt_with_notebook_options(nb.metadata)
      if "use_runtools" not in self.fmt:
          for cell in nb.cells:
              if cell.metadata.get(
                  "hide_input", False
              ) or cell.metadata.get("hide_output", False):
                  self.fmt["use_runtools"] = True
                  break
  
      header = encoding_and_executable(nb, metadata, self.ext)
      unsupported_keys = set()
      (
          header_content,
          header_lines_to_next_cell,
      ) = metadata_and_cell_to_header(
          nb,
          metadata,
          self.implementation,
          self.fmt,
          unsupported_keys=unsupported_keys,
      )
      header.extend(header_content)
  
      cell_exporters = []
      looking_for_first_markdown_cell = (
          self.implementation.format_name
          and self.implementation.format_name.startswith("sphinx")
      )
      split_at_heading = self.fmt.get("split_at_heading", False)
  
      for cell in nb.cells:
          if (
              looking_for_first_markdown_cell
              and cell.cell_type == "markdown"
          ):
              cell.metadata.setdefault("cell_marker", '"""')
              looking_for_first_markdown_cell = False
  
          cell_exporters.append(
              self.implementation.cell_exporter_class(
                  cell,
                  default_language,
                  self.fmt,
                  unsupported_keys=unsupported_keys,
              )
          )
  
      _warn_on_unsupported_keys(unsupported_keys)
  
      texts = [cell.cell_to_text() for cell in cell_exporters]
      lines = []
  
      # concatenate cells in reverse order to determine how many blank lines (pep8)
      for i, cell in reversed(list(enumerate(cell_exporters))):
          text = cell.remove_eoc_marker(texts[i], lines)
  
          if (
              i == 0
              and self.implementation.format_name
              and self.implementation.format_name.startswith("sphinx")
              and (
                  text
                  in [["%matplotlib inline"], ["# %matplotlib inline"]]
              )
          ):
              continue
  
          lines_to_next_cell = cell.lines_to_next_cell
          if lines_to_next_cell is None:
              lines_to_next_cell = pep8_lines_between_cells(
                  text, lines, self.implementation.extension
              )
  
          text.extend([""] * lines_to_next_cell)
  
          # two blank lines between markdown cells in Rmd when those do not have explicit region markers
          if (
              self.ext in [".md", ".markdown", ".Rmd"]
              and not cell.is_code()
          ):
              if (
                  i + 1 < len(cell_exporters)
                  and not cell_exporters[i + 1].is_code()
                  and not texts[i][0].startswith("<!-- #")
                  and not texts[i + 1][0].startswith("<!-- #")
                  and (
                      not split_at_heading
                      or not (
                          texts[i + 1]
                          and texts[i + 1][0].startswith("#")
                      )
                  )
              ):
                  text.append("")
  
          # "" between two consecutive code cells in sphinx
          if (
              self.implementation.format_name.startswith("sphinx")
              and cell.is_code()
          ):
              if (
                  i + 1 < len(cell_exporters)
                  and cell_exporters[i + 1].is_code()
              ):
                  text.append('""')
  
          lines = text + lines
  
      if header_lines_to_next_cell is None:
          header_lines_to_next_cell = pep8_lines_between_cells(
              header_content, lines, self.implementation.extension
          )
  
      header.extend([""] * header_lines_to_next_cell)
  
      return "\n".join(header + lines)
  
imports: import logging
  import os
  import sys
  import warnings
  from copy import copy, deepcopy
  import nbformat
  from nbformat.v4.nbbase import NotebookNode, new_code_cell, new_notebook
  from nbformat.v4.rwbase import NotebookReader, NotebookWriter
  from .cell_metadata import _IGNORE_CELL_METADATA
  from .formats import _VALID_FORMAT_OPTIONS, divine_format, format_name_for_ext, get_format_implementation, guess_format, long_form_one_format, read_format_from_metadata, rearrange_jupytext_metadata, update_jupytext_formats_metadata
  from .header import encoding_and_executable, header_to_metadata_and_cell, insert_jupytext_info_and_filter_metadata, insert_or_test_version_number, metadata_and_cell_to_header
  from .languages import default_language_from_metadata_and_ext, set_main_and_cell_language
  from .metadata_filter import filter_metadata, update_metadata_filters
  from .myst import MYST_FORMAT_NAME, myst_extensions, myst_to_notebook, notebook_to_myst
  from .pandoc import md_to_notebook, notebook_to_md
  from .pep8 import pep8_lines_between_cells
  from .quarto import notebook_to_qmd, qmd_to_notebook
  from .version import __version__
label_desc: Use image node_id 5 for calling the TextNotebookConverter obj's underlying member method code with example usage: obj.writes(nb, metadata) and returns: str, notebook_to_md, notebook_to_qmd, notebook_to_myst