Created
July 26, 2020 06:40
-
-
Save rickerbh/4bcc3b3243e0f271b9ca3c8e16028948 to your computer and use it in GitHub Desktop.
Babashka script to port posts from jekyll/octopress format to cryogen
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
(require '[clojure.java.io :as io] | |
'[clojure.string :as string] | |
'[clojure.tools.cli :refer [parse-opts]]) | |
(def cli-options | |
[["-o" "--out DIR" "Output directory" | |
:default "out"] | |
["-s" "--source SOURCE" "Source directory" | |
:default "source/_posts"] | |
["-h" "--help"]]) | |
(def frontmatter-delimiter "---") | |
(defn files-in-dir | |
"Returns a list of all files in a given path" | |
[path] | |
(->> (io/file path) | |
file-seq | |
(filter #(.isFile %)))) | |
(defn output-key? | |
"Checks the given key against a list of known keys. Returns true if the key is in the list." | |
[key] | |
(let [good-keys #{:title :date :author :tags :toc :toc-class :draft? :klipse :layout :description}] | |
(contains? good-keys key))) | |
(defn normalise-frontmatter-key-pair | |
"Normalise the key/value pairs from frontmatter. | |
- Converts keys to keywords | |
- Replaces :status with :draft? | |
- If key is :layout, make value a keyword | |
- Have draft? status as a boolean, driven based on \"publish\" being true | |
- Strip single quotes from any :date keys value" | |
[key value] | |
(let [normal-key (let [keyword-key (-> key | |
(string/replace #":$" "") | |
keyword)] | |
(cond | |
(= :status keyword-key) :draft? | |
:else keyword-key)) | |
normal-value (cond | |
(= :layout normal-key) (keyword value) | |
(= :draft? normal-key) (get {"publish" false} value true) | |
(= :date normal-key) (string/replace value #"'" "") | |
:else value)] | |
[normal-key | |
normal-value])) | |
(defn normalise-filename | |
"Function to change the name of the output files. | |
- Rename from .markdown to .md" | |
[name] | |
(-> name | |
(string/replace #"markdown$" "md"))) | |
(defn convert-file | |
[path] | |
(with-open [reader (io/reader path)] | |
(reduce (fn [acc line] | |
(if (:in-frontmatter? acc) | |
(if (= frontmatter-delimiter line) | |
(-> acc | |
(assoc :output (conj (:output acc) (:frontmatter acc) "\n")) | |
(assoc :in-frontmatter? false)) | |
(let [components (string/split line #"\s+") | |
[key value] (normalise-frontmatter-key-pair (first components) | |
(string/join " " (rest components)))] | |
(if (output-key? key) | |
(-> acc | |
(assoc :frontmatter (merge (:frontmatter acc) {key value}))) | |
acc))) | |
(if (= frontmatter-delimiter line) | |
(-> acc | |
(assoc :in-frontmatter? true)) | |
(-> acc | |
(assoc :output (conj (:output acc) line "\n")))))) | |
{:output [] | |
:frontmatter {} | |
:in-frontmatter? false} (line-seq reader)))) | |
(let [options (:options (parse-opts *command-line-args* cli-options)) | |
source-dir (:source options) | |
output-dir (:out options) | |
files (files-in-dir source-dir)] | |
(run! (fn [file] | |
(let [content (apply str (:output (convert-file file))) | |
name (.getName file) | |
output-name (str output-dir "/" (normalise-filename name))] | |
(io/make-parents output-name) | |
(spit output-name content))) | |
files)) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
It's a bit of a mess, but for a once-use I wasn't going to refactor it too much.