Using Tufte CSS and org-page
I want to use the Tufte CSS for this blog, but one thing that was annoying me was the display of footnotes. They are actually called sidenotes.
I kind of fixed it by using literal html tags but that makes the org source file unpleasant to read. That in turn means that the html export should be changed to not export the footnotes as some internal anchors but as the format specified in the tufte report, which meant that I had to change the html export.
Looking at an exported footnote, we can see that the footnote section
is automatically created. I wasn't able to stop it so I simply
changed the command string org-html-footnotes-section
to comment it
out.
(setq org-html-footnotes-section "<!-- %s --><!-- %s -->")
Then I had to derive a new backend from the html export where I
override the footnote-reference
. Although I also specified a new
function for the footnote-definitions
I couldn't prevent the section
being printed at the bottom of the article so I still had to comment
it out.
Since the construct for a side note is a bit specialIt's an input with the type checkbox that will take the next span element as its content. the function does look a bit weird, but it works for my tastes.
(defun tufte-html-footnote-reference (footnote-reference contents info) "Create a footnote according to the tufte css format. FOOTNOTE-REFERENCE is the org element, CONTENTS is nil. INFO is a plist holding contextual information." (format "<label for=\"%s\" class=\"margin-toggle sidenote-number\"></label><input type=\"checkbox\" id=\"%s\" class=\"margin-toggle\"/><span class=\"sidenote\">%s</span>" (org-export-get-footnote-number footnote-reference info) (org-export-get-footnote-number footnote-reference info) (org-trim (org-export-data (org-export-get-footnote-definition footnote-reference info) info))))
I mostly looked at the backend for LaTeX exports and copied the code from there when it seemed logical to me.
That took care of the side notes but I still wanted to be able to have
margin notes. I realized that with an ugly hack that simply checks
the links whether they have the prefix mnfor margin note and
then wrap it into the according tags which is similar to the way side
notes work. You have to write the links with a unique word after the
link for the for
and id
attribute to not get confusedIt takes
the first word of the link. The links should come in the format
mn:unique-id
.
(defun tufte-html-margin-note-link (link desc info) "LINK is the margin note (or not). If it is not, it willl be passed onto the original function in order to be handled properly. DESC is the description part of the link. INFO is a plist holding contextual information." (let ((path (split-string (org-element-property :path link) ":"))) (if (and (string= (org-element-property :type link) "fuzzy") (string= (car path) "mn")) (format "<label for=\"%s\" class=\"margin-toggle\">⊕</label><input type=\"checkbox\" id=\"%s\" class=\"margin-toggle\"/><span class=\"marginnote\">%s</span>" (cadr path) (cadr path) desc) (org-html-link link desc info))))
If there is no match it will simply pass everythin along to the original exporter to not mess anything up.
To finally define the exporter you have to define a derived backend.
(org-export-define-derived-backend 'tufte-html 'html :translate-alist '((footnote-reference . tufte-html-footnote-reference) (footnote-definition . tufte-html-footnote-definition) (link . tufte-html-margin-note-link)))
Because I build this blog with org-page I simply had to specify in
op-template.el
lines 150 and 152 in the version from github.
my own exporter; I named it tufte-html
. Then I copied the css file
into the theme folderspeicied by the variable
op/theme-root-directory
. into its own folder. The folder was simply
a copy of another one, then I only had to replace the file main.css
with the contents of tufte.css
.
Afterwards I noticed that the source blocks were still styled in the
normal org style so I had to write yet another function that simply
stuffed the code into a <pre>
tag. Of course the backend had to be
redefined to override the default function.
(defun tufte-html-src-block (src-block contents info) "Transcode an SRC-BLOCK element from Org to HTML. CONTENTS holds the contents of the item. INFO is a plist holding contextual information." (format "<pre class=\"code\">%s</pre>" (org-html-format-code src-block info))) (org-export-define-derived-backend 'tufte-html 'html :translate-alist '((footnote-reference . tufte-html-footnote-reference) (footnote-definition . tufte-html-footnote-definition) (link . tufte-html-margin-note-link) (src-block . tufte-html-src-block)))
So far that was everything I did, the next things are probably going to be cleaning up the css a bit. I hope it's useful to someone. The code is in a gist/snippet. Although to me it was kind of interesting to dabble into the org exporters so I consider it a success.