From fb8b62e5faabca2b6c6514e25bd306f7a5e8696f Mon Sep 17 00:00:00 2001 From: Daniele Nicolodi Date: Tue, 20 Oct 2020 15:13:40 +0200 Subject: [PATCH 2/3] org-table: Simplify mode string parsing * org-table.el (org-table-eval-formula): Simplify mode string parsing and reduce scope of local variables. --- lisp/org-table.el | 98 +++++++++++++++++++++-------------------------- 1 file changed, 43 insertions(+), 55 deletions(-) diff --git a/lisp/org-table.el b/lisp/org-table.el index 0790dc3ca..4baad2600 100644 --- a/lisp/org-table.el +++ b/lisp/org-table.el @@ -722,7 +722,7 @@ Field is restored even in case of abnormal exit." (set-marker ,line nil))))) (defsubst org-table--set-calc-mode (var value) - (plist-put org-tbl-calc-modes var value)) + (setq org-tbl-calc-modes (plist-put org-tbl-calc-modes var value))) ;;; Predicates @@ -2427,54 +2427,42 @@ location of point." (org-tbl-calc-modes (copy-sequence org-calc-default-modes)) (numbers nil) ; was a variable, now fixed default (keep-empty nil) - n form form0 formrpl formrg bw fmt x ev orig c lispp literal + form form0 formrpl formrg bw fmt ev orig lispp literal duration duration-output-format) ;; Parse the format string. Since we have a lot of modes, this is ;; a lot of work. However, I think calc still uses most of the time. - (if (string-match ";" formula) - (let ((tmp (org-split-string formula ";"))) - (setq formula (car tmp) - fmt (concat (cdr (assoc "%" org-table-local-parameters)) - (nth 1 tmp))) + (if (string-match "\\(.*\\);\\(.*\\)" formula) + (progn + (setq fmt (concat (match-string-no-properties 2 formula) + (cdr (assoc "%" org-table-local-parameters))) + formula (match-string-no-properties 1 formula)) (while (string-match "\\([pnfse]\\)\\(-?[0-9]+\\)" fmt) - (setq c (string-to-char (match-string 1 fmt)) - n (string-to-number (match-string 2 fmt))) - (if (= c ?p) - (setq org-tbl-calc-modes - (org-table--set-calc-mode 'calc-internal-prec n)) - (setq org-tbl-calc-modes - (org-table--set-calc-mode - 'calc-float-format - (list (cdr (assoc c '((?n . float) (?f . fix) - (?s . sci) (?e . eng)))) - n)))) + (let ((c (string-to-char (match-string 1 fmt))) + (n (string-to-number (match-string 2 fmt)))) + (cl-case c + (?p (org-table--set-calc-mode 'calc-internal-prec n)) + (?n (org-table--set-calc-mode 'calc-float-format (list 'float n))) + (?f (org-table--set-calc-mode 'calc-float-format (list 'fix n))) + (?s (org-table--set-calc-mode 'calc-float-format (list 'sci n))) + (?e (org-table--set-calc-mode 'calc-float-format (list 'eng n))))) + ;; Remove matched flags from the mode string. + (setq fmt (replace-match "" t t fmt))) + (while (string-match "\\([tTUNLEDRFS]\\)" fmt) + (let ((c (string-to-char (match-string 1 fmt)))) + (cl-case c + (?t (setq duration t numbers t + duration-output-format org-table-duration-custom-format)) + (?T (setq duration t numbers t duration-output-format nil)) + (?U (setq duration t numbers t duration-output-format 'hh:mm)) + (?N (setq numbers t)) + (?L (setq literal t)) + (?E (setq keep-empty t)) + (?D (org-table--set-calc-mode 'calc-angle-mode 'deg)) + (?R (org-table--set-calc-mode 'calc-angle-mode 'rad)) + (?F (org-table--set-calc-mode 'calc-prefer-frac t)) + (?S (org-table--set-calc-mode 'calc-symbolic-mode t)))) + ;; Remove matched flags from the mode string. (setq fmt (replace-match "" t t fmt))) - (if (string-match "[tTU]" fmt) - (let ((ff (match-string 0 fmt))) - (setq duration t numbers t - duration-output-format - (cond ((equal ff "T") nil) - ((equal ff "t") org-table-duration-custom-format) - ((equal ff "U") 'hh:mm)) - fmt (replace-match "" t t fmt)))) - (if (string-match "N" fmt) - (setq numbers t - fmt (replace-match "" t t fmt))) - (if (string-match "L" fmt) - (setq literal t - fmt (replace-match "" t t fmt))) - (if (string-match "E" fmt) - (setq keep-empty t - fmt (replace-match "" t t fmt))) - (while (string-match "[DRFS]" fmt) - (let* ((c (string-to-char (match-string 0 fmt))) - (mode (cdr (assoc c '((?D calc-angle-mode deg) - (?R calc-angle-mode rad) - (?F calc-prefer-frac t) - (?S calc-symbolic-mode t)))))) - (setq org-tbl-calc-modes (org-table--set-calc-mode - (car mode) (cadr mode)) - fmt (replace-match "" t t fmt)))) (unless (string-match "\\S-" fmt) (setq fmt nil)))) (when (and (not suppress-const) org-table-formula-use-constants) @@ -2575,17 +2563,17 @@ location of point." (setq form0 form) ;; Insert the references to fields in same row (while (string-match "\\$\\(\\([-+]\\)?[0-9]+\\)" form) - (setq n (+ (string-to-number (match-string 1 form)) - (if (match-end 2) n0 0)) - x (nth (1- (if (= n 0) n0 (max n 1))) fields) - formrpl (save-match-data - (org-table-make-reference - x keep-empty numbers lispp))) - (when (or (not x) - (save-match-data - (string-match (regexp-quote formula) formrpl))) - (user-error "Invalid field specifier \"%s\"" - (match-string 0 form))) + (let* ((n (+ (string-to-number (match-string 1 form)) + (if (match-end 2) n0 0))) + (x (nth (1- (if (= n 0) n0 (max n 1))) fields))) + (setq formrpl (save-match-data + (org-table-make-reference + x keep-empty numbers lispp))) + (when (or (not x) + (save-match-data + (string-match (regexp-quote formula) formrpl))) + (user-error "Invalid field specifier \"%s\"" + (match-string 0 form)))) (setq form (replace-match formrpl t t form))) (if lispp -- 2.28.0