emacs-orgmode@gnu.org archives
 help / color / mirror / code / Atom feed
* [dev] Implement "ref" link types
@ 2012-02-19 18:08 Nicolas Goaziou
  2012-02-19 19:28 ` Christian Moe
                   ` (2 more replies)
  0 siblings, 3 replies; 19+ messages in thread
From: Nicolas Goaziou @ 2012-02-19 18:08 UTC (permalink / raw)
  To: Org Mode List

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

Hello,

I'd like to introduce a new type of internal links, namely "ref" links.

Since any element can now have a "#+name: something" affiliated keyword,
it would be practical to have a way to go straight to that name, from
anywhere in the buffer. The following patch implements
a [[ref:something]] syntax, or even [[ref:something][text]] to do so.

The problem that I see here is that is breaks a bit syntax for internal
links ("protocol:path" is usually for external links). Another solution
would be to make them more hermetic: [[!something]].

On the export side, a "ref" link should be replaced by its description,
if it has any, or by the sequence number of the matching element among
elements of the same type. With the new exporter and the following
buffer:

#+begin_src org
  #+name: tab:letters
  #+caption: Letters
  | a | b |
  | c | d |

  #+name: tab:numbers
  #+caption: Numbers
  | 1 |
  | 2 |


  In tableau [[ref:tab:numbers]] we can see... Yet, in
  [[ref:tab:numbers][the same table]], ...
#+end_src

the last sentence, in ascii, becomes:

         In tableau 2 we can see... Yet, in the same table, ...


Even if it's not a perfect replacement for "\ref{something}" commands,
it should be sufficient for all major back-ends to provide an
approximate functionality. And we gain interactivity in the Org buffer.

What do you think?


Regards,

-- 
Nicolas Goaziou

[-- Warning: decoded text below may be mangled, UTF-8 assumed --]
[-- Attachment #2: patch for ref links --]
[-- Type: text/x-patch, Size: 1263 bytes --]

From f92e12a9482613d4b1d27090fac8d2667b094fdb Mon Sep 17 00:00:00 2001
From: Nicolas Goaziou <n.goaziou@gmail.com>
Date: Sun, 19 Feb 2012 18:48:41 +0100
Subject: [PATCH] Implement "ref" internal link type in Org buffers

* lisp/org.el (org-link-search): Handle "ref" internal link types.

A [[ref:some-name]] link points to a "#+name: some-name" in the same
buffer.
---
 lisp/org.el |   10 ++++++++++
 1 files changed, 10 insertions(+), 0 deletions(-)

diff --git a/lisp/org.el b/lisp/org.el
index a81f7fc..ea06863 100644
--- a/lisp/org.el
+++ b/lisp/org.el
@@ -9875,6 +9875,16 @@ visibility around point, thus ignoring
      ;; First check if there are any special search functions
      ((run-hook-with-args-until-success 'org-execute-file-search-functions s))
      ;; Now try the builtin stuff
+     ;; Ref internal link.
+     ((and (string-match "^ref:\\(.*\\)" s0)
+	   (let ((name (org-trim (match-string 1 s0))))
+	     (save-excursion
+	       (goto-char (point-min))
+	       (and (re-search-forward
+		     (format "^[ \t]*#\\+name: %s" name) nil t)
+		    (setq type 'dedicated pos (match-beginning 0))))))
+      (goto-char pos))
+     ;; Custom-id
      ((and (equal (string-to-char s0) ?#)
 	   (> (length s0) 1)
 	   (save-excursion
-- 
1.7.9.1


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

* Re: [dev] Implement "ref" link types
  2012-02-19 18:08 [dev] Implement "ref" link types Nicolas Goaziou
@ 2012-02-19 19:28 ` Christian Moe
  2012-02-19 19:41   ` Nicolas Goaziou
  2012-02-19 19:41 ` Samuel Wales
  2012-02-19 20:10 ` Carsten Dominik
  2 siblings, 1 reply; 19+ messages in thread
From: Christian Moe @ 2012-02-19 19:28 UTC (permalink / raw)
  To: Nicolas Goaziou; +Cc: Org Mode List

Hi,

I think it's a great idea, as I've wanted to do it myself :-) , but 
I'm glad it's in competent hands instead.

Me, I don't see any problem with a [[ref:something]] syntax. It's the 
obvious org-native, cross-backend replacement for \ref. The 
[[protocol:something]] syntax already widens the notion of link to 
shell: and elisp: links, so I wouldn't worry about breaking 
conventions. Using e.g. [[!something]] instead would introduce a brand 
new bit of syntax.

Suggestion: On export, how about enabling automatic element 
descriptions for references following the type:name convention, so 
that e.g. just

: in [[ref:tab:numbers]] we can see...

would expand to

   in Table 2 we can see...

If implemented, this should be user-customizable e.g. through an alist 
like

   (("fig" . "Figure") ("tab" . "Table") ("map" . "Map"))


Yours,
Christian





On 2/19/12 7:08 PM, Nicolas Goaziou wrote:
> Hello,
>
> I'd like to introduce a new type of internal links, namely "ref" links.
>
> Since any element can now have a "#+name: something" affiliated keyword,
> it would be practical to have a way to go straight to that name, from
> anywhere in the buffer. The following patch implements
> a [[ref:something]] syntax, or even [[ref:something][text]] to do so.
>
> The problem that I see here is that is breaks a bit syntax for internal
> links ("protocol:path" is usually for external links). Another solution
> would be to make them more hermetic: [[!something]].
>
> On the export side, a "ref" link should be replaced by its description,
> if it has any, or by the sequence number of the matching element among
> elements of the same type. With the new exporter and the following
> buffer:
>
> #+begin_src org
>    #+name: tab:letters
>    #+caption: Letters
>    | a | b |
>    | c | d |
>
>    #+name: tab:numbers
>    #+caption: Numbers
>    | 1 |
>    | 2 |
>
>
>    In tableau [[ref:tab:numbers]] we can see... Yet, in
>    [[ref:tab:numbers][the same table]], ...
> #+end_src
>
> the last sentence, in ascii, becomes:
>
>           In tableau 2 we can see... Yet, in the same table, ...
>
>
> Even if it's not a perfect replacement for "\ref{something}" commands,
> it should be sufficient for all major back-ends to provide an
> approximate functionality. And we gain interactivity in the Org buffer.
>
> What do you think?
>
>
> Regards,
>

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

* Re: [dev] Implement "ref" link types
  2012-02-19 18:08 [dev] Implement "ref" link types Nicolas Goaziou
  2012-02-19 19:28 ` Christian Moe
@ 2012-02-19 19:41 ` Samuel Wales
  2012-02-19 20:02   ` Nicolas Goaziou
  2012-02-19 20:10 ` Carsten Dominik
  2 siblings, 1 reply; 19+ messages in thread
From: Samuel Wales @ 2012-02-19 19:41 UTC (permalink / raw)
  To: Nicolas Goaziou; +Cc: Org Mode List

I think it's a good idea, and would suggest this:

  * If it is not going to have features added, then [[ref:asdf]] is OK
  * If it /is/ going to have features added, then I recommend ES/US

ES/US is extensible syntax / universal syntax, a specific proposal for
an orthogonal and future-proof syntax for new capabilities like this.

For example, you might want to put the target anywhere, not just where
there are elements.  The ID marker idea implements this with ES/US.
In this case, we'd simply allow element names in addition with the
same source syntax.

Of course, you might decide that nobody will ever want to add new
syntax to those links, in which case a simple new link type would make
sense.

Samuel

-- 
The Kafka Pandemic: http://thekafkapandemic.blogspot.com

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

* Re: [dev] Implement "ref" link types
  2012-02-19 19:28 ` Christian Moe
@ 2012-02-19 19:41   ` Nicolas Goaziou
  2012-02-19 20:11     ` Toby Cubitt
  2012-02-19 20:20     ` Christian Moe
  0 siblings, 2 replies; 19+ messages in thread
From: Nicolas Goaziou @ 2012-02-19 19:41 UTC (permalink / raw)
  To: mail; +Cc: Org Mode List

Hello,

Christian Moe <mail@christianmoe.com> writes:

> Me, I don't see any problem with a [[ref:something]] syntax. It's the
> obvious org-native, cross-backend replacement for \ref. The
> [[protocol:something]] syntax already widens the notion of link to
> shell: and elisp: links, so I wouldn't worry about breaking
> conventions. Using e.g. [[!something]] instead would introduce a brand
> new bit of syntax.

Not really brand new, since there already are [[#custom-id]] and
[[*headline]].  Though, I'd favour [[ref:name]], too.

> Suggestion: On export, how about enabling automatic element
> descriptions for references following the type:name convention, so
> that e.g. just
>
> : in [[ref:tab:numbers]] we can see...
>
> would expand to
>
>   in Table 2 we can see...
>
> If implemented, this should be user-customizable e.g. through an alist
> like
>
>   (("fig" . "Figure") ("tab" . "Table") ("map" . "Map"))

That's another possibility, but I'd rather follow LaTeX usage. I think
it gives user more latitude in the end. Indeed, You don't have to think
about a name prefix ; you can also have constructs like "Tables
[[ref:table1]], [[ref:table2]] and [[ref:table3]]" for "Tables 1, 2 and
3", etc.

Note that the behaviour you suggest can easily be implemented using
filters in the new exporter.


Regards,

-- 
Nicolas Goaziou

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

* Re: [dev] Implement "ref" link types
  2012-02-19 19:41 ` Samuel Wales
@ 2012-02-19 20:02   ` Nicolas Goaziou
  2012-02-19 20:48     ` Samuel Wales
  0 siblings, 1 reply; 19+ messages in thread
From: Nicolas Goaziou @ 2012-02-19 20:02 UTC (permalink / raw)
  To: Samuel Wales; +Cc: Org Mode List

Hello,

Samuel Wales <samologist@gmail.com> writes:

> I think it's a good idea, and would suggest this:
>
>   * If it is not going to have features added, then [[ref:asdf]] is OK
>   * If it /is/ going to have features added, then I recommend ES/US
>
> ES/US is extensible syntax / universal syntax, a specific proposal for
> an orthogonal and future-proof syntax for new capabilities like this.

Ok, I found the thread[1] about extensible syntax for links.

I don't think that it would be a good idea to use a completely different
syntax for just one type of link. Either we change the whole link system
into the extensible syntax proposal, or we don't change it at
all. I don't mind either way, but that's orthogonal to the problem at
hand.

For now, I'll assume we keep the classical link syntax.

> For example, you might want to put the target anywhere, not just where
> there are elements.

Org already has targets for that: <<anywhere>> and [[anywhere]].  The
[[ref:element]] link is more interesting for its export effect. Moving
back and forth between it and targeted element is a bonus.


Regards,

[1] http://thread.gmane.org/gmane.emacs.orgmode/11896

-- 
Nicolas Goaziou

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

* Re: [dev] Implement "ref" link types
  2012-02-19 18:08 [dev] Implement "ref" link types Nicolas Goaziou
  2012-02-19 19:28 ` Christian Moe
  2012-02-19 19:41 ` Samuel Wales
@ 2012-02-19 20:10 ` Carsten Dominik
  2012-02-20  0:51   ` Nicolas Goaziou
  2 siblings, 1 reply; 19+ messages in thread
From: Carsten Dominik @ 2012-02-19 20:10 UTC (permalink / raw)
  To: Nicolas Goaziou; +Cc: Org Mode List


On 19.2.2012, at 19:08, Nicolas Goaziou wrote:

> Hello,
> 
> I'd like to introduce a new type of internal links, namely "ref" links.
> 
> Since any element can now have a "#+name: something" affiliated keyword,
> it would be practical to have a way to go straight to that name, from
> anywhere in the buffer. The following patch implements
> a [[ref:something]] syntax, or even [[ref:something][text]] to do so.
> 
> The problem that I see here is that is breaks a bit syntax for internal
> links ("protocol:path" is usually for external links). Another solution
> would be to make them more hermetic: [[!something]].
> 
> On the export side, a "ref" link should be replaced by its description,
> if it has any, or by the sequence number of the matching element among
> elements of the same type. With the new exporter and the following
> buffer:
> 
> #+begin_src org
>  #+name: tab:letters
>  #+caption: Letters
>  | a | b |
>  | c | d |
> 
>  #+name: tab:numbers
>  #+caption: Numbers
>  | 1 |
>  | 2 |
> 
> 
>  In tableau [[ref:tab:numbers]] we can see... Yet, in
>  [[ref:tab:numbers][the same table]], ...
> #+end_src
> 
> the last sentence, in ascii, becomes:
> 
>         In tableau 2 we can see... Yet, in the same table, ...
> 
> 
> Even if it's not a perfect replacement for "\ref{something}" commands,
> it should be sufficient for all major back-ends to provide an
> approximate functionality. And we gain interactivity in the Org buffer.
> 
> What do you think?

Love it!  Why are you saying it is not a full replacement for \ref{something}?
It is better than that because it will work in more backends....

- Carsten

> 
> 
> Regards,
> 
> -- 
> Nicolas Goaziou
> From f92e12a9482613d4b1d27090fac8d2667b094fdb Mon Sep 17 00:00:00 2001
> From: Nicolas Goaziou <n.goaziou@gmail.com>
> Date: Sun, 19 Feb 2012 18:48:41 +0100
> Subject: [PATCH] Implement "ref" internal link type in Org buffers
> 
> * lisp/org.el (org-link-search): Handle "ref" internal link types.
> 
> A [[ref:some-name]] link points to a "#+name: some-name" in the same
> buffer.
> ---
> lisp/org.el |   10 ++++++++++
> 1 files changed, 10 insertions(+), 0 deletions(-)
> 
> diff --git a/lisp/org.el b/lisp/org.el
> index a81f7fc..ea06863 100644
> --- a/lisp/org.el
> +++ b/lisp/org.el
> @@ -9875,6 +9875,16 @@ visibility around point, thus ignoring
>      ;; First check if there are any special search functions
>      ((run-hook-with-args-until-success 'org-execute-file-search-functions s))
>      ;; Now try the builtin stuff
> +     ;; Ref internal link.
> +     ((and (string-match "^ref:\\(.*\\)" s0)
> +	   (let ((name (org-trim (match-string 1 s0))))
> +	     (save-excursion
> +	       (goto-char (point-min))
> +	       (and (re-search-forward
> +		     (format "^[ \t]*#\\+name: %s" name) nil t)
> +		    (setq type 'dedicated pos (match-beginning 0))))))
> +      (goto-char pos))
> +     ;; Custom-id
>      ((and (equal (string-to-char s0) ?#)
> 	   (> (length s0) 1)
> 	   (save-excursion
> -- 
> 1.7.9.1
> 

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

* Re: [dev] Implement "ref" link types
  2012-02-19 19:41   ` Nicolas Goaziou
@ 2012-02-19 20:11     ` Toby Cubitt
  2012-02-19 20:20     ` Christian Moe
  1 sibling, 0 replies; 19+ messages in thread
From: Toby Cubitt @ 2012-02-19 20:11 UTC (permalink / raw)
  To: emacs-orgmode

On Sun, Feb 19, 2012 at 08:41:45PM +0100, Nicolas Goaziou wrote:
> > Suggestion: On export, how about enabling automatic element
> > descriptions for references following the type:name convention, so
> > that e.g. just
> >
> > : in [[ref:tab:numbers]] we can see...
> >
> > would expand to
> >
> >   in Table 2 we can see...
> >
> > If implemented, this should be user-customizable e.g. through an alist
> > like
> >
> >   (("fig" . "Figure") ("tab" . "Table") ("map" . "Map"))
> 
> That's another possibility, but I'd rather follow LaTeX usage. I think
> it gives user more latitude in the end. Indeed, You don't have to think
> about a name prefix ; you can also have constructs like "Tables
> [[ref:table1]], [[ref:table2]] and [[ref:table3]]" for "Tables 1, 2 and
> 3", etc.
> 
> Note that the behaviour you suggest can easily be implemented using
> filters in the new exporter.

Note that for LaTeX export, there's no need to explicitly add names to
references -- LaTeX can figure them out for itself from the label alone,
with a little of help.

There are various CTAN packages implementing this, such as cleveref,
hyperref's \autoref command, varioref's \labelformat command... Cleveref
is arguably the most powerful of these, as you can just chuck references
into a \cref command (which replaces \ref):
\cref{figure1,table1,table3,table2}, and it sorts them all out for you,
to produce "Figure~1, and Tables~1 to~3". (Disclaimer: I'm the author of
cleveref.)

Toby
-- 
Dr T. S. Cubitt
Mathematics and Quantum Information group
Department of Mathematics
Complutense University
Madrid, Spain

email: tsc25@cantab.net
web:   www.dr-qubit.org

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

* Re: [dev] Implement "ref" link types
  2012-02-19 19:41   ` Nicolas Goaziou
  2012-02-19 20:11     ` Toby Cubitt
@ 2012-02-19 20:20     ` Christian Moe
  1 sibling, 0 replies; 19+ messages in thread
From: Christian Moe @ 2012-02-19 20:20 UTC (permalink / raw)
  To: Nicolas Goaziou; +Cc: Org Mode List

On 2/19/12 8:41 PM, Nicolas Goaziou wrote:
>
> That's another possibility, but I'd rather follow LaTeX usage. I think
> it gives user more latitude in the end. Indeed, You don't have to think
> about a name prefix ; you can also have constructs like "Tables
> [[ref:table1]], [[ref:table2]] and [[ref:table3]]" for "Tables 1, 2 and
> 3", etc.

Good points.

> Note that the behaviour you suggest can easily be implemented using
> filters in the new exporter.

Right. I regret not having had the time to play with the new exporter 
and give feedback, it sounds very smart.

Christian

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

* Re: [dev] Implement "ref" link types
  2012-02-19 20:02   ` Nicolas Goaziou
@ 2012-02-19 20:48     ` Samuel Wales
  0 siblings, 0 replies; 19+ messages in thread
From: Samuel Wales @ 2012-02-19 20:48 UTC (permalink / raw)
  To: Nicolas Goaziou; +Cc: Org Mode List

On 2012-02-19, Nicolas Goaziou <n.goaziou@gmail.com> wrote:
> Ok, I found the thread[1] about extensible syntax for links.

Again this isn't just for links and if your syntax does all you ever
anticipate, then I like it.  I am talking about the future and the
difficulty of adding ad-hoc syntax fore new features /later/.

There are a few other threads (just FYI).  I might have them listed someplace.

Overview (also FYI): one concern is syntax creep in Org for new
features.  This affects external parsers and overall complexity and
nonorthogonality, and introduces parsing risk, in which there are many
gotchas -- such as inability to escape, quote, nest, pretty-print,
etc.  ES/US solves all of that in a single, simple way.

If all you're doing is the one set of features now, then your syntax
is great.  But I'm talking about the future.

> I don't think that it would be a good idea to use a completely different
> syntax for just one type of link. Either we change the whole link system

No, it's not for just one type of link.  It applies to new features
also, not just for ref links but for ID markers (links to anything,
even words, using Org ID), very fancy dates that have features that
are too difficult to include in existing date syntax, annotation of
words or paragraphs or elements, maybe fancy detangling, browser-like
link coloring by expiry and cached links, digraphs, undirected graphs
including bidirectional links, super-fancy footnotes, any new feature
we do not currently anticipate for the ref syntax or any other feature
that would create nonorthogonality and complexity in existing syntax,
and many new features we haven't thought of.

It won't replace existing syntax.  It's for new features.

One point is that when we address something (such as nestability) for
one new feature, it works for all others automatically.

> into the extensible syntax proposal, or we don't change it at
> all. I don't mind either way, but that's orthogonal to the problem at
> hand.

Again I think your syntax is great if that is all it is going to do.
All I am doing is raising a possible alternative way of doing it.  If
you don't like it, that's fine.

But my point is that if we only look at the problem at hand, we get
syntax creep -- because new features are not at hand.  Think of how
dates now have to deal with deadlines, repeaters, etc.  That's OK, but
it's going to get harder to add new features to them.  I'm not saying
to replace dates, but for many new features, we might want to try
something more orthogonal and extensible and universal.

>> For example, you might want to put the target anywhere, not just where
>> there are elements.
>
> Org already has targets for that: <<anywhere>> and [[anywhere]].  The

Those do not use the Org ID mechanism, so they are brittle and don't
operate across files in the same way Org IDs can (IIRC -- do they?).

Again it's an example of how the syntax can add features without
making parsing difficult.  This all concerns future features, not
anything today.

Just something to consider.

-- 
The Kafka Pandemic: http://thekafkapandemic.blogspot.com

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

* Re: [dev] Implement "ref" link types
  2012-02-19 20:10 ` Carsten Dominik
@ 2012-02-20  0:51   ` Nicolas Goaziou
  2012-02-20  7:09     ` Carsten Dominik
  0 siblings, 1 reply; 19+ messages in thread
From: Nicolas Goaziou @ 2012-02-20  0:51 UTC (permalink / raw)
  To: Carsten Dominik; +Cc: Org Mode List

Hello,

Carsten Dominik <carsten.dominik@gmail.com> writes:

> Why are you saying it is not a full replacement for \ref{something}?

There are still a few limitations. For example, you cannot reference
a precise list item since items do not accept affiliated keywords.

> It is better than that because it will work in more backends....

Yes, this is a big advantage.


Regards,

-- 
Nicolas Goaziou

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

* Re: [dev] Implement "ref" link types
  2012-02-20  0:51   ` Nicolas Goaziou
@ 2012-02-20  7:09     ` Carsten Dominik
  2012-02-20 10:59       ` Nicolas Goaziou
  0 siblings, 1 reply; 19+ messages in thread
From: Carsten Dominik @ 2012-02-20  7:09 UTC (permalink / raw)
  To: Nicolas Goaziou; +Cc: Org Mode List


On Feb 20, 2012, at 1:51 AM, Nicolas Goaziou wrote:

> Hello,
> 
> Carsten Dominik <carsten.dominik@gmail.com> writes:
> 
>> Why are you saying it is not a full replacement for \ref{something}?
> 
> There are still a few limitations. For example, you cannot reference
> a precise list item since items do not accept affiliated keywords.

Ah, yes, this is right.

Regards

- Carsten

> 
>> It is better than that because it will work in more backends....
> 
> Yes, this is a big advantage.
> 
> 
> Regards,
> 
> -- 
> Nicolas Goaziou

- Carsten

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

* Re: [dev] Implement "ref" link types
  2012-02-20  7:09     ` Carsten Dominik
@ 2012-02-20 10:59       ` Nicolas Goaziou
  2012-02-20 22:06         ` Nicolas Goaziou
  2012-03-05  9:37         ` Jambunathan K
  0 siblings, 2 replies; 19+ messages in thread
From: Nicolas Goaziou @ 2012-02-20 10:59 UTC (permalink / raw)
  To: Carsten Dominik; +Cc: Org Mode List

Hello,

Carsten Dominik <carsten.dominik@gmail.com> writes:

> On Feb 20, 2012, at 1:51 AM, Nicolas Goaziou wrote:

>> There are still a few limitations. For example, you cannot reference
>> a precise list item since items do not accept affiliated keywords.

> Ah, yes, this is right.

Thinking about it, there may exist a better alternative to [[ref:name]]
links: fuzzy links. In other words, "#+name: something" could be made an
alternate of "<<something>>", with a lower priority.

On the Org side, when a link like [[something]] or [[something][text]]
is encountered in a buffer, the search would go on like this:

  1. Search any "<<something>>" or "#+target: something"[1].
  2. If none is found, search any "#+name: something".
  3. If it fails, try to find the headline "* something".
  4. Eventually offer to create such headline. This step doesn't apply
     during export.

On the export side, it depends on the description part of the link:

  - If there's a description (i.e. [[something][description]]), display
    it and link to target if possible, whatever that target is.

  - If there's no description:

    1. A link to an invisible target will be replaced with _nothing_
       (that's the point of being invisible).

    2. A link to a target (i.e. <<something>>) will be replaced with the
       sequence number of the closest item or headline[2]. Examples:

       #+begin_src org
       - item one
       - item two
         - <<here>> item two dot one
       #+end_src

       Any link like [[here]] will be replaced with "2.1" during export.

       #+begin_src org
       * Headline one
       * Headline two
         * Headline two dot one

           Some paragraph.

           Another paragraph <<warning>>.
       #+end_src

       Here [[warning]] will also be replaced with "2.1" during export.
       Note that [[Headline two dot one]] would also be replaced with
       "2.1".

    3. An link to an element (i.e. "#+name: something") would return the
       sequence number of that element among elements of the same type
       with a caption, a name affiliated keyword, or both. Example:

       #+begin_src org
       #+name: letters
       #+caption: I know my alphabet.
       |a|b|c|

       |foo|bar|

       #+name: numbers
       |1|2|3|
       #+end_src

       Here, a [[numbers]] link would be replaced with 2, since middle
       table has no name nor caption.


To sum it up, at a quick glance, I can see the following:

  - Pros ::
    + No new syntax,
    + Possibly number every element, including items.
  - Cons ::
    + Fuzzy links are a bit overloaded, but, on the other hand, linking to
      headlines is not very useful since custom-id and id implementation.
    + There is more documentation to write.

Again, what do you think?


Regards,

[1] This is the replacement for invisible targets, since they cannot
live in comments anymore.

[2] If headlines are not numbered (i.e. num:nil), replace link with
headline's title instead.

-- 
Nicolas Goaziou

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

* Re: [dev] Implement "ref" link types
  2012-02-20 10:59       ` Nicolas Goaziou
@ 2012-02-20 22:06         ` Nicolas Goaziou
  2012-02-21  1:26           ` Thomas S. Dye
  2012-02-21  5:14           ` David Maus
  2012-03-05  9:37         ` Jambunathan K
  1 sibling, 2 replies; 19+ messages in thread
From: Nicolas Goaziou @ 2012-02-20 22:06 UTC (permalink / raw)
  To: Carsten Dominik; +Cc: Org Mode List

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

Completing myself, here is a patch implementing the previous suggestion,
along with example output obtained with it.  You may need to
(fmakunbound 'org-e-ascii-target) to avoid an error, since this patch
removes the function.


First, the test buffer.


#+begin_src org
#+TITLE: Cross-references
#+LANGUAGE: en

* First headline.

  Here we demonstrate cross-references to items.

  1. A first item in a list.
  2. Another item
     1. With three subparts. This one.
     2. Another one.
     3. <<itm:last>> And the last subpart.
        
  We end the list at item [[itm:last]].

  Before we continue, here is a rather trivial equation, assuming base
  isn't too low[fn:1].
  
  #+name: eq:trivial
  \begin{equation}
  1 + 1 = 2
  \end{equation}

  We can verify it with the following code:

  #+name: oneplusone
  #+caption: Shortly after the beginning of arithmetic.
  #+BEGIN_SRC emacs-lisp :exports code
  (+ 1 1)
  #+END_SRC

** Sub-topic

   Here we demonstrate cross-references to tables.<<sec:tables>>

   #+name: tab:numbers
   #+caption: Test
   | one | 1 |
   | two | 2 |

   #+name: tab:letters
   #+caption: Letters
   | a | aille |
   | b | bi    |

   In table [[tab:numbers]] we can only see two numbers.  Yet, in [[tab:numbers][the very
   same table]], we can already tell the radix used isn't too low
   (remember footnote [[fn:basetwo]]?).  On the other hand, table
   [[tab:letters]] shows letters, but that's clearly uninteresting.

   #+name: eq:euler
   \begin{equation}
   e^{i\pi} + 1 = 0
   \end{equation}

   Equation [[eq:euler]], also known as Euler's equation, is remarkable
   unlike to the equation [[eq:trivial]], which is boring (except the
   elisp part, in listing [[oneplusone]]).

   #+target: end
   This is the end of section [[sec:tables]]. [[end][Invisible link to line above]]

* Footnotes

[fn:1] <<fn:basetwo>> That is strictly greater than two.
#+end_src



Then the ASCII output.



#+begin_src text
1 First headline.
=================

  Here we demonstrate cross-references to items.

  1. A first item in a list.
  2. Another item
     1. With three subparts. This one.
     2. Another one.
     3. And the last subpart.

  We end the list at item 2.3.

  Before we continue, here is a rather trivial equation, assuming base
  isn't too low[1].

  \begin{equation}
  1 + 1 = 2
  \end{equation}

  We can verify it with the following code:

  ,----
  | (+ 1 1)
  `----
  Listing 1: Shortly after the beginning of arithmetic.


1.1 Sub-topic
~~~~~~~~~~~~~

  Here we demonstrate cross-references to tables.

   one  1 
   two  2 
  Table 1: Test

   a  aille 
   b  bi    
  Table 2: Letters

  In table 1 we can only see two numbers.  Yet, in the very same table,
  we can already tell the radix used isn't too low (remember footnote
  1?).  On the other hand, table 2 shows letters, but that's clearly
  uninteresting.

  \begin{equation}
  e^{i\pi} + 1 = 0
  \end{equation}

  Equation 2, also known as Euler's equation, is remarkable unlike to
  the equation 1, which is boring (except the elisp part, in listing 1).

  This is the end of section 1.1.
#+end_src



And with LaTeX.



#+begin_src latex
\section{First headline.}
\label{sec-1}

Here we demonstrate cross-references to items.

\begin{enumerate}
\item A first item in a list.
\item Another item
\begin{enumerate}
\item With three subparts. This one.
\item Another one.
\item \label{itm:last} And the last subpart.
\end{enumerate}
\end{enumerate}

We end the list at item \ref{itm:last}.

Before we continue, here is a rather trivial equation, assuming base
isn't too low\footnote{\label{fn:basetwo} That is strictly greater than two.}.

\begin{equation}
\label{eq:trivial}
1 + 1 = 2
\end{equation}

We can verify it with the following code:

\begin{figure}[H]
\caption{\label{oneplusone}Shortly after the beginning of arithmetic.}
\begin{verbatim}
(+ 1 1)
\end{verbatim}
\end{figure}

\subsection{Sub-topic}
\label{sec-1-1}

Here we demonstrate cross-references to tables.\label{sec:tables}

\begin{table}[htb]
\caption{\label{tab:numbers}Test}
\begin{center}
\begin{tabular}{lr}
one & 1 \\
two & 2 \\
\end{tabular}
\end{center}
\end{table}

\begin{table}[htb]
\caption{\label{tab:letters}Letters}
\begin{center}
\begin{tabular}{ll}
a & aille \\
b & bi \\
\end{tabular}
\end{center}
\end{table}

In table \ref{tab:numbers} we can only see two numbers.  Yet, in \hyperref[tab:numbers]{the very
   same table}, we can already tell the radix used isn't too low
(remember footnote \ref{fn:basetwo}?).  On the other hand, table
\ref{tab:letters} shows letters, but that's clearly uninteresting.

\begin{equation}
\label{eq:euler}
e^{i\pi} + 1 = 0
\end{equation}

Equation \ref{eq:euler}, also known as Euler's equation, is remarkable
unlike to the equation \ref{eq:trivial}, which is boring (except the
elisp part, in listing \ref{oneplusone}).

This is the end of section \ref{sec:tables}. 
#+end_src


Regards,

-- 
Nicolas Goaziou

[-- Warning: decoded text below may be mangled, UTF-8 assumed --]
[-- Attachment #2: cross-reference numbers --]
[-- Type: text/x-patch, Size: 22154 bytes --]

From dcae2d1015f958dcb1ed3c92349ad0c2e18a1219 Mon Sep 17 00:00:00 2001
From: Nicolas Goaziou <n.goaziou@gmail.com>
Date: Mon, 20 Feb 2012 22:24:38 +0100
Subject: [PATCH] Implement cross-references numbers

* lisp/org.el (org-link-search): Search for #+name affiliated keywords
  and invisible targets.
* contrib/lisp/org-element.el (org-element-link-parser): Remove "ref"
  links relative part.
(org-element-target-parser): Move property name from `:raw-value' to
`:value'.
(org-element-recursive-objects): Remove targets from tables.  Cells
are not parsed unless explicitely asked by back-end developer, too
late.  A target wouldn't be noticed in time.  One solution could be to
parse every table, but that's time consumming.
(org-element-object-restrictions): Target are not recursive anymore.
* contrib/lisp/org-export.el (org-export-resolve-fuzzy-link): Find
  elements with a matching "#+name: path" affiliated keyword.
(org-export-get-ordinal): Make special cases for headlines, items,
footnotes definitions and references.
(org-export-resolve-ref-link): Removed function.
* EXPERIMENTAL/org-e-latex.el (org-e-latex-link): Handle
  cross-reference numbers.
(org-e-latex-target): Targets have no contents.
* EXPERIMENTAL/org-e-ascii.el (org-e-ascii--describe-links): Ignore
  fuzzy links in link description at the end of the section.
(org-e-ascii-link): Handle cross-reference numbers.
---
 EXPERIMENTAL/org-e-ascii.el |   80 ++++++++-----------
 EXPERIMENTAL/org-e-latex.el |   48 ++++-------
 contrib/lisp/org-element.el |   20 ++---
 contrib/lisp/org-export.el  |  185 ++++++++++++++++++++++++++----------------
 lisp/org.el                 |   16 ++++
 5 files changed, 187 insertions(+), 162 deletions(-)

diff --git a/EXPERIMENTAL/org-e-ascii.el b/EXPERIMENTAL/org-e-ascii.el
index ef1ca1c..1361e23 100644
--- a/EXPERIMENTAL/org-e-ascii.el
+++ b/EXPERIMENTAL/org-e-ascii.el
@@ -826,28 +826,24 @@ channel."
 			 (org-element-get-property :raw-link link)
 		       (org-export-secondary-string desc 'e-ascii info)))))
        (cond
-	;; Coderefs, radio links and ref links are ignored.
-	((member type '("coderef" "radio" "ref")) nil)
-	;; Id, custom-id and fuzzy links (with the exception of
-	;; targets): Headlines refer to their numbering.
-	((member type '("custom-id" "fuzzy" "id"))
-	 (let ((destination (if (string= type "fuzzy")
-				(org-export-resolve-fuzzy-link link info)
-			      (org-export-resolve-id-link link info))))
-	   (unless (eq (car destination) 'target)
-	     (concat
-	      (org-e-ascii--fill-string
-	       (format
-		"[%s] %s"
-		anchor
-		(if (not destination)
-		    (org-e-ascii--translate "Unknown reference" info)
-		  (format
-		   (org-e-ascii--translate "See section %s" info)
-		   (mapconcat 'number-to-string
-			      (org-export-get-headline-number destination info)
-			      "."))))
-	       width info) "\n\n"))))
+	;; Coderefs, radio links and fuzzy links are ignored.
+	((member type '("coderef" "radio" "fuzzy")) nil)
+	;; Id and custom-id links: Headlines refer to their numbering.
+	((member type '("custom-id" "id"))
+	 (let ((destination (org-export-resolve-id-link link info)))
+	   (concat
+	    (org-e-ascii--fill-string
+	     (format
+	      "[%s] %s"
+	      anchor
+	      (if (not destination)
+		  (org-e-ascii--translate "Unknown reference" info)
+		(format
+		 (org-e-ascii--translate "See section %s" info)
+		 (mapconcat 'number-to-string
+			    (org-export-get-headline-number destination info)
+			    "."))))
+	     width info) "\n\n")))
 	;; Do not add a link that cannot be resolved and doesn't have
 	;; any description: destination is already visible in the
 	;; paragraph.
@@ -1392,29 +1388,23 @@ INFO is a plist holding contextual information."
 	(org-element-get-property :path link)
 	(cdr (assq 'radio-target org-element-object-restrictions)))
        'e-ascii info))
-     ;; Ref link: If there's no description (DESC, return link's
-     ;; destination sequence number among elements of same
-     ;; type. Otherwise, use DESC.
-     ((string= type "ref")
-      (if (org-string-nw-p desc) desc
-	(format "%d"
-		(org-export-get-ordinal
-		 (org-export-resolve-ref-link link info)
-		 info nil nil
-		 (lambda (el) (or (org-element-get-property :caption el)
-			     (org-element-get-property :name el)))))))
      ;; Do not apply a special syntax on fuzzy links pointing to
      ;; targets.
-     ((and (string= type "fuzzy")
-	   (let ((path (org-element-get-property :path link)))
-	     (loop for target in (plist-get info :target-list)
-		   thereis (string=
-			    (org-element-get-property :raw-value target)
-			    path))))
-      (if (org-string-nw-p desc) desc raw-link))
+     ((string= type "fuzzy")
+      (let ((destination (org-export-resolve-fuzzy-link link info)))
+	;; Ignore invisible "#+target: path".
+	(unless (eq (car destination) 'keyword)
+	  (if (org-string-nw-p desc) desc
+	    (when destination
+	      (let ((number (org-export-get-ordinal destination info)))
+		(when number
+		  (if (atom number) (number-to-string number)
+		    (mapconcat 'number-to-string number ".")))))))))
      (t
-      (concat (format "[%s]" (if (org-string-nw-p desc) desc raw-link))
-	      (unless org-e-ascii-links-to-notes (format " (%s)" raw-link)))))))
+      (if (not (org-string-nw-p desc)) (format "[%s]" raw-link)
+	(concat
+	 (format "[%s]" desc)
+	 (unless org-e-ascii-links-to-notes (format " (%s)" raw-link))))))))
 
 
 ;;;; Macro
@@ -1852,11 +1842,7 @@ INFO is a plist used as a communication channel."
 
 ;;;; Target
 
-(defun org-e-ascii-target (target contents info)
-  "Transcode a TARGET object from Org to ASCII.
-CONTENTS is the contents of the target.  INFO is a plist holding
-contextual information."
-  contents)
+;; Targets are invisible.
 
 
 ;;;; Time-stamp
diff --git a/EXPERIMENTAL/org-e-latex.el b/EXPERIMENTAL/org-e-latex.el
index eec331a..75b5a9b 100644
--- a/EXPERIMENTAL/org-e-latex.el
+++ b/EXPERIMENTAL/org-e-latex.el
@@ -1266,8 +1266,8 @@ CONTENTS is nil.  INFO is a plist holding contextual information."
     (cond
      ((string= key "latex") value)
      ((string= key "index") (format "\\index{%s}" value))
-     ((string= key "target")
-      (format "\\label{%s}" (org-export-solidify-link-text value)))
+     ;; Invisible targets.
+     ((string= key "target") nil)
      ((string= key "toc")
       (let ((value (downcase value)))
 	(cond
@@ -1426,32 +1426,26 @@ INFO is a plist holding contextual information.  See
 	       (org-element-parse-secondary-string
 		path (cdr (assq 'radio-target org-element-object-restrictions)))
 	       'e-latex info)))
-     ;; Ref link: If no description is provided, reference label PATH
-     ;; and display table number.  Otherwise move to label but display
-     ;; description instead.
-     ((string= type "ref")
-      (if (not desc) (format "\\ref{%s}" path)
-	(format "\\hyperref[%s]{%s}" path desc)))
      ;; Links pointing to an headline: Find destination and build
      ;; appropriate referencing command.
      ((member type '("custom-id" "fuzzy" "id"))
       (let ((destination (if (string= type "fuzzy")
 			     (org-export-resolve-fuzzy-link link info)
 			   (org-export-resolve-id-link link info))))
-	;; Fuzzy link points to a target.  Do as above.
 	(case (car destination)
-	  (target
-	   (format "\\hyperref[%s]{%s}"
-		   (org-export-solidify-link-text
-		    (org-element-get-property :raw-value destination))
+	  ;; Fuzzy link points nowhere.
+	  ('nil
+	   (format "\\texttt{%s}"
 		   (or desc
 		       (org-export-secondary-string
 			(org-element-get-property :raw-link link)
 			'e-latex info))))
-	  ;; Fuzzy link points to an headline.  If headlines are
-	  ;; numbered and the link has no description, display
-	  ;; headline's number.  Otherwise, display description or
-	  ;; headline's title.
+	  ;; Fuzzy link points to an invisible target.
+	  (keyword nil)
+	  ;; LINK points to an headline.  If headlines are numbered
+	  ;; and the link has no description, display headline's
+	  ;; number.  Otherwise, display description or headline's
+	  ;; title.
 	  (headline
 	   (let ((label
 		  (format "sec-%s"
@@ -1466,13 +1460,10 @@ INFO is a plist holding contextual information.  See
 			   (org-export-secondary-string
 			    (org-element-get-property :title destination)
 			    'e-latex info))))))
-	  ;; Fuzzy link points nowhere.
+	;; Fuzzy link points to a target.  Do as above.
 	  (otherwise
-	   (format "\\texttt{%s}"
-		   (or desc
-		       (org-export-secondary-string
-			(org-element-get-property :raw-link link)
-			'e-latex info)))))))
+	   (if (not desc) (format "\\ref{%s}" path)
+	     (format "\\hyperref[%s]{%s}" path desc))))))
      ;; Coderef: replace link with the reference name or the
      ;; equivalent line number.
      ((string= type "coderef")
@@ -1945,14 +1936,11 @@ CONTENTS is nil.  INFO is a plist holding contextual information."
 
 ;;;; Target
 
-(defun org-e-latex-target (target text info)
+(defun org-e-latex-target (target contents info)
   "Transcode a TARGET object from Org to LaTeX.
-TEXT is the text of the target.  INFO is a plist holding
-contextual information."
-  (format "\\label{%s}%s"
-	  (org-export-solidify-link-text
-	   (org-element-get-property :raw-value target))
-	  text))
+CONTENTS is nil.  INFO is a plist holding contextual
+information."
+  (format "\\label{%s}" (org-element-get-property :value target)))
 
 
 ;;;; Time-stamp
diff --git a/contrib/lisp/org-element.el b/contrib/lisp/org-element.el
index 5b61942..554537e 100644
--- a/contrib/lisp/org-element.el
+++ b/contrib/lisp/org-element.el
@@ -1961,9 +1961,6 @@ Assume point is at the beginning of the link."
 	 ;; Explicit type (http, irc, bbdb...).  See `org-link-types'.
 	 ((string-match org-link-re-with-space3 link)
 	  (setq type (match-string 1 link) path (match-string 2 link)))
-	 ;; Ref type: PATH is the name of the target element.
-	 ((string-match "^ref:\\(.*\\)" link)
-	  (setq type "ref" path (org-trim (match-string 1 link))))
 	 ;; Id type: PATH is the id.
 	 ((string-match "^id:\\([-a-f0-9]+\\)" link)
 	  (setq type "id" path (match-string 1 link)))
@@ -2265,25 +2262,21 @@ CONTENTS is the contents of the object."
   "Parse target at point.
 
 Return a list whose car is `target' and cdr a plist with
-`:begin', `:end', `:contents-begin', `:contents-end', `raw-value'
-and `:post-blank' as keywords.
+`:begin', `:end', `:contents-begin', `:contents-end', `value' and
+`:post-blank' as keywords.
 
 Assume point is at the target."
   (save-excursion
     (looking-at org-target-regexp)
     (let ((begin (point))
-	  (contents-begin (match-beginning 1))
-	  (contents-end (match-end 1))
-	  (raw-value (org-match-string-no-properties 1))
+	  (value (org-match-string-no-properties 1))
 	  (post-blank (progn (goto-char (match-end 0))
 			     (skip-chars-forward " \t")))
 	  (end (point)))
       `(target
 	(:begin ,begin
 		:end ,end
-		:contents-begin ,contents-begin
-		:contents-end ,contents-end
-		:raw-value ,raw-value
+		:value ,value
 		:post-blank ,post-blank)))))
 
 (defun org-element-target-interpreter (target contents)
@@ -2470,7 +2463,7 @@ Sharing the same successor comes handy when, for example, the
 regexp matching one object can also match the other object.")
 
 (defconst org-element-recursive-objects
-  '(emphasis link macro subscript superscript target radio-target)
+  '(emphasis link macro subscript superscript radio-target)
   "List of recursive object types.")
 
 (defconst org-element-non-recursive-block-alist
@@ -2540,8 +2533,7 @@ This list is checked after translations have been applied.  See
     (subscript entity export-snippet inline-babel-call inline-src-block
 	       latex-fragment sub/superscript text-markup)
     (superscript entity export-snippet inline-babel-call inline-src-block
-		 latex-fragment sub/superscript text-markup)
-    (target entity export-snippet latex-fragment sub/superscript text-markup))
+		 latex-fragment sub/superscript text-markup))
   "Alist of recursive objects restrictions.
 
 CAR is a recursive object type and CDR is a list of successors
diff --git a/contrib/lisp/org-export.el b/contrib/lisp/org-export.el
index 34f290e..aa6ca52 100644
--- a/contrib/lisp/org-export.el
+++ b/contrib/lisp/org-export.el
@@ -1278,7 +1278,13 @@ Following tree properties are set:
    `(:parse-tree
      ,data
      :target-list
-     ,(org-element-map data 'target (lambda (target local) target) info)
+     ,(org-element-map
+       data '(keyword target)
+       (lambda (blob local)
+	 (when (or (eq (car blob) 'target)
+		   (string= (downcase (org-element-get-property :key blob))
+			    "target"))
+	   blob)) info)
      :headline-numbering ,(org-export-collect-headline-numbering data info)
      :back-end ,backend)
    info))
@@ -2579,8 +2585,11 @@ INFO is a plist holding contextual information.
 
 Return value can be an object, an element, or nil:
 
-- If LINK path exactly matches any target, return the target
-  object.
+- If LINK path matches a target object (i.e. <<path>>) or
+  element (i.e. \"#+target: path\"), return it.
+
+- If LINK path exactly matches the name affiliated keyword
+  \(i.e. #+name: path) of an element, return that element.
 
 - If LINK path exactly matches any headline name, return that
   element.  If more than one headline share that name, priority
@@ -2591,39 +2600,53 @@ Return value can be an object, an element, or nil:
 
 Assume LINK type is \"fuzzy\"."
   (let ((path (org-element-get-property :path link)))
-    ;; Link points to a target: return it.
-    (or (loop for target in (plist-get info :target-list)
-	      when (string= (org-element-get-property :raw-value target) path)
-	      return target)
-	;; Link either points to an headline or nothing.  Try to find
-	;; the source, with priority given to headlines with the closest
-	;; common ancestor.  If such candidate is found, return its
-	;; beginning position as an unique identifier, otherwise return
-	;; nil.
-	(let ((find-headline
-	       (function
-		;; Return first headline whose `:raw-value' property
-		;; is NAME in parse tree DATA, or nil.
-		(lambda (name data)
-		  (org-element-map
-		   data 'headline
-		   (lambda (headline local)
-		     (when (string=
-			    (org-element-get-property :raw-value headline)
-			    name)
-		       headline))
-		   info 'first-match)))))
-	  ;; Search among headlines sharing an ancestor with link,
-	  ;; from closest to farthest.
-	  (or (catch 'exit
-		(mapc
-		 (lambda (parent)
-		   (when (eq (car parent) 'headline)
-		     (let ((foundp (funcall find-headline path parent)))
-		       (when foundp (throw 'exit foundp)))))
-		 (plist-get info :genealogy)) nil)
-	      ;; No match with a common ancestor: try the full parse-tree.
-	      (funcall find-headline path (plist-get info :parse-tree)))))))
+    (cond
+     ;; First try to find a matching "<<path>>" unless user specified
+     ;; he was looking for an headline (path starts with a *
+     ;; character).
+     ((and (not (eq (substring path 0 1) ?*))
+	   (loop for target in (plist-get info :target-list)
+		 when (string= (org-element-get-property :value target) path)
+		 return target)))
+     ;; Then try to find an element with a matching "#+name: path"
+     ;; affiliated keyword.
+     ((and (not (eq (substring path 0 1) ?*))
+	   (org-element-map
+	    (plist-get info :parse-tree) org-element-all-elements
+	    (lambda (el local)
+	      (when (string= (org-element-get-property :name el) path) el))
+	    info 'first-match)))
+     ;; Last case: link either points to an headline or to
+     ;; nothingness.  Try to find the source, with priority given to
+     ;; headlines with the closest common ancestor.  If such candidate
+     ;; is found, return its beginning position as an unique
+     ;; identifier, otherwise return nil.
+     (t
+      (let ((find-headline
+	     (function
+	      ;; Return first headline whose `:raw-value' property is
+	      ;; NAME in parse tree DATA, or nil.
+	      (lambda (name data)
+		(org-element-map
+		 data 'headline
+		 (lambda (headline local)
+		   (when (string=
+			  (org-element-get-property :raw-value headline)
+			  name)
+		     headline))
+		 info 'first-match)))))
+	;; Search among headlines sharing an ancestor with link, from
+	;; closest to farthest.
+	(or (catch 'exit
+	      (mapc
+	       (lambda (parent)
+		 (when (eq (car parent) 'headline)
+		   (let ((foundp (funcall find-headline path parent)))
+		     (when foundp (throw 'exit foundp)))))
+	       (plist-get info :genealogy)) nil)
+	    ;; No match with a common ancestor: try the full
+	    ;; parse-tree.
+	    (funcall find-headline path (plist-get info :parse-tree))))))))
 
 (defun org-export-resolve-id-link (link info)
   "Return headline referenced as LINK destination.
@@ -2641,20 +2664,6 @@ is either \"id\" or \"custom-id\"."
          headline))
      info 'first-match)))
 
-(defun org-export-resolve-ref-link (link info)
-  "Return element referenced as LINK destination.
-
-INFO is a plist used as a communication channel.
-
-Assume LINK type is \"ref\" and.  Return value is the first
-element whose `:name' property matches LINK's `:path', or nil."
-  (let ((name (org-element-get-property :path link)))
-    (org-element-map
-     (plist-get info :parse-tree) org-element-all-elements
-     (lambda (el local)
-       (when (string= (org-element-get-property :name el) name) el))
-     info 'first-match)))
-
 (defun org-export-resolve-coderef (ref info)
   "Resolve a code reference REF.
 
@@ -2745,27 +2754,61 @@ Optional argument PREDICATE is a function returning a non-nil
 value if the current element or object should be counted in.  It
 accepts one argument: the element or object being considered.
 This argument allows to count only a certain type of objects,
-like inline images, which are a subset of links \(in that case,
-`org-export-inline-image-p' might be an useful predicate\)."
-  (let ((counter 0)
-        ;; Determine if search should apply to current section, in
-        ;; which case it should be retrieved first, or to full parse
-        ;; tree.  As a special case, an element or object without
-        ;; a parent headline will also trigger a full search,
-        ;; notwithstanding WITHIN-SECTION value.
-        (data
-         (if (not within-section) (plist-get info :parse-tree)
-	   (or (org-export-get-parent-headline element info)
-	       (plist-get info :parse-tree)))))
-    ;; Increment counter until ELEMENT is found again.
-    (org-element-map
-     data (or types (car element))
-     (lambda (el local)
-       (cond
-        ((equal element el) (1+ counter))
-	((not predicate) (incf counter) nil)
-	((funcall predicate el) (incf counter) nil)))
-     info 'first-match)))
+like inline images, which are a subset of links (in that case,
+`org-export-inline-image-p' might be an useful predicate).
+
+Return value is a list of numbers if ELEMENT is an headline or an
+item.  It is nil for keywords.  It represents the footnote number
+for footnote definitions and footnote references.  If ELEMENT is
+a target, return the same value as if ELEMENT was the closest
+table, item or headline containing the target.  In any other
+case, return the sequence number of ELEMENT among elements or
+objects of the same type."
+  ;; A target keyword, representing an invisible target, never has
+  ;; a sequence number.
+  (unless (eq (car element) 'keyword)
+    ;; Ordinal of a target object is the ordinal of the closest table,
+    ;; item, or headline containing the object.
+    (when (eq (car element) 'target)
+      (setq element
+	    (loop for parent in (org-export-get-genealogy element info)
+		  when
+		  (memq
+		   (car parent)
+		   '(footnote-definition footnote-reference headline item table))
+		  return parent)))
+    (case (car element)
+      ;; Special case 1: An headline returns its number as a list.
+      (headline (org-export-get-headline-number element info))
+      ;; Special case 2: An item returns its number as a list.
+      (item (let ((struct (org-element-get-property :structure element)))
+	      (org-list-get-item-number
+	       (org-element-get-property :begin element)
+	       struct
+	       (org-list-prevs-alist struct)
+	       (org-list-parents-alist struct))))
+      ((footnote definition footnote-reference)
+       (org-export-get-footnote-number element info))
+      (otherwise
+       (let ((counter 0)
+	     ;; Determine if search should apply to current section,
+	     ;; in which case it should be retrieved first, or to full
+	     ;; parse tree.  As a special case, an element or object
+	     ;; without a parent headline will also trigger a full
+	     ;; search, notwithstanding WITHIN-SECTION value.
+	     (data
+	      (if (not within-section) (plist-get info :parse-tree)
+		(or (org-export-get-parent-headline element info)
+		    (plist-get info :parse-tree)))))
+	 ;; Increment counter until ELEMENT is found again.
+	 (org-element-map
+	  data (or types (car element))
+	  (lambda (el local)
+	    (cond
+	     ((equal element el) (1+ counter))
+	     ((not predicate) (incf counter) nil)
+	     ((funcall predicate el) (incf counter) nil)))
+	  info 'first-match))))))
 
 
 ;;;; For Src-Blocks
diff --git a/lisp/org.el b/lisp/org.el
index a81f7fc..6708801 100644
--- a/lisp/org.el
+++ b/lisp/org.el
@@ -9896,6 +9896,22 @@ visibility around point, thus ignoring
 	       pos (match-beginning 0))))
       ;; There is an exact target for this
       (goto-char pos))
+     ((save-excursion
+	(goto-char (point-min))
+	(and
+	 (re-search-forward
+	  (format "^[ \t]*#\\+target: %s" (regexp-quote s0)) nil t)
+	 (setq type 'dedicated pos (match-beginning 0))))
+      ;; Found an invisible target.
+      (goto-char pos))
+     ((save-excursion
+	(goto-char (point-min))
+	(and
+	 (re-search-forward
+	  (format "^[ \t]*#\\+name: %s" (regexp-quote s0)) nil t)
+	 (setq type 'dedicated pos (match-beginning 0))))
+      ;; Found an element with a matching name.
+      (goto-char pos))
      ((and (string-match "^(\\(.*\\))$" s0)
 	   (save-excursion
 	     (goto-char (point-min))
-- 
1.7.9.1


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

* Re: [dev] Implement "ref" link types
  2012-02-20 22:06         ` Nicolas Goaziou
@ 2012-02-21  1:26           ` Thomas S. Dye
  2012-02-21  5:14           ` David Maus
  1 sibling, 0 replies; 19+ messages in thread
From: Thomas S. Dye @ 2012-02-21  1:26 UTC (permalink / raw)
  To: Nicolas Goaziou; +Cc: Org Mode List, Carsten Dominik

Nice!

Nicolas Goaziou <n.goaziou@gmail.com> writes:

> Completing myself, here is a patch implementing the previous suggestion,
> along with example output obtained with it.  You may need to
> (fmakunbound 'org-e-ascii-target) to avoid an error, since this patch
> removes the function.
>
>
> First, the test buffer.
>
>
> #+begin_src org
> #+TITLE: Cross-references
> #+LANGUAGE: en
>
> * First headline.
>
>   Here we demonstrate cross-references to items.
>
>   1. A first item in a list.
>   2. Another item
>      1. With three subparts. This one.
>      2. Another one.
>      3. <<itm:last>> And the last subpart.
>         
>   We end the list at item [[itm:last]].
>
>   Before we continue, here is a rather trivial equation, assuming base
>   isn't too low[fn:1].
>   
>   #+name: eq:trivial
>   \begin{equation}
>   1 + 1 = 2
>   \end{equation}
>
>   We can verify it with the following code:
>
>   #+name: oneplusone
>   #+caption: Shortly after the beginning of arithmetic.
>   #+BEGIN_SRC emacs-lisp :exports code
>   (+ 1 1)
>   #+END_SRC
>
> ** Sub-topic
>
>    Here we demonstrate cross-references to tables.<<sec:tables>>
>
>    #+name: tab:numbers
>    #+caption: Test
>    | one | 1 |
>    | two | 2 |
>
>    #+name: tab:letters
>    #+caption: Letters
>    | a | aille |
>    | b | bi    |
>
>    In table [[tab:numbers]] we can only see two numbers.  Yet, in [[tab:numbers][the very
>    same table]], we can already tell the radix used isn't too low
>    (remember footnote [[fn:basetwo]]?).  On the other hand, table
>    [[tab:letters]] shows letters, but that's clearly uninteresting.
>
>    #+name: eq:euler
>    \begin{equation}
>    e^{i\pi} + 1 = 0
>    \end{equation}
>
>    Equation [[eq:euler]], also known as Euler's equation, is remarkable
>    unlike to the equation [[eq:trivial]], which is boring (except the
>    elisp part, in listing [[oneplusone]]).
>
>    #+target: end
>    This is the end of section [[sec:tables]]. [[end][Invisible link to line above]]
>
> * Footnotes
>
> [fn:1] <<fn:basetwo>> That is strictly greater than two.
> #+end_src
>
>
>
> Then the ASCII output.
>
>
>
> #+begin_src text
> 1 First headline.
> =================
>
>   Here we demonstrate cross-references to items.
>
>   1. A first item in a list.
>   2. Another item
>      1. With three subparts. This one.
>      2. Another one.
>      3. And the last subpart.
>
>   We end the list at item 2.3.
>
>   Before we continue, here is a rather trivial equation, assuming base
>   isn't too low[1].
>
>   \begin{equation}
>   1 + 1 = 2
>   \end{equation}
>
>   We can verify it with the following code:
>
>   ,----
>   | (+ 1 1)
>   `----
>   Listing 1: Shortly after the beginning of arithmetic.
>
>
> 1.1 Sub-topic
> ~~~~~~~~~~~~~
>
>   Here we demonstrate cross-references to tables.
>
>    one  1 
>    two  2 
>   Table 1: Test
>
>    a  aille 
>    b  bi    
>   Table 2: Letters
>
>   In table 1 we can only see two numbers.  Yet, in the very same table,
>   we can already tell the radix used isn't too low (remember footnote
>   1?).  On the other hand, table 2 shows letters, but that's clearly
>   uninteresting.
>
>   \begin{equation}
>   e^{i\pi} + 1 = 0
>   \end{equation}
>
>   Equation 2, also known as Euler's equation, is remarkable unlike to
>   the equation 1, which is boring (except the elisp part, in listing 1).
>
>   This is the end of section 1.1.
> #+end_src
>
>
>
> And with LaTeX.
>
>
>
> #+begin_src latex
> \section{First headline.}
> \label{sec-1}
>
> Here we demonstrate cross-references to items.
>
> \begin{enumerate}
> \item A first item in a list.
> \item Another item
> \begin{enumerate}
> \item With three subparts. This one.
> \item Another one.
> \item \label{itm:last} And the last subpart.
> \end{enumerate}
> \end{enumerate}
>
> We end the list at item \ref{itm:last}.
>
> Before we continue, here is a rather trivial equation, assuming base
> isn't too low\footnote{\label{fn:basetwo} That is strictly greater than two.}.
>
> \begin{equation}
> \label{eq:trivial}
> 1 + 1 = 2
> \end{equation}
>
> We can verify it with the following code:
>
> \begin{figure}[H]
> \caption{\label{oneplusone}Shortly after the beginning of arithmetic.}
> \begin{verbatim}
> (+ 1 1)
> \end{verbatim}
> \end{figure}
>
> \subsection{Sub-topic}
> \label{sec-1-1}
>
> Here we demonstrate cross-references to tables.\label{sec:tables}
>
> \begin{table}[htb]
> \caption{\label{tab:numbers}Test}
> \begin{center}
> \begin{tabular}{lr}
> one & 1 \\
> two & 2 \\
> \end{tabular}
> \end{center}
> \end{table}
>
> \begin{table}[htb]
> \caption{\label{tab:letters}Letters}
> \begin{center}
> \begin{tabular}{ll}
> a & aille \\
> b & bi \\
> \end{tabular}
> \end{center}
> \end{table}
>
> In table \ref{tab:numbers} we can only see two numbers.  Yet, in \hyperref[tab:numbers]{the very
>    same table}, we can already tell the radix used isn't too low
> (remember footnote \ref{fn:basetwo}?).  On the other hand, table
> \ref{tab:letters} shows letters, but that's clearly uninteresting.
>
> \begin{equation}
> \label{eq:euler}
> e^{i\pi} + 1 = 0
> \end{equation}
>
> Equation \ref{eq:euler}, also known as Euler's equation, is remarkable
> unlike to the equation \ref{eq:trivial}, which is boring (except the
> elisp part, in listing \ref{oneplusone}).
>
> This is the end of section \ref{sec:tables}. 
> #+end_src
>
>
> Regards,
>
> -- 
> Nicolas Goaziou
> From dcae2d1015f958dcb1ed3c92349ad0c2e18a1219 Mon Sep 17 00:00:00 2001
> From: Nicolas Goaziou <n.goaziou@gmail.com>
> Date: Mon, 20 Feb 2012 22:24:38 +0100
> Subject: [PATCH] Implement cross-references numbers
>
> * lisp/org.el (org-link-search): Search for #+name affiliated keywords
>   and invisible targets.
> * contrib/lisp/org-element.el (org-element-link-parser): Remove "ref"
>   links relative part.
> (org-element-target-parser): Move property name from `:raw-value' to
> `:value'.
> (org-element-recursive-objects): Remove targets from tables.  Cells
> are not parsed unless explicitely asked by back-end developer, too
> late.  A target wouldn't be noticed in time.  One solution could be to
> parse every table, but that's time consumming.
> (org-element-object-restrictions): Target are not recursive anymore.
> * contrib/lisp/org-export.el (org-export-resolve-fuzzy-link): Find
>   elements with a matching "#+name: path" affiliated keyword.
> (org-export-get-ordinal): Make special cases for headlines, items,
> footnotes definitions and references.
> (org-export-resolve-ref-link): Removed function.
> * EXPERIMENTAL/org-e-latex.el (org-e-latex-link): Handle
>   cross-reference numbers.
> (org-e-latex-target): Targets have no contents.
> * EXPERIMENTAL/org-e-ascii.el (org-e-ascii--describe-links): Ignore
>   fuzzy links in link description at the end of the section.
> (org-e-ascii-link): Handle cross-reference numbers.
> ---
>  EXPERIMENTAL/org-e-ascii.el |   80 ++++++++-----------
>  EXPERIMENTAL/org-e-latex.el |   48 ++++-------
>  contrib/lisp/org-element.el |   20 ++---
>  contrib/lisp/org-export.el  |  185 ++++++++++++++++++++++++++----------------
>  lisp/org.el                 |   16 ++++
>  5 files changed, 187 insertions(+), 162 deletions(-)
>
> diff --git a/EXPERIMENTAL/org-e-ascii.el b/EXPERIMENTAL/org-e-ascii.el
> index ef1ca1c..1361e23 100644
> --- a/EXPERIMENTAL/org-e-ascii.el
> +++ b/EXPERIMENTAL/org-e-ascii.el
> @@ -826,28 +826,24 @@ channel."
>  			 (org-element-get-property :raw-link link)
>  		       (org-export-secondary-string desc 'e-ascii info)))))
>         (cond
> -	;; Coderefs, radio links and ref links are ignored.
> -	((member type '("coderef" "radio" "ref")) nil)
> -	;; Id, custom-id and fuzzy links (with the exception of
> -	;; targets): Headlines refer to their numbering.
> -	((member type '("custom-id" "fuzzy" "id"))
> -	 (let ((destination (if (string= type "fuzzy")
> -				(org-export-resolve-fuzzy-link link info)
> -			      (org-export-resolve-id-link link info))))
> -	   (unless (eq (car destination) 'target)
> -	     (concat
> -	      (org-e-ascii--fill-string
> -	       (format
> -		"[%s] %s"
> -		anchor
> -		(if (not destination)
> -		    (org-e-ascii--translate "Unknown reference" info)
> -		  (format
> -		   (org-e-ascii--translate "See section %s" info)
> -		   (mapconcat 'number-to-string
> -			      (org-export-get-headline-number destination info)
> -			      "."))))
> -	       width info) "\n\n"))))
> +	;; Coderefs, radio links and fuzzy links are ignored.
> +	((member type '("coderef" "radio" "fuzzy")) nil)
> +	;; Id and custom-id links: Headlines refer to their numbering.
> +	((member type '("custom-id" "id"))
> +	 (let ((destination (org-export-resolve-id-link link info)))
> +	   (concat
> +	    (org-e-ascii--fill-string
> +	     (format
> +	      "[%s] %s"
> +	      anchor
> +	      (if (not destination)
> +		  (org-e-ascii--translate "Unknown reference" info)
> +		(format
> +		 (org-e-ascii--translate "See section %s" info)
> +		 (mapconcat 'number-to-string
> +			    (org-export-get-headline-number destination info)
> +			    "."))))
> +	     width info) "\n\n")))
>  	;; Do not add a link that cannot be resolved and doesn't have
>  	;; any description: destination is already visible in the
>  	;; paragraph.
> @@ -1392,29 +1388,23 @@ INFO is a plist holding contextual information."
>  	(org-element-get-property :path link)
>  	(cdr (assq 'radio-target org-element-object-restrictions)))
>         'e-ascii info))
> -     ;; Ref link: If there's no description (DESC, return link's
> -     ;; destination sequence number among elements of same
> -     ;; type. Otherwise, use DESC.
> -     ((string= type "ref")
> -      (if (org-string-nw-p desc) desc
> -	(format "%d"
> -		(org-export-get-ordinal
> -		 (org-export-resolve-ref-link link info)
> -		 info nil nil
> -		 (lambda (el) (or (org-element-get-property :caption el)
> -			     (org-element-get-property :name el)))))))
>       ;; Do not apply a special syntax on fuzzy links pointing to
>       ;; targets.
> -     ((and (string= type "fuzzy")
> -	   (let ((path (org-element-get-property :path link)))
> -	     (loop for target in (plist-get info :target-list)
> -		   thereis (string=
> -			    (org-element-get-property :raw-value target)
> -			    path))))
> -      (if (org-string-nw-p desc) desc raw-link))
> +     ((string= type "fuzzy")
> +      (let ((destination (org-export-resolve-fuzzy-link link info)))
> +	;; Ignore invisible "#+target: path".
> +	(unless (eq (car destination) 'keyword)
> +	  (if (org-string-nw-p desc) desc
> +	    (when destination
> +	      (let ((number (org-export-get-ordinal destination info)))
> +		(when number
> +		  (if (atom number) (number-to-string number)
> +		    (mapconcat 'number-to-string number ".")))))))))
>       (t
> -      (concat (format "[%s]" (if (org-string-nw-p desc) desc raw-link))
> -	      (unless org-e-ascii-links-to-notes (format " (%s)" raw-link)))))))
> +      (if (not (org-string-nw-p desc)) (format "[%s]" raw-link)
> +	(concat
> +	 (format "[%s]" desc)
> +	 (unless org-e-ascii-links-to-notes (format " (%s)" raw-link))))))))
>  
>  
>  ;;;; Macro
> @@ -1852,11 +1842,7 @@ INFO is a plist used as a communication channel."
>  
>  ;;;; Target
>  
> -(defun org-e-ascii-target (target contents info)
> -  "Transcode a TARGET object from Org to ASCII.
> -CONTENTS is the contents of the target.  INFO is a plist holding
> -contextual information."
> -  contents)
> +;; Targets are invisible.
>  
>  
>  ;;;; Time-stamp
> diff --git a/EXPERIMENTAL/org-e-latex.el b/EXPERIMENTAL/org-e-latex.el
> index eec331a..75b5a9b 100644
> --- a/EXPERIMENTAL/org-e-latex.el
> +++ b/EXPERIMENTAL/org-e-latex.el
> @@ -1266,8 +1266,8 @@ CONTENTS is nil.  INFO is a plist holding contextual information."
>      (cond
>       ((string= key "latex") value)
>       ((string= key "index") (format "\\index{%s}" value))
> -     ((string= key "target")
> -      (format "\\label{%s}" (org-export-solidify-link-text value)))
> +     ;; Invisible targets.
> +     ((string= key "target") nil)
>       ((string= key "toc")
>        (let ((value (downcase value)))
>  	(cond
> @@ -1426,32 +1426,26 @@ INFO is a plist holding contextual information.  See
>  	       (org-element-parse-secondary-string
>  		path (cdr (assq 'radio-target org-element-object-restrictions)))
>  	       'e-latex info)))
> -     ;; Ref link: If no description is provided, reference label PATH
> -     ;; and display table number.  Otherwise move to label but display
> -     ;; description instead.
> -     ((string= type "ref")
> -      (if (not desc) (format "\\ref{%s}" path)
> -	(format "\\hyperref[%s]{%s}" path desc)))
>       ;; Links pointing to an headline: Find destination and build
>       ;; appropriate referencing command.
>       ((member type '("custom-id" "fuzzy" "id"))
>        (let ((destination (if (string= type "fuzzy")
>  			     (org-export-resolve-fuzzy-link link info)
>  			   (org-export-resolve-id-link link info))))
> -	;; Fuzzy link points to a target.  Do as above.
>  	(case (car destination)
> -	  (target
> -	   (format "\\hyperref[%s]{%s}"
> -		   (org-export-solidify-link-text
> -		    (org-element-get-property :raw-value destination))
> +	  ;; Fuzzy link points nowhere.
> +	  ('nil
> +	   (format "\\texttt{%s}"
>  		   (or desc
>  		       (org-export-secondary-string
>  			(org-element-get-property :raw-link link)
>  			'e-latex info))))
> -	  ;; Fuzzy link points to an headline.  If headlines are
> -	  ;; numbered and the link has no description, display
> -	  ;; headline's number.  Otherwise, display description or
> -	  ;; headline's title.
> +	  ;; Fuzzy link points to an invisible target.
> +	  (keyword nil)
> +	  ;; LINK points to an headline.  If headlines are numbered
> +	  ;; and the link has no description, display headline's
> +	  ;; number.  Otherwise, display description or headline's
> +	  ;; title.
>  	  (headline
>  	   (let ((label
>  		  (format "sec-%s"
> @@ -1466,13 +1460,10 @@ INFO is a plist holding contextual information.  See
>  			   (org-export-secondary-string
>  			    (org-element-get-property :title destination)
>  			    'e-latex info))))))
> -	  ;; Fuzzy link points nowhere.
> +	;; Fuzzy link points to a target.  Do as above.
>  	  (otherwise
> -	   (format "\\texttt{%s}"
> -		   (or desc
> -		       (org-export-secondary-string
> -			(org-element-get-property :raw-link link)
> -			'e-latex info)))))))
> +	   (if (not desc) (format "\\ref{%s}" path)
> +	     (format "\\hyperref[%s]{%s}" path desc))))))
>       ;; Coderef: replace link with the reference name or the
>       ;; equivalent line number.
>       ((string= type "coderef")
> @@ -1945,14 +1936,11 @@ CONTENTS is nil.  INFO is a plist holding contextual information."
>  
>  ;;;; Target
>  
> -(defun org-e-latex-target (target text info)
> +(defun org-e-latex-target (target contents info)
>    "Transcode a TARGET object from Org to LaTeX.
> -TEXT is the text of the target.  INFO is a plist holding
> -contextual information."
> -  (format "\\label{%s}%s"
> -	  (org-export-solidify-link-text
> -	   (org-element-get-property :raw-value target))
> -	  text))
> +CONTENTS is nil.  INFO is a plist holding contextual
> +information."
> +  (format "\\label{%s}" (org-element-get-property :value target)))
>  
>  
>  ;;;; Time-stamp
> diff --git a/contrib/lisp/org-element.el b/contrib/lisp/org-element.el
> index 5b61942..554537e 100644
> --- a/contrib/lisp/org-element.el
> +++ b/contrib/lisp/org-element.el
> @@ -1961,9 +1961,6 @@ Assume point is at the beginning of the link."
>  	 ;; Explicit type (http, irc, bbdb...).  See `org-link-types'.
>  	 ((string-match org-link-re-with-space3 link)
>  	  (setq type (match-string 1 link) path (match-string 2 link)))
> -	 ;; Ref type: PATH is the name of the target element.
> -	 ((string-match "^ref:\\(.*\\)" link)
> -	  (setq type "ref" path (org-trim (match-string 1 link))))
>  	 ;; Id type: PATH is the id.
>  	 ((string-match "^id:\\([-a-f0-9]+\\)" link)
>  	  (setq type "id" path (match-string 1 link)))
> @@ -2265,25 +2262,21 @@ CONTENTS is the contents of the object."
>    "Parse target at point.
>  
>  Return a list whose car is `target' and cdr a plist with
> -`:begin', `:end', `:contents-begin', `:contents-end', `raw-value'
> -and `:post-blank' as keywords.
> +`:begin', `:end', `:contents-begin', `:contents-end', `value' and
> +`:post-blank' as keywords.
>  
>  Assume point is at the target."
>    (save-excursion
>      (looking-at org-target-regexp)
>      (let ((begin (point))
> -	  (contents-begin (match-beginning 1))
> -	  (contents-end (match-end 1))
> -	  (raw-value (org-match-string-no-properties 1))
> +	  (value (org-match-string-no-properties 1))
>  	  (post-blank (progn (goto-char (match-end 0))
>  			     (skip-chars-forward " \t")))
>  	  (end (point)))
>        `(target
>  	(:begin ,begin
>  		:end ,end
> -		:contents-begin ,contents-begin
> -		:contents-end ,contents-end
> -		:raw-value ,raw-value
> +		:value ,value
>  		:post-blank ,post-blank)))))
>  
>  (defun org-element-target-interpreter (target contents)
> @@ -2470,7 +2463,7 @@ Sharing the same successor comes handy when, for example, the
>  regexp matching one object can also match the other object.")
>  
>  (defconst org-element-recursive-objects
> -  '(emphasis link macro subscript superscript target radio-target)
> +  '(emphasis link macro subscript superscript radio-target)
>    "List of recursive object types.")
>  
>  (defconst org-element-non-recursive-block-alist
> @@ -2540,8 +2533,7 @@ This list is checked after translations have been applied.  See
>      (subscript entity export-snippet inline-babel-call inline-src-block
>  	       latex-fragment sub/superscript text-markup)
>      (superscript entity export-snippet inline-babel-call inline-src-block
> -		 latex-fragment sub/superscript text-markup)
> -    (target entity export-snippet latex-fragment sub/superscript text-markup))
> +		 latex-fragment sub/superscript text-markup))
>    "Alist of recursive objects restrictions.
>  
>  CAR is a recursive object type and CDR is a list of successors
> diff --git a/contrib/lisp/org-export.el b/contrib/lisp/org-export.el
> index 34f290e..aa6ca52 100644
> --- a/contrib/lisp/org-export.el
> +++ b/contrib/lisp/org-export.el
> @@ -1278,7 +1278,13 @@ Following tree properties are set:
>     `(:parse-tree
>       ,data
>       :target-list
> -     ,(org-element-map data 'target (lambda (target local) target) info)
> +     ,(org-element-map
> +       data '(keyword target)
> +       (lambda (blob local)
> +	 (when (or (eq (car blob) 'target)
> +		   (string= (downcase (org-element-get-property :key blob))
> +			    "target"))
> +	   blob)) info)
>       :headline-numbering ,(org-export-collect-headline-numbering data info)
>       :back-end ,backend)
>     info))
> @@ -2579,8 +2585,11 @@ INFO is a plist holding contextual information.
>  
>  Return value can be an object, an element, or nil:
>  
> -- If LINK path exactly matches any target, return the target
> -  object.
> +- If LINK path matches a target object (i.e. <<path>>) or
> +  element (i.e. \"#+target: path\"), return it.
> +
> +- If LINK path exactly matches the name affiliated keyword
> +  \(i.e. #+name: path) of an element, return that element.
>  
>  - If LINK path exactly matches any headline name, return that
>    element.  If more than one headline share that name, priority
> @@ -2591,39 +2600,53 @@ Return value can be an object, an element, or nil:
>  
>  Assume LINK type is \"fuzzy\"."
>    (let ((path (org-element-get-property :path link)))
> -    ;; Link points to a target: return it.
> -    (or (loop for target in (plist-get info :target-list)
> -	      when (string= (org-element-get-property :raw-value target) path)
> -	      return target)
> -	;; Link either points to an headline or nothing.  Try to find
> -	;; the source, with priority given to headlines with the closest
> -	;; common ancestor.  If such candidate is found, return its
> -	;; beginning position as an unique identifier, otherwise return
> -	;; nil.
> -	(let ((find-headline
> -	       (function
> -		;; Return first headline whose `:raw-value' property
> -		;; is NAME in parse tree DATA, or nil.
> -		(lambda (name data)
> -		  (org-element-map
> -		   data 'headline
> -		   (lambda (headline local)
> -		     (when (string=
> -			    (org-element-get-property :raw-value headline)
> -			    name)
> -		       headline))
> -		   info 'first-match)))))
> -	  ;; Search among headlines sharing an ancestor with link,
> -	  ;; from closest to farthest.
> -	  (or (catch 'exit
> -		(mapc
> -		 (lambda (parent)
> -		   (when (eq (car parent) 'headline)
> -		     (let ((foundp (funcall find-headline path parent)))
> -		       (when foundp (throw 'exit foundp)))))
> -		 (plist-get info :genealogy)) nil)
> -	      ;; No match with a common ancestor: try the full parse-tree.
> -	      (funcall find-headline path (plist-get info :parse-tree)))))))
> +    (cond
> +     ;; First try to find a matching "<<path>>" unless user specified
> +     ;; he was looking for an headline (path starts with a *
> +     ;; character).
> +     ((and (not (eq (substring path 0 1) ?*))
> +	   (loop for target in (plist-get info :target-list)
> +		 when (string= (org-element-get-property :value target) path)
> +		 return target)))
> +     ;; Then try to find an element with a matching "#+name: path"
> +     ;; affiliated keyword.
> +     ((and (not (eq (substring path 0 1) ?*))
> +	   (org-element-map
> +	    (plist-get info :parse-tree) org-element-all-elements
> +	    (lambda (el local)
> +	      (when (string= (org-element-get-property :name el) path) el))
> +	    info 'first-match)))
> +     ;; Last case: link either points to an headline or to
> +     ;; nothingness.  Try to find the source, with priority given to
> +     ;; headlines with the closest common ancestor.  If such candidate
> +     ;; is found, return its beginning position as an unique
> +     ;; identifier, otherwise return nil.
> +     (t
> +      (let ((find-headline
> +	     (function
> +	      ;; Return first headline whose `:raw-value' property is
> +	      ;; NAME in parse tree DATA, or nil.
> +	      (lambda (name data)
> +		(org-element-map
> +		 data 'headline
> +		 (lambda (headline local)
> +		   (when (string=
> +			  (org-element-get-property :raw-value headline)
> +			  name)
> +		     headline))
> +		 info 'first-match)))))
> +	;; Search among headlines sharing an ancestor with link, from
> +	;; closest to farthest.
> +	(or (catch 'exit
> +	      (mapc
> +	       (lambda (parent)
> +		 (when (eq (car parent) 'headline)
> +		   (let ((foundp (funcall find-headline path parent)))
> +		     (when foundp (throw 'exit foundp)))))
> +	       (plist-get info :genealogy)) nil)
> +	    ;; No match with a common ancestor: try the full
> +	    ;; parse-tree.
> +	    (funcall find-headline path (plist-get info :parse-tree))))))))
>  
>  (defun org-export-resolve-id-link (link info)
>    "Return headline referenced as LINK destination.
> @@ -2641,20 +2664,6 @@ is either \"id\" or \"custom-id\"."
>           headline))
>       info 'first-match)))
>  
> -(defun org-export-resolve-ref-link (link info)
> -  "Return element referenced as LINK destination.
> -
> -INFO is a plist used as a communication channel.
> -
> -Assume LINK type is \"ref\" and.  Return value is the first
> -element whose `:name' property matches LINK's `:path', or nil."
> -  (let ((name (org-element-get-property :path link)))
> -    (org-element-map
> -     (plist-get info :parse-tree) org-element-all-elements
> -     (lambda (el local)
> -       (when (string= (org-element-get-property :name el) name) el))
> -     info 'first-match)))
> -
>  (defun org-export-resolve-coderef (ref info)
>    "Resolve a code reference REF.
>  
> @@ -2745,27 +2754,61 @@ Optional argument PREDICATE is a function returning a non-nil
>  value if the current element or object should be counted in.  It
>  accepts one argument: the element or object being considered.
>  This argument allows to count only a certain type of objects,
> -like inline images, which are a subset of links \(in that case,
> -`org-export-inline-image-p' might be an useful predicate\)."
> -  (let ((counter 0)
> -        ;; Determine if search should apply to current section, in
> -        ;; which case it should be retrieved first, or to full parse
> -        ;; tree.  As a special case, an element or object without
> -        ;; a parent headline will also trigger a full search,
> -        ;; notwithstanding WITHIN-SECTION value.
> -        (data
> -         (if (not within-section) (plist-get info :parse-tree)
> -	   (or (org-export-get-parent-headline element info)
> -	       (plist-get info :parse-tree)))))
> -    ;; Increment counter until ELEMENT is found again.
> -    (org-element-map
> -     data (or types (car element))
> -     (lambda (el local)
> -       (cond
> -        ((equal element el) (1+ counter))
> -	((not predicate) (incf counter) nil)
> -	((funcall predicate el) (incf counter) nil)))
> -     info 'first-match)))
> +like inline images, which are a subset of links (in that case,
> +`org-export-inline-image-p' might be an useful predicate).
> +
> +Return value is a list of numbers if ELEMENT is an headline or an
> +item.  It is nil for keywords.  It represents the footnote number
> +for footnote definitions and footnote references.  If ELEMENT is
> +a target, return the same value as if ELEMENT was the closest
> +table, item or headline containing the target.  In any other
> +case, return the sequence number of ELEMENT among elements or
> +objects of the same type."
> +  ;; A target keyword, representing an invisible target, never has
> +  ;; a sequence number.
> +  (unless (eq (car element) 'keyword)
> +    ;; Ordinal of a target object is the ordinal of the closest table,
> +    ;; item, or headline containing the object.
> +    (when (eq (car element) 'target)
> +      (setq element
> +	    (loop for parent in (org-export-get-genealogy element info)
> +		  when
> +		  (memq
> +		   (car parent)
> +		   '(footnote-definition footnote-reference headline item table))
> +		  return parent)))
> +    (case (car element)
> +      ;; Special case 1: An headline returns its number as a list.
> +      (headline (org-export-get-headline-number element info))
> +      ;; Special case 2: An item returns its number as a list.
> +      (item (let ((struct (org-element-get-property :structure element)))
> +	      (org-list-get-item-number
> +	       (org-element-get-property :begin element)
> +	       struct
> +	       (org-list-prevs-alist struct)
> +	       (org-list-parents-alist struct))))
> +      ((footnote definition footnote-reference)
> +       (org-export-get-footnote-number element info))
> +      (otherwise
> +       (let ((counter 0)
> +	     ;; Determine if search should apply to current section,
> +	     ;; in which case it should be retrieved first, or to full
> +	     ;; parse tree.  As a special case, an element or object
> +	     ;; without a parent headline will also trigger a full
> +	     ;; search, notwithstanding WITHIN-SECTION value.
> +	     (data
> +	      (if (not within-section) (plist-get info :parse-tree)
> +		(or (org-export-get-parent-headline element info)
> +		    (plist-get info :parse-tree)))))
> +	 ;; Increment counter until ELEMENT is found again.
> +	 (org-element-map
> +	  data (or types (car element))
> +	  (lambda (el local)
> +	    (cond
> +	     ((equal element el) (1+ counter))
> +	     ((not predicate) (incf counter) nil)
> +	     ((funcall predicate el) (incf counter) nil)))
> +	  info 'first-match))))))
>  
>  
>  ;;;; For Src-Blocks
> diff --git a/lisp/org.el b/lisp/org.el
> index a81f7fc..6708801 100644
> --- a/lisp/org.el
> +++ b/lisp/org.el
> @@ -9896,6 +9896,22 @@ visibility around point, thus ignoring
>  	       pos (match-beginning 0))))
>        ;; There is an exact target for this
>        (goto-char pos))
> +     ((save-excursion
> +	(goto-char (point-min))
> +	(and
> +	 (re-search-forward
> +	  (format "^[ \t]*#\\+target: %s" (regexp-quote s0)) nil t)
> +	 (setq type 'dedicated pos (match-beginning 0))))
> +      ;; Found an invisible target.
> +      (goto-char pos))
> +     ((save-excursion
> +	(goto-char (point-min))
> +	(and
> +	 (re-search-forward
> +	  (format "^[ \t]*#\\+name: %s" (regexp-quote s0)) nil t)
> +	 (setq type 'dedicated pos (match-beginning 0))))
> +      ;; Found an element with a matching name.
> +      (goto-char pos))
>       ((and (string-match "^(\\(.*\\))$" s0)
>  	   (save-excursion
>  	     (goto-char (point-min))

-- 
Thomas S. Dye
http://www.tsdye.com

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

* Re: [dev] Implement "ref" link types
  2012-02-20 22:06         ` Nicolas Goaziou
  2012-02-21  1:26           ` Thomas S. Dye
@ 2012-02-21  5:14           ` David Maus
  2012-02-21  9:18             ` Nicolas Goaziou
  1 sibling, 1 reply; 19+ messages in thread
From: David Maus @ 2012-02-21  5:14 UTC (permalink / raw)
  To: Nicolas Goaziou; +Cc: Org Mode List, Carsten Dominik

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

At Mon, 20 Feb 2012 23:06:32 +0100,
Nicolas Goaziou wrote:
>
> Completing myself, here is a patch implementing the previous suggestion,
> along with example output obtained with it.  You may need to
> (fmakunbound 'org-e-ascii-target) to avoid an error, since this patch
> removes the function.

I don't see why we should drop the link type in fuzzy links. After all
they /are/ are special type of link.

Without the link type we will run into trouble, won't we?.

In the example file:

,----
| We end the list at item [[itm:last]].
`----

So, itm:last is a fuzzy link but it could as well be a "regular" link
of type "itm" with a path component of "last" and no description.

If we say that we use itm:last as a fuzzy link iff there is no
registered link type "itm" we might put people into trouble if in some
point in the future Org mode introduces a link of type "itm" and the
fuzzy links stop working.

Or is there any technical reason to use [[itm:last]] instead of
[[ref:itm:last]]?

Best,
  -- David
--
OpenPGP... 0x99ADB83B5A4478E6
Jabber.... dmjena@jabber.org
Email..... dmaus@ictsoc.de

[-- Attachment #2: Type: application/pgp-signature, Size: 230 bytes --]

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

* Re: [dev] Implement "ref" link types
  2012-02-21  5:14           ` David Maus
@ 2012-02-21  9:18             ` Nicolas Goaziou
  2012-02-27 19:38               ` Nicolas Goaziou
  2012-02-27 20:38               ` David Maus
  0 siblings, 2 replies; 19+ messages in thread
From: Nicolas Goaziou @ 2012-02-21  9:18 UTC (permalink / raw)
  To: David Maus; +Cc: Org Mode List, Carsten Dominik

Hello,

David Maus <dmaus@ictsoc.de> writes:

> I don't see why we should drop the link type in fuzzy links. After all
> they /are/ are special type of link.

There is no link type in fuzzy links : [[something]] matches
<<something>> in master.

> Without the link type we will run into trouble, won't we?.
>
> In the example file:
>
> ,----
> | We end the list at item [[itm:last]].
> `----
>
> So, itm:last is a fuzzy link but it could as well be a "regular" link
> of type "itm" with a path component of "last" and no description.

I realize my examples are confusing. I shouldn't have used colons. In
fact, the output will be the same if the target is <<itm-last>>,
<<table-last>> or even <<foo>>.

In other words, the "itm:" part wasn't meant as a link type, but as
a cosmetic part of the name. So the list example could as well be:

#+begin_src org
  1. A first item in a list.
  2. Another item
     1. With three subparts. This one.
     2. Another one.
     3. <<last>> And the last subpart.
        
  We end the list at item [[last]].
#+end_src

> If we say that we use itm:last as a fuzzy link iff there is no
> registered link type "itm" we might put people into trouble if in some
> point in the future Org mode introduces a link of type "itm" and the
> fuzzy links stop working.

Certainly. I should have used another name for my examples.

The point is that a fuzzy link [[foo]] will detect the context of its
matching target (<<foo>>) or element (#+name: foo) and return an
appropriate sequence number.

The main difference with the current behaviour is that the target part
is ignored. At the moment, in LaTeX, <<path>> becomes
\label{path}path. It will be only \label{path} with the patch. This
allows for more flexibility (note that other types of targets, like
radio targets are unchanged).

> Or is there any technical reason to use [[itm:last]] instead of
> [[ref:itm:last]]?

I won't answer this question, since it came out from a mistake of
mine. Though, I'd answer another one: "Why do I prefer [[something]]
over [[ref:something]]?".

Thank you for asking this... Well, that's because Org also recognizes
plain links, i.e. http//orgmode.org. And, for an internal link, I'd
rather enforce the use of square brackets, as it is done actually.

Also, we don't require extra syntax, unless we don't want to change
behaviour of targets.


Regards,

-- 
Nicolas Goaziou

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

* Re: [dev] Implement "ref" link types
  2012-02-21  9:18             ` Nicolas Goaziou
@ 2012-02-27 19:38               ` Nicolas Goaziou
  2012-02-27 20:38               ` David Maus
  1 sibling, 0 replies; 19+ messages in thread
From: Nicolas Goaziou @ 2012-02-27 19:38 UTC (permalink / raw)
  To: David Maus; +Cc: Org Mode List, Carsten Dominik

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

Hello,

Here is a new version of the patch built on top of master, along with
test cases.

If there is no objection, I'll push it to master in a couple of days.
I really think that's a great feature to have in Org.


Regards,

-- 
Nicolas Goaziou

[-- Warning: decoded text below may be mangled, UTF-8 assumed --]
[-- Attachment #2: numbered cross references --]
[-- Type: text/x-patch, Size: 27354 bytes --]

From 2fdde87bb7f1241f3d24dbd8ae030a300fe8f0fc Mon Sep 17 00:00:00 2001
From: Nicolas Goaziou <n.goaziou@gmail.com>
Date: Mon, 20 Feb 2012 22:24:38 +0100
Subject: [PATCH] Implement numbered cross-references

* lisp/org.el (org-link-search): Search for #+name affiliated keywords
  and invisible targets.
* contrib/lisp/org-element.el (org-element-link-parser): Remove "ref"
  links relative part.
(org-element-target-parser): Move property name from `:raw-value' to
`:value'.
(org-element-recursive-objects): Remove targets from tables.  Cells
are not parsed unless explicitely asked by back-end developer, too
late.  A target wouldn't be noticed in time.  One solution could be to
parse every table, but that's time consumming.
(org-element-object-restrictions): Target are not recursive anymore.
* contrib/lisp/org-export.el (org-export-resolve-fuzzy-link): Find
  elements with a matching "#+name: path" affiliated keyword.
(org-export-get-ordinal): Make special cases for headlines, items,
footnotes definitions and references.
(org-export-resolve-ref-link): Removed function.
* EXPERIMENTAL/org-e-latex.el (org-e-latex-link): Handle
  cross-reference numbers.
(org-e-latex-target): Targets have no contents.
* EXPERIMENTAL/org-e-ascii.el (org-e-ascii--describe-links): Ignore
  fuzzy links in link description at the end of the section.
(org-e-ascii-link): Handle cross-reference numbers.
* testing/contrib/lisp/test-org-export.el: Add tests.
* testing/lisp/test-org.el: Add tests.
---
 EXPERIMENTAL/org-e-ascii.el             |   80 ++++++++----------
 EXPERIMENTAL/org-e-latex.el             |   50 +++++------
 contrib/lisp/org-element.el             |   20 ++---
 contrib/lisp/org-export.el              |  141 ++++++++++++++++++++-----------
 lisp/org.el                             |   16 ++++
 testing/contrib/lisp/test-org-export.el |   91 ++++++++++++++++++++
 testing/lisp/test-org.el                |   41 +++++++++
 7 files changed, 299 insertions(+), 140 deletions(-)

diff --git a/EXPERIMENTAL/org-e-ascii.el b/EXPERIMENTAL/org-e-ascii.el
index 0eb547b..c9cca4a 100644
--- a/EXPERIMENTAL/org-e-ascii.el
+++ b/EXPERIMENTAL/org-e-ascii.el
@@ -825,28 +825,24 @@ channel."
 		     (if (not desc) (org-element-property :raw-link link)
 		       (org-export-secondary-string desc 'e-ascii info)))))
        (cond
-	;; Coderefs, radio links and ref links are ignored.
-	((member type '("coderef" "radio" "ref")) nil)
-	;; Id, custom-id and fuzzy links (with the exception of
-	;; targets): Headlines refer to their numbering.
-	((member type '("custom-id" "fuzzy" "id"))
-	 (let ((destination (if (string= type "fuzzy")
-				(org-export-resolve-fuzzy-link link info)
-			      (org-export-resolve-id-link link info))))
-	   (unless (eq (org-element-type destination) 'target)
-	     (concat
-	      (org-e-ascii--fill-string
-	       (format
-		"[%s] %s"
-		anchor
-		(if (not destination)
-		    (org-e-ascii--translate "Unknown reference" info)
-		  (format
-		   (org-e-ascii--translate "See section %s" info)
-		   (mapconcat 'number-to-string
-			      (org-export-get-headline-number destination info)
-			      "."))))
-	       width info) "\n\n"))))
+	;; Coderefs, radio links and fuzzy links are ignored.
+	((member type '("coderef" "radio" "fuzzy")) nil)
+	;; Id and custom-id links: Headlines refer to their numbering.
+	((member type '("custom-id" "id"))
+	 (let ((destination (org-export-resolve-id-link link info)))
+	   (concat
+	    (org-e-ascii--fill-string
+	     (format
+	      "[%s] %s"
+	      anchor
+	      (if (not destination)
+		  (org-e-ascii--translate "Unknown reference" info)
+		(format
+		 (org-e-ascii--translate "See section %s" info)
+		 (mapconcat 'number-to-string
+			    (org-export-get-headline-number destination info)
+			    "."))))
+	     width info) "\n\n")))
 	;; Do not add a link that cannot be resolved and doesn't have
 	;; any description: destination is already visible in the
 	;; paragraph.
@@ -1390,29 +1386,23 @@ INFO is a plist holding contextual information."
 	(org-element-property :path link)
 	(cdr (assq 'radio-target org-element-object-restrictions)))
        'e-ascii info))
-     ;; Ref link: If there's no description (DESC, return link's
-     ;; destination sequence number among elements of same
-     ;; type. Otherwise, use DESC.
-     ((string= type "ref")
-      (if (org-string-nw-p desc) desc
-	(format "%d"
-		(org-export-get-ordinal
-		 (org-export-resolve-ref-link link info)
-		 info nil nil
-		 (lambda (el) (or (org-element-property :caption el)
-			     (org-element-property :name el)))))))
      ;; Do not apply a special syntax on fuzzy links pointing to
      ;; targets.
-     ((and (string= type "fuzzy")
-	   (let ((path (org-element-property :path link)))
-	     (loop for target in (plist-get info :target-list)
-		   thereis (string=
-			    (org-element-property :raw-value target)
-			    path))))
-      (if (org-string-nw-p desc) desc raw-link))
+     ((string= type "fuzzy")
+      (let ((destination (org-export-resolve-fuzzy-link link info)))
+	;; Ignore invisible "#+target: path".
+	(unless (eq (org-element-type destination) 'keyword)
+	  (if (org-string-nw-p desc) desc
+	    (when destination
+	      (let ((number (org-export-get-ordinal destination info)))
+		(when number
+		  (if (atom number) (number-to-string number)
+		    (mapconcat 'number-to-string number ".")))))))))
      (t
-      (concat (format "[%s]" (if (org-string-nw-p desc) desc raw-link))
-	      (unless org-e-ascii-links-to-notes (format " (%s)" raw-link)))))))
+      (if (not (org-string-nw-p desc)) (format "[%s]" raw-link)
+	(concat
+	 (format "[%s]" desc)
+	 (unless org-e-ascii-links-to-notes (format " (%s)" raw-link))))))))
 
 
 ;;;; Macro
@@ -1850,11 +1840,7 @@ INFO is a plist used as a communication channel."
 
 ;;;; Target
 
-(defun org-e-ascii-target (target contents info)
-  "Transcode a TARGET object from Org to ASCII.
-CONTENTS is the contents of the target.  INFO is a plist holding
-contextual information."
-  contents)
+;; Targets are invisible.
 
 
 ;;;; Time-stamp
diff --git a/EXPERIMENTAL/org-e-latex.el b/EXPERIMENTAL/org-e-latex.el
index 43bbde7..01b8ee2 100644
--- a/EXPERIMENTAL/org-e-latex.el
+++ b/EXPERIMENTAL/org-e-latex.el
@@ -1291,8 +1291,8 @@ CONTENTS is nil.  INFO is a plist holding contextual information."
     (cond
      ((string= key "latex") value)
      ((string= key "index") (format "\\index{%s}" value))
-     ((string= key "target")
-      (format "\\label{%s}" (org-export-solidify-link-text value)))
+     ;; Invisible targets.
+     ((string= key "target") nil)
      ((string= key "toc")
       (let ((value (downcase value)))
 	(cond
@@ -1451,32 +1451,26 @@ INFO is a plist holding contextual information.  See
 	       (org-element-parse-secondary-string
 		path (cdr (assq 'radio-target org-element-object-restrictions)))
 	       'e-latex info)))
-     ;; Ref link: If no description is provided, reference label PATH
-     ;; and display table number.  Otherwise move to label but display
-     ;; description instead.
-     ((string= type "ref")
-      (if (not desc) (format "\\ref{%s}" path)
-	(format "\\hyperref[%s]{%s}" path desc)))
      ;; Links pointing to an headline: Find destination and build
      ;; appropriate referencing command.
      ((member type '("custom-id" "fuzzy" "id"))
       (let ((destination (if (string= type "fuzzy")
 			     (org-export-resolve-fuzzy-link link info)
 			   (org-export-resolve-id-link link info))))
-	;; Fuzzy link points to a target.  Do as above.
 	(case (org-element-type destination)
-	  (target
-	   (format "\\hyperref[%s]{%s}"
-		   (org-export-solidify-link-text
-		    (org-element-property :raw-value destination))
+	  ;; Fuzzy link points nowhere.
+	  ('nil
+	   (format "\\texttt{%s}"
 		   (or desc
 		       (org-export-secondary-string
 			(org-element-property :raw-link link)
 			'e-latex info))))
-	  ;; Fuzzy link points to an headline.  If headlines are
-	  ;; numbered and the link has no description, display
-	  ;; headline's number.  Otherwise, display description or
-	  ;; headline's title.
+	  ;; Fuzzy link points to an invisible target.
+	  (keyword nil)
+	  ;; LINK points to an headline.  If headlines are numbered
+	  ;; and the link has no description, display headline's
+	  ;; number.  Otherwise, display description or headline's
+	  ;; title.
 	  (headline
 	   (let ((label
 		  (format "sec-%s"
@@ -1491,13 +1485,11 @@ INFO is a plist holding contextual information.  See
 			   (org-export-secondary-string
 			    (org-element-property :title destination)
 			    'e-latex info))))))
-	  ;; Fuzzy link points nowhere.
+          ;; Fuzzy link points to a target.  Do as above.
 	  (otherwise
-	   (format "\\texttt{%s}"
-		   (or desc
-		       (org-export-secondary-string
-			(org-element-property :raw-link link)
-			'e-latex info)))))))
+	   (let ((path (org-export-solidify-link-text path)))
+	     (if (not desc) (format "\\ref{%s}" path)
+	       (format "\\hyperref[%s]{%s}" path desc)))))))
      ;; Coderef: replace link with the reference name or the
      ;; equivalent line number.
      ((string= type "coderef")
@@ -1970,14 +1962,12 @@ CONTENTS is nil.  INFO is a plist holding contextual information."
 
 ;;;; Target
 
-(defun org-e-latex-target (target text info)
+(defun org-e-latex-target (target contents info)
   "Transcode a TARGET object from Org to LaTeX.
-TEXT is the text of the target.  INFO is a plist holding
-contextual information."
-  (format "\\label{%s}%s"
-	  (org-export-solidify-link-text
-	   (org-element-property :raw-value target))
-	  text))
+CONTENTS is nil.  INFO is a plist holding contextual
+information."
+  (format "\\label{%s}"
+	  (org-export-solidify-link-text (org-element-property :value target))))
 
 
 ;;;; Time-stamp
diff --git a/contrib/lisp/org-element.el b/contrib/lisp/org-element.el
index 4e5e7fd..de5d4ea 100644
--- a/contrib/lisp/org-element.el
+++ b/contrib/lisp/org-element.el
@@ -1967,9 +1967,6 @@ Assume point is at the beginning of the link."
 	 ;; Explicit type (http, irc, bbdb...).  See `org-link-types'.
 	 ((string-match org-link-re-with-space3 link)
 	  (setq type (match-string 1 link) path (match-string 2 link)))
-	 ;; Ref type: PATH is the name of the target element.
-	 ((string-match "^ref:\\(.*\\)" link)
-	  (setq type "ref" path (org-trim (match-string 1 link))))
 	 ;; Id type: PATH is the id.
 	 ((string-match "^id:\\([-a-f0-9]+\\)" link)
 	  (setq type "id" path (match-string 1 link)))
@@ -2269,25 +2266,21 @@ CONTENTS is the contents of the object."
   "Parse target at point.
 
 Return a list whose car is `target' and cdr a plist with
-`:begin', `:end', `:contents-begin', `:contents-end', `raw-value'
-and `:post-blank' as keywords.
+`:begin', `:end', `:contents-begin', `:contents-end', `value' and
+`:post-blank' as keywords.
 
 Assume point is at the target."
   (save-excursion
     (looking-at org-target-regexp)
     (let ((begin (point))
-	  (contents-begin (match-beginning 1))
-	  (contents-end (match-end 1))
-	  (raw-value (org-match-string-no-properties 1))
+	  (value (org-match-string-no-properties 1))
 	  (post-blank (progn (goto-char (match-end 0))
 			     (skip-chars-forward " \t")))
 	  (end (point)))
       `(target
 	(:begin ,begin
 		:end ,end
-		:contents-begin ,contents-begin
-		:contents-end ,contents-end
-		:raw-value ,raw-value
+		:value ,value
 		:post-blank ,post-blank)))))
 
 (defun org-element-target-interpreter (target contents)
@@ -2481,7 +2474,7 @@ regexp matching one object can also match the other object.")
   "Complete list of object types.")
 
 (defconst org-element-recursive-objects
-  '(emphasis link macro subscript superscript target radio-target)
+  '(emphasis link macro subscript superscript radio-target)
   "List of recursive object types.")
 
 (defconst org-element-non-recursive-block-alist
@@ -2551,8 +2544,7 @@ This list is checked after translations have been applied.  See
     (subscript entity export-snippet inline-babel-call inline-src-block
 	       latex-fragment sub/superscript text-markup)
     (superscript entity export-snippet inline-babel-call inline-src-block
-		 latex-fragment sub/superscript text-markup)
-    (target entity export-snippet latex-fragment sub/superscript text-markup))
+		 latex-fragment sub/superscript text-markup))
   "Alist of recursive objects restrictions.
 
 CAR is a recursive object type and CDR is a list of successors
diff --git a/contrib/lisp/org-export.el b/contrib/lisp/org-export.el
index b809758..e7cca50 100644
--- a/contrib/lisp/org-export.el
+++ b/contrib/lisp/org-export.el
@@ -1289,7 +1289,13 @@ Following tree properties are set:
    `(:parse-tree
      ,data
      :target-list
-     ,(org-element-map data 'target 'identity info)
+     ,(org-element-map
+       data '(keyword target)
+       (lambda (blob)
+	 (when (or (eq (org-element-type blob) 'target)
+		   (string= (upcase (org-element-property :key blob))
+                            "TARGET"))
+	   blob)) info)
      :headline-numbering ,(org-export-collect-headline-numbering data info)
      :back-end ,backend)
    info))
@@ -2697,8 +2703,11 @@ INFO is a plist holding contextual information.
 
 Return value can be an object, an element, or nil:
 
-- If LINK path exactly matches any target, return the target
-  object.
+- If LINK path matches a target object (i.e. <<path>>) or
+  element (i.e. \"#+target: path\"), return it.
+
+- If LINK path exactly matches the name affiliated keyword
+  \(i.e. #+name: path) of an element, return that element.
 
 - If LINK path exactly matches any headline name, return that
   element.  If more than one headline share that name, priority
@@ -2709,16 +2718,29 @@ Return value can be an object, an element, or nil:
 
 Assume LINK type is \"fuzzy\"."
   (let ((path (org-element-property :path link)))
-    ;; Link points to a target: return it.
-    (or (loop for target in (plist-get info :target-list)
-	      when (string= (org-element-property :raw-value target) path)
-	      return target)
-	;; Link either points to an headline or nothing.  Try to find
-	;; the source, with priority given to headlines with the closest
-	;; common ancestor.  If such candidate is found, return its
-	;; beginning position as an unique identifier, otherwise return
-	;; nil.
-	(let ((find-headline
+    (cond
+     ;; First try to find a matching "<<path>>" unless user specified
+     ;; he was looking for an headline (path starts with a *
+     ;; character).
+     ((and (not (eq (substring path 0 1) ?*))
+	   (loop for target in (plist-get info :target-list)
+		 when (string= (org-element-property :value target) path)
+		 return target)))
+     ;; Then try to find an element with a matching "#+name: path"
+     ;; affiliated keyword.
+     ((and (not (eq (substring path 0 1) ?*))
+	   (org-element-map
+	    (plist-get info :parse-tree) org-element-all-elements
+	    (lambda (el)
+              (when (string= (org-element-property :name el) path) el))
+	    info 'first-match)))
+     ;; Last case: link either points to an headline or to
+     ;; nothingness.  Try to find the source, with priority given to
+     ;; headlines with the closest common ancestor.  If such candidate
+     ;; is found, return its beginning position as an unique
+     ;; identifier, otherwise return nil.
+     (t
+      (let ((find-headline
 	       (function
 		;; Return first headline whose `:raw-value' property
 		;; is NAME in parse tree DATA, or nil.
@@ -2741,7 +2763,7 @@ Assume LINK type is \"fuzzy\"."
 		       (when foundp (throw 'exit foundp)))))
 		 (org-export-get-genealogy link info)) nil)
 	      ;; No match with a common ancestor: try the full parse-tree.
-	      (funcall find-headline path (plist-get info :parse-tree)))))))
+	      (funcall find-headline path (plist-get info :parse-tree))))))))
 
 (defun org-export-resolve-id-link (link info)
   "Return headline referenced as LINK destination.
@@ -2759,20 +2781,6 @@ is either \"id\" or \"custom-id\"."
          headline))
      info 'first-match)))
 
-(defun org-export-resolve-ref-link (link info)
-  "Return element referenced as LINK destination.
-
-INFO is a plist used as a communication channel.
-
-Assume LINK type is \"ref\" and.  Return value is the first
-element whose `:name' property matches LINK's `:path', or nil."
-  (let ((name (org-element-property :path link)))
-    (org-element-map
-     (plist-get info :parse-tree) org-element-all-elements
-     (lambda (el)
-       (when (string= (org-element-property :name el) name) el))
-     info 'first-match)))
-
 (defun org-export-resolve-coderef (ref info)
   "Resolve a code reference REF.
 
@@ -2863,27 +2871,62 @@ Optional argument PREDICATE is a function returning a non-nil
 value if the current element or object should be counted in.  It
 accepts one argument: the element or object being considered.
 This argument allows to count only a certain type of objects,
-like inline images, which are a subset of links \(in that case,
-`org-export-inline-image-p' might be an useful predicate\)."
-  (let ((counter 0)
-        ;; Determine if search should apply to current section, in
-        ;; which case it should be retrieved first, or to full parse
-        ;; tree.  As a special case, an element or object without
-        ;; a parent headline will also trigger a full search,
-        ;; notwithstanding WITHIN-SECTION value.
-        (data
-         (if (not within-section) (plist-get info :parse-tree)
-	   (or (org-export-get-parent-headline element info)
-	       (plist-get info :parse-tree)))))
-    ;; Increment counter until ELEMENT is found again.
-    (org-element-map
-     data (or types (org-element-type element))
-     (lambda (el)
-       (cond
-        ((equal element el) (1+ counter))
-	((not predicate) (incf counter) nil)
-	((funcall predicate el) (incf counter) nil)))
-     info 'first-match)))
+like inline images, which are a subset of links (in that case,
+`org-export-inline-image-p' might be an useful predicate).
+
+Return value is a list of numbers if ELEMENT is an headline or an
+item.  It is nil for keywords.  It represents the footnote number
+for footnote definitions and footnote references.  If ELEMENT is
+a target, return the same value as if ELEMENT was the closest
+table, item or headline containing the target.  In any other
+case, return the sequence number of ELEMENT among elements or
+objects of the same type."
+  ;; A target keyword, representing an invisible target, never has
+  ;; a sequence number.
+  (unless (eq (org-element-type element) 'keyword)
+    ;; Ordinal of a target object refer to the ordinal of the closest
+    ;; table, item, or headline containing the object.
+    (when (eq (org-element-type element) 'target)
+      (setq element
+	    (loop for parent in (org-export-get-genealogy element info)
+		  when
+		  (memq
+		   (org-element-type parent)
+		   '(footnote-definition footnote-reference headline item
+                                         table))
+		  return parent)))
+    (case (org-element-type element)
+      ;; Special case 1: An headline returns its number as a list.
+      (headline (org-export-get-headline-number element info))
+      ;; Special case 2: An item returns its number as a list.
+      (item (let ((struct (org-element-property :structure element)))
+	      (org-list-get-item-number
+	       (org-element-property :begin element)
+	       struct
+	       (org-list-prevs-alist struct)
+	       (org-list-parents-alist struct))))
+      ((footnote definition footnote-reference)
+       (org-export-get-footnote-number element info))
+      (otherwise
+       (let ((counter 0)
+	     ;; Determine if search should apply to current section,
+	     ;; in which case it should be retrieved first, or to full
+	     ;; parse tree.  As a special case, an element or object
+	     ;; without a parent headline will also trigger a full
+	     ;; search, notwithstanding WITHIN-SECTION value.
+	     (data
+	      (if (not within-section) (plist-get info :parse-tree)
+		(or (org-export-get-parent-headline element info)
+		    (plist-get info :parse-tree)))))
+	 ;; Increment counter until ELEMENT is found again.
+	 (org-element-map
+	  data (or types (org-element-type element))
+	  (lambda (el)
+	    (cond
+	     ((equal element el) (1+ counter))
+	     ((not predicate) (incf counter) nil)
+	     ((funcall predicate el) (incf counter) nil)))
+	  info 'first-match))))))
 
 
 ;;;; For Src-Blocks
diff --git a/lisp/org.el b/lisp/org.el
index a81f7fc..b8dd292 100644
--- a/lisp/org.el
+++ b/lisp/org.el
@@ -9896,6 +9896,22 @@ visibility around point, thus ignoring
 	       pos (match-beginning 0))))
       ;; There is an exact target for this
       (goto-char pos))
+     ((save-excursion
+	(goto-char (point-min))
+	(and
+	 (re-search-forward
+	  (format "^[ \t]*#\\+TARGET: %s" (regexp-quote s0)) nil t)
+	 (setq type 'dedicated pos (match-beginning 0))))
+      ;; Found an invisible target.
+      (goto-char pos))
+     ((save-excursion
+	(goto-char (point-min))
+	(and
+	 (re-search-forward
+	  (format "^[ \t]*#\\+NAME: %s" (regexp-quote s0)) nil t)
+	 (setq type 'dedicated pos (match-beginning 0))))
+      ;; Found an element with a matching #+name affiliated keyword.
+      (goto-char pos))
      ((and (string-match "^(\\(.*\\))$" s0)
 	   (save-excursion
 	     (goto-char (point-min))
diff --git a/testing/contrib/lisp/test-org-export.el b/testing/contrib/lisp/test-org-export.el
index c9923d4..f791391 100644
--- a/testing/contrib/lisp/test-org-export.el
+++ b/testing/contrib/lisp/test-org-export.el
@@ -369,3 +369,94 @@ body\n")))
 	;; Both footnotes should be seen.
 	(should
 	 (= (length (org-export-collect-footnote-definitions tree info)) 2))))))
+
+(ert-deftest test-org-export/fuzzy-links ()
+  "Test fuzz link export specifications."
+  ;; 1. Links to invisible (keyword) targets should be ignored.
+  (org-test-with-temp-text
+      "Paragraph.\n#+TARGET: Test\n[[Test]]"
+    (let* ((tree (org-element-parse-buffer))
+	   (info (org-combine-plists (org-export-initial-options))))
+      (setq info (org-combine-plists
+		  info (org-export-collect-tree-properties tree info 'test)))
+      (should-not
+       (org-element-map
+	tree 'link
+	(lambda (link)
+	  (org-export-get-ordinal
+	   (org-export-resolve-fuzzy-link link info) info)) info))))
+  ;; 2. Link to an headline should return headline's number.
+  (org-test-with-temp-text
+      "Paragraph.\n* Head1\n* Head2\n* Head3\n[[Head2]]"
+    (let* ((tree (org-element-parse-buffer))
+	   (info (org-combine-plists (org-export-initial-options))))
+      (setq info (org-combine-plists
+		  info (org-export-collect-tree-properties tree info 'test)))
+      (should
+       ;; Note: Headline's number is in fact a list of numbers.
+       (equal '(2)
+	      (org-element-map
+	       tree 'link
+	       (lambda (link)
+		 (org-export-get-ordinal
+		  (org-export-resolve-fuzzy-link link info) info)) info t)))))
+  ;; 3. Link to a target in an item should return item's number.
+  (org-test-with-temp-text
+      "- Item1\n  - Item11\n  - <<test>>Item12\n- Item2\n\n\n[[test]]"
+    (let* ((tree (org-element-parse-buffer))
+	   (info (org-combine-plists (org-export-initial-options))))
+      (setq info (org-combine-plists
+		  info (org-export-collect-tree-properties tree info 'test)))
+      (should
+       ;; Note: Item's number is in fact a list of numbers.
+       (equal '(1 2)
+	      (org-element-map
+	       tree 'link
+	       (lambda (link)
+		 (org-export-get-ordinal
+		  (org-export-resolve-fuzzy-link link info) info)) info t)))))
+  ;; 4. Link to a target in a footnote should return footnote's
+  ;;    number.
+  (org-test-with-temp-text
+      "Paragraph[1][2][fn:lbl3:C<<target>>][[test]][[target]]\n[1] A\n\n[2] <<test>>B"
+    (let* ((tree (org-element-parse-buffer))
+	   (info (org-combine-plists (org-export-initial-options))))
+      (setq info (org-combine-plists
+		  info (org-export-collect-tree-properties tree info 'test)))
+      (should
+       (equal '(2 3)
+	      (org-element-map
+	       tree 'link
+	       (lambda (link)
+		 (org-export-get-ordinal
+		  (org-export-resolve-fuzzy-link link info) info)) info)))))
+  ;; 5. Link to a named element should return sequence number of that
+  ;;    element.
+  (org-test-with-temp-text
+      "#+NAME: tbl1\n|1|2|\n#+NAME: tbl2\n|3|4|\n#+NAME: tbl3\n|5|6|\n[[tbl2]]"
+    (let* ((tree (org-element-parse-buffer))
+	   (info (org-combine-plists (org-export-initial-options))))
+      (setq info (org-combine-plists
+		  info (org-export-collect-tree-properties tree info 'test)))
+      (should
+       (= 2
+	  (org-element-map
+	   tree 'link
+	   (lambda (link)
+	     (org-export-get-ordinal
+	      (org-export-resolve-fuzzy-link link info) info)) info t)))))
+  ;; 6. Link to a target not within an item, a table, a footnote
+  ;;    reference or definition should return section number.
+  (org-test-with-temp-text
+      "* Head1\n* Head2\nParagraph<<target>>\n* Head3\n[[target]]"
+    (let* ((tree (org-element-parse-buffer))
+	   (info (org-combine-plists (org-export-initial-options))))
+      (setq info (org-combine-plists
+		  info (org-export-collect-tree-properties tree info 'test)))
+      (should
+       (equal '(2)
+	      (org-element-map
+	       tree 'link
+	       (lambda (link)
+		 (org-export-get-ordinal
+		  (org-export-resolve-fuzzy-link link info) info)) info t))))))
diff --git a/testing/lisp/test-org.el b/testing/lisp/test-org.el
index 4fc9ac9..3639367 100644
--- a/testing/lisp/test-org.el
+++ b/testing/lisp/test-org.el
@@ -98,6 +98,47 @@ http://article.gmane.org/gmane.emacs.orgmode/21459/"
     (org-babel-next-src-block)
     (should (equal '(2 1) (org-babel-execute-src-block)))))
 
+
+\f
+;;; Links
+
+;;;; Fuzzy links
+
+;; Fuzzy links [[text]] encompass links to a target (<<text>>), to
+;; a target keyword (aka an invisible target: #+TARGET: text), to
+;; a named element (#+name: text) and to headlines (* Text).
+
+(ert-deftest test-org-export/fuzzy-links ()
+  "Test fuzzy links specifications."
+  ;; 1. Fuzzy link goes in priority to a matching target.
+  (org-test-with-temp-text
+      "#+TARGET: Test\n#+NAME: Test\n|a|b|\n<<Test>>\n* Test\n[[Test]]"
+    (goto-line 4)
+    (org-open-at-point)
+    (should (looking-at "<<Test>>")))
+  ;; 2. Fuzzy link should then go to a matching target keyword.
+  (org-test-with-temp-text
+      "#+NAME: Test\n|a|b|\n#+TARGET: Test\n* Test\n[[Test]]"
+    (goto-line 4)
+    (org-open-at-point)
+    (should (looking-at "#\\+TARGET: Test")))
+  ;; 3. Then fuzzy link points to an element with a given name.
+  (org-test-with-temp-text "Test\n#+NAME: Test\n|a|b|\n* Test\n[[Test]]"
+    (goto-line 5)
+    (org-open-at-point)
+    (should (looking-at "#\\+NAME: Test")))
+  ;; 4. A target still lead to a matching headline otherwise.
+  (org-test-with-temp-text "* Head1\n* Head2\n*Head3\n[[Head2]]"
+    (goto-line 4)
+    (org-open-at-point)
+    (should (looking-at "\\* Head2")))
+  ;; 5. With a leading star in link, enforce heading match.
+  (org-test-with-temp-text "#+TARGET: Test\n* Test\n<<Test>>\n[[*Test]]"
+    (goto-line 4)
+    (org-open-at-point)
+    (should (looking-at "\\* Test"))))
+
+
 (provide 'test-org)
 
 ;;; test-org.el ends here
-- 
1.7.9.2


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

* Re: [dev] Implement "ref" link types
  2012-02-21  9:18             ` Nicolas Goaziou
  2012-02-27 19:38               ` Nicolas Goaziou
@ 2012-02-27 20:38               ` David Maus
  1 sibling, 0 replies; 19+ messages in thread
From: David Maus @ 2012-02-27 20:38 UTC (permalink / raw)
  To: Nicolas Goaziou; +Cc: David Maus, Org Mode List, Carsten Dominik

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

At Tue, 21 Feb 2012 10:18:00 +0100,
Nicolas Goaziou wrote:
>
> Hello,
>
> David Maus <dmaus@ictsoc.de> writes:
>
> > I don't see why we should drop the link type in fuzzy links. After all
> > they /are/ are special type of link.
>
> There is no link type in fuzzy links : [[something]] matches
> <<something>> in master.
>
> > Without the link type we will run into trouble, won't we?.
> >
> > In the example file:
> >
> > ,----
> > | We end the list at item [[itm:last]].
> > `----
> >
> > So, itm:last is a fuzzy link but it could as well be a "regular" link
> > of type "itm" with a path component of "last" and no description.
>
> I realize my examples are confusing. I shouldn't have used colons. In
> fact, the output will be the same if the target is <<itm-last>>,
> <<table-last>> or even <<foo>>.
>
> In other words, the "itm:" part wasn't meant as a link type, but as
> a cosmetic part of the name. So the list example could as well be:

Thanks for the clarification.

Best,
  -- David
--
OpenPGP... 0x99ADB83B5A4478E6
Jabber.... dmjena@jabber.org
Email..... dmaus@ictsoc.de

[-- Attachment #2: Type: application/pgp-signature, Size: 230 bytes --]

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

* Re: [dev] Implement "ref" link types
  2012-02-20 10:59       ` Nicolas Goaziou
  2012-02-20 22:06         ` Nicolas Goaziou
@ 2012-03-05  9:37         ` Jambunathan K
  1 sibling, 0 replies; 19+ messages in thread
From: Jambunathan K @ 2012-03-05  9:37 UTC (permalink / raw)
  To: Nicolas Goaziou; +Cc: Org Mode List


> On the Org side, when a link like [[something]] or [[something][text]]
> is encountered in a buffer, the search would go on like this:
>
>   1. Search any "<<something>>" or "#+target: something"[1].

>     1. A link to an invisible target will be replaced with _nothing_
>        (that's the point of being invisible).

What led you to come up with this interpretation? [3].    

A target *reference* will *always* export and create a clickable link
irrespective how the target is *defined*.

Read on...

> [1] This is the replacement for invisible targets, since they cannot
> live in comments anymore.

I think there is an element of confusion about what invisible target is.
After some digging, I realize that they were originally called as
invisible anchors.  

The manual [1] has the following note:

,----
|    * Matt Lundin has proposed last-row references for table formulas
|      and named invisible anchors.
`----

The original post [2] from Matt says
,----
| # <<radiotarget>>
| 
| should become
| 
| <a name="radiotarget"></a>
`----

Now the question is what is invisible? The "description" in <a ...> </a>
becomes invisible.  

Why was the term invisible chosen in the first place.  For this one has
to look at the the "default" behaviour for targets which is to export
with *both* the anchor name and anchor description.  

So, I think a correction is in order.

Footnotes:

[1] (info "(org) History and Acknowledgments")
[2] http://lists.gnu.org/archive/html/emacs-orgmode/2008-11/msg00327.html
[3] If I export the following unit test snippet, the produced output
from LaTeX/PDF has *just* "Paragraph" and nothing else.

,----
| Paragraph.
| #+TARGET: Test
| [[Test]]
`----
-- 

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

end of thread, other threads:[~2012-03-05  9:37 UTC | newest]

Thread overview: 19+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2012-02-19 18:08 [dev] Implement "ref" link types Nicolas Goaziou
2012-02-19 19:28 ` Christian Moe
2012-02-19 19:41   ` Nicolas Goaziou
2012-02-19 20:11     ` Toby Cubitt
2012-02-19 20:20     ` Christian Moe
2012-02-19 19:41 ` Samuel Wales
2012-02-19 20:02   ` Nicolas Goaziou
2012-02-19 20:48     ` Samuel Wales
2012-02-19 20:10 ` Carsten Dominik
2012-02-20  0:51   ` Nicolas Goaziou
2012-02-20  7:09     ` Carsten Dominik
2012-02-20 10:59       ` Nicolas Goaziou
2012-02-20 22:06         ` Nicolas Goaziou
2012-02-21  1:26           ` Thomas S. Dye
2012-02-21  5:14           ` David Maus
2012-02-21  9:18             ` Nicolas Goaziou
2012-02-27 19:38               ` Nicolas Goaziou
2012-02-27 20:38               ` David Maus
2012-03-05  9:37         ` Jambunathan K

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