Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

defblock fails to export output when using latex derived backend #12

Open
arongile opened this issue Jun 29, 2021 · 5 comments
Open

defblock fails to export output when using latex derived backend #12

arongile opened this issue Jun 29, 2021 · 5 comments
Labels
documentation Improvements or additions to documentation good first issue Good for newcomers

Comments

@arongile
Copy link

Consider some latex derived backend:

(org-export-define-derived-backend
    'mybackend
    'latex
 ;; implementation detail ... 
)

And a custom special block myblock to go with it

(defblock  myblock
  (when  (or (equals 'latex) (equals 'mybackend)) 
    (concat
     "\\my-latex-command\n"
     raw-contents
     "\n\\my-latex-command")))

Use mybloc in some test.org file:

#+begin_myblock
<some content goes here>
#+end_myblock

Now the issue is myblock is never rendered when exporting test.org to latex

(org-export-to-buffer 'mybackend  "*Export Result Buffer*)

Is there a proper way to make defblock work with latex dervied backends?

Currently overriding org-latex-special-block from my-backend translation table
and fixing org-export-current-backend to point to latex during export seems to
work.

(defun ox-mybackend-special-block ( special-block contents info )
  (let ((org-export-current-backend 'latex))
         (org-latex-special-block special-block contents info))) 
@sopoforic
Copy link

I encounter a similar problem when exporting with ox-gfm. My guess is that #+begin_export gfm blocks are being generated, but then ox-gfm is delegating to ox-md, so they are not present in the output. I couldn't work out how to avoid this problem, but I don't think I understand org's export mechanism very well.

@alhassy alhassy added enhancement New feature or request help wanted Extra attention is needed labels Aug 5, 2021
@DPDmancul
Copy link

DPDmancul commented Aug 26, 2021

The same when exporting to epub with ox-epub: the special blocks are not present in final file.
Here the trick of @arongile is not applicable because ox-epub already uses org-html-special-block.

I've tried with

(advice-add 'org-hmtl-special-block :around
 (lambda (f &rest r)
   (let ((org-export-current-backend 'html))
     (apply 'f r))))

but nothing changed.

@DPDmancul
Copy link

Finally I found a temporay fix to convert all epub exports to html ones:

(add-to-list 'org-export-filter-parse-tree-functions
             (lambda (tree backend info)
               (when (eq backend 'epub)
                 (org-element-map tree 'export-block
                   (lambda (el)
                     (when (string= (org-element-property :type el) "EPUB")
                       (org-element-put-property el :type "HTML")))))
               tree))

@alhassy
Copy link
Owner

alhassy commented Jan 1, 2022

Hey @arongile, adopting @DPDmancul's approach, we have a solution 😉

  1. Evaluate ospe-add-support-for-derived-backend
  2. Evaluate the following let to see an example in-action.
(defun ospe-add-support-for-derived-backend (new-backend parent-backend)
  "See subsequent snippet for a working example use."
  (add-to-list 'org-export-filter-parse-tree-functions
                `(lambda (tree backend info)
                  (when (eq backend (quote ,new-backend))
                    (org-element-map tree 'export-block
                      (lambda (el)
                        (when (string= (org-element-property :type el) (s-upcase (symbol-name (quote ,new-backend))))
                          (org-element-put-property el :type (s-upcase (symbol-name (quote ,parent-backend))))))))
                  tree)))

;; “C-x C-e” at the end to see an example of support for derived modes.
(-let [new-backend 'super-duper-new-derived-backend]
  ;; Register new backend
  (org-export-define-derived-backend new-backend 'latex)
  (ospe-add-support-for-derived-backend new-backend 'latex)
  ;; Register new special block
  (o-defblock amyblock nil nil
    "Place a ‘✓’ before contents when doing latex derived backend exports."
    (if ;; ≈ (or (equal backend 'latex) (equal backend new-backend) ⋯)
        (org-export-derived-backend-p backend 'latex)
        (format "✓ %s" raw-contents)
      raw-contents))
  ;; Do an example export
  (with-temp-buffer
    (insert (s-join "\n" '("#+begin_amyblock"
                           "It worked!"
                           "#+end_amyblock")))
    ;; (org-export-to-buffer 'html "*Export Result Buffer*" nil nil t t) ;; No “✓”
    (org-export-to-buffer new-backend "*Export Result Buffer*" nil nil t t) ;; Yes “✓”
    ))

However, I don't know enough about derived backends to explain why this is needed. Perhaps @DPDmancul can provide more insight 🙏


@sopoforic, this solution also works for ox-gfm 😲

;; “C-x C-e” at the end to see an example of support for ox-gfm
(progn 
;; Register new backend
(ospe-add-support-for-derived-backend 'gfm 'html)
;; Register new special block
(o-defblock nice (𝒏 "1") nil
    "Place 𝒏-many ‘✓’ before contents when doing latex derived backend exports."
    (if ;; ≈ (or (equal backend 'latex) (equal backend new-backend) ⋯)
        (org-export-derived-backend-p backend 'html)
        (format "%s %s" (s-repeat (string-to-number 𝒏) "") raw-contents)
      raw-contents))
  ;; Do an example export
(with-temp-buffer
  (insert (s-join "\n" '("#+begin_nice 3"
                         "It worked!"
                         "#+end_nice")))
  (org-export-to-buffer 'gfm "*Export Result Buffer*" nil nil t t)))

Aslo @authsec, and @kaushalmodi of #21, this solution also works for ox-hugo 😲 Notice that block arguments also work as expected 🥳

;; “C-x C-e” at the end to see an example of support for ox-hugo
(progn
;; Register new backend
(ospe-add-support-for-derived-backend 'hugo 'html)
;; Register new special block
(o-defblock nice (𝒏 "1") nil
    "Place 𝒏-many ‘✓’ before contents when doing latex derived backend exports."
    (if ;; ≈ (or (equal backend 'latex) (equal backend new-backend) ⋯)
        (org-export-derived-backend-p backend 'html)
        (format "%s %s" (s-repeat (string-to-number 𝒏) "") raw-contents)
      raw-contents))
  ;; Do an example export
(with-temp-buffer
  (insert (s-join "\n" '("#+begin_nice 3"
                         "It worked!"
                         "#+end_nice")))
  (org-export-to-buffer 'hugo "*Export Result Buffer*" nil nil t t)))

@alhassy alhassy added documentation Improvements or additions to documentation and removed enhancement New feature or request help wanted Extra attention is needed labels Jan 1, 2022
@authsec
Copy link

authsec commented Jan 5, 2022

Hi @alhassy, that sounds awesome, but unfortunately I cannot get it to work 😞.

I am using the following configuration, but if I export with C-c C-e H A I end up with Symbol's value as variable is void: org-export-derived-backend-p.

If I execute the temp buffer test however, that seems to work for me and produces:

+++
draft = false
+++

{{% alert title="My new Title" color="secondary"%}}
It worked!
{{% /alert %}}

New Configuration

 (use-package org-special-block-extras
  :ensure t
  :after org
  :hook (org-mode . org-special-block-extras-mode)
  :config
  (defun ospe-add-support-for-derived-backend (new-backend parent-backend)
    "See subsequent snippet for a working example use."
    (add-to-list 'org-export-filter-parse-tree-functions
		 `(lambda (tree backend info)
		    (when (eq backend (quote ,new-backend))
		      (org-element-map tree 'export-block
			(lambda (el)
			  (when (string= (org-element-property :type el) (s-upcase (symbol-name (quote ,new-backend))))
			    (org-element-put-property el :type (s-upcase (symbol-name (quote ,parent-backend))))))))
		    tree)))
;; “C-x C-e” at the end to see an example of support for ox-hugo
(progn
;; Register new backend
(ospe-add-support-for-derived-backend 'hugo 'html)
;; Register new special block
(o-defblock noteblock (title "Note") (titleColor "primary")
	    "Define noteblock export for docsy ox hugo"
	    (if ;; ≈ (or (equal backend 'latex) (equal backend new-backend) ⋯)
		(org-export-derived-backend-p backend 'hugo)
		(format "{{%% alert title=\"%s\" color=\"%s\"%%}}\n%s{{%% /alert %%}}" title titleColor raw-contents) title titleColor
		raw-contents))
;; Do an example export
(with-temp-buffer
  (insert (s-join "\n" '("#+begin_noteblock \"My new Title\" :titleColor \"secondary\""
                         "It worked!"
                         "#+end_noteblock")))
  (org-export-to-buffer 'hugo "*Export Result Buffer*" nil nil t t)))
)

"Old" Configuration

The configuration I tried to build before is which works, but is unable to interpret the parameters given.:

 (use-package org-special-block-extras
       :ensure t
       :after org
       :hook (org-mode . org-special-block-extras-mode)
       :config
       (o-defblock noteblock (title "Note") (title-color "primary")
		   "Define noteblock export for docsy ox hugo"
		   (apply #'concat
			  (pcase backend
			    (`latex `("\\begin{noteblock}", contents, "\\end{noteblock}"))
			    (`hugo `("{{% alert title=\"", title, "\" color=\"", title-color, "\" %}}\n", contents, "\n{{% /alert %}}"))
			    )
			  )
		   )
       (o-defblock cautionblock (title "Caution") (title-color "warning")
		   "Awesomebox caution"
		   (apply #'concat
			  (pcase backend
			    (`latex `("\\begin{cautionblock}", contents, "\\end{cautionblock}"))
			    (`hugo `("{{% alert title=\"", title, "\" color=\"", title-color, "\" %}}\n", contents, "\n{{% /alert %}}"))
			    )
			  )
		   )
       )

Can you please update the "old" configuration with the pcase in a way that I might make it work?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
documentation Improvements or additions to documentation good first issue Good for newcomers
Projects
None yet
Development

No branches or pull requests

5 participants