|
@@ -3281,116 +3281,119 @@ storing and resolving footnotes. It is created automatically."
|
|
|
;; Expand INCLUDE keywords.
|
|
|
(goto-char (point-min))
|
|
|
(while (re-search-forward include-re nil t)
|
|
|
- (let ((element (save-match-data (org-element-at-point))))
|
|
|
- (when (eq (org-element-type element) 'keyword)
|
|
|
- (beginning-of-line)
|
|
|
- ;; Extract arguments from keyword's value.
|
|
|
- (let* ((value (org-element-property :value element))
|
|
|
- (ind (org-get-indentation))
|
|
|
- location
|
|
|
- (file
|
|
|
- (and (string-match
|
|
|
- "^\\(\".+?\"\\|\\S-+\\)\\(?:\\s-+\\|$\\)" value)
|
|
|
- (prog1
|
|
|
- (save-match-data
|
|
|
- (let ((matched (match-string 1 value)))
|
|
|
- (when (string-match "\\(::\\(.*?\\)\\)\"?\\'"
|
|
|
- matched)
|
|
|
- (setq location (match-string 2 matched))
|
|
|
- (setq matched
|
|
|
- (replace-match "" nil nil matched 1)))
|
|
|
- (expand-file-name
|
|
|
- (org-unbracket-string "\"" "\"" matched)
|
|
|
- dir)))
|
|
|
- (setq value (replace-match "" nil nil value)))))
|
|
|
- (only-contents
|
|
|
- (and (string-match ":only-contents *\\([^: \r\t\n]\\S-*\\)?"
|
|
|
- value)
|
|
|
- (prog1 (org-not-nil (match-string 1 value))
|
|
|
- (setq value (replace-match "" nil nil value)))))
|
|
|
- (lines
|
|
|
- (and (string-match
|
|
|
- ":lines +\"\\(\\(?:[0-9]+\\)?-\\(?:[0-9]+\\)?\\)\""
|
|
|
- value)
|
|
|
- (prog1 (match-string 1 value)
|
|
|
- (setq value (replace-match "" nil nil value)))))
|
|
|
- (env (cond
|
|
|
- ((string-match "\\<example\\>" value) 'literal)
|
|
|
- ((string-match "\\<export\\(?: +\\(.*\\)\\)?" value)
|
|
|
- 'literal)
|
|
|
- ((string-match "\\<src\\(?: +\\(.*\\)\\)?" value)
|
|
|
- 'literal)))
|
|
|
- ;; Minimal level of included file defaults to the child
|
|
|
- ;; level of the current headline, if any, or one. It
|
|
|
- ;; only applies is the file is meant to be included as
|
|
|
- ;; an Org one.
|
|
|
- (minlevel
|
|
|
- (and (not env)
|
|
|
- (if (string-match ":minlevel +\\([0-9]+\\)" value)
|
|
|
- (prog1 (string-to-number (match-string 1 value))
|
|
|
- (setq value (replace-match "" nil nil value)))
|
|
|
- (get-text-property (point)
|
|
|
- :org-include-induced-level))))
|
|
|
- (args (and (eq env 'literal) (match-string 1 value)))
|
|
|
- (block (and (string-match "\\<\\(\\S-+\\)\\>" value)
|
|
|
- (match-string 1 value))))
|
|
|
- ;; Remove keyword.
|
|
|
- (delete-region (point) (line-beginning-position 2))
|
|
|
- (cond
|
|
|
- ((not file) nil)
|
|
|
- ((not (file-readable-p file))
|
|
|
- (error "Cannot include file %s" file))
|
|
|
- ;; Check if files has already been parsed. Look after
|
|
|
- ;; inclusion lines too, as different parts of the same file
|
|
|
- ;; can be included too.
|
|
|
- ((member (list file lines) included)
|
|
|
- (error "Recursive file inclusion: %s" file))
|
|
|
- (t
|
|
|
+ (unless (org-in-commented-heading-p)
|
|
|
+ (let ((element (save-match-data (org-element-at-point))))
|
|
|
+ (when (eq (org-element-type element) 'keyword)
|
|
|
+ (beginning-of-line)
|
|
|
+ ;; Extract arguments from keyword's value.
|
|
|
+ (let* ((value (org-element-property :value element))
|
|
|
+ (ind (org-get-indentation))
|
|
|
+ location
|
|
|
+ (file
|
|
|
+ (and (string-match
|
|
|
+ "^\\(\".+?\"\\|\\S-+\\)\\(?:\\s-+\\|$\\)" value)
|
|
|
+ (prog1
|
|
|
+ (save-match-data
|
|
|
+ (let ((matched (match-string 1 value)))
|
|
|
+ (when (string-match "\\(::\\(.*?\\)\\)\"?\\'"
|
|
|
+ matched)
|
|
|
+ (setq location (match-string 2 matched))
|
|
|
+ (setq matched
|
|
|
+ (replace-match "" nil nil matched 1)))
|
|
|
+ (expand-file-name
|
|
|
+ (org-unbracket-string "\"" "\"" matched)
|
|
|
+ dir)))
|
|
|
+ (setq value (replace-match "" nil nil value)))))
|
|
|
+ (only-contents
|
|
|
+ (and (string-match ":only-contents *\\([^: \r\t\n]\\S-*\\)?"
|
|
|
+ value)
|
|
|
+ (prog1 (org-not-nil (match-string 1 value))
|
|
|
+ (setq value (replace-match "" nil nil value)))))
|
|
|
+ (lines
|
|
|
+ (and (string-match
|
|
|
+ ":lines +\"\\(\\(?:[0-9]+\\)?-\\(?:[0-9]+\\)?\\)\""
|
|
|
+ value)
|
|
|
+ (prog1 (match-string 1 value)
|
|
|
+ (setq value (replace-match "" nil nil value)))))
|
|
|
+ (env (cond
|
|
|
+ ((string-match "\\<example\\>" value) 'literal)
|
|
|
+ ((string-match "\\<export\\(?: +\\(.*\\)\\)?" value)
|
|
|
+ 'literal)
|
|
|
+ ((string-match "\\<src\\(?: +\\(.*\\)\\)?" value)
|
|
|
+ 'literal)))
|
|
|
+ ;; Minimal level of included file defaults to the
|
|
|
+ ;; child level of the current headline, if any, or
|
|
|
+ ;; one. It only applies is the file is meant to be
|
|
|
+ ;; included as an Org one.
|
|
|
+ (minlevel
|
|
|
+ (and (not env)
|
|
|
+ (if (string-match ":minlevel +\\([0-9]+\\)" value)
|
|
|
+ (prog1 (string-to-number (match-string 1 value))
|
|
|
+ (setq value (replace-match "" nil nil value)))
|
|
|
+ (get-text-property (point)
|
|
|
+ :org-include-induced-level))))
|
|
|
+ (args (and (eq env 'literal) (match-string 1 value)))
|
|
|
+ (block (and (string-match "\\<\\(\\S-+\\)\\>" value)
|
|
|
+ (match-string 1 value))))
|
|
|
+ ;; Remove keyword.
|
|
|
+ (delete-region (point) (line-beginning-position 2))
|
|
|
(cond
|
|
|
- ((eq env 'literal)
|
|
|
- (insert
|
|
|
- (let ((ind-str (make-string ind ?\s))
|
|
|
- (arg-str (if (stringp args) (format " %s" args) ""))
|
|
|
- (contents
|
|
|
- (org-escape-code-in-string
|
|
|
- (org-export--prepare-file-contents file lines))))
|
|
|
- (format "%s#+BEGIN_%s%s\n%s%s#+END_%s\n"
|
|
|
- ind-str block arg-str contents ind-str block))))
|
|
|
- ((stringp block)
|
|
|
- (insert
|
|
|
- (let ((ind-str (make-string ind ?\s))
|
|
|
- (contents
|
|
|
- (org-export--prepare-file-contents file lines)))
|
|
|
- (format "%s#+BEGIN_%s\n%s%s#+END_%s\n"
|
|
|
- ind-str block contents ind-str block))))
|
|
|
+ ((not file) nil)
|
|
|
+ ((not (file-readable-p file))
|
|
|
+ (error "Cannot include file %s" file))
|
|
|
+ ;; Check if files has already been parsed. Look after
|
|
|
+ ;; inclusion lines too, as different parts of the same
|
|
|
+ ;; file can be included too.
|
|
|
+ ((member (list file lines) included)
|
|
|
+ (error "Recursive file inclusion: %s" file))
|
|
|
(t
|
|
|
- (insert
|
|
|
- (with-temp-buffer
|
|
|
- (let ((org-inhibit-startup t)
|
|
|
- (lines
|
|
|
- (if location
|
|
|
- (org-export--inclusion-absolute-lines
|
|
|
- file location only-contents lines)
|
|
|
- lines)))
|
|
|
- (org-mode)
|
|
|
- (insert
|
|
|
- (org-export--prepare-file-contents
|
|
|
- file lines ind minlevel
|
|
|
- (or (gethash file file-prefix)
|
|
|
- (puthash file (cl-incf current-prefix) file-prefix))
|
|
|
- footnotes)))
|
|
|
- (org-export-expand-include-keyword
|
|
|
- (cons (list file lines) included)
|
|
|
- (file-name-directory file)
|
|
|
- footnotes)
|
|
|
- (buffer-string)))))
|
|
|
- ;; Expand footnotes after all files have been included.
|
|
|
- ;; Footnotes are stored at end of buffer.
|
|
|
- (unless included
|
|
|
- (org-with-wide-buffer
|
|
|
- (goto-char (point-max))
|
|
|
- (maphash (lambda (k v) (insert (format "\n[fn:%s] %s\n" k v)))
|
|
|
- footnotes)))))))))))
|
|
|
+ (cond
|
|
|
+ ((eq env 'literal)
|
|
|
+ (insert
|
|
|
+ (let ((ind-str (make-string ind ?\s))
|
|
|
+ (arg-str (if (stringp args) (format " %s" args) ""))
|
|
|
+ (contents
|
|
|
+ (org-escape-code-in-string
|
|
|
+ (org-export--prepare-file-contents file lines))))
|
|
|
+ (format "%s#+BEGIN_%s%s\n%s%s#+END_%s\n"
|
|
|
+ ind-str block arg-str contents ind-str block))))
|
|
|
+ ((stringp block)
|
|
|
+ (insert
|
|
|
+ (let ((ind-str (make-string ind ?\s))
|
|
|
+ (contents
|
|
|
+ (org-export--prepare-file-contents file lines)))
|
|
|
+ (format "%s#+BEGIN_%s\n%s%s#+END_%s\n"
|
|
|
+ ind-str block contents ind-str block))))
|
|
|
+ (t
|
|
|
+ (insert
|
|
|
+ (with-temp-buffer
|
|
|
+ (let ((org-inhibit-startup t)
|
|
|
+ (lines
|
|
|
+ (if location
|
|
|
+ (org-export--inclusion-absolute-lines
|
|
|
+ file location only-contents lines)
|
|
|
+ lines)))
|
|
|
+ (org-mode)
|
|
|
+ (insert
|
|
|
+ (org-export--prepare-file-contents
|
|
|
+ file lines ind minlevel
|
|
|
+ (or
|
|
|
+ (gethash file file-prefix)
|
|
|
+ (puthash file (cl-incf current-prefix) file-prefix))
|
|
|
+ footnotes)))
|
|
|
+ (org-export-expand-include-keyword
|
|
|
+ (cons (list file lines) included)
|
|
|
+ (file-name-directory file)
|
|
|
+ footnotes)
|
|
|
+ (buffer-string)))))
|
|
|
+ ;; Expand footnotes after all files have been
|
|
|
+ ;; included. Footnotes are stored at end of buffer.
|
|
|
+ (unless included
|
|
|
+ (org-with-wide-buffer
|
|
|
+ (goto-char (point-max))
|
|
|
+ (maphash (lambda (k v)
|
|
|
+ (insert (format "\n[fn:%s] %s\n" k v)))
|
|
|
+ footnotes))))))))))))
|
|
|
|
|
|
(defun org-export--inclusion-absolute-lines (file location only-contents lines)
|
|
|
"Resolve absolute lines for an included file with file-link.
|