I have used something like this: (defun gb-set-filetag (tag value) "Set filetag TAG to VALUE. If VALUE is nil, remove the filetag." (save-excursion (goto-char (point-min)) (if (re-search-forward (format "#\\+%s:" tag) (point-max) 'end) ;; replace existing filetag (progn (beginning-of-line) (kill-line) (when value (insert (format "#+%s: %s" tag value)))) ;; add new filetag (if (looking-at "^$") ;empty line ;; at beginning of line (when value (insert (format "#+%s: %s" tag value))) ;; at end of some line, so add a new line (when value (insert (format "\n#+%s: %s" tag value))))))) I am not sure what you mean by the end of the headers. This code ends up putting new keywords at the end of the file. You could add some code I guess that jumps back to the top, and puts it at the next line after the last #+ or something. John ----------------------------------- Professor John Kitchin Doherty Hall A207F Department of Chemical Engineering Carnegie Mellon University Pittsburgh, PA 15213 412-268-7803 @johnkitchin http://kitchingroup.cheme.cmu.edu On Thu, Nov 15, 2018 at 7:14 AM Matt Price wrote: > > > On Sat, Nov 10, 2018 at 1:58 PM Nicolas Goaziou > wrote: > >> Hello, >> >> John Kitchin writes: >> >> > You can retrieve keywords in the org-file like this: >> > >> > (defun get-keyword (key) >> > (org-element-map (org-element-parse-buffer) 'keyword >> > (lambda (k) >> > (when (string= key (org-element-property :key k)) >> > (org-element-property :value k))) >> > nil t)) >> >> As a minor addendum, >> >> (org-element-parse-buffer 'element) >> >> is more efficient in this case. >> >> An even more efficient way to retrieve keywords, assuming buffer is not >> already parsed, would be: >> >> (org-with-point-at 1 >> (let ((case-fold-search t) >> (regexp (format "^[ \t]*#\\+%s:" key)) >> (result nil)) >> (while (re-search-forward regexp nil t) >> (let ((element (org-element-at-point))) >> (when (eq 'keyword (org-element-type element)) >> (push (org-element-property :value element) result)))) >> result)) >> >> This is very helpful, Nicolas and John. > > What about *setting* a global keyword? I would like to write something > like this: > > (defun org-lms-set-global-prop-value (key value) > "Add or update keyword KEY in the org file header." > (save-excursion > (goto-char (point-min)) > (insert (format "#+%s: %" (upcase key) value)))) > > But > (a) insert the value at the *end* of the headers section, not the > beginning. > (b) preferably replace any existing values of the keyword rather than > write a whole new line. > > (b) I guess could be achieved with something like > > (replace-regexp (format "\(^[ \t]*#\\+%s: \)\(.*\)" key) (concat "\1" > value)) > But what about (a)? I thought org already had a couple of functions that > performed this kind of serach but now I'm not so sure. > > > > >> Regards, >> >> -- >> Nicolas Goaziou >> >