- (types '())
- indentation type func start body headers preserve-indent progress-marker)
- (flet ((interblock (start end)
- (mapcar (lambda (pair) (funcall (second pair) start end))
- org-export-interblocks)))
- (goto-char (point-min))
- (setq start (point))
- (while (re-search-forward
- "^\\([ \t]*\\)#\\+begin_\\(\\S-+\\)[ \t]*\\(.*\\)?[\r\n]\\([^\000]*?\\)[\r\n][ \t]*#\\+end_\\S-+.*[\r\n]?" nil t)
- (setq indentation (length (match-string 1)))
- (setq type (intern (downcase (match-string 2))))
- (setq headers (save-match-data (org-split-string (match-string 3) "[ \t]+")))
- (setq body (match-string 4))
- (setq preserve-indent (or org-src-preserve-indentation (member "-i" headers)))
- (unless preserve-indent
- (setq body (save-match-data (org-remove-indentation body))))
- (unless (memq type types) (setq types (cons type types)))
- (save-match-data (interblock start (match-beginning 0)))
- (when (setq func (cadr (assoc type org-export-blocks)))
- (let ((replacement (save-match-data
- (if (memq type org-export-blocks-witheld) ""
- (apply func body headers)))))
- (when replacement
- (replace-match replacement t t)
- (unless preserve-indent
- (indent-code-rigidly
- (match-beginning 0) (match-end 0) indentation)))))
- (setq start (match-end 0)))
- (interblock start (point-max))
- (run-hooks 'org-export-blocks-postblock-hook)))))
+ (interblock (lambda (start end)
+ (mapcar (lambda (pair) (funcall (second pair) start end))
+ org-export-interblocks)))
+ matched indentation type types func
+ start end body headers preserve-indent progress-marker)
+ (goto-char (point-min))
+ (setq start (point))
+ (let ((beg-re "^\\([ \t]*\\)#\\+begin_\\(\\S-+\\)[ \t]*\\(.*\\)?[\r\n]"))
+ (while (re-search-forward beg-re nil t)
+ (let* ((match-start (copy-marker (match-beginning 0)))
+ (body-start (copy-marker (match-end 0)))
+ (indentation (length (match-string 1)))
+ (inner-re (format "^[ \t]*#\\+\\(begin\\|end\\)_%s"
+ (regexp-quote (downcase (match-string 2)))))
+ (type (intern (downcase (match-string 2))))
+ (headers (save-match-data
+ (org-split-string (match-string 3) "[ \t]+")))
+ (balanced 1)
+ (preserve-indent (or org-src-preserve-indentation
+ (member "-i" headers)))
+ match-end)
+ (while (and (not (zerop balanced))
+ (re-search-forward inner-re nil t))
+ (if (string= (downcase (match-string 1)) "end")
+ (decf balanced)
+ (incf balanced)))
+ (when (not (zerop balanced))
+ (error "Unbalanced begin/end_%s blocks with %S"
+ type (buffer-substring match-start (point))))
+ (setq match-end (copy-marker (match-end 0)))
+ (unless preserve-indent
+ (setq body (save-match-data (org-remove-indentation
+ (buffer-substring
+ body-start (match-beginning 0))))))
+ (unless (memq type types) (setq types (cons type types)))
+ (save-match-data (funcall interblock start match-start))
+ (when (setq func (cadr (assoc type org-export-blocks)))
+ (let ((replacement (save-match-data
+ (if (memq type org-export-blocks-witheld) ""
+ (apply func body headers)))))
+ ;; ;; un-comment this code after the org-element merge
+ ;; (save-match-data
+ ;; (when (and replacement (string= replacement ""))
+ ;; (delete-region
+ ;; (car (org-element-collect-affiliated-keyword))
+ ;; match-start)))
+ (when replacement
+ (delete-region match-start match-end)
+ (goto-char match-start) (insert replacement)
+ (if preserve-indent
+ ;; indent only the code block markers
+ (save-excursion
+ (indent-line-to indentation) ; indent end_block
+ (goto-char match-start)
+ (indent-line-to indentation)) ; indent begin_block
+ ;; indent everything
+ (indent-code-rigidly match-start (point) indentation)))))
+ ;; cleanup markers
+ (set-marker match-start nil)
+ (set-marker body-start nil)
+ (set-marker match-end nil))
+ (setq start (point))))
+ (funcall interblock start (point-max))
+ (run-hooks 'org-export-blocks-postblock-hook))))