ox-ascii: Fix internal and ID links

* lisp/ox-ascii.el (org-ascii--describe-datum): New function.
(org-ascii--describe-links): Use new function.  Do not ignore fuzzy
links anymore when they contain a description.
(org-ascii-link): Use new function.  Better handling of internal
links.
* lisp/ox.el (org-export-dictionary): New entries: "See figure %s",
  "See listing %s", "See table %s".

Reported-by: Samuel Wales <samologist@gmail.com>
<http://permalink.gmane.org/gmane.emacs.orgmode/110788>
This commit is contained in:
Nicolas Goaziou 2016-12-15 15:59:11 +01:00
parent 51227cff94
commit 3e60cb900d
2 changed files with 92 additions and 44 deletions

View File

@ -896,41 +896,71 @@ is a plist used as a communication channel."
(car (org-element-contents element)))) (car (org-element-contents element))))
'link unique-link-p info nil 'headline t))) 'link unique-link-p info nil 'headline t)))
(defun org-ascii--describe-datum (datum info)
"Describe DATUM object or element.
If DATUM is a string, consider it to be a file name, per
`org-export-resolve-id-link'. INFO is the communication channel,
as a plist."
(pcase (org-element-type datum)
(`plain-text (format "See file %s" datum)) ;External file
(`headline
(format (org-ascii--translate "See section %s" info)
(if (org-export-numbered-headline-p datum info)
(mapconcat #'number-to-string
(org-export-get-headline-number datum info)
".")
(org-export-data (org-element-property :title datum) info))))
(_
(let ((number (org-export-get-ordinal
datum info nil #'org-ascii--has-caption-p))
;; If destination is a target, make sure we can name the
;; container it refers to.
(enumerable
(org-element-lineage datum '(headline paragrah src-block table) t)))
(pcase (org-element-type enumerable)
(`headline
(format (org-ascii--translate "See section %s" info)
(if (org-export-numbered-headline-p enumerable info)
(mapconcat #'number-to-string number ".")
(org-export-data
(org-element-property :title enumerable) info))))
((guard (not number))
(org-ascii--translate "Unknown reference" info))
(`paragraph
(format (org-ascii--translate "See figure %s" info) number))
(`src-block
(format (org-ascii--translate "See listing %s" info) number))
(`table
(format (org-ascii--translate "See table %s" info) number))
(_ (org-ascii--translate "Unknown reference" info)))))))
(defun org-ascii--describe-links (links width info) (defun org-ascii--describe-links (links width info)
"Return a string describing a list of links. "Return a string describing a list of links.
LINKS is a list of link type objects, as returned by LINKS is a list of link type objects, as returned by
`org-ascii--unique-links'. WIDTH is the text width allowed for `org-ascii--unique-links'. WIDTH is the text width allowed for
the output string. INFO is a plist used as a communication the output string. INFO is a plist used as a communication
channel." channel."
(mapconcat (mapconcat
(lambda (link) (lambda (link)
(let ((type (org-element-property :type link)) (let* ((type (org-element-property :type link))
(anchor (let ((desc (org-element-contents link))) (description (org-element-contents link))
(if desc (org-export-data desc info) (anchor (org-export-data
(org-element-property :raw-link link))))) (or description (org-element-property :raw-link link))
info)))
(cond (cond
;; Coderefs, radio links and fuzzy links are ignored. ((member type '("coderef" "radio")) nil)
((member type '("coderef" "radio" "fuzzy")) nil) ((member type '("custom-id" "fuzzy" "id"))
;; Id and custom-id links: Headlines refer to their numbering. ;; Only links with a description need an entry. Other are
((member type '("custom-id" "id")) ;; already handled in `org-ascii-link'.
(let ((dest (org-export-resolve-id-link link info))) (when description
(concat (let ((dest (if (equal type "fuzzy")
(org-ascii--fill-string (org-export-resolve-fuzzy-link link info)
(format (org-export-resolve-id-link link info))))
"[%s] %s" (concat
anchor (org-ascii--fill-string
(if (stringp dest) ; External file. (format "[%s] %s" anchor (org-ascii--describe-datum dest info))
dest width info)
(format "\n\n"))))
(org-ascii--translate "See section %s" info)
(if (org-export-numbered-headline-p dest info)
(mapconcat #'number-to-string
(org-export-get-headline-number dest info)
".")
(org-export-data (org-element-property :title dest) info)))))
width info)
"\n\n")))
;; Do not add a link that cannot be resolved and doesn't have ;; Do not add a link that cannot be resolved and doesn't have
;; any description: destination is already visible in the ;; any description: destination is already visible in the
;; paragraph. ;; paragraph.
@ -1541,24 +1571,33 @@ INFO is a plist holding contextual information."
;; Do not apply a special syntax on radio links. Though, use ;; Do not apply a special syntax on radio links. Though, use
;; transcoded target's contents as output. ;; transcoded target's contents as output.
((string= type "radio") desc) ((string= type "radio") desc)
;; Do not apply a special syntax on fuzzy links pointing to ((member type '("custom-id" "fuzzy" "id"))
;; targets. (let ((destination (if (string= type "fuzzy")
((string= type "fuzzy") (org-export-resolve-fuzzy-link link info)
(let ((destination (org-export-resolve-fuzzy-link link info))) (org-export-resolve-id-link link info))))
(if (org-string-nw-p desc) desc (pcase (org-element-type destination)
(when destination ((guard desc)
(let ((number (if (plist-get info :ascii-links-to-notes)
(org-export-get-ordinal (format "[%s]" desc)
destination info nil 'org-ascii--has-caption-p))) (concat desc
(if number (format " (%s)"
(if (atom number) (number-to-string number) (org-ascii--describe-datum destination info)))))
(mapconcat #'number-to-string number ".")) ;; External file.
;; Unnumbered headline. (`plain-text destination)
(when (eq 'headline (org-element-type destination)) (`headline
(format "[%s]" (if (org-export-numbered-headline-p destination info)
(org-export-data (mapconcat #'number-to-string
(org-element-property :title destination) (org-export-get-headline-number destination info)
info))))))))) ".")
(org-export-data (org-element-property :title destination) info)))
;; Handle enumerable elements and targets within them.
((and (let number (org-export-get-ordinal
destination info nil #'org-ascii--has-caption-p))
(guard number))
(if (atom number) (number-to-string number)
(mapconcat #'number-to-string number ".")))
;; Don't know what to do. Signal it.
(_ "???"))))
(t (t
(let ((raw-link (org-element-property :raw-link link))) (let ((raw-link (org-element-property :raw-link link)))
(if (not (org-string-nw-p desc)) (format "[%s]" raw-link) (if (not (org-string-nw-p desc)) (format "[%s]" raw-link)

View File

@ -5744,6 +5744,12 @@ them."
("fr" :ascii "References" :default "Références") ("fr" :ascii "References" :default "Références")
("de" :default "Quellen") ("de" :default "Quellen")
("es" :default "Referencias")) ("es" :default "Referencias"))
("See figure %s"
("fr" :default "cf. figure %s"
:html "cf.&nbsp;figure&nbsp;%s" :latex "cf.~figure~%s"))
("See listing %s"
("fr" :default "cf. programme %s"
:html "cf.&nbsp;programme&nbsp;%s" :latex "cf.~programme~%s"))
("See section %s" ("See section %s"
("da" :default "jævnfør afsnit %s") ("da" :default "jævnfør afsnit %s")
("de" :default "siehe Abschnitt %s") ("de" :default "siehe Abschnitt %s")
@ -5756,6 +5762,9 @@ them."
("ru" :html "&#1057;&#1084;. &#1088;&#1072;&#1079;&#1076;&#1077;&#1083; %s" ("ru" :html "&#1057;&#1084;. &#1088;&#1072;&#1079;&#1076;&#1077;&#1083; %s"
:utf-8 "См. раздел %s") :utf-8 "См. раздел %s")
("zh-CN" :html "&#21442;&#35265;&#31532;%s&#33410;" :utf-8 "参见第%s节")) ("zh-CN" :html "&#21442;&#35265;&#31532;%s&#33410;" :utf-8 "参见第%s节"))
("See table %s"
("fr" :default "cf. tableau %s"
:html "cf.&nbsp;tableau&nbsp;%s" :latex "cf.~tableau~%s"))
("Table" ("Table"
("de" :default "Tabelle") ("de" :default "Tabelle")
("es" :default "Tabla") ("es" :default "Tabla")