예제 #1
0
def writes(notebook, fmt, version=nbformat.NO_CONVERT, **kwargs):
    """Write a notebook to a string"""
    metadata = deepcopy(notebook.metadata)
    rearrange_jupytext_metadata(metadata)
    fmt = copy(fmt)
    fmt = long_form_one_format(fmt, metadata)
    ext = fmt['extension']
    format_name = fmt.get('format_name')

    jupytext_metadata = metadata.get('jupytext', {})

    if ext == '.ipynb':
        # Remove jupytext section if empty
        jupytext_metadata.pop('text_representation', {})
        if not jupytext_metadata:
            metadata.pop('jupytext', {})
        return nbformat.writes(
            NotebookNode(nbformat=notebook.nbformat,
                         nbformat_minor=notebook.nbformat_minor,
                         metadata=metadata,
                         cells=notebook.cells), version, **kwargs)

    if not format_name:
        format_name = format_name_for_ext(metadata,
                                          ext,
                                          explicit_default=False)

    if format_name:
        fmt['format_name'] = format_name
        update_jupytext_formats_metadata(metadata, fmt)

    writer = TextNotebookConverter(fmt)
    return writer.writes(notebook, metadata)
예제 #2
0
def writes(notebook, fmt, version=nbformat.NO_CONVERT, **kwargs):
    """"
    Write a notebook to a file name or a file object

    :param notebook: the notebook
    :param fmt: the jupytext format like `md`, `py:percent`, ...
    :param version: see nbformat.writes
    :param kwargs: (not used) additional parameters for nbformat.writes
    :return: the text representation of the notebook
    """
    metadata = deepcopy(notebook.metadata)
    rearrange_jupytext_metadata(metadata)
    fmt = copy(fmt)
    fmt = long_form_one_format(fmt, metadata)
    ext = fmt["extension"]
    format_name = fmt.get("format_name")

    jupytext_metadata = metadata.get("jupytext", {})

    if ext == ".ipynb":
        # Remove jupytext section if empty
        jupytext_metadata.pop("text_representation", {})
        if not jupytext_metadata:
            metadata.pop("jupytext", {})
        return nbformat.writes(
            NotebookNode(
                nbformat=notebook.nbformat,
                nbformat_minor=notebook.nbformat_minor,
                metadata=metadata,
                cells=notebook.cells,
            ),
            version,
            **kwargs
        )

    if not format_name:
        format_name = format_name_for_ext(metadata, ext, explicit_default=False)

    if format_name:
        fmt["format_name"] = format_name
        update_jupytext_formats_metadata(metadata, fmt)

    writer = TextNotebookConverter(fmt)
    return writer.writes(notebook, metadata)
예제 #3
0
def writes(notebook, fmt, version=nbformat.NO_CONVERT, config=None, **kwargs):
    """Return the text representation of the notebook

    :param notebook: the notebook
    :param fmt: the jupytext format like `md`, `py:percent`, ...
    :param version: see nbformat.writes
    :param config: (optional) a Jupytext configuration object
    :param kwargs: (not used) additional parameters for nbformat.writes
    :return: the text representation of the notebook
    """
    if version is not nbformat.NO_CONVERT:
        if not isinstance(version, int):
            raise TypeError(
                "The argument 'version' should be either nbformat.NO_CONVERT, or an integer."
            )
        notebook = nbformat.convert(notebook, version)
    (version, version_minor) = nbformat.reader.get_version(notebook)
    if version < 4:
        raise NotSupportedNBFormatVersion(
            f"Notebooks in nbformat version {version}.{version_minor} are not supported by Jupytext. "
            f"Please convert your notebooks to nbformat version 4 with "
            f"'jupyter nbconvert --to notebook --inplace', or call this function with 'version=4'."
        )
    if version > 4 or (version == 4 and version_minor > 5):
        warnings.warn(
            f"Notebooks in nbformat version {version}.{version_minor} "
            f"have not been tested with Jupytext version {__version__}."
        )

    metadata = deepcopy(notebook.metadata)
    rearrange_jupytext_metadata(metadata)
    fmt = copy(fmt)
    fmt = long_form_one_format(fmt, metadata)
    ext = fmt["extension"]
    format_name = fmt.get("format_name")

    jupytext_metadata = metadata.get("jupytext", {})

    if ext == ".ipynb":
        # Remove jupytext section if empty
        jupytext_metadata.pop("text_representation", {})
        if not jupytext_metadata:
            metadata.pop("jupytext", {})
        return nbformat.writes(
            NotebookNode(
                nbformat=notebook.nbformat,
                nbformat_minor=notebook.nbformat_minor,
                metadata=metadata,
                cells=notebook.cells,
            ),
            version,
            **kwargs,
        )

    if not format_name:
        format_name = format_name_for_ext(metadata, ext, explicit_default=False)

    if format_name:
        fmt["format_name"] = format_name
        update_jupytext_formats_metadata(metadata, fmt)

    writer = TextNotebookConverter(fmt, config)
    return writer.writes(notebook, metadata)
예제 #4
0
    def writes(self, nb, metadata=None, **kwargs):
        """Return the text representation of the notebook"""
        if self.fmt.get("format_name") == "pandoc":
            self.update_fmt_with_notebook_options(nb.metadata)
            metadata = insert_jupytext_info_and_filter_metadata(
                metadata, self.fmt, self.implementation
            )

            cells = []
            for cell in nb.cells:
                cell_metadata = filter_metadata(
                    cell.metadata,
                    self.fmt.get("cell_metadata_filter"),
                    _IGNORE_CELL_METADATA,
                )
                if cell.cell_type == "code":
                    cells.append(
                        new_code_cell(source=cell.source, metadata=cell_metadata)
                    )
                else:
                    cells.append(
                        NotebookNode(
                            source=cell.source,
                            metadata=cell_metadata,
                            cell_type=cell.cell_type,
                        )
                    )

            return notebook_to_md(
                NotebookNode(
                    nbformat=nb.nbformat,
                    nbformat_minor=nb.nbformat_minor,
                    metadata=metadata,
                    cells=cells,
                )
            )

        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
            )
            self.update_fmt_with_notebook_options(nb.metadata)
            metadata = insert_jupytext_info_and_filter_metadata(
                metadata, self.fmt, self.implementation
            )

            cells = []
            for cell in nb.cells:
                cell_metadata = filter_metadata(
                    cell.metadata,
                    self.fmt.get("cell_metadata_filter"),
                    _IGNORE_CELL_METADATA,
                )
                if cell.cell_type == "code":
                    cells.append(
                        new_code_cell(source=cell.source, metadata=cell_metadata)
                    )
                else:
                    cells.append(
                        NotebookNode(
                            source=cell.source,
                            metadata=cell_metadata,
                            cell_type=cell.cell_type,
                        )
                    )
            return notebook_to_myst(
                NotebookNode(
                    nbformat=nb.nbformat,
                    nbformat_minor=nb.nbformat_minor,
                    metadata=metadata,
                    cells=cells,
                ),
                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)
        header_content, header_lines_to_next_cell = metadata_and_cell_to_header(
            nb,
            metadata,
            self.implementation,
            self.fmt,
        )
        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
                )
            )

        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)
예제 #5
0
    def writes(self, nb, metadata=None, **kwargs):
        """Return the text representation of the notebook"""
        if self.fmt.get('format_name') == 'pandoc':
            metadata = insert_jupytext_info_and_filter_metadata(
                metadata, self.ext, self.implementation)

            cells = []
            for cell in nb.cells:
                cell_metadata = filter_metadata(
                    copy(cell.metadata), self.fmt.get('cell_metadata_filter'),
                    _IGNORE_CELL_METADATA)
                if cell.cell_type == 'code':
                    cells.append(
                        new_code_cell(source=cell.source,
                                      metadata=cell_metadata))
                else:
                    cells.append(
                        NotebookNode(source=cell.source,
                                     metadata=cell_metadata,
                                     cell_type=cell.cell_type))

            return notebook_to_md(
                NotebookNode(nbformat=nb.nbformat,
                             nbformat_minor=nb.nbformat_minor,
                             metadata=metadata,
                             cells=cells))

        # 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) or 'python'
        self.update_fmt_with_notebook_options(nb.metadata)

        if 'main_language' in metadata.get('jupytext', {}):
            del metadata['jupytext']['main_language']

        header = encoding_and_executable(nb, metadata, self.ext)
        header_content, header_lines_to_next_cell = metadata_and_cell_to_header(
            nb, metadata, self.implementation, self.ext)
        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))

        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 ['.Rmd', '.md'] 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('<!-- #region')
                        and not texts[i + 1][0].startswith('<!-- #region') 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('""')

            if i + 1 < len(cell_exporters):
                lines = cell_exporters[i + 1].simplify_soc_marker(lines, text)
            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)

        if cell_exporters:
            lines = cell_exporters[0].simplify_soc_marker(lines, header)

        return '\n'.join(header + lines)
예제 #6
0
def test_empty_notebook():
    nb = new_notebook()
    assert nb.cells == []
    assert nb.metadata == NotebookNode()
    assert nb.nbformat == nbformat