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.
This commit is contained in:
Nicolas Goaziou 2013-10-27 11:03:05 +01:00
parent bdbf80aacb
commit 73f2ef866d
3 changed files with 66 additions and 73 deletions

View File

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

View File

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

View File

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