Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
42 commits
Select commit Hold shift + click to select a range
e6ca001
Merge branch 'refactor-yaml' into content-pipeline
bhagany Dec 4, 2016
e04d824
Merge branch 'render-pre-wrap' into content-pipeline
bhagany Dec 4, 2016
fb4a69b
Merge branch 'render-pre-wrap' into content-pipeline
bhagany Dec 4, 2016
27394a0
Merge branch 'render-pre-wrap' into content-pipeline
bhagany Dec 4, 2016
8b05456
Merge branch 'merge-filedata' into content-pipeline
bhagany Dec 5, 2016
55412cc
Allow more flexibility and composability based around file content
bhagany Dec 5, 2016
c431711
Simplify finding unchanged content files
bhagany Dec 5, 2016
03eec4e
Include `:parent-path` in parsed file metadata
bhagany Dec 5, 2016
88e5ff5
Exclude `:include-rss` and `:include-atom` from original content file…
bhagany Dec 5, 2016
7f40dc8
Get original, not fully-rendered, content into atom xml
bhagany Dec 5, 2016
b36bac8
Update spec document with `:has-content`, `:original-content`, `:parsed`
bhagany Dec 5, 2016
14a7e1b
Small `content-pre-wrap` refactor; pass only `pod` instead of `option…
bhagany Dec 5, 2016
f17e211
Add docstrings to `content-pre-wrap` and `make-path`
bhagany Dec 5, 2016
e7bcf75
Merge branch 'merge-filedata' into content-pipeline
bhagany Dec 5, 2016
4563918
Update new default filterers, `:content` -> `:has-content`
bhagany Dec 5, 2016
d0acca3
Don't store `:original-content` in meta; get it on demand
bhagany Dec 6, 2016
ba71a04
Update spec document, `:original-content` -> `:original-path`
bhagany Dec 6, 2016
e2ba0e3
Make atom content more flexible
bhagany Dec 6, 2016
cf07276
Correctly handle `:include-rss` and `:include-atom` on markdown file …
bhagany Dec 8, 2016
a9566b1
merge merge-filedata -> content-pipeline
bhagany Dec 11, 2016
0ea04a4
Use correct namespace for `get-global-meta`
bhagany Dec 12, 2016
01516fb
Add `extensions` parameter to `atom-feed` and `rss`
bhagany Dec 12, 2016
c5f6ff7
Set `:content\` key for `\ttr\` and \`word-count\` tasks
bhagany Dec 13, 2016
a401423
Use output-files for rss
bhagany Dec 13, 2016
0432a3c
Use full extensions, with leading dot, for extension lookups
bhagany Dec 13, 2016
72b4bfa
Add `:content` key to collection `:entries`
bhagany Dec 18, 2016
ea7939f
Tighten up the data that `render-paths-fn`s return
bhagany Dec 18, 2016
61c14f1
Avoid setting `:content` key on file metadata; only use for rendering
bhagany Jan 7, 2017
a1c4bfe
merge master -> content-pipeline
bhagany Jan 8, 2017
40fd58d
Count words in original markdown, rather than parsed or rendered content
bhagany Jan 8, 2017
96fef7e
Use `:path` from TmpFile, rather than maintaining in perun metadata
bhagany Jan 8, 2017
c8b1023
Build regex from `file-exts` parameter to `content-pre-wrap`
bhagany Jan 14, 2017
51e7fef
Set new filedata on files created by `content-pre-wrap`
bhagany Jan 14, 2017
51fe571
Amend `markdown` docstring to note it writes HTML files
bhagany Jan 14, 2017
5c64296
Add debug statement before file removal during rendering
bhagany Jan 14, 2017
919f16f
Move rendering debug and info statements to more logical places
bhagany Jan 14, 2017
c8248f5
merge master -> content-pipeline
bhagany Jan 14, 2017
1e3a3f0
merge task-tests -> content-pipeline
bhagany Jan 14, 2017
5a48a1f
Add test for #77 - collection renders without input files
bhagany Jan 14, 2017
f677bd8
Add content tests
bhagany Jan 14, 2017
61d8860
merge master -> content-pipeline
bhagany Jan 15, 2017
d7cb61b
Add testing util task
bhagany Jan 15, 2017
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
13 changes: 11 additions & 2 deletions SPEC.md
Original file line number Diff line number Diff line change
Expand Up @@ -27,13 +27,22 @@ set for the tasks using task options.

## Post metadata

All posts have a filename which is used as a key to identify the post.
All posts have a path which is used as a key to identify the post.

- **:title**
- Required by: *atom-feed*
- Used by: *rss* either this or description is required
- **:content** The post content
- Set by: *markdown*
- Populated from file content
- Only set in the `:entry` value of the map passed to `renderer` functions
- **:has-content** Flag indicating that this file contains page content
- Set by input parsing tasks (like `markdown`) on output files
- Passed through by rendering tasks
- **:original-path** The path for the input file from which this entry is descended
- Set by input parsing tasks (like `markdown`) on output files
- Passed through by rendering tasks
- **:parsed** Contains the parsed file content
- Set by input parsing tasks (like `markdown`) on input files
- **:description**
- Used by: *rss* either this or title is required
- **:slug**
Expand Down
327 changes: 207 additions & 120 deletions src/io/perun.clj

Large diffs are not rendered by default.

5 changes: 2 additions & 3 deletions src/io/perun/atom.clj
Original file line number Diff line number Diff line change
Expand Up @@ -32,8 +32,7 @@
[:link {:href (str base-url filename) :rel "self"}]
[:link {:href base-url :type "text/html"}]
[:updated (->> (take 10 posts)
(map updated)
(map iso-datetime)
(map (comp iso-datetime updated first))
sort
reverse
first)]
Expand All @@ -44,7 +43,7 @@
[:name (:author global-metadata)]
[:email (:author-email global-metadata)]])

(for [{:keys [uuid canonical-url content title author author-email] :as post} (take 10 posts)
(for [[{:keys [uuid canonical-url title author author-email] :as post} content] (take 10 posts)
:let [author (or author (:author global-metadata))
author-email (or author-email (:author-email global-metadata))]]
(do
Expand Down
2 changes: 1 addition & 1 deletion src/io/perun/markdown.clj
Original file line number Diff line number Diff line change
Expand Up @@ -55,7 +55,7 @@
(let [file-content (-> file :full-path io/file slurp)
md-metadata (merge (:meta options) (yaml/parse-file-metadata file-content))
html (markdown-to-html file-content (:options options))]
(merge md-metadata {:content html} file)))
(merge md-metadata {:parsed html} file)))

(defn parse-markdown [markdown-files options]
(let [updated-files (doall (map #(process-file % options) markdown-files))]
Expand Down
9 changes: 7 additions & 2 deletions src/io/perun/meta.clj
Original file line number Diff line number Diff line change
Expand Up @@ -4,19 +4,24 @@

(def +meta-key+ :io.perun)

(defn meta-from-file
[tmpfile]
(when-let [meta (+meta-key+ tmpfile)]
(assoc meta :path (:path tmpfile))))

(defn get-meta
"Return metadata on files. Files metadata is a list.
Internally it's stored as a map indexed by `:path`"
[fileset]
(keep +meta-key+ (vals (:tree fileset))))
(keep meta-from-file (vals (:tree fileset))))

(defn key-meta [data]
(into {} (for [d data] [(:path d) d])))

(defn set-meta
"Update `+meta-key+` metadata for files in `data` and return updated fileset"
[fileset data]
(boot/add-meta fileset (into {} (for [d data] [(:path d) {+meta-key+ d}]))))
(boot/add-meta fileset (into {} (for [d data] [(:path d) {+meta-key+ (dissoc d :path)}]))))

(defn merge-meta* [m1 m2]
(vals (merge-with merge (key-meta m1) (key-meta m2))))
Expand Down
15 changes: 7 additions & 8 deletions src/io/perun/ttr.clj
Original file line number Diff line number Diff line change
Expand Up @@ -2,12 +2,11 @@
(:require [io.perun.core :as perun]
[time-to-read.core :as time-to-read]))

(defn add-ttr [file]
(if-let [content (:content file)]
(assoc file :ttr (time-to-read/estimate-for-text content))
file))
(defn add-ttr [[meta content]]
(when content
(assoc meta :ttr (time-to-read/estimate-for-text content))))

(defn calculate-ttr [files]
(let [updated-files (map add-ttr files)]
(perun/report-info "ttr" "added TTR to %s files" (count updated-files))
updated-files))
(defn calculate-ttr [meta-contents]
(let [metas (keep add-ttr meta-contents)]
(perun/report-info "ttr" "added TTR to %s files" (count metas))
metas))
17 changes: 8 additions & 9 deletions src/io/perun/word_count.clj
Original file line number Diff line number Diff line change
@@ -1,12 +1,11 @@
(ns io.perun.word-count
(:require [io.perun.core :as perun]))
(:require [io.perun.core :as perun]))

(defn add-word-count [file]
(if-let [content (:content file)]
(assoc file :word-count (count (clojure.string/split content #"\s")))
file))
(defn add-word-count [[meta content]]
(when content
(assoc meta :word-count (count (clojure.string/split content #"\s")))))

(defn count-words [files]
(let [updated-files (map add-word-count files)]
(perun/report-info "word-count" "added word-count to %s files" (count updated-files))
updated-files))
(defn count-words [meta-contents]
(let [metas (map add-word-count meta-contents)]
(perun/report-info "word-count" "added word-count to %s files" (count metas))
metas))
115 changes: 86 additions & 29 deletions test/io/perun_test.clj
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,12 @@
(or (some #{val} (-> file pm/+meta-key+ key))
(contains? (-> file pm/+meta-key+ key) val)))

(deftask prn-meta-key
[p path PATH str "path of the file to test"
k key KEY kw "the key to prn"]
(boot/with-pass-thru fileset
(->> path (boot/tmp-get fileset) pm/+meta-key+ key prn)))

(deftask key-test
[p path PATH str "path of the file to test"
k key KEY kw "the key to test"
Expand All @@ -34,6 +40,15 @@
(let [file (boot/tmp-get fileset path)]
(is (and (not (nil? file)) (value-fn file)) msg))))

(deftask content-test
[p path PATH str "path of the file to test"
c content CONTENT str "The content of the file"
n negate? bool "true to check if file doesn't exist"
m msg MSG str "message shown on failure"]
(boot/with-pass-thru fileset
(let [f (if negate? not identity)]
(is (f (.contains (slurp (boot/tmp-file (boot/tmp-get fileset path))) content))))))

(deftask file-exists?
[p path PATH str "path of the image to add"
n negate? bool "true to check if file doesn't exist"
Expand Down Expand Up @@ -105,6 +120,10 @@ author: Testy McTesterson

This --- be ___markdown___.")

(def parsed-md-basic "<h1><a href=\"#hello-there\" name=\"hello-there\"></a>Hello there</h1>\n<p>This --- be <strong><em>markdown</em></strong>.</p>")

(def parsed-md-smarts "<h1><a href=\"#hello-there\" name=\"hello-there\"></a>Hello there</h1>\n<p>This &mdash; be <strong><em>markdown</em></strong>.</p>")

(def js-content "(function somejs() { console.log('foo'); })();")

(deftesttask global-metadata-test []
Expand All @@ -117,7 +136,7 @@ This --- be ___markdown___.")
[data]
(str "<body>" (:content (:entry data)) "</body>"))

(deftesttask default-test []
(deftesttask default-tests []
(comp (add-txt-file :path "2017-01-01-test.md" :content md-content)
(boot/with-pre-wrap fileset
(pm/set-global-meta fileset {:base-url "http://example.com/"
Expand All @@ -126,51 +145,54 @@ This --- be ___markdown___.")
(p/markdown)
(testing "markdown"
(value-test :path "2017-01-01-test.md"
:value-fn #(meta= % :content "<h1><a href=\"#hello-there\" name=\"hello-there\"></a>Hello there</h1>\n<p>This --- be <strong><em>markdown</em></strong>.</p>")
:msg "`markdown` should set `:content` metadata on markdown file"))
:value-fn #(meta= % :parsed parsed-md-basic)
:msg "`markdown` should set `:parsed` metadata on markdown file")
(content-test :path "2017-01-01-test.html"
:content parsed-md-basic
:msg "`markdown` should populate HTML file with parsed content"))

(p/ttr)
(testing "ttr"
(value-test :path "2017-01-01-test.md"
(value-test :path "2017-01-01-test.html"
:value-fn #(meta= % :ttr 1)
:msg "`ttr` should set `:ttr` metadata"))

(p/word-count)
(testing "word-count"
(value-test :path "2017-01-01-test.md"
:value-fn #(meta= % :word-count 8)
(value-test :path "2017-01-01-test.html"
:value-fn #(meta= % :word-count 19)
:msg "`word-count` should set `:word-count` metadata"))

(p/gravatar :source-key :email :target-key :gravatar)
(testing "gravatar"
(value-test :path "2017-01-01-test.md"
(value-test :path "2017-01-01-test.html"
:value-fn
#(meta= % :gravatar "http://www.gravatar.com/avatar/a1a361f6c96acb1e31ad4b3bbf7aa444")
:msg "`gravatar` should set `:gravatar` metadata"))

(p/build-date)
(testing "build-date"
(key-test :path "2017-01-01-test.md"
(key-test :path "2017-01-01-test.html"
:key :date-build
:msg "`build-date` should set `:date-build` metadata"))

(p/slug)
(testing "slug"
(value-test :path "2017-01-01-test.md"
(value-test :path "2017-01-01-test.html"
:value-fn #(meta= % :slug "test")
:msg "`:slug` should set `:slug` metadata"))
:msg "`slug` should set `:slug` metadata"))

(p/permalink)
(testing "permalink"
(value-test :path "2017-01-01-test.md"
(value-test :path "2017-01-01-test.html"
:value-fn #(meta= % :permalink "/test/index.html")
:msg "`:permalink` should set `:permalink` metadata"))
:msg "`permalink` should set `:permalink` metadata"))

(p/canonical-url)
(testing "canonical-url"
(value-test :path "2017-01-01-test.md"
(value-test :path "2017-01-01-test.html"
:value-fn #(meta= % :canonical-url "http://example.com/test/index.html")
:msg "`:canonical-url` should set `:canonical-url` metadata"))
:msg "`canonical-url` should set `:canonical-url` metadata"))

(p/sitemap)
(testing "sitemap"
Expand All @@ -192,14 +214,13 @@ This --- be ___markdown___.")
(add-txt-file :path "test.js" :content js-content)
(p/inject-scripts :scripts #{"test.js"})
(testing "inject-scripts"
(boot/with-pass-thru fileset
(is (.contains (slurp (boot/tmp-file (boot/tmp-get fileset "public/test/index.html")))
(str "<script>" js-content "</script>"))
"`inject-scripts` should alter the contents of a file")))
(content-test :path "public/test/index.html"
:content (str "<script>" js-content "</script>")
:msg "`inject-scripts` should alter the contents of a file"))

(p/draft)
(testing "draft"
(file-exists? :path "2017-01-01-test.md"
(file-exists? :path "2017-01-01-test.html"
:negate? true
:msg "`draft` should remove files"))))

Expand All @@ -212,8 +233,11 @@ This --- be ___markdown___.")
(p/markdown :meta {:markdown-set :metadata} :options {:extensions {:smarts true}})
(testing "markdown"
(value-test :path "test.md"
:value-fn #(meta= % :content "<h1><a href=\"#hello-there\" name=\"hello-there\"></a>Hello there</h1>\n<p>This &mdash; be <strong><em>markdown</em></strong>.</p>")
:msg "`markdown` should set `:content` metadata on markdown file"))
:value-fn #(meta= % :parsed parsed-md-smarts)
:msg "`markdown` should set `:parsed` metadata on markdown file")
(content-test :path "test.html"
:content parsed-md-smarts
:msg "`markdown` should populate HTML file with parsed content"))

(p/ttr :filterer :markdown-set)
(testing "ttr"
Expand All @@ -224,7 +248,7 @@ This --- be ___markdown___.")
(p/word-count :filterer :markdown-set)
(testing "word-count"
(value-test :path "test.md"
:value-fn #(meta= % :word-count 8)
:value-fn #(meta= % :word-count 19)
:msg "`word-count` should set `:word-count` metadata"))

(p/gravatar :source-key :email :target-key :gravatar :filterer :markdown-set)
Expand Down Expand Up @@ -298,10 +322,43 @@ This --- be ___markdown___.")
(p/inject-scripts :scripts #{"test.js"} :filter #{#"foo"})
(p/inject-scripts :scripts #{"test.js"} :remove #{#"baz"})
(testing "inject-scripts"
(boot/with-pass-thru fileset
(is (.contains (slurp (boot/tmp-file (boot/tmp-get fileset "bar/foo.html")))
(str "<script>" js-content "</script>"))
"`inject-scripts` should alter the contents of an included file")
(is (not (.contains (slurp (boot/tmp-file (boot/tmp-get fileset "baz.html")))
(str "<script>" js-content "</script>")))
"`inject-scripts` should not alter the contents of a removed file")))))
(content-test :path "bar/foo.html"
:content (str "<script>" js-content "</script>")
:msg "`inject-scripts` should alter the contents of a file")
(content-test :path "baz.html"
:content (str "<script>" js-content "</script>")
:negate? true
:msg "`inject-scripts` should not alter the contents of a removed file"))))

(deftesttask content-tests []
(comp (testing "Collection works without input files" ;; #77
(p/collection :renderer 'io.perun-test/render))

(add-txt-file :path "test.md" :content md-content)
(p/markdown) ;; render once

(add-txt-file :path "test.md" :content (str/replace md-content #"Hello" "Salutations"))
(p/markdown)
(testing "detecting content changes"
(content-test :path "test.html" :content "Salutations"))

(add-txt-file :path "test.md" :content (str/replace md-content #"draft: true" "draft: false"))
(p/markdown)
(testing "detecting metadata changes"
(value-test :path "test.html" :value-fn #(meta= % :draft false)))

(add-txt-file :path "test.md" :content (str/replace md-content #"draft: true" "draft: true\nfoo: bar"))
(p/markdown)
(testing "detecting metadata additions"
(value-test :path "test.html" :value-fn #(meta= % :foo "bar")))

(add-txt-file :path "test.md" :content md-content)
(p/markdown)
(testing "detecting metadata deletions"
(value-test :path "test.html" :value-fn #(meta= % :foo nil)))

(add-txt-file :path "test2.md" :content md-content)
(p/markdown)
(testing "detecting new files"
(content-test :path "test2.html" :content parsed-md-basic)
(value-test :path "test2.md" :value-fn #(meta= % :parsed parsed-md-basic)))))