Преглед изворни кода

Make invisible targets anchors in the headlines or items.

Org allows to define invisible anchors in a document in comment lines
like

If such a line is directly before or after a headline, previously this
anchor was removed, and all references to it were replaced with
references to the anchor that the headline had anyway.

Matthew Lundin pointed out that this makes it impossible to have
permanent links to headlines that can also be used from outside the
current page.

This patch changes his situation by adding the additional targets as
empty anchors to the section heading.  If works by creating, during
preprocessing, an alist with targets that do have aliases.  During
publishing, these aliases are looked up and converted into anchors.
In LaTeX export, these additional targets become additional labels.
Carsten Dominik пре 16 година
родитељ
комит
a4f9f8c93b
3 измењених фајлова са 47 додато и 15 уклоњено
  1. 11 0
      lisp/ChangeLog
  2. 30 13
      lisp/org-exp.el
  3. 6 2
      lisp/org-export-latex.el

+ 11 - 0
lisp/ChangeLog

@@ -1,5 +1,16 @@
 2008-11-16  Carsten Dominik  <carsten.dominik@gmail.com>
 
+	* org-export-latex.el (org-export-latex-subcontent): Interprete
+	target aliases as additonal labels.
+
+	* org-exp.el (org-export-target-aliases): New variable.
+	(org-export-preprocess-string)
+	(org-export-handle-invisible-targets): Fill the alias alist.
+	(org-export-as-html): Remove the &nbsp; from the anchor, and also
+	assign an id.
+	(org-html-level-start): Insert the target aliases as additonal
+	anchors.
+
 	* org.el (org-edit-fixed-width-region): Fix bug when sarting a new
 	picture area.
 

+ 30 - 13
lisp/org-exp.el

@@ -1415,6 +1415,9 @@ translations.  There is currently no way for users to extend this.")
 
 ;;; General functions for all backends
 
+(defvar org-export-target-aliases nil
+  "Alist of targets with invisible aliases.")
+
 (defun org-export-preprocess-string (string &rest parameters)
   "Cleanup STRING so that that the true exported has a more consistent source.
 This function takes STRING, which should be a buffer-string of an org-file
@@ -1431,6 +1434,8 @@ on this string to produce the exported version."
 	 (outline-regexp "\\*+ ")
 	 target-alist rtn)
 
+    (setq org-export-target-aliases nil)
+
     (with-current-buffer (get-buffer-create " org-mode-tmp")
       (erase-buffer)
       (insert string)
@@ -1576,7 +1581,7 @@ The new targets are added to TARGET-ALIST, which is also returned."
 (defun org-export-handle-invisible-targets (target-alist)
   "Find targets in comments and move them out of comments.
 Mark them as invisible targets."
-  (let (target tmp)
+  (let (target tmp a)
     (goto-char (point-min))
     (while (re-search-forward "^#.*?\\(<<<?\\([^>\r\n]+\\)>>>?\\).*" nil t)
       ;; Check if the line before or after is a headline with a target
@@ -1587,8 +1592,13 @@ Mark them as invisible targets."
 	    (setq tmp (match-string 2))
 	    (replace-match "")
 	    (and (looking-at "\n") (delete-char 1))
-	    (push (cons (org-solidify-link-text tmp) target)
-		  target-alist))
+	    (push (cons (setq tmp (org-solidify-link-text tmp)) target)
+		  target-alist)
+	    (setq a (or (assoc target org-export-target-aliases)
+			(progn
+			  (push (list target) org-export-target-aliases)
+			  (car org-export-target-aliases))))
+	    (push tmp (cdr a)))
 	;; Make an invisible target
 	(replace-match "\\1(INVISIBLE)"))))
   target-alist)
@@ -3184,9 +3194,10 @@ lang=\"%s\" xml:lang=\"%s\">
 	    (cond
 	     ((match-end 2)
 	      (setq line (replace-match
-			  (concat "@<a name=\""
-				  (org-solidify-link-text (match-string 1 line))
-				  "\">\\nbsp@</a>")
+			  (format
+			   "@<a name=\"%s\" id=\"%s\">@</a>"
+			   (org-solidify-link-text (match-string 1 line))
+			   (org-solidify-link-text (match-string 1 line)))
 			  t t line)))
 	     ((and org-export-with-toc (equal (string-to-char line) ?*))
 	      ;; FIXME: NOT DEPENDENT on TOC?????????????????????
@@ -4151,9 +4162,15 @@ stacked delimiters is N.  Escaping delimiters is not possible."
   "Insert a new level in HTML export.
 When TITLE is nil, just close all open levels."
   (org-close-par-maybe)
-  (let ((target (and title (org-get-text-property-any 0 'target title)))
-	(l org-level-max)
-	snumber)
+  (let* ((target (and title (org-get-text-property-any 0 'target title)))
+	 (extra-targets
+	  (mapconcat (lambda (x)
+		       (format "<a name=\"%s\" id=\"%s\"></a>"
+			       x x))
+		     (cdr (assoc target org-export-target-aliases))
+		     ""))
+	 (l org-level-max)
+	 snumber)
     (while (>= l level)
       (if (aref org-levels-open (1- l))
 	  (progn
@@ -4181,13 +4198,13 @@ When TITLE is nil, just close all open levels."
 		(progn
 		  (org-close-li)
 		  (if target
-		      (insert (format "<li id=\"%s\">" target) title "<br/>\n")
+		      (insert (format "<li id=\"%s\">" target) extra-targets title "<br/>\n")
 		    (insert "<li>" title "<br/>\n")))
 	      (aset org-levels-open (1- level) t)
 	      (org-close-par-maybe)
 	      (if target
 		  (insert (format "<ul>\n<li id=\"%s\">" target)
-			  title "<br/>\n")
+			  extra-targets title "<br/>\n")
 		(insert "<ul>\n<li>" title "<br/>\n"))))
 	(aset org-levels-open (1- level) t)
 	(setq snumber (org-section-number level))
@@ -4195,8 +4212,8 @@ When TITLE is nil, just close all open levels."
 	    (setq title (concat snumber " " title)))
 	(setq level (+ level org-export-html-toplevel-hlevel -1))
 	(unless (= head-count 1) (insert "\n</div>\n"))
-	(insert (format "\n<div id=\"outline-container-%s\" class=\"outline-%d\">\n<h%d id=\"sec-%s\">%s</h%d>\n<div id=\"text-%s\">\n"
-			snumber level level snumber title level snumber))
+	(insert (format "\n<div id=\"outline-container-%s\" class=\"outline-%d\">\n<h%d id=\"sec-%s\">%s%s</h%d>\n<div id=\"text-%s\">\n"
+			snumber level level snumber extra-targets title level snumber))
 	(org-open-par)))))
 
 (defun org-get-text-property-any (pos prop &optional object)

+ 6 - 2
lisp/org-export-latex.el

@@ -613,7 +613,9 @@ If NUM, export sections as numerical sections."
 	 (occur (number-to-string (cdr (assoc 'occur subcontent))))
 	 (content (cdr (assoc 'content subcontent)))
 	 (subcontent (cadr (assoc 'subcontent subcontent)))
-	 (label (org-get-text-property-any 0 'target heading)))
+	 (label (org-get-text-property-any 0 'target heading))
+	 (label-list (cons label (cdr (assoc label
+					     org-export-target-aliases)))))
     (cond
      ;; Normal conversion
      ((<= level org-export-latex-sectioning-depth)
@@ -624,7 +626,9 @@ If NUM, export sections as numerical sections."
 		  end (nth (if num 1 3) sec))
 	  (setq start (if num (car sec) (cdr sec))))
 	(insert (format start heading) "\n")
-	(when label (insert (format "\\label{%s}\n" label)))
+	(when label
+	  (insert (mapconcat (lambda (l) (format "\\label{%s}" l))
+			     label-list "\n") "\n"))
 	(insert (org-export-latex-content content))
 	(cond ((stringp subcontent) (insert subcontent))
 	      ((listp subcontent) (org-export-latex-sub subcontent)))