-
-
Save martinklepsch/b534f6be88cd48bf9aad4076dc2ccbfa to your computer and use it in GitHub Desktop.
This file contains hidden or 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
| #!/usr/bin/env bb | |
| (require '[babashka.cli :as cli] | |
| '[babashka.fs :as fs] | |
| '[clojure.string :as str] | |
| '[clj-yaml.core :as yaml]) | |
| (def cli-opts | |
| {:spec {:files {:desc "Individual markdown files to process" | |
| :coerce []} | |
| :pattern {:desc "Regex pattern to match markdown files (e.g. \"posts/*.md\")" | |
| :alias :p} | |
| :dry-run {:desc "Print what would be changed without making changes" | |
| :coerce :boolean} | |
| :verbose {:desc "Print additional information during processing" | |
| :coerce :boolean}}}) | |
| (defn extract-frontmatter | |
| "Extracts YAML frontmatter from markdown content. | |
| Returns [frontmatter remaining-content] or nil if no frontmatter found." | |
| [content] | |
| (when (str/starts-with? content "---\n") | |
| (when-let [end-idx (str/index-of content "\n---\n" 4)] | |
| (let [frontmatter (subs content 4 end-idx) | |
| remaining (subs content (+ end-idx 5))] | |
| [frontmatter remaining])))) | |
| (defn update-frontmatter | |
| "Updates the frontmatter by adding type: post if not present" | |
| [markdown-str] | |
| (if-let [[frontmatter content] (extract-frontmatter markdown-str)] | |
| (let [data (yaml/parse-string frontmatter) | |
| updated-data (cond-> data | |
| (not (:type data)) (assoc :type "post")) | |
| new-frontmatter (yaml/generate-string updated-data :dumper-options {:flow-style :block})] | |
| (str "---\n" new-frontmatter "---\n" content)) | |
| markdown-str)) | |
| (defn process-file | |
| "Process a single markdown file, updating its frontmatter" | |
| [file {:keys [dry-run verbose]}] | |
| (let [content (slurp file) | |
| updated-content (update-frontmatter content)] | |
| (when verbose | |
| (println "π Processing" (str file))) | |
| (if (= content updated-content) | |
| (when verbose | |
| (println "βοΈ No changes needed for" (str file))) | |
| (do | |
| (when verbose | |
| (println "π Updating frontmatter in" (str file))) | |
| (when-not dry-run | |
| (spit file updated-content)))))) | |
| (defn process-files | |
| "Process multiple markdown files based on CLI options" | |
| [{:keys [files pattern] :as opts}] | |
| (let [pattern-files (when pattern | |
| (->> (fs/glob "." pattern) | |
| (map fs/file) | |
| (filter #(str/ends-with? (str %) ".md")))) | |
| all-files (concat (map fs/file files) pattern-files)] | |
| (if (seq all-files) | |
| (do | |
| (when (:verbose opts) | |
| (println "π Found" (count all-files) "files to process")) | |
| (doseq [file all-files] | |
| (process-file file opts)) | |
| (println "β¨ Processing complete!")) | |
| (println "β οΈ No markdown files found to process")))) | |
| (defn -main [& args] | |
| (let [opts (cli/parse-opts args cli-opts)] | |
| (if (:help opts) | |
| (println (cli/format-opts cli-opts)) | |
| (process-files opts)))) | |
| (when (= *file* (System/getProperty "babashka.file")) | |
| (apply -main *command-line-args*)) |
Author
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Another example that downloads files based on frontmatter, straight out of Claude: