diff --git a/nbrmd/nbrmd.py b/nbrmd/nbrmd.py index 22b3f121c..d2d2267a1 100644 --- a/nbrmd/nbrmd.py +++ b/nbrmd/nbrmd.py @@ -102,6 +102,10 @@ def to_notebook(self, text, **kwargs): if self.ext == '.Rmd': find_main_language(metadata, cells) + elif self.ext == '.R': + if not (metadata.get('main_language') or + metadata.get('language_info', {})): + metadata['main_language'] = 'R' nb = new_notebook(cells=cells, metadata=metadata) return nb @@ -140,6 +144,8 @@ def writes(self, nb, **kwargs): default_language = (nb.metadata.get('main_language') or nb.metadata.get('language_info', {}) .get('name', 'R')) + if nb.metadata.get('main_language') == 'R': + del nb.metadata['main_language'] else: default_language = get_default_language(nb) diff --git a/tests/knitr-spin.R b/tests/knitr-spin.R new file mode 100644 index 000000000..7aae90e35 --- /dev/null +++ b/tests/knitr-spin.R @@ -0,0 +1,44 @@ +#' This is a special R script which can be used to generate a report. You can +#' write normal text in roxygen comments. +#' +#' First we set up some options (you do not have to do this): + +#+ setup, include=FALSE +library(knitr) +opts_chunk$set(fig.path = 'figure/silk-') + +#' The report begins here. + +#+ test-a, cache=FALSE +# boring examples as usual +set.seed(123) +x = rnorm(5) +mean(x) + +#' You can not use here the special syntax {{code}} to embed inline expressions, e.g. +#' {{mean(x) + 2}} +#' is the mean of x plus 2. +#' The code itself may contain braces, but these are not checked. Thus, +#' perfectly valid (though very strange) R code such as `{{2 + 3}} - {{4 - 5}}` +#' can lead to errors because `2 + 3}} - {{4 - 5` will be treated as inline code. +#' +#' Now we continue writing the report. We can draw plots as well. + +#+ test-b, fig.height=5, fig.width=5 +par(mar = c(4, 4, .1, .1)); plot(x) + +#' Actually you do not have to write chunk options, in which case knitr will use +#' default options. For example, the code below has no options attached: + +var(x) +quantile(x) + +#' And you can also write two chunks successively like this: + +#+ test-chisq5 +sum(x^2) # chi-square distribution with df 5 +#+ test-chisq4 +sum((x - mean(x))^2) # df is 4 now + +#' Done. Call spin('knitr-spin.R') to make silk from sow's ear now and knit a +#' lovely purse. diff --git a/tests/knitr-spin.Rmd b/tests/knitr-spin.Rmd new file mode 100644 index 000000000..dd2b9d37b --- /dev/null +++ b/tests/knitr-spin.Rmd @@ -0,0 +1,51 @@ +This is a special R script which can be used to generate a report. You can +write normal text in roxygen comments. + +First we set up some options (you do not have to do this): + +```{r setup, include=FALSE} +library(knitr) +opts_chunk$set(fig.path = 'figure/silk-') +``` + +The report begins here. + +```{r test-a, cache=FALSE} +# boring examples as usual +set.seed(123) +x = rnorm(5) +mean(x) +``` + +You can not use here the special syntax {{code}} to embed inline expressions, e.g. +{{mean(x) + 2}} +is the mean of x plus 2. +The code itself may contain braces, but these are not checked. Thus, +perfectly valid (though very strange) R code such as `{{2 + 3}} - {{4 - 5}}` +can lead to errors because `2 + 3}} - {{4 - 5` will be treated as inline code. + +Now we continue writing the report. We can draw plots as well. + +```{r test-b, fig.height=5, fig.width=5} +par(mar = c(4, 4, .1, .1)); plot(x) +``` + +Actually you do not have to write chunk options, in which case knitr will use +default options. For example, the code below has no options attached: + +```{r} +var(x) +quantile(x) +``` + +And you can also write two chunks successively like this: + +```{r test-chisq5} +sum(x^2) # chi-square distribution with df 5 +``` +```{r test-chisq4} +sum((x - mean(x))^2) # df is 4 now +``` + +Done. Call spin('knitr-spin.R') to make silk from sow's ear now and knit a +lovely purse. diff --git a/tests/mirror/knitr-spin.ipynb b/tests/mirror/knitr-spin.ipynb new file mode 100644 index 000000000..482af5a24 --- /dev/null +++ b/tests/mirror/knitr-spin.ipynb @@ -0,0 +1,137 @@ +{ + "cells": [ + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "This is a special R script which can be used to generate a report. You can\n", + "write normal text in roxygen comments.\n", + "\n", + "First we set up some options (you do not have to do this):" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "hide_output": true, + "name": "setup" + }, + "outputs": [], + "source": [ + "library(knitr)\n", + "opts_chunk$set(fig.path = 'figure/silk-')" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "The report begins here." + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "cache": false, + "name": "test-a" + }, + "outputs": [], + "source": [ + "# boring examples as usual\n", + "set.seed(123)\n", + "x = rnorm(5)\n", + "mean(x)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "You can not use here the special syntax {{code}} to embed inline expressions, e.g.\n", + "{{mean(x) + 2}}\n", + "is the mean of x plus 2.\n", + "The code itself may contain braces, but these are not checked. Thus,\n", + "perfectly valid (though very strange) R code such as `{{2 + 3}} - {{4 - 5}}`\n", + "can lead to errors because `2 + 3}} - {{4 - 5` will be treated as inline code.\n", + "\n", + "Now we continue writing the report. We can draw plots as well." + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "fig.height": 5, + "fig.width": 5, + "name": "test-b" + }, + "outputs": [], + "source": [ + "par(mar = c(4, 4, .1, .1)); plot(x)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Actually you do not have to write chunk options, in which case knitr will use\n", + "default options. For example, the code below has no options attached:" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "var(x)\n", + "quantile(x)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "And you can also write two chunks successively like this:" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "name": "test-chisq5", + "noskipline": true + }, + "outputs": [], + "source": [ + "sum(x^2) # chi-square distribution with df 5" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "name": "test-chisq4" + }, + "outputs": [], + "source": [ + "sum((x - mean(x))^2) # df is 4 now" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Done. Call spin('knitr-spin.R') to make silk from sow's ear now and knit a\n", + "lovely purse." + ] + } + ], + "metadata": { + "main_language": "R" + }, + "nbformat": 4, + "nbformat_minor": 2 +} diff --git a/tests/test_knitr_spin.py b/tests/test_knitr_spin.py new file mode 100644 index 000000000..f8d53bbb4 --- /dev/null +++ b/tests/test_knitr_spin.py @@ -0,0 +1,23 @@ +import sys +import pytest +import nbrmd +from .utils import list_all_notebooks + +nbrmd.file_format_version.FILE_FORMAT_VERSION = {} + + +@pytest.mark.skipif(sys.version_info < (3, 6), + reason="unordered dict result in changes in chunk options") +@pytest.mark.parametrize('r_file', + list_all_notebooks('.R')) +def test_nbrmd_same_as_knitr_spin(r_file, tmpdir): + nb = nbrmd.readf(r_file) + rmd_nbrmd = nbrmd.writes(nb, ext='.Rmd') + + # Rmd file generated with spin(hair='R/spin.R', knit=FALSE) + rmd_file = r_file.replace('.R', '.Rmd') + + with open(rmd_file) as fp: + rmd_spin = fp.read() + + assert rmd_nbrmd == rmd_spin