0

Typically, it is possible to add html attributes to the #+begin_xxx tags, e.g.:

#+attr_html: :style display:flex;
#+begin_div
Testing...
#+end_div

However, when I try to do this with #+begin_center, no such changes are applied, e.g.:

#+attr_html: :style display:flex;
#+begin_center
Testing...
#+end_center

Yields the HTML:

<div class="org-center">
<p>
Testing&#x2026;
</p>
</div>

I assume this is because center is used specially somehow, but is it possible to add these attributes to that environment anyways?

1
  • You will have to override the built-in function that processes center blocks (org-html-center-block) which does not look at any atrributes and replace it with one that does. It's a one-line function so it should not be too difficult.
    – NickD
    Commented Jan 24, 2023 at 22:30

1 Answer 1

1

The function that processes center blocks in the HTML exporter is org-html-center-block. Here it is in its entirety:

(defun org-html-center-block (_center-block contents _info)
  "Transcode a CENTER-BLOCK element from Org to HTML.
CONTENTS holds the contents of the block.  INFO is a plist
holding contextual information."
  (format "<div class=\"org-center\">\n%s</div>" contents))

As you can see, it doesn't do anything with attributes: it just wraps a div of class org-center around the contents and that's it.

You will need to override this function in order to add attributes. Here's a slightly enhanced Org mode file that's based on your example. It adds a noexport Code section that contains an elisp source code block with a modified org-html-center-block function:

#+OPTIONS: toc:nil

* Foo

#+attr_html: :style display:flex;
#+begin_div
Testing...
#+end_div

However, when I try to do this with #+begin_center,
no such changes are applied, e.g.:

#+attr_html: :style display:flex;
#+begin_center
Testing...
#+end_center

* Code                                                         :noexport:
#+begin_src elisp
  (defun org-html-center-block (center-block contents _info)
    "Transcode a CENTER-BLOCK element from Org to HTML.
  CONTENTS holds the contents of the block.  INFO is a plist
  holding contextual information."
    (let* ((attributes (org-export-read-attribute :attr_html center-block))
           (attrs (org-html--make-attribute-string attributes)))
      (format "<div class=\"org-center\"%s>\n%s</div>"
              (if (org-string-nw-p attrs)
                  (concat " " attrs)
                "")
              contents)))
#+end_src

If you press C-c C-c on the code block, the modified function will override the original one. You can then export with C-c C-e h h and look at the HTML file.

The function makes use of the center-block argument and extracts the :attr_html value (which was initialized from the #+ATTR_HTML that was attached to the center block in the file). The value is a list of zero or more elements (in this case just one: the :style attribute with value display:flex;). The list is massaged and converted into a string (in this case a string like this: "style=\"display;flex;\"") which is then given to format to produce the final form:

<div class="org-center" style="display:flex;">
<p>
Testing&#x2026;
</p>
</div>

The function can accommodate multiple attributes (or no attributes).

If after you've done the export, you decide that you want to revert to the original function after all, you can restart Emacs or do M-x load-library ox-html. OTOH, if you decide you want to have the new function in force permanently, you can add it to your init file, although you'll have to make sure to evaluate the defun after the original function has been defined, so that the original will be overridden. You can do that with an eval-after-load form like this:

(eval-after-load 'ox-html
  (defun org-html-center-block (center-block contents _info)
     ...)
)
1
  • Thanks a lot for this very thorough answer!
    – Xaldew
    Commented Jan 26, 2023 at 10:20

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.