From mboxrd@z Thu Jan 1 00:00:00 1970 From: John Kitchin Subject: Re: Structured links to headings with endless depth Date: Wed, 14 Mar 2018 07:15:13 -0700 Message-ID: References: <1520849353.1793.66.camel@gmail.com> <87tvtlsi2f.fsf@gmail.com> <1520851190.1793.74.camel@gmail.com> <87lgexfnl6.fsf@christianmoe.com> <1520862394.1793.83.camel@gmail.com> <87r2opcrkm.fsf@nicolasgoaziou.fr> <1520867316.1793.87.camel@gmail.com> <1521022248.1930.85.camel@gmail.com> Mime-Version: 1.0 Content-Type: multipart/alternative; boundary="001a114433bef4e05b0567600002" Return-path: Received: from eggs.gnu.org ([2001:4830:134:3::10]:44442) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1ew7Bb-0000S4-H1 for Emacs-orgmode@gnu.org; Wed, 14 Mar 2018 10:15:25 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1ew7BU-0007am-0u for Emacs-orgmode@gnu.org; Wed, 14 Mar 2018 10:15:23 -0400 Received: from mail-wm0-x235.google.com ([2a00:1450:400c:c09::235]:52864) by eggs.gnu.org with esmtps (TLS1.0:RSA_AES_128_CBC_SHA1:16) (Exim 4.71) (envelope-from ) id 1ew7BT-0007aC-Gv for Emacs-orgmode@gnu.org; Wed, 14 Mar 2018 10:15:15 -0400 Received: by mail-wm0-x235.google.com with SMTP id t3so4360958wmc.2 for ; Wed, 14 Mar 2018 07:15:15 -0700 (PDT) In-Reply-To: <1521022248.1930.85.camel@gmail.com> List-Id: "General discussions about Org-mode." List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: emacs-orgmode-bounces+geo-emacs-orgmode=m.gmane.org@gnu.org Sender: "Emacs-orgmode" To: ST Cc: Eric S Fraga , org-mode-email , Christian Moe , Nicolas Goaziou --001a114433bef4e05b0567600002 Content-Type: text/plain; charset="UTF-8" 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 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 <> > 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 <> > - 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 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 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, > > > > > > > > > > > > > > > --001a114433bef4e05b0567600002 Content-Type: text/html; charset="UTF-8" Content-Transfer-Encoding: quoted-printable
I don't think this should be in org-mode, it is still = too fragile in many ways.=C2=A0

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

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

What i= f 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, th= e next best solution for a static file might be to just jump to line number= s, and use a path-like link description. That will allow you to jump to a p= recise line with a link that looks like the path to that line.
[[file:some/file.org::43][1:2:3]]

Her= e is a function that will copy a link to the kill ring from the current poi= nt 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 ()
=C2=A0 (interactive)
= =C2=A0 (let ((line)
(fnam= e (buffer-file-name))
(pa= th-components '()))
=C2=A0 =C2=A0 (save-excursion
= =C2=A0 =C2=A0 =C2=A0 (org-back-to-heading)
=C2=A0 =C2=A0 =C2=A0 (= setq line (line-number-at-pos))
=C2=A0 =C2=A0 =C2=A0 (push (nth 4= (org-heading-components)) path-components)

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





John

-------------------= ----------------
Professor John Kitchin=C2=A0
Doherty Hall A207F
D= epartment of Chemical Engineering
Carnegie Mellon University
Pittsbur= gh, PA 15213
412-268-7803

On Wed, Mar 14, 2018 at 3:10 AM, ST <smntov@= gmail.com> wrote:
John, th= ank you for this solution!

I posted this question also here:

https://emacs.stackexchange.com/q/39384/18760<= br>
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 targe= t]]

- 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 ':' aft= er '::'
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)
>=C2=A0 =C2=A0(let* ((fields (split-string path "::"))
> (fname (car fields))
> (paths (split-string (cadr fields) ":"))
> (level 0)
> (current-point (point))
> cp hls n found)
>=C2=A0 =C2=A0 =C2=A0(org-mark-ring-push)
>=C2=A0 =C2=A0 =C2=A0(find-file fname)
>=C2=A0 =C2=A0 =C2=A0(save-restriction
>=C2=A0 =C2=A0 =C2=A0 =C2=A0(while paths
> (setq cp (pop paths))
> (incf level)
> (setq hls (org-element-map (org-element-parse-buffer) 'headline >=C2=A0 =C2=A0 =C2=A0(lambda (hl)
>=C2=A0 =C2=A0 =C2=A0 =C2=A0(when (eq level (org-element-property :level= hl))
> hl))))
> (setq n (-find-index (lambda (hl)
>=C2=A0 =C2=A0 =C2=A0 =C2=A0 (string=3D cp (org-no-properties
>=C2=A0 =C2=A0 =C2=A0(org-element-property :raw-value hl))))
>=C2=A0 =C2=A0 =C2=A0 hls))
> (if (not n)
>=C2=A0 =C2=A0 =C2=A0(progn
>=C2=A0 =C2=A0 =C2=A0 =C2=A0(goto-char current-point)
>=C2=A0 =C2=A0 =C2=A0 =C2=A0(user-error "%s not found" cp)) >=C2=A0 =C2=A0(goto-char (org-element-property :begin (nth n hls)))
>=C2=A0 =C2=A0(org-narrow-to-subtree))))))
>
>
> (org-link-set-parameters
>=C2=A0 "xpath"
>=C2=A0 :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:
>=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0Hello,
>
>=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0Ss Christian has pointed out - introd= uce a separate CUSTOM_ID
>=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0for text
>=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0with fixed structure and rather short= verses is too heavy.
>
>=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0I do need to write a custom link type= , if this use case is not
>=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0of common
>=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0interest for the orgmode community. >
>=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0Thank you,
>
>
>=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0On Mon, 2018-03-12 at 15:10 +0100, Ni= colas Goaziou wrote:
>=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0> Hello,
>=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0>
>=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0> ST <smntov@gmail.com> writes:
>=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0>
>=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0> > I'm not that experience= d in writing in lisp. Is it
>=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0difficult to create
>=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0> > such custom link type? What= is the closest link type that
>=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0you would
>=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0> > recommend to take as starti= ng point (link on code, if
>=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0possible)?
>=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0>
>=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0> I'm not answering your quest= ion, but I suggest to use a
>=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0CUSTOM_ID
>=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0> instead. This is readily availab= le.
>=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0>
>=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0> Regards,
>=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0>
>
>
>
>
>


--001a114433bef4e05b0567600002--