 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
 ;; Org mode export to TREC format ;;
 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+
+(defun org-trec-fold (f x list) ;; copped from the net, name-prefixed to avoid collision
+  "Recursively applies (F i j) to LIST starting with X.
+For example, (fold F X '(1 2 3)) computes (F (F (F X 1) 2) 3)."
+ (let ((li list) (x2 x))
+   (while li
+     (setq x2 (funcall f x2 (pop li)))
+   )
+   x2
+  )
+)
+
+;; escaping for XML
+(setq org-trec-escape-alist
+	  '(("&" . "&amp;") ;; MUST be first to avoid double-escaping of &'s
+		("<" . "&lt;")
+		(">" . "&gt;")))
+
 (defun org-trec-escape (data)
   "Escape data to be put into the TREC format"
-  data)
+  (if data
+	  (org-trec-fold
+	   (lambda (data pair)
+		 (replace-regexp-in-string (car pair) (cdr pair) data))
+	   data
+	   org-trec-escape-alist)))
 
 ;; boring, undecorated stuff
 (defun org-trec-export-raw (element contents info)
-  (org-trec-escape contents))
+  contents)
 (defun org-trec-export-value (element contents info)
-  (org-trec-escape (org-element-property :value element)))
+  (org-element-property :value element))
 
 (defun org-trec-link (link desc info)
-  (org-trec-escape
-   (concat desc " <" (org-element-property :raw-link link) ">")))
+  (concat desc " <" (org-element-property :raw-link link) ">"))
 (defun org-trec-plain-text (text info)
-  (org-trec-escape text))
+  text)
 ;; i don't often use it in this context...
 (defun org-trec-subscript (element contents info)
-  (org-trec-escape (concat "_" contents)))
+  (concat "_" contents))
 
 ;; other stuff
 (defun org-trec-headline (headline contents info)
- ;;(with-output-to-string (princ (org-element-property :title headline)))
-  (org-trec-escape
-   (concat (org-export-data (org-element-property :title headline) info) "\n" contents
-		  ;;(with-output-to-string (princ (org-element-contents headline)))
-		   ))
-)
+  ;;(with-output-to-string (princ (org-element-property :title headline)))
+  ;;(with-output-to-string (princ (org-element-contents headline)))
+  (let* ((escaped-contents (org-trec-escape contents))
+		 (escaped-title
+		  (org-trec-escape
+		   (org-export-data
+			(org-element-property :title headline)
+			info)))
+		 (headline-level (org-element-property :level headline))
+		 (tag-name (concat "H" (number-to-string (- headline-level 0)))))
+	(concat "<" tag-name ">" escaped-title "</" tag-name ">\n" contents)))
 
 (defun org-trec-planning (planning contents info)
   (message (with-output-to-string (princ (org-element-property :closed planning))))


(defun org-trec-template (contents info)
  "Wrap the complete exported contents"
  (concat "<DOC>\n" contents "</TEXT>\n</DOC>"))

;; http://orgmode.org/worg/dev/org-export-reference.html
;; c.f. org-export-registered-backends

(defun org-trec-section (section contents info)
  ;; TODO this is a bit limiting, it implies all docs have a beginning
  ;; "section" to set the title
  (let ((escaped-contents (org-trec-escape contents)))
	(if (= 1 (org-element-property :begin section))
		(concat "<TITLE>" escaped-contents "</TITLE>\n<TEXT>\n")
	  ;; these contents will be escape by their headlines
	  escaped-contents)))

(defun org-timestamp-to-date-string (timestamp)
  "Convert an Org mode timestamp object to a string with time if given. e.g. 2013-01-01 10:13"
