emacs-orgmode@gnu.org archives
 help / color / mirror / code / Atom feed
* Structured links to headings with endless depth
@ 2018-03-12 10:09 ST
  2018-03-12 10:29 ` Eric S Fraga
  0 siblings, 1 reply; 21+ messages in thread
From: ST @ 2018-03-12 10:09 UTC (permalink / raw)
  To: Emacs-orgmode

Hi,

after reading the manual I didn't find a way to construct structured
links referring to headings with endless depth, like:

having an file.org:

* 1
** 1
** 2
*** 1
<---link here

with the link:
[[path/to/file.org::*1:2:1]]

Is this possible or should I file it as feature request?

PS: It should work also with link abbreviations:
#+LINK: file path/to/file.org::*%s
[[file:1:2:1]]

Thank you!

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

* Re: Structured links to headings with endless depth
  2018-03-12 10:09 Structured links to headings with endless depth ST
@ 2018-03-12 10:29 ` Eric S Fraga
  2018-03-12 10:39   ` ST
  2018-03-12 12:43   ` ST
  0 siblings, 2 replies; 21+ messages in thread
From: Eric S Fraga @ 2018-03-12 10:29 UTC (permalink / raw)
  To: ST; +Cc: Emacs-orgmode

[-- Attachment #1: Type: text/plain, Size: 450 bytes --]

On Monday, 12 Mar 2018 at 12:09, ST wrote:
> Hi,
>
> after reading the manual I didn't find a way to construct structured
> links referring to headings with endless depth, like:

I'm not entirely sure what your use case is but could you use a target,
i.e. something like <<target>>, to indicate where you want to link to?
Cf. section 4.2 of org manual on internal links.

-- 
Eric S Fraga via Emacs 27.0.50, Org release_9.1.6-191-g90607d

[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 194 bytes --]

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

* Re: Structured links to headings with endless depth
  2018-03-12 10:29 ` Eric S Fraga
@ 2018-03-12 10:39   ` ST
  2018-03-12 13:08     ` Christian Moe
  2018-03-12 12:43   ` ST
  1 sibling, 1 reply; 21+ messages in thread
From: ST @ 2018-03-12 10:39 UTC (permalink / raw)
  To: Eric S Fraga; +Cc: Emacs-orgmode

Adding an extra <<target>> is not an option, as it will make the text
less readable, and there is no need in this, as the headings tree
structure is already there:

* 1
** 1
** 2
*** 1

Why should I turn it into the following

* 1
** 1
** 2
*** 1
<<1>>

and then link with [[file:1]]?!... This both:
a) adds unnecessary information into the text making it less readable
b) those who read the org file as simple text without the ability to
click the link will not know where it goes... while the link
[[file:1:2:1]] makes it quite clear even without clicking it.

Example use case: scriptures with well known structure, e.g. the Bible. 


On Mon, 2018-03-12 at 10:29 +0000, Eric S Fraga wrote:
> On Monday, 12 Mar 2018 at 12:09, ST wrote:
> > Hi,
> >
> > after reading the manual I didn't find a way to construct structured
> > links referring to headings with endless depth, like:
> 
> I'm not entirely sure what your use case is but could you use a target,
> i.e. something like <<target>>, to indicate where you want to link to?
> Cf. section 4.2 of org manual on internal links.
> 

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

* Re: Structured links to headings with endless depth
  2018-03-12 10:29 ` Eric S Fraga
  2018-03-12 10:39   ` ST
@ 2018-03-12 12:43   ` ST
  1 sibling, 0 replies; 21+ messages in thread
From: ST @ 2018-03-12 12:43 UTC (permalink / raw)
  To: Eric S Fraga; +Cc: Emacs-orgmode

PS: It doesn't have to be Bible. Links in form of citations, like
[[MyBook:Chapter 1:Section 5:Subsection 3]]

Is quite useful in general. Where

#+LINK: MyBook path/to/MyBook.org::*%s

It is both readable as raw text and clickable.

Maybe it will be a good idea to be able to also add a <<target>> at the
end of the tree, like: 

[[MyBook:Chapter 1:Section 5:Subsection 3:target]]

* Chapter 1
...
** Section 5
...
*** Subsection 3
...
<<target>>
...

-----------------------------

Adding an extra <<target>> is not an option, as it will make the text
less readable, and there is no need in this, as the headings tree
structure is already there:

* 1
** 1
** 2
*** 1

Why should I turn it into the following

* 1
** 1
** 2
*** 1
<<1>>

and then link with [[file:1]]?!... This both:
a) adds unnecessary information into the text making it less readable
b) those who read the org file as simple text without the ability to
click the link will not know where it goes... while the link
[[file:1:2:1]] makes it quite clear even without clicking it.

Example use case: scriptures with well known structure, e.g. the Bible. 


On Mon, 2018-03-12 at 10:29 +0000, Eric S Fraga wrote:
> On Monday, 12 Mar 2018 at 12:09, ST wrote:
> > Hi,
> >
> > after reading the manual I didn't find a way to construct structured
> > links referring to headings with endless depth, like:
> 
> I'm not entirely sure what your use case is but could you use a target,
> i.e. something like <<target>>, to indicate where you want to link to?
> Cf. section 4.2 of org manual on internal links.
> 

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

* Re: Structured links to headings with endless depth
  2018-03-12 10:39   ` ST
@ 2018-03-12 13:08     ` Christian Moe
  2018-03-12 13:46       ` ST
  0 siblings, 1 reply; 21+ messages in thread
From: Christian Moe @ 2018-03-12 13:08 UTC (permalink / raw)
  To: ST; +Cc: Eric S Fraga, Emacs-orgmode


ST writes:

> Adding an extra <<target>> is not an option, as it will make the text
> less readable, and there is no need in this, as the headings tree
> structure is already there:

Adding targets, CUSTOM_IDs or IDs are all options. You may not like them.

> * 1
> ** 1
> ** 2
> *** 1
>
> Why should I turn it into the following
>
> * 1
> ** 1
> ** 2
> *** 1
> <<1>>

With a fixed structure, you wouldn't; you'd use e.g. <<1:2:1>>.

> and then link with [[file:1]]?!... This both:
> a) adds unnecessary information into the text making it less readable

Let's not exaggerate the readability cost. And it does add information.

> b) those who read the org file as simple text without the ability to
> click the link will not know where it goes... while the link
> [[file:1:2:1]] makes it quite clear even without clicking it.

But so does the link [[1:2:1]] to the target <<1:2:1>>.

also, c): Adding a target like <<1:2:1>> to a section preserves
information about the location of that section in the source document if
you later cut that part out and insert it somewhere else. This
information is not contained in your headlines.

> Example use case: scriptures with well known structure, e.g. the Bible.

Fair enough.

But typical Org use will quickly break links like that, since Org shines
as an organizer for drafting and easily restructuring text. I don't
think Org needs a link type that would encourage people to make easily
breakable links.

I acknowledge that a separate target or CUSTOM_ID for every verse in the
Bible seems a bit heavy; if that's what you need, it might be better
solved by a custom link type.

Yours,
Christian

>
> On Mon, 2018-03-12 at 10:29 +0000, Eric S Fraga wrote:
>> On Monday, 12 Mar 2018 at 12:09, ST wrote:
>> > Hi,
>> >
>> > after reading the manual I didn't find a way to construct structured
>> > links referring to headings with endless depth, like:
>>
>> I'm not entirely sure what your use case is but could you use a target,
>> i.e. something like <<target>>, to indicate where you want to link to?
>> Cf. section 4.2 of org manual on internal links.
>>

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

* Re: Structured links to headings with endless depth
  2018-03-12 13:08     ` Christian Moe
@ 2018-03-12 13:46       ` ST
  2018-03-12 14:10         ` Nicolas Goaziou
  0 siblings, 1 reply; 21+ messages in thread
From: ST @ 2018-03-12 13:46 UTC (permalink / raw)
  To: Christian Moe; +Cc: Eric S Fraga, Emacs-orgmode

Thank you for your reply.

I'm not that experienced in writing in lisp. Is it difficult to create
such custom link type? What is the closest link type that you would
recommend to take as starting point (link on code, if possible)?

Thank you!


On Mon, 2018-03-12 at 14:08 +0100, Christian Moe wrote:
> ST writes:
> 
> > Adding an extra <<target>> is not an option, as it will make the text
> > less readable, and there is no need in this, as the headings tree
> > structure is already there:
> 
> Adding targets, CUSTOM_IDs or IDs are all options. You may not like them.
> 
> > * 1
> > ** 1
> > ** 2
> > *** 1
> >
> > Why should I turn it into the following
> >
> > * 1
> > ** 1
> > ** 2
> > *** 1
> > <<1>>
> 
> With a fixed structure, you wouldn't; you'd use e.g. <<1:2:1>>.
> 
> > and then link with [[file:1]]?!... This both:
> > a) adds unnecessary information into the text making it less readable
> 
> Let's not exaggerate the readability cost. And it does add information.
> 
> > b) those who read the org file as simple text without the ability to
> > click the link will not know where it goes... while the link
> > [[file:1:2:1]] makes it quite clear even without clicking it.
> 
> But so does the link [[1:2:1]] to the target <<1:2:1>>.
> 
> also, c): Adding a target like <<1:2:1>> to a section preserves
> information about the location of that section in the source document if
> you later cut that part out and insert it somewhere else. This
> information is not contained in your headlines.
> 
> > Example use case: scriptures with well known structure, e.g. the Bible.
> 
> Fair enough.
> 
> But typical Org use will quickly break links like that, since Org shines
> as an organizer for drafting and easily restructuring text. I don't
> think Org needs a link type that would encourage people to make easily
> breakable links.
> 
> I acknowledge that a separate target or CUSTOM_ID for every verse in the
> Bible seems a bit heavy; if that's what you need, it might be better
> solved by a custom link type.
> 
> Yours,
> Christian
> 
> >
> > On Mon, 2018-03-12 at 10:29 +0000, Eric S Fraga wrote:
> >> On Monday, 12 Mar 2018 at 12:09, ST wrote:
> >> > Hi,
> >> >
> >> > after reading the manual I didn't find a way to construct structured
> >> > links referring to headings with endless depth, like:
> >>
> >> I'm not entirely sure what your use case is but could you use a target,
> >> i.e. something like <<target>>, to indicate where you want to link to?
> >> Cf. section 4.2 of org manual on internal links.
> >>

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

* Re: Structured links to headings with endless depth
  2018-03-12 13:46       ` ST
@ 2018-03-12 14:10         ` Nicolas Goaziou
  2018-03-12 15:08           ` ST
  0 siblings, 1 reply; 21+ messages in thread
From: Nicolas Goaziou @ 2018-03-12 14:10 UTC (permalink / raw)
  To: ST; +Cc: Eric S Fraga, Emacs-orgmode, Christian Moe

Hello,

ST <smntov@gmail.com> writes:

> I'm not that experienced in writing in lisp. Is it difficult to create
> such custom link type? What is the closest link type that you would
> recommend to take as starting point (link on code, if possible)?

I'm not answering your question, but I suggest to use a CUSTOM_ID
instead. This is readily available.

Regards,

-- 
Nicolas Goaziou

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

* Re: Structured links to headings with endless depth
  2018-03-12 14:10         ` Nicolas Goaziou
@ 2018-03-12 15:08           ` ST
  2018-03-14  3:49             ` John Kitchin
  0 siblings, 1 reply; 21+ messages in thread
From: ST @ 2018-03-12 15:08 UTC (permalink / raw)
  To: Nicolas Goaziou; +Cc: Eric S Fraga, Emacs-orgmode, Christian Moe

Hello,

Ss Christian has pointed out - introduce a separate CUSTOM_ID for text
with fixed structure and rather short verses is too heavy.

I do need to write a custom link type, if this use case is not of common
interest for the orgmode community.

Thank you,


On Mon, 2018-03-12 at 15:10 +0100, Nicolas Goaziou wrote:
> Hello,
> 
> ST <smntov@gmail.com> writes:
> 
> > I'm not that experienced in writing in lisp. Is it difficult to create
> > such custom link type? What is the closest link type that you would
> > recommend to take as starting point (link on code, if possible)?
> 
> I'm not answering your question, but I suggest to use a CUSTOM_ID
> instead. This is readily available.
> 
> Regards,
> 

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

* Re: Structured links to headings with endless depth
  2018-03-12 15:08           ` ST
@ 2018-03-14  3:49             ` John Kitchin
  2018-03-14  6:58               ` Michael Brand
  2018-03-14 10:10               ` ST
  0 siblings, 2 replies; 21+ messages in thread
From: John Kitchin @ 2018-03-14  3:49 UTC (permalink / raw)
  To: ST; +Cc: Eric S Fraga, org-mode-email, Christian Moe, Nicolas Goaziou

[-- Attachment #1: Type: text/plain, Size: 2191 bytes --]

This is a tricky problem to generally solve. I think this does it
approximately well enough. It is lightly tested and works by exactly
matching headlines at subsequent levels. It will be problematic if you have
headlines with : in them, and it assumes there is a level 1 headline to
start in.

#+BEGIN_SRC emacs-lisp
(defun xpath-follow (path)
  (let* ((fields (split-string path "::"))
(fname (car fields))
(paths (split-string (cadr fields) ":"))
(level 0)
(current-point (point))
cp hls n found)
    (org-mark-ring-push)
    (find-file fname)
    (save-restriction
      (while paths
(setq cp (pop paths))
(incf level)
(setq hls (org-element-map (org-element-parse-buffer) 'headline
    (lambda (hl)
      (when (eq level (org-element-property :level hl))
hl))))
(setq n (-find-index (lambda (hl)
       (string= cp (org-no-properties
    (org-element-property :raw-value hl))))
     hls))
(if (not n)
    (progn
      (goto-char current-point)
      (user-error "%s not found" cp))
  (goto-char (org-element-property :begin (nth n hls)))
  (org-narrow-to-subtree))))))

(org-link-set-parameters
 "xpath"
 :follow 'xpath-follow)
#+END_SRC


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 Mon, Mar 12, 2018 at 8:08 AM, ST <smntov@gmail.com> wrote:

> Hello,
>
> Ss Christian has pointed out - introduce a separate CUSTOM_ID for text
> with fixed structure and rather short verses is too heavy.
>
> I do need to write a custom link type, if this use case is not of common
> interest for the orgmode community.
>
> Thank you,
>
>
> On Mon, 2018-03-12 at 15:10 +0100, Nicolas Goaziou wrote:
> > Hello,
> >
> > ST <smntov@gmail.com> writes:
> >
> > > I'm not that experienced in writing in lisp. Is it difficult to create
> > > such custom link type? What is the closest link type that you would
> > > recommend to take as starting point (link on code, if possible)?
> >
> > I'm not answering your question, but I suggest to use a CUSTOM_ID
> > instead. This is readily available.
> >
> > Regards,
> >
>
>
>

[-- Attachment #2: Type: text/html, Size: 4258 bytes --]

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

* Re: Structured links to headings with endless depth
  2018-03-14  3:49             ` John Kitchin
@ 2018-03-14  6:58               ` Michael Brand
  2019-05-06 16:34                 ` Michael Brand
  2018-03-14 10:10               ` ST
  1 sibling, 1 reply; 21+ messages in thread
From: Michael Brand @ 2018-03-14  6:58 UTC (permalink / raw)
  To: John Kitchin
  Cc: Eric S Fraga, Nicolas Goaziou, org-mode-email, Christian Moe, ST

Hi John

On Wed, Mar 14, 2018 at 4:49 AM, John Kitchin <jkitchin@andrew.cmu.edu> wrote:
> (defun xpath-follow (path)

Thank you for this solution. I plan to adapt it to match the link path
only to a portion of a headline branch by ignoring the higher and
lower levels not given in the link path for my use case:

,    (arbitrarily more levels upwards)
,      * [...]
,        * <composer>
,          * <work>
,            * TODO <movement>
,              * <interpreter> :5:
,                - The tag 5 is my rating of this audio recording.
,                - The audio recording is stored under the file path
,                  [...]/<composer>/<work>/<movement>/<interpreter>/<sth>.mp3
,
,    * TODO [...]
,      - The theme is very similar to this prelude
,        [[/:<composer_1>/<work_1>/<movement_1>]].
,    * [...]
,      - [...] like in this piano concert
,        [[/:<composer_2>/<work_2>]].

Michael

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

* Re: Structured links to headings with endless depth
  2018-03-14  3:49             ` John Kitchin
  2018-03-14  6:58               ` Michael Brand
@ 2018-03-14 10:10               ` ST
  2018-03-14 13:26                 ` Nicolas Goaziou
  2018-03-14 14:15                 ` John Kitchin
  1 sibling, 2 replies; 21+ messages in thread
From: ST @ 2018-03-14 10:10 UTC (permalink / raw)
  To: John Kitchin; +Cc: Eric S Fraga, org-mode-email, Christian Moe, Nicolas Goaziou

John, thank you for this solution!

I posted this question also here:

https://emacs.stackexchange.com/q/39384/18760

So if you wish, you may add your solution also there.

Somebody there, posted also a possible solution however the syntax is
pretty heavy:

[[org-heading:/path/to/file.org::*1:2:1]]

There is a workaround using links abbreviations, but still it is a
workaround...

I think this kind of linking is useful for many general cases. Christian
has expressed concerns that such links are easily breakable which is
true but only for documents that are in draft phase (or those which are
supposed to be restructured on regular basis - like ToDo lists). However
documents that has been published, like books or scientific papers, and
will no longer change - will benefit greatly from such linking option.
Imagine you have a scientific paper in your archive that you have
already published and removed write access from it in order not to
change it accidentally. You do want to reference certain
chapter:section:subsection from it in your new paper, which you are
currently writing, but creating a target <<chapter:section:subsection>>
in the old paper is no longer an option...

So may I ask as a feature request, to please add, following link type as
standard to the org-mode:

[[path/to/file.org::chapter:section:subsection:etc:optional target]]

- chapter/section/subsection could be also just numbers
- optional target target might be <<optional target target>>
- there is no need to add '*' (like
[[path/to/file.org::*chapter:section]] to the link, as ':' after '::'
imply that headings are referred.

Thank you!

On Tue, 2018-03-13 at 20:49 -0700, John Kitchin wrote:
> This is a tricky problem to generally solve. I think this does it
> approximately well enough. It is lightly tested and works by exactly
> matching headlines at subsequent levels. It will be problematic if you
> have headlines with : in them, and it assumes there is a level 1
> headline to start in.
> 
> 
> #+BEGIN_SRC emacs-lisp
> (defun xpath-follow (path)
>   (let* ((fields (split-string path "::"))
> (fname (car fields))
> (paths (split-string (cadr fields) ":"))
> (level 0)
> (current-point (point))
> cp hls n found) 
>     (org-mark-ring-push)
>     (find-file fname)
>     (save-restriction
>       (while paths
> (setq cp (pop paths))
> (incf level)
> (setq hls (org-element-map (org-element-parse-buffer) 'headline
>     (lambda (hl)
>       (when (eq level (org-element-property :level hl))
> hl))))
> (setq n (-find-index (lambda (hl)
>        (string= cp (org-no-properties
>     (org-element-property :raw-value hl))))
>      hls))
> (if (not n)
>     (progn
>       (goto-char current-point)
>       (user-error "%s not found" cp))
>   (goto-char (org-element-property :begin (nth n hls)))
>   (org-narrow-to-subtree))))))
> 
> 
> (org-link-set-parameters
>  "xpath"
>  :follow 'xpath-follow)
> #+END_SRC
> 
> 
> 
> 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 Mon, Mar 12, 2018 at 8:08 AM, ST <smntov@gmail.com> wrote:
>         Hello,
>         
>         Ss Christian has pointed out - introduce a separate CUSTOM_ID
>         for text
>         with fixed structure and rather short verses is too heavy.
>         
>         I do need to write a custom link type, if this use case is not
>         of common
>         interest for the orgmode community.
>         
>         Thank you,
>         
>         
>         On Mon, 2018-03-12 at 15:10 +0100, Nicolas Goaziou wrote:
>         > Hello,
>         >
>         > ST <smntov@gmail.com> writes:
>         >
>         > > I'm not that experienced in writing in lisp. Is it
>         difficult to create
>         > > such custom link type? What is the closest link type that
>         you would
>         > > recommend to take as starting point (link on code, if
>         possible)?
>         >
>         > I'm not answering your question, but I suggest to use a
>         CUSTOM_ID
>         > instead. This is readily available.
>         >
>         > Regards,
>         >
>         
>         
>         
> 
> 

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

* Re: Structured links to headings with endless depth
  2018-03-14 10:10               ` ST
@ 2018-03-14 13:26                 ` Nicolas Goaziou
  2018-03-14 18:11                   ` ST
  2018-03-14 14:15                 ` John Kitchin
  1 sibling, 1 reply; 21+ messages in thread
From: Nicolas Goaziou @ 2018-03-14 13:26 UTC (permalink / raw)
  To: ST; +Cc: Eric S Fraga, org-mode-email, Christian Moe, John Kitchin

Hello,

> I think this kind of linking is useful for many general cases. Christian
> has expressed concerns that such links are easily breakable which is
> true but only for documents that are in draft phase (or those which are
> supposed to be restructured on regular basis - like ToDo lists). However
> documents that has been published, like books or scientific papers, and
> will no longer change - will benefit greatly from such linking option.
> Imagine you have a scientific paper in your archive that you have
> already published and removed write access from it in order not to
> change it accidentally. You do want to reference certain
> chapter:section:subsection from it in your new paper, which you are
> currently writing, but creating a target <<chapter:section:subsection>>
> in the old paper is no longer an option...
>
> So may I ask as a feature request, to please add, following link type as
> standard to the org-mode:
>
> [[path/to/file.org::chapter:section:subsection:etc:optional target]]
>
> - chapter/section/subsection could be also just numbers
> - optional target target might be <<optional target target>>
> - there is no need to add '*' (like
> [[path/to/file.org::*chapter:section]] to the link, as ':' after '::'
> imply that headings are referred.
>
> Thank you!

Again, even in the case you are talking about, CUSTOM_ID is better, for
at least two reasons:
- it leads to much simpler links: [[file.org::#my-id]]
- it translates nicely to "id" tag in HTML.

I understand this was not so useful in your use case (only headlines, no
contents), but, it is still valid as a general mechanism.

Regards,

-- 
Nicolas Goaziou                                                0x80A93738

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

* Re: Structured links to headings with endless depth
  2018-03-14 10:10               ` ST
  2018-03-14 13:26                 ` Nicolas Goaziou
@ 2018-03-14 14:15                 ` John Kitchin
  2018-03-14 18:07                   ` ST
  1 sibling, 1 reply; 21+ messages in thread
From: John Kitchin @ 2018-03-14 14:15 UTC (permalink / raw)
  To: ST; +Cc: Eric S Fraga, org-mode-email, Christian Moe, Nicolas Goaziou

[-- Attachment #1: Type: text/plain, Size: 6255 bytes --]

I don't think this should be in org-mode, it is still too fragile in many
ways.

For example, what if you have a colon in your headlines, e.g. "A chapter
about Romans 15:13".  That will will mess up the suggested approach that
splits on ":".

What if you have duplicate headlines in a hierarchy, how would you specify
the nth one?

What if you have some convention to start at level 2 headlines? what would
you do then?

What about include files?

What if you skip a level for some reason? What should the path look like
then?

If you can't put custom_ids in, the next best solution for a static file
might be to just jump to line numbers, and use a path-like link
description. That will allow you to jump to a precise line with a link that
looks like the path to that line.

[[file:some/file.org::43][1:2:3]]

Here is a function that will copy a link to the kill ring from the current
point so it is easy to paste somewhere. That link will fold so it looks
like 1:2:3 visually.

#+BEGIN_SRC emacs-lisp
(defun copy-link-with-path ()
  (interactive)
  (let ((line)
(fname (buffer-file-name))
(path-components '()))
    (save-excursion
      (org-back-to-heading)
      (setq line (line-number-at-pos))
      (push (nth 4 (org-heading-components)) path-components)

      (while (org-up-heading-safe)
(when (looking-at "*")
  (push (nth 4 (org-heading-components)) path-components)))
      (kill-new (format "[[file:%s::%s][%s]]"
fname
line
(s-join ":" path-components))))))
#+END_SRC





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 Wed, Mar 14, 2018 at 3:10 AM, ST <smntov@gmail.com> wrote:

> John, thank you for this solution!
>
> I posted this question also here:
>
> https://emacs.stackexchange.com/q/39384/18760
>
> So if you wish, you may add your solution also there.
>
> Somebody there, posted also a possible solution however the syntax is
> pretty heavy:
>
> [[org-heading:/path/to/file.org::*1:2:1]]
>
> There is a workaround using links abbreviations, but still it is a
> workaround...
>
> I think this kind of linking is useful for many general cases. Christian
> has expressed concerns that such links are easily breakable which is
> true but only for documents that are in draft phase (or those which are
> supposed to be restructured on regular basis - like ToDo lists). However
> documents that has been published, like books or scientific papers, and
> will no longer change - will benefit greatly from such linking option.
> Imagine you have a scientific paper in your archive that you have
> already published and removed write access from it in order not to
> change it accidentally. You do want to reference certain
> chapter:section:subsection from it in your new paper, which you are
> currently writing, but creating a target <<chapter:section:subsection>>
> in the old paper is no longer an option...
>
> So may I ask as a feature request, to please add, following link type as
> standard to the org-mode:
>
> [[path/to/file.org::chapter:section:subsection:etc:optional target]]
>
> - chapter/section/subsection could be also just numbers
> - optional target target might be <<optional target target>>
> - there is no need to add '*' (like
> [[path/to/file.org::*chapter:section]] to the link, as ':' after '::'
> imply that headings are referred.
>
> Thank you!
>
> On Tue, 2018-03-13 at 20:49 -0700, John Kitchin wrote:
> > This is a tricky problem to generally solve. I think this does it
> > approximately well enough. It is lightly tested and works by exactly
> > matching headlines at subsequent levels. It will be problematic if you
> > have headlines with : in them, and it assumes there is a level 1
> > headline to start in.
> >
> >
> > #+BEGIN_SRC emacs-lisp
> > (defun xpath-follow (path)
> >   (let* ((fields (split-string path "::"))
> > (fname (car fields))
> > (paths (split-string (cadr fields) ":"))
> > (level 0)
> > (current-point (point))
> > cp hls n found)
> >     (org-mark-ring-push)
> >     (find-file fname)
> >     (save-restriction
> >       (while paths
> > (setq cp (pop paths))
> > (incf level)
> > (setq hls (org-element-map (org-element-parse-buffer) 'headline
> >     (lambda (hl)
> >       (when (eq level (org-element-property :level hl))
> > hl))))
> > (setq n (-find-index (lambda (hl)
> >        (string= cp (org-no-properties
> >     (org-element-property :raw-value hl))))
> >      hls))
> > (if (not n)
> >     (progn
> >       (goto-char current-point)
> >       (user-error "%s not found" cp))
> >   (goto-char (org-element-property :begin (nth n hls)))
> >   (org-narrow-to-subtree))))))
> >
> >
> > (org-link-set-parameters
> >  "xpath"
> >  :follow 'xpath-follow)
> > #+END_SRC
> >
> >
> >
> > 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 Mon, Mar 12, 2018 at 8:08 AM, ST <smntov@gmail.com> wrote:
> >         Hello,
> >
> >         Ss Christian has pointed out - introduce a separate CUSTOM_ID
> >         for text
> >         with fixed structure and rather short verses is too heavy.
> >
> >         I do need to write a custom link type, if this use case is not
> >         of common
> >         interest for the orgmode community.
> >
> >         Thank you,
> >
> >
> >         On Mon, 2018-03-12 at 15:10 +0100, Nicolas Goaziou wrote:
> >         > Hello,
> >         >
> >         > ST <smntov@gmail.com> writes:
> >         >
> >         > > I'm not that experienced in writing in lisp. Is it
> >         difficult to create
> >         > > such custom link type? What is the closest link type that
> >         you would
> >         > > recommend to take as starting point (link on code, if
> >         possible)?
> >         >
> >         > I'm not answering your question, but I suggest to use a
> >         CUSTOM_ID
> >         > instead. This is readily available.
> >         >
> >         > Regards,
> >         >
> >
> >
> >
> >
> >
>
>

[-- Attachment #2: Type: text/html, Size: 9027 bytes --]

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

* Re: Structured links to headings with endless depth
  2018-03-14 14:15                 ` John Kitchin
@ 2018-03-14 18:07                   ` ST
  0 siblings, 0 replies; 21+ messages in thread
From: ST @ 2018-03-14 18:07 UTC (permalink / raw)
  To: John Kitchin; +Cc: Eric S Fraga, org-mode-email, Christian Moe, Nicolas Goaziou

On Wed, 2018-03-14 at 07:15 -0700, John Kitchin wrote:
> I don't think this should be in org-mode, it is still too fragile in
> many ways. 
> 
> 
> For example, what if you have a colon in your headlines, e.g. "A
> chapter about Romans 15:13".  That will will mess up the suggested
> approach that splits on ":".

My bad, I didn't mean to add this specific solution, but rather improve
it till it is no longer fragile. I appealed to those who are responsible
for adding new feature requests (as described on the website) to
consider this idea (and maybe find other more stable ways to implement
it). I'm not sure who they are...

> 
> What if you have duplicate headlines in a hierarchy, how would you
> specify the nth one?

Normally there shouldn't be identical headlines on the same level (on
different levels [[My_Book::2:2:2]] is perfectly fine). Should this
happen - take first occurrence.

> 
> What if you have some convention to start at level 2 headlines? what
> would you do then?
> 
> 
> What about include files?
> 
> 
> What if you skip a level for some reason? What should the path look
> like then?

Then your structure is not well-defined and you should not use such
links.

Thank you!

> 
> 
> 
> On Wed, Mar 14, 2018 at 3:10 AM, ST <smntov@gmail.com> wrote:
>         John, thank you for this solution!
>         
>         I posted this question also here:
>         
>         https://emacs.stackexchange.com/q/39384/18760
>         
>         So if you wish, you may add your solution also there.
>         
>         Somebody there, posted also a possible solution however the
>         syntax is
>         pretty heavy:
>         
>         [[org-heading:/path/to/file.org::*1:2:1]]
>         
>         There is a workaround using links abbreviations, but still it
>         is a
>         workaround...
>         
>         I think this kind of linking is useful for many general cases.
>         Christian
>         has expressed concerns that such links are easily breakable
>         which is
>         true but only for documents that are in draft phase (or those
>         which are
>         supposed to be restructured on regular basis - like ToDo
>         lists). However
>         documents that has been published, like books or scientific
>         papers, and
>         will no longer change - will benefit greatly from such linking
>         option.
>         Imagine you have a scientific paper in your archive that you
>         have
>         already published and removed write access from it in order
>         not to
>         change it accidentally. You do want to reference certain
>         chapter:section:subsection from it in your new paper, which
>         you are
>         currently writing, but creating a target
>         <<chapter:section:subsection>>
>         in the old paper is no longer an option...
>         
>         So may I ask as a feature request, to please add, following
>         link type as
>         standard to the org-mode:
>         
>         [[path/to/file.org::chapter:section:subsection:etc:optional
>         target]]
>         
>         - chapter/section/subsection could be also just numbers
>         - optional target target might be <<optional target target>>
>         - there is no need to add '*' (like
>         [[path/to/file.org::*chapter:section]] to the link, as ':'
>         after '::'
>         imply that headings are referred.
>         
>         Thank you!
>         
>         On Tue, 2018-03-13 at 20:49 -0700, John Kitchin wrote:
>         > This is a tricky problem to generally solve. I think this
>         does it
>         > approximately well enough. It is lightly tested and works by
>         exactly
>         > matching headlines at subsequent levels. It will be
>         problematic if you
>         > have headlines with : in them, and it assumes there is a
>         level 1
>         > headline to start in.
>         >
>         >
>         > #+BEGIN_SRC emacs-lisp
>         > (defun xpath-follow (path)
>         >   (let* ((fields (split-string path "::"))
>         > (fname (car fields))
>         > (paths (split-string (cadr fields) ":"))
>         > (level 0)
>         > (current-point (point))
>         > cp hls n found)
>         >     (org-mark-ring-push)
>         >     (find-file fname)
>         >     (save-restriction
>         >       (while paths
>         > (setq cp (pop paths))
>         > (incf level)
>         > (setq hls (org-element-map (org-element-parse-buffer)
>         'headline
>         >     (lambda (hl)
>         >       (when (eq level (org-element-property :level hl))
>         > hl))))
>         > (setq n (-find-index (lambda (hl)
>         >        (string= cp (org-no-properties
>         >     (org-element-property :raw-value hl))))
>         >      hls))
>         > (if (not n)
>         >     (progn
>         >       (goto-char current-point)
>         >       (user-error "%s not found" cp))
>         >   (goto-char (org-element-property :begin (nth n hls)))
>         >   (org-narrow-to-subtree))))))
>         >
>         >
>         > (org-link-set-parameters
>         >  "xpath"
>         >  :follow 'xpath-follow)
>         > #+END_SRC
>         >
>         >
>         >
>         > 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 Mon, Mar 12, 2018 at 8:08 AM, ST <smntov@gmail.com>
>         wrote:
>         >         Hello,
>         >
>         >         Ss Christian has pointed out - introduce a separate
>         CUSTOM_ID
>         >         for text
>         >         with fixed structure and rather short verses is too
>         heavy.
>         >
>         >         I do need to write a custom link type, if this use
>         case is not
>         >         of common
>         >         interest for the orgmode community.
>         >
>         >         Thank you,
>         >
>         >
>         >         On Mon, 2018-03-12 at 15:10 +0100, Nicolas Goaziou
>         wrote:
>         >         > Hello,
>         >         >
>         >         > ST <smntov@gmail.com> writes:
>         >         >
>         >         > > I'm not that experienced in writing in lisp. Is
>         it
>         >         difficult to create
>         >         > > such custom link type? What is the closest link
>         type that
>         >         you would
>         >         > > recommend to take as starting point (link on
>         code, if
>         >         possible)?
>         >         >
>         >         > I'm not answering your question, but I suggest to
>         use a
>         >         CUSTOM_ID
>         >         > instead. This is readily available.
>         >         >
>         >         > Regards,
>         >         >
>         >
>         >
>         >
>         >
>         >
>         
>         
> 
> 

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

* Re: Structured links to headings with endless depth
  2018-03-14 13:26                 ` Nicolas Goaziou
@ 2018-03-14 18:11                   ` ST
  2018-03-14 18:32                     ` Nicolas Goaziou
  0 siblings, 1 reply; 21+ messages in thread
From: ST @ 2018-03-14 18:11 UTC (permalink / raw)
  To: Nicolas Goaziou; +Cc: Eric S Fraga, org-mode-email, Christian Moe, John Kitchin

On Wed, 2018-03-14 at 14:26 +0100, Nicolas Goaziou wrote:
> Hello,
> 
> > I think this kind of linking is useful for many general cases. Christian
> > has expressed concerns that such links are easily breakable which is
> > true but only for documents that are in draft phase (or those which are
> > supposed to be restructured on regular basis - like ToDo lists). However
> > documents that has been published, like books or scientific papers, and
> > will no longer change - will benefit greatly from such linking option.
> > Imagine you have a scientific paper in your archive that you have
> > already published and removed write access from it in order not to
> > change it accidentally. You do want to reference certain
> > chapter:section:subsection from it in your new paper, which you are
> > currently writing, but creating a target <<chapter:section:subsection>>
> > in the old paper is no longer an option...
> >
> > So may I ask as a feature request, to please add, following link type as
> > standard to the org-mode:
> >
> > [[path/to/file.org::chapter:section:subsection:etc:optional target]]
> >
> > - chapter/section/subsection could be also just numbers
> > - optional target target might be <<optional target target>>
> > - there is no need to add '*' (like
> > [[path/to/file.org::*chapter:section]] to the link, as ':' after '::'
> > imply that headings are referred.
> >
> > Thank you!
> 
> Again, even in the case you are talking about, CUSTOM_ID is better, for
> at least two reasons:
> - it leads to much simpler links: [[file.org::#my-id]]

Why [[file.org::#1:2:1]] is nicer than [file.org::1:2:1]]?

> - it translates nicely to "id" tag in HTML.

You can generate the "id" tag in HTML like this 1-2-1 (if HTML dislikes
1:2:1 tag)

> 
> I understand this was not so useful in your use case (only headlines, no
> contents), but, it is still valid as a general mechanism.

Isn't a good idea to add such a built in link type in the long term?

Thank you!

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

* Re: Structured links to headings with endless depth
  2018-03-14 18:11                   ` ST
@ 2018-03-14 18:32                     ` Nicolas Goaziou
  2018-03-14 18:46                       ` ST
  0 siblings, 1 reply; 21+ messages in thread
From: Nicolas Goaziou @ 2018-03-14 18:32 UTC (permalink / raw)
  To: ST; +Cc: Eric S Fraga, org-mode-email, Christian Moe, John Kitchin

ST <smntov@gmail.com> writes:

> Why [[file.org::#1:2:1]] is nicer than [file.org::1:2:1]]?

Because you can write something more meaningful than "1:2:1" when using
a CUSTOM_ID.

>> - it translates nicely to "id" tag in HTML.
>
> You can generate the "id" tag in HTML like this 1-2-1 (if HTML dislikes
> 1:2:1 tag)

CUSTOM_ID is built-in, without implementing anything.

> Isn't a good idea to add such a built in link type in the long term?

IMO, Org has enough internal link types. 

In particular, this one brings little value compared to CUSTOM_ID. It is
fragile wrt re-ordering, refiling, capture... It may be a headache to
export, too, because "1.2.1" may mean something entirely different once
non-exportable trees have been pruned.

No offence intended, but it really sounds like a false good idea.

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

* Re: Structured links to headings with endless depth
  2018-03-14 18:32                     ` Nicolas Goaziou
@ 2018-03-14 18:46                       ` ST
  0 siblings, 0 replies; 21+ messages in thread
From: ST @ 2018-03-14 18:46 UTC (permalink / raw)
  To: Nicolas Goaziou; +Cc: Eric S Fraga, org-mode-email, Christian Moe, John Kitchin

On Wed, 2018-03-14 at 19:32 +0100, Nicolas Goaziou wrote:
> ST <smntov@gmail.com> writes:
> 
> > Why [[file.org::#1:2:1]] is nicer than [file.org::1:2:1]]?
> 
> Because you can write something more meaningful than "1:2:1" when using
> a CUSTOM_ID.
> 
> >> - it translates nicely to "id" tag in HTML.
> >
> > You can generate the "id" tag in HTML like this 1-2-1 (if HTML dislikes
> > 1:2:1 tag)
> 
> CUSTOM_ID is built-in, without implementing anything.
> 
> > Isn't a good idea to add such a built in link type in the long term?
> 
> IMO, Org has enough internal link types. 
> 
> In particular, this one brings little value compared to CUSTOM_ID. It is
> fragile wrt re-ordering, refiling, capture... It may be a headache to
> export, too, because "1.2.1" may mean something entirely different once
> non-exportable trees have been pruned.

Sure, numbers were just a short abstract example. This can very well be:
fruits:apples:jonagold

> 
> No offence intended, but it really sounds like a false good idea.

You definitely have more experience with org (I'm just learning), so you
indeed know better :)

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

* Re: Structured links to headings with endless depth
  2018-03-14  6:58               ` Michael Brand
@ 2019-05-06 16:34                 ` Michael Brand
  2019-05-07  3:26                   ` Ihor Radchenko
  0 siblings, 1 reply; 21+ messages in thread
From: Michael Brand @ 2019-05-06 16:34 UTC (permalink / raw)
  To: org-mode-email
  Cc: Eric S Fraga, Nicolas Goaziou, Christian Moe, ST, John Kitchin

[-- Attachment #1: Type: text/plain, Size: 2148 bytes --]

Hi all

On Wed, Mar 14, 2018 at 7:58 AM Michael Brand
<michael.ch.brand@gmail.com> wrote:

> ,    (arbitrarily more levels upwards)
> ,      * [...]
> ,        * <composer>
> ,          * <work>
> ,            * TODO <movement>
> ,              * <interpreter> :5:
> ,                - The tag 5 is my rating of this audio recording.
> ,                - The audio recording is stored under the file path
> ,                  [...]/<composer>/<work>/<movement>/<interpreter>/<sth>.mp3
> ,
> ,    * TODO [...]
> ,      - The theme is very similar to this prelude
> ,        [[/:<composer_1>/<work_1>/<movement_1>]].
> ,    * [...]
> ,      - [...] like in this piano concert
> ,        [[/:<composer_2>/<work_2>]].

Despite all the valuable recommendations in this thread I implemented
something simple for my very specific use case of a music database
where I want self-explaining links with the already existing and
complete heading structure and don't want to add any ID, CUSTOM_ID or
<<target>>. See this example:

#+begin_src org
,#+STARTUP: oddeven showeverything

Specs for outline path of links to a heading, any combinations allowed
including none:
- "/" delimits headings of adjacent levels.
- A leading "/" requires matching the top level heading.
- "//" delimits heading levels with 0 to n discarded heading levels
between them.

Demo examples:
- Goes to tag 1: [[*Chopin/Prelude]]
- Goes to tag 2: [[*/Prelude]]
- Goes to tag 3: [[*d/c//b/a]]
- Goes to tag 4: [[*d/c/b/a]]
,* Foo
,** Bach
,*** Prelude
,** Chopin
,*** Prelude :1:
,* Prelude :2:
,* d
,** c
,*** Bar
,**** Baz
,***** b
,****** a :3:
,*** b
,**** a :4:
#+end_src

Limitations of this simplified implementation:
- Export of links with a path to a heading is not supported.
- Links to a heading with "/" that existed before are broken.
- There may be other issues for your use case already discussed in the
current thread (
http://lists.gnu.org/archive/html/emacs-orgmode/2018-03/msg00231.html
).

Due to the limitations this implementation is for private use only and
not meant to be commited upstream although the format of the attached
patches might imply that.

Michael

[-- Attachment #2: 0001-org-get-heading-New-parameter-no-cookie.patch --]
[-- Type: text/x-patch, Size: 2633 bytes --]

From 3a594dfa9967ed4fd70aae04559dde757fb21b1b Mon Sep 17 00:00:00 2001
From: Michael Brand <michael.ch.brand@gmail.com>
Date: Mon, 6 May 2019 18:17:52 +0200
Subject: [PATCH 1/2] org-get-heading: New parameter no-cookie

* lisp/ol.el (org-link-search): Remove regexps for comment and cookie.
* lisp/org.el (org-get-heading:): New parameter no-cookie used above.
---
 lisp/ol.el  | 10 ++--------
 lisp/org.el | 11 +++++++++--
 2 files changed, 11 insertions(+), 10 deletions(-)

diff --git a/lisp/ol.el b/lisp/ol.el
index a6f76a39f..f5bd63e96 100644
--- a/lisp/ol.el
+++ b/lisp/ol.el
@@ -1108,18 +1108,12 @@ of matched result, which is either `dedicated' or `fuzzy'."
 		  (format "%s.*\\(?:%s[ \t]\\)?.*%s"
 			  org-outline-regexp-bol
 			  org-comment-string
-			  (mapconcat #'regexp-quote words ".+")))
-		 (cookie-re "\\[[0-9]*\\(?:%\\|/[0-9]*\\)\\]")
-		 (comment-re (format "\\`%s[ \t]+" org-comment-string)))
+			  (mapconcat #'regexp-quote words ".+"))))
 	     (goto-char (point-min))
 	     (catch :found
 	       (while (re-search-forward title-re nil t)
 		 (when (equal words
-			      (split-string
-			       (replace-regexp-in-string
-				cookie-re ""
-				(replace-regexp-in-string
-				 comment-re "" (org-get-heading t t t)))))
+			      (split-string (org-get-heading t t t t t)))
 		   (throw :found t)))
 	       nil)))
       (beginning-of-line)
diff --git a/lisp/org.el b/lisp/org.el
index 94713a7e5..48f7874ac 100644
--- a/lisp/org.el
+++ b/lisp/org.el
@@ -6938,12 +6938,14 @@ So this will delete or add empty lines."
     (insert (make-string n ?\n))
     (move-to-column column)))
 
-(defun org-get-heading (&optional no-tags no-todo no-priority no-comment)
+(defun org-get-heading (&optional
+			no-tags no-todo no-priority no-comment no-cookie)
   "Return the heading of the current entry, without the stars.
 When NO-TAGS is non-nil, don't include tags.
 When NO-TODO is non-nil, don't include TODO keywords.
 When NO-PRIORITY is non-nil, don't include priority cookie.
 When NO-COMMENT is non-nil, don't include COMMENT string.
+When NO-COOKIE is non-nil, don't include cookie string.
 Return nil before first heading."
   (unless (org-before-first-heading-p)
     (save-excursion
@@ -6958,7 +6960,12 @@ Return nil before first heading."
 			   (replace-regexp-in-string
 			    (eval-when-compile
 			      (format "\\`%s[ \t]+" org-comment-string))
-			    "" h))
+			    ""
+			    (if no-cookie
+				(replace-regexp-in-string
+				 "\\[[0-9]*\\(?:%\\|/[0-9]*\\)\\]"
+				 "" h)
+			      h)))
 			  (h h)))
 	      (tags (and (not no-tags) (match-string 5))))
 	  (mapconcat #'identity
-- 
2.20.1


[-- Attachment #3: 0002-org-link-search-Search-for-outline-path.patch --]
[-- Type: text/x-patch, Size: 4394 bytes --]

From fee37436abbe4a7d6b79161b9230f02de6e7d54d Mon Sep 17 00:00:00 2001
From: Michael Brand <michael.ch.brand@gmail.com>
Date: Mon, 6 May 2019 18:19:44 +0200
Subject: [PATCH 2/2] org-link-search: Search for outline path

* lisp/ol.el (org-link-search): Externalize matching logic to new function
  org-link--heading-path-match-p.
  (org-link--heading-path-split):
  (org-link--heading-path-match-p): New function.
---
 lisp/ol.el | 69 +++++++++++++++++++++++++++++++++++++++++++++++++++---
 1 file changed, 66 insertions(+), 3 deletions(-)

diff --git a/lisp/ol.el b/lisp/ol.el
index f5bd63e96..b79efdf6b 100644
--- a/lisp/ol.el
+++ b/lisp/ol.el
@@ -1034,7 +1034,16 @@ of matched result, which is either `dedicated' or `fuzzy'."
 	 (origin (point))
 	 (normalized (replace-regexp-in-string "\n[ \t]*" " " s))
 	 (starred (eq (string-to-char normalized) ?*))
-	 (words (split-string (if starred (substring s 1) s)))
+	 (heading-path (and starred (substring normalized 1)))
+	 (words (split-string
+		 (if starred
+		     (replace-regexp-in-string "^.*/" "" heading-path)
+		   s)))
+	 (path-rest
+	  (and starred
+	       (cdr (org-link--heading-path-split
+		     (replace-regexp-in-string "^/" "" heading-path)))))
+	 (path-rooted-p (and starred (eq ?/ (string-to-char heading-path))))
 	 (s-multi-re (mapconcat #'regexp-quote words "\\(?:[ \t\n]+\\)"))
 	 (s-single-re (mapconcat #'regexp-quote words "[ \t]+"))
 	 type)
@@ -1112,8 +1121,8 @@ of matched result, which is either `dedicated' or `fuzzy'."
 	     (goto-char (point-min))
 	     (catch :found
 	       (while (re-search-forward title-re nil t)
-		 (when (equal words
-			      (split-string (org-get-heading t t t t t)))
+		 (when (org-link--heading-path-match-p
+			words path-rest path-rooted-p)
 		   (throw :found t)))
 	       nil)))
       (beginning-of-line)
@@ -1163,6 +1172,60 @@ of matched result, which is either `dedicated' or `fuzzy'."
       (org-show-context 'link-search))
     type))
 
+(defun org-link--heading-path-split (path)
+  "Split the PATH string and enumerate the headings by contiguous groups.
+For example \"f/e//d/c/b//a\"
+=> ((\"a\" . 0) (\"b\" . 0) (\"c\" . 1) (\"d\" . 2) (\"e\" . 0) (\"f\" . 1))"
+  (apply #'append
+	 (mapcar (lambda (contiguous)
+		   (let* ((headings (reverse (split-string contiguous "/")))
+			  (enum (number-sequence 0 (1- (length headings)))))
+		     (mapcar* #'cons headings enum)))
+		 (reverse (split-string path "//")))))
+
+(defun org-link--heading-path-match-p (current path-rest path-rooted-p)
+  "Match heading hierarchy at point with CURRENT and PATH-REST.
+
+CURRENT is `split-string' of the string for the requested lowest
+level heading.
+
+PATH-REST is the `cdr' of `org-link--heading-path-split' of the
+path string originally still including the current heading.
+PATH-REST can be nil or contains the upper level headings in
+groups indicated by an enumeration starting at 0. Every 0
+indicates the beginning of a new group. Examples for PATH-REST
+values: ((\"a\" . 1) (\"b\" . 2)) which is the `cdr'
+of ((\"current\" . 0) (\"a\" . 1) (\"b\" . 2)) indicates that
+there is one group which means that it matches the Org hierarchy
+b/a/current but not b/x/a/current or b/a/x/current. ((\"a\" .
+1) (\"b\" . 0)) indicates that there are two groups separated
+between a and b which means that it matches b/a/current,
+b/x/a/current, b/x/x/a/current etc. with any number of discarded
+headings x between the groups but not b/a/x/current. ((\"a\" .
+0) (\"b\" . 1)) indicates that there are two groups separated
+between current and a which means that it matches for example
+b/a/x/current.
+
+Non-nil PATH-ROOTED-P means that the first level heading in the
+buffer must be part of the match."
+       (save-excursion
+	 (and (equal current (split-string (org-get-heading t t t t t)))
+	      (or (not path-rest)
+		  (every (lambda (heading)
+			   (let (match)
+			     (while (and (org-up-heading-safe)
+					 (not (setq match
+						    (equal (split-string
+							    (car heading))
+							   (split-string
+							    (org-get-heading
+							     t t t t t)))))
+					 (zerop (cdr heading))))
+			     match))
+			 path-rest))
+	      (or (not path-rooted-p)
+		  (eq 1 (org-outline-level))))))
+
 (defun org-link-heading-search-string (&optional string)
   "Make search string for the current headline or STRING."
   (let ((s (or string
-- 
2.20.1


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

* Re: Structured links to headings with endless depth
  2019-05-06 16:34                 ` Michael Brand
@ 2019-05-07  3:26                   ` Ihor Radchenko
  2019-05-07 14:39                     ` Michael Brand
  0 siblings, 1 reply; 21+ messages in thread
From: Ihor Radchenko @ 2019-05-07  3:26 UTC (permalink / raw)
  To: Michael Brand, org-mode-email
  Cc: Eric S Fraga, ST, Christian Moe, Nicolas Goaziou, John Kitchin

Dear Michael,

> ... I want self-explaining links with the already existing and
> complete heading structure and don't want to add any ID, CUSTOM_ID or
> <<target>>. See this example:

I am wondering why you are strictly against ID properties.

The IDs can be set automatically. The property drawer can be hidden (see
https://stackoverflow.com/questions/17478260/completely-hide-the-properties-drawer-in-org-mode)
and will not clutter you org file.

An arbitrary id link can be self-explaining if you add a proper link
description: [[id:your_id][composer_1/work_1/movement_1]]. Moreover it
is not fragile against refiling or duplicate entries.

Best,
Ihor


Michael Brand <michael.ch.brand@gmail.com> writes:

> Hi all
>
> On Wed, Mar 14, 2018 at 7:58 AM Michael Brand
> <michael.ch.brand@gmail.com> wrote:
>
>> ,    (arbitrarily more levels upwards)
>> ,      * [...]
>> ,        * <composer>
>> ,          * <work>
>> ,            * TODO <movement>
>> ,              * <interpreter> :5:
>> ,                - The tag 5 is my rating of this audio recording.
>> ,                - The audio recording is stored under the file path
>> ,                  [...]/<composer>/<work>/<movement>/<interpreter>/<sth>.mp3
>> ,
>> ,    * TODO [...]
>> ,      - The theme is very similar to this prelude
>> ,        [[/:<composer_1>/<work_1>/<movement_1>]].
>> ,    * [...]
>> ,      - [...] like in this piano concert
>> ,        [[/:<composer_2>/<work_2>]].
>
> Despite all the valuable recommendations in this thread I implemented
> something simple for my very specific use case of a music database
> where I want self-explaining links with the already existing and
> complete heading structure and don't want to add any ID, CUSTOM_ID or
> <<target>>. See this example:
>
> #+begin_src org
> ,#+STARTUP: oddeven showeverything
>
> Specs for outline path of links to a heading, any combinations allowed
> including none:
> - "/" delimits headings of adjacent levels.
> - A leading "/" requires matching the top level heading.
> - "//" delimits heading levels with 0 to n discarded heading levels
> between them.
>
> Demo examples:
> - Goes to tag 1: [[*Chopin/Prelude]]
> - Goes to tag 2: [[*/Prelude]]
> - Goes to tag 3: [[*d/c//b/a]]
> - Goes to tag 4: [[*d/c/b/a]]
> ,* Foo
> ,** Bach
> ,*** Prelude
> ,** Chopin
> ,*** Prelude :1:
> ,* Prelude :2:
> ,* d
> ,** c
> ,*** Bar
> ,**** Baz
> ,***** b
> ,****** a :3:
> ,*** b
> ,**** a :4:
> #+end_src
>
> Limitations of this simplified implementation:
> - Export of links with a path to a heading is not supported.
> - Links to a heading with "/" that existed before are broken.
> - There may be other issues for your use case already discussed in the
> current thread (
> http://lists.gnu.org/archive/html/emacs-orgmode/2018-03/msg00231.html
> ).
>
> Due to the limitations this implementation is for private use only and
> not meant to be commited upstream although the format of the attached
> patches might imply that.
>
> Michael
> From 3a594dfa9967ed4fd70aae04559dde757fb21b1b Mon Sep 17 00:00:00 2001
> From: Michael Brand <michael.ch.brand@gmail.com>
> Date: Mon, 6 May 2019 18:17:52 +0200
> Subject: [PATCH 1/2] org-get-heading: New parameter no-cookie
>
> * lisp/ol.el (org-link-search): Remove regexps for comment and cookie.
> * lisp/org.el (org-get-heading:): New parameter no-cookie used above.
> ---
>  lisp/ol.el  | 10 ++--------
>  lisp/org.el | 11 +++++++++--
>  2 files changed, 11 insertions(+), 10 deletions(-)
>
> diff --git a/lisp/ol.el b/lisp/ol.el
> index a6f76a39f..f5bd63e96 100644
> --- a/lisp/ol.el
> +++ b/lisp/ol.el
> @@ -1108,18 +1108,12 @@ of matched result, which is either `dedicated' or `fuzzy'."
>  		  (format "%s.*\\(?:%s[ \t]\\)?.*%s"
>  			  org-outline-regexp-bol
>  			  org-comment-string
> -			  (mapconcat #'regexp-quote words ".+")))
> -		 (cookie-re "\\[[0-9]*\\(?:%\\|/[0-9]*\\)\\]")
> -		 (comment-re (format "\\`%s[ \t]+" org-comment-string)))
> +			  (mapconcat #'regexp-quote words ".+"))))
>  	     (goto-char (point-min))
>  	     (catch :found
>  	       (while (re-search-forward title-re nil t)
>  		 (when (equal words
> -			      (split-string
> -			       (replace-regexp-in-string
> -				cookie-re ""
> -				(replace-regexp-in-string
> -				 comment-re "" (org-get-heading t t t)))))
> +			      (split-string (org-get-heading t t t t t)))
>  		   (throw :found t)))
>  	       nil)))
>        (beginning-of-line)
> diff --git a/lisp/org.el b/lisp/org.el
> index 94713a7e5..48f7874ac 100644
> --- a/lisp/org.el
> +++ b/lisp/org.el
> @@ -6938,12 +6938,14 @@ So this will delete or add empty lines."
>      (insert (make-string n ?\n))
>      (move-to-column column)))
>  
> -(defun org-get-heading (&optional no-tags no-todo no-priority no-comment)
> +(defun org-get-heading (&optional
> +			no-tags no-todo no-priority no-comment no-cookie)
>    "Return the heading of the current entry, without the stars.
>  When NO-TAGS is non-nil, don't include tags.
>  When NO-TODO is non-nil, don't include TODO keywords.
>  When NO-PRIORITY is non-nil, don't include priority cookie.
>  When NO-COMMENT is non-nil, don't include COMMENT string.
> +When NO-COOKIE is non-nil, don't include cookie string.
>  Return nil before first heading."
>    (unless (org-before-first-heading-p)
>      (save-excursion
> @@ -6958,7 +6960,12 @@ Return nil before first heading."
>  			   (replace-regexp-in-string
>  			    (eval-when-compile
>  			      (format "\\`%s[ \t]+" org-comment-string))
> -			    "" h))
> +			    ""
> +			    (if no-cookie
> +				(replace-regexp-in-string
> +				 "\\[[0-9]*\\(?:%\\|/[0-9]*\\)\\]"
> +				 "" h)
> +			      h)))
>  			  (h h)))
>  	      (tags (and (not no-tags) (match-string 5))))
>  	  (mapconcat #'identity
> -- 
> 2.20.1
>
> From fee37436abbe4a7d6b79161b9230f02de6e7d54d Mon Sep 17 00:00:00 2001
> From: Michael Brand <michael.ch.brand@gmail.com>
> Date: Mon, 6 May 2019 18:19:44 +0200
> Subject: [PATCH 2/2] org-link-search: Search for outline path
>
> * lisp/ol.el (org-link-search): Externalize matching logic to new function
>   org-link--heading-path-match-p.
>   (org-link--heading-path-split):
>   (org-link--heading-path-match-p): New function.
> ---
>  lisp/ol.el | 69 +++++++++++++++++++++++++++++++++++++++++++++++++++---
>  1 file changed, 66 insertions(+), 3 deletions(-)
>
> diff --git a/lisp/ol.el b/lisp/ol.el
> index f5bd63e96..b79efdf6b 100644
> --- a/lisp/ol.el
> +++ b/lisp/ol.el
> @@ -1034,7 +1034,16 @@ of matched result, which is either `dedicated' or `fuzzy'."
>  	 (origin (point))
>  	 (normalized (replace-regexp-in-string "\n[ \t]*" " " s))
>  	 (starred (eq (string-to-char normalized) ?*))
> -	 (words (split-string (if starred (substring s 1) s)))
> +	 (heading-path (and starred (substring normalized 1)))
> +	 (words (split-string
> +		 (if starred
> +		     (replace-regexp-in-string "^.*/" "" heading-path)
> +		   s)))
> +	 (path-rest
> +	  (and starred
> +	       (cdr (org-link--heading-path-split
> +		     (replace-regexp-in-string "^/" "" heading-path)))))
> +	 (path-rooted-p (and starred (eq ?/ (string-to-char heading-path))))
>  	 (s-multi-re (mapconcat #'regexp-quote words "\\(?:[ \t\n]+\\)"))
>  	 (s-single-re (mapconcat #'regexp-quote words "[ \t]+"))
>  	 type)
> @@ -1112,8 +1121,8 @@ of matched result, which is either `dedicated' or `fuzzy'."
>  	     (goto-char (point-min))
>  	     (catch :found
>  	       (while (re-search-forward title-re nil t)
> -		 (when (equal words
> -			      (split-string (org-get-heading t t t t t)))
> +		 (when (org-link--heading-path-match-p
> +			words path-rest path-rooted-p)
>  		   (throw :found t)))
>  	       nil)))
>        (beginning-of-line)
> @@ -1163,6 +1172,60 @@ of matched result, which is either `dedicated' or `fuzzy'."
>        (org-show-context 'link-search))
>      type))
>  
> +(defun org-link--heading-path-split (path)
> +  "Split the PATH string and enumerate the headings by contiguous groups.
> +For example \"f/e//d/c/b//a\"
> +=> ((\"a\" . 0) (\"b\" . 0) (\"c\" . 1) (\"d\" . 2) (\"e\" . 0) (\"f\" . 1))"
> +  (apply #'append
> +	 (mapcar (lambda (contiguous)
> +		   (let* ((headings (reverse (split-string contiguous "/")))
> +			  (enum (number-sequence 0 (1- (length headings)))))
> +		     (mapcar* #'cons headings enum)))
> +		 (reverse (split-string path "//")))))
> +
> +(defun org-link--heading-path-match-p (current path-rest path-rooted-p)
> +  "Match heading hierarchy at point with CURRENT and PATH-REST.
> +
> +CURRENT is `split-string' of the string for the requested lowest
> +level heading.
> +
> +PATH-REST is the `cdr' of `org-link--heading-path-split' of the
> +path string originally still including the current heading.
> +PATH-REST can be nil or contains the upper level headings in
> +groups indicated by an enumeration starting at 0. Every 0
> +indicates the beginning of a new group. Examples for PATH-REST
> +values: ((\"a\" . 1) (\"b\" . 2)) which is the `cdr'
> +of ((\"current\" . 0) (\"a\" . 1) (\"b\" . 2)) indicates that
> +there is one group which means that it matches the Org hierarchy
> +b/a/current but not b/x/a/current or b/a/x/current. ((\"a\" .
> +1) (\"b\" . 0)) indicates that there are two groups separated
> +between a and b which means that it matches b/a/current,
> +b/x/a/current, b/x/x/a/current etc. with any number of discarded
> +headings x between the groups but not b/a/x/current. ((\"a\" .
> +0) (\"b\" . 1)) indicates that there are two groups separated
> +between current and a which means that it matches for example
> +b/a/x/current.
> +
> +Non-nil PATH-ROOTED-P means that the first level heading in the
> +buffer must be part of the match."
> +       (save-excursion
> +	 (and (equal current (split-string (org-get-heading t t t t t)))
> +	      (or (not path-rest)
> +		  (every (lambda (heading)
> +			   (let (match)
> +			     (while (and (org-up-heading-safe)
> +					 (not (setq match
> +						    (equal (split-string
> +							    (car heading))
> +							   (split-string
> +							    (org-get-heading
> +							     t t t t t)))))
> +					 (zerop (cdr heading))))
> +			     match))
> +			 path-rest))
> +	      (or (not path-rooted-p)
> +		  (eq 1 (org-outline-level))))))
> +
>  (defun org-link-heading-search-string (&optional string)
>    "Make search string for the current headline or STRING."
>    (let ((s (or string
> -- 
> 2.20.1
>

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

* Re: Structured links to headings with endless depth
  2019-05-07  3:26                   ` Ihor Radchenko
@ 2019-05-07 14:39                     ` Michael Brand
  2019-05-18 10:44                       ` Ihor Radchenko
  0 siblings, 1 reply; 21+ messages in thread
From: Michael Brand @ 2019-05-07 14:39 UTC (permalink / raw)
  To: Ihor Radchenko
  Cc: Nicolas Goaziou, Christian Moe, John Kitchin, Eric S Fraga,
	org-mode-email, ST

Hi Ihor

On Tue, May 7, 2019 at 5:27 AM Ihor Radchenko <yantar92@gmail.com> wrote:

> I am wondering why you are strictly against ID properties.

To me this looks like a misunderstanding. I use the ID often but my
weighting of the different advantages is not the same in all cases.
Some situations where no ID can be seen as an advantage: Looking at
the raw view (for example visible-mode during ediff), looking at the
raw file (when in the other world outside of Org mode), the time it
can take to not find an ID in all the ID files when the target file or
ID is not accessible, etc. There must be good reasons why some more
users than just me sometimes prefer the format B over A:

#+name: A
#+begin_src org
- [[id:8e5c5d87-291e-469b-a8e4-15704610c82c][The heading name]]
,* The heading name
  :PROPERTIES:
  :ID:       8e5c5d87-291e-469b-a8e4-15704610c82c
  :END:
#+end_src

#+name: B
#+begin_src org
- [[*The heading name]]
,* The heading name
#+end_src

Michael

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

* Re: Structured links to headings with endless depth
  2019-05-07 14:39                     ` Michael Brand
@ 2019-05-18 10:44                       ` Ihor Radchenko
  0 siblings, 0 replies; 21+ messages in thread
From: Ihor Radchenko @ 2019-05-18 10:44 UTC (permalink / raw)
  To: Michael Brand
  Cc: Nicolas Goaziou, Christian Moe, John Kitchin, Eric S Fraga,
	org-mode-email, ST

> There must be good reasons why some more
> users than just me sometimes prefer the format B over A:

Fair enough. Thanks for the clarification.

Best,
Ihor


Michael Brand <michael.ch.brand@gmail.com> writes:

> Hi Ihor
>
> On Tue, May 7, 2019 at 5:27 AM Ihor Radchenko <yantar92@gmail.com> wrote:
>
>> I am wondering why you are strictly against ID properties.
>
> To me this looks like a misunderstanding. I use the ID often but my
> weighting of the different advantages is not the same in all cases.
> Some situations where no ID can be seen as an advantage: Looking at
> the raw view (for example visible-mode during ediff), looking at the
> raw file (when in the other world outside of Org mode), the time it
> can take to not find an ID in all the ID files when the target file or
> ID is not accessible, etc. There must be good reasons why some more
> users than just me sometimes prefer the format B over A:
>
> #+name: A
> #+begin_src org
> - [[id:8e5c5d87-291e-469b-a8e4-15704610c82c][The heading name]]
> ,* The heading name
>   :PROPERTIES:
>   :ID:       8e5c5d87-291e-469b-a8e4-15704610c82c
>   :END:
> #+end_src
>
> #+name: B
> #+begin_src org
> - [[*The heading name]]
> ,* The heading name
> #+end_src
>
> Michael

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

end of thread, other threads:[~2019-05-18 11:01 UTC | newest]

Thread overview: 21+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2018-03-12 10:09 Structured links to headings with endless depth ST
2018-03-12 10:29 ` Eric S Fraga
2018-03-12 10:39   ` ST
2018-03-12 13:08     ` Christian Moe
2018-03-12 13:46       ` ST
2018-03-12 14:10         ` Nicolas Goaziou
2018-03-12 15:08           ` ST
2018-03-14  3:49             ` John Kitchin
2018-03-14  6:58               ` Michael Brand
2019-05-06 16:34                 ` Michael Brand
2019-05-07  3:26                   ` Ihor Radchenko
2019-05-07 14:39                     ` Michael Brand
2019-05-18 10:44                       ` Ihor Radchenko
2018-03-14 10:10               ` ST
2018-03-14 13:26                 ` Nicolas Goaziou
2018-03-14 18:11                   ` ST
2018-03-14 18:32                     ` Nicolas Goaziou
2018-03-14 18:46                       ` ST
2018-03-14 14:15                 ` John Kitchin
2018-03-14 18:07                   ` ST
2018-03-12 12:43   ` ST

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).