From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: from mp12.migadu.com ([2001:41d0:8:6d80::]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits)) by ms0.migadu.com with LMTPS id WBzvKKYJ02EwrQAAgWs5BA (envelope-from ) for ; Mon, 03 Jan 2022 15:35:18 +0100 Received: from aspmx1.migadu.com ([2001:41d0:8:6d80::]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits)) by mp12.migadu.com with LMTPS id 6D+PJaYJ02E7CwAAauVa8A (envelope-from ) for ; Mon, 03 Jan 2022 15:35:18 +0100 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 4BBAF292CB for ; Mon, 3 Jan 2022 15:35:18 +0100 (CET) Received: from localhost ([::1]:54560 helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1n4OQf-0000fQ-BE for larch@yhetil.org; Mon, 03 Jan 2022 09:35:17 -0500 Received: from eggs.gnu.org ([209.51.188.92]:49940) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1n4OPr-0000am-N2 for emacs-orgmode@gnu.org; Mon, 03 Jan 2022 09:34:28 -0500 Received: from ciao.gmane.io ([116.202.254.214]:35144) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1n4OPq-0006h9-3K for emacs-orgmode@gnu.org; Mon, 03 Jan 2022 09:34:27 -0500 Received: from list by ciao.gmane.io with local (Exim 4.92) (envelope-from ) id 1n4OPo-0007jC-4f for emacs-orgmode@gnu.org; Mon, 03 Jan 2022 15:34:24 +0100 X-Injected-Via-Gmane: http://gmane.org/ To: emacs-orgmode@gnu.org From: Max Nikulin Subject: Re: Raw Org AST snippets for "impossible" markup Date: Mon, 3 Jan 2022 21:34:16 +0700 Message-ID: References: <4897bc60-b74f-ccfd-e13e-9b89a1194fdf@mailbox.org> <87fsrbp673.fsf@gmail.com> <1ef0e093-c165-2a5f-954d-6a33b64c8ee9@mailbox.org> <87r1avgnpi.fsf@localhost> <878rx2bzhw.fsf@nicolasgoaziou.fr> <9525e029-a590-3f48-df64-ffb9176075d9@mailbox.org> <87k0gh68ke.fsf@posteo.net> <8735n2hehj.fsf@posteo.net> <87lf0u8dnf.fsf@posteo.net> <87wnkdiwrd.fsf@posteo.net> <87y24txvlv.fsf@posteo.net> Mime-Version: 1.0 Content-Type: multipart/mixed; boundary="------------4565B326A2C3F4A1E127A837" User-Agent: Mozilla/5.0 (X11; Linux x86_64; rv:78.0) Gecko/20100101 Thunderbird/78.14.0 In-Reply-To: <87y24txvlv.fsf@posteo.net> Content-Language: en-US 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: 14 X-Spam_score: 1.4 X-Spam_bar: + X-Spam_report: (1.4 / 5.0 requ) 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, NICE_REPLY_A=-3.354, NML_ADSP_CUSTOM_MED=0.9, SPF_HELO_NONE=0.001, SPF_PASS=-0.001 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" X-Migadu-Flow: FLOW_IN X-Migadu-Country: US ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=yhetil.org; s=key1; t=1641220518; 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:in-reply-to:in-reply-to: references:references:list-id:list-help:list-unsubscribe: list-subscribe:list-post; bh=anFzFsraSPgJP4aangdtYed0NANYZ2t9UUTGFpb9D5g=; b=cGK22EQartxdlWiEt22PZbMAYIbRMnwTaAxMATGZcNVhCn2kOau9RRe/r3ypLMzMoBCOGe ZZhJ2lbWWj0K9aGs7aY2okcJVQfE3Tnc6HyY7pyovQCjS2Ekk/wbm11sseprBAnNmthdIO iS8DmidWadCNlhABzNAnJ6u1OXXoD4gDqtUhbJJZJGha1CrYPj6H+dEf+NpGyUQ4i+8lbn ueqydO3l8mvlIZrc1Yqve3IyGl9c7fjILabe5vG1uSmIbDYFi+bmgIV6oKgS+ZoKoTBb03 jR6osCJI9xqU30B6a2tRxWcboP6ucVnU+bDE79QgjCSmScVphfxvgz8/tohKyQ== ARC-Seal: i=1; s=key1; d=yhetil.org; t=1641220518; a=rsa-sha256; cv=none; b=AX4K4fazdOEZsSwzwP9PNefXfjBO03LqXEoxyPJj44Djn6dUhouysYq/EFBDk60USAMOwv l0LbNQNrEtU4kXO5XPm9qwWJ3vcK8Y15yLSgkjSOKJmfn2UxxFlNFGpsM9mm3CEpBHvn7o JKlZkDB5eYYY9rYQTeDJ9YXEQhfk42G3ROwnbE7EuYa3dLVSRCRLkSRcxWWyFGE23YLOSF K+4ee6KCMv7bXLd72WQoFZDcpXdQoGIOInzagaAXn/eblJs/vto0+btshbPin95Zupfwq+ dApK2stFeKdBYPyawNGGdvvNJUc6PfCd8a5SXjFgZjNkbWCdd2JaS06e6UdXig== ARC-Authentication-Results: i=1; aspmx1.migadu.com; dkim=none; dmarc=fail reason="SPF not aligned (relaxed), No valid DKIM" header.from=gmail.com (policy=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" X-Migadu-Spam-Score: -2.99 Authentication-Results: aspmx1.migadu.com; dkim=none; dmarc=fail reason="SPF not aligned (relaxed), No valid DKIM" header.from=gmail.com (policy=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" X-Migadu-Queue-Id: 4BBAF292CB X-Spam-Score: -2.99 X-Migadu-Scanner: scn0.migadu.com X-TUID: EZekHZwM7jKi This is a multi-part message in MIME format. --------------4565B326A2C3F4A1E127A837 Content-Type: text/plain; charset=utf-8; format=flowed Content-Transfer-Encoding: 8bit On 10/12/2021 05:27, Juan Manuel Macías wrote: > Juan Manuel Macías writes: > >> Jumping into the "real world", how about these two examples of nested emphasis? > > By the way, what do you think about allowing the use of some kind of > aliases, so that the aspect is less verbose? I have no particular opinion concerning aliases, but certainly they should not work through string search and replace when parsed tree is available. > (defun orgia--transform-path (path) > (with-temp-buffer > (insert path) > (mapc (lambda (el) > (orgia-replace (concat "(" (car el) "::") (concat "(" (cadr el) " () "))) By the way, is there any problem with `replace-regexp-in-string'? See the attached file for definitions of some helper functions. Final setup: #+begin_src elisp :results silent (setq orgia-demo-alias-alist '((b . bold) (i . italic) (s . strike-through) (_ . underline))) (defun orgia-demo-alias-post-filter (node &optional _children) (when (listp node) (let ((sym (and (symbolp (car node)) (assq (car node) orgia-demo-alias-alist)))) (when sym (setcar node (cdr sym))))) node) (defun orgia-demo-alias (tree) (orgia-transform-tree-deep tree nil #'orgia-demo-alias-post-filter)) #+end_src #+begin_src elisp :results silent (require 'ox) (add-to-list 'org-export-filter-parse-tree-functions #'orgia-parse-tree-filter) (org-link-set-parameters "orgia") (require 'ob-org) (add-to-list 'orgia-transform-functions #'orgia-demo-alias) #+end_src And a bit modified your test sample: #+begin_src org :results latex :results replace [[orgia:(i nil "The English versions of the " (b nil (i () "Iliad")) " and the " (b () (i () "Odyssey")))]] #+end_src #+RESULTS: #+begin_export latex \emph{The English versions of the \textbf{\emph{Iliad}} and the \textbf{\emph{Odyssey}}} #+end_export --------------4565B326A2C3F4A1E127A837 Content-Type: text/x-emacs-lisp; charset=UTF-8; name="orgia-draft.el" Content-Transfer-Encoding: 7bit Content-Disposition: attachment; filename="orgia-draft.el" (defvar orgia-transform-functions nil) (defun orgia-default-pre-filter (node) "Returns (node . children)" (if (listp node) (cons node node) (cons node nil))) (defun orgia-transform-tree-deep (tree &optional pre-filter post-filter) "Deep-first walk." ;; Queue items: ((node-cell . children) . next-list) (let* ((pre-filter (or pre-filter #'orgia-default-pre-filter)) (top (list tree)) (queue (list (cons (cons top top) top)))) (while queue (let* ((item (pop queue)) (next-list (cdr item))) (if (not next-list) ;; post; skip POST-FILTER for the list wrapping TREE (when (and queue post-filter) (let* ((node-cell-children (car item)) (children (cdr node-cell-children))) (setcar (car node-cell-children) (funcall post-filter (caar node-cell-children) children)))) ;; pre (setcdr item (cdr next-list)) (push item queue) (let* ((node-children (funcall pre-filter (car next-list))) (node (car node-children)) (children (cdr node-children))) (setcar next-list node) (push (cons (cons next-list children) children) queue))))) (car top))) (defun orgia-element-replace (current new destructive?) (if (eq current new) current (let* ((lst? (and (listp new) (not (symbolp (car new))))) (new-lst (if lst? (if destructive? (nconc new) (reverse new)) (list new)))) (dolist (element new-lst) (org-element-insert-before element current))) (org-element-extract-element current) new)) (defun orgia--transform-link (data) (if (not (string-equal "orgia" (org-element-property :type data))) data (let* ((path (org-element-property :path data))) (if (not (eq ?\( (aref path 0))) (or path (org-element-contents data)) (let ((tree (read path))) (dolist (f orgia-transform-functions tree) (setq tree (funcall f tree)))))))) (defun orgia-parse-tree-filter (data _backend info) (org-element-map data 'link (lambda (data) (orgia-element-replace data (orgia--transform-link data) t)) info nil nil t) data) --------------4565B326A2C3F4A1E127A837--