Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with
or
.
Download ZIP

Comparing changes

Choose two branches to see what's changed or to start a new pull request. If you need to, you can also compare across forks.

Open a pull request

Create a new pull request by comparing changes across two branches. If you need to, you can also compare across forks.
base fork: raek/bokareis
base: 2ce1b4b2aa
...
head fork: raek/bokareis
compare: fb5fb32fa7
  • 2 commits
  • 3 files changed
  • 0 commit comments
  • 1 contributor
View
66 src/bokareis/main.clj
@@ -19,20 +19,27 @@
(def markdown-command "markdown")
-(declare list-posts slurp-shell-out render-and-slurp-markdown read-post
- read-json-file render-post render-index write-text-file
- relative-post-output-dir post-title post-url post-path-segments
- expand-links post-link-node? expand-post-link)
+(declare list-posts slurp-shell-out render-and-slurp-markdown
+ read-template read-post read-json-file render-post render-index
+ write-text-file relative-post-output-dir post-title post-url
+ post-path-segments expand-links post-link-node? expand-post-link
+ expand-post-template post-text-node? expand-index-template
+ posts-node?)
(defn -main [root]
(let [posts (map read-post (list-posts (f root "posts")))
posts-by-slug (into {} (for [post posts]
[(get post "slug") post]))
- out-dir (f root "out")]
- (write-text-file (render-index posts)
+ out-dir (f root "out")
+ post-template (read-template (f root "templates" "post.html"))
+ index-template (read-template (f root "templates" "index.html"))
+ blog {:templates {:post post-template
+ :index index-template}
+ :posts-by-slug posts-by-slug}]
+ (write-text-file (render-index blog)
(f out-dir "index.html"))
(doseq [post posts]
- (write-text-file (render-post post posts-by-slug)
+ (write-text-file (render-post post blog)
(f out-dir
(relative-post-output-dir post)
"index.html")))))
@@ -42,6 +49,9 @@
(list node)
(mapcat list-posts (.listFiles node))))
+(defn read-template [file]
+ (h/html-resource (io/reader file :encoding html-file-encoding)))
+
(defn read-post [post-dir]
(let [meta (read-json-file (f post-dir post-meta-file-name))
text (render-and-slurp-markdown (f post-dir post-text-file-name))
@@ -71,17 +81,25 @@
(str "Command exited with non-zero status: " command)))
out)))
-(defn render-post [post posts-by-slug]
- (apply str (h/emit* (expand-links (get post "text") posts-by-slug))))
-
-(defn render-index [posts]
- (apply str
- (concat ["<ul>\n"]
- (for [post posts]
- (format "<li><a href=\"%s\">%s</a></li>\n"
- (post-url post)
- (apply str (h/emit* (post-title post)))))
- ["</ul>"])))
+(defn render-post [post blog]
+ (let [{:keys [posts-by-slug templates]} blog
+ text-tree (expand-links (get post "text") posts-by-slug)
+ post-tree (expand-post-template (:post templates) text-tree)]
+ (apply str (h/emit* post-tree))))
+
+(defn render-index [blog]
+ (let [{:keys [posts-by-slug templates]} blog
+ posts (vals posts-by-slug)
+ posts-string (apply str
+ (concat ["<ul>\n"]
+ (for [post posts]
+ (format "<li><a href=\"%s\">%s</a></li>\n"
+ (post-url post)
+ (apply str (h/emit* (post-title post)))))
+ ["</ul>"]))
+ posts-tree (h/html-snippet posts-string)]
+ (apply str (h/emit* (expand-index-template (:index templates)
+ posts-tree)))))
(defn write-text-file [string file]
(.mkdirs (.getParentFile file))
@@ -125,3 +143,15 @@
:attrs {:href url}
:content title})
(throw (RuntimeException. (str "Unknown post slug: " slug)))))))
+
+(defn expand-post-template [template text-tree]
+ (h/at template [(h/pred post-text-node?)] (constantly text-tree)))
+
+(defn post-text-node? [node]
+ (= (:tag node) :post-text))
+
+(defn expand-index-template [template post-list-tree]
+ (h/at template [(h/pred posts-node?)] (constantly post-list-tree)))
+
+(defn posts-node? [node]
+ (= (:tag node) :posts))
View
63 test/bokareis/main_test.clj
@@ -1,50 +1,11 @@
(ns bokareis.main-test
(:use midje.sweet
bokareis.main
+ [bokareis.util :only [with-temp-dir html-contains create-post]]
[clojure.java.io :only [file] :rename {file f}]
[clojure.data.json :only [json-str]])
(:require [net.cgrand.enlive-html :as h])
- (:import (java.io File)
- (org.joda.time DateTime)))
-
-(defn create-temp-dir []
- (let [file (File/createTempFile "bokareis-test" "")]
- (when-not (.delete file)
- (throw (RuntimeException.)))
- (when-not (.mkdir file)
- (throw (RuntimeException.)))
- file))
-
-(defn delete-file-tree [^File tree]
- (when (.isDirectory tree)
- (doseq [child (.listFiles tree)]
- (delete-file-tree child)))
- (.delete tree))
-
-(defmacro with-temp-dir [sym & body]
- `(let [~sym (create-temp-dir)]
- (try (do
- ~@body)
- (finally
- (delete-file-tree ~sym)))))
-
-(defn html-contains [html-string]
- (fn [html-tree]
- ((contains html-string) (apply str (h/emit* html-tree)))))
-
-(fact "temp dir exists within body"
- (with-temp-dir t
- (.exists t) => truthy))
-
-(fact "temp dir does not exist after body"
- (.exists (with-temp-dir t
- t))
- => falsey)
-
-(defn create-post [post-dir meta-content text-content]
- (.mkdirs post-dir)
- (spit (f post-dir "post.meta") meta-content)
- (spit (f post-dir "text.markdown") text-content))
+ (:import (org.joda.time DateTime)))
(fact "application renders posts"
(with-temp-dir root
@@ -52,15 +13,22 @@
(json-str {"slug" "hello-world"
"published" "2012-02-11T14:47:00Z"})
"# Hello world\n\nThis is a paragraph\n\n<post-link to=\"hello-world\"></post-link>\n")
- (spit (f root "blog.meta")
- "{}")
+ (write-text-file "{}" (f root "blog.meta"))
+ (write-text-file "This is a post.<post-text></post-text>"
+ (f root "templates" "post.html"))
+ (write-text-file "This is the index.<posts></posts>"
+ (f root "templates" "index.html"))
(-main (str root))
(slurp (f root "out" "index.html"))
=> (contains "<a href=\"/2012/02/11/hello-world/\">Hello world</a>")
(slurp (f root "out" "2012" "02" "11" "hello-world" "index.html"))
=> (contains "<h1>Hello world</h1>")
(slurp (f root "out" "2012" "02" "11" "hello-world" "index.html"))
- => (contains "<a href=\"/2012/02/11/hello-world/\">Hello world</a>")))
+ => (contains "<a href=\"/2012/02/11/hello-world/\">Hello world</a>")
+ (slurp (f root "out" "index.html"))
+ => (contains "This is the index.")
+ (slurp (f root "out" "2012" "02" "11" "hello-world" "index.html"))
+ => (contains "This is a post.")))
(fact "list-post finds a post"
(with-temp-dir root
@@ -110,8 +78,9 @@
(render-post {"slug" "foo-bar"
"published" (DateTime/parse "2012-03-01T16:41:00Z")
"text" (h/html-snippet "<h1>Foo Bar</h1><p><post-link to=\"hello-world\"></p>")}
- {"hello-world" {"slug" "hello-world"
- "published" (DateTime/parse "2012-02-11T14:47:00Z")
- "text" (h/html-snippet "<h1>Hello world</h1>\n\n<p>This is a paragraph</p>\n")}})
+ {:posts-by-slug {"hello-world" {"slug" "hello-world"
+ "published" (DateTime/parse "2012-02-11T14:47:00Z")
+ "text" (h/html-snippet "<h1>Hello world</h1>\n\n<p>This is a paragraph</p>\n")}}
+ :templates {:post {:tag :post-text}}})
=> (contains "<a href=\"/2012/02/11/hello-world/\">Hello world</a>"))
View
44 test/bokareis/util.clj
@@ -0,0 +1,44 @@
+(ns bokareis.util
+ (:use midje.sweet
+ [clojure.java.io :only [file] :rename {file f}])
+ (:require [net.cgrand.enlive-html :as h])
+ (:import (java.io File)))
+
+(defn create-temp-dir []
+ (let [file (File/createTempFile "bokareis-test" "")]
+ (when-not (.delete file)
+ (throw (RuntimeException.)))
+ (when-not (.mkdir file)
+ (throw (RuntimeException.)))
+ file))
+
+(defn delete-file-tree [^File tree]
+ (when (.isDirectory tree)
+ (doseq [child (.listFiles tree)]
+ (delete-file-tree child)))
+ (.delete tree))
+
+(defmacro with-temp-dir [sym & body]
+ `(let [~sym (create-temp-dir)]
+ (try (do
+ ~@body)
+ (finally
+ (delete-file-tree ~sym)))))
+
+(defn html-contains [html-string]
+ (fn [html-tree]
+ ((contains html-string) (apply str (h/emit* html-tree)))))
+
+(fact "temp dir exists within body"
+ (with-temp-dir t
+ (.exists t) => truthy))
+
+(fact "temp dir does not exist after body"
+ (.exists (with-temp-dir t
+ t))
+ => falsey)
+
+(defn create-post [post-dir meta-content text-content]
+ (.mkdirs post-dir)
+ (spit (f post-dir "post.meta") meta-content)
+ (spit (f post-dir "text.markdown") text-content))

No commit comments for this range

Something went wrong with that request. Please try again.