diff --git a/README.md b/README.md index 32fbc56..7c32ad2 100644 --- a/README.md +++ b/README.md @@ -45,12 +45,20 @@ Add `[clojure-ini "0.0.2"]` as a dependency to your `project.clj`. server=192.0.2.62 port=143 file = payroll.dat + + [access-allowed] + users[]=mike + users[]=nike + users[]=joe + users[]=tom + REPL session: > (use 'clojure-ini.core) > (read-ini "conf.ini" :keywordize? true) - {:database {:file "payroll.dat" + {:access-allowed {:users ("tom" "joe" "nika" "mike")} + :database {:file "payroll.dat" :port "143" :server "192.0.2.62"} :organization "Acme Widgets Inc." diff --git a/src/clojure_ini/core.clj b/src/clojure_ini/core.clj index 920cfa2..8237d81 100644 --- a/src/clojure_ini/core.clj +++ b/src/clojure_ini/core.clj @@ -2,6 +2,21 @@ (:require [clojure.string :as s] [clojure.java.io :as io])) + +(defn- is-list? [kword] + (let [rkw (reverse (name kword))] + (and (= (first rkw) \]) (= (second rkw) \[)))) + + +(defn- strip-braces [kw] + (let [kword (name kw)] + (let [n (.indexOf kword "[")] + (if (not (neg? n)) + (if (keyword? kw) + (keyword (subs kword 0 n)) + (subs kword 0 n)))))) + + (defn- parse-line [s kw trim] (if (= (first s) \[) (-> s (subs 1 (.indexOf s "]")) trim kw) @@ -11,6 +26,7 @@ [(-> s (subs 0 n) trim kw) (-> s (subs (inc n)) trim)])))) + (defn- strip-comment [s chr allow-anywhere?] (let [n (.indexOf s (int chr))] (if (and (not (neg? n)) @@ -19,6 +35,7 @@ (subs s 0 n) s))) + (defn- mapify [coll] (loop [xs coll m {} key nil] (if-let [x (first xs)] @@ -27,14 +44,19 @@ (recur (rest xs) (assoc m (first x) (second x)) key) - (recur (rest xs) - (assoc-in m [key (first x)] (second x)) - key)) + (if (is-list? (first x)) + (recur (rest xs) + (update-in m [key (strip-braces (first x))] conj (second x)) + key) + (recur (rest xs) + (assoc-in m [key (first x)] (second x)) + key))) (recur (rest xs) (assoc m x {}) x)) m))) + (defn read-ini "Read an .ini-file into a Clojure map. @@ -63,3 +85,4 @@ (remove (fn [s] (every? #(Character/isWhitespace %) s))) (map #(parse-line % kw trim)) mapify)))) +