2

I currently begin to write a org-mode backend for a custom file format, so I can export from org-file to that format.

Therefore I need to apply properties (or attributes) to headings. My prolbem is now, how I could solve this.

I currently have the following headline function:

(defun org-mine-headline (headline contents info)
  (let ((full-text
         (substring-no-properties
          (org-export-data (org-element-property :title headline) info)))
        (p (org-element-property nil headline))
        (a (org-export-read-attribute :attr_mine headline)))
    (format "%s: [%s] %s" full-text p contents)))

Which gives me with the following org file:

* H1
#+PROPERTY: findme a
foo

the following output:

H1: [nil] foo

But I would like it to become something like that:

H1: [(:findme "a")] foo

I also tried attributes with no success:

* H1
#+ATTR_MINE: :findme a
foo
5
  • You could try (let* ((first-keyword (car (org-element-map headline 'keyword #'identity))) (key (org-element-property :key first-keyword)) (value (org-element-property :value first-keyword))) (list key value)). Depends on the parse depth of headline whether this works or not. key should be "PROPERTY" and value should be "findme a".
    – Tobias
    Jun 1, 2016 at 16:07
  • Thanks, great. That goes into the right direction, it works for the first proprerty. However, I would like to have more than one.
    – theldoria
    Jun 1, 2016 at 16:39
  • No problem. org-element-map gives you the list and you can replace #'identity with the mapping from key to value. So you get the list of values.
    – Tobias
    Jun 1, 2016 at 16:43
  • I now going to do something like (let* ((keywords (org-element-map headline 'keyword #'identity)) (values (mapcar (lambda (keyword) (org-element-property :value keyword)) keywords))) values). Not yet well formed but I think I can work it out. Thanks again for the neat trick with org-element-map. One question, may I need those PROPERTY keys?
    – theldoria
    Jun 1, 2016 at 16:47
  • I've added an answer where the statement from the comment is realized, i.e., #'identity is replaced by the map from the keys to the values. That has the advantage of a selective listing. In our example only PROPERTY keys are listed.
    – Tobias
    Jun 1, 2016 at 17:43

1 Answer 1

2

You can use org-element-map to convert the properties in the section following the heading into a string of values.

There follows an example which should run in the scratch buffer. I have commented out some lines of your code to make this example independent from the org exporter.

(require 'org-element)

(defun org-mine-headline (headline contents info)
  (let ((full-text
         (substring-no-properties
          ;;(org-export-data (org-element-property :title headline) info))
      "\nfull-text\n"))
    (vals (org-element-map headline 'keyword (lambda (key)
                           (when (string= (org-element-property :key key) "PROPERTY")
                             (org-element-property :value key)))))
    ;;(p (org-element-property nil headline))
    ;;(a (org-export-read-attribute :attr_mine headline))
    )
    (format "%s: [%s] %s" full-text (mapconcat #'identity vals ",") contents)))

;; test:

(let ((headline '(headline (:raw-value nil) (section (:begin 436 :end 1516 :contents-begin 436 :contents-end 1516 :post-blank 0 :post-affiliated 436 :parent nil) (keyword (:key "PROPERTY" :value "findme a" :begin 436 :end 459 :post-blank 0 :post-affiliated 436 :parent nil)) (keyword (:key "PROPERTY" :value "findother b" :begin 459 :end 486 :post-blank 1 :post-affiliated 459 :parent nil))))))
  (org-mine-headline headline " contents " nil))
4
  • I had to change the when condition to (when (and (string= (org-element-property :key key) "PROPERTY") (eq (org-element-property :parent (org-element-property :parent key)) headline)), so I don't get properties of subheadings. That now works, hoverer, I'am a bit confused. Following orgmode.org/manual/Property-syntax.html#Property-syntax a property has the form #+PROPERTY: var foo=1 and I should be able to extend the value via #+PROPERTY: var+ bar=2. But I get two distinct elements.
    – theldoria
    Jun 2, 2016 at 11:09
  • Do I have to parse them manually or is there some sort of convenience functions for that?
    – theldoria
    Jun 2, 2016 at 11:09
  • One more question regarding this: is it possible to have values calculated, e.g. with emacs lisp? Inline source blocks seem not to work
    – theldoria
    Jun 2, 2016 at 11:09
  • @Tobias Is there a builtin function for getting the headline at point? Your example seems to suggest so
    – vfclists
    Oct 23, 2020 at 0:32

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.