From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: from mp0 ([2001:41d0:2:bcc0::]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits)) by ms11 with LMTPS id EEFOFaKpkF4PRQAA0tVLHw (envelope-from ) for ; Fri, 10 Apr 2020 17:15:14 +0000 Received: from aspmx2.migadu.com ([2001:41d0:2:bcc0::]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits)) by mp0 with LMTPS id KDTyLqOpkF5yTAAA1q6Kng (envelope-from ) for ; Fri, 10 Apr 2020 17:15:15 +0000 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 aspmx2.migadu.com (Postfix) with ESMTPS id 04821682259 for ; Fri, 10 Apr 2020 17:15:13 +0000 (UTC) Received: from localhost ([::1]:37234 helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1jMxFI-0006gq-MM for larch@yhetil.org; Fri, 10 Apr 2020 13:15:12 -0400 Received: from eggs.gnu.org ([2001:470:142:3::10]:45341) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1jMxEn-0006gc-Go for emacs-orgmode@gnu.org; Fri, 10 Apr 2020 13:14:43 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1jMxEl-00041m-I8 for emacs-orgmode@gnu.org; Fri, 10 Apr 2020 13:14:41 -0400 Received: from mail-qt1-x834.google.com ([2607:f8b0:4864:20::834]:46122) by eggs.gnu.org with esmtps (TLS1.0:RSA_AES_128_CBC_SHA1:16) (Exim 4.71) (envelope-from ) id 1jMxEl-00041T-Di for emacs-orgmode@gnu.org; Fri, 10 Apr 2020 13:14:39 -0400 Received: by mail-qt1-x834.google.com with SMTP id g7so1930892qtj.13 for ; Fri, 10 Apr 2020 10:14:39 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20161025; h=mime-version:references:in-reply-to:from:date:message-id:subject:to :cc; bh=MWkWHtqCqmpKhUzJ7Np2AuMsX7cdg+Fia3p7ySkSsAY=; b=rqun1bHOsy8fYB9DvnJGqiu0N1aa0Z0Q7GQBM9eQUe/EfhZ0vO54fdEOjBDlFCpFl6 87Dak8jwB/JP9g1+s1hgya/U56gsMt99aCoaSTECRHx+DhTbN3ov3giVhC8orXrNaFp/ uNoXLkd2KlZgEZm3JSM2ONnKz0YK2hYx2pO4yuBYzPga8QUy5WfpOdX5lWmM2aVe3ooS ZcwInRaLQ+2vpjdCqJMOO8alD05Ziq1N7I8KWsa06m/O0NuLTvvMJ7cUylW2aM2HhA2g FwtL8TgjtjrTLLQIKKuWQhKJ6YTp104llgaPeo+F0uiycAdV1ghvKATwQALFj7cyse7G 9Drw== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:mime-version:references:in-reply-to:from:date :message-id:subject:to:cc; bh=MWkWHtqCqmpKhUzJ7Np2AuMsX7cdg+Fia3p7ySkSsAY=; b=NXrww9WNAaVAdu/CZeJbPrnXwpKDXI3Ec6u4k5cIddmKMPjRAYg8kxNFHSFaePmQiD A32YhcU01baZjk5EoWsuak+yNu5YqfrXri+8JK6uY+2CZxrMNmeBK7m9NfWfiaX/IAi3 t5Wghe6PKw9W//DXS25bMq/jEcAlJw2HJzkhasdhjxKMPZpTP3dVuHj8jIvv5WPAber1 ceOf/oLctcgZ1MauWY8peKlD80QcjGca1CNB0+CPESxfw/w/rPYQWVXzsqTpUztDCY4f DHRAihFghG4IDHnylS1ys7xXMQ/CD4OGnT3VfmFc9NhUrmvoB40nqRYlUDg+hk8g2rEQ 9LZQ== X-Gm-Message-State: AGi0PuaG01J66gX2Mq17hRbuQyK1pgbXaBgfW50epZgiI9Oyv4YtVPqs cSu0xlgVpidyKGatbGu+Z+DRn7DTyBLYgntuQu8= X-Google-Smtp-Source: APiQypJvF8ag7cH/bUUMtiG0QcBCOs0bGPjT0/CGOEX70zkgy5mgDccrE72AA8ZsXO6TeQjUaBCwxPNKRyCmME86Fjo= X-Received: by 2002:aed:3284:: with SMTP id z4mr228624qtd.22.1586538878791; Fri, 10 Apr 2020 10:14:38 -0700 (PDT) MIME-Version: 1.0 References: In-Reply-To: From: Salomon Turgman Date: Fri, 10 Apr 2020 13:14:26 -0400 Message-ID: Subject: Re: How to add new type of block to a derived back-end? To: "Berry, Charles" Content-Type: multipart/alternative; boundary="0000000000004af30405a2f2de54" X-detected-operating-system: by eggs.gnu.org: Genre and OS details not recognized. X-Received-From: 2607:f8b0:4864:20::834 X-BeenThere: emacs-orgmode@gnu.org X-Mailman-Version: 2.1.23 Precedence: list List-Id: "General discussions about Org-mode." List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: org mode Errors-To: emacs-orgmode-bounces+larch=yhetil.org@gnu.org Sender: "Emacs-orgmode" ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=yhetil.org; s=default; t=1586538913; h=from:from:sender:sender:reply-to:subject:subject:date:date: message-id:message-id:to:to:cc: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:dkim-signature; bh=MWkWHtqCqmpKhUzJ7Np2AuMsX7cdg+Fia3p7ySkSsAY=; b=fWiLQATjniISm+otSibR+C+5M4BN1E/jJoifop5z/+RthZ/13jqSo6N4YF188JCYrVIbvf 029jbyUzz7xygXub6Ic3mb9L7wtgm81aI6teMeu4gf0+TO820YUaKBmTaFrm5k1Wvc+BNi Fg48ZpDIa9neGoCSrkDdrDyS6Jrk1h0= ARC-Seal: i=1; s=default; d=yhetil.org; t=1586538913; a=rsa-sha256; cv=none; b=NH7d/sOHROREM4H3z2EGbGW/NcNU/ylEElvryrZAIZzmbk/Qk8dcDO/Fj50ZEu0/fMOpKq XuQyfrrYzWpKccYg/u3dQyFHBiCwTeAtvpg/9lRasX0EpOcLUAkc7wUYHTBJAAUpaSlVUa cNwkzMgJLC0OMU649QhZa+GX8mJzu74= ARC-Authentication-Results: i=1; aspmx2.migadu.com; dkim=pass header.d=gmail.com header.s=20161025 header.b=rqun1bHO; dmarc=pass (policy=none) header.from=gmail.com; spf=pass (aspmx2.migadu.com: domain of emacs-orgmode-bounces@gnu.org designates 209.51.188.17 as permitted sender) smtp.mailfrom=emacs-orgmode-bounces@gnu.org X-Scanner: scn0 X-Spam-Score: -0.71 Authentication-Results: aspmx2.migadu.com; dkim=pass header.d=gmail.com header.s=20161025 header.b=rqun1bHO; dmarc=pass (policy=none) header.from=gmail.com; spf=pass (aspmx2.migadu.com: domain of emacs-orgmode-bounces@gnu.org designates 209.51.188.17 as permitted sender) smtp.mailfrom=emacs-orgmode-bounces@gnu.org X-Scan-Result: default: False [-0.71 / 13.00]; GENERIC_REPUTATION(0.00)[-0.58005783884072]; R_SPF_ALLOW(-0.20)[+ip4:209.51.188.0/24:c]; FREEMAIL_FROM(0.00)[gmail.com]; IP_REPUTATION_HAM(0.00)[asn: 22989(0.30), country: US(-0.01), ip: 209.51.188.17(-0.58)]; ARC_SIGNED(0.00)[i=1]; TO_DN_ALL(0.00)[]; MX_GOOD(-0.50)[cached: eggs.gnu.org]; RCPT_COUNT_TWO(0.00)[2]; DMARC_POLICY_ALLOW(-0.50)[gmail.com,none]; DKIM_TRACE(0.00)[gmail.com:+]; MAILLIST(-0.20)[mailman]; FORGED_RECIPIENTS_MAILLIST(0.00)[]; RCVD_TLS_LAST(0.00)[]; MIME_TRACE(0.00)[0:+,1:+,2:~]; ASN(0.00)[asn:22989, ipnet:209.51.188.0/24, country:US]; SUBJECT_ENDS_QUESTION(1.00)[]; TAGGED_FROM(0.00)[larch=yhetil.org]; FROM_NEQ_ENVFROM(0.00)[sturgman@gmail.com,emacs-orgmode-bounces@gnu.org]; ARC_NA(0.00)[]; RCVD_COUNT_FIVE(0.00)[6]; R_DKIM_ALLOW(-0.20)[gmail.com:s=20161025]; FROM_HAS_DN(0.00)[]; MIME_GOOD(-0.10)[multipart/alternative,text/plain]; PREVIOUSLY_DELIVERED(0.00)[emacs-orgmode@gnu.org]; HAS_LIST_UNSUB(-0.01)[]; FORGED_SENDER_MAILLIST(0.00)[] X-TUID: +zvnSlIgqe2E --0000000000004af30405a2f2de54 Content-Type: text/plain; charset="UTF-8" Thank you very much. I will explore what you suggest. I'm glad I emailed, seems like I was going down the wrong path. Salomon On Fri, Apr 10, 2020, 1:10 PM Berry, Charles wrote: > Salomon, see inline comments below. > > HTH, > > Chuck > > > On Apr 10, 2020, at 7:56 AM, Salomon Turgman wrote: > > > > Hello all, > > > > Thanks in advance for any hints you can provide for this. I am trying to > create a derived back-end that handles a new type of block in org-mode. I > am trying to derive using the html export backend as a parent. > > > > Currently I am solving my problem like this: > > #+CAPTION[Manual control]: Simulation 1: Manual control of the tank > level. > > #+BEGIN_EXPORT html > >
Simulation 1: Manual control of the tank > level.
> >
> >
> > > >
> >
> > > > #+END_EXPORT > > > > This has a few downsides: > > 1. I have to specify the caption twice since export translator does not > handle captions. > > 2. I have to include substantial amounts of html. > > 3. I have keep track of references to simulations manually (simulation > 1, simulation 2, etc) > > 4. I have to include the identifier `main1` or `Main1` in several > locations in the snippet. > > > > I could solve some of this with an automated snippet insertion tool but > I thought that maybe I can get the export back-end to do most of the work > for me. > > > > So I am trying to derive as follows (in pseudo-elisp-code): > > (require 'ox) > > (require 'ox-html) > > > > (org-export-define-derived-backend 'textbook 'html > > :menu-entry > > '(?I "Export textbook section" > > ((?b "To buffer" org-html-export-as-html) > > (?I "To file" org-html-export-to-html) > > (?o "As HTML file and open" > > (lambda (a s v b) > > (if a (org-html-export-to-html t s v b) > > (org-open-file (org-html-export-to-html nil s v > b))))))) > > :translate-alist '((simulation . org-textbook-simulation))) > > From the `org-export-define-backend' docstring: > > "TRANSCODERS is an alist between object or element types and > functions handling them." > > But `simulation' is not such a type. So, this will not work. > > > > > (defun org-textbook-simulation (element contents info) > > (let* ((simnum (extract simnum value)) > > (caption (org-export-get-caption element)) > > (divid (extrac divid value)) > > (modid (convert divid into modid)) > > ) > > (format "
Simulation %simnum%: %Caption%.
> >
> >
> >
> >
> > " > > simnum caption divid modid divid))) > > > > With the hope that I can do something like this in my .org file: > > > > #+CAPTION[Manual control]: Simulation 1: Manual control of the tank > level. > > #+BEGIN_SIMULATION main1 > > Some other cool stuff here > > #+END_SIMULATION > > > I think an easier approach is to write a babel src-block that formats the > inputs you need and creates a value that is your desired output. > > Use `:var' header arguments to define the inputs. > > Use `:wrap html' to prevent the exporter from changing the output. > > Subsequent calls can use the `#+CALL' idiom. > > You can use any scripting language that suits you - elisp, python, shell, > R, ... --- for this purpose. > > If you are skilled in emacs-lisp you might write an `eval' macro instead > of a src block. > > > > > Am I on the right track here? Can someone point me to an example on how > to: > > 1. Keep track of the number of simulations for referencing? > > Using the babel approach, you would need a `:session' with a persistent > variable that would hold the count. You would need to initialize it in your > document so that subsequent exports will start counting at zero. > > > 2. Extract the caption properly? The above is just my guess. > > > IIRC, the info channel is not populated when babel runs, so you will need > to parse the src-block and extract the `:caption' element. I think you can > use a `:var cap=(find-caption)' idiom, where `find-caption' is a function > you write using `org-element-context' as a starting point. > > Or if the only need you have for the caption is within that src block just > use `:var cap="". > > > 3. Extract the divid value (main1) > > :var divid="main1" > > > > 4. And finally, how to get org to recognize the new SIMULATION block so > that it can apply `org-textbook-simulation`? Do I need to register this > type of block somewhere? Or is the name of the first member of the > :translate-alist translation pair have some special meaning? > > Don't go in that direction. Use babel or write an eval macro. > > [snip] > --0000000000004af30405a2f2de54 Content-Type: text/html; charset="UTF-8" Content-Transfer-Encoding: quoted-printable
Thank you very much. I will explore what you suggest. I&#= 39;m glad I emailed, seems like I was going down the wrong path.

Salomon

On Fri, Apr 10, 2020, 1:10 = PM Berry, Charles <ccberry@he= alth.ucsd.edu> wrote:
Salomo= n, see inline comments below.

HTH,

Chuck

> On Apr 10, 2020, at 7:56 AM, Salomon Turgman <sturgman@gmail.com> wrote:
>
> Hello all,
>
> Thanks in advance for any hints you can provide for this. I am trying = to create a derived back-end that handles a new type of block in org-mode. = I am trying to derive using the html export backend as a parent.
>
> Currently I am solving my problem like this:
> #+CAPTION[Manual control]: Simulation 1: Manual control of the tank le= vel.
> #+BEGIN_EXPORT html
> <div class=3D"caption">Simulation 1: Manual control of= the tank level.</div>
> <div class=3D"simulation">
> <div id=3D"main1">
> <noscript>
> Some other cool stuff here.
> </noscript>
> </div>
> </div>
> <script>var app =3D Main1.init({node: document.getElementById(&q= uot;main1")});</script>
> #+END_EXPORT
>
> This has a few downsides:
> 1. I have to specify the caption twice since export translator does no= t handle captions.
> 2. I have to include substantial amounts of html.
> 3. I have keep track of references to simulations manually (simulation= 1, simulation 2, etc)
> 4. I have to include the identifier `main1` or `Main1` in several loca= tions in the snippet.
>
> I could solve some of this with an automated snippet insertion tool bu= t I thought that maybe I can get the export back-end to do most of the work= for me.
>
> So I am trying to derive as follows (in pseudo-elisp-code):
> (require 'ox)
> (require 'ox-html)
>
> (org-export-define-derived-backend 'textbook 'html
>=C2=A0 =C2=A0:menu-entry
>=C2=A0 =C2=A0'(?I "Export textbook section"
>=C2=A0 =C2=A0 =C2=A0 =C2=A0 ((?b "To buffer" org-html-export-= as-html)
>=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0(?I "To fil= e" org-html-export-to-html)
>=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0(?o "As HTM= L file and open"
>=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0(lambda (a s v b)
>=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0(if a (org-html-= export-to-html t s v b)
>=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 = =C2=A0 =C2=A0(org-open-file (org-html-export-to-html nil s v b)))))))
>=C2=A0 =C2=A0:translate-alist '((simulation . org-textbook-simulati= on)))

>From the `org-export-define-backend' docstring:

"TRANSCODERS is an alist between object or element types and
functions handling them."

But `simulation' is not such a type. So, this will not work.

>
> (defun org-textbook-simulation (element contents info)
>=C2=A0 =C2=A0(let* ((simnum (extract simnum value))
>=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0(caption (org-ex= port-get-caption element))
>=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 (divid (extrac divid value))
>=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0(modid (convert = divid into modid))
>=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 )
>=C2=A0 =C2=A0 =C2=A0(format "<div class=3D\"caption\"= >Simulation %simnum%: %Caption%.</div>
>=C2=A0 =C2=A0<div class=3D\"simulation\">
>=C2=A0 =C2=A0 =C2=A0<div id=3D\"%divid%\">
>=C2=A0 =C2=A0 =C2=A0</div>
>=C2=A0 =C2=A0</div>
> <script>var app =3D %modid%.init({node: document.getElementById(= \"%divid%\")});</script>"
>=C2=A0 =C2=A0 simnum caption divid modid divid)))
>
> With the hope that I can do something like this in my .org file:
>
> #+CAPTION[Manual control]: Simulation 1: Manual control of the tank le= vel.
> #+BEGIN_SIMULATION main1
> Some other cool stuff here
> #+END_SIMULATION


I think an easier approach is to write a babel src-block that formats the i= nputs you need and creates a value that is your desired output.

Use `:var' header arguments to define the inputs.

Use `:wrap html' to prevent the exporter from changing the output.

Subsequent calls can use the `#+CALL' idiom.

You can use any scripting language that suits you - elisp, python, shell, R= , ... --- for this purpose.

If you are skilled in emacs-lisp you might write an `eval' macro instea= d of a src block.

>
> Am I on the right track here? Can someone point me to an example on ho= w to:
> 1. Keep track of the number of simulations for referencing?

Using the babel approach, you would need a `:session' with a persistent= variable that would hold the count. You would need to initialize it in you= r document so that subsequent exports will start counting at zero.

> 2. Extract the caption properly? The above is just my guess.


IIRC, the info channel is not populated when babel runs, so you will need t= o parse the src-block and extract the `:caption' element. I think you c= an use a `:var cap=3D(find-caption)' idiom, where `find-caption' is= a function you write using `org-element-context' as a starting point.<= br>
Or if the only need you have for the caption is within that src block just = use `:var cap=3D"<your caption here>".

> 3. Extract the divid value (main1)

:var divid=3D"main1"


> 4. And finally, how to get org to recognize the new SIMULATION block s= o that it can apply `org-textbook-simulation`? Do I need to register this t= ype of block somewhere? Or is the name of the first member of the :translat= e-alist translation pair have some special meaning?

Don't go in that direction. Use babel or write an eval macro.

[snip]
--0000000000004af30405a2f2de54--