From mboxrd@z Thu Jan 1 00:00:00 1970 From: tsd@tsdye.com (Thomas S. Dye) Subject: Re: [dev] Implement "ref" link types Date: Mon, 20 Feb 2012 15:26:39 -1000 Message-ID: References: <87vcn2vgq7.fsf@gmail.com> <8739a62upy.fsf@gmail.com> <763A8736-3DB8-492D-95CB-2E2D90982BAE@gmail.com> <87y5rx22km.fsf@gmail.com> <87ty2l17o7.fsf@gmail.com> Mime-Version: 1.0 Content-Type: text/plain; charset=us-ascii Return-path: Received: from eggs.gnu.org ([140.186.70.92]:39475) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1RzeVE-00014y-QC for emacs-orgmode@gnu.org; Mon, 20 Feb 2012 20:26:51 -0500 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1RzeVB-0006t8-NR for emacs-orgmode@gnu.org; Mon, 20 Feb 2012 20:26:48 -0500 Received: from oproxy5-pub.bluehost.com ([67.222.38.55]:35324) by eggs.gnu.org with smtp (Exim 4.71) (envelope-from ) id 1RzeVB-0006sk-9f for emacs-orgmode@gnu.org; Mon, 20 Feb 2012 20:26:45 -0500 In-Reply-To: <87ty2l17o7.fsf@gmail.com> (Nicolas Goaziou's message of "Mon, 20 Feb 2012 23:06:32 +0100") List-Id: "General discussions about Org-mode." List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: emacs-orgmode-bounces+geo-emacs-orgmode=m.gmane.org@gnu.org Sender: emacs-orgmode-bounces+geo-emacs-orgmode=m.gmane.org@gnu.org To: Nicolas Goaziou Cc: Org Mode List , Carsten Dominik Nice! Nicolas Goaziou 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. <> 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.<> > > #+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] <> 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 > 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. <>) 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 "<>" 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