|
@@ -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.
|