diff --git a/docs/CHANGELOG.md b/docs/CHANGELOG.md index f14ec10e3..8a7b03d17 100644 --- a/docs/CHANGELOG.md +++ b/docs/CHANGELOG.md @@ -4,6 +4,9 @@ Jupytext ChangeLog 1.10.1 (2021-02-??) ------------------- +**Added** +- Sage notebooks are supported. They can be converted to `.sage` and `.md` files and back. Thanks to Lars Franke for suggesting this! ([#727](https://github.com/mwouts/jupytext/issues/727)) + 1.10.0 (2021-02-04) ------------------- diff --git a/docs/languages.md b/docs/languages.md index 859ef5178..7efd87a67 100644 --- a/docs/languages.md +++ b/docs/languages.md @@ -21,6 +21,7 @@ Jupytext works with notebooks in any of the following languages: - R - Robot Framework - Rust/Evxcr +- Sage - Scala - Scheme - Script of Script diff --git a/jupytext/formats.py b/jupytext/formats.py index 4346e4384..23425b876 100644 --- a/jupytext/formats.py +++ b/jupytext/formats.py @@ -766,6 +766,11 @@ def auto_ext_from_metadata(metadata): """Script extension from notebook metadata""" auto_ext = metadata.get("language_info", {}).get("file_extension") + # Sage notebooks have ".py" as the associated extension in "language_info", + # so we change it to ".sage" in that case, see #727 + if auto_ext == ".py" and metadata.get("kernelspec", {}).get("language") == "sage": + auto_ext = ".sage" + if auto_ext is None: language = metadata.get("kernelspec", {}).get("language") or metadata.get( "jupytext", {} diff --git a/jupytext/languages.py b/jupytext/languages.py index b52bbe47d..284c3ba0f 100644 --- a/jupytext/languages.py +++ b/jupytext/languages.py @@ -57,6 +57,7 @@ ".sos": {"language": "sos", "comment": "#"}, ".java": {"language": "java", "comment": "//"}, ".groovy": {"language": "groovy", "comment": "//"}, + ".sage": {"language": "sage", "comment": "#"}, } _COMMENT_CHARS = [ diff --git a/tests/notebooks/ipynb_sage/sage_print_hello.ipynb b/tests/notebooks/ipynb_sage/sage_print_hello.ipynb new file mode 100644 index 000000000..c1206f2a2 --- /dev/null +++ b/tests/notebooks/ipynb_sage/sage_print_hello.ipynb @@ -0,0 +1,34 @@ +{ + "cells": [ + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "print(\"Hello world\")" + ] + } + ], + "metadata": { + "kernelspec": { + "display_name": "SageMath 9.2", + "language": "sage", + "name": "sagemath" + }, + "language_info": { + "codemirror_mode": { + "name": "ipython", + "version": 3 + }, + "file_extension": ".py", + "mimetype": "text/x-python", + "name": "python", + "nbconvert_exporter": "python", + "pygments_lexer": "ipython3", + "version": "3.9.1" + } + }, + "nbformat": 4, + "nbformat_minor": 4 +} diff --git a/tests/notebooks/mirror/ipynb_to_Rmd/sage_print_hello.Rmd b/tests/notebooks/mirror/ipynb_to_Rmd/sage_print_hello.Rmd new file mode 100644 index 000000000..6793b5c45 --- /dev/null +++ b/tests/notebooks/mirror/ipynb_to_Rmd/sage_print_hello.Rmd @@ -0,0 +1,11 @@ +--- +jupyter: + kernelspec: + display_name: SageMath 9.2 + language: sage + name: sagemath +--- + +```{sage} +print("Hello world") +``` diff --git a/tests/notebooks/mirror/ipynb_to_hydrogen/sage_print_hello.sage b/tests/notebooks/mirror/ipynb_to_hydrogen/sage_print_hello.sage new file mode 100644 index 000000000..bf0bfccb9 --- /dev/null +++ b/tests/notebooks/mirror/ipynb_to_hydrogen/sage_print_hello.sage @@ -0,0 +1,10 @@ +# --- +# jupyter: +# kernelspec: +# display_name: SageMath 9.2 +# language: sage +# name: sagemath +# --- + +# %% +print("Hello world") diff --git a/tests/notebooks/mirror/ipynb_to_md/sage_print_hello.md b/tests/notebooks/mirror/ipynb_to_md/sage_print_hello.md new file mode 100644 index 000000000..6131043b8 --- /dev/null +++ b/tests/notebooks/mirror/ipynb_to_md/sage_print_hello.md @@ -0,0 +1,11 @@ +--- +jupyter: + kernelspec: + display_name: SageMath 9.2 + language: sage + name: sagemath +--- + +```sage +print("Hello world") +``` diff --git a/tests/notebooks/mirror/ipynb_to_myst/sage_print_hello.md b/tests/notebooks/mirror/ipynb_to_myst/sage_print_hello.md new file mode 100644 index 000000000..445c3ee86 --- /dev/null +++ b/tests/notebooks/mirror/ipynb_to_myst/sage_print_hello.md @@ -0,0 +1,10 @@ +--- +kernelspec: + display_name: SageMath 9.2 + language: sage + name: sagemath +--- + +```{code-cell} ipython3 +print("Hello world") +``` diff --git a/tests/notebooks/mirror/ipynb_to_percent/sage_print_hello.sage b/tests/notebooks/mirror/ipynb_to_percent/sage_print_hello.sage new file mode 100644 index 000000000..bf0bfccb9 --- /dev/null +++ b/tests/notebooks/mirror/ipynb_to_percent/sage_print_hello.sage @@ -0,0 +1,10 @@ +# --- +# jupyter: +# kernelspec: +# display_name: SageMath 9.2 +# language: sage +# name: sagemath +# --- + +# %% +print("Hello world") diff --git a/tests/notebooks/mirror/ipynb_to_script/sage_print_hello.sage b/tests/notebooks/mirror/ipynb_to_script/sage_print_hello.sage new file mode 100644 index 000000000..09e3f421d --- /dev/null +++ b/tests/notebooks/mirror/ipynb_to_script/sage_print_hello.sage @@ -0,0 +1,9 @@ +# --- +# jupyter: +# kernelspec: +# display_name: SageMath 9.2 +# language: sage +# name: sagemath +# --- + +print("Hello world") diff --git a/tests/test_auto_ext.py b/tests/test_auto_ext.py index 721ba2ae1..d68fb6686 100644 --- a/tests/test_auto_ext.py +++ b/tests/test_auto_ext.py @@ -39,6 +39,10 @@ def test_auto_from_kernelspecs_works(nb_file): elif expected_ext == ".fs": expected_ext = ".fsx" auto_ext = auto_ext_from_metadata(nb.metadata) + if auto_ext == ".sage": + pytest.xfail( + "Sage notebooks have Python in their language_info metadata, see #727" + ) assert auto_ext == expected_ext