emacs-orgmode
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: Links & images with different attributes in the same paragraph


From: Max Nikulin
Subject: Re: Links & images with different attributes in the same paragraph
Date: Tue, 12 Dec 2023 18:08:49 +0700
User-agent: Mozilla Thunderbird

On 05/12/2023 20:46, Ihor Radchenko wrote:

We definitely need something to fine-tune export properties inline.
However, I am skeptical about using links for this purpose in Org
proper, not individual user configs.

Sometimes links are really links, however some links require some tuning. Global style or custom export backend that modifies all links is not always suitable.

Perhaps special :href values may be added to allow just decorations without hyperlinks.

I believe that the right way to go here is what we previously discussed
as inline special block equivalent. That way, we will not need to create
workarounds with special link type.

It is limitation of top-down parser that object of the same time can not be nested, so I am unsure if special blocks would be solution in all cases.

I have added a hack to allow definitions of links or their attributes outside of paragraphs. Noweb and source code blocks allow it. Perhaps is should be implemented as a filter to avoid tricks to get noexport source blocks

---- 8< ----
A link defined in a source block
[[wrap:<<org-mode>> :attr_html ":class org"][Org mode]]

#+name: org-mode
#+begin_src elisp :exports none
:href "https://orgmode.org";
:attr_html ":title Org Mode — Your life in plain text"
#+end_src
---- >8 ----

(defun nm/org-link-wrap-path-to-props (path &optional info)
  (let* ((with-broken-links (plist-get info :with-broken-links))
         (org-babel-noweb-error-all-langs
          (if (not with-broken-links)
              t
            ;; TODO Handle `mark', currently errors are ignored.
            org-babel-noweb-error-all-langs))
         (expanded
          (org-babel-expand-noweb-references
           (list "elisp" path '(:noweb-prefix "no"))
           ;; Allow noweb references to code blocks
           ;; having ":exports none".
           (plist-get info :input-buffer))))
    (read(concat "(" expanded ")"))))

(defun nm/org-link-wrap-assert-href (props path)
  (let ((href (plist-get props :href)))
    (pcase href
      ((pred null) (signal
                    'org-link-broken
                    (list (format "no :href property in `%s'" path))))
      ((pred stringp) href)
      ((pred symbolp) (symbol-name href))
      (_ (signal
          'org-link-broken
          (list (format "Invalid :href type in `%s'" path)))))))

(defun nm/org-link-wrap-copy-props (props link)
  (while props
    (let ((name (pop props))
          (value (pop props))
          (case-fold-search t))
      (org-element-put-property
       link
       name
       ;; `org-element--collect-affiliated-keywords'
       (if (string-match-p "\\`:attr_" (symbol-name name))
           (append (org-element-property name link) (list value))
         value)))))

(defun nm/org-link-wrap-export
    (path description backend info)
  (let* ((props-all (nm/org-link-wrap-path-to-props path info))
         (href (nm/org-link-wrap-assert-href props-all path))
         ;; `org-plist-delete' removes other duplicated keys as well.
         (props (map-delete props-all :href))
         ;; Taken from `org-link-open-from-string'.
         (link (with-temp-buffer
                 (let ((org-inhibit-startup nil))
                   (insert "[[" (org-link-escape href) "]]")
                   (org-mode)
                   (goto-char (point-min))
                   (org-element-link-parser)))))
    (nm/org-link-wrap-copy-props props link)
    (when description
      (org-element-set-contents link description))
    (org-no-properties
     (org-export-data-with-backend link backend info))))

(defun nm/org-link-wrap-follow (path arg)
  (let* ((props (nm/org-link-wrap-path-to-props path))
         (href (nm/org-link-wrap-assert-href props path)))
    (org-link-open-from-string
     (concat "[[" (org-link-escape href) "]]")
     arg)))

(org-link-set-parameters
 "wrap"
 :follow #'nm/org-link-wrap-follow
 :export #'nm/org-link-wrap-export)





reply via email to

[Prev in Thread] Current Thread [Next in Thread]