Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
a blog engine so cool it wears skinny jeans
branch: master

Fetching latest commit…

Cannot retrieve the latest commit at this time

Failed to load latest commit information.
README.creole
skinny.el

README.creole

Skinny blog engine for super hipsters

Skinny is a blog engine written with Elnode.

It serves files written in Creole Wiki format as blog entries. It allows customization with CSS files and headers and footers.

Blog directory structure

Skinny has a fixed directory structure right now. It looks like this:

blogroot/
  template/
    headerhtml
    footerhtml
  stuff/
    css/
      site.css
    ico/
       favicon.ico
    img/
       name-of-some-image.png
  blog/
    201212/
       name-of-blog-entry.creole
       other-blog-entry.creole
    201301/
       latest-blog-entry.creole

Blog entries are served from blog/ and should be separated out by date.

The favicon, site css and template files are all fixed for now. Configuration for those coming later.

Configuring Skinny

You can configure skinny with Emacs' Customize:

M-x customize-group skinny

Here is what you get:

Skinny group: 
       State : something in this group has been set and saved.
   A blog engine written with Elnode. Good for hipsters.

Skinny Host: localhost
    State : STANDARD.
   The interface to start talking hipster shite on.

Skinny Port: 8090
    State : STANDARD.
   The TCP port to start talking hipster shite on.

Skinny Root: ~/myblog
    State : SAVED and set.
   The directory used tostore the skinny docroot.

Skinny Sort Posts By Filename: Toggle  on (non-nil)
    State : SAVED and set.
   Sort blog posts by filename instead of by mtime. Hide
   If you enable this option, only files that match the following
   pattern are listed:

     <YEAR>_<MONTH>/<DAY>-<post-title>.creole

   where `<YEAR>_MONTH>/' is the directory containing the post.
   Then, if you have the following files:

     2015_01/22-stuff.creole
     2015_02/05-more-stuff.creole
     2015_02/07-newest.creole
     random-post.creole

   skinny/list-published will return:

     (07-newest.creole 05-more-stuff.creole 22-stuff.creole random-post.creole)

   Regardless of mtimes of the files.

Set skinny-root to the root directory of your blog and skinny-port to whatever port you want to use to serve Skinny.

Starting Skinny

After configuring just do:

M-x skinny-start

Or use the code:

(skinny-start)

or do it from the command line:

emacsclient -e '(skinny-start)' -s /path/to/some/daemon-emacs

Skinny's Paste handling

I've recently added a paste handler to Skinny. I did this because GitHub's gist service has stopped working for me and pasting is such a simple thing to do.

I use a simple function to upload files to the directory where this elnode handler serves files from. I just use Emacs' TRAMP to do that.

Here's the upload function:

;;; paste.el --- wrap a piece of text with creole stuff and save it somewhere

(defvar skinny-paste-dir "/po3:skinny-pastes/pastes"
  "The directory where we save paste files.

A full tramp name is possible so you can save to a remote.")

(defvar skinny-paste-http "http://nic.ferrier.me.uk/pastes"
  "The HTTP URL where the pastes are accessible.")

(defvar skinny-paste-history nil
  "The history of `skinny-paste-region' descriptions.")

(defun skinny-paste-region (start end description)
  "Make a new paste out of the region between START and END.

DESCRIPTION describes the paste."
  (interactive
   (list (region-beginning)
         (region-end)
         (read-from-minibuffer
          "paste description: "
          nil nil nil skinny-paste-history)))
  (let ((region (buffer-substring-no-properties start end))
        (buffer-mode (replace-regexp-in-string
                      "-mode$" "" (symbol-name major-mode))))
    (let* ((basename (base64-encode-string (sha1 description)))
           (filename
            (format "%s/%s.creole" skinny-paste-dir basename)))
      (with-temp-file filename
          (insert
           (format
            "== %s ==\n\n{{{\n##! %s\n%s}}}\n//%s//\n"
            description buffer-mode region (current-time-string))))
      (when (called-interactively-p 'any)
        (kill-new (concat skinny-paste-http "/" basename)))
      filename)))

;;; paste.el ends here
Something went wrong with that request. Please try again.