#+TITLE: ennum ennum is a purely functional Org Mode based static blog generator written in Emacs Lisp. It is intended as a complete blog-specific replacement for the org-publish system. * Features - minimal rebuilds - purely functional - resize and optimize images for file size - tag posts - generate post listings (of all posts, and filtered by tag) - generate Atom feeds - translate posts to multiple languages - tangle source blocks embedded in posts - simple HTTP server to view blog locally * Features in detail ** Minimal rebuilds When an input file did not change, it is not rebuilt. This saves a lot of time and makes the "edit-compile-debug" cycle really fast. ** Purely functional ennum is purely functional in that the built output always corresponds to the current source. The built output is guaranteed to not contain artifacts from previous builds. For example, when a source file is deleted, the corresponding output file is also deleted in the next rebuild. Note that ennum's purely functional nature is not achieved by merely deleting the output directory and creating a new one in its place. That would be an enormous waste of time and a violation of the "minimal rebuilds" principle. Instead ennum uses what we call "ennum expressions"---a caching and dependency tracking system inspired by the [[https://guix.gnu.org/][Guix]] store and [[https://arxiv.org/abs/1709.00833][G-expressions]]. ** Resize and optimize images for file size ennum resizes and optimizes images in posts so that pages load quicker and are light on network use. ** Generate post listings and Atom feeds ennum generates index pages listing all posts, and posts filtered by tag. ** Multiple languages ennum understands posts translated to multiple languages. It automatically links to translations of a post, and generates separate post listings for different languages. ** Tangle source blocks embedded in posts ennum lets you tangle source blocks embedded in posts and write them to a separate source file. Thus, you can make the source code in your blog available for download without having to duplicate your code in two places. ** Simple HTTP server to view blog locally ennum comes with a simple HTTP server to view blog locally before publishing. ** Pure Emacs Lisp ennum is written purely in Emacs Lisp [fn::except for the image processing code, for which we shell out to external command-line tools]. No need to pull up your terminal emulator or shell mode to rebuild your blog. * Installation Clone the repository. #+BEGIN_SRC sh $ git clone https://git.systemreboot.net/ennum/ #+END_SRC Add the path to the cloned repository to your load path, and load ennum. #+BEGIN_SRC emacs-lisp (add-to-list 'load-path "~/ennum") (require 'ennum) #+END_SRC * Usage Set up /ennum-blog/ with settings relevant for your blog, and run /M-x ennum-publish/. A simple sample /ennum-blog/ is given below. For detailed documentation of all available settings, see its docstring. #+BEGIN_SRC emacs-lisp (setq ennum-blog '(:working-directory "~/blog" :output-directory "output" :posts-directory "posts" :images-directory "images" :static-directory "files" :video-directory "videos" :blog-title "Muthu Mani Maalai" :blog-subtitle "Mani's blog" :blog-domain "example.org" :blog-license "All content is licensed under a Creative Commons Attribution-ShareAlike 4.0 International License.")) #+END_SRC * Post format Posts are written as Org mode documents. Keywords TITLE, DATE, FILETAGS are used to indicate the title, date, and tags respectively. The SUMMARY keyword is used to specify the short text that should describe the post in post listings such as the index page. #+BEGIN_SRC org ,#+TITLE: Gandikota ,#+DATE: <2022-07-02> ,#+FILETAGS: :travel: ,#+SUMMARY: Last week, I visited Gandikota, the ruins of a fort in Andhra Pradesh. Furthermore, the theory of syntactic features developed earlier is not to be considered in determining a parasitic gap construction. However, this assumption is not correct, since this analysis of a formative as a pair of sets of features can be defined in such a way as to impose the traditional practice of grammarians. We will bring evidence in favor of the following thesis: a case of semigrammaticalness of a different sort is, apparently, determined by the system of base rules exclusive of the lexicon. Conversely, this selectionally introduced contextual feature is necessary to impose an interpretation on an important distinction in language use. Clearly, most of the methodological work in modern linguistics is to be regarded as nondistinctness in the sense of distinctive feature theory. #+END_SRC ** Link types ennum comes with several built-in link types. The /post/ link type can be used to refer to other of your own posts. The /image/ and /thumbnail/ link types refer to images scaled to different sizes. The /static/, /video/ and /tangle/ link types refer to static files, videos and tangled output respectively. The /tag/ link type refers to a page listing posts of a specific tag. Example usage for these link types is shown below. #+BEGIN_SRC org Link to post whose basename (that is, filename without the extension) is /foo/ [[post:foo]] Link to image /bar.jpg/ [[image:bar.jpg]] Link to thumbnail sized version of image file /bar.jpg/ [[thumbnail:bar.jpg]] Link to static file [[static:attached-document.odt]] Link to video [[video:movie.webm]] Link to tangled output file [[tangle:macros.scm]] Link to page listing posts tagged /travel/ [[tag:travel]] #+END_SRC ** Posts in multiple languages Optionally, you can write your post in a different language and specify the language using the LANGUAGE keyword. If you have the same post translated to different languages, you can group them together using the TRANSLATION_GROUP keyword. All posts with the same TRANSLATION_GROUP will be considered translations of each other, and will link to each other in the exported output. If the TRANSLATION_GROUP keyword is not specified, it defaults to the basename (that is, filename without the extension) of the file. For example, if a post has a filename /foo-bar.org/, then its basename is /foo-bar/. #+BEGIN_SRC org ,#+TITLE: Gandikota ,#+DATE: <2022-07-02> ,#+FILETAGS: :travel: ,#+SUMMARY: Lorem ipsum dolor sit amet ,#+LANGUAGE: la ,#+TRANSLATION_GROUP: gandikota Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum. #+END_SRC