From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: from mp2.migadu.com ([2001:41d0:700:3204::]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits)) by ms8.migadu.com with LMTPS id aB6YO4E/eGUFvgAAkFu2QA (envelope-from ) for ; Tue, 12 Dec 2023 12:09:54 +0100 Received: from aspmx1.migadu.com ([2001:41d0:303:e224::]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits)) by mp2.migadu.com with LMTPS id AOV1NoE/eGXqLwAAe85BDQ (envelope-from ) for ; Tue, 12 Dec 2023 12:09:53 +0100 X-Envelope-To: larch@yhetil.org Authentication-Results: aspmx1.migadu.com; dkim=none; spf=pass (aspmx1.migadu.com: domain of "emacs-orgmode-bounces+larch=yhetil.org@gnu.org" designates 209.51.188.17 as permitted sender) smtp.mailfrom="emacs-orgmode-bounces+larch=yhetil.org@gnu.org"; dmarc=fail reason="SPF not aligned (relaxed), No valid DKIM" header.from=gmail.com (policy=none) ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=yhetil.org; s=key1; t=1702379393; h=from:from:sender:sender:reply-to:subject:subject:date:date: message-id:message-id:to:to:cc:mime-version:mime-version: content-type:content-type: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references:list-id:list-help: list-unsubscribe:list-subscribe:list-post; bh=aw8pAoMDrA6fUYzKt91pqQEN9YXQYrBKRdnq0Zd3WC8=; b=tTllNKzeFwls7uPqylc0wj5sg0nx9fb9zZX7ZitJ5+Q30q1nKGaoywH66EFO2x693BY0Fl amTR4S88HNlrBP5kYXtAWPsH6/m9k+UYlhoIctemFT46KlgHgnTeCGh9aMpTuL/hI48L3c QgAqD6ALqZXYoVcummOVCiZvftzQTLgg9qdCbsThcymMxIgBJ2R1syW480mby5fErjYBJM yuGfYJeXwk/AIj5uIYAxjTndDaZi79rGw3ZYRPC3vW7looN4yYUMcOVJ7+XhL3hwG7gm8i 0URPkGjEz6gW1nrFYYRRaNmPQVHlG80oG1s+BptocDxXyNPzr7xM+XJgJOn8Rw== ARC-Seal: i=1; s=key1; d=yhetil.org; t=1702379393; a=rsa-sha256; cv=none; b=TN0gaM3pXAv2Igu703AuSeHh8DaqUwo0bBq5S7bnBexh7T7VN9jU9SFrOG8nry9+7I19rW jLM/CSZFeQ9/Bic03S5mOc0TGMwb3JfkaUVQUQRq4wdjUeGrJ+aNhcvnHzIbMgobDQ0oFo yEHewmSKU49G1k943x1JqoJqgP43hR/MVryOa4biSyjt9SL/6nK+9xyyeBwxD3eYtvd18r wLTiSC9HSutG47t0l/XzRWZ3i4Pgbd5KjJs80cK04by4fB5Jzy/1cVwchrTeYv20msIElD QOIOrnEIpaI2oJMyHtVUB2ouND71e2bArLSwYNPye2Z6aNvcY9pHp79Kw1w3Bg== ARC-Authentication-Results: i=1; aspmx1.migadu.com; dkim=none; spf=pass (aspmx1.migadu.com: domain of "emacs-orgmode-bounces+larch=yhetil.org@gnu.org" designates 209.51.188.17 as permitted sender) smtp.mailfrom="emacs-orgmode-bounces+larch=yhetil.org@gnu.org"; dmarc=fail reason="SPF not aligned (relaxed), No valid DKIM" header.from=gmail.com (policy=none) Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by aspmx1.migadu.com (Postfix) with ESMTPS id B6E3813AD9 for ; Tue, 12 Dec 2023 12:09:53 +0100 (CET) Received: from localhost ([::1] helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1rD0dO-0000KS-1r; Tue, 12 Dec 2023 06:09:07 -0500 Received: from eggs.gnu.org ([2001:470:142:3::10]) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1rD0dM-0000K3-Al for emacs-orgmode@gnu.org; Tue, 12 Dec 2023 06:09:04 -0500 Received: from ciao.gmane.io ([116.202.254.214]) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1rD0dK-0002Rm-L4 for emacs-orgmode@gnu.org; Tue, 12 Dec 2023 06:09:04 -0500 Received: from list by ciao.gmane.io with local (Exim 4.92) (envelope-from ) id 1rD0dG-0008CU-Jo for emacs-orgmode@gnu.org; Tue, 12 Dec 2023 12:08:58 +0100 X-Injected-Via-Gmane: http://gmane.org/ To: emacs-orgmode@gnu.org From: Max Nikulin Subject: Re: Links & images with different attributes in the same paragraph Date: Tue, 12 Dec 2023 18:08:49 +0700 Message-ID: References: <87lea8vk1i.fsf@localhost> Mime-Version: 1.0 Content-Type: text/plain; charset=UTF-8; format=flowed Content-Transfer-Encoding: 8bit User-Agent: Mozilla Thunderbird Content-Language: en-US, ru-RU In-Reply-To: <87lea8vk1i.fsf@localhost> Received-SPF: pass client-ip=116.202.254.214; envelope-from=geo-emacs-orgmode@m.gmane-mx.org; helo=ciao.gmane.io X-Spam_score_int: 28 X-Spam_score: 2.8 X-Spam_bar: ++ X-Spam_report: (2.8 / 5.0 requ) BAYES_00=-1.9, DKIM_ADSP_CUSTOM_MED=0.001, FORGED_GMAIL_RCVD=1, FORGED_MUA_MOZILLA=2.309, FREEMAIL_FORGED_FROMDOMAIN=0.249, FREEMAIL_FROM=0.001, HEADER_FROM_DIFFERENT_DOMAINS=0.25, NML_ADSP_CUSTOM_MED=0.9, SPF_HELO_NONE=0.001, SPF_PASS=-0.001, T_SCC_BODY_TEXT_LINE=-0.01 autolearn=no autolearn_force=no X-Spam_action: no action X-BeenThere: emacs-orgmode@gnu.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: "General discussions about Org-mode." List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: emacs-orgmode-bounces+larch=yhetil.org@gnu.org Sender: emacs-orgmode-bounces+larch=yhetil.org@gnu.org X-Migadu-Flow: FLOW_IN X-Migadu-Country: US X-Migadu-Spam-Score: -5.57 X-Spam-Score: -5.57 X-Migadu-Queue-Id: B6E3813AD9 X-Migadu-Scanner: mx12.migadu.com X-TUID: LW73WJw9klNX 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:<> :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)