diff --git a/nbconvert/exporters/rst.py b/nbconvert/exporters/rst.py index 23061f14e..07984d1e5 100644 --- a/nbconvert/exporters/rst.py +++ b/nbconvert/exporters/rst.py @@ -6,6 +6,7 @@ from traitlets import default from traitlets.config import Config +from ..filters import DataTypeFilter from .templateexporter import TemplateExporter @@ -22,9 +23,24 @@ def _file_extension_default(self): def _template_name_default(self): return "rst" - output_mimetype = "text/restructuredtext" + @default("raw_mimetypes") + def _raw_mimetypes_default(self): + # Up to summer 2024, nbconvert had a mistaken output_mimetype. + # Listing that as an extra option here maintains compatibility for + # notebooks with raw cells marked as that mimetype. + return [self.output_mimetype, "text/restructuredtext", ""] + + output_mimetype = "text/x-rst" export_from_notebook = "reST" + def default_filters(self): + """Override filter_data_type to use native rst outputs""" + dtf = DataTypeFilter() + dtf.display_data_priority = [self.output_mimetype, *dtf.display_data_priority] + filters = dict(super().default_filters()) + filters["filter_data_type"] = dtf + return filters.items() + @property def default_config(self): c = Config( diff --git a/nbconvert/exporters/templateexporter.py b/nbconvert/exporters/templateexporter.py index c6a337d48..42220cbda 100644 --- a/nbconvert/exporters/templateexporter.py +++ b/nbconvert/exporters/templateexporter.py @@ -407,6 +407,7 @@ def from_notebook_node( # type:ignore[explicit-override, override] """ nb_copy, resources = super().from_notebook_node(nb, resources, **kw) resources.setdefault("raw_mimetypes", self.raw_mimetypes) + resources.setdefault("output_mimetype", self.output_mimetype) resources["global_content_filter"] = { "include_code": not self.exclude_code_cell, "include_markdown": not self.exclude_markdown, diff --git a/share/templates/base/display_priority.j2 b/share/templates/base/display_priority.j2 index 27c3c87e9..c24639e9a 100644 --- a/share/templates/base/display_priority.j2 +++ b/share/templates/base/display_priority.j2 @@ -38,6 +38,9 @@ {%- elif type == 'application/vnd.jupyter.widget-view+json' -%} {%- block data_widget_view -%} {%- endblock -%} + {%- elif type == resources.output_mimetype -%} + {%- block data_native -%} + {%- endblock -%} {%- else -%} {%- block data_other -%} {%- endblock -%} diff --git a/share/templates/rst/conf.json b/share/templates/rst/conf.json index cf2f30a0f..f1dd78aa6 100644 --- a/share/templates/rst/conf.json +++ b/share/templates/rst/conf.json @@ -1,6 +1,6 @@ { "base_template": "base", "mimetypes": { - "text/restructuredtext": true + "text/x-rst": true } } diff --git a/share/templates/rst/index.rst.j2 b/share/templates/rst/index.rst.j2 index bda5c5fb9..c374cd240 100644 --- a/share/templates/rst/index.rst.j2 +++ b/share/templates/rst/index.rst.j2 @@ -44,6 +44,10 @@ {{ output.text | indent }} {% endblock stream %} +{% block data_native %} +{{ output.data['text/x-rst'] }} +{% endblock data_native %} + {% block data_svg %} .. image:: {{ output.metadata.filenames['image/svg+xml'] | urlencode }} {% endblock data_svg %} diff --git a/tests/exporters/files/rst_output.ipynb b/tests/exporters/files/rst_output.ipynb new file mode 100644 index 000000000..86dee7d63 --- /dev/null +++ b/tests/exporters/files/rst_output.ipynb @@ -0,0 +1,75 @@ +{ + "cells": [ + { + "cell_type": "code", + "execution_count": 1, + "id": "d5202f0f-21b8-4509-a9e2-45caf1c7db7a", + "metadata": {}, + "outputs": [], + "source": [ + "from textwrap import indent\n", + "\n", + "\n", + "class Note:\n", + " def __init__(self, text):\n", + " self.text = text\n", + "\n", + " def _repr_html_(self):\n", + " return f'