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