0

I see the abstract block

#+begin_abstract
Hello, here's my article's abstract...
#+end_abstract

and it exports nicely into LaTeX with a nice title heading "Abstract" above it, i.e., LaTeX export knows what to do with it. But with an HTML export it just throws the text and no title. How could I alter things to have a LaTeX-like export with my HTML export? In general, I could use a nice How To Hack the HTML Export tutorial, all the essentials, main points, first principles...

1 Answer 1

2

LaTeX export has the handy feature that if you give it a special block (like #+begin_abstract ... #+end_abstract), it will blindly turn it into a LaTeX environment (\begin{abstract}...\end{abstract} in this case) and let LaTeX do what it will with it. Since LaTeX knows how to deal with the abstract environment, everything works out well. If you gave it a different special block (e.g. foo), it would still be turned into a foo environment and LaTeX would barf since the environment foo is not defined. But you could define it in a package, and make sure that the package is loaded, thereby teaching LaTeX how to deal with it. See org-latex-latex-special-block for the code.

HTML is much less structured: the same special block is turned into a <div class="abstract"><p>...</p></div> but, in contrast to LaTeX, HTML doesn't know anything about an abstract class, so it just renders the text (but note that it does not barf, as LaTeX does with an unknown environment). Now, "teaching" HTML about the abstract class is merely a matter of including some CSS that tells HTML how to style the class and some way to include the title for the abstract, simulating what LaTeX does.

E.g. for CSS styling, try something like this:

#+TITLE: Nice title, isn't it?
#+AUTHOR: A.U.Thor
#+HTML_HEAD_EXTRA: <style> div.abstract { margin: auto; width: 80%; text-align: justify; color: red; } </style>

#+begin_abstract
Lorem ipsum dolor sit amet, ... sunt in culpa qui officia deserunt mollit anim id est laborum.
#+end_abstract

That will certainly distinguish the abstract from the rest of the text! A bit garish for my taste though, although getting rid of the color is easy.

As a debugging hint for the above and also for what follows, I highly recommend that you create an Org mode file as above, export it to HTML, look in the HTML file to see what is produced (you only need to worry about the added <style> and the abstract) and also check the file in a browser. It's easy to iterate with a setup like this: make a change in the Org file, save it, export it to HTML, hop to the browser, refresh; if it doesn't work, look in the HTML file and see what happened - lather, rinse, repeat.

The one remaining thing is to add a title Abstract, like LaTeX. AFAIK, that cannot be done with CSS. One way to do it is to define your own exporter derived from HTML and overriding the org-html-special-block function: your function can check what kind of special block it is dealing with and inject the title in the appropriate place.

Another way to do it is to define a filter (see the "Filters" section in the Org manual with C-h i g(org)filters).

Here is a filter solution:

#+begin_src elisp
  (defun ndk/add-title-to-abstract (text backend info)
     (when (org-export-derived-backend-p backend 'html)
       (if (string-match "class=\"abstract\"" text)
           ;; got one - rewrite the text to include the title
           (replace-regexp-in-string "<p>" "<div class=\"abstract_title\">Abstract</div><p>" text))))

  (add-to-list 'org-export-filter-special-block-functions
               #'ndk/add-title-to-abstract)
#+end_src

Note that the filter is applied to the transcoded string (i.e. the string that is produced by org-html-special-block). It is an HTML string like this:

<div class="abstract" id="orgdbb679b">
<p>
Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do
... 
sunt in culpa qui officia deserunt mollit anim id est laborum.
</p>

</div>

We define a filter that checks only special blocks (since it is added to org-export-filter-special-block-functions). It checks that the backend is (derived from) html and does a crude string search to make sure that it is an abstract by checking that it contains class="abstract". It then replaces the <p> by adding some stuff so that the <p> line now looks like this: <div class="abstract_title">Abstract</div><p>.

That will produce the title, but it is not going to be styled very nicely. But that's why we added the new div with its own distinctive class, so that we can style it just as we did the abstract class. So back to CSS we go to add some styling for the new abstract_title class:

#+HTML_HEAD_EXTRA: <style> div.abstract_title { font-size: 150%; font-variant: small-caps; text-align: center; color: blue; } </style>

I should point out that what I know about CSS can be written down on an index card: seasoned CSS people are probably ROFLTAO or worse...

If I find some time, I may come back and do the derived-backend implementation. But there are many examples of derived backends e.g. on Github, although they will probably be a bit more complicated than is necessary for the simple problem we are considering here. We only need to override one function: org-html-special-block.

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.