diff --git a/HISTORY.rst b/HISTORY.rst index e0c0218e9..db4c9d090 100644 --- a/HISTORY.rst +++ b/HISTORY.rst @@ -3,6 +3,13 @@ Release History --------------- +1.0.2 (2019-02-??) +++++++++++++++++++++++ + +**BugFixes** +- Allow spaces between ``?`` or ``!`` and python or bash command (#189) + + 1.0.1 (2019-02-23) ++++++++++++++++++++++ diff --git a/jupytext/contentsmanager.py b/jupytext/contentsmanager.py index e637df558..1020fa3ea 100644 --- a/jupytext/contentsmanager.py +++ b/jupytext/contentsmanager.py @@ -413,6 +413,14 @@ def trust_notebook(self, path): def rename_file(self, old_path, new_path): """Rename the current notebook, as well as its alternative representations""" + if old_path not in self.paired_notebooks: + try: + # we do not know yet if this is a paired notebook (#190) + # -> to get this information we open the notebook + self.get(old_path, content=True) + except Exception: + pass + if old_path not in self.paired_notebooks: super(TextFileContentsManager, self).rename_file(old_path, new_path) return diff --git a/jupytext/languages.py b/jupytext/languages.py index 3eea0b542..6c3cf5993 100644 --- a/jupytext/languages.py +++ b/jupytext/languages.py @@ -10,6 +10,7 @@ '.cpp': {'language': 'c++', 'comment': '//'}, '.ss': {'language': 'scheme', 'comment': ';;'}, '.clj': {'language': 'clojure', 'comment': ';;'}, + '.scm': {'language': 'scheme', 'comment': ';;'}, '.sh': {'language': 'bash', 'comment': '#'}, '.q': {'language': 'q', 'comment': '/'}} diff --git a/jupytext/magics.py b/jupytext/magics.py index e089abae4..3704673f3 100644 --- a/jupytext/magics.py +++ b/jupytext/magics.py @@ -16,7 +16,7 @@ _COMMENT = {_SCRIPT_EXTENSIONS[ext]['language']: _SCRIPT_EXTENSIONS[ext]['comment'] for ext in _SCRIPT_EXTENSIONS} # Commands starting with a question or exclamation mark have to be escaped -_PYTHON_HELP_OR_BASH_CMD = re.compile(r"^(# |#)*(\?|!)[A-Za-z]") +_PYTHON_HELP_OR_BASH_CMD = re.compile(r"^(# |#)*(\?|!)\s*[A-Za-z]") _PYTHON_MAGIC_CMD = re.compile(r"^(# |#)*({})(\s|$)".format('|'.join( # posix diff --git a/jupytext/version.py b/jupytext/version.py index 8e49dc8eb..86b6eea1f 100644 --- a/jupytext/version.py +++ b/jupytext/version.py @@ -1,3 +1,3 @@ """Jupytext's version number""" -__version__ = '1.0.1' +__version__ = '1.0.2-dev' diff --git a/tests/notebooks/mirror/ipynb_to_percent/Reference Guide for Calysto Scheme.scm b/tests/notebooks/mirror/ipynb_to_percent/Reference Guide for Calysto Scheme.scm new file mode 100644 index 000000000..f0b527eb1 --- /dev/null +++ b/tests/notebooks/mirror/ipynb_to_percent/Reference Guide for Calysto Scheme.scm @@ -0,0 +1,443 @@ +;; -*- coding: utf-8 -*- +;; --- +;; jupyter: +;; kernelspec: +;; display_name: Calysto Scheme (Python) +;; language: scheme +;; name: calysto_scheme +;; --- + +;; %% [markdown] +;; +;;

Reference Guide for Calysto Scheme

+;; +;; [Calysto Scheme](https://github.com/Calysto/calysto_scheme) is a real Scheme programming language, with full support for continuations, including call/cc. It can also use all Python libraries. Also has some extensions that make it more useful (stepper-debugger, choose/fail, stack traces), or make it better integrated with Python. +;; +;; In Jupyter notebooks, because Calysto Scheme uses [MetaKernel](https://github.com/Calysto/metakernel/blob/master/README.rst), it has a fully-supported set of "magics"---meta-commands for additional functionality. This includes running Scheme in parallel. See all of the [MetaKernel Magics](https://github.com/Calysto/metakernel/blob/master/metakernel/magics/README.md). +;; +;; Calysto Scheme is written in Scheme, and then translated into Python (and other backends). The entire functionality lies in a single Python file: https://github.com/Calysto/calysto_scheme/blob/master/calysto_scheme/scheme.py However, you can easily install it (see below). +;; +;; Please see [Calysto Scheme Language](Calysto%20Scheme%20Language.ipynb) for more details on the Calysto Scheme language. +;; +;; ## Installation +;; +;; You can install Calysto Scheme with Python3: +;; +;; ``` +;; pip3 install --upgrade calysto-scheme --user -U +;; python3 -m calysto_kernel install --user +;; ``` +;; +;; or in the system kernel folder with: +;; +;; ``` +;; sudo pip3 install --upgrade calysto-scheme -U +;; sudo python3 -m calysto_kernel install +;; ``` +;; +;; Change pip3/python3 to use a different pip or Python. The version of Python used will determine how Calysto Scheme is run. +;; +;; Use it in the console, qtconsole, or notebook with IPython 3: +;; +;; ``` +;; ipython console --kernel calysto_scheme +;; ipython qtconsole --kernel calysto_scheme +;; ipython notebook --kernel calysto_scheme +;; ``` +;; +;; In addition to all of the following items, Calysto Scheme also has access to all of Python's builtin functions, and all of Python's libraries. For example, you can use `(complex 3 2)` to create a complex number by calling Python's complex function. +;; +;; ## Jupyter Enhancements +;; +;; When you run Calysto Scheme in Jupyter (console, notebook, qtconsole, etc.) you get: +;; +;; * TAB completions of Scheme functions and variable names +;; * display of rich media +;; * stepper/debugger +;; * magics (% macros) +;; * shell commands (! command) +;; * LaTeX equations +;; * LaTeX-style variables +;; * Python integration + +;; %% [markdown] +;; ### LaTeX-style variables +;; +;; Calysto Scheme allows you to use LaTeX-style variables in code. For example, if you type: +;; +;; ``` +;; \beta +;; ``` +;; +;; with the cursor right after the 'a' in beta, and then press TAB, it will turn into the unicode character: +;; +;; ``` +;; β +;; ``` +;; +;; There are nearly 1300 different symbols defined (thanks to the Julia language) and documented here: +;; +;; http://docs.julialang.org/en/release-0.4/manual/unicode-input/#man-unicode-input +;; +;; Calysto Scheme may not implement all of those. Some useful and suggestive ones: +;; +;; * \pi - π +;; * \Pi - Π +;; * \Sigma - Σ +;; * \_i - subscript i, such as vectorᵢ + +;; %% +(define α 67) + +;; %% +α + +;; %% +(define i 2) +(define vectorᵢ (vector-ref (vector 0 6 3 2) i)) +vectorᵢ + +;; %% [markdown] +;; ### Rich media + +;; %% +(import "calysto.display") + +;; %% +(calysto.display.HTML "This is bold, italics, underlined.") + +;; %% +(import "calysto.graphics") + +;; %% +(define canvas (calysto.graphics.Canvas)) + +;; %% +(define ball (calysto.graphics.Circle '(150 150) 100)) + +;; %% +(ball.draw canvas) + +;; %% [markdown] +;; ### Shell commands + +;; %% +! ls /tmp + +;; %% [markdown] +;; ### Stepper/Debugger +;; +;; Here is what the debugger looks like: +;; +;; +;; +;; It has breakpoints (click in left margin). You must press Stop to exit the debugger. + +;; %% [markdown] +;; ```scheme +;; %%debug +;; +;; (begin +;; (define x 1) +;; (set! x 2) +;; ) +;; ``` + +;; %% [markdown] +;; ### Python Integration +;; +;; You can import and use any Python library in Calysto Scheme. +;; +;; In addition, if you wish, you can execute expressions and statements in a Python environment: + +;; %% +(python-eval "1 + 2") + +;; %% +(python-exec +" +def mypyfunc(a, b): + return a * b +") + +;; %% [markdown] +;; This is a shared environment with Scheme: + +;; %% +(mypyfunc 4 5) + +;; %% [markdown] +;; You can use `func` to turn a Scheme procedure into a Python function, and `define!` to put it into the shared enviornment with Python: + +;; %% +(define! mypyfunc2 (func (lambda (n) n))) + +;; %% +(python-eval "mypyfunc2(34)") + +;; %% [markdown] +;; # Differences Between Languages +;; +;; ## Major differences between Scheme and Python +;; +;; 1. In Scheme, double quotes are used for strings and may contain newlines +;; 1. In Scheme, a single quote is short for (quote ...) and means "literal" +;; 1. In Scheme, everything is an expression and has a return value +;; 1. Python does not support macros (e.g., extending syntax) +;; 1. In Python, "if X" is false if X is None, False, [], (,) or 0. In Scheme, "if X" is only false if X is #f or 0 +;; 1. Calysto Scheme uses continuations, not the call stack. However, for debugging there is a pseudo-stack when an error is raised. You can trun that off with (use-stack-trace #f) +;; 1. Scheme procedures are not Python functions, but there are means to use one as the other. +;; +;; ## Major Differences Between Calysto Scheme and other Schemes +;; +;; 1. define-syntax works slightly differently +;; 1. In Calysto Scheme, #(...) is short for '#(...) +;; 1. Calysto Scheme is missing many standard functions (see list at bottom) +;; 1. Calysto Scheme has a built-in amb operator called `choose` +;; 1. For debugging there is a pseudo-stack when errors are raised in Calysto Scheme. You can trun that off with (use-stack-trace #f) +;; +;; ### Stack Trace +;; +;; Calysto Scheme acts as if it has a call stack, for easier debugging. For example: + +;; %% +(define fact + (lambda (n) + (if (= n 1) + q + (* n (fact (- n 1)))))) + +;; %% +(fact 5) + +;; %% [markdown] +;; To turn off the stack trace on error: +;; +;; ```scheme +;; (use-stack-trace #f) +;; ``` +;; That will allow infinite recursive loops without keeping track of the "stack". + +;; %% [markdown] +;; # Calysto Scheme Variables +;; +;; ## SCHEMEPATH +;; SCHEMEPATH is a list of search directories used with (load NAME). This is a reference, so you should append to it rather than attempting to redefine it. + +;; %% +SCHEMEPATH + +;; %% +(set-cdr! (cdr SCHEMEPATH) (list "/var/modules")) + +;; %% +SCHEMEPATH + +;; %% [markdown] +;; ## Getting Started +;; +;; Note that you can use the word `lambda` or \lambda and then press [TAB] + +;; %% +(define factorial + (λ (n) + (cond + ((zero? n) 1) + (else (* n (factorial (- n 1))))))) + +;; %% +(factorial 5) + +;; %% [markdown] +;; ## define-syntax +;; (define-syntax NAME RULES): a method for creating macros + +;; %% +(define-syntax time + [(time ?exp) (let ((start (current-time))) + ?exp + (- (current-time) start))]) + +;; %% +(time (car '(1 2 3 4))) + +;; %% +;;--------------------------------------------------------------------- +;; collect is like list comprehension in Python + +(define-syntax collect + [(collect ?exp for ?var in ?list) + (filter-map (lambda (?var) ?exp) (lambda (?var) #t) ?list)] + [(collect ?exp for ?var in ?list if ?condition) + (filter-map (lambda (?var) ?exp) (lambda (?var) ?condition) ?list)]) + +(define filter-map + (lambda (f pred? values) + (if (null? values) + '() + (if (pred? (car values)) + (cons (f (car values)) (filter-map f pred? (cdr values))) + (filter-map f pred? (cdr values)))))) + +;; %% +(collect (* n n) for n in (range 10)) + +;; %% +(collect (* n n) for n in (range 5 20 3)) + +;; %% +(collect (* n n) for n in (range 10) if (> n 5)) + +;; %% +;;--------------------------------------------------------------------- +;; for loops + +(define-syntax for + [(for ?exp times do . ?bodies) + (for-repeat ?exp (lambda () . ?bodies))] + [(for ?var in ?exp do . ?bodies) + (for-iterate1 ?exp (lambda (?var) . ?bodies))] + [(for ?var at (?i) in ?exp do . ?bodies) + (for-iterate2 0 ?exp (lambda (?var ?i) . ?bodies))] + [(for ?var at (?i ?j . ?rest) in ?exp do . ?bodies) + (for ?var at (?i) in ?exp do + (for ?var at (?j . ?rest) in ?var do . ?bodies))]) + +(define for-repeat + (lambda (n f) + (if (< n 1) + 'done + (begin + (f) + (for-repeat (- n 1) f))))) + +(define for-iterate1 + (lambda (values f) + (if (null? values) + 'done + (begin + (f (car values)) + (for-iterate1 (cdr values) f))))) + +(define for-iterate2 + (lambda (i values f) + (if (null? values) + 'done + (begin + (f (car values) i) + (for-iterate2 (+ i 1) (cdr values) f))))) + +;; %% +(define matrix2d + '((10 20) + (30 40) + (50 60) + (70 80))) + +(define matrix3d + '(((10 20 30) (40 50 60)) + ((70 80 90) (100 110 120)) + ((130 140 150) (160 170 180)) + ((190 200 210) (220 230 240)))) + +;; %% +(begin + (define hello 0) + (for 5 times do (set! hello (+ hello 1))) + hello + ) + +;; %% +(for sym in '(a b c d) do (define x 1) (set! x sym) (print x)) + +;; %% +(for n in (range 10 20 2) do (print n)) + +;; %% +(for n at (i j) in matrix2d do (print (list n 'coords: i j))) + +;; %% +(for n at (i j k) in matrix3d do (print (list n 'coords: i j k))) + +;; %% +(define-syntax scons + [(scons ?x ?y) (cons ?x (lambda () ?y))]) + +(define scar car) + +(define scdr + (lambda (s) + (let ((result ((cdr s)))) + (set-cdr! s (lambda () result)) + result))) + +(define first + (lambda (n s) + (if (= n 0) + '() + (cons (scar s) (first (- n 1) (scdr s)))))) + +(define nth + (lambda (n s) + (if (= n 0) + (scar s) + (nth (- n 1) (scdr s))))) + +(define smap + (lambda (f s) + (scons (f (scar s)) (smap f (scdr s))))) + +(define ones (scons 1 ones)) + +(define nats (scons 0 (combine nats + ones))) + +(define combine + (lambda (s1 op s2) + (scons (op (scar s1) (scar s2)) (combine (scdr s1) op (scdr s2))))) + +(define fibs (scons 1 (scons 1 (combine fibs + (scdr fibs))))) + +(define facts (scons 1 (combine facts * (scdr nats)))) + +(define ! (lambda (n) (nth n facts))) + +;; %% +(! 5) + +;; %% +(nth 10 facts) + +;; %% +(nth 20 fibs) + +;; %% +(first 30 fibs) + +;; %% [markdown] +;; ## for-each +;; (for-each PROCEDURE LIST): apply PROCEDURE to each item in LIST; like `map` but don't return results + +;; %% +(for-each (lambda (n) (print n)) '(3 4 5)) + +;; %% [markdown] +;; ## format +;; (format STRING ITEM ...): format the string with ITEMS as arguments + +;; %% +(format "This uses formatting ~a ~s ~%" 'apple 'apple) + +;; %% [markdown] +;; ## func +;; +;; Turns a lambda into a Python function. +;; +;; (func (lambda ...)) + +;; %% +(func (lambda (n) n)) + +;; %% [markdown] +;; ## There's more! +;; +;; Please see [Calysto Scheme Language](Calysto%20Scheme%20Language.ipynb) for more details on the Calysto Scheme language. diff --git a/tests/notebooks/mirror/ipynb_to_script/Reference Guide for Calysto Scheme.scm b/tests/notebooks/mirror/ipynb_to_script/Reference Guide for Calysto Scheme.scm new file mode 100644 index 000000000..ba044c3bd --- /dev/null +++ b/tests/notebooks/mirror/ipynb_to_script/Reference Guide for Calysto Scheme.scm @@ -0,0 +1,389 @@ +;; -*- coding: utf-8 -*- +;; --- +;; jupyter: +;; kernelspec: +;; display_name: Calysto Scheme (Python) +;; language: scheme +;; name: calysto_scheme +;; --- + +;; +;;

Reference Guide for Calysto Scheme

+;; +;; [Calysto Scheme](https://github.com/Calysto/calysto_scheme) is a real Scheme programming language, with full support for continuations, including call/cc. It can also use all Python libraries. Also has some extensions that make it more useful (stepper-debugger, choose/fail, stack traces), or make it better integrated with Python. +;; +;; In Jupyter notebooks, because Calysto Scheme uses [MetaKernel](https://github.com/Calysto/metakernel/blob/master/README.rst), it has a fully-supported set of "magics"---meta-commands for additional functionality. This includes running Scheme in parallel. See all of the [MetaKernel Magics](https://github.com/Calysto/metakernel/blob/master/metakernel/magics/README.md). +;; +;; Calysto Scheme is written in Scheme, and then translated into Python (and other backends). The entire functionality lies in a single Python file: https://github.com/Calysto/calysto_scheme/blob/master/calysto_scheme/scheme.py However, you can easily install it (see below). +;; +;; Please see [Calysto Scheme Language](Calysto%20Scheme%20Language.ipynb) for more details on the Calysto Scheme language. +;; +;; ## Installation +;; +;; You can install Calysto Scheme with Python3: +;; +;; ``` +;; pip3 install --upgrade calysto-scheme --user -U +;; python3 -m calysto_kernel install --user +;; ``` +;; +;; or in the system kernel folder with: +;; +;; ``` +;; sudo pip3 install --upgrade calysto-scheme -U +;; sudo python3 -m calysto_kernel install +;; ``` +;; +;; Change pip3/python3 to use a different pip or Python. The version of Python used will determine how Calysto Scheme is run. +;; +;; Use it in the console, qtconsole, or notebook with IPython 3: +;; +;; ``` +;; ipython console --kernel calysto_scheme +;; ipython qtconsole --kernel calysto_scheme +;; ipython notebook --kernel calysto_scheme +;; ``` +;; +;; In addition to all of the following items, Calysto Scheme also has access to all of Python's builtin functions, and all of Python's libraries. For example, you can use `(complex 3 2)` to create a complex number by calling Python's complex function. +;; +;; ## Jupyter Enhancements +;; +;; When you run Calysto Scheme in Jupyter (console, notebook, qtconsole, etc.) you get: +;; +;; * TAB completions of Scheme functions and variable names +;; * display of rich media +;; * stepper/debugger +;; * magics (% macros) +;; * shell commands (! command) +;; * LaTeX equations +;; * LaTeX-style variables +;; * Python integration + +;; ### LaTeX-style variables +;; +;; Calysto Scheme allows you to use LaTeX-style variables in code. For example, if you type: +;; +;; ``` +;; \beta +;; ``` +;; +;; with the cursor right after the 'a' in beta, and then press TAB, it will turn into the unicode character: +;; +;; ``` +;; β +;; ``` +;; +;; There are nearly 1300 different symbols defined (thanks to the Julia language) and documented here: +;; +;; http://docs.julialang.org/en/release-0.4/manual/unicode-input/#man-unicode-input +;; +;; Calysto Scheme may not implement all of those. Some useful and suggestive ones: +;; +;; * \pi - π +;; * \Pi - Π +;; * \Sigma - Σ +;; * \_i - subscript i, such as vectorᵢ + +(define α 67) + +α + +(define i 2) +(define vectorᵢ (vector-ref (vector 0 6 3 2) i)) +vectorᵢ + +;; ### Rich media + +(import "calysto.display") + +(calysto.display.HTML "This is bold, italics, underlined.") + +(import "calysto.graphics") + +(define canvas (calysto.graphics.Canvas)) + +(define ball (calysto.graphics.Circle '(150 150) 100)) + +(ball.draw canvas) + +;; ### Shell commands + +! ls /tmp + +;; ### Stepper/Debugger +;; +;; Here is what the debugger looks like: +;; +;; +;; +;; It has breakpoints (click in left margin). You must press Stop to exit the debugger. + +;; ```scheme +;; ;; %%debug +;; +;; (begin +;; (define x 1) +;; (set! x 2) +;; ) +;; ``` + +;; ### Python Integration +;; +;; You can import and use any Python library in Calysto Scheme. +;; +;; In addition, if you wish, you can execute expressions and statements in a Python environment: + +(python-eval "1 + 2") + +(python-exec +" +def mypyfunc(a, b): + return a * b +") + +;; This is a shared environment with Scheme: + +(mypyfunc 4 5) + +;; You can use `func` to turn a Scheme procedure into a Python function, and `define!` to put it into the shared enviornment with Python: + +(define! mypyfunc2 (func (lambda (n) n))) + +(python-eval "mypyfunc2(34)") + +;; # Differences Between Languages +;; +;; ## Major differences between Scheme and Python +;; +;; 1. In Scheme, double quotes are used for strings and may contain newlines +;; 1. In Scheme, a single quote is short for (quote ...) and means "literal" +;; 1. In Scheme, everything is an expression and has a return value +;; 1. Python does not support macros (e.g., extending syntax) +;; 1. In Python, "if X" is false if X is None, False, [], (,) or 0. In Scheme, "if X" is only false if X is #f or 0 +;; 1. Calysto Scheme uses continuations, not the call stack. However, for debugging there is a pseudo-stack when an error is raised. You can trun that off with (use-stack-trace #f) +;; 1. Scheme procedures are not Python functions, but there are means to use one as the other. +;; +;; ## Major Differences Between Calysto Scheme and other Schemes +;; +;; 1. define-syntax works slightly differently +;; 1. In Calysto Scheme, #(...) is short for '#(...) +;; 1. Calysto Scheme is missing many standard functions (see list at bottom) +;; 1. Calysto Scheme has a built-in amb operator called `choose` +;; 1. For debugging there is a pseudo-stack when errors are raised in Calysto Scheme. You can trun that off with (use-stack-trace #f) +;; +;; ### Stack Trace +;; +;; Calysto Scheme acts as if it has a call stack, for easier debugging. For example: + +(define fact + (lambda (n) + (if (= n 1) + q + (* n (fact (- n 1)))))) + +(fact 5) + +;; To turn off the stack trace on error: +;; +;; ```scheme +;; (use-stack-trace #f) +;; ``` +;; That will allow infinite recursive loops without keeping track of the "stack". + +;; # Calysto Scheme Variables +;; +;; ## SCHEMEPATH +;; SCHEMEPATH is a list of search directories used with (load NAME). This is a reference, so you should append to it rather than attempting to redefine it. + +SCHEMEPATH + +(set-cdr! (cdr SCHEMEPATH) (list "/var/modules")) + +SCHEMEPATH + +;; ## Getting Started +;; +;; Note that you can use the word `lambda` or \lambda and then press [TAB] + +(define factorial + (λ (n) + (cond + ((zero? n) 1) + (else (* n (factorial (- n 1))))))) + +(factorial 5) + +;; ## define-syntax +;; (define-syntax NAME RULES): a method for creating macros + +(define-syntax time + [(time ?exp) (let ((start (current-time))) + ?exp + (- (current-time) start))]) + +(time (car '(1 2 3 4))) + +;; + +;;--------------------------------------------------------------------- +;; collect is like list comprehension in Python + +(define-syntax collect + [(collect ?exp for ?var in ?list) + (filter-map (lambda (?var) ?exp) (lambda (?var) #t) ?list)] + [(collect ?exp for ?var in ?list if ?condition) + (filter-map (lambda (?var) ?exp) (lambda (?var) ?condition) ?list)]) + +(define filter-map + (lambda (f pred? values) + (if (null? values) + '() + (if (pred? (car values)) + (cons (f (car values)) (filter-map f pred? (cdr values))) + (filter-map f pred? (cdr values)))))) +;; - + +(collect (* n n) for n in (range 10)) + +(collect (* n n) for n in (range 5 20 3)) + +(collect (* n n) for n in (range 10) if (> n 5)) + +;; + +;;--------------------------------------------------------------------- +;; for loops + +(define-syntax for + [(for ?exp times do . ?bodies) + (for-repeat ?exp (lambda () . ?bodies))] + [(for ?var in ?exp do . ?bodies) + (for-iterate1 ?exp (lambda (?var) . ?bodies))] + [(for ?var at (?i) in ?exp do . ?bodies) + (for-iterate2 0 ?exp (lambda (?var ?i) . ?bodies))] + [(for ?var at (?i ?j . ?rest) in ?exp do . ?bodies) + (for ?var at (?i) in ?exp do + (for ?var at (?j . ?rest) in ?var do . ?bodies))]) + +(define for-repeat + (lambda (n f) + (if (< n 1) + 'done + (begin + (f) + (for-repeat (- n 1) f))))) + +(define for-iterate1 + (lambda (values f) + (if (null? values) + 'done + (begin + (f (car values)) + (for-iterate1 (cdr values) f))))) + +(define for-iterate2 + (lambda (i values f) + (if (null? values) + 'done + (begin + (f (car values) i) + (for-iterate2 (+ i 1) (cdr values) f))))) + +;; + +(define matrix2d + '((10 20) + (30 40) + (50 60) + (70 80))) + +(define matrix3d + '(((10 20 30) (40 50 60)) + ((70 80 90) (100 110 120)) + ((130 140 150) (160 170 180)) + ((190 200 210) (220 230 240)))) +;; - + +(begin + (define hello 0) + (for 5 times do (set! hello (+ hello 1))) + hello + ) + +(for sym in '(a b c d) do (define x 1) (set! x sym) (print x)) + +(for n in (range 10 20 2) do (print n)) + +(for n at (i j) in matrix2d do (print (list n 'coords: i j))) + +(for n at (i j k) in matrix3d do (print (list n 'coords: i j k))) + +;; + +(define-syntax scons + [(scons ?x ?y) (cons ?x (lambda () ?y))]) + +(define scar car) + +(define scdr + (lambda (s) + (let ((result ((cdr s)))) + (set-cdr! s (lambda () result)) + result))) + +(define first + (lambda (n s) + (if (= n 0) + '() + (cons (scar s) (first (- n 1) (scdr s)))))) + +(define nth + (lambda (n s) + (if (= n 0) + (scar s) + (nth (- n 1) (scdr s))))) + +(define smap + (lambda (f s) + (scons (f (scar s)) (smap f (scdr s))))) + +(define ones (scons 1 ones)) + +(define nats (scons 0 (combine nats + ones))) + +(define combine + (lambda (s1 op s2) + (scons (op (scar s1) (scar s2)) (combine (scdr s1) op (scdr s2))))) + +(define fibs (scons 1 (scons 1 (combine fibs + (scdr fibs))))) + +(define facts (scons 1 (combine facts * (scdr nats)))) + +(define ! (lambda (n) (nth n facts))) +;; - + +(! 5) + +(nth 10 facts) + +(nth 20 fibs) + +(first 30 fibs) + +;; ## for-each +;; (for-each PROCEDURE LIST): apply PROCEDURE to each item in LIST; like `map` but don't return results + +(for-each (lambda (n) (print n)) '(3 4 5)) + +;; ## format +;; (format STRING ITEM ...): format the string with ITEMS as arguments + +(format "This uses formatting ~a ~s ~%" 'apple 'apple) + +;; ## func +;; +;; Turns a lambda into a Python function. +;; +;; (func (lambda ...)) + +(func (lambda (n) n)) + +;; ## There's more! +;; +;; Please see [Calysto Scheme Language](Calysto%20Scheme%20Language.ipynb) for more details on the Calysto Scheme language. diff --git a/tests/test_cli.py b/tests/test_cli.py index 6ef6af711..564a118ba 100644 --- a/tests/test_cli.py +++ b/tests/test_cli.py @@ -15,7 +15,7 @@ from jupytext.compare import compare_notebooks from jupytext.paired_paths import paired_paths from jupytext.formats import long_form_one_format, JupytextFormatError -from .utils import list_notebooks, requires_black, requires_flake8 +from .utils import list_notebooks, requires_black, requires_flake8, skip_if_dict_is_not_ordered def test_str2bool(): @@ -304,6 +304,7 @@ def test_convert_to_percent_format_and_keep_magics(nb_file, tmpdir): compare_notebooks(nb1, nb2) +@skip_if_dict_is_not_ordered def test_pre_commit_hook(tmpdir): tmp_ipynb = str(tmpdir.join('nb with spaces.ipynb')) tmp_py = str(tmpdir.join('nb with spaces.py')) @@ -334,6 +335,7 @@ def git(*args): assert os.path.isfile(tmp_py) +@skip_if_dict_is_not_ordered def test_pre_commit_hook_py_to_ipynb_and_md(tmpdir): tmp_ipynb = str(tmpdir.join('nb with spaces.ipynb')) tmp_py = str(tmpdir.join('nb with spaces.py')) diff --git a/tests/test_escape_magics.py b/tests/test_escape_magics.py index 77fb01d71..190f9dc88 100644 --- a/tests/test_escape_magics.py +++ b/tests/test_escape_magics.py @@ -107,22 +107,22 @@ def test_force_comment_using_contents_manager(tmpdir): assert '%pylab inline' in stream.read().splitlines() -@pytest.mark.parametrize('magic_cmd', ['ls', '!ls', 'ls -al', '!whoami', '# ls', '# mv a b']) +@pytest.mark.parametrize('magic_cmd', ['ls', '!ls', 'ls -al', '!whoami', '# ls', '# mv a b', '! mkdir tmp']) def test_comment_bash_commands_in_python(magic_cmd): - comment_magic([magic_cmd]) == ['# ' + magic_cmd] - uncomment_magic(['# ' + magic_cmd]) == magic_cmd + assert comment_magic([magic_cmd]) == ['# ' + magic_cmd] + assert uncomment_magic(['# ' + magic_cmd]) == [magic_cmd] @pytest.mark.parametrize('not_magic_cmd', ['copy(a)', 'copy.deepcopy']) def test_do_not_comment_python_cmds(not_magic_cmd): - comment_magic([not_magic_cmd]) == [not_magic_cmd] - uncomment_magic([not_magic_cmd]) == not_magic_cmd + assert comment_magic([not_magic_cmd]) == [not_magic_cmd] + assert uncomment_magic([not_magic_cmd]) == [not_magic_cmd] @pytest.mark.parametrize('magic_cmd', ['ls', '!ls', 'ls -al', '!whoami', '# ls', '# mv a b']) def test_do_not_comment_bash_commands_in_R(magic_cmd): - comment_magic([magic_cmd], language='R') == ['# ' + magic_cmd] - uncomment_magic(['# ' + magic_cmd], language='R') == magic_cmd + assert comment_magic([magic_cmd], language='R') == [magic_cmd] + assert uncomment_magic([magic_cmd], language='R') == [magic_cmd] def test_markdown_image_is_not_magic(): diff --git a/tests/test_mirror.py b/tests/test_mirror.py index a3a59a097..34c1229ef 100644 --- a/tests/test_mirror.py +++ b/tests/test_mirror.py @@ -109,9 +109,12 @@ def test_ipynb_to_r(nb_file): assert_conversion_same_as_mirror(nb_file, '.low.r', 'ipynb_to_script') -@pytest.mark.parametrize('nb_file', list_notebooks('ipynb_scheme')) -def test_ipynb_to_scheme(nb_file): - assert_conversion_same_as_mirror(nb_file, 'ss', 'ipynb_to_script') +@pytest.mark.parametrize('nb_file,extension', + [(nb_file, extension) + for nb_file in list_notebooks('ipynb_scheme') + for extension in ('ss', 'scm')]) +def test_ipynb_to_scheme(nb_file, extension): + assert_conversion_same_as_mirror(nb_file, extension, 'ipynb_to_script') @pytest.mark.parametrize('nb_file', list_notebooks('ipynb_clojure')) @@ -174,9 +177,14 @@ def test_ipynb_to_cpp_percent(nb_file): assert_conversion_same_as_mirror(nb_file, 'cpp:percent', 'ipynb_to_percent') -@pytest.mark.parametrize('nb_file', list_notebooks('ipynb_scheme')) -def test_ipynb_to_scheme_percent(nb_file): - assert_conversion_same_as_mirror(nb_file, 'ss:percent', 'ipynb_to_percent') +@pytest.mark.parametrize('nb_file,extension', + [(nb_file, extension) + for nb_file in list_notebooks('ipynb_scheme') + for extension in ('ss', 'scm')]) +def test_ipynb_to_scheme_percent(nb_file, extension): + assert_conversion_same_as_mirror(nb_file, + '{}:percent'.format(extension), + 'ipynb_to_percent') @pytest.mark.parametrize('nb_file', list_notebooks('ipynb_clojure')) diff --git a/tests/test_read_simple_percent.py b/tests/test_read_simple_percent.py index 814c6511d..b16de2774 100644 --- a/tests/test_read_simple_percent.py +++ b/tests/test_read_simple_percent.py @@ -189,3 +189,20 @@ def test_multiple_empty_cells(): nb2 = jupytext.reads(text, 'py:percent') nb2.metadata = nb.metadata compare(nb, nb2) + + +def test_first_cell_markdown_191(): + text = """# %% [markdown] +# Docstring + +# %% +from math import pi + +# %% [markdown] +# Another markdown cell +""" + + nb = jupytext.reads(text, 'py') + assert nb.cells[0].cell_type == 'markdown' + assert nb.cells[1].cell_type == 'code' + assert nb.cells[2].cell_type == 'markdown' diff --git a/tests/test_read_simple_scheme.py b/tests/test_read_simple_scheme.py index dffa49625..ef532a530 100644 --- a/tests/test_read_simple_scheme.py +++ b/tests/test_read_simple_scheme.py @@ -13,15 +13,16 @@ def test_read_simple_file(script=""";; --- (define a 35) """): - nb = jupytext.reads(script, 'ss') - assert len(nb.cells) == 3 - assert nb.cells[0].cell_type == 'raw' - assert nb.cells[0].source == '---\ntitle: Simple file\n---' - assert nb.cells[1].cell_type == 'markdown' - assert nb.cells[1].source == 'Here we have some text\n' \ - 'And below we have some code' - assert nb.cells[2].cell_type == 'code' - compare(nb.cells[2].source, '(define a 35)') + for file_extension in ('ss', 'scm'): + nb = jupytext.reads(script, file_extension) + assert len(nb.cells) == 3 + assert nb.cells[0].cell_type == 'raw' + assert nb.cells[0].source == '---\ntitle: Simple file\n---' + assert nb.cells[1].cell_type == 'markdown' + assert nb.cells[1].source == 'Here we have some text\n' \ + 'And below we have some code' + assert nb.cells[2].cell_type == 'code' + compare(nb.cells[2].source, '(define a 35)') - script2 = jupytext.writes(nb, 'ss') - compare(script, script2) + script2 = jupytext.writes(nb, file_extension) + compare(script, script2)