|
(ns briefcase.files |
|
(require [stasis.core :as stasis] |
|
[clygments.core :as pygments] |
|
[cheshire.core :refer :all] |
|
[briefcase.content.utils :as util] |
|
[net.cgrand.enlive-html :as html] |
|
[clj-yaml.core :as yaml])) |
|
|
|
(def articles |
|
(stasis/slurp-directory "resources/content/articles" #".*\.md$")) |
|
|
|
(defn has-gists [[path content]] |
|
(not (nil? (re-find #"://gist\.github\.com/" content)))) |
|
|
|
(defn load-gist [path] |
|
[path (gist-content path)]) |
|
|
|
(defn extract-gists [content] |
|
(->> content |
|
(re-seq #"[\"|\'](http[s]?://gist\.github\.com/\d*\.js(\?[^\'\"]*)?)[\"|\']") |
|
(map #(nth % 1)) |
|
(map load-gist) |
|
(into {}))) |
|
|
|
(defn gist-content |
|
"given a path to a gists embed script this function will grab the contents of |
|
the gist. If a file name is also specified for a multi file gist it will |
|
extract the correct one" |
|
[path] |
|
(let [id (gist-id path) |
|
data (fetch-gist id) |
|
files (:files data) |
|
filename (last (re-find #"\?file=([^&]*)" path))] |
|
(:content (if (nil? filename) |
|
(first (vals files)) |
|
((keyword filename) files))))) |
|
|
|
(def gist-source |
|
(let [gisted (filter has-gists articles)] |
|
(zipmap (keys gisted) |
|
(map extract-gists (vals gisted))))) |
|
|
|
(spit "data.edn" (with-out-str (clojure.pprint/pprint gist-source))) |
|
|
|
(def gist-content (load-string (slurp "data.edn"))) |
|
|
|
(def gist-content-types (load-string (slurp "types.edn"))) |
|
|
|
|
|
(spit "merged.edn" (with-out-str (clojure.pprint/pprint (into {} |
|
(map (fn [[path gists]] |
|
(let [types (get gist-content-types path)] |
|
[path (merge-with (fn [a b] { :content a |
|
:type (get pygments-shortnames b "text") }) |
|
gists types)])) gist-content)) )) ) |
|
|
|
(def gist-data (load-string (slurp "merged.edn"))) |
|
|
|
(->> gist-content-types |
|
(vals) |
|
(map vals) |
|
(apply concat) |
|
(distinct)) |
|
|
|
(def pygments-shortnames |
|
{ "C#" "csharp" |
|
"CSS" "css" |
|
"XML" "xml" |
|
"JavaScript" "javascript" |
|
"HTML" "html" |
|
"ASP" "html" |
|
"PostScript" "powershell" ; this was supposed to be powershell not postscript |
|
"PowerShell" "powershell" |
|
"Ruby" "ruby" |
|
"Cucumber" "cucumber" |
|
"SQL" "sql" }) |
|
|
|
(def gist-types |
|
(let [gisted (filter has-gists articles)] |
|
(zipmap (keys gisted) |
|
(map extract-gist-types (vals gisted))))) |
|
|
|
(defn gist-content-type |
|
[path] |
|
(let [id (gist-id path) |
|
data (fetch-gist id) |
|
files (:files data) |
|
filename (last (re-find #"\?file=([^&]*)" path))] |
|
(:language (if (nil? filename) |
|
(first (vals files)) |
|
((keyword filename) files))))) |
|
|
|
(defn load-gist-type [path] |
|
[path (gist-content-type path)]) |
|
|
|
(defn extract-gist-types [content] |
|
(->> content |
|
(re-seq #"[\"|\'](http[s]?://gist\.github\.com/\d*\.js(\?[^\'\"]*)?)[\"|\']") |
|
(map #(nth % 1)) |
|
(map load-gist-type) |
|
(into {}))) |
|
|
|
(spit "types.edn" (with-out-str (clojure.pprint/pprint gist-types))) |
|
; |
|
(= loaded gist-source) ; proves that original data is the same as the slurped data |
|
|
|
(defn gist-id [path] |
|
(last (re-find #"/(\d*)\.js" path))) |
|
|
|
(defn get-one [path] |
|
(get gist-source path)) |
|
|
|
(get-one "/2011-06-21-microorms-for-dotnet-inserts-updates-deletes.md") |
|
|
|
|
|
(defn fetch-url[address] |
|
(with-open [stream (.openStream (java.net.URL. address))] |
|
(let [reader (java.io.InputStreamReader. stream) |
|
buf (java.io.BufferedReader. reader)] |
|
(apply str (line-seq buf))))) |
|
|
|
(defn fetch-json [address] |
|
(-> address |
|
(fetch-url) |
|
(parse-string true))) |
|
|
|
|
|
(defn fetch-gist [gist-id] |
|
(fetch-json (str "https://api.github.com/gists/" gist-id "?client_id=" client-id "&client_secret=" client-secret))) |
|
|
|
(defn highlight-codes [gist-map] |
|
(let [gists (vals gist-map)] |
|
(zipmap (keys gist-map) |
|
(map #(pygments/highlight (:content %) |
|
(:type %) |
|
:html) gists)))) |
|
|
|
|
|
(defn wrap-codes [gist-map] |
|
(let [gists (vals gist-map)] |
|
(zipmap (keys gist-map) |
|
(map #(str "<pre><code>" (:content %) "</code></pre>") gists)))) |
|
|
|
(def highlighted-gist-code (zipmap (keys gist-data) (map highlight-codes (vals gist-data)))) |
|
|
|
|
|
(spit "formatted.edn" (with-out-str (clojure.pprint/pprint highlighted-gist-code))) |
|
|
|
(def snippets (read-string (slurp "wrapped.edn"))) |
|
|
|
(defn wrap-block [snippet] |
|
(html/sniptest "<div></div>" [:div] (html/substitute (html/at (html/html-resource (java.io.StringReader. snippet)) |
|
[#{:html :body}] |
|
html/unwrap |
|
[:div.highlight :pre] |
|
(html/do-> |
|
(html/wrap :code) |
|
(html/wrap :pre)) |
|
[:div.highlight :pre :code :pre] |
|
html/unwrap)))) |
|
|
|
(spit "wrapped.edn" (with-out-str (clojure.pprint/pprint (zipmap (keys snippets) |
|
(map wrap-blocks (vals snippets)))))) |
|
|
|
(defn wrap-blocks [blocks] |
|
(into {} (map (fn [[path code]] [path (wrap-block code)]) blocks))) |
|
|
|
|
|
|
|
|
|
(defn replace-gist [source [path snippet]] |
|
(html/sniptest source |
|
[[:script (html/attr-starts :src path)]] |
|
(html/substitute (html/at (html/html-resource (java.io.StringReader. snippet)) |
|
[#{:html :body}] html/unwrap)))) |
|
|
|
|
|
(defn replace-gists [content snippets] |
|
(let [un-no-script (html/sniptest content [:noscript] (fn [_] ""))] |
|
(reduce replace-gist un-no-script snippets))) |
|
|
|
(defn transmogrify-article |
|
"take the original gisted article and replaces its gists with real code. it |
|
expects the original content (yep yaml frontmatter as well) and the map of |
|
gists generated including content, url and type" |
|
[original snippets] |
|
(let [fm (util/frontmatter original) |
|
bd (util/content-body original)] |
|
(println (:title fm)) |
|
(str "---\n" |
|
(yaml/generate-string fm) |
|
"\n---\n" |
|
(replace-gists bd snippets)))) |
|
|
|
(defn run! [] |
|
(doall |
|
(for [[path content] articles |
|
:when (contains? snippets path) |
|
:let [snippets (get snippets path) |
|
updated (transmogrify-article content snippets)]] |
|
(spit (str "./temp" path) updated)))) |
|
|
|
(defn test! [] |
|
(into {} (for [[path content] articles |
|
:when (contains? snippets path) |
|
:let [snippets (get snippets path) |
|
updated (transmogrify-article content snippets)]] |
|
[path updated]))) |
|
|
|
(first (test!)) |
|
|
|
|
|
(get (test!) "/2009-04-15-updatepanels-alternatives.md") |
|
|
|
(run!) |
|
|
|
(keys (filter has-gists articles)) |
|
|
|
|
|
(html/at (html/html-resource (java.io.StringReader. "<div class='highlight'>asdasdas</div>")) [#{:html :body}] html/unwrap) |
|
|
|
(html/sniptest "<a></a><script src='test.html'></script><h1>pants</h1>" |
|
[[:script (html/attr-starts :src "test.html")]] |
|
(html/substitute (html/at (html/html-resource (java.io.StringReader. "<div class='highlight'><pre><span>1</span><span>2</span></pre></div>")) |
|
[#{:html :body}] |
|
html/unwrap |
|
[:div.highlight :pre] |
|
(html/do-> |
|
(html/wrap :code) |
|
(html/wrap :pre)) |
|
[:div.highlight :pre :code :pre] |
|
html/unwrap))) |
|
|