From 9c9b59180857a3a40a9462924e9567648c5bad08 Mon Sep 17 00:00:00 2001 From: Marc Wouts Date: Tue, 21 Aug 2018 10:21:08 +0200 Subject: [PATCH 1/4] Update README.md --- README.md | 22 ++++++++++++---------- 1 file changed, 12 insertions(+), 10 deletions(-) diff --git a/README.md b/README.md index 19078f7e5..1f9ab22c4 100644 --- a/README.md +++ b/README.md @@ -14,13 +14,13 @@ These alternative representations allow to - edit notebooks in both Jupyter and your favorite IDE, and refactor them - extract executable scripts from your notebooks - get meaningfull diffs for notebooks under version control, and easily merge contributions -- edit the same notebook in both Jupyter and Rstudio, and use RStudio's advanced rendering of notebooks to PDF, HTML or [HTML slides](https://rmarkdown.rstudio.com/ioslides_presentation_format.html). +- edit the same notebook in both Jupyter and RStudio, and use RStudio's advanced rendering of notebooks to PDF, HTML or [HTML slides](https://rmarkdown.rstudio.com/ioslides_presentation_format.html). -Scripts and R markdown notebooks only store the source of the notebook, and work in pair with the original `.ipynb` file. Jupyter saves notebooks to both the classical `.ipynb` form, and to the text-only representation. When a text-only notebook is loaded in Jupyter, inputs are taken there, and outputs are taken from the `.ipynb` file, if present. +Scripts and R markdown notebooks only store the source of the notebook, and work in pair with the original `.ipynb` file. With our plugin, Jupyter saves notebooks to both the classical `.ipynb` form, and to the text-only representation. When a text-only notebook is loaded in Jupyter, inputs are taken there, and outputs are taken from the `.ipynb` file, if present. ## Can I have a demo? -Sure. Try our package on [binder](https://mybinder.org/v2/gh/mwouts/nbrmd/master?filepath=demo). Notice that every `.py`, `.R` and `.Rmd` file now opens as a Jupyter notebook. I suggest you open the matplotlib demo there: `filled_step.py`, run it and save it, close notebook and reopen, to observe persistence of outputs. +Sure. Try our package on [binder](https://mybinder.org/v2/gh/mwouts/nbrmd/master?filepath=demo). Notice that every `.py`, `.R` and `.Rmd` file opens as a Jupyter notebook. I suggest you open the matplotlib demo `filled_step.py`, run it and save it, close notebook and reopen, to observe persistence of outputs. The other examples demo how to *edit* the script and reload the notebook (preserving the kernel variables), and how to edit in Jupyter an interactive ioslide presentation. @@ -38,15 +38,13 @@ Rmd notebook in jupyter | Rmd notebook as text ## Have you tested round-trip conversion? -Round trip conversion is safe! A few hundreds of tests help to guarantee this. +Round trip conversion is safe! A few hundred of tests help to guarantee this. - Script to Jupyter notebook, to script again is identity. If you associate a Jupyter kernel to your notebook, that information will go to a yaml header at the top of your script. - R markdown to Jupyter notebook, to R markdown again is identity. - Jupyter to script, and Jupyter again preserves source and metadata. -- Jupyter to R markdown, and Jupyter again preserves source and metadata. -In some occasions (consecutive blank lines in markdown cells), markdown cells may -be splitted into smaller ones. +- Jupyter to R markdown, and Jupyter again preserves source and metadata (only, markdown cells with two consecutive blank lines will be splitted into multiple cells, as the two blank line pattern is used to separate cells). ## How do I activate the companion scripts or R markdown notebooks in Jupyter? @@ -67,6 +65,12 @@ jupyter notebook With the above configuration, every Jupyter notebook will have a companion `.py` (`.nb.py`, or `.Rmd`) notebook. And every `.py` (`.nb.py`, or `.Rmd`) notebook will have a companion `.ipynb` notebook. +The default configuration can also contain multiple groups. Use +```python +c.NotebookApp.contents_manager_class = "nbrmd.RmdFileContentsManager" +c.ContentsManager.default_nbrmd_formats = "ipynb,nb.py;py.ipynb,py" +``` +if you want `.ipynb` notebooks to have `.nb.py` companion scripts, and `.py` files to have `.py.ipynb` companion notebooks (Learn more on the possible values for `nbrmd_formats` [here](https://github.com/mwouts/nbsrc/issues/5#issuecomment-414093471)). ## Per notebook configuration @@ -92,8 +96,6 @@ In case you want both `py` and `Rmd`, please note that the order matters: the first non-`ipynb` extension is the one used as the reference source for notebook inputs when you open the `ipynb` file. -Learn more on the possible values for `nbrmd_formats` [here](https://github.com/mwouts/nbsrc/issues/5#issuecomment-414093471). - ## Command line conversion The package provides two `nbrmd` and `nbsrc` scripts that convert Jupyter notebooks to R markdown notebooks and scripts, and vice-versa. @@ -126,4 +128,4 @@ nbconvert jupyter.ipynb --to rnotebook ## Jupyter magics -Jupyter magics are escaped in the script and R markdown representations so that scripts can actually be executed. Comment a magic with `#noescape` on the same line to avoid escaping. Non-standard magics can be escaped with `#escape`. +Jupyter magics are escaped in the script and R markdown representations so that scripts can actually be executed. Comment a magic with `#noescape` on the same line to avoid escaping. User defined magics can be escaped with `#escape`. From 381cc737a88d2bfed9aaa4d575c9f3ecf2894f02 Mon Sep 17 00:00:00 2001 From: Marc Wouts Date: Tue, 21 Aug 2018 10:32:59 +0200 Subject: [PATCH 2/4] Source only notebooks can be trusted. Make test effective --- nbrmd/contentsmanager.py | 2 ++ tests/test_trust_notebook.py | 12 ++++++++---- 2 files changed, 10 insertions(+), 4 deletions(-) diff --git a/nbrmd/contentsmanager.py b/nbrmd/contentsmanager.py index f0b23cc2a..4ae74dbe8 100644 --- a/nbrmd/contentsmanager.py +++ b/nbrmd/contentsmanager.py @@ -188,6 +188,8 @@ def _read_notebook(self, os_path, as_version=4, combine.combine_inputs_with_outputs(nb, nb_outputs) if self.notary.check_signature(nb_outputs): self.notary.sign(nb) + elif not fmt.endswith('.ipynb'): + self.notary.sign(nb) return nb diff --git a/tests/test_trust_notebook.py b/tests/test_trust_notebook.py index 412516d62..34b92ccb9 100644 --- a/tests/test_trust_notebook.py +++ b/tests/test_trust_notebook.py @@ -11,7 +11,8 @@ def test_py_notebooks_are_trusted(nb_file): root, file = os.path.split(nb_file) cm.root_dir = root nb = cm.get(file) - assert cm.notary.check_cells(nb['content']) + for cell in nb['content'].cells: + assert cell.metadata.get('trusted', True) @pytest.mark.parametrize('nb_file', list_all_notebooks('.Rmd')) @@ -20,7 +21,8 @@ def test_rmd_notebooks_are_trusted(nb_file): root, file = os.path.split(nb_file) cm.root_dir = root nb = cm.get(file) - assert cm.notary.check_cells(nb['content']) + for cell in nb['content'].cells: + assert cell.metadata.get('trusted', True) @pytest.mark.parametrize('nb_file', list_all_notebooks('.ipynb')) @@ -43,11 +45,13 @@ def test_ipynb_notebooks_can_be_trusted(nb_file, tmpdir): cm.notary.sign(nb) nb = cm.get(file) - assert cm.notary.check_cells(nb['content']) + for cell in nb['content'].cells: + assert cell.metadata.get('trusted', True) # Remove py file, content should be the same os.remove(tmp_py) nb2 = cm.get(file) - assert cm.notary.check_cells(nb2['content']) + for cell in nb2['content'].cells: + assert cell.metadata.get('trusted', True) assert nb['content'] == nb2['content'] From 48b4a731778da1185e90b76a853c60f6544bedb7 Mon Sep 17 00:00:00 2001 From: Marc Wouts Date: Tue, 21 Aug 2018 10:43:50 +0200 Subject: [PATCH 3/4] Version 0.5.1 --- HISTORY.rst | 7 +++++++ binder/requirements.txt | 2 +- setup.py | 2 +- 3 files changed, 9 insertions(+), 2 deletions(-) diff --git a/HISTORY.rst b/HISTORY.rst index 8abc52bfb..d1e3fead0 100644 --- a/HISTORY.rst +++ b/HISTORY.rst @@ -6,6 +6,13 @@ Release History dev +++ +0.5.1 (2018-08-21) ++++++++++++++++++++ + +**BugFixes** + +- Source only notebooks can be trusted. + 0.5.0 (2018-08-21) +++++++++++++++++++ diff --git a/binder/requirements.txt b/binder/requirements.txt index 8ba68987b..398d2c7ce 100644 --- a/binder/requirements.txt +++ b/binder/requirements.txt @@ -1,4 +1,4 @@ -nbrmd>=0.5.0 +nbrmd>=0.5.1 plotly matplotlib pandas diff --git a/setup.py b/setup.py index 62d6c7fd2..7e3a7aedd 100644 --- a/setup.py +++ b/setup.py @@ -7,7 +7,7 @@ setup( name='nbrmd', - version='0.5.0', + version='0.5.1', author='Marc Wouts', author_email='marc.wouts@gmail.com', description='Jupyter from/to R markdown notebooks', From 4a0c7a28d8714f2381146db1772d6f367cfd22aa Mon Sep 17 00:00:00 2001 From: Marc Wouts Date: Tue, 21 Aug 2018 10:52:29 +0200 Subject: [PATCH 4/4] Update README.md --- README.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index 1f9ab22c4..6d0f0534f 100644 --- a/README.md +++ b/README.md @@ -65,12 +65,12 @@ jupyter notebook With the above configuration, every Jupyter notebook will have a companion `.py` (`.nb.py`, or `.Rmd`) notebook. And every `.py` (`.nb.py`, or `.Rmd`) notebook will have a companion `.ipynb` notebook. -The default configuration can also contain multiple groups. Use +The default configuration can also contain multiple extension groups. Use ```python c.NotebookApp.contents_manager_class = "nbrmd.RmdFileContentsManager" c.ContentsManager.default_nbrmd_formats = "ipynb,nb.py;py.ipynb,py" ``` -if you want `.ipynb` notebooks to have `.nb.py` companion scripts, and `.py` files to have `.py.ipynb` companion notebooks (Learn more on the possible values for `nbrmd_formats` [here](https://github.com/mwouts/nbsrc/issues/5#issuecomment-414093471)). +if you want `.ipynb` notebooks to have `.nb.py` companion scripts, and `.py` files to have `.py.ipynb` companion notebooks (learn more on the possible values for `nbrmd_formats` [here](https://github.com/mwouts/nbsrc/issues/5#issuecomment-414093471)). ## Per notebook configuration