forked from mirrors/org-mode
ox: Look for export and noexport tags in FILETAGS
* lisp/ox.el (org-export--selected-trees): (org-export--skip-p): Check also FILETAGS. * lisp/ox.el (org-export-get-tags): Also report export and noexport tags. Reported-by: Michael Welle <mwe012008@gmx.net> <http://permalink.gmane.org/gmane.emacs.orgmode/102754>
This commit is contained in:
parent
c993007eb6
commit
b5b08a7f52
71
lisp/ox.el
71
lisp/ox.el
|
@ -1774,35 +1774,39 @@ for a footnotes section."
|
||||||
"List headlines and inlinetasks with a select tag in their tree.
|
"List headlines and inlinetasks with a select tag in their tree.
|
||||||
DATA is parsed data as returned by `org-element-parse-buffer'.
|
DATA is parsed data as returned by `org-element-parse-buffer'.
|
||||||
INFO is a plist holding export options."
|
INFO is a plist holding export options."
|
||||||
(letrec ((selected-trees)
|
(let ((select (plist-get info :select-tags)))
|
||||||
(walk-data
|
(if (cl-some (lambda (tag) (member tag select)) (plist-get info :filetags))
|
||||||
(lambda (data genealogy)
|
;; If FILETAGS contains a select tag, every headline or
|
||||||
(let ((type (org-element-type data)))
|
;; inlinetask is returned.
|
||||||
(cond
|
(org-element-map data '(headline inlinetask) #'identity)
|
||||||
((memq type '(headline inlinetask))
|
(letrec ((selected-trees)
|
||||||
(let ((tags (org-element-property :tags data)))
|
(walk-data
|
||||||
(if (cl-loop for tag in (plist-get info :select-tags)
|
(lambda (data genealogy)
|
||||||
thereis (member tag tags))
|
(let ((type (org-element-type data)))
|
||||||
;; When a select tag is found, mark full
|
(cond
|
||||||
;; genealogy and every headline within the
|
((memq type '(headline inlinetask))
|
||||||
;; tree as acceptable.
|
(let ((tags (org-element-property :tags data)))
|
||||||
(setq selected-trees
|
(if (cl-some (lambda (tag) (member tag select)) tags)
|
||||||
(append
|
;; When a select tag is found, mark full
|
||||||
genealogy
|
;; genealogy and every headline within the
|
||||||
(org-element-map data '(headline inlinetask)
|
;; tree as acceptable.
|
||||||
#'identity)
|
(setq selected-trees
|
||||||
selected-trees))
|
(append
|
||||||
;; If at a headline, continue searching in tree,
|
genealogy
|
||||||
;; recursively.
|
(org-element-map data '(headline inlinetask)
|
||||||
(when (eq type 'headline)
|
#'identity)
|
||||||
(dolist (el (org-element-contents data))
|
selected-trees))
|
||||||
(funcall walk-data el (cons data genealogy)))))))
|
;; If at a headline, continue searching in
|
||||||
((or (eq type 'org-data)
|
;; tree, recursively.
|
||||||
(memq type org-element-greater-elements))
|
(when (eq type 'headline)
|
||||||
(dolist (el (org-element-contents data))
|
(dolist (el (org-element-contents data))
|
||||||
(funcall walk-data el genealogy))))))))
|
(funcall walk-data el (cons data genealogy)))))))
|
||||||
(funcall walk-data data nil)
|
((or (eq type 'org-data)
|
||||||
selected-trees))
|
(memq type org-element-greater-elements))
|
||||||
|
(dolist (el (org-element-contents data))
|
||||||
|
(funcall walk-data el genealogy))))))))
|
||||||
|
(funcall walk-data data nil)
|
||||||
|
selected-trees))))
|
||||||
|
|
||||||
(defun org-export--skip-p (blob options selected)
|
(defun org-export--skip-p (blob options selected)
|
||||||
"Non-nil when element or object BLOB should be skipped during export.
|
"Non-nil when element or object BLOB should be skipped during export.
|
||||||
|
@ -1831,7 +1835,7 @@ a tree with a select tag."
|
||||||
(todo (org-element-property :todo-keyword blob))
|
(todo (org-element-property :todo-keyword blob))
|
||||||
(todo-type (org-element-property :todo-type blob))
|
(todo-type (org-element-property :todo-type blob))
|
||||||
(archived (plist-get options :with-archived-trees))
|
(archived (plist-get options :with-archived-trees))
|
||||||
(tags (org-element-property :tags blob)))
|
(tags (org-export-get-tags blob options nil t)))
|
||||||
(or
|
(or
|
||||||
(and (eq (org-element-type blob) 'inlinetask)
|
(and (eq (org-element-type blob) 'inlinetask)
|
||||||
(not (plist-get options :with-inlinetasks)))
|
(not (plist-get options :with-inlinetasks)))
|
||||||
|
@ -3942,18 +3946,13 @@ INFO is a plist used as a communication channel."
|
||||||
ELEMENT has either an `headline' or an `inlinetask' type. INFO
|
ELEMENT has either an `headline' or an `inlinetask' type. INFO
|
||||||
is a plist used as a communication channel.
|
is a plist used as a communication channel.
|
||||||
|
|
||||||
Select tags (see `org-export-select-tags') and exclude tags (see
|
|
||||||
`org-export-exclude-tags') are removed from the list.
|
|
||||||
|
|
||||||
When non-nil, optional argument TAGS should be a list of strings.
|
When non-nil, optional argument TAGS should be a list of strings.
|
||||||
Any tag belonging to this list will also be removed.
|
Any tag belonging to this list will also be removed.
|
||||||
|
|
||||||
When optional argument INHERITED is non-nil, tags can also be
|
When optional argument INHERITED is non-nil, tags can also be
|
||||||
inherited from parent headlines and FILETAGS keywords."
|
inherited from parent headlines and FILETAGS keywords."
|
||||||
(cl-remove-if
|
(cl-remove-if
|
||||||
(lambda (tag) (or (member tag (plist-get info :select-tags))
|
(lambda (tag) (member tag tags))
|
||||||
(member tag (plist-get info :exclude-tags))
|
|
||||||
(member tag tags)))
|
|
||||||
(if (not inherited) (org-element-property :tags element)
|
(if (not inherited) (org-element-property :tags element)
|
||||||
;; Build complete list of inherited tags.
|
;; Build complete list of inherited tags.
|
||||||
(let ((current-tag-list (org-element-property :tags element)))
|
(let ((current-tag-list (org-element-property :tags element)))
|
||||||
|
|
|
@ -406,27 +406,39 @@ Paragraph"
|
||||||
(org-test-with-temp-text "* Head1 :noexp:"
|
(org-test-with-temp-text "* Head1 :noexp:"
|
||||||
(org-export-as (org-test-default-backend)
|
(org-export-as (org-test-default-backend)
|
||||||
nil nil nil '(:exclude-tags ("noexp")))))))
|
nil nil nil '(:exclude-tags ("noexp")))))))
|
||||||
|
(should
|
||||||
|
(equal "#+FILETAGS: noexp\n"
|
||||||
|
(let (org-export-filter-body-functions
|
||||||
|
org-export-filter-final-output-functions)
|
||||||
|
(org-test-with-temp-text "#+FILETAGS: noexp\n* Head1"
|
||||||
|
(org-export-as (org-test-default-backend)
|
||||||
|
nil nil nil '(:exclude-tags ("noexp")))))))
|
||||||
;; Test include tags for headlines and inlinetasks.
|
;; Test include tags for headlines and inlinetasks.
|
||||||
(should
|
(should
|
||||||
(equal "* H2\n** Sub :exp:\n*** Sub Sub\n"
|
(equal (org-test-with-temp-text "* H1\n* H2\n** Sub :exp:\n*** Sub Sub\n* H3"
|
||||||
(org-test-with-temp-text "* H1\n* H2\n** Sub :exp:\n*** Sub Sub\n* H3"
|
|
||||||
(let ((org-tags-column 0))
|
(let ((org-tags-column 0))
|
||||||
(org-export-as (org-test-default-backend)
|
(org-export-as (org-test-default-backend)
|
||||||
nil nil nil '(:select-tags ("exp")))))))
|
nil nil nil '(:select-tags ("exp")))))
|
||||||
|
"* H2\n** Sub :exp:\n*** Sub Sub\n"))
|
||||||
;; If there is an include tag, ignore the section before the first
|
;; If there is an include tag, ignore the section before the first
|
||||||
;; headline, if any.
|
;; headline, if any.
|
||||||
(should
|
(should
|
||||||
(equal "* H1 :exp:\nBody\n"
|
(equal (org-test-with-temp-text "First section\n* H1 :exp:\nBody"
|
||||||
(org-test-with-temp-text "First section\n* H1 :exp:\nBody"
|
|
||||||
(let ((org-tags-column 0))
|
(let ((org-tags-column 0))
|
||||||
(org-export-as (org-test-default-backend)
|
(org-export-as (org-test-default-backend)
|
||||||
nil nil nil '(:select-tags ("exp")))))))
|
nil nil nil '(:select-tags ("exp")))))
|
||||||
|
"* H1 :exp:\nBody\n"))
|
||||||
|
(should
|
||||||
|
(equal (org-test-with-temp-text "#+FILETAGS: exp\nFirst section\n* H1\nBody"
|
||||||
|
(org-export-as (org-test-default-backend)
|
||||||
|
nil nil nil '(:select-tags ("exp"))))
|
||||||
|
"* H1\nBody\n"))
|
||||||
(should-not
|
(should-not
|
||||||
(equal "* H1 :exp:\n"
|
(equal (org-test-with-temp-text "* H1 :exp:\nBody"
|
||||||
(org-test-with-temp-text "* H1 :exp:\nBody"
|
|
||||||
(let ((org-tags-column 0))
|
(let ((org-tags-column 0))
|
||||||
(org-export-as (org-test-default-backend)
|
(org-export-as (org-test-default-backend)
|
||||||
nil nil nil '(:select-tags ("exp")))))))
|
nil nil nil '(:select-tags ("exp")))))
|
||||||
|
"* H1 :exp:\n"))
|
||||||
;; Test mixing include tags and exclude tags.
|
;; Test mixing include tags and exclude tags.
|
||||||
(should
|
(should
|
||||||
(string-match
|
(string-match
|
||||||
|
@ -2099,49 +2111,31 @@ Footnotes[fn:2], foot[fn:test], digit only[3], and [fn:inline:anonymous footnote
|
||||||
|
|
||||||
(ert-deftest test-org-export/get-tags ()
|
(ert-deftest test-org-export/get-tags ()
|
||||||
"Test `org-export-get-tags' specifications."
|
"Test `org-export-get-tags' specifications."
|
||||||
(let ((org-export-exclude-tags '("noexport"))
|
;; Standard test: tags which are not a select tag, an exclude tag,
|
||||||
(org-export-select-tags '("export")))
|
;; or specified as optional argument shouldn't be ignored.
|
||||||
;; Standard test: tags which are not a select tag, an exclude tag,
|
(should
|
||||||
;; or specified as optional argument shouldn't be ignored.
|
(org-test-with-parsed-data "* Headline :tag:"
|
||||||
(should
|
(org-export-get-tags (org-element-map tree 'headline 'identity info t)
|
||||||
(org-test-with-parsed-data "* Headline :tag:"
|
info)))
|
||||||
(org-export-get-tags (org-element-map tree 'headline 'identity info t)
|
;; Tags provided in the optional argument are ignored.
|
||||||
info)))
|
(should-not
|
||||||
;; Exclude tags are removed.
|
(org-test-with-parsed-data "* Headline :ignore:"
|
||||||
(should-not
|
(org-export-get-tags (org-element-map tree 'headline 'identity info t)
|
||||||
(org-test-with-parsed-data "* Headline :noexport:"
|
info '("ignore"))))
|
||||||
(org-export-get-tags (org-element-map tree 'headline 'identity info t)
|
;; Allow tag inheritance.
|
||||||
info)))
|
(should
|
||||||
;; Select tags are removed.
|
(equal
|
||||||
(should-not
|
'(("tag") ("tag"))
|
||||||
(org-test-with-parsed-data "* Headline :export:"
|
(org-test-with-parsed-data "* Headline :tag:\n** Sub-heading"
|
||||||
(org-export-get-tags (org-element-map tree 'headline 'identity info t)
|
(org-element-map tree 'headline
|
||||||
info)))
|
(lambda (hl) (org-export-get-tags hl info nil t)) info))))
|
||||||
(should
|
;; Tag inheritance checks FILETAGS keywords.
|
||||||
(equal
|
(should
|
||||||
'("tag")
|
(equal
|
||||||
(org-test-with-parsed-data "* Headline :tag:export:"
|
'(("a" "b" "tag"))
|
||||||
(org-export-get-tags (org-element-map tree 'headline 'identity info t)
|
(org-test-with-parsed-data "#+FILETAGS: :a:b:\n* Headline :tag:"
|
||||||
info))))
|
(org-element-map tree 'headline
|
||||||
;; Tags provided in the optional argument are also ignored.
|
(lambda (hl) (org-export-get-tags hl info nil t)) info)))))
|
||||||
(should-not
|
|
||||||
(org-test-with-parsed-data "* Headline :ignore:"
|
|
||||||
(org-export-get-tags (org-element-map tree 'headline 'identity info t)
|
|
||||||
info '("ignore"))))
|
|
||||||
;; Allow tag inheritance.
|
|
||||||
(should
|
|
||||||
(equal
|
|
||||||
'(("tag") ("tag"))
|
|
||||||
(org-test-with-parsed-data "* Headline :tag:\n** Sub-heading"
|
|
||||||
(org-element-map tree 'headline
|
|
||||||
(lambda (hl) (org-export-get-tags hl info nil t)) info))))
|
|
||||||
;; Tag inheritance checks FILETAGS keywords.
|
|
||||||
(should
|
|
||||||
(equal
|
|
||||||
'(("a" "b" "tag"))
|
|
||||||
(org-test-with-parsed-data "#+FILETAGS: :a:b:\n* Headline :tag:"
|
|
||||||
(org-element-map tree 'headline
|
|
||||||
(lambda (hl) (org-export-get-tags hl info nil t)) info))))))
|
|
||||||
|
|
||||||
(ert-deftest test-org-export/get-node-property ()
|
(ert-deftest test-org-export/get-node-property ()
|
||||||
"Test`org-export-get-node-property' specifications."
|
"Test`org-export-get-node-property' specifications."
|
||||||
|
|
Loading…
Reference in New Issue