From 96cfef229d21daecc914bbd4edc2ea0ee69cf1c3 Mon Sep 17 00:00:00 2001 From: Nicolas Goaziou Date: Tue, 24 May 2016 21:40:43 +0200 Subject: [PATCH] ox: Small refactoring * lisp/ox.el (org-export-get-loc): Refactor code. Speed-up processing when the element doesn't require line numbering. * testing/lisp/test-ox.el (test-org-gen-loc-list): Reformat code. --- lisp/ox.el | 58 +++++++++---------- testing/lisp/test-ox.el | 123 +++++++++++++++++++++++++++++----------- 2 files changed, 115 insertions(+), 66 deletions(-) diff --git a/lisp/ox.el b/lisp/ox.el index 714000b65..ada62615d 100644 --- a/lisp/ox.el +++ b/lisp/ox.el @@ -4450,40 +4450,34 @@ objects of the same type." ;; code in a format suitable for plain text or verbatim output. (defun org-export-get-loc (element info) - "Return accumulated lines of code up to ELEMENT. + "Return count of lines of code before ELEMENT. -INFO is the plist used as a communication channel. +ELEMENT is an example-block or src-block element. INFO is the +plist used as a communication channel. -ELEMENT is excluded from count." - (let ((loc 0) - (linum (org-element-property :number-lines element))) - (org-element-map (plist-get info :parse-tree) - `(src-block example-block ,(org-element-type element)) - (lambda (el) - (cond - ;; ELEMENT is reached: Quit the loop. - ((eq el element)) - ;; Only count lines from src-block and example-block elements - ;; with a "+n" or "-n" switch. A "-n" switch resets counter. - ((not (memq (org-element-type el) '(src-block example-block))) nil) - ((let ((linums (org-element-property :number-lines el))) - (when linums - ;; Accumulate locs or reset them. - (let ((lines (org-count-lines - (org-trim (org-element-property :value el))))) - (if (eq (car linums) 'new) - (setq loc 0)) - (setq loc (+ loc lines (cdr linums)))))) - ;; Return nil to stay in the loop. - nil))) - info 'first-match) - ;; Add the offset from [+-]n to the loc for the final starting - ;; number of lines before the first starting line. - (setq loc (cl-case (car linum) - (continued (+ (cdr linum) loc)) - (new (cdr linum)))) - ;; Return value. - loc)) +Count includes every line of code in example-block or src-block +with a \"+n\" or \"-n\" switch before block. Return nil if +ELEMENT doesn't allow line numbering." + (pcase (org-element-property :number-lines element) + (`(new . ,n) n) + (`(continued . ,n) + (let ((loc 0)) + (org-element-map (plist-get info :parse-tree) '(src-block example-block) + (lambda (el) + ;; ELEMENT is reached: Quit loop and return locs. + (if (eq el element) (+ loc n) + ;; Only count lines from src-block and example-block + ;; elements with a "+n" or "-n" switch. + (let ((linum (org-element-property :number-lines el))) + (when linum + (let ((lines (org-count-lines + (org-trim (org-element-property :value el))))) + ;; Accumulate locs or reset them. + (pcase linum + (`(new . ,n) (setq loc (+ n lines))) + (`(continued . ,n) (cl-incf loc (+ n lines))))))) + nil)) ;Return nil to stay in the loop. + info 'first-match))))) (defun org-export-unravel-code (element) "Clean source code and extract references out of it. diff --git a/testing/lisp/test-ox.el b/testing/lisp/test-ox.el index 209dc643f..13f406d79 100644 --- a/testing/lisp/test-ox.el +++ b/testing/lisp/test-ox.el @@ -2587,68 +2587,123 @@ Paragraph[fn:1][fn:2][fn:lbl3:C<>][[test]][[target]] info t)))) (defun test-org-gen-loc-list(text type) - (org-test-with-parsed-data text - (org-element-map tree type - (lambda(el) (or (org-export-get-loc el info) "nil"))))) + (org-test-with-parsed-data text + (org-element-map tree type + (lambda (el) (or (org-export-get-loc el info) 'no-loc))))) (ert-deftest test-org-export/get-loc () "Test `org-export-get-loc' specifications." (should ;; "-n" resets line number. (equal '(0) - (test-org-gen-loc-list "#+BEGIN_EXAMPLE -n\n Text\n#+END_EXAMPLE" 'example-block))) + (test-org-gen-loc-list "#+BEGIN_EXAMPLE -n\n Text\n#+END_EXAMPLE" + 'example-block))) ;; The first "+n" has 0 lines before it (should (equal '(0) - (test-org-gen-loc-list "#+BEGIN_EXAMPLE +n\n Text\n#+END_EXAMPLE" 'example-block))) + (test-org-gen-loc-list "#+BEGIN_EXAMPLE +n\n Text\n#+END_EXAMPLE" + 'example-block))) ;; "-n 10" resets line number but has "9 lines" before it. (should (equal '(9) - (test-org-gen-loc-list "#+BEGIN_EXAMPLE -n 10\n Text\n#+END_EXAMPLE" 'example-block))) + (test-org-gen-loc-list "#+BEGIN_EXAMPLE -n 10\n Text\n#+END_EXAMPLE" + 'example-block))) ;; -n10 with two lines then +n 15 (should (equal '(9 25) - (test-org-gen-loc-list "#+BEGIN_EXAMPLE -n 10\n Text_10\n Second line(11)\n#+END_EXAMPLE -#+BEGIN_EXAMPLE +n 15\n Text line (11 + 15)\n#+END_EXAMPLE" 'example-block))) + (test-org-gen-loc-list " +#+BEGIN_EXAMPLE -n 10 + Text_10 + Second line(11) +#+END_EXAMPLE +#+BEGIN_EXAMPLE +n 15 + Text line (11 + 15) +#+END_EXAMPLE" + 'example-block))) (should (equal '(9 19 0) - (test-org-gen-loc-list "#+BEGIN_EXAMPLE -n 10\n Text\n#+END_EXAMPLE -#+BEGIN_EXAMPLE +n 10\n Text \n#+END_EXAMPLE\n -#+BEGIN_EXAMPLE -n\n Text \n#+END_EXAMPLE" 'example-block))) + (test-org-gen-loc-list " +#+BEGIN_EXAMPLE -n 10 + Text +#+END_EXAMPLE +#+BEGIN_EXAMPLE +n 10 + Text +#+END_EXAMPLE + +#+BEGIN_EXAMPLE -n + Text +#+END_EXAMPLE" + 'example-block))) + ;; an Example Block without -n does not add to the line count. (should - ;; an Example Block without -n does not add to the line count - (equal '(9 "nil" 19) - (test-org-gen-loc-list "#+BEGIN_EXAMPLE -n 10\n Text\n#+END_EXAMPLE -#+BEGIN_EXAMPLE\n Text\n#+END_EXAMPLE -#+BEGIN_EXAMPLE +n 10\n Text\n#+END_EXAMPLE" 'example-block))) + (equal '(9 no-loc 19) + (test-org-gen-loc-list " +#+BEGIN_EXAMPLE -n 10 + Text +#+END_EXAMPLE +#+BEGIN_EXAMPLE + Text +#+END_EXAMPLE +#+BEGIN_EXAMPLE +n 10 + Text +#+END_EXAMPLE" + 'example-block))) + ;; "-n" resets line number. + (should + (equal + '(0) + (test-org-gen-loc-list "#+BEGIN_SRC emacs-lisp -n \n (- 1 1) \n#+END_SRC" + 'src-block))) + ;; The first "+n" has 0 lines before it. (should - ;; "-n" resets line number. (equal '(0) - (test-org-gen-loc-list "#+BEGIN_SRC emacs-lisp -n \n (- 1 1) \n#+END_SRC" 'src-block))) + (test-org-gen-loc-list + "#+BEGIN_SRC emacs-lisp +n \n (+ 0 (- 1 1))\n#+END_SRC" + 'src-block))) + ;; "-n 10" resets line number but has "9 lines" before it. (should - ;; The first "+n" has 0 lines before it - (equal '(0) - (test-org-gen-loc-list "#+BEGIN_SRC emacs-lisp +n \n (+ 0 (- 1 1))\n#+END_SRC" 'src-block))) - (should - ;; "-n 10" resets line number but has "9 lines" before it. (equal '(9) - (test-org-gen-loc-list "#+BEGIN_SRC emacs-lisp -n 10\n (- 10 1)\n#+END_SRC" 'src-block))) + (test-org-gen-loc-list + "#+BEGIN_SRC emacs-lisp -n 10\n (- 10 1)\n#+END_SRC" + 'src-block))) (should (equal '(9 25) - (test-org-gen-loc-list "#+BEGIN_SRC emacs-lisp -n 10\n (- 10 1)\n (+ (- 10 1) 1)\n#+END_SRC -#+BEGIN_SRC emacs-lisp +n 15\n (+ (- 10 1) 2 (- 15 1))\n#+END_SRC" 'src-block))) + (test-org-gen-loc-list " +#+BEGIN_SRC emacs-lisp -n 10 + (- 10 1) + (+ (- 10 1) 1) +#+END_SRC +#+BEGIN_SRC emacs-lisp +n 15 + (+ (- 10 1) 2 (- 15 1)) +#+END_SRC" + 'src-block))) (should (equal '(9 19 0) - (test-org-gen-loc-list "#+BEGIN_SRC emacs-lisp -n 10\n (- 10 1)\n#+END_SRC -#+BEGIN_SRC emacs-lisp +n 10\n (+ (- 10 1) 1 (- 10 1))\n#+END_SRC -#+BEGIN_SRC emacs-lisp -n\n (- 1 1)\n#+END_SRC" 'src-block))) + (test-org-gen-loc-list " +#+BEGIN_SRC emacs-lisp -n 10 + (- 10 1) +#+END_SRC +#+BEGIN_SRC emacs-lisp +n 10 + (+ (- 10 1) 1 (- 10 1)) +#+END_SRC +#+BEGIN_SRC emacs-lisp -n + (- 1 1) +#+END_SRC" + 'src-block))) + ;; A SRC Block without -n does not add to the line count. (should - ;; an SRC Block without -n does not add to the line count - (equal '(9 "nil" 19) + (equal '(9 no-loc 19) (test-org-gen-loc-list - "#+BEGIN_SRC emacs-lisp -n 10\n (+ (-10 1) 1)\n#+END_SRC -#+BEGIN_SRC emacs-lisp \n (+ 2 2) \n#+END_SRC -#+BEGIN_SRC emacs-lisp +n 10\n (+ (- 10 1) 1 (- 10 1))\n#+END_SRC" 'src-block)))) + "#+BEGIN_SRC emacs-lisp -n 10 + (+ (-10 1) 1) +#+END_SRC +#+BEGIN_SRC emacs-lisp + (+ 2 2) +#+END_SRC +#+BEGIN_SRC emacs-lisp +n 10 + (+ (- 10 1) 1 (- 10 1)) +#+END_SRC" + 'src-block)))) (ert-deftest test-org-export/resolve-coderef () "Test `org-export-resolve-coderef' specifications."