emacs-orgmode
[Top][All Lists]
Advanced

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

Re: How to add new type of block to a derived back-end?


From: Berry, Charles
Subject: Re: How to add new type of block to a derived back-end?
Date: Fri, 10 Apr 2020 17:10:12 +0000

Salomon, see inline comments below. 

HTH, 

Chuck

> On Apr 10, 2020, at 7:56 AM, Salomon Turgman <address@hidden> 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
> <div class="caption">Simulation 1: Manual control of the tank level.</div>
> <div class="simulation">
> <div id="main1">
> <noscript>
> Some other cool stuff here.
> </noscript>
> </div>
> </div>
> <script>var app = Main1.init({node: 
> document.getElementById("main1")});</script>
> #+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 "<div class=\"caption\">Simulation %simnum%: %Caption%.</div>
>   <div class=\"simulation\">
>     <div id=\"%divid%\">
>     </div>
>   </div>
> <script>var app = %modid%.init({node: 
> document.getElementById(\"%divid%\")});</script>"
>    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="<your caption here>".

> 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]



reply via email to

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