diff options
author | Vincent Ambo <tazjin@google.com> | 2019-12-21T00·56+0000 |
---|---|---|
committer | Vincent Ambo <tazjin@google.com> | 2019-12-21T00·56+0000 |
commit | 1c767a174888d3c8fe582f0b7d418b3ddbd30700 (patch) | |
tree | 6a60c7841718382c128081f021cc965c8dcc3df1 /fun/elblog | |
parent | fbdc9b1d6009c7b9294542c6935a760a6d5eb819 (diff) | |
parent | 3253e4c4fba26f5cebc41c10a28b0722f9efcac1 (diff) |
merge(elblog): Integrate at //fun/elblog r/263
Diffstat (limited to 'fun/elblog')
-rw-r--r-- | fun/elblog/.gitignore | 1 | ||||
-rw-r--r-- | fun/elblog/README.md | 11 | ||||
-rw-r--r-- | fun/elblog/blog.css | 37 | ||||
-rw-r--r-- | fun/elblog/blog.el | 123 | ||||
-rw-r--r-- | fun/elblog/postamble.html | 9 | ||||
-rw-r--r-- | fun/elblog/preamble.html | 6 |
6 files changed, 187 insertions, 0 deletions
diff --git a/fun/elblog/.gitignore b/fun/elblog/.gitignore new file mode 100644 index 000000000000..c531d9867f6c --- /dev/null +++ b/fun/elblog/.gitignore @@ -0,0 +1 @@ +*.elc diff --git a/fun/elblog/README.md b/fun/elblog/README.md new file mode 100644 index 000000000000..994b1138ef8f --- /dev/null +++ b/fun/elblog/README.md @@ -0,0 +1,11 @@ +elblog +====== + +This is a simple blogging software written in Emacs Lisp. + +The idea is that it should be able to do most of the things [my actual blog][] +does at the moment. + +No documentation exists for now besides the commit messages, but it works! + +[my actual blog]: https://www.tazj.in/ diff --git a/fun/elblog/blog.css b/fun/elblog/blog.css new file mode 100644 index 000000000000..0d021f78e89b --- /dev/null +++ b/fun/elblog/blog.css @@ -0,0 +1,37 @@ +<style type="text/css"> +body { + margin: 40px auto; + max-width: 800px; + line-height: 1.6; + font-size: 18px; + color: #383838; + padding: 0 10px +} +h1, h2, h3 { + line-height: 1.2 +} +.footer { + text-align: right; +} +.lod { + text-align: center; +} +.unstyled-link { + color: inherit; + text-decoration: none; +} +.uncoloured-link { + color: inherit; +} +.date { + text-align: right; + font-style: italic; + float: right; +} +.inline { + display: inline; +} +.navigation { + text-align: center; +} +</style> diff --git a/fun/elblog/blog.el b/fun/elblog/blog.el new file mode 100644 index 000000000000..102aa3791481 --- /dev/null +++ b/fun/elblog/blog.el @@ -0,0 +1,123 @@ +;;; blog.el --- A simple org-mode & elnode blog software. +;;; -*- lexical-binding: t; -*- + +(require 'dash) +(require 'elnode) +(require 'f) +(require 'ht) + +;; Definition of customization options + +(defgroup elblog nil + "Configuration for the Emacs Lisp blog software" + :link '(url-link "https://github.com/tazjin/elblog")) + +(defcustom elblog-port 8010 + "Port to run elblog's HTTP server on" + :group 'elblog + :type 'integer) + +(defcustom elblog-host "localhost" + "Host for elblog's HTTP server to listen on" + :group 'elblog + :type 'string) + +(defcustom elblog-title "Elblog" + "Title text for this elblog instance" + :group 'elblog + :type 'string) + +(defcustom elblog-article-directory nil + "Directory in which elblog articles are stored" + :group 'elblog + :type 'string) + +(defcustom elblog-additional-routes '() + "Additional Elnode routes to register in the Elblog instance" + :group 'elblog + :type '(alist :key-type regexp :value-type function)) + +;; Declare user-configurable variables needed at runtime. + +(defvar elblog-articles (ht-create) + "A hash-table of blog articles. This is used for looking up articles from + URL fragments as well as for rendering the index.") + +;; HTML templating setup + +(defun template-preamble () + "Templates the preamble snippet with the correct blog title." + (format (f-read-text "preamble.html") elblog-title)) + +(defun configure-org-html-export () + "Configure org-mode settings for elblog's HTML templating to work correctly." + (setq org-html-postamble t) + (setq org-html-doctype "html5") + (setq org-html-head-include-scripts nil) + (setq org-html-style-default (f-read-text "blog.css")) + (setq org-html-preamble-format `(("en" ,(template-preamble)))) + (setq org-html-postamble-format `(("en" ,(f-read-text "postamble.html"))))) + +;; Article fetching & rendering functions + +(defun render-org-buffer (input-buffer &optional force) + "Renders an org-mode buffer as HTML and returns the name of the output buffer." + (letrec ((output-buffer (concat (buffer-name input-buffer) "-rendered")) + ;; Don't re-render articles unless forced. + (must-render (or force + (not (get-buffer output-buffer))))) + (if (and input-buffer must-render) + (with-current-buffer input-buffer + (org-export-to-buffer 'html output-buffer nil nil t))) + (if input-buffer output-buffer nil))) + +(defun get-buffer-string (buffer) + "Returns the contents of the specified buffer as a string." + (with-current-buffer (get-buffer buffer) + (buffer-string))) + +(defvar-local article-not-found + '(404 . "<html><body><p>Oh no, the article was not found.</p></body></html>")) + +(defvar-local text-html '("Content-Type" . "text/html")) + +(defun render-article (article) + "Renders an article, if it exists." + (letrec ((rendered (-some->> + (ht-get elblog-articles article) + (concat elblog-article-directory) + (find-file) + (render-org-buffer)))) + (if rendered `(200 . ,(get-buffer-string rendered)) + article-not-found))) + +(defun blog-post-handler (httpcon) + "This handler servers a blog post from the configured blog post directory." + (let ((response (render-article (elnode-http-mapping httpcon 1)))) + (elnode-http-start httpcon (car response) text-html) + (elnode-http-return httpcon (cdr response)))) + +;; Web server implementation + +(defvar elblog-routes + '(("^.*//\\(.*\\)" . blog-post-handler)) + "The default routes available in elblog. They can be extended by the user +by setting the elblog-additional-routes customize option.") + +(defun elblog-handler (httpcon) + (elnode-hostpath-dispatcher + httpcon + (-concat elblog-additional-routes elblog-routes))) + +(defun start-elblog () + (interactive) + (configure-org-html-export) + (elnode-start 'elblog-handler + :port elblog-port + :host elblog-host)) + +(defun stop-elblog () + (interactive) + (elnode-stop elblog-port)) + +(provide 'elblog) diff --git a/fun/elblog/postamble.html b/fun/elblog/postamble.html new file mode 100644 index 000000000000..16a26218a0c0 --- /dev/null +++ b/fun/elblog/postamble.html @@ -0,0 +1,9 @@ +<hr> +<footer><p class="footer">Served with <a class="uncoloured-link" href="https://github.com/tazjin/elblog">Emacs</a>.</p> + <p class="footer"> + <a class="uncoloured-link" href="https://twitter.com/tazjin">Twitter</a> + | + <a class="uncoloured-link" href="mailto:blog@tazj.in">Mail</a> + </p> + <p class="lod">ಠ_ಠ</p> +</footer> diff --git a/fun/elblog/preamble.html b/fun/elblog/preamble.html new file mode 100644 index 000000000000..be74b9207e72 --- /dev/null +++ b/fun/elblog/preamble.html @@ -0,0 +1,6 @@ +<header> + <h1> + <a class="unstyled-link" href="/">%s</a> + </h1> + <hr> +</header> |