소스 검색

org-element: Internally store headline/inlinetask's tags as a list of strings

* contrib/lisp/org-element.el (org-element-headline-parser,
  org-element-headline-interpreter, org-element-inlinetask-parser,
  org-element-inlinetask-interpreter): Store headline/inlinetask's
  tags as a list of strings.
* contrib/lisp/org-export.el (org-export--selected-trees,
  org-export--skip-p): Use new tag representation.
* contrib/lisp/org-e-ascii.el (org-e-ascii--build-title,
  org-e-ascii-format-inlinetask-function, org-e-ascii-inlinetask): Use
  new tag representation.
* contrib/lisp/org-e-html.el (org-e-html-format-headline-function,
  org-e-html-format-inlinetask-function, org-e-html--tags): Use new
  tag representation.
* contrib/lisp/org-e-latex.el (org-e-latex-format-headline-function,
  org-e-latex-format-inlinetask-function, org-e-latex-headline,
  org-e-latex-inlinetask): Use new tag representation.
* contrib/lisp/org-e-odt.el (org-e-odt-format-org-tags): Use new tag
  representation.
* testing/lisp/test-org-element.el: Update test.
Nicolas Goaziou 13 년 전
부모
커밋
32a5920e69
7개의 변경된 파일92개의 추가작업 그리고 81개의 파일을 삭제
  1. 24 14
      contrib/lisp/org-e-ascii.el
  2. 17 17
      contrib/lisp/org-e-html.el
  3. 27 20
      contrib/lisp/org-e-latex.el
  4. 1 1
      contrib/lisp/org-e-odt.el
  5. 18 21
      contrib/lisp/org-element.el
  6. 4 7
      contrib/lisp/org-export.el
  7. 1 1
      testing/lisp/test-org-element.el

+ 24 - 14
contrib/lisp/org-e-ascii.el

@@ -368,7 +368,7 @@ The function must accept six parameters:
   TODO-TYPE the todo type, a symbol among `todo', `done' and nil.
   PRIORITY  the inlinetask priority, as a string
   NAME      the inlinetask name, as a string.
-  TAGS      the inlinetask tags, as a string.
+  TAGS      the inlinetask tags, as a list of strings.
   CONTENTS  the contents of the inlinetask, as a string.
 
 The function should return either the string to be exported or
@@ -580,7 +580,7 @@ title."
 	       ;; All tests passed: build numbering string.
 	       (concat
 		(mapconcat
-		 #'number-to-string
+		 'number-to-string
 		 (org-export-get-headline-number element info) ".")
 		" ")))
 	 (text (org-export-data (org-element-property :title element) info))
@@ -590,7 +590,10 @@ title."
 		 (and todo (concat (org-export-data todo info) " ")))))
 	 (tags (and (not notags)
 		    (plist-get info :with-tags)
-		    (org-element-property :tags element)))
+		    (let ((tag-list (org-element-property :tags element)))
+		      (and tag-list
+			   (format ":%s:"
+				   (mapconcat 'identity tag-list ":"))))))
 	 (priority
 	  (and (plist-get info :with-priority)
 	       (concat (org-element-property :priority element) " ")))
@@ -1220,21 +1223,28 @@ contextual information."
   "Transcode an INLINETASK element from Org to ASCII.
 CONTENTS holds the contents of the block.  INFO is a plist
 holding contextual information."
-  (let ((width (org-e-ascii--current-text-width inlinetask info))
-	(title (org-export-data (org-element-property :title inlinetask) info))
-	(todo (and (plist-get info :with-todo-keywords)
-		   (let ((todo (org-element-property :todo-keyword inlinetask)))
-		     (and todo (org-export-data todo info)))))
-	(todo-type (org-element-property :todo-type inlinetask))
-	(tags (and (plist-get info :with-tags)
-		   (org-element-property :tags inlinetask)))
-	(priority (and (plist-get info :with-priority)
-		       (org-element-property :priority inlinetask))))
+  (let ((width (org-e-ascii--current-text-width inlinetask info)))
     ;; If `org-e-ascii-format-inlinetask-function' is provided, call it
     ;; with appropriate arguments.
     (if (functionp org-e-ascii-format-inlinetask-function)
 	(funcall org-e-ascii-format-inlinetask-function
-		 todo todo-type priority title tags contents width)
+		 ;; todo.
+		 (and (plist-get info :with-todo-keywords)
+		      (let ((todo (org-element-property
+				   :todo-keyword inlinetask)))
+			(and todo (org-export-data todo info))))
+		 ;; todo-type
+		 (org-element-property :todo-type inlinetask)
+		 ;; priority
+		 (and (plist-get info :with-priority)
+		      (org-element-property :priority inlinetask))
+		 ;; title
+		 (org-export-data (org-element-property :title inlinetask) info)
+		 ;; tags
+		 (and (plist-get info :with-tags)
+		      (org-element-property :tags inlinetask))
+		 ;; contents and width
+		 contents width)
       ;; Otherwise, use a default template.
       (let* ((utf8p (eq (plist-get info :ascii-charset) 'utf-8)))
 	(org-e-ascii--indent-string

+ 17 - 17
contrib/lisp/org-e-html.el

@@ -840,25 +840,25 @@ When nil, the links still point to the plain `.org' file."
   "Function to format headline text.
 
 This function will be called with 5 arguments:
-TODO      the todo keyword \(string or nil\).
-TODO-TYPE the type of todo \(symbol: `todo', `done', nil\)
-PRIORITY  the priority of the headline \(integer or nil\)
-TEXT      the main headline text \(string\).
-TAGS      the tags string, separated with colons \(string or nil\).
+TODO      the todo keyword (string or nil).
+TODO-TYPE the type of todo (symbol: `todo', `done', nil)
+PRIORITY  the priority of the headline (integer or nil)
+TEXT      the main headline text (string).
+TAGS      the tags (string or nil).
 
 The function result will be used in the section format string.
 
 As an example, one could set the variable to the following, in
 order to reproduce the default set-up:
 
-\(defun org-e-html-format-headline \(todo todo-type priority text tags\)
+\(defun org-e-html-format-headline \(todo todo-type priority text tags)
   \"Default format function for an headline.\"
   \(concat \(when todo
-            \(format \"\\\\textbf{\\\\textsc{\\\\textsf{%s}}} \" todo\)\)
+            \(format \"\\\\textbf{\\\\textsc{\\\\textsf{%s}}} \" todo))
 	  \(when priority
-            \(format \"\\\\framebox{\\\\#%c} \" priority\)\)
+            \(format \"\\\\framebox{\\\\#%c} \" priority))
 	  text
-	  \(when tags \(format \"\\\\hfill{}\\\\textsc{%s}\" tags\)\)\)\)"
+	  \(when tags (format \"\\\\hfill{}\\\\textsc{%s}\" tags))))"
   :group 'org-export-e-html
   :type 'function)
 
@@ -972,7 +972,7 @@ The function must accept six parameters:
   TODO-TYPE the todo type, a symbol among `todo', `done' and nil.
   PRIORITY  the inlinetask priority, as a string
   NAME      the inlinetask name, as a string.
-  TAGS      the inlinetask tags, as a string.
+  TAGS      the inlinetask tags, as a list of strings.
   CONTENTS  the contents of the inlinetask, as a string.
 
 The function should return the string to be exported.
@@ -985,19 +985,19 @@ in order to mimic default behaviour:
   \(let \(\(full-title
 	 \(concat
 	  \(when todo
-            \(format \"\\\\textbf{\\\\textsf{\\\\textsc{%s}}} \" todo\)\)
-	  \(when priority \(format \"\\\\framebox{\\\\#%c} \" priority\)\)
+            \(format \"\\\\textbf{\\\\textsf{\\\\textsc{%s}}} \" todo))
+	  \(when priority (format \"\\\\framebox{\\\\#%c} \" priority))
 	  title
-	  \(when tags \(format \"\\\\hfill{}\\\\textsc{%s}\" tags\)\)\)\)\)
-    \(format \(concat \"\\\\begin{center}\\n\"
+	  \(when tags (format \"\\\\hfill{}\\\\textsc{%s}\" tags)))))
+    \(format (concat \"\\\\begin{center}\\n\"
 		    \"\\\\fbox{\\n\"
 		    \"\\\\begin{minipage}[c]{.6\\\\textwidth}\\n\"
 		    \"%s\\n\\n\"
 		    \"\\\\rule[.8em]{\\\\textwidth}{2pt}\\n\\n\"
 		    \"%s\"
 		    \"\\\\end{minipage}}\"
-		    \"\\\\end{center}\"\)
-	    full-title contents\)\)"
+		    \"\\\\end{center}\")
+	    full-title contents))"
   :group 'org-export-e-html
   :type 'function)
 
@@ -1715,7 +1715,7 @@ original parsed data.  INFO is a plist holding export options."
 		       (concat org-e-html-tag-class-prefix
 			       (org-e-html-fix-class-name tag))
 		       tag))
-	     (org-split-string tags ":") " "))))
+	     tags " "))))
 
 ;;;; Headline
 

+ 27 - 20
contrib/lisp/org-e-latex.el

@@ -266,25 +266,27 @@ argument."
   "Function to format headline text.
 
 This function will be called with 5 arguments:
-TODO      the todo keyword \(string or nil\).
-TODO-TYPE the type of todo \(symbol: `todo', `done', nil\)
-PRIORITY  the priority of the headline \(integer or nil\)
-TEXT      the main headline text \(string\).
-TAGS      the tags string, separated with colons \(string or nil\).
+TODO      the todo keyword (string or nil).
+TODO-TYPE the type of todo (symbol: `todo', `done', nil)
+PRIORITY  the priority of the headline (integer or nil)
+TEXT      the main headline text (string).
+TAGS      the tags as a list of strings (list of strings or nil).
 
 The function result will be used in the section format string.
 
 As an example, one could set the variable to the following, in
 order to reproduce the default set-up:
 
-\(defun org-e-latex-format-headline \(todo todo-type priority text tags\)
+\(defun org-e-latex-format-headline (todo todo-type priority text tags)
   \"Default format function for an headline.\"
-  \(concat \(when todo
-            \(format \"\\\\textbf{\\\\textsc{\\\\textsf{%s}}} \" todo\)\)
+  \(concat (when todo
+            \(format \"\\\\textbf{\\\\textsc{\\\\textsf{%s}}} \" todo))
 	  \(when priority
-            \(format \"\\\\framebox{\\\\#%c} \" priority\)\)
+            \(format \"\\\\framebox{\\\\#%c} \" priority))
 	  text
-	  \(when tags \(format \"\\\\hfill{}\\\\textsc{%s}\" tags\)\)\)\)"
+	  \(when tags
+            \(format \"\\\\hfill{}\\\\textsc{%s}\"
+              \(mapconcat 'identity tags \":\"))))"
   :group 'org-export-e-latex
   :type 'function)
 
@@ -447,7 +449,7 @@ The function must accept six parameters:
   TODO-TYPE the todo type, a symbol among `todo', `done' and nil.
   PRIORITY  the inlinetask priority, as a string
   NAME      the inlinetask name, as a string.
-  TAGS      the inlinetask tags, as a string.
+  TAGS      the inlinetask tags, as a list of strings.
   CONTENTS  the contents of the inlinetask, as a string.
 
 The function should return the string to be exported.
@@ -457,22 +459,24 @@ in order to mimic default behaviour:
 
 \(defun org-e-latex-format-inlinetask \(todo type priority name tags contents\)
 \"Format an inline task element for LaTeX export.\"
-  \(let \(\(full-title
+  \(let ((full-title
 	 \(concat
 	  \(when todo
-            \(format \"\\\\textbf{\\\\textsf{\\\\textsc{%s}}} \" todo\)\)
-	  \(when priority \(format \"\\\\framebox{\\\\#%c} \" priority\)\)
+            \(format \"\\\\textbf{\\\\textsf{\\\\textsc{%s}}} \" todo))
+	  \(when priority (format \"\\\\framebox{\\\\#%c} \" priority))
 	  title
-	  \(when tags \(format \"\\\\hfill{}\\\\textsc{%s}\" tags\)\)\)\)\)
-    \(format \(concat \"\\\\begin{center}\\n\"
+	  \(when tags
+            \(format \"\\\\hfill{}\\\\textsc{:%s:}\"
+                    \(mapconcat 'identity tags \":\")))))
+    \(format (concat \"\\\\begin{center}\\n\"
 		    \"\\\\fbox{\\n\"
 		    \"\\\\begin{minipage}[c]{.6\\\\textwidth}\\n\"
 		    \"%s\\n\\n\"
 		    \"\\\\rule[.8em]{\\\\textwidth}{2pt}\\n\\n\"
 		    \"%s\"
 		    \"\\\\end{minipage}}\"
-		    \"\\\\end{center}\"\)
-	    full-title contents\)\)"
+		    \"\\\\end{center}\")
+	    full-title contents))"
   :group 'org-export-e-latex
   :type 'function)
 
@@ -1194,7 +1198,9 @@ holding contextual information."
 			 (format "\\textbf{\\textsf{\\textsc{%s}}} " todo))
 		       (when priority (format "\\framebox{\\#%c} " priority))
 		       text
-		       (when tags (format "\\hfill{}\\textsc{%s}" tags)))))
+		       (when tags
+			 (format "\\hfill{}\\textsc{:%s:}"
+				 (mapconcat 'identity tags ":"))))))
 	 ;; Associate some \label to the headline for internal links.
 	 (headline-label
 	  (format "\\label{sec-%s}\n"
@@ -1313,7 +1319,8 @@ holding contextual information."
 	       (when todo (format "\\textbf{\\textsf{\\textsc{%s}}} " todo))
 	       (when priority (format "\\framebox{\\#%c} " priority))
 	       title
-	       (when tags (format "\\hfill{}\\textsc{%s}" tags)))))
+	       (when tags (format "\\hfill{}\\textsc{:%s:}"
+				  (mapconcat 'identity tags ":"))))))
 	 (format (concat "\\begin{center}\n"
 			 "\\fbox{\n"
 			 "\\begin{minipage}[c]{.6\\textwidth}\n"

+ 1 - 1
contrib/lisp/org-e-odt.el

@@ -2690,7 +2690,7 @@ Replaces invalid characters with \"_\"."
 	(org-e-odt-format-fontify
 	 x (concat "" ;; org-e-odt-tag-class-prefix
 		   (org-e-odt-fix-class-name x))))
-      (org-split-string tags ":")
+      tags
       (org-e-odt-format-spaces 1)) "tag")))
 
 (defun org-e-odt-format-section-number (&optional snumber level)

+ 18 - 21
contrib/lisp/org-element.el

@@ -344,7 +344,8 @@ Assume point is at beginning of the headline."
 	   (todo (nth 2 components))
 	   (todo-type
 	    (and todo (if (member todo org-done-keywords) 'done 'todo)))
-	   (tags (nth 5 components))
+	   (tags (let ((raw-tags (nth 5 components)))
+		   (and raw-tags (org-split-string raw-tags ":"))))
 	   (raw-value (nth 4 components))
 	   (quotedp
 	    (let ((case-fold-search nil))
@@ -352,10 +353,7 @@ Assume point is at beginning of the headline."
 	   (commentedp
 	    (let ((case-fold-search nil))
 	      (string-match (format "^%s +" org-comment-string) raw-value)))
-	   (archivedp
-	    (and tags
-		 (let ((case-fold-search nil))
-		   (string-match (format ":%s:" org-archive-tag) tags))))
+	   (archivedp (member org-archive-tag tags))
 	   (footnote-section-p (and org-footnote-section
 				    (string= org-footnote-section raw-value)))
 	   (standard-props (let (plist)
@@ -394,12 +392,7 @@ Assume point is at beginning of the headline."
 	       ""
 	       raw-value)))
       ;; Clean TAGS from archive tag, if any.
-      (when archivedp
-	(setq tags
-	      (and (not (string= tags (format ":%s:" org-archive-tag)))
-		   (replace-regexp-in-string
-		    (concat org-archive-tag ":") "" tags)))
-	(when (string= tags ":") (setq tags nil)))
+      (when archivedp (setq tags (delete org-archive-tag tags)))
       ;; Then get TITLE.
       (setq title
 	    (if raw-secondary-p raw-value
@@ -436,14 +429,14 @@ CONTENTS is the contents of the element."
   (let* ((level (org-element-property :level headline))
 	 (todo (org-element-property :todo-keyword headline))
 	 (priority (org-element-property :priority headline))
-	 (title (org-element-interpret-data (org-element-property :title headline)))
-	 (tags (let ((tag-string (org-element-property :tags headline))
-		     (archivedp (org-element-property :archivedp headline)))
-		 (cond
-		  ((and (not tag-string) archivedp)
-		   (format ":%s:" org-archive-tag))
-		  (archivedp (concat ":" org-archive-tag tag-string))
-		  (t tag-string))))
+	 (title (org-element-interpret-data
+		 (org-element-property :title headline)))
+	 (tags (let ((tag-list (if (org-element-property :archivedp headline)
+				   (cons org-archive-tag
+					 (org-element-property :tags headline))
+				 (org-element-property :tags headline))))
+		 (and tag-list
+		      (format ":%s:" (mapconcat 'identity tag-list ":")))))
 	 (commentedp (org-element-property :commentedp headline))
 	 (quotedp (org-element-property :quotedp headline))
 	 (pre-blank (or (org-element-property :pre-blank headline) 0))
@@ -504,6 +497,8 @@ Assume point is at beginning of the inline task."
 	   (todo (nth 2 components))
 	   (todo-type (and todo
 			   (if (member todo org-done-keywords) 'done 'todo)))
+	   (tags (let ((raw-tags (nth 5 components)))
+		   (and raw-tags (org-split-string raw-tags ":"))))
 	   (title (if raw-secondary-p (nth 4 components)
 		    (org-element-parse-secondary-string
 		     (nth 4 components)
@@ -544,7 +539,7 @@ Assume point is at beginning of the inline task."
 		:contents-end ,contents-end
 		:level ,(nth 1 components)
 		:priority ,(nth 3 components)
-		:tags ,(nth 5 components)
+		:tags ,tags
 		:todo-keyword ,todo
 		:todo-type ,todo-type
 		:scheduled ,scheduled
@@ -563,7 +558,9 @@ CONTENTS is the contents of inlinetask."
 	 (priority (org-element-property :priority inlinetask))
 	 (title (org-element-interpret-data
 		 (org-element-property :title inlinetask)))
-	 (tags (org-element-property :tags inlinetask))
+	 (tags (let ((tag-list (org-element-property :tags inlinetask)))
+		 (and tag-list
+		      (format ":%s:" (mapconcat 'identity tag-list ":")))))
 	 (task (concat (make-string level ?*)
 		       (and todo (concat " " todo))
 		       (and priority

+ 4 - 7
contrib/lisp/org-export.el

@@ -1450,10 +1450,8 @@ INFO is a plist holding export options."
 	       (funcall walk-data (org-element-contents data) genealogy))
 	      (headline
 	       (let ((tags (org-element-property :tags headline)))
-		 (if (and tags
-			  (loop for tag in (plist-get info :select-tags)
-				thereis (string-match
-					 (format ":%s:" tag) tags)))
+		 (if (loop for tag in (plist-get info :select-tags)
+			   thereis (member tag tags))
 		     ;; When a select tag is found, mark as acceptable
 		     ;; full genealogy and every headline within the
 		     ;; tree.
@@ -1477,12 +1475,11 @@ non-nil, is a list of tags marking a subtree as exportable."
 	   (todo (org-element-property :todo-keyword blob))
 	   (todo-type (org-element-property :todo-type blob))
 	   (archived (plist-get options :with-archived-trees))
-	   (tag-list (let ((tags (org-element-property :tags blob)))
-		       (and tags (org-split-string tags ":")))))
+	   (tags (org-element-property :tags blob)))
        (or
 	;; Ignore subtrees with an exclude tag.
 	(loop for k in (plist-get options :exclude-tags)
-	      thereis (member k tag-list))
+	      thereis (member k tags))
 	;; Ignore subtrees without a select tag, when such tag is
 	;; found in the buffer.
 	(member blob select-tags)

+ 1 - 1
testing/lisp/test-org-element.el

@@ -275,7 +275,7 @@ Return interpreted string."
       (let ((headline (org-element-at-point)))
 	(should (org-element-property :archivedp headline))
 	;; Test tag removal.
-	(should (equal (org-element-property :tags headline) ":test:"))))))
+	(should (equal (org-element-property :tags headline) '("test")))))))
 
 
 ;;;; Verse blocks