diff --git a/project.clj b/project.clj index 86806dd..9f20be0 100644 --- a/project.clj +++ b/project.clj @@ -30,7 +30,8 @@ [ring/ring-anti-forgery "1.1.0"] [ring-server "0.4.0"] [selmer "1.11.0"] - [com.stuartsierra/component "0.3.2"]] + [com.stuartsierra/component "0.3.2"] + [prismatic/schema "1.1.9"]] :repl-options {:init-ns smeagol.repl} diff --git a/src/smeagol/include.clj b/src/smeagol/include.clj index adc361f..80d9640 100644 --- a/src/smeagol/include.clj +++ b/src/smeagol/include.clj @@ -1,11 +1,26 @@ (ns smeagol.include (:require - [com.stuartsierra.component :as component])) + [schema.core :as s] + [com.stuartsierra.component :as component] + [smeagol.include.resolver :as resolver])) -(defrecord Resolver [resolver-fn]) +(s/defrecord Includer + [resolver]) -(defn new-resolver [resolver-fn] - (map->Resolver {:resolver-fn resolver-fn})) +(defprotocol IncludeMd + (expand-include-md + [includer md-src] + "return a markfown file content for given uri.")) -(defn resolve-include [resolver uri] - (apply (:resolver-fn resolver) [uri])) +(extend-type Includer + IncludeMd + (expand-include-md [includer md-src] + ;parse md-src + ;resolve found includes + ;indent & integrate + md-src)) + +(s/defn + new-includer + [] + (map->Includer {})) diff --git a/src/smeagol/include/resolver.clj b/src/smeagol/include/resolver.clj new file mode 100644 index 0000000..cca0934 --- /dev/null +++ b/src/smeagol/include/resolver.clj @@ -0,0 +1,38 @@ +(ns smeagol.include.resolver + (:require + [schema.core :as s] + [com.stuartsierra.component :as component])) + +(s/defrecord Resolver + [type :- s/Keyword]) + +;As schema does'nt support s/defprotocol we use the dispatcher for annotation & validation. +(s/defn dispatch-by-resolver-type :- s/Keyword + "Dispatcher for different resolver implementations." + [resolver :- Resolver + uri :- s/Str] + (:type resolver)) + +(defmulti do-resolve-md + "Multimethod return a markfown file content for given uri." + dispatch-by-resolver-type) +(s/defmethod do-resolve-md :default + [resolver :- Resolver + uri :- s/Str] + (throw (Exception. (str "No implementation for " resolver)))) + +(defprotocol ResolveMd + (resolve-md + [resolver uri] + "return a markfown file content for given uru.")) + +(extend-type Resolver + ResolveMd + (resolve-md [resolver uri] + (s/validate s/Str uri) + (s/validate s/Str (do-resolve-md resolver uri)))) + +(s/defn + new-resolver + [type :- s/Keyword] + (map->Resolver {:type type})) diff --git a/test/smeagol/test/include.clj b/test/smeagol/test/include.clj index 143eb61..749482b 100644 --- a/test/smeagol/test/include.clj +++ b/test/smeagol/test/include.clj @@ -1,16 +1,32 @@ (ns smeagol.test.include (:require [clojure.test :refer :all] + [schema.core :as s] [com.stuartsierra.component :as component] + [smeagol.include.resolver :as resolver] [smeagol.include :as sut])) -(defn test-include-resolver [uri] +(s/defmethod resolver/do-resolve-md :test-mock + [resolver + uri :- s/Str] (cond (= uri "./simple.md") "Simple content.")) (def system-under-test (component/system-map - :resolver (sut/new-resolver test-include-resolver))) + :resolver (resolver/new-resolver :test-mock) + :includer (component/using + (sut/new-includer) + {:resolver :resolver}))) -(deftest test-local-links +(deftest test-expand-include-md (testing "Rewriting of local links" - (is (= "Simple content." (sut/resolve-include (:resolver system-under-test) "./simple.md"))))) + (is + (= "# Heading" + (sut/expand-include-md (:includer system-under-test) "# Heading"))) + (is + (= "# Heading 1 + Simple content." + (sut/expand-include-md + (:includer system-under-test) + "# Heading1 +#[](.simple.md)"))))) diff --git a/test/smeagol/test/include/resolver.clj b/test/smeagol/test/include/resolver.clj new file mode 100644 index 0000000..fd080d9 --- /dev/null +++ b/test/smeagol/test/include/resolver.clj @@ -0,0 +1,8 @@ +(ns smeagol.test.include.resolver + (:require [clojure.test :refer :all] + [smeagol.include.resolver :as sut])) + +(deftest test-local-links + (testing "Rewriting of local links" + (is (thrown? Exception + (sut/resolve-md (sut/new-resolver (:default)) "./some-uri.md")))))