* Re: Standalone hyperlinked images in HTML export
2013-06-30 20:07 Standalone hyperlinked images in HTML export Kodi Arfer
2013-06-30 22:08 ` Bastien
@ 2013-07-01 21:01 ` Nicolas Goaziou
2013-07-01 21:26 ` Kodi Arfer
1 sibling, 1 reply; 6+ messages in thread
From: Nicolas Goaziou @ 2013-07-01 21:01 UTC (permalink / raw)
To: Kodi Arfer; +Cc: emacs-orgmode
[-- Attachment #1: Type: text/plain, Size: 1195 bytes --]
Hello,
Kodi Arfer <kodi@arfer.net> writes:
> The manual explains in "Images in HTML export" that you can make an
> image a hyperlink like this:
>
> [[file:highres.jpg][file:thumb.jpg]]
>
> where thumb.jpg becomes the <img> 'src' and highres.jpg becomes the <a>
> 'href'. One might infer it should also be possible to link to something
> other than an image, like this:
>
> [[http://gnu.org][http://example.com/gnu-head.jpg]]
>
> For example, try exporting this file:
>
> #+begin_src org
> Some initial text.
>
> [[http://example.com/a.png]]
>
> Some text between images 1 and 2.
>
> [[http://eeyup.com][http://example.com/b.png]]
>
> Some text between images 2 and 3.
>
> http://example.com/c.png
>
> Some trailing text.
> #+end_src
>
> You do indeed get
>
> <a href="http://eeyup.com"><img src="http://example.com/b.png"
> alt="b.png" /></a>
>
> in the output, but the exporter doesn't regard the image as standalone,
> so it doesn't get put in a <div> (or, in HTML5 mode, <figure>) like the
> others, and if you add a #+CAPTION, no caption will be included.
Indeed. Would you mind testing the following patch against master? It
should fix the issues.
Regards,
--
Nicolas Goaziou
[-- Warning: decoded text below may be mangled, UTF-8 assumed --]
[-- Attachment #2: 0001-ox-html-Fix-standalone-hyperlinked-images.patch --]
[-- Type: text/x-diff, Size: 14651 bytes --]
From b20ae9f2cc1af67250af9917541b071ab778f36f Mon Sep 17 00:00:00 2001
From: Nicolas Goaziou <n.goaziou@gmail.com>
Date: Mon, 1 Jul 2013 22:51:26 +0200
Subject: [PATCH] ox-html: Fix standalone hyperlinked images
* lisp/ox-html.el (org-html-inline-images): Change default value and
remove `maybe'.
(org-html-format-inline-image): Remove functions.
(org-html--wrap-image, org-html--format-image,
org-html-inline-image-p): New functions.
(org-html-latex-environment, org-html-latex-fragment): Use new
functions.
(org-html-standalone-image-p): Use new functions. Also remove an
unused optional argument.
(org-html-link, org-html-paragraph): Correctly export hyperlinked
images.
This patch permits the back-end to recognize links like:
[[http://orgmode.org][http://orgmode.org/img/org-mode-unicorn-logo.png]]
as standalone, so they can get wrapped within a proper environment and
get captions.
Thanks to Kodi Arfer for reporting it.
---
lisp/ox-html.el | 257 +++++++++++++++++++++++++++-----------------------------
1 file changed, 124 insertions(+), 133 deletions(-)
diff --git a/lisp/ox-html.el b/lisp/ox-html.el
index 4753e66..b8d927f 100644
--- a/lisp/ox-html.el
+++ b/lisp/ox-html.el
@@ -713,16 +713,14 @@ When nil, the links still point to the plain `.org' file."
;;;; Links :: Inline images
-(defcustom org-html-inline-images 'maybe
+(defcustom org-html-inline-images t
"Non-nil means inline images into exported HTML pages.
This is done using an <img> tag. When nil, an anchor with href is used to
-link to the image. If this option is `maybe', then images in links with
-an empty description will be inlined, while images with a description will
-be linked only."
+link to the image."
:group 'org-export-html
- :type '(choice (const :tag "Never" nil)
- (const :tag "Always" t)
- (const :tag "When there is no description" maybe)))
+ :version "24.4"
+ :package-version '(Org . "8.1")
+ :type 'boolean)
(defcustom org-html-inline-image-rules
'(("file" . "\\.\\(jpeg\\|jpg\\|png\\|gif\\|svg\\)\\'")
@@ -1326,39 +1324,43 @@ attributes with a nil value will be omitted from the result."
"\"" """ (org-html-encode-plain-text item))))
(setcar output (format "%s=\"%s\"" key value))))))))
-(defun org-html-format-inline-image (src info &optional
- caption label attr standalone-p)
- "Format an inline image from SRC.
-CAPTION, LABEL and ATTR are optional arguments providing the
-caption, the label and the attribute of the image.
-When STANDALONE-P is t, wrap the <img.../> into a <div>...</div>."
- (let* ((id (if (not label) ""
- (format " id=\"%s\"" (org-export-solidify-link-text label))))
- (attr (concat attr
- (format " src=\"%s\"" src)
- (cond
- ((string-match "\\<alt=" (or attr "")) "")
- ((string-match "^ltxpng/" src)
- (format " alt=\"%s\""
- (org-html-encode-plain-text
- (org-find-text-property-in-string
- 'org-latex-src src))))
- (t (format " alt=\"%s\""
- (file-name-nondirectory src))))))
- (html5-fancy (and (org-html-html5-p info)
- (plist-get info :html-html5-fancy))))
- (cond
- (standalone-p
- (let ((img (org-html-close-tag "img" attr info)))
- (format (if html5-fancy
- "\n<figure%s>%s%s\n</figure>"
- "\n<div%s class=\"figure\">%s%s\n</div>")
- id (format "\n<p>%s</p>" img)
- (if (and caption (not (string= caption "")))
- (format (if html5-fancy
- "\n<figcaption>%s</figcaption>"
- "\n<p>%s</p>") caption) ""))))
- (t (org-html-close-tag "img" (concat attr id) info)))))
+(defun org-html--wrap-image (contents info &optional caption label)
+ "Wrap CONTENTS string within an appropriate environment for images.
+INFO is a plist used as a communication channel. When optional
+arguments CAPTION and LABEL are given, use them for caption and
+\"id\" attribute."
+ (let ((html5-fancy (and (org-html-html5-p info)
+ (plist-get info :html-html5-fancy))))
+ (format (if html5-fancy "\n<figure%s>%s%s\n</figure>"
+ "\n<div%s class=\"figure\">%s%s\n</div>")
+ ;; ID.
+ (if (not (org-string-nw-p label)) ""
+ (format " id=\"%s\"" (org-export-solidify-link-text label)))
+ ;; Contents.
+ (format "\n<p>%s</p>" contents)
+ ;; Caption.
+ (if (not (org-string-nw-p caption)) ""
+ (format (if html5-fancy "\n<figcaption>%s</figcaption>"
+ "\n<p>%s</p>")
+ caption)))))
+
+(defun org-html--format-image (source attributes info)
+ "Return \"img\" tag with given SOURCE and ATTRIBUTES.
+SOURCE is a string specifying the location of the image.
+ATTRIBUTES is a plist, as returned by
+`org-export-read-attribute'. INFO is a plist used as
+a communication channel."
+ (org-html-close-tag
+ "img"
+ (org-html--make-attribute-string
+ (org-combine-plists
+ (list :src source
+ :alt (if (string-match-p "^ltxpng/" source)
+ (org-html-encode-plain-text
+ (org-find-text-property-in-string 'org-latex-src source))
+ (file-name-nondirectory source)))
+ attributes))
+ info))
(defun org-html--textarea-block (element)
"Transcode ELEMENT into a textarea block.
@@ -2478,21 +2480,19 @@ CONTENTS is nil. INFO is a plist holding contextual information."
(let ((processing-type (plist-get info :with-latex))
(latex-frag (org-remove-indentation
(org-element-property :value latex-environment)))
- (caption (org-export-data
- (org-export-get-caption latex-environment) info))
- (attr nil) ; FIXME
- (label (org-element-property :name latex-environment)))
- (cond
- ((memq processing-type '(t mathjax))
- (org-html-format-latex latex-frag 'mathjax))
- ((eq processing-type 'dvipng)
- (let* ((formula-link (org-html-format-latex
- latex-frag processing-type)))
- (when (and formula-link
- (string-match "file:\\([^]]*\\)" formula-link))
- (org-html-format-inline-image
- (match-string 1 formula-link) info caption label attr t))))
- (t latex-frag))))
+ (attributes (org-export-read-attribute :attr_html latex-environment)))
+ (case processing-type
+ ((t mathjax)
+ (org-html-format-latex latex-frag 'mathjax))
+ (dvipng
+ (let ((formula-link (org-html-format-latex latex-frag processing-type)))
+ (when (and formula-link (string-match "file:\\([^]]*\\)" formula-link))
+ ;; Do not provide a caption or a name to be consistent with
+ ;; `mathjax' handling.
+ (org-html--wrap-image
+ (org-html--format-image
+ (match-string 1 formula-link) attributes info) info))))
+ (t latex-frag))))
;;;; Latex Fragment
@@ -2505,12 +2505,9 @@ CONTENTS is nil. INFO is a plist holding contextual information."
((t mathjax)
(org-html-format-latex latex-frag 'mathjax))
(dvipng
- (let* ((formula-link (org-html-format-latex
- latex-frag processing-type)))
- (when (and formula-link
- (string-match "file:\\([^]]*\\)" formula-link))
- (org-html-format-inline-image
- (match-string 1 formula-link) info))))
+ (let ((formula-link (org-html-format-latex latex-frag processing-type)))
+ (when (and formula-link (string-match "file:\\([^]]*\\)" formula-link))
+ (org-html--format-image (match-string 1 formula-link) nil info))))
(t latex-frag))))
;;;; Line Break
@@ -2522,41 +2519,30 @@ CONTENTS is nil. INFO is a plist holding contextual information."
;;;; Link
-(defun org-html-link--inline-image (link desc info)
- "Return HTML code for an inline image.
-
-LINK is the link pointing to the inline image. INFO is a plist
-used as a communication channel.
-
-Inline images can have these attributes:
-
-#+ATTR_HTML: :width 100px :height 100px :alt \"Alt description\"."
- (let* ((type (org-element-property :type link))
- (raw-path (org-element-property :path link))
- (path (cond ((member type '("http" "https"))
- (concat type ":" raw-path))
- ((file-name-absolute-p raw-path)
- (expand-file-name raw-path))
- (t raw-path)))
- (parent (org-export-get-parent-element link))
- (caption
- (let ((raw (org-export-data (org-export-get-caption parent) info))
- (org-html-standalone-image-predicate 'org-html--has-caption-p))
- (if (not (org-string-nw-p raw)) raw
- (concat (format (org-html--translate "Figure %d:" info)
- (org-export-get-ordinal
- link info nil 'org-html-standalone-image-p))
- " " raw))))
- (label (org-element-property :name parent)))
- ;; Return proper string, depending on DISPOSITION.
- (org-html-format-inline-image
- path info caption label
- (org-html--make-attribute-string
- (org-export-read-attribute :attr_html parent))
- (org-html-standalone-image-p link info))))
+(defun org-html-inline-image-p (link info)
+ "Non-nil when LINK stands for an inline image.
+INFO is a plist used as a communication channel. LINK is an
+inline image when it has no description and targets an image
+file (see `org-html-inline-image-rules' for more information), or
+if its description is a single link targeting an image file."
+ (if (not (org-element-contents link))
+ (org-export-inline-image-p link org-html-inline-image-rules)
+ (not
+ (let ((link-count 0))
+ (org-element-map (org-element-contents link)
+ (cons 'plain-text org-element-all-objects)
+ (lambda (obj)
+ (case (org-element-type obj)
+ (plain-text (org-string-nw-p obj))
+ (link (if (= link-count 1) t
+ (incf link-count)
+ (not (org-export-inline-image-p
+ obj org-html-inline-image-rules))))
+ (otherwise t)))
+ info t)))))
(defvar org-html-standalone-image-predicate)
-(defun org-html-standalone-image-p (element info &optional predicate)
+(defun org-html-standalone-image-p (element info)
"Test if ELEMENT is a standalone image for the purpose HTML export.
INFO is a plist holding contextual information.
@@ -2570,34 +2556,29 @@ whitespaces.
Return nil, otherwise.
-Bind `org-html-standalone-image-predicate' to constrain
-paragraph further. For example, to check for only captioned
-standalone images, do the following.
+Bind `org-html-standalone-image-predicate' to constrain paragraph
+further. For example, to check for only captioned standalone
+images, set it to:
- \(setq org-html-standalone-image-predicate
- \(lambda \(paragraph\)
- \(org-element-property :caption paragraph\)\)\)"
+ \(lambda (paragraph) (org-element-property :caption paragraph))"
(let ((paragraph (case (org-element-type element)
(paragraph element)
- (link (and (org-export-inline-image-p
- element org-html-inline-image-rules)
- (org-export-get-parent element)))
- (t nil))))
- (when (eq (org-element-type paragraph) 'paragraph)
- (when (or (not (and (boundp 'org-html-standalone-image-predicate)
- (functionp org-html-standalone-image-predicate)))
- (funcall org-html-standalone-image-predicate paragraph))
- (let ((contents (org-element-contents paragraph)))
- (loop for x in contents
- with inline-image-count = 0
- always (cond
- ((eq (org-element-type x) 'plain-text)
- (not (org-string-nw-p x)))
- ((eq (org-element-type x) 'link)
- (when (org-export-inline-image-p
- x org-html-inline-image-rules)
- (= (incf inline-image-count) 1)))
- (t nil))))))))
+ (link (and (org-html-inline-image-p element info)
+ (org-export-get-parent element))))))
+ (and (eq (org-element-type paragraph) 'paragraph)
+ (or (not (and (boundp 'org-html-standalone-image-predicate)
+ (functionp org-html-standalone-image-predicate)))
+ (funcall org-html-standalone-image-predicate paragraph))
+ (not (let ((link-count 0))
+ (org-element-map (org-element-contents paragraph)
+ (cons 'plain-text org-element-all-objects)
+ (lambda (obj) (case (org-element-type obj)
+ (plain-text (org-string-nw-p obj))
+ (link
+ (or (> (incf link-count) 1)
+ (not (org-html-inline-image-p obj info))))
+ (otherwise t)))
+ info 'first-match 'link))))))
(defun org-html-link (link desc info)
"Transcode a LINK object from Org to HTML.
@@ -2656,22 +2637,17 @@ INFO is a plist holding contextual information. See
;; Extract attributes from parent's paragraph. HACK: Only do
;; this for the first link in parent. This is needed as long
;; as attributes cannot be set on a per link basis.
- (attributes
+ (attributes-plist
(let ((parent (org-export-get-parent-element link)))
- (if (not (eq (org-element-map parent 'link 'identity info t) link))
- ""
- (let ((att (org-html--make-attribute-string
- (org-export-read-attribute :attr_html parent))))
- (cond ((not (org-string-nw-p att)) "")
- ((and desc (string-match (regexp-quote att) desc)) "")
- (t (concat " " att)))))))
+ (and (eq (org-element-map parent 'link 'identity info t) link)
+ (org-export-read-attribute :attr_html parent))))
+ (attributes (org-html--make-attribute-string attributes-plist))
protocol)
(cond
;; Image file.
- ((and (or (eq t org-html-inline-images)
- (and org-html-inline-images (not desc)))
+ ((and org-html-inline-images
(org-export-inline-image-p link org-html-inline-image-rules))
- (org-html-link--inline-image link desc info))
+ (org-html--format-image path attributes-plist info))
;; Radio target: Transcode target's contents and use them as
;; link's description.
((string= type "radio")
@@ -2791,11 +2767,26 @@ the plist used as a communication channel."
((and (eq (org-element-type parent) 'item)
(= (org-element-property :begin paragraph)
(org-element-property :contents-begin parent)))
- ;; leading paragraph in a list item have no tags
+ ;; Leading paragraph in a list item have no tags.
contents)
((org-html-standalone-image-p paragraph info)
- ;; standalone image
- contents)
+ ;; Standalone image.
+ (let ((caption
+ (let ((raw (org-export-data
+ (org-export-get-caption paragraph) info))
+ (org-html-standalone-image-predicate
+ 'org-html--has-caption-p))
+ (if (not (org-string-nw-p raw)) raw
+ (concat
+ (format (org-html--translate "Figure %d:" info)
+ (org-export-get-ordinal
+ (org-element-map paragraph 'link
+ 'identity info t)
+ info nil 'org-html-standalone-image-p))
+ " " raw))))
+ (label (org-element-property :name paragraph)))
+ (org-html--wrap-image contents info caption label)))
+ ;; Regular paragraph.
(t (format "<p%s>\n%s</p>" extra contents)))))
;;;; Plain List
--
1.8.3.2
^ permalink raw reply related [flat|nested] 6+ messages in thread