Repository: mwouts/jupytext
Pull request #403 (2019-12-20 05:44:56)

fix multiline comments instruction for percent

codecov[bot]: # [Codecov](https://codecov.io/gh/mwouts/jupytext/pull/403?src=pr&el=h1) Report
> Merging [#403](https://codecov.io/gh/mwouts/jupytext/pull/403?src=pr&el=desc) into [master](https://codecov.io/gh/mwouts/jupytext/commit/8cc0d8348f6cf989a1f4f354bda4bf2beafdd90d?src=pr&el=desc) will **decrease** coverage by `11.06%`.
> The diff coverage is `n/a`.

[![Impacted file tree graph](https://codecov.io/gh/mwouts/jupytext/pull/403/graphs/tree.svg?width=650&token=a1pNjsiILi&height=150&src=pr)](https://codecov.io/gh/mwouts/jupytext/pull/403?src=pr&el=tree)

```diff
@@             Coverage Diff             @@
##           master     #403       +/-   ##
===========================================
- Coverage   99.05%   87.99%   -11.07%     
===========================================
  Files          75       75               
  Lines        7538     7378      -160     
===========================================
- Hits         7467     6492      -975     
- Misses         71      886      +815
```


| [Impacted Files](https://codecov.io/gh/mwouts/jupytext/pull/403?src=pr&el=tree) | Coverage Δ | |
|---|---|---|
| [tests/test\_hide\_remove\_input\_outputs\_rmarkdown.py](https://codecov.io/gh/mwouts/jupytext/pull/403/diff?src=pr&el=tree#diff-dGVzdHMvdGVzdF9oaWRlX3JlbW92ZV9pbnB1dF9vdXRwdXRzX3JtYXJrZG93bi5weQ==) | `28.57% <0%> (-71.43%)` | :arrow_down: |
| [tests/test\_black.py](https://codecov.io/gh/mwouts/jupytext/pull/403/diff?src=pr&el=tree#diff-dGVzdHMvdGVzdF9ibGFjay5weQ==) | `31.53% <0%> (-68.47%)` | :arrow_down: |
| [tests/test\_mirror.py](https://codecov.io/gh/mwouts/jupytext/pull/403/diff?src=pr&el=tree#diff-dGVzdHMvdGVzdF9taXJyb3IucHk=) | `36.84% <0%> (-63.16%)` | :arrow_down: |
| [tests/test\_cell\_metadata.py](https://codecov.io/gh/mwouts/jupytext/pull/403/diff?src=pr&el=tree#diff-dGVzdHMvdGVzdF9jZWxsX21ldGFkYXRhLnB5) | `40.5% <0%> (-59.5%)` | :arrow_down: |
| [tests/test\_read\_simple\_pandoc.py](https://codecov.io/gh/mwouts/jupytext/pull/403/diff?src=pr&el=tree#diff-dGVzdHMvdGVzdF9yZWFkX3NpbXBsZV9wYW5kb2MucHk=) | `44.82% <0%> (-55.18%)` | :arrow_down: |
| [jupytext/pandoc.py](https://codecov.io/gh/mwouts/jupytext/pull/403/diff?src=pr&el=tree#diff-anVweXRleHQvcGFuZG9jLnB5) | `40.81% <0%> (-55.11%)` | :arrow_down: |
| [tests/test\_knitr\_spin.py](https://codecov.io/gh/mwouts/jupytext/pull/403/diff?src=pr&el=tree#diff-dGVzdHMvdGVzdF9rbml0cl9zcGluLnB5) | `45.45% <0%> (-54.55%)` | :arrow_down: |
| [tests/test\_active\_cells.py](https://codecov.io/gh/mwouts/jupytext/pull/403/diff?src=pr&el=tree#diff-dGVzdHMvdGVzdF9hY3RpdmVfY2VsbHMucHk=) | `52.54% <0%> (-47.46%)` | :arrow_down: |
| [tests/test\_contentsmanager.py](https://codecov.io/gh/mwouts/jupytext/pull/403/diff?src=pr&el=tree#diff-dGVzdHMvdGVzdF9jb250ZW50c21hbmFnZXIucHk=) | `69.18% <0%> (-30.82%)` | :arrow_down: |
| [tests/test\_rmd\_to\_ipynb.py](https://codecov.io/gh/mwouts/jupytext/pull/403/diff?src=pr&el=tree#diff-dGVzdHMvdGVzdF9ybWRfdG9faXB5bmIucHk=) | `75% <0%> (-25%)` | :arrow_down: |
| ... and [30 more](https://codecov.io/gh/mwouts/jupytext/pull/403/diff?src=pr&el=tree-more) | |

------

[Continue to review full report at Codecov](https://codecov.io/gh/mwouts/jupytext/pull/403?src=pr&el=continue).
> **Legend** - [Click here to learn more](https://docs.codecov.io/docs/codecov-delta)
> `Δ = absolute <relative> (impact)`, `ø = not affected`, `? = missing data`
> Powered by [Codecov](https://codecov.io/gh/mwouts/jupytext/pull/403?src=pr&el=footer). Last update [8cc0d83...0827828](https://codecov.io/gh/mwouts/jupytext/pull/403?src=pr&el=lastupdated). Read the [comment docs](https://docs.codecov.io/docs/pull-request-comments).


Patch:
diff --git a/CHANGELOG.md b/CHANGELOG.md
index c8774592..385d00f9 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -1,3 +1,10 @@
+1.3.1 (2019-12-??)
+------------------
+
+**Fixed**
+- Multiline strings are now accepted in the YAML header (#404). Fix contributed by ZHUO Qiang (#405).
+
+
 1.3.0 (2019-11-23)
 ------------------
 
diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md
index 9c105432..42f41c60 100644
--- a/CONTRIBUTING.md
+++ b/CONTRIBUTING.md
@@ -37,14 +37,13 @@ A pull request for which you do not need to contact us in advance is the additio
 Most of Jupytext's code is written in Python. To develop the Python part of Jupytext, you should clone Jupytext, then create a dedicated Python env:
 ```
 cd jupytext
-conda create -n jupytext-dev jupyterlab pyyaml
+conda env create --file environment.yml
 conda activate jupytext-dev
-pip install -r requirements-dev.txt
+pip install -e .
 ```
 
-Tests are executed with `pytest`. Install `pytest-xdist` to allow running the tests in parallel:
+Tests are executed with `pytest`. You can run them in parallel with for instance
 ```
-pip install pytest-xdist
 pytest -n 5
 ``` 
 
diff --git a/docs/formats.md b/docs/formats.md
index 98ebbee1..c077a9e1 100644
--- a/docs/formats.md
+++ b/docs/formats.md
@@ -195,9 +195,9 @@ that uses multiline comments
 """
 ```
 
-By default Jupytext will use line comments when it converts your Jupyter notebooks for `percent` scripts. If you prefer to use multiline comments for all text cells, add a `{"jupytext": '{"cell_markers": "\\"\\"\\""}'}` metadata to your notebook, either with the notebook metadata editor in Jupyter, or at the command line:
+By default Jupytext will use line comments when it converts your Jupyter notebooks for `percent` scripts. If you prefer to use multiline comments for all text cells, add a `{"jupytext": {"cell_markers": "\"\"\""}}` metadata to your notebook, either with the notebook metadata editor in Jupyter, or at the command line:
 ```bash
-jupytext --update-metadata '{"jupytext": {"cell_markers": "\\"\\"\\""}}' notebook.ipynb --to py:percent
+jupytext --update-metadata '{"jupytext": {"cell_markers": "\"\"\""}}' notebook.ipynb --to py:percent
 ```
 
 If you want to use multiline comments for all your paired notebooks, you could also add
diff --git a/environment.yml b/environment.yml
new file mode 100644
index 00000000..5d3cff21
--- /dev/null
+++ b/environment.yml
@@ -0,0 +1,21 @@
+name: jupytext-dev
+channels:
+  - default
+  - conda-forge
+dependencies:
+  - python==3.7
+  - jupyter
+  - pyyaml
+  - nbconvert
+  - jupyter_contrib_nbextensions
+  - pytest
+  - pytest-xdist
+  - pylint
+  - flake8
+  - black
+  - autopep8
+  - sphinx-gallery
+  - nodejs
+  - pip
+  - setuptools
+  - pandoc
diff --git a/jupytext/cell_reader.py b/jupytext/cell_reader.py
index ed6e595f..472706f6 100644
--- a/jupytext/cell_reader.py
+++ b/jupytext/cell_reader.py
@@ -509,7 +509,7 @@ class LightScriptCellReader(ScriptCellReader):
         self.comment = script['comment']
         self.ignore_end_marker = True
         self.explicit_end_marker_required = False
-        if fmt and 'cell_markers' in fmt and fmt['cell_markers'] != '+,-':
+        if fmt and fmt.get('format_name', 'light') == 'light' and 'cell_markers' in fmt and fmt['cell_markers'] != '+,-':
             self.cell_marker_start, self.cell_marker_end = fmt['cell_markers'].split(',', 1)
             self.start_code_re = re.compile('^' + self.comment + r'\s*' + self.cell_marker_start + r'(.*)$')
             self.end_code_re = re.compile('^' + self.comment + r'\s*' + self.cell_marker_end + r'\s*$')
diff --git a/jupytext/header.py b/jupytext/header.py
index b477b555..c23ff725 100644
--- a/jupytext/header.py
+++ b/jupytext/header.py
@@ -173,7 +173,7 @@ def header_to_metadata_and_cell(lines, header_prefix, ext=None):
 
         if _JUPYTER_RE.match(line):
             injupyter = True
-        elif not _LEFTSPACE_RE.match(line):
+        elif line and not _LEFTSPACE_RE.match(line):
             injupyter = False
 
         if injupyter:


Test patch:
diff --git a/tests/test_header.py b/tests/test_header.py
index 762456d1..9f9c86d3 100644
--- a/tests/test_header.py
+++ b/tests/test_header.py
@@ -99,3 +99,24 @@ def test_notebook_from_plain_script_has_metadata_filter(script="""print('Hello w
     script2 = jupytext.writes(nb, '.py')
 
     compare(script2, script)
+
+
+def test_multiline_metadata(
+        no_jupytext_version_number,
+        notebook=new_notebook(metadata={'multiline': """A multiline string
+
+with a blank line""", 'jupytext': {'notebook_metadata_filter': 'all'}}),
+        markdown="""---
+jupyter:
+  jupytext:
+    notebook_metadata_filter: all
+  multiline: 'A multiline string
+
+
+    with a blank line'
+---
+"""):
+    actual = jupytext.writes(notebook, '.md')
+    compare(actual, markdown)
+    nb2 = jupytext.reads(markdown, '.md')
+    compare(nb2, notebook)
diff --git a/tests/test_read_simple_percent.py b/tests/test_read_simple_percent.py
index 642d3a84..42af3889 100644
--- a/tests/test_read_simple_percent.py
+++ b/tests/test_read_simple_percent.py
@@ -389,3 +389,19 @@ def test_default_cell_markers_in_contents_manager_does_not_impact_light_format(t
 
     nb2 = jupytext.read(tmp_py)
     compare_notebooks(nb, nb2)
+
+
+def test_single_triple_quote_works(no_jupytext_version_number, text='''# ---
+# jupyter:
+#   jupytext:
+#     cell_markers: '"""'
+#     formats: ipynb,py:percent
+#     text_representation:
+#       extension: .py
+#       format_name: percent
+# ---
+
+# %%
+print("hello")
+''', notebook=new_notebook(cells=[new_code_cell('print("hello")')])):
+    compare_notebooks(jupytext.reads(text, 'py'), notebook)