branch: elpa/adoc-mode
commit 9f54d7bf1972c66c83e639dc617bcc10cd6c8eec
Author: Bozhidar Batsov <[email protected]>
Commit: Bozhidar Batsov <[email protected]>

    [Fix #65] Resolve attribute references in image paths
    
    Image macros using attribute references (e.g. image:{my-badge}[])
    now resolve the reference against :name: value entries defined in the
    document before attempting to display the image.
---
 adoc-mode-image.el           | 26 ++++++++++++++++++++++++++
 test/adoc-mode-image-test.el | 26 ++++++++++++++++++++++++++
 2 files changed, 52 insertions(+)

diff --git a/adoc-mode-image.el b/adoc-mode-image.el
index acb64a79c6..22ad4b54e8 100644
--- a/adoc-mode-image.el
+++ b/adoc-mode-image.el
@@ -73,6 +73,31 @@ See also `adoc-display-remote-images'."
 (defconst adoc-re-image "\\<image::?\\([^]]+\\)\\(\\[[^]]*\\]\\)"
   "Regexp matching block- and inline-images.")
 
+(defun adoc--resolve-attribute-references (str)
+  "Resolve AsciiDoc attribute references in STR.
+Replaces occurrences of {name} with the value defined by
+`:name: value' attribute entries in the current buffer.
+References without a matching definition are left unchanged."
+  (if (not (string-match-p "{" str))
+      str
+    (let ((attrs (make-hash-table :test 'equal)))
+      (save-excursion
+        (save-restriction
+          (widen)
+          (goto-char (point-min))
+          (while (re-search-forward
+                  "^:\\([a-zA-Z0-9_][^.\n]*?\\(?:\\..*?\\)?\\):[ 
\t]+\\(.*?\\)$"
+                  nil t)
+            (puthash (match-string-no-properties 1)
+                     (match-string-no-properties 2)
+                     attrs))))
+      (replace-regexp-in-string
+       "{\\([^}\n]+\\)}"
+       (lambda (match)
+         (let ((name (match-string 1 match)))
+           (gethash name attrs match)))
+       str t t))))
+
 (defvar adoc-image-overlay-functions nil
   "Functions called after the creation of an image overlay.
 Each function is called with the created overlay as argument.")
@@ -116,6 +141,7 @@ Each function is called with the created overlay as 
argument.")
 
 (defun adoc-create-image-overlay (file start end)
   "Create image overlay with START and END displaying image FILE."
+  (setq file (adoc--resolve-attribute-references file))
   (when (not (zerop (length file)))
     (unless (file-exists-p file)
       (when adoc-display-remote-images
diff --git a/test/adoc-mode-image-test.el b/test/adoc-mode-image-test.el
index 4c5ae4fda2..0a5b5f7146 100644
--- a/test/adoc-mode-image-test.el
+++ b/test/adoc-mode-image-test.el
@@ -63,4 +63,30 @@
                   "title" adoc-attribute-face "=" adoc-meta-face
                   "lorem\nipsum\nsit" adoc-secondary-text-face "]" 
adoc-meta-face "\n" nil))
 
+(ert-deftest adoctest-test-resolve-attribute-references ()
+  (with-temp-buffer
+    (adoc-mode)
+    (insert ":my-url: https://example.com/image.png\n";
+            ":badge: http://melpa.org/badge.svg\n";
+            "\n"
+            "image:{my-url}[]\n"
+            "image:{badge}[alt]\n"
+            "image:{undefined}[]\n"
+            "image:plain.png[]\n")
+    ;; Single reference
+    (should (equal (adoc--resolve-attribute-references "{my-url}")
+                   "https://example.com/image.png";))
+    ;; Another reference
+    (should (equal (adoc--resolve-attribute-references "{badge}")
+                   "http://melpa.org/badge.svg";))
+    ;; Undefined reference is left unchanged
+    (should (equal (adoc--resolve-attribute-references "{undefined}")
+                   "{undefined}"))
+    ;; No references - returned as-is
+    (should (equal (adoc--resolve-attribute-references "plain.png")
+                   "plain.png"))
+    ;; Empty string
+    (should (equal (adoc--resolve-attribute-references "")
+                   ""))))
+
 ;;; adoc-mode-image-test.el ends here

Reply via email to