summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorNicolas Goaziou <mail@nicolasgoaziou.fr>2015-04-13 14:03:50 +0200
committerNicolas Goaziou <mail@nicolasgoaziou.fr>2015-04-13 15:37:27 +0200
commitcd7cbdcda870a8bc4b6c578efd9a037ed38caaab (patch)
tree1fade8eb4596ad130d9d78ddd690f2b72a93e9d4
parent4bbc054bd252b975f483a29515495a9af9329c71 (diff)
downloadorg-mode-cd7cbdcda870a8bc4b6c578efd9a037ed38caaab.tar.gz
ox-publish: Extend published external links
* lisp/ox-publish.el (org-publish-collect-numbering): (org-publish-resolve-external-fuzzy-link): Remove functions. (org-publish--collect-references, org-publish-resolve-external-link): New functions. (org-publish-org-to): Use new functions. * lisp/ox-html.el (org-html-link): Reflect changes above. This patch extends `org-publish-resolve-external-fuzzy-link', now known as `org-publish-resolve-external-link' to custom-id links and dedicated targets.
-rw-r--r--lisp/ox-html.el22
-rw-r--r--lisp/ox-publish.el101
2 files changed, 88 insertions, 35 deletions
diff --git a/lisp/ox-html.el b/lisp/ox-html.el
index 073e379..87856c0 100644
--- a/lisp/ox-html.el
+++ b/lisp/ox-html.el
@@ -2838,21 +2838,15 @@ INFO is a plist holding contextual information. See
((and home use-abs-url)
(setq raw-path (concat (file-name-as-directory home) raw-path))))
;; Add search option, if any. A search option can be
- ;; relative to a custom-id or a headline title. Append
- ;; a hash sign to any unresolved option, as it might point
- ;; to a target.
+ ;; relative to a custom-id, a headline title a name,
+ ;; a target or a radio-target.
(let ((option (org-element-property :search-option link)))
- (cond ((not option) raw-path)
- ((eq (aref option 0) ?#) (concat raw-path option))
- (t
- (let ((destination
- (org-publish-resolve-external-fuzzy-link
- (org-element-property :path link) option)))
- (concat raw-path
- (if (not destination) (concat "#" option)
- (concat "#sec-"
- (mapconcat #'number-to-string
- destination "-")))))))))
+ (if (not option) raw-path
+ (concat raw-path
+ "#"
+ (org-publish-resolve-external-link
+ option
+ (org-element-property :path link))))))
(t raw-path)))
;; Extract attributes from parent's paragraph. HACK: Only do
;; this for the first link in parent (inner image link for
diff --git a/lisp/ox-publish.el b/lisp/ox-publish.el
index d450c0e..cf70e80 100644
--- a/lisp/ox-publish.el
+++ b/lisp/ox-publish.el
@@ -583,7 +583,7 @@ Return output file name."
(body-p (plist-get plist :body-only)))
(org-export-to-file backend output-file
nil nil nil body-p
- ;; Add `org-publish-collect-numbering' and
+ ;; Add `org-publish--collect-references' and
;; `org-publish-collect-index' to final output
;; filters. The latter isn't dependent on
;; `:makeindex', since we want to keep it up-to-date
@@ -591,7 +591,7 @@ Return output file name."
(org-combine-plists
plist
`(:filter-final-output
- ,(cons 'org-publish-collect-numbering
+ ,(cons 'org-publish--collect-references
(cons 'org-publish-collect-index
(plist-get plist :filter-final-output))))))))
;; Remove opened buffer in the process.
@@ -1068,31 +1068,90 @@ publishing directory."
;; This part implements tools to resolve [[file.org::*Some headline]]
;; links, where "file.org" belongs to the current project.
-(defun org-publish-collect-numbering (output backend info)
+(defun org-publish--collect-references (output backend info)
+ "Store headlines references for current published file.
+
+OUPUT is the produced output, as a string. BACKEND is the export
+back-end used, as a symbol. INFO is the final export state, as
+a plist.
+
+References are stored as an alist ((TYPE SEARCH) . VALUE) where
+
+ TYPE is a symbol among `headline', `custom-id', `target' and
+ `other'.
+
+ SEARCH is the string a link is expected to match. It is
+
+ - headline's title, as a string, with all whitespace
+ characters and statistics cookies removed, if TYPE is
+ `headline'.
+
+ - CUSTOM_ID value if TYPE is `custom-id'.
+
+ - target's or radio-target's name if TYPE is `target'.
+
+ - NAME affiliated keyword is TYPE is `other'.
+
+ VALUE is an internal reference used in the document, as
+ a string.
+
+This function is meant to be used as a final out filter. See
+`org-publish-org-to'."
(org-publish-cache-set-file-property
- (plist-get info :input-file) :numbering
- (mapcar (lambda (entry)
- (cons (org-split-string
- (replace-regexp-in-string
- "\\[[0-9]+%\\]\\|\\[[0-9]+/[0-9]+\\]" ""
- (org-element-property :raw-value (car entry))))
- (cdr entry)))
- (plist-get info :headline-numbering)))
+ (plist-get info :input-file) :references
+ (let (refs)
+ (when (hash-table-p (plist-get info :internal-references))
+ (maphash
+ (lambda (k v)
+ (case (org-element-type k)
+ ((headline inlinetask)
+ (push (cons
+ (cons 'headline
+ (replace-regexp-in-string
+ "\\[[0-9]+%\\]\\|\\[[0-9]+/[0-9]+\\]\\|[ \r\t\n]+" ""
+ (org-element-property :raw-value k)))
+ v)
+ refs)
+ (let ((custom-id (org-element-property :CUSTOM_ID k)))
+ (when custom-id
+ (push (cons (cons 'custom-id custom-id) v) refs))))
+ ((radio-target target)
+ (push
+ (cons (cons 'target
+ (replace-regexp-in-string
+ "[ \r\t\n]+" "" (org-element-property :value k)))
+ v)
+ refs))
+ ((org-element-property :name k)
+ (push (cons (cons 'other (org-element-property :name k)) v) refs)))
+ refs)
+ (plist-get info :internal-references)))
+ refs))
;; Return output unchanged.
output)
-(defun org-publish-resolve-external-fuzzy-link (file fuzzy)
- "Return numbering for headline matching FUZZY search in FILE.
+(defun org-publish-resolve-external-link (search file)
+ "Return reference for elements or objects matching SEARCH in FILE.
+
+Return value is an internal reference, as a string.
-Return value is a list of numbers, or nil. This function allows
-to resolve external fuzzy links like:
+This function allows to resolve external links like:
- [[file.org::*fuzzy][description]]"
- (when org-publish-cache
- (cdr (assoc (org-split-string
- (if (eq (aref fuzzy 0) ?*) (substring fuzzy 1) fuzzy))
- (org-publish-cache-get-file-property
- (expand-file-name file) :numbering nil t)))))
+ [[file.org::*fuzzy][description]]
+ [[file.org::#custom-id][description]]
+ [[file.org::fuzzy][description]]"
+ (let ((references (org-publish-cache-get-file-property
+ (expand-file-name file) :references nil t))
+ (search (replace-regexp-in-string "[ \r\t\n]+" "" search)))
+ (cond
+ ((cdr (case (aref search 0)
+ (?* (assoc (cons 'headline (substring search 1)) references))
+ (?# (assoc (cons 'custom-id (substring search 1)) references))
+ (t (or (assoc (cons 'target search) references)
+ (assoc (cons 'other search) references)
+ (assoc (cons 'headline search) references))))))
+ (t (message "Unknown cross-reference \"%s\" in file \"%s\"" search file)
+ "MissingReference"))))