December 8, 2014

Splitting Out Cryogen's Compiler

As Cryogen continued to grow over the past few weeks, a couple of users - including myself - found it increasingly cumbersome to update our blogs with the newest features in the template. It seemed the general approach was to do another lein new cryogen and then copy over the updates. Obviously this is very error prone and merging is a pain for those who have their own modifications to the template.

Seeing as how Cryogen is pretty stable now, pulling out the compiler code into a library was the clear direction to go in and was also agreed upon by the current users.

With that, I'm happy to report that I've migrated everything except for server.clj from Cryogen's src folder to Cryogen-core. This library is also on clojars so you can simply add the dependency to your project. You can still create a new Cryogen template with lein new cryogen my-blog, but this will be the new file structure:

 |   |---templates
 |   |   |---css
 |   |   |   |---screen.css
 |   |   |---js
 |   |   |   |---highlight.pack.js
 |   |   |---html
 |   |   |   |---layouts
 |   |   |       |---archives.html
 |   |   |       |---base.html
 |   |   |       |---home.html
 |   |   |       |---page.html
 |   |   |       |---post.html
 |   |   |       |---tag.html
 |   |   |---md
 |   |       |---pages
 |   |       |   |
 |   |       |   |
 |   |       |---posts
 |   |           |
 |   |           |
 |   |           |
 |   |---404.html
 |   |---config.edn
 |   |---cryogen
 |   |   |---server.clj

If you have your own modifications to the compiler, you can do a redef in your project to override the default behaviour. When there are updates to the compiler you can simply bump up the version in your project while keeping your modifications.

On one more note, there was an issue where local resource links would have to be absolute such as:


Where /blog is your blog-prefix specified in your config. If you changed your blog prefix though you would have to manually search and replace all of the /blog's in your markdown files so I've added a simple transformer function, rewrite-hrefs, in the compiler amend this.

 (defn rewrite-hrefs
   [{:keys [blog-prefix]} text state]
   [(clojure.string/replace text #"href=.?/|src=.?/" #(str (subs % 0 (dec (count %))) blog-prefix "/"))
 (defn parse-content
   [rdr config]
     (->> ( rdr)
          (s/join "\n"))
     :heading-anchors true
     :replacement-transformers (conj transformer-vector (partial rewrite-hrefs config))))

When parse-content is called, the replacement transformer will process the html generated by md-to-html-string and inject the blog prefix in front of any local resource links in your markdown. For example, if your blog prefix was /blog,


would become

 <img src="/blog/img/cryogen.png">

once the post gets compiled. Do note that the leading slash in front of the local resource is required.

These are the things that have been happening with Cryogen lately. And as usual, if you want new features added please feel free to submit an issue or pull request. :)

Tags: cryogen clojure