>From dd01dada2c3c0ee0d8cc28184026720f8602680b Mon Sep 17 00:00:00 2001 From: Brian Carlson Date: Mon, 16 May 2016 10:58:01 -0400 Subject: [PATCH] ox: Provide offset to [+-]n in SRC/EXAMPLE export * lisp/org-element.el (org-element-example-block-parser): Use cons cell for :number-lines specifying offset in addition to type (new/continue). ('continue . offset) for :number-lines will add this offset count to the last line number. ('new . offset) for :number-lines will reset the line number counting starting at offset (org-element-src-block-parser): same for SRC block as EXAMPLE block * lisp/ox-html.el (org-html-format-code): Use cons cell :number-lines * lisp/ox-latex.el (org-latex-src-block): Use cons cell :number-lines * lisp/ox-odt.el (org-odt-format-code): Use cons cell for :number-lines * lisp/ox.el (org-export-resolve-coderef): Use cons cell for :number-lines (org-export-get-loc): Use new cons cell for :number-lines (org-export-format-code-default): Use new cons cell for :number-lines * testing/lisp/test-ox.el (ert-deftest test-org-export/get-loc): Tests for changes (test-org-gen-loc-list): helper function for test-org-export/get-loc * contrib/lisp/ox-groff.el (org-groff-src-block): Use new cons cell for :number-lines --- contrib/lisp/ox-groff.el | 4 +- lisp/org-element.el | 26 ++++++++--- lisp/ox-html.el | 4 +- lisp/ox-latex.el | 4 +- lisp/ox-odt.el | 4 +- lisp/ox.el | 20 +++++---- testing/lisp/test-ox.el | 109 +++++++++++++++++++++++++++++++++++++++++++++++ 7 files changed, 146 insertions(+), 25 deletions(-) diff --git a/contrib/lisp/ox-groff.el b/contrib/lisp/ox-groff.el index b49edce..25ed8b0 100644 --- a/contrib/lisp/ox-groff.el +++ b/contrib/lisp/ox-groff.el @@ -1488,9 +1488,7 @@ contextual information." (custom-env (and lang (cadr (assq (intern lang) org-groff-custom-lang-environments)))) - (num-start (case (org-element-property :number-lines src-block) - (continued (org-export-get-loc src-block info)) - (new 0))) + (num-start (org-export-get-loc src-block info)) (retain-labels (org-element-property :retain-labels src-block)) (caption (and (not (org-export-read-attribute :attr_groff src-block :disable-caption)) diff --git a/lisp/org-element.el b/lisp/org-element.el index 368da60..5f62a7e 100644 --- a/lisp/org-element.el +++ b/lisp/org-element.el @@ -1896,8 +1896,16 @@ containing `:begin', `:end', `:number-lines', `:preserve-indent', ;; Switches analysis (number-lines (cond ((not switches) nil) - ((string-match "-n\\>" switches) 'new) - ((string-match "+n\\>" switches) 'continued))) + ((string-match "-n *\\([0-9]+\\)\\>" switches) + ;; subtract 1 to give number of lines before first line + (cons 'new (- (string-to-number (match-string 1 switches)) 1))) + ((string-match "-n\\>" switches) + (cons 'new 0)) + ((string-match "+n *\\([0-9]+\\)\\>" switches) + ;; subtract 1 to give number of lines between last number and first line + (cons 'continued (- (string-to-number (match-string 1 switches)) 1))) + ((string-match "+n\\>" switches) + (cons 'continued 0)))) (preserve-indent (and switches (string-match "-i\\>" switches))) ;; Should labels be retained in (or stripped from) example @@ -2393,7 +2401,7 @@ Assume point is at the beginning of the block." (looking-at (concat "^[ \t]*#\\+BEGIN_SRC" "\\(?: +\\(\\S-+\\)\\)?" - "\\(\\(?: +\\(?:-l \".*?\"\\|[-+][A-Za-z]\\)\\)+\\)?" + "\\(\\(?: +\\(?:-l \".+\"\\|[+-]n *[0-9]+\\|-[iIkKrRnN]\\|+[nN]\\)\\)+\\)?" "\\(.*\\)[ \t]*$")) (org-match-string-no-properties 1))) ;; Get switches. @@ -2403,8 +2411,16 @@ Assume point is at the beginning of the block." ;; Switches analysis (number-lines (cond ((not switches) nil) - ((string-match "-n\\>" switches) 'new) - ((string-match "+n\\>" switches) 'continued))) + ((string-match "-n *\\([0-9]+\\)\\>" switches) + ;; subtract 1 to give number of lines before first line + (cons 'new (- (string-to-number (match-string 1 switches)) 1))) + ((string-match "-n\\>" switches) + (cons 'new 0)) + ((string-match "+n *\\([0-9]+\\)\\>" switches) + ;; subtract 1 to give number of lines between last number and first line + (cons 'continued (- (string-to-number (match-string 1 switches)) 1))) + ((string-match "+n\\>" switches) + (cons 'continued 0)))) (preserve-indent (and switches (string-match "-i\\>" switches))) (label-fmt diff --git a/lisp/ox-html.el b/lisp/ox-html.el index e33d91e..3f5802a 100644 --- a/lisp/ox-html.el +++ b/lisp/ox-html.el @@ -2207,9 +2207,7 @@ a plist used as a communication channel." ;; Does the src block contain labels? (retain-labels (org-element-property :retain-labels element)) ;; Does it have line numbers? - (num-start (case (org-element-property :number-lines element) - (continued (org-export-get-loc element info)) - (new 0)))) + (num-start (org-export-get-loc element info))) (org-html-do-format-code code lang refs retain-labels num-start))) diff --git a/lisp/ox-latex.el b/lisp/ox-latex.el index 9c31645..41a238e 100644 --- a/lisp/ox-latex.el +++ b/lisp/ox-latex.el @@ -2762,9 +2762,7 @@ contextual information." (custom-env (and lang (cadr (assq (intern lang) org-latex-custom-lang-environments)))) - (num-start (case (org-element-property :number-lines src-block) - (continued (org-export-get-loc src-block info)) - (new 0))) + (num-start (org-export-get-loc src-block info)) (retain-labels (org-element-property :retain-labels src-block)) (attributes (org-export-read-attribute :attr_latex src-block)) (float (plist-get attributes :float)) diff --git a/lisp/ox-odt.el b/lisp/ox-odt.el index d996689..548445c 100644 --- a/lisp/ox-odt.el +++ b/lisp/ox-odt.el @@ -3168,9 +3168,7 @@ and prefix with \"OrgSrc\". For example, ;; Does the src block contain labels? (retain-labels (org-element-property :retain-labels element)) ;; Does it have line numbers? - (num-start (case (org-element-property :number-lines element) - (continued (org-export-get-loc element info)) - (new 0)))) + (num-start (org-export-get-loc element info))) (org-odt-do-format-code code info lang refs retain-labels num-start))) (defun org-odt-src-block (src-block _contents info) diff --git a/lisp/ox.el b/lisp/ox.el index 5ad17ec..714000b 100644 --- a/lisp/ox.el +++ b/lisp/ox.el @@ -4148,9 +4148,7 @@ error if no block contains REF." (when (re-search-backward ref-re nil t) (cond ((org-element-property :use-labels el) ref) - ((eq (org-element-property :number-lines el) 'continued) - (+ (org-export-get-loc el info) (line-number-at-pos))) - (t (line-number-at-pos))))))) + (t (+ (or (org-export-get-loc el info) 0) (line-number-at-pos)))))))) info 'first-match) (signal 'org-link-broken (list ref)))) @@ -4457,7 +4455,8 @@ objects of the same type." INFO is the plist used as a communication channel. ELEMENT is excluded from count." - (let ((loc 0)) + (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) @@ -4472,10 +4471,17 @@ ELEMENT is excluded from count." ;; Accumulate locs or reset them. (let ((lines (org-count-lines (org-trim (org-element-property :value el))))) - (setq loc (if (eq linums 'new) lines (+ loc lines)))))) + (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)) @@ -4573,9 +4579,7 @@ code." (let* ((refs (and (org-element-property :retain-labels element) (cdr code-info))) ;; Handle line numbering. - (num-start (cl-case (org-element-property :number-lines element) - (continued (org-export-get-loc element info)) - (new 0))) + (num-start (org-export-get-loc element info)) (num-fmt (and num-start (format "%%%ds " diff --git a/testing/lisp/test-ox.el b/testing/lisp/test-ox.el index e27954c..209dc64 100644 --- a/testing/lisp/test-ox.el +++ b/testing/lisp/test-ox.el @@ -2586,6 +2586,70 @@ Paragraph[fn:1][fn:2][fn:lbl3:C<>][[test]][[target]] (lambda (link) (org-export-resolve-fuzzy-link link info)) 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"))))) + +(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))) + ;; 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))) + ;; "-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))) + ;; -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))) + (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))) + (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))) + (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))) + (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))) + (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))) + (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))) + (should + ;; an SRC Block without -n does not add to the line count + (equal '(9 "nil" 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)))) + (ert-deftest test-org-export/resolve-coderef () "Test `org-export-resolve-coderef' specifications." (let ((org-coderef-label-format "(ref:%s)")) @@ -2596,10 +2660,32 @@ Paragraph[fn:1][fn:2][fn:lbl3:C<>][[test]][[target]] "#+BEGIN_EXAMPLE -n -k -r\nText (ref:coderef)\n#+END_EXAMPLE" (org-export-resolve-coderef "coderef" info)))) (should + (= 10 + (org-test-with-parsed-data + "#+BEGIN_EXAMPLE -n 10 -k -r\nText (ref:coderef)\n#+END_EXAMPLE" + (org-export-resolve-coderef "coderef" info)))) + (should + (= 135 + (org-test-with-parsed-data + "#+BEGIN_EXAMPLE -n 10 -k -r\nText \n#+END_EXAMPLE\n +#+BEGIN_EXAMPLE +n 125 -k -r\nText (ref:coderef)\n#+END_EXAMPLE" + (org-export-resolve-coderef "coderef" info)))) + (should (= 1 (org-test-with-parsed-data "#+BEGIN_SRC emacs-lisp -n -k -r\n(+ 1 1) (ref:coderef)\n#+END_SRC" (org-export-resolve-coderef "coderef" info)))) + (should + (= 10 + (org-test-with-parsed-data + "#+BEGIN_SRC emacs-lisp -n 10 -k -r\n(+ 1 1) (ref:coderef)\n#+END_SRC" + (org-export-resolve-coderef "coderef" info)))) + (should + (= 135 + (org-test-with-parsed-data + "#+BEGIN_SRC emacs-lisp -n 10 -k -r\n(+ 1 1) \n#+END_SRC\n +#+BEGIN_SRC emacs-lisp +n 125 -k -r\n(+ 1 1) (ref:coderef)\n#+END_SRC" + (org-export-resolve-coderef "coderef" info)))) ;; A link to a "-n -r" block returns line number. (should (= 1 @@ -2607,10 +2693,33 @@ Paragraph[fn:1][fn:2][fn:lbl3:C<>][[test]][[target]] "#+BEGIN_EXAMPLE -n -r\nText (ref:coderef)\n#+END_EXAMPLE" (org-export-resolve-coderef "coderef" info)))) (should + (= 10 + (org-test-with-parsed-data + "#+BEGIN_EXAMPLE -n 10 -r\nText (ref:coderef)\n#+END_EXAMPLE" + (org-export-resolve-coderef "coderef" info)))) + (should + (= 135 + (org-test-with-parsed-data + "#+BEGIN_EXAMPLE +n 10 -r\nText \n#+END_EXAMPLE +#+BEGIN_EXAMPLE +n 125 -r\nText (ref:coderef)\n#+END_EXAMPLE" + (org-export-resolve-coderef "coderef" info)))) + + (should (= 1 (org-test-with-parsed-data "#+BEGIN_SRC emacs-lisp -n -r\n(+ 1 1) (ref:coderef)\n#+END_SRC" (org-export-resolve-coderef "coderef" info)))) + (should + (= 10 + (org-test-with-parsed-data + "#+BEGIN_SRC emacs-lisp -n10 -r\n(+ 1 1) (ref:coderef)\n#+END_SRC" + (org-export-resolve-coderef "coderef" info)))) + (should + (= 135 + (org-test-with-parsed-data + "#+BEGIN_SRC emacs-lisp -n10 -r\n(+ 1 1) \n#+END_SRC +#+BEGIN_SRC emacs-lisp +n125 -r\n(+ 1 1) (ref:coderef)\n#+END_SRC" + (org-export-resolve-coderef "coderef" info)))) ;; A link to a "-n" block returns coderef. (should (equal "coderef" -- 2.8.3