diff options
author | Nicolas Goaziou <mail@nicolasgoaziou.fr> | 2017-05-02 08:24:24 +0200 |
---|---|---|
committer | Nicolas Goaziou <mail@nicolasgoaziou.fr> | 2017-05-02 08:24:24 +0200 |
commit | cecdb2bd671f45ff3c11c73fefedb0ba67145c62 (patch) | |
tree | abcd80336db29645c2104620699c61764f40a4f9 | |
parent | 5bc540eae129c34d7763aacf7eaa596b04a3f256 (diff) | |
parent | 500abcd7fbe24abc887300faec2058905a13fa33 (diff) | |
download | org-mode-cecdb2bd671f45ff3c11c73fefedb0ba67145c62.tar.gz |
Merge branch 'maint'
-rw-r--r-- | lisp/ob-core.el | 127 | ||||
-rw-r--r-- | lisp/org-compat.el | 3 | ||||
-rw-r--r-- | testing/lisp/test-ob.el | 16 |
3 files changed, 100 insertions, 46 deletions
diff --git a/lisp/ob-core.el b/lisp/ob-core.el index d64f7b1..cb332ff 100644 --- a/lisp/ob-core.el +++ b/lisp/ob-core.el @@ -1440,36 +1440,79 @@ specified in the properties of the current outline entry." (defun org-babel-balanced-split (string alts) "Split STRING on instances of ALTS. -ALTS is a cons of two character options where each option may be -either the numeric code of a single character or a list of -character alternatives. For example to split on balanced -instances of \"[ \t]:\" set ALTS to ((32 9) . 58)." - (let* ((matches (lambda (ch spec) (if (listp spec) (member ch spec) (equal spec ch)))) - (matched (lambda (ch last) - (if (consp alts) - (and (funcall matches ch (cdr alts)) - (funcall matches last (car alts))) - (funcall matches ch alts)))) - (balance 0) (last 0) - quote partial lst) - (mapc (lambda (ch) ; split on [], (), "" balanced instances of [ \t]: - (setq balance (+ balance - (cond ((or (equal 91 ch) (equal 40 ch)) 1) - ((or (equal 93 ch) (equal 41 ch)) -1) - (t 0)))) - (when (and (equal 34 ch) (not (equal 92 last))) - (setq quote (not quote))) - (setq partial (cons ch partial)) - (when (and (= balance 0) (not quote) (funcall matched ch last)) - (setq lst (cons (apply #'string (nreverse - (if (consp alts) - (cddr partial) - (cdr partial)))) - lst)) - (setq partial nil)) - (setq last ch)) - (string-to-list string)) - (nreverse (cons (apply #'string (nreverse partial)) lst)))) +ALTS is a character, or cons of two character options where each +option may be either the numeric code of a single character or +a list of character alternatives. For example, to split on +balanced instances of \"[ \t]:\", set ALTS to ((32 9) . 58)." + (with-temp-buffer + (insert string) + (goto-char (point-min)) + (let ((splitp (lambda (past next) + ;; Non-nil when there should be a split after NEXT + ;; character. PAST is the character before NEXT. + (pcase alts + (`(,(and first (pred consp)) . ,(and second (pred consp))) + (and (memq past first) (memq next second))) + (`(,first . ,(and second (pred consp))) + (and (eq past first) (memq next second))) + (`(,(and first (pred consp)) . ,second) + (and (memq past first) (eq next second))) + (`(,first . ,second) + (and (eq past first) (eq next second))) + ((pred (eq next)) t) + (_ nil)))) + (partial nil) + (result nil)) + (while (not (eobp)) + (cond + ((funcall splitp (char-before) (char-after)) + ;; There is a split after point. If ALTS is two-folds, + ;; remove last parsed character as it belongs to ALTS. + (when (consp alts) (pop partial)) + ;; Include elements parsed so far in RESULTS and flush + ;; partial parsing. + (when partial + (push (apply #'string (nreverse partial)) result) + (setq partial nil)) + (forward-char)) + ((memq (char-after) '(?\( ?\[)) + ;; Include everything between balanced brackets. + (let* ((origin (point)) + (after (char-after)) + (openings (list after))) + (forward-char) + (while (and openings (re-search-forward "[]()]" nil t)) + (pcase (char-before) + ((and match (or ?\[ ?\()) (push match openings)) + (?\] (when (eq ?\[ (car openings)) (pop openings))) + (_ (when (eq ?\( (car openings)) (pop openings))))) + (if (null openings) + (setq partial + (nconc (nreverse (string-to-list + (buffer-substring origin (point)))) + partial)) + ;; Un-balanced bracket. Backtrack. + (push after partial) + (goto-char (1+ origin))))) + ((and (eq ?\" (char-after)) (not (eq ?\\ (char-before)))) + ;; Include everything between non-escaped double quotes. + (push ?\" partial) + (let ((origin (point))) + (condition-case nil + ;; Use `read' since it is fast and takes care of + ;; escaped quotes already. + (setq partial + (nconc (cons ?\" + (nreverse (string-to-list + (read (current-buffer))))) + partial)) + ;; No closing double quote found. Backtrack. + (end-of-file (goto-char (1+ origin)))))) + (t (push (char-after) partial) + (forward-char)))) + ;; Add pending parsing and return result. + (when partial (push (apply #'string (nreverse partial)) result)) + (nreverse result)))) (defun org-babel-join-splits-near-ch (ch list) "Join splits where \"=\" is on either end of the split." @@ -2854,24 +2897,20 @@ Otherwise if CELL looks like lisp (meaning it starts with a lisp, otherwise return it unmodified as a string. Optional argument INHIBIT-LISP-EVAL inhibits lisp evaluation for situations in which is it not appropriate." - (if (and (stringp cell) (not (equal cell ""))) - (or (org-babel--string-to-number cell) - (if (and (not inhibit-lisp-eval) - (or (member (substring cell 0 1) '("(" "'" "`" "[")) - (string= cell "*this*"))) - (eval (read cell) t) - (if (string= (substring cell 0 1) "\"") - (read cell) - (progn (set-text-properties 0 (length cell) nil cell) cell)))) - cell)) + (cond ((not (org-string-nw-p cell)) cell) + ((org-babel--string-to-number cell)) + ((and (not inhibit-lisp-eval) + (or (memq (string-to-char cell) '(?\( ?' ?` ?\[)) + (string= cell "*this*"))) + (eval (read cell) t)) + ((eq (string-to-char cell) ?\") (read cell)) + (t (org-no-properties cell)))) (defun org-babel--string-to-number (string) "If STRING represents a number return its value. - Otherwise return nil." - (when (string-match "\\`-?[0-9]*\\.?[0-9]*\\'" string) - (string-to-number string))) -(define-obsolete-function-alias 'org-babel-number-p 'org-babel--string-to-number "Org 9.0") + (and (string-match-p "\\`-?[0-9]*\\.?[0-9]*\\'" string) + (string-to-number string))) (defun org-babel-import-elisp-from-file (file-name &optional separator) "Read the results located at FILE-NAME into an elisp table. diff --git a/lisp/org-compat.el b/lisp/org-compat.el index 8106c5e..3580807 100644 --- a/lisp/org-compat.el +++ b/lisp/org-compat.el @@ -362,6 +362,9 @@ use of this function is for the stuck project list." (make-obsolete-variable 'org-time-clocksum-use-effort-durations "set `org-duration-units' instead." "Org 9.1") +(define-obsolete-function-alias 'org-babel-number-p + 'org-babel--string-to-number "Org 9.0") + ;;;; Obsolete link types diff --git a/testing/lisp/test-ob.el b/testing/lisp/test-ob.el index fe74c0c..fe4ecb8 100644 --- a/testing/lisp/test-ob.el +++ b/testing/lisp/test-ob.el @@ -701,11 +701,23 @@ x (should (= 2 (length (org-babel-ref-split-args "a=\"this, no work\", b=1")))))) -(ert-deftest test-ob/org-babel-balanced-split () +(ert-deftest test-ob/balanced-split () + "Test `org-babel-balanced-split' specifications." (should (equal '(":a 1" "b [2 3]" "c (4 :d (5 6))") (org-babel-balanced-split ":a 1 :b [2 3] :c (4 :d (5 6))" - '((32 9) . 58))))) + '((32 9) . 58)))) + ;; Handle un-balanced parens. + (should + (equal '(":foo ((6)" "bar 1") + (org-babel-balanced-split ":foo ((6) :bar 1" '((32 9) . 58)))) + (should + (equal '(":foo \"(foo\"" "bar 2") + (org-babel-balanced-split ":foo \"(foo\" :bar 2" '((32 9) . 58)))) + ;; Handle un-balanced quotes. + (should + (equal '(":foo \"1" "bar 3") + (org-babel-balanced-split ":foo \"1 :bar 3" '((32 9) . 58))))) (ert-deftest test-ob/commented-last-block-line-no-var () (org-test-with-temp-text-in-file " |