emacs-orgmode@gnu.org archives
 help / color / mirror / code / Atom feed
* How to change a link?
@ 2014-10-15  0:19 Marcin Borkowski
  2014-10-15  7:16 ` Thorsten Jolitz
  2014-10-15 10:19 ` Nicolas Goaziou
  0 siblings, 2 replies; 24+ messages in thread
From: Marcin Borkowski @ 2014-10-15  0:19 UTC (permalink / raw)
  To: org-mode List

Hi list,

assume that I have a link object (e.g., I'm in the ellipsis part of
this:

(org-element-map (org-element-parse-buffer 'object) 'link
  (lambda (elt) ... ))

What I want to do is this:
1. check whether it is an internal link, and
2. if it is, change it so that it points to the analogous place in
another file.

Any hints about how to do these things?

(The rationale is that I'm writing a function which splits a single Org
file into a bunch of smaller ones, and I want to preserve links.)

Best,

-- 
Marcin Borkowski
http://octd.wmi.amu.edu.pl/en/Marcin_Borkowski
Adam Mickiewicz University

^ permalink raw reply	[flat|nested] 24+ messages in thread

* Re: How to change a link?
  2014-10-15  0:19 How to change a link? Marcin Borkowski
@ 2014-10-15  7:16 ` Thorsten Jolitz
  2014-10-15  9:50   ` Marcin Borkowski
  2014-10-15 10:19 ` Nicolas Goaziou
  1 sibling, 1 reply; 24+ messages in thread
From: Thorsten Jolitz @ 2014-10-15  7:16 UTC (permalink / raw)
  To: emacs-orgmode

Marcin Borkowski <mbork@wmi.amu.edu.pl> writes:

> Hi list,
>
> assume that I have a link object (e.g., I'm in the ellipsis part of
> this:
>
> (org-element-map (org-element-parse-buffer 'object) 'link
>   (lambda (elt) ... ))
>
> What I want to do is this:
> 1. check whether it is an internal link, and
> 2. if it is, change it so that it points to the analogous place in
> another file.
>
> Any hints about how to do these things?
>
> (The rationale is that I'm writing a function which splits a single Org
> file into a bunch of smaller ones, and I want to preserve links.)

[[http:www.orgmode.org][Org-mode]]

#+BEGIN_SRC emacs-lisp :results raw
(save-excursion
 (re-search-backward org-link-re-with-space)
 (goto-char (match-beginning 0))
 (org-dp-contents (org-element-at-point)))
#+END_SRC

#+results:
((link
  (:type "http" :path "www.orgmode.org" :raw-link "http:www.orgmode.org"
  :application nil :search-option nil :begin 609 :end 643
  :contents-begin 633 :contents-end 641 :post-blank 0 :parent ...)))

so these

,----
| :type "http" :path "www.orgmode.org" :raw-link "http:www.orgmode.org"
`----

are your candidates for getting and setting with
'org-element-property' and 'org-element-put-property'.

-- 
cheers,
Thorsten

^ permalink raw reply	[flat|nested] 24+ messages in thread

* Re: How to change a link?
  2014-10-15  7:16 ` Thorsten Jolitz
@ 2014-10-15  9:50   ` Marcin Borkowski
  2014-10-15 10:02     ` Thorsten Jolitz
  0 siblings, 1 reply; 24+ messages in thread
From: Marcin Borkowski @ 2014-10-15  9:50 UTC (permalink / raw)
  To: emacs-orgmode


On 2014-10-15, at 09:16, Thorsten Jolitz wrote:

> Marcin Borkowski <mbork@wmi.amu.edu.pl> writes:
>
>> Hi list,
>>
>> assume that I have a link object (e.g., I'm in the ellipsis part of
>> this:
>>
>> (org-element-map (org-element-parse-buffer 'object) 'link
>>   (lambda (elt) ... ))
>>
>> What I want to do is this:
>> 1. check whether it is an internal link, and
>> 2. if it is, change it so that it points to the analogous place in
>> another file.
>>
>> Any hints about how to do these things?
>>
>> (The rationale is that I'm writing a function which splits a single Org
>> file into a bunch of smaller ones, and I want to preserve links.)
>
> [[http:www.orgmode.org][Org-mode]]
>
> #+BEGIN_SRC emacs-lisp :results raw
> (save-excursion
>  (re-search-backward org-link-re-with-space)
>  (goto-char (match-beginning 0))
>  (org-dp-contents (org-element-at-point)))
> #+END_SRC
>
> #+results:
> ((link
>   (:type "http" :path "www.orgmode.org" :raw-link "http:www.orgmode.org"
>   :application nil :search-option nil :begin 609 :end 643
>   :contents-begin 633 :contents-end 641 :post-blank 0 :parent ...)))
>
> so these
>
> ,----
> | :type "http" :path "www.orgmode.org" :raw-link "http:www.orgmode.org"
> `----
>
> are your candidates for getting and setting with
> 'org-element-property' and 'org-element-put-property'.

Thanks, but...

1. I have no org-dp-contents function in my Org.  (Org-mode version
8.2.5f (8.2.5f-elpa @ /home/marcin/.emacs.d/elpa/org-20140116/)).

2. What about internal links like

[[My Target][Find my target]]

(taken from the manual)?

In fact, I don't care about /external/ links at all; I'm /only/
interested in links pointing to the file they are in.

Best,

-- 
Marcin Borkowski
http://octd.wmi.amu.edu.pl/en/Marcin_Borkowski
Adam Mickiewicz University

^ permalink raw reply	[flat|nested] 24+ messages in thread

* Re: How to change a link?
  2014-10-15  9:50   ` Marcin Borkowski
@ 2014-10-15 10:02     ` Thorsten Jolitz
  2014-10-15 16:17       ` Marcin Borkowski
  0 siblings, 1 reply; 24+ messages in thread
From: Thorsten Jolitz @ 2014-10-15 10:02 UTC (permalink / raw)
  To: emacs-orgmode

Marcin Borkowski <mbork@wmi.amu.edu.pl> writes:

> On 2014-10-15, at 09:16, Thorsten Jolitz wrote:
>
>> Marcin Borkowski <mbork@wmi.amu.edu.pl> writes:
>>
>>> Hi list,
>>>
>>> assume that I have a link object (e.g., I'm in the ellipsis part of
>>> this:
>>>
>>> (org-element-map (org-element-parse-buffer 'object) 'link
>>>   (lambda (elt) ... ))
>>>
>>> What I want to do is this:
>>> 1. check whether it is an internal link, and
>>> 2. if it is, change it so that it points to the analogous place in
>>> another file.
>>>
>>> Any hints about how to do these things?
>>>
>>> (The rationale is that I'm writing a function which splits a single Org
>>> file into a bunch of smaller ones, and I want to preserve links.)
>>
>> [[http:www.orgmode.org][Org-mode]]
>>
>> #+BEGIN_SRC emacs-lisp :results raw
>> (save-excursion
>>  (re-search-backward org-link-re-with-space)
>>  (goto-char (match-beginning 0))
>>  (org-dp-contents (org-element-at-point)))
>> #+END_SRC
>>
>> #+results:
>> ((link
>>   (:type "http" :path "www.orgmode.org" :raw-link "http:www.orgmode.org"
>>   :application nil :search-option nil :begin 609 :end 643
>>   :contents-begin 633 :contents-end 641 :post-blank 0 :parent ...)))
>>
>> so these
>>
>> ,----
>> | :type "http" :path "www.orgmode.org" :raw-link "http:www.orgmode.org"
>> `----
>>
>> are your candidates for getting and setting with
>> 'org-element-property' and 'org-element-put-property'.
>
> Thanks, but...
>
> 1. I have no org-dp-contents function in my Org.  (Org-mode version
> 8.2.5f (8.2.5f-elpa @ /home/marcin/.emacs.d/elpa/org-20140116/)).

org-dp.el (and org-dp-lib.el) are libraries of mine that aim to make
local programming with org-elements (org-element-at-point) as convenient
as global programming (org-element-parse-buffer), see
https://github.com/tj64/org-dp. I find them very useful, unfortunately
they have been widely ignored so far ;)

> 2. What about internal links like
>
> [[My Target][Find my target]]
>
> (taken from the manual)?
>
> In fact, I don't care about /external/ links at all; I'm /only/
> interested in links pointing to the file they are in.

This was just an example (using local parsing for convenience), giving
the hint that you could put some links of interest in an Org file, parse
it, and look at the (link (:type ...)) alists in the parse tree to see
the properties you need to get and set. The internal link representation
is the same for all types anyway.

-- 
cheers,
Thorsten

^ permalink raw reply	[flat|nested] 24+ messages in thread

* Re: How to change a link?
  2014-10-15  0:19 How to change a link? Marcin Borkowski
  2014-10-15  7:16 ` Thorsten Jolitz
@ 2014-10-15 10:19 ` Nicolas Goaziou
  2014-10-15 21:30   ` Marcin Borkowski
  2014-10-20  0:02   ` Marcin Borkowski
  1 sibling, 2 replies; 24+ messages in thread
From: Nicolas Goaziou @ 2014-10-15 10:19 UTC (permalink / raw)
  To: Marcin Borkowski; +Cc: org-mode List

Hello,

Marcin Borkowski <mbork@wmi.amu.edu.pl> writes:

> assume that I have a link object (e.g., I'm in the ellipsis part of
> this:
>
> (org-element-map (org-element-parse-buffer 'object) 'link
>   (lambda (elt) ... ))
>
> What I want to do is this:
> 1. check whether it is an internal link, and

(member (org-element-property :type elt) '("custom-id" "fuzzy"))

> 2. if it is, change it so that it points to the analogous place in
> another file.

  (org-element-put-property elt :raw-link
                            (concat "file:path/to/other-file.org::"
                                    (org-element-property :path elt)))

Untested.


Regards,

-- 
Nicolas Goaziou

^ permalink raw reply	[flat|nested] 24+ messages in thread

* Re: How to change a link?
  2014-10-15 10:02     ` Thorsten Jolitz
@ 2014-10-15 16:17       ` Marcin Borkowski
  2014-10-15 22:28         ` Thorsten Jolitz
  0 siblings, 1 reply; 24+ messages in thread
From: Marcin Borkowski @ 2014-10-15 16:17 UTC (permalink / raw)
  To: emacs-orgmode


On 2014-10-15, at 12:02, Thorsten Jolitz wrote:

> Marcin Borkowski <mbork@wmi.amu.edu.pl> writes:
>
>> Thanks, but...
>>
>> 1. I have no org-dp-contents function in my Org.  (Org-mode version
>> 8.2.5f (8.2.5f-elpa @ /home/marcin/.emacs.d/elpa/org-20140116/)).
>
> org-dp.el (and org-dp-lib.el) are libraries of mine that aim to make
> local programming with org-elements (org-element-at-point) as convenient
> as global programming (org-element-parse-buffer), see
> https://github.com/tj64/org-dp. I find them very useful, unfortunately
> they have been widely ignored so far ;)

I see.  Unfortunately, I'll ignore them, too, for the simple reason that
I do not want to introduce additional dependencies (and I have to walk
through the whole document anyway).

>> 2. What about internal links like
>>
>> [[My Target][Find my target]]
>>
>> (taken from the manual)?
>>
>> In fact, I don't care about /external/ links at all; I'm /only/
>> interested in links pointing to the file they are in.
>
> This was just an example (using local parsing for convenience), giving
> the hint that you could put some links of interest in an Org file, parse
> it, and look at the (link (:type ...)) alists in the parse tree to see
> the properties you need to get and set. The internal link representation
> is the same for all types anyway.

I see.  What is the most interesting for me is the idea of
getting/setting properties, that's what I was looking for.

Thanks,

-- 
Marcin Borkowski
http://octd.wmi.amu.edu.pl/en/Marcin_Borkowski
Adam Mickiewicz University

^ permalink raw reply	[flat|nested] 24+ messages in thread

* Re: How to change a link?
  2014-10-15 10:19 ` Nicolas Goaziou
@ 2014-10-15 21:30   ` Marcin Borkowski
  2014-10-15 21:52     ` Nicolas Goaziou
  2014-10-20  0:02   ` Marcin Borkowski
  1 sibling, 1 reply; 24+ messages in thread
From: Marcin Borkowski @ 2014-10-15 21:30 UTC (permalink / raw)
  To: org-mode List


On 2014-10-15, at 12:19, Nicolas Goaziou wrote:

> Hello,
>
> Marcin Borkowski <mbork@wmi.amu.edu.pl> writes:
>
>> assume that I have a link object (e.g., I'm in the ellipsis part of
>> this:
>>
>> (org-element-map (org-element-parse-buffer 'object) 'link
>>   (lambda (elt) ... ))
>>
>> What I want to do is this:
>> 1. check whether it is an internal link, and
>
> (member (org-element-property :type elt) '("custom-id" "fuzzy"))
>
>> 2. if it is, change it so that it points to the analogous place in
>> another file.
>
>   (org-element-put-property elt :raw-link
>                             (concat "file:path/to/other-file.org::"
>                                     (org-element-property :path elt)))

Thanks a lot, that was helpful!  I'm starting to feel more and more
confident with org-element-whatever, that's good.

I have one more question.  What I'm about to do is (basically) put
"file:some-file-name::" in front of the link, without changing the
description.  I could use `org-element-put-property' and (AFAIU)
org-element-link-interpreter to put it into the buffer (and probably
delete the old one).  It would be much easier (and maybe faster) just to
go to the point in the buffer where the link starts, go `(forward-char
2)' (past the brackets) and `(insert (concat "file" name "::"))'.

But, is it safe?  Wouldn't it break something?  And is it considered a
good practice?

Regards,

-- 
Marcin Borkowski
http://octd.wmi.amu.edu.pl/en/Marcin_Borkowski
Adam Mickiewicz University

^ permalink raw reply	[flat|nested] 24+ messages in thread

* Re: How to change a link?
  2014-10-15 21:30   ` Marcin Borkowski
@ 2014-10-15 21:52     ` Nicolas Goaziou
  2014-10-16 17:55       ` Marcin Borkowski
  0 siblings, 1 reply; 24+ messages in thread
From: Nicolas Goaziou @ 2014-10-15 21:52 UTC (permalink / raw)
  To: Marcin Borkowski; +Cc: org-mode List

Marcin Borkowski <mbork@wmi.amu.edu.pl> writes:

> I have one more question.  What I'm about to do is (basically) put
> "file:some-file-name::" in front of the link, without changing the
> description.  I could use `org-element-put-property' and (AFAIU)
> org-element-link-interpreter to put it into the buffer (and probably
> delete the old one).  It would be much easier (and maybe faster) just to
> go to the point in the buffer where the link starts, go `(forward-char
> 2)' (past the brackets) and `(insert (concat "file" name "::"))'.
>
> But, is it safe?  Wouldn't it break something?  And is it considered a
> good practice?

There are caveats.

For example, as soon as you alter the buffer, your AST becomes invalid
(buffer positions are all wrong after the insertion). If you want to
process all the links from the same AST, you can, for example, maintain
a counter for characters inserted so far that will fix buffer positions,
or first get all internal links with `org-element-map', then process
them in reverse order so buffer modifications do not invalidate them.

You may also directly work on the buffer, with something like

  (org-with-wide-buffer
   (goto-char (point-min))
   (while (re-search-forward org-bracket-link-regexp nil t)
     (forward-char -1)
     (let ((context (org-element-context)))
       (when (and (eq (org-element-type context) 'link)
                  (member (org-element-property :type context)
                          '("custom-id" "fuzzy")))
         (goto-char (+ (org-element-property :begin context) 2))
         (insert "file:path/to-file::")))))


Regards,

-- 
Nicolas Goaziou

^ permalink raw reply	[flat|nested] 24+ messages in thread

* Re: How to change a link?
  2014-10-15 16:17       ` Marcin Borkowski
@ 2014-10-15 22:28         ` Thorsten Jolitz
  2014-10-15 22:36           ` Marcin Borkowski
  0 siblings, 1 reply; 24+ messages in thread
From: Thorsten Jolitz @ 2014-10-15 22:28 UTC (permalink / raw)
  To: emacs-orgmode

Marcin Borkowski <mbork@wmi.amu.edu.pl> writes:

> I see.  What is the most interesting for me is the idea of
> getting/setting properties, that's what I was looking for.

Thats exactly what org-dp (https://github.com/tj64/org-dp) is about: 
getting and setting element properties instead of working on the textual
representation in the buffer. 

Here the commentary section of org-dp.el:

,----
| ** Commentary
| 
| Functions for declarative local programming with Org elements. They
| allow to declare what should be done and leave the low-level work,
| the "how-to", to the Org parser/interpreter framework.
| 
| With other words, org-dp acts on the internal representation of Org
| elements rather than on their textual representation, and leaves
| the transformation between both representations to the
| parser/interpreter framework. To create or modify an element, you
| call the parser to open it up, rewire its internals, and then call
| the interpreter to build the element again based on its modified
| internals.
| 
| Since all Org elements are uniformely represented as nested lists
| internally, with their properties stored as key-val pairs in
| plists, they can be treated in a much more uniform way when dealing
| with the internal representation instead of the highly variable
| textual representations. A big advantage of plists is that only
| those properties that are actually accessed matter, so when
| transforming one Org element into another on the internal level one
| does not have to worry about not matching properties as long as
| these are not used by the interpreter when building the textual
| representation of the transformed element.
| 
| Library org-dp is meant for programming at the local level,
| i.e. without any (contextual) information except those about the
| parsed element at point. It is designed to make using the Org-mode
| parser/interpreter framework at local level as convenient as using
| it at the global level (with a complete parse-tree produced by
| `org-element-parse-buffer` available). It takes care of the
| org-element caching mechanism in that it only acts on copies of the
| locally parsed elements at point, never on the original parsed (and
| cached) object itself.
`----

With just a few functions:

,----
| (defun* org-dp-create (elem-type &optional contents insert-p
|                            affiliated &rest args)
| 
| (defun* org-dp-rewire (elem-type &optional contents replace
|                            affiliated element &rest args)
| 
| (defun org-dp-map (fun-with-args rgxp &optional match-pos
|                    backward-search-p beg end silent-p)
| 
| (defun org-dp-contents (&optional element interpret-p no-properties-p)
| 
| (defun* org-dp-prompt (&optional elem elem-lst &key noprompt- [...]
`----

you can do almost all you local Org programming (i.e. doing stuff
"at-point" without the need for a complete parse-tree) by getting and
setting element properties, thats why I called the library

,----
| org-dp.el --- Declarative Local Programming with Org Elements
`----

it allows to leave most of the low-level parsing and interpreting stuff
to the parser framework, you only need to 'declare' the element-type and
the property values to create or modify elements.

-- 
cheers,
Thorsten

^ permalink raw reply	[flat|nested] 24+ messages in thread

* Re: How to change a link?
  2014-10-15 22:28         ` Thorsten Jolitz
@ 2014-10-15 22:36           ` Marcin Borkowski
  2014-10-15 22:51             ` Thorsten Jolitz
  0 siblings, 1 reply; 24+ messages in thread
From: Marcin Borkowski @ 2014-10-15 22:36 UTC (permalink / raw)
  To: emacs-orgmode


On 2014-10-16, at 00:28, Thorsten Jolitz wrote:

> Marcin Borkowski <mbork@wmi.amu.edu.pl> writes:
>
>> I see.  What is the most interesting for me is the idea of
>> getting/setting properties, that's what I was looking for.
>
> Thats exactly what org-dp (https://github.com/tj64/org-dp) is about: 
> getting and setting element properties instead of working on the textual
> representation in the buffer. 

OK, I'm (almost) convinced now.  What about availability on MELPA or
somewhere?  I'm going to release my code, and ease of installation is
one of possible concerns.

(OTOH, if someone is brave enough to use Emacs, installing a package
from git should not be too difficult...)

Thanks!

Best,

-- 
Marcin Borkowski
http://octd.wmi.amu.edu.pl/en/Marcin_Borkowski
Adam Mickiewicz University

^ permalink raw reply	[flat|nested] 24+ messages in thread

* Re: How to change a link?
  2014-10-15 22:36           ` Marcin Borkowski
@ 2014-10-15 22:51             ` Thorsten Jolitz
  2014-10-15 23:06               ` Thorsten Jolitz
  0 siblings, 1 reply; 24+ messages in thread
From: Thorsten Jolitz @ 2014-10-15 22:51 UTC (permalink / raw)
  To: emacs-orgmode

Marcin Borkowski <mbork@wmi.amu.edu.pl> writes:

> On 2014-10-16, at 00:28, Thorsten Jolitz wrote:
>
>> Marcin Borkowski <mbork@wmi.amu.edu.pl> writes:
>>
>>> I see.  What is the most interesting for me is the idea of
>>> getting/setting properties, that's what I was looking for.
>>
>> Thats exactly what org-dp (https://github.com/tj64/org-dp) is about: 
>> getting and setting element properties instead of working on the textual
>> representation in the buffer. 
>
> OK, I'm (almost) convinced now.

you can have a look at org-dp-lib.el in the same repo, it has a few
(quite useful) convenience functions written on top of org-dp.el, so
they serve as usage examples too:

,----
| (defun org-dp-wrap-in-block (&optional lines user-info &rest prompt-spec)
| (defun org-dp-toggle-headers (&optional action)
| (defun org-dp-filter-node-props (filter &optional negate-p verbose-p)
| (defun org-dp-create-table (row-lst &optional tblfm table-el-p insert-p)
`----

> What about availability on MELPA or
> somewhere?  I'm going to release my code, and ease of installation is
> one of possible concerns.

I would actually appreciate if someone else uses it for a while before I
making it a MELPA package, but I put this on my todo list.

> (OTOH, if someone is brave enough to use Emacs, installing a package
> from git should not be too difficult...)

it shouldn't really ...

-- 
cheers,
Thorsten

^ permalink raw reply	[flat|nested] 24+ messages in thread

* Re: How to change a link?
  2014-10-15 22:51             ` Thorsten Jolitz
@ 2014-10-15 23:06               ` Thorsten Jolitz
  0 siblings, 0 replies; 24+ messages in thread
From: Thorsten Jolitz @ 2014-10-15 23:06 UTC (permalink / raw)
  To: emacs-orgmode

Thorsten Jolitz <tjolitz@gmail.com> writes:

> Marcin Borkowski <mbork@wmi.amu.edu.pl> writes:
>
>> On 2014-10-16, at 00:28, Thorsten Jolitz wrote:
>>
>>> Marcin Borkowski <mbork@wmi.amu.edu.pl> writes:
>>>
>>>> I see.  What is the most interesting for me is the idea of
>>>> getting/setting properties, that's what I was looking for.
>>>
>>> Thats exactly what org-dp (https://github.com/tj64/org-dp) is about: 
>>> getting and setting element properties instead of working on the textual
>>> representation in the buffer. 
>>
>> OK, I'm (almost) convinced now.

PS
org-dp is for local programming - if you parse the buffer anyway in your
programm then working with the parse-tree is the 'default', of course. 

There is a mapping function, 'org-dp-map', but its very lightweight - it
gathers no context information at all, just moves point to all regexp
matches in buffer and applies a (local org-dp) function at that points.

-- 
cheers,
Thorsten

^ permalink raw reply	[flat|nested] 24+ messages in thread

* Re: How to change a link?
  2014-10-15 21:52     ` Nicolas Goaziou
@ 2014-10-16 17:55       ` Marcin Borkowski
  2014-10-16 20:10         ` Nicolas Goaziou
  2014-10-16 22:19         ` Thorsten Jolitz
  0 siblings, 2 replies; 24+ messages in thread
From: Marcin Borkowski @ 2014-10-16 17:55 UTC (permalink / raw)
  To: org-mode List


On 2014-10-15, at 23:52, Nicolas Goaziou wrote:

> Marcin Borkowski <mbork@wmi.amu.edu.pl> writes:
>
>> I have one more question.  What I'm about to do is (basically) put
>> "file:some-file-name::" in front of the link, without changing the
>> description.  I could use `org-element-put-property' and (AFAIU)
>> org-element-link-interpreter to put it into the buffer (and probably
>> delete the old one).  It would be much easier (and maybe faster) just to
>> go to the point in the buffer where the link starts, go `(forward-char
>> 2)' (past the brackets) and `(insert (concat "file" name "::"))'.
>>
>> But, is it safe?  Wouldn't it break something?  And is it considered a
>> good practice?
>
> There are caveats.
>
> For example, as soon as you alter the buffer, your AST becomes invalid
> (buffer positions are all wrong after the insertion). If you want to
> process all the links from the same AST, you can, for example, maintain
> a counter for characters inserted so far that will fix buffer positions,
> or first get all internal links with `org-element-map', then process
> them in reverse order so buffer modifications do not invalidate them.

OK, so what is the canonical way of doing this?  I don't want to use
org-dp, since it is another dependency.

> Regards,

Best,

-- 
Marcin Borkowski
http://octd.wmi.amu.edu.pl/en/Marcin_Borkowski
Adam Mickiewicz University

^ permalink raw reply	[flat|nested] 24+ messages in thread

* Re: How to change a link?
  2014-10-16 17:55       ` Marcin Borkowski
@ 2014-10-16 20:10         ` Nicolas Goaziou
  2014-10-16 21:46           ` Marcin Borkowski
  2014-10-16 22:19         ` Thorsten Jolitz
  1 sibling, 1 reply; 24+ messages in thread
From: Nicolas Goaziou @ 2014-10-16 20:10 UTC (permalink / raw)
  To: Marcin Borkowski; +Cc: org-mode List

Marcin Borkowski <mbork@wmi.amu.edu.pl> writes:

> OK, so what is the canonical way of doing this?  I don't want to use
> org-dp, since it is another dependency.

There is no canonical way. I would personally collect a reverse list of
internal links and proceed from there.

Regards,

^ permalink raw reply	[flat|nested] 24+ messages in thread

* Re: How to change a link?
  2014-10-16 20:10         ` Nicolas Goaziou
@ 2014-10-16 21:46           ` Marcin Borkowski
  0 siblings, 0 replies; 24+ messages in thread
From: Marcin Borkowski @ 2014-10-16 21:46 UTC (permalink / raw)
  To: org-mode List


On 2014-10-16, at 22:10, Nicolas Goaziou wrote:

> Marcin Borkowski <mbork@wmi.amu.edu.pl> writes:
>
>> OK, so what is the canonical way of doing this?  I don't want to use
>> org-dp, since it is another dependency.
>
> There is no canonical way. I would personally collect a reverse list of
> internal links and proceed from there.

Thanks!  I didn't think about reversing the list.  Obvious in hindsight.

> Regards,

Best,

-- 
Marcin Borkowski
http://octd.wmi.amu.edu.pl/en/Marcin_Borkowski
Adam Mickiewicz University

^ permalink raw reply	[flat|nested] 24+ messages in thread

* Re: How to change a link?
  2014-10-16 17:55       ` Marcin Borkowski
  2014-10-16 20:10         ` Nicolas Goaziou
@ 2014-10-16 22:19         ` Thorsten Jolitz
  2014-10-17  8:52           ` Marcin Borkowski
  2014-10-18  1:44           ` Marcin Borkowski
  1 sibling, 2 replies; 24+ messages in thread
From: Thorsten Jolitz @ 2014-10-16 22:19 UTC (permalink / raw)
  To: emacs-orgmode

Marcin Borkowski <mbork@wmi.amu.edu.pl> writes:

> On 2014-10-15, at 23:52, Nicolas Goaziou wrote:
>
>> Marcin Borkowski <mbork@wmi.amu.edu.pl> writes:
>>
>>> I have one more question.  What I'm about to do is (basically) put
>>> "file:some-file-name::" in front of the link, without changing the
>>> description.  I could use `org-element-put-property' and (AFAIU)
>>> org-element-link-interpreter to put it into the buffer (and probably
>>> delete the old one).  It would be much easier (and maybe faster) just to
>>> go to the point in the buffer where the link starts, go `(forward-char
>>> 2)' (past the brackets) and `(insert (concat "file" name "::"))'.
>>>
>>> But, is it safe?  Wouldn't it break something?  And is it considered a
>>> good practice?
>>
>> There are caveats.
>>
>> For example, as soon as you alter the buffer, your AST becomes invalid
>> (buffer positions are all wrong after the insertion). If you want to
>> process all the links from the same AST, you can, for example, maintain
>> a counter for characters inserted so far that will fix buffer positions,
>> or first get all internal links with `org-element-map', then process
>> them in reverse order so buffer modifications do not invalidate them.
>
> OK, so what is the canonical way of doing this?  I don't want to use
> org-dp, since it is another dependency.

It is a problem to add dependencies to libraries the user must install
himself, and at the same time its a pity that there is so much
duplication instead of reuse ...

However, here is a org-dp solution, use 't' instead of 'prepend to
replace the links, and whatever you want instead of "file+emacs" as
replacement. Of course one could easily re-search and replace "[[file:"
in this simple case, but this uses the parser and allows doing more
complex stuff in a clean way too:

,----
| * ORG SCRATCH
| 
| ** Level 2
| 
| [[file+emacs:~/junk/org/minimal.org][min.org]]
| 
| [[file:~/junk/org/minimal.org][min.org]]
| 
| *** Level 3
| 
| [[file+emacs:~/junk/org/trash-me.org][trash.org]]
| 
| [[file:~/junk/org/trash-me.org][trash.org]]
| 
| 
| #+BEGIN_SRC emacs-lisp :results none
|   (require 'org-dp)
|   (org-dp-map
|    '(org-dp-rewire
|      'paragraph 
|      (lambda (cont elem)
|        (let* ((link (car cont))
|               (raw-val (org-element-property :raw-link link))
|               (new-val (mapconcat 'identity
|                                   (cons "file+emacs"
|                                         (cdr
|                                          (split-string
|                                           raw-val ":" t)))
|                                   ":")))
|          (org-element-put-property link :raw-link new-val)))
|      'prepend)
|    org-link-re-with-space t)
| #+END_SRC
`----

-- 
cheers,
Thorsten

^ permalink raw reply	[flat|nested] 24+ messages in thread

* Re: How to change a link?
  2014-10-16 22:19         ` Thorsten Jolitz
@ 2014-10-17  8:52           ` Marcin Borkowski
  2014-10-17 15:25             ` Nick Dokos
  2014-10-18  1:44           ` Marcin Borkowski
  1 sibling, 1 reply; 24+ messages in thread
From: Marcin Borkowski @ 2014-10-17  8:52 UTC (permalink / raw)
  To: emacs-orgmode


On 2014-10-17, at 00:19, Thorsten Jolitz wrote:

>> OK, so what is the canonical way of doing this?  I don't want to use
>> org-dp, since it is another dependency.
>
> It is a problem to add dependencies to libraries the user must install
> himself, and at the same time its a pity that there is so much
> duplication instead of reuse ...

Very true.  I'm torn inside;).

> However, here is a org-dp solution, use 't' instead of 'prepend to
> replace the links, and whatever you want instead of "file+emacs" as
> replacement. Of course one could easily re-search and replace "[[file:"
> in this simple case, but this uses the parser and allows doing more
> complex stuff in a clean way too:

I'll study it, thanks!

Best,

-- 
Marcin Borkowski
http://octd.wmi.amu.edu.pl/en/Marcin_Borkowski
Adam Mickiewicz University

^ permalink raw reply	[flat|nested] 24+ messages in thread

* Re: How to change a link?
  2014-10-17  8:52           ` Marcin Borkowski
@ 2014-10-17 15:25             ` Nick Dokos
  2014-10-18 13:54               ` Thorsten Jolitz
  0 siblings, 1 reply; 24+ messages in thread
From: Nick Dokos @ 2014-10-17 15:25 UTC (permalink / raw)
  To: emacs-orgmode

Marcin Borkowski <mbork@wmi.amu.edu.pl> writes:

> On 2014-10-17, at 00:19, Thorsten Jolitz wrote:
>
>>> OK, so what is the canonical way of doing this?  I don't want to use
>>> org-dp, since it is another dependency.
>>
>> It is a problem to add dependencies to libraries the user must install
>> himself, and at the same time its a pity that there is so much
>> duplication instead of reuse ...
>
> Very true.  I'm torn inside;).
>
>> However, here is a org-dp solution, use 't' instead of 'prepend to
>> replace the links, and whatever you want instead of "file+emacs" as
>> replacement. Of course one could easily re-search and replace "[[file:"
>> in this simple case, but this uses the parser and allows doing more
>> complex stuff in a clean way too:
>
> I'll study it, thanks!
>

Why not move org-dp into contrib? It's still a dependency but it's
easier to satisfy if it's in contrib. Or, if it's deemed useful enough,
even moved into core (perhaps after some cleanup)?

Nick

^ permalink raw reply	[flat|nested] 24+ messages in thread

* Re: How to change a link?
  2014-10-16 22:19         ` Thorsten Jolitz
  2014-10-17  8:52           ` Marcin Borkowski
@ 2014-10-18  1:44           ` Marcin Borkowski
  2014-10-18 13:48             ` Thorsten Jolitz
  1 sibling, 1 reply; 24+ messages in thread
From: Marcin Borkowski @ 2014-10-18  1:44 UTC (permalink / raw)
  To: emacs-orgmode


On 2014-10-17, at 00:19, Thorsten Jolitz wrote:

> However, here is a org-dp solution, use 't' instead of 'prepend to
> replace the links, and whatever you want instead of "file+emacs" as
> replacement. Of course one could easily re-search and replace "[[file:"
> in this simple case, but this uses the parser and allows doing more
> complex stuff in a clean way too:
>
> ,----
> | * ORG SCRATCH
> | 
> | ** Level 2
> | 
> | [[file+emacs:~/junk/org/minimal.org][min.org]]
> | 
> | [[file:~/junk/org/minimal.org][min.org]]
> | 
> | *** Level 3
> | 
> | [[file+emacs:~/junk/org/trash-me.org][trash.org]]
> | 
> | [[file:~/junk/org/trash-me.org][trash.org]]
> | 
> | 
> | #+BEGIN_SRC emacs-lisp :results none
> |   (require 'org-dp)
> |   (org-dp-map
> |    '(org-dp-rewire
> |      'paragraph 
> |      (lambda (cont elem)
> |        (let* ((link (car cont))
> |               (raw-val (org-element-property :raw-link link))
> |               (new-val (mapconcat 'identity
> |                                   (cons "file+emacs"
> |                                         (cdr
> |                                          (split-string
> |                                           raw-val ":" t)))
> |                                   ":")))
> |          (org-element-put-property link :raw-link new-val)))
> |      'prepend)
> |    org-link-re-with-space t)
> | #+END_SRC
> `----

Hi Thorsten,

one thing I don't quite understand yet: why is the first argument to
org-dp-rewire `'paragraph'?  My intuition says it should rather be
'link, though this doesn't seem to work.  How come that you say
'paragraph, but the lambda in the second parameter gets the link data in
`cont'?  (This might be a stupid question, but I really want to grok
this.)

Second question: do I get it correctly that `org-element-put-property'
returns the "new" version of the element (link, in this case), with
everything as it was but the :raw-link property changed?

TIA,

-- 
Marcin Borkowski
http://octd.wmi.amu.edu.pl/en/Marcin_Borkowski
Adam Mickiewicz University

^ permalink raw reply	[flat|nested] 24+ messages in thread

* Re: How to change a link?
  2014-10-18  1:44           ` Marcin Borkowski
@ 2014-10-18 13:48             ` Thorsten Jolitz
  0 siblings, 0 replies; 24+ messages in thread
From: Thorsten Jolitz @ 2014-10-18 13:48 UTC (permalink / raw)
  To: emacs-orgmode

Marcin Borkowski <mbork@wmi.amu.edu.pl> writes:

> On 2014-10-17, at 00:19, Thorsten Jolitz wrote:
>
>> However, here is a org-dp solution, use 't' instead of 'prepend to
>> replace the links, and whatever you want instead of "file+emacs" as
>> replacement. Of course one could easily re-search and replace "[[file:"
>> in this simple case, but this uses the parser and allows doing more
>> complex stuff in a clean way too:
>>
>> ,----
>> | #+BEGIN_SRC emacs-lisp :results none
>> |   (require 'org-dp)
>> |   (org-dp-map
>> |    '(org-dp-rewire
>> |      'paragraph 
>> |      (lambda (cont elem)
>> |        (let* ((link (car cont))
>> |               (raw-val (org-element-property :raw-link link))
>> |               (new-val (mapconcat 'identity
>> |                                   (cons "file+emacs"
>> |                                         (cdr
>> |                                          (split-string
>> |                                           raw-val ":" t)))
>> |                                   ":")))
>> |          (org-element-put-property link :raw-link new-val)))
>> |      'prepend)
>> |    org-link-re-with-space t)
>> | #+END_SRC
>> `----
>
Hi Marcin,

> one thing I don't quite understand yet: why is the first argument to
> org-dp-rewire `'paragraph'?  My intuition says it should rather be
> 'link, though this doesn't seem to work.  How come that you say
> 'paragraph, but the lambda in the second parameter gets the link data in
> `cont'?  (This might be a stupid question, but I really want to grok
> this.)

I was surprised too! But links are objects, and with point at a link
org-element-at-point return a paragraph with the link as content. So
to get the contents of a link, you take the contents of the contents
of a paragraph, but that a special case, because mostly you will work
directly with elements.

The 'paragraph' is the target element type. In this case I could have
written 
 
,----
| '(org-dp-rewire nil ...)
`----

instead, since then parsed and rewired element types are the same. See
examples below of how to convert a link into a src-block or a keyword
(e.g.).

For more in depth info, have a look at:

,----[ C-h f org-dp-rewire RET ]
| org-dp-rewire is a Lisp function in `org-dp.el'.
| 
| (org-dp-rewire ELEM-TYPE &optional CONTENTS REPLACE AFFILIATED ELEMENT
| &rest ARGS)
| 
| Rewire element-at-point or ELEMENT (if given). [...]
`----

Example:

When you start with the file link below and eval the
following src-blocks in order, you get:

#+BEGIN_SRC picolisp
  (println "Link label: min.org")
  (println "Link type: file")
#+END_SRC

#+LABEL: min.org

[[file:junk/org/minimal.org][min.org]]

#+BEGIN_SRC emacs-lisp :results none
  (require 'org-dp)
  (org-dp-map
   '(org-dp-rewire 'src-block  nil 'prepend nil nil
                   :language "picolisp"
                   :value (lambda (_old_ elem)
                            (format
                             (concat
                              "(println \"Link label: %s\")\n"
                              "(println \"Link type: %s\")")
                             (org-dp-contents
                              (car (org-dp-contents elem nil t))
                              t t)
                             (org-element-property
                              :type (car
                                     (org-dp-contents elem nil t))))))
   org-link-re-with-space t)
#+END_SRC

#+BEGIN_SRC emacs-lisp :results none
  (require 'org-dp)
  (org-dp-map
   '(org-dp-rewire 'keyword nil 'prepend nil nil
                   :key "LABEL"
                   :value (lambda (_old_ elem)
                            (org-dp-contents
                             (car (org-dp-contents elem nil t))
                             t t)))
   org-link-re-with-space t)
#+END_SRC

This should give you a better idea of what the org-dp-rewire function
arguments stand for. In generel, org-dp functions have extensive
docstrings, so C-h f 'org-dp-xyz' is you friend.

For org-dp, the (few) properties that are interpreted are most
relevant, not so much the (many) properties that are parsed. See
variable `org-dp-elem-props' for an overview. In general, when
programming with org-dp, I often look into org-element.el, especially
at the interpreters. 

> Second question: do I get it correctly that `org-element-put-property'
> returns the "new" version of the element (link, in this case), with
> everything as it was but the :raw-link property changed?

,----[ C-h f org-element-put-property RET ]
| org-element-put-property is a compiled Lisp function in
| `org-element.el'. [...]
| Return modified element.
`----

Yes!

-- 
cheers,
Thorsten

^ permalink raw reply	[flat|nested] 24+ messages in thread

* Re: How to change a link?
  2014-10-17 15:25             ` Nick Dokos
@ 2014-10-18 13:54               ` Thorsten Jolitz
  0 siblings, 0 replies; 24+ messages in thread
From: Thorsten Jolitz @ 2014-10-18 13:54 UTC (permalink / raw)
  To: emacs-orgmode

Nick Dokos <ndokos@gmail.com> writes:

> Marcin Borkowski <mbork@wmi.amu.edu.pl> writes:
>
>> On 2014-10-17, at 00:19, Thorsten Jolitz wrote:
>>
>>>> OK, so what is the canonical way of doing this?  I don't want to use
>>>> org-dp, since it is another dependency.
>>>
>>> It is a problem to add dependencies to libraries the user must install
>>> himself, and at the same time its a pity that there is so much
>>> duplication instead of reuse ...
>>
>> Very true.  I'm torn inside;).
>>
>>> However, here is a org-dp solution, use 't' instead of 'prepend to
>>> replace the links, and whatever you want instead of "file+emacs" as
>>> replacement. Of course one could easily re-search and replace "[[file:"
>>> in this simple case, but this uses the parser and allows doing more
>>> complex stuff in a clean way too:
>>
>> I'll study it, thanks!
>>
>
> Why not move org-dp into contrib? It's still a dependency but it's
> easier to satisfy if it's in contrib. Or, if it's deemed useful enough,
> even moved into core (perhaps after some cleanup)?

I should really make it a MELPA package, and org-dp.el seems ready,
while org-dp-lib.el still contains some experimental stuff.  But its
still v0.9, I would really prefer if some people (besides me) actually
(clone the github repo and) use it before I make it v1.0 and a package,
to avoid unpleasant surprises.

-- 
cheers,
Thorsten

^ permalink raw reply	[flat|nested] 24+ messages in thread

* Re: How to change a link?
  2014-10-15 10:19 ` Nicolas Goaziou
  2014-10-15 21:30   ` Marcin Borkowski
@ 2014-10-20  0:02   ` Marcin Borkowski
  2014-10-20 13:02     ` Nicolas Goaziou
  1 sibling, 1 reply; 24+ messages in thread
From: Marcin Borkowski @ 2014-10-20  0:02 UTC (permalink / raw)
  To: org-mode List


On 2014-10-15, at 12:19, Nicolas Goaziou wrote:

> Hello,
>
> Marcin Borkowski <mbork@wmi.amu.edu.pl> writes:
>
>> assume that I have a link object (e.g., I'm in the ellipsis part of
>> this:
>>
>> (org-element-map (org-element-parse-buffer 'object) 'link
>>   (lambda (elt) ... ))
>>
>> What I want to do is this:
>> 1. check whether it is an internal link, and
>
> (member (org-element-property :type elt) '("custom-id" "fuzzy"))
>
>> 2. if it is, change it so that it points to the analogous place in
>> another file.
>
>   (org-element-put-property elt :raw-link
>                             (concat "file:path/to/other-file.org::"
>                                     (org-element-property :path elt)))

OK, it works, but: if the link description is empty, after this change
it's still empty, so that it becomes the result of concatenation.  I'd
like the link description to stay the same, no matter whether it's empty
or not.  How do I set the /contents/ of a link object (as opposed to a
property)?

> Regards,

Best,

-- 
Marcin Borkowski
http://octd.wmi.amu.edu.pl/en/Marcin_Borkowski
Adam Mickiewicz University

^ permalink raw reply	[flat|nested] 24+ messages in thread

* Re: How to change a link?
  2014-10-20  0:02   ` Marcin Borkowski
@ 2014-10-20 13:02     ` Nicolas Goaziou
  2014-10-20 13:11       ` Nicolas Goaziou
  0 siblings, 1 reply; 24+ messages in thread
From: Nicolas Goaziou @ 2014-10-20 13:02 UTC (permalink / raw)
  To: Marcin Borkowski; +Cc: org-mode List

Marcin Borkowski <mbork@wmi.amu.edu.pl> writes:

> OK, it works, but: if the link description is empty, after this change
> it's still empty, so that it becomes the result of concatenation.  I'd
> like the link description to stay the same, no matter whether it's empty
> or not.  How do I set the /contents/ of a link object (as opposed to a
> property)?

Two examples:

1. with a full AST

    (org-with-wide-buffer
     (dolist (link (nreverse
                    (org-element-map (org-element-parse-buffer) 'link
                      (lambda (l)
                        (member (org-element-property :type l)
                                '("custom-id" "fuzzy"))))))
       (goto-char (+ (org-element-property :begin link) 2))
       (insert "file:path/to/other-file.org::")))

2. working directly on the buffer

    (org-with-wide-buffer
     (goto-char (point-min))
     (while (re-search-forward org-bracket-link-regexp nil t)
       (let ((context (org-element-context)))
         (when (and (eq (org-element-type context) 'link)
                    (member (org-element-property :type context)
                            '("custom-id" "fuzzy")))
           (goto-char (+ (org-element-property :begin context) 2))
           (insert "file:path/to/other-file.org::")))))


Regards,

-- 
Nicolas Goaziou

^ permalink raw reply	[flat|nested] 24+ messages in thread

* Re: How to change a link?
  2014-10-20 13:02     ` Nicolas Goaziou
@ 2014-10-20 13:11       ` Nicolas Goaziou
  0 siblings, 0 replies; 24+ messages in thread
From: Nicolas Goaziou @ 2014-10-20 13:11 UTC (permalink / raw)
  To: Marcin Borkowski; +Cc: org-mode List

Nicolas Goaziou <mail@nicolasgoaziou.fr> writes:

>     (org-with-wide-buffer
>      (dolist (link (nreverse
>                     (org-element-map (org-element-parse-buffer) 'link
>                       (lambda (l)
>                         (member (org-element-property :type l)
>                                 '("custom-id" "fuzzy"))))))
>        (goto-char (+ (org-element-property :begin link) 2))
>        (insert "file:path/to/other-file.org::")))

Err, should be

  (org-with-wide-buffer
   (dolist (link (nreverse
                  (org-element-map (org-element-parse-buffer) 'link
                    (lambda (l)
                      (and (member (org-element-property :type l)
                                   '("custom-id" "fuzzy"))
                           l)))))
     (goto-char (org-element-property :begin link))
     (forward-char 2)
     (insert "file:path/to/other-file.org::")))

^ permalink raw reply	[flat|nested] 24+ messages in thread

end of thread, other threads:[~2014-10-20 13:10 UTC | newest]

Thread overview: 24+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2014-10-15  0:19 How to change a link? Marcin Borkowski
2014-10-15  7:16 ` Thorsten Jolitz
2014-10-15  9:50   ` Marcin Borkowski
2014-10-15 10:02     ` Thorsten Jolitz
2014-10-15 16:17       ` Marcin Borkowski
2014-10-15 22:28         ` Thorsten Jolitz
2014-10-15 22:36           ` Marcin Borkowski
2014-10-15 22:51             ` Thorsten Jolitz
2014-10-15 23:06               ` Thorsten Jolitz
2014-10-15 10:19 ` Nicolas Goaziou
2014-10-15 21:30   ` Marcin Borkowski
2014-10-15 21:52     ` Nicolas Goaziou
2014-10-16 17:55       ` Marcin Borkowski
2014-10-16 20:10         ` Nicolas Goaziou
2014-10-16 21:46           ` Marcin Borkowski
2014-10-16 22:19         ` Thorsten Jolitz
2014-10-17  8:52           ` Marcin Borkowski
2014-10-17 15:25             ` Nick Dokos
2014-10-18 13:54               ` Thorsten Jolitz
2014-10-18  1:44           ` Marcin Borkowski
2014-10-18 13:48             ` Thorsten Jolitz
2014-10-20  0:02   ` Marcin Borkowski
2014-10-20 13:02     ` Nicolas Goaziou
2014-10-20 13:11       ` Nicolas Goaziou

Code repositories for project(s) associated with this public inbox

	https://git.savannah.gnu.org/cgit/emacs/org-mode.git

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).