From 73f2ef866d059d8d05a9d68d7de5588b590ed6f6 Mon Sep 17 00:00:00 2001 From: Nicolas Goaziou Date: Sun, 27 Oct 2013 11:03:05 +0100 Subject: [PATCH] org-element: Small change to src block indentation * lisp/org-element.el (org-element-remove-indentation): Renamed from `org-element--remove-indentation'. (org-element-example-block-interpreter, org-element-src-block-parser): Do not depend on `org-src-preserve-indentation'. (org-element-src-block-interpreter, org-element-example-block-parser): Check `org-src-preserve-indentation'. * lisp/ox.el (org-export-unravel-code): Handle `org-src-preserve-indentation'. * testing/lisp/test-org-element.el: Update tests. --- lisp/org-element.el | 103 ++++++++++++++++--------------- lisp/ox.el | 12 ++-- testing/lisp/test-org-element.el | 24 ++----- 3 files changed, 66 insertions(+), 73 deletions(-) diff --git a/lisp/org-element.el b/lisp/org-element.el index 329d00a4d..254af3c69 100644 --- a/lisp/org-element.el +++ b/lisp/org-element.el @@ -1711,35 +1711,6 @@ CONTENTS is nil." ;;;; Example Block -(defun org-element--remove-indentation (s &optional n) - "Remove maximum common indentation in string S and return it. -When optional argument N is a positive integer, remove exactly -that much characters from indentation, if possible, or return -S as-is otherwise. Unlike to `org-remove-indentation', this -function doesn't call `untabify' on S." - (catch 'exit - (with-temp-buffer - (insert s) - (goto-char (point-min)) - ;; Find maximum common indentation, if not specified. - (setq n (or n - (let ((min-ind (point-max))) - (save-excursion - (while (re-search-forward "^[ \t]*\\S-" nil t) - (let ((ind (1- (current-column)))) - (if (zerop ind) (throw 'exit s) - (setq min-ind (min min-ind ind)))))) - min-ind))) - (if (zerop n) s - ;; Remove exactly N indentation, but give up if not possible. - (while (not (eobp)) - (let ((ind (progn (skip-chars-forward " \t") (current-column)))) - (cond ((eolp) (delete-region (line-beginning-position) (point))) - ((< ind n) (throw 'exit s)) - (t (org-indent-line-to (- ind n)))) - (forward-line))) - (buffer-string))))) - (defun org-element-example-block-parser (limit affiliated) "Parse an example block. @@ -1769,8 +1740,7 @@ containing `:begin', `:end', `:number-lines', `:preserve-indent', ((string-match "-n\\>" switches) 'new) ((string-match "+n\\>" switches) 'continued))) (preserve-indent - (or org-src-preserve-indentation - (and switches (string-match "-i\\>" switches)))) + (and switches (string-match "-i\\>" switches))) ;; Should labels be retained in (or stripped from) example ;; blocks? (retain-labels @@ -1792,11 +1762,11 @@ containing `:begin', `:end', `:number-lines', `:preserve-indent', (post-affiliated (point)) (block-ind (progn (skip-chars-forward " \t") (current-column))) (contents-begin (progn (forward-line) (point))) - (value (org-element--remove-indentation + (value (org-element-remove-indentation (org-unescape-code-in-string (buffer-substring-no-properties contents-begin contents-end)) - (and preserve-indent block-ind))) + block-ind)) (pos-before-blank (progn (goto-char contents-end) (forward-line) (point))) @@ -1821,10 +1791,14 @@ containing `:begin', `:end', `:number-lines', `:preserve-indent', (defun org-element-example-block-interpreter (example-block contents) "Interpret EXAMPLE-BLOCK element as Org syntax. CONTENTS is nil." - (let ((switches (org-element-property :switches example-block))) + (let ((switches (org-element-property :switches example-block)) + (value (org-element-property :value example-block))) (concat "#+BEGIN_EXAMPLE" (and switches (concat " " switches)) "\n" (org-escape-code-in-string - (org-element-property :value example-block)) + (if (or org-src-preserve-indentation + (org-element-property :preserve-indent example-block)) + value + (org-element-remove-indentation value))) "#+END_EXAMPLE"))) @@ -2324,9 +2298,8 @@ Assume point is at the beginning of the block." (cond ((not switches) nil) ((string-match "-n\\>" switches) 'new) ((string-match "+n\\>" switches) 'continued))) - (preserve-indent (or org-src-preserve-indentation - (and switches - (string-match "-i\\>" switches)))) + (preserve-indent (and switches + (string-match "-i\\>" switches))) (label-fmt (and switches (string-match "-l +\"\\([^\"\n]+\\)\"" switches) @@ -2346,11 +2319,11 @@ Assume point is at the beginning of the block." ;; Indentation. (block-ind (progn (skip-chars-forward " \t") (current-column))) ;; Retrieve code. - (value (org-element--remove-indentation + (value (org-element-remove-indentation (org-unescape-code-in-string (buffer-substring-no-properties (progn (forward-line) (point)) contents-end)) - (and preserve-indent block-ind))) + block-ind)) (pos-before-blank (progn (goto-char contents-end) (forward-line) (point))) @@ -2383,15 +2356,17 @@ CONTENTS is nil." (let ((lang (org-element-property :language src-block)) (switches (org-element-property :switches src-block)) (params (org-element-property :parameters src-block)) - (value (let ((val (org-element-property :value src-block))) - (cond - ((org-element-property :preserve-indent src-block) val) - ((zerop org-edit-src-content-indentation) val) - (t - (let ((ind (make-string - org-edit-src-content-indentation 32))) - (replace-regexp-in-string - "\\(^\\)[ \t]*\\S-" ind val nil nil 1))))))) + (value + (let ((val (org-element-property :value src-block))) + (cond + ((or org-src-preserve-indentation + (org-element-property :preserve-indent src-block)) + val) + ((zerop org-edit-src-content-indentation) val) + (t + (let ((ind (make-string org-edit-src-content-indentation ?\s))) + (replace-regexp-in-string + "\\(^\\)[ \t]*\\S-" ind val nil nil 1))))))) (concat (format "#+BEGIN_SRC%s\n" (concat (and lang (concat " " lang)) (and switches (concat " " switches)) @@ -4972,6 +4947,36 @@ end of ELEM-A." (cdr overlays))) (goto-char (org-element-property :end elem-B))))) +(defun org-element-remove-indentation (s &optional n) + "Remove maximum common indentation in string S and return it. +When optional argument N is a positive integer, remove exactly +that much characters from indentation, if possible, or return +S as-is otherwise. Unlike to `org-remove-indentation', this +function doesn't call `untabify' on S." + (catch 'exit + (with-temp-buffer + (insert s) + (goto-char (point-min)) + ;; Find maximum common indentation, if not specified. + (setq n (or n + (let ((min-ind (point-max))) + (save-excursion + (while (re-search-forward "^[ \t]*\\S-" nil t) + (let ((ind (1- (current-column)))) + (if (zerop ind) (throw 'exit s) + (setq min-ind (min min-ind ind)))))) + min-ind))) + (if (zerop n) s + ;; Remove exactly N indentation, but give up if not possible. + (while (not (eobp)) + (let ((ind (progn (skip-chars-forward " \t") (current-column)))) + (cond ((eolp) (delete-region (line-beginning-position) (point))) + ((< ind n) (throw 'exit s)) + (t (org-indent-line-to (- ind n)))) + (forward-line))) + (buffer-string))))) + + (provide 'org-element) ;; Local variables: diff --git a/lisp/ox.el b/lisp/ox.el index d00bb17eb..d8b10e8c6 100644 --- a/lisp/ox.el +++ b/lisp/ox.el @@ -4192,17 +4192,21 @@ ELEMENT is excluded from count." ELEMENT has either a `src-block' an `example-block' type. Return a cons cell whose CAR is the source code, cleaned from any -reference and protective comma and CDR is an alist between -relative line number (integer) and name of code reference on that -line (string)." +reference, protective commas and spurious indentation, and CDR is +an alist between relative line number (integer) and name of code +reference on that line (string)." (let* ((line 0) refs + (value (org-element-property :value element)) ;; Get code and clean it. Remove blank lines at its ;; beginning and end. (code (replace-regexp-in-string "\\`\\([ \t]*\n\\)+" "" (replace-regexp-in-string "\\([ \t]*\n\\)*[ \t]*\\'" "\n" - (org-element-property :value element)))) + (if (or org-src-preserve-indentation + (org-element-property :preserve-indent element)) + value + (org-element-remove-indentation value))))) ;; Get format used for references. (label-fmt (regexp-quote (or (org-element-property :label-fmt element) diff --git a/testing/lisp/test-org-element.el b/testing/lisp/test-org-element.el index 103ba99a3..4f08e3e7a 100644 --- a/testing/lisp/test-org-element.el +++ b/testing/lisp/test-org-element.el @@ -504,16 +504,8 @@ Some other text (org-test-with-temp-text "#+BEGIN_EXAMPLE\n,* Headline\n ,#+keyword\nText\n#+END_EXAMPLE" (org-element-property :value (org-element-at-point))))) - ;; Nil `org-src-preserve-indentation': Remove maximum common - ;; indentation. - (should - (equal " L1\nL2\n" - (org-test-with-temp-text "#+BEGIN_EXAMPLE\n L1\n L2\n#+END_EXAMPLE" - (let ((org-src-preserve-indentation nil)) - (org-element-property :value (org-element-at-point)))))) - ;; Non-nil `org-src-preserve-indentation': Remove block indentation - ;; only, unless block contents are less indented than block - ;; boundaries. + ;; Remove block indentation according to block boundaries, unless + ;; block contents are less indented than block boundaries. (should (equal " L1\nL2\n" (org-test-with-temp-text " #+BEGIN_EXAMPLE\n L1\n L2\n #+END_EXAMPLE" @@ -1645,16 +1637,8 @@ Outside list" (org-test-with-temp-text "#+BEGIN_SRC org\n,* Headline\n ,#+keyword\nText\n#+END_SRC" (org-element-property :value (org-element-at-point))))) - ;; Nil `org-src-preserve-indentation': Remove maximum common - ;; indentation. - (should - (equal " L1\nL2\n" - (org-test-with-temp-text "#+BEGIN_SRC org\n L1\n L2\n#+END_SRC" - (let ((org-src-preserve-indentation nil)) - (org-element-property :value (org-element-at-point)))))) - ;; Non-nil `org-src-preserve-indentation': Remove block indentation - ;; only, unless block contents are less indented than block - ;; boundaries. + ;; Remove block indentation according to block boundaries, unless + ;; block contents are less indented than block boundaries. (should (equal " L1\nL2\n" (org-test-with-temp-text " #+BEGIN_SRC org\n L1\n L2\n #+END_SRC"