From mboxrd@z Thu Jan 1 00:00:00 1970 From: Matt Price Subject: Re: creating new #+KEYWORD: variables Date: Thu, 15 Nov 2018 07:15:16 -0500 Message-ID: References: <87h8gpcs86.fsf@nicolasgoaziou.fr> <87r2fsbvz2.fsf@nicolasgoaziou.fr> Mime-Version: 1.0 Content-Type: multipart/alternative; boundary="00000000000066e66c057ab2ffc4" Return-path: Received: from eggs.gnu.org ([2001:4830:134:3::10]:53046) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1gNGXv-0000Ig-PY for emacs-orgmode@gnu.org; Thu, 15 Nov 2018 07:14:56 -0500 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1gNGXs-00037X-RU for emacs-orgmode@gnu.org; Thu, 15 Nov 2018 07:14:55 -0500 Received: from mail-it1-x134.google.com ([2607:f8b0:4864:20::134]:33292) by eggs.gnu.org with esmtps (TLS1.0:RSA_AES_128_CBC_SHA1:16) (Exim 4.71) (envelope-from ) id 1gNGXs-000373-Dq for emacs-orgmode@gnu.org; Thu, 15 Nov 2018 07:14:52 -0500 Received: by mail-it1-x134.google.com with SMTP id p11-v6so18801602itf.0 for ; Thu, 15 Nov 2018 04:14:51 -0800 (PST) In-Reply-To: <87r2fsbvz2.fsf@nicolasgoaziou.fr> List-Id: "General discussions about Org-mode." List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: emacs-orgmode-bounces+geo-emacs-orgmode=m.gmane.org@gnu.org Sender: "Emacs-orgmode" To: John Kitchin , Org Mode --00000000000066e66c057ab2ffc4 Content-Type: text/plain; charset="UTF-8" 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 > --00000000000066e66c057ab2ffc4 Content-Type: text/html; charset="UTF-8" Content-Transfer-Encoding: quoted-printable


On Sat, Nov 10, 2018 at 1:58 PM Nicolas Goaziou <mail@nicolasgoaziou.fr> wrote:
Hello,

John Kitchin <jkitchin@andrew.cmu.edu> writes:

> You can retrieve keywords in the org-file like this:
>
> (defun get-keyword (key)
>=C2=A0 =C2=A0(org-element-map (org-element-parse-buffer) 'keyword >=C2=A0 =C2=A0 =C2=A0(lambda (k)
>=C2=A0 =C2=A0 =C2=A0 =C2=A0(when (string=3D key (org-element-property := key k))
> (org-element-property :value k)))
>=C2=A0 =C2=A0 =C2=A0nil t))

As a minor addendum,

=C2=A0 =C2=A0 (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:

=C2=A0 =C2=A0 (org-with-point-at 1
=C2=A0 =C2=A0 =C2=A0 (let ((case-fold-search t)
=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 (regexp (format "^[ \t]*#\\+= %s:" key))
=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 (result nil))
=C2=A0 =C2=A0 =C2=A0 =C2=A0 (while (re-search-forward regexp nil t)
=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 (let ((element (org-element-at-point)))<= br> =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 (when (eq 'keyword (org-eleme= nt-type element))
=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 (push (org-element-propert= y :value element) result))))
=C2=A0 =C2=A0 =C2=A0 =C2=A0 result))

This is very helpful, Nicolas and John.=C2=A0

What about *setting* a global keyword? I would like = to write something like this:

(defun org-lms-= set-global-prop-value (key value)
=C2=A0 "Add or update keyword KEY= in the org file header."
=C2=A0 (save-excursion
=C2=A0=C2=A0=C2= =A0 (goto-char (point-min))
=C2=A0=C2=A0=C2=A0 (insert (format "#+%= s: %" (upcase key) value))))

But
(a) insert the value at the *end* of the headers section, not the beginn= ing.
(b) preferably replace any existing values of the keywo= rd rather than write a whole new line.

(b) I guess= could be achieved with something like

(repla= ce-regexp (format "\(^[ \t]*#\\+%s: \)\(.*\)" key) (concat "= \1" value))
But what about (a)? I thought org already h= ad a couple of functions that performed this kind of serach but now I'm= not so sure.=C2=A0


=C2=A0
Regards,

--
Nicolas Goaziou
--00000000000066e66c057ab2ffc4--