Skip to content

cosmicz/org-html-interface

 
 

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 
 
 
 
 
 
 

Repository files navigation

Nice Org to HTML pipeline

tl;dr

This package generates pretty, responsive, websites from .org files and your choice of Emacs themes. You can optionally specify a header, footer, and additional CSS and JS to be included. To see the default output, for my chosen themes and with no header, footer or extras, view this README in your browser here. If you’re already there, you can find the GitHub repo here.

With the README I also publish these samples, which include a list-specified header and footer:

About this package

nice-org-html defines an Emacs pipeline for exporting Org files, or publishing Org projects, to HTML. The generated HTML is optimized for readability and responsiveness, esp. of documents that include code, and makes it easy to achieve a custom look-and-feel, in part by leveraging the variety of themes available for Emacs. Under the hood, this is achieved by:

  1. Extracting colors from user-specified themes, inserting these in a CSS template (nice-org-html.css), and injecting the result into a <style> element.
  2. Inserting toggle-buttons for light- and dark-mode viewing, and a click-to-jump table-of-content view, governed by the included scripts (nice-org-html.js).
  3. Extending the default org-to-html export backend to include copy-to-clipboard buttons for source blocks.
  4. Injecting (optional) header and footer, CSS styling, and JS scripts.

How to use it

Setup

  • Get the source files on your load path. E.g. with MELPA and use-package:
    (require 'package)
    (add-to-list 'package-archives
                 '("melpa" . "http://melpa.org/packages/"))
    (package-initialize)
    
    (unless (package-installed-p 'use-package)
      (package-install 'use-package))
        
  • Add something like this to your configuration file:
    (use-package nice-org-html
      :hook (org-mode . nice-org-html-mode)
      :config
      (setq nice-org-html-theme-alist
            '((light . solo-jazz)
              (dark  . tomorrow-night-eighties)))
      (setq nice-org-html-default-mode 'dark)
      (setq nice-org-html-headline-bullets nil)      
        
  • If values for any of these variables are not specified, these defaults will be used:
    • Themes: tsdh-light and tsdh-dark distributed with GNU Emacs
    • Default viewing mode: 'query
      • This will check against the visitor’s browser-set preference, and default to 'dark if no preference is specified. Anti-fingerprinting settings may prevent reading the browser setting, or cause the browser to mask it (usually, by showing a preference for 'light).
    • Headline bullets: 'nil – i.e. bullets will not be prefixed to headlines
      • To prefix headlines with the default bullets, instead use:
        (setq nice-org-html-headline-bullets t)
                    
      • Or you can specify headline bullets with a plist like this (the defaults):
        (setq nice-org-html-headline-bullets
              '(:h1 "" :h2 "" :h3 "" :h4 "" :h5 ""))
                    
  • Further look-and-feel customization is handled through the nice-org-html-options plist. The following properties and values are supported (so far):
    PropertyValueEffect
    :layout“compact”Header and footer links always contained in drawer
    :layout“expanded”Header and footer links never contained in drawer
    :collapsingtClicking headlines collapses / expands sections
    :src-langtSource language displayed in header of source blocks

Exporting

  • After loading this package and hooking nice-org-html-mode to org-mode, when you open an Org buffer, nice-org-html-mode will activate.
  • If you then interactively export your Org buffer via the dispatcher (C-c C-e), you will be presented with options to export to ‘nice HTML’, in addition to the basic HTML export options.
  • When exporting to ‘nice HTML’, you will be prompted for (all optional) options plist, header and footer, and CSS and JS filepaths. If specified, the contents of those variables will be injected, accordingly, into the generated HTML.
    • CSS and JS must be paths (strings) to files with contents to be injected.
    • Header and footer may be a path to an HTML file, or a list of cons pairs.
    • A default HTML structure will be used for the header and/or footer, if a list of this form:
      '(("left" . uri0) ("link1" . "uri1") ... ("linkN" . "uriN"))
              
      • left will be displayed as anchor text, and hyperlinked if uri0 is non-nil.
      • link1linkN will be hyperlinks, collapsed into a drawer for mobile viewers.
  • These variables may also be set globally, and then used or overridden during interactive export. For example:
    (setq nice-org-html-header
          '(("title" . "/home.html")
            ("foo" . "/foo.html") ("bar" . "/bar.html")))
    ;; Or: (setq nice-org-html-header "path/to/your/header.html")
    
    (setq nice-org-html-footer
          '(("© author" . "mailto:a@b.c")
            ("oof" . "https://oof.a") ("rab" . "https://rab.b")))
    ;; Or: (setq nice-org-html-header "path/to/your/footer.html")
    
    (setq nice-org-html-css "path/to/your/style.css")
    
    (setq nice-org-html-js "path/to/your/script.js")
    
    (setq nice-org-html-options '(:layout "compact" :collapsing t))
        

Publishing

  • This package is particularly well-suited to publishing Org projects, as websites comprised of many linked pages. The included publishing function, nice-org-html-publish-to-html, relies on global values for all of the above variables. To use it, in specifying the value of org-publish-projects-alist, for a given project just specify:
    ;; ...
    :publishing-function #'nice-org-html-publish-to-html
    ;; ...
        
  • For more granular per-project configuration, there is a publishing-function-generating macro, nice-org-html-publishing-function, which takes values for the above configuration variables, and defines a publishing function unique to that invocation. Note: the options plist is constructed out of remaining arguments to this macro, so options should be specified directly. For example, your per-project configuration - i.e. the value of org-publish-projects-alist - may look something like this:
    `(("project-x/files"
       :base-extension "org"
       :base-directory "path/to/source-x/"       
       :publishing-directory "path/to/target-x/"
       ;; ...
       :publishing-function
       ,(nice-org-html-publishing-function
         :theme-alist ((light . spacemacs-light) (dark . spacemacs-dark))
         :default-mode dark
         :headline-bullets (:h1 "" :h2 "" :h3 "" :h4 "" :h5 "")
         :header "path/to/your/header.html"
         :footer "path/to/your/footer.html"
         :css "path/to/your/style.css"
         :js "path/to/your/script.js"
         :layout "compact"
         :collapsing t)))
        
    • Any variable for which values are not specified will take the global (or default) value.
  • Finally, there is a less ergonomic alternative macro, nice-org-html-make-publishing-function, which takes values for all of the above configuration variables as direct arguments, rather than properties. The function defined by this macro does not validate its arguments, and the macro is primarily for use in contexts where invocations need to be constructed programmatically, with lexically bound variables spliced in. For most uses, nice-org-html-publishing-function should be preferred over the “-make-” alternative.

Things to keep in mind

  • Important: for downloaded themes, you must run M-x load-theme once, at some point, before exporting or publishing, so that Emacs “recognizes” the theme as safe to load. Failure to do so may brick an Emacs instance, requiring a restart.
  • You can specify "" as the bullet for a headline level to omit bullets for that level.
  • The HTML specified by nice-org-html-header and nice-org-html-footer will inherit the package default styling, unless further styling for these is defined in the file specified by nice-org-html-css.
  • For easy CSS customization, the contents of each user-specified HTML file are wrapped together in a <div> element; with id = ‘injected-header’ and id = ‘injected-footer’, respectively, and both with class = ‘injected’.
  • The CSS specified by nice-org-html-css may also use the CSS variables defined in nice-org-html.css, which ultimately refer to Emacs face attribute values determined by your chosen themes.
  • The CSS specified by nice-org-html-css may override the default styling.

Contributing

  • If you find a bug and want it fixed, please raise an issue.
  • If you would like to add or refine something feel free to:
    1. Fork the repo
    2. Clone your fork and develop / use it
    3. Create a pull request – I’ll probably approve it
  • Note: there are so many themes for Emacs, that it’s tough to make them all render nicely with a uniform mapping of face-attributes to CSS variables. But fear not! If you find that this package doesn’t “play nice” with your preferred theme, there is a built-in mechanism for re-mapping variables on a per-theme basis, precisely to handle these outliers. Just raise an issue, or take a look at the CSS specific to ‘leuven’ themes and create a PR with something similar.

Credits

  • All of the theme developers, without which this package would be useless.
  • Shi Tianshu’s org-html-themify provided the basic model for CSS interpolation.
  • Various stackoverflow posts were of great help, but alas, I’ve lost the links.

About

Modern Org HTML interface

Resources

License

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published

Languages

  • Emacs Lisp 53.2%
  • CSS 30.5%
  • JavaScript 16.3%