From 6be21214b0267c18d203bef0c44768804e25bb0b Mon Sep 17 00:00:00 2001 From: jem Date: Tue, 15 May 2018 18:50:54 +0200 Subject: [PATCH 01/17] start with some thinking about the problem ... --- doc/include.md | 14 ++++++++++++++ 1 file changed, 14 insertions(+) create mode 100644 doc/include.md diff --git a/doc/include.md b/doc/include.md new file mode 100644 index 0000000..8614fc9 --- /dev/null +++ b/doc/include.md @@ -0,0 +1,14 @@ +# Include Feature +## Requirements +The user can include page title, abstract or the whole content in a given page. Headings and enumerations can be indented by a given include-level. + +## Thoughts & Questions +* Which include syntax should be used? + * page include can be definde alongsite of image includes - sth. like `#[indent-level](relative or absolute url)` +* Which kind of urls should we accept for page includes? + * relative local urls (we will need some care to prohibit directory traversal ...) + * absolute github / gitlab / gitblit urls without authentication. +* Which metadata can be used for title / abstract ? + * MultiMarcdown-Metadata is supported by clj-markdown :-) +* How can we test page includes? + * we will need a content resolver component for testing and at least one for production resolving. From 464e9af7d63a89c2625fee34bf3cc5cacc541df1 Mon Sep 17 00:00:00 2001 From: jem Date: Tue, 15 May 2018 19:31:24 +0200 Subject: [PATCH 02/17] use dependency injection in order to make include resolving testable --- project.clj | 3 ++- src/smeagol/include.clj | 11 +++++++++++ test/smeagol/test/include.clj | 16 ++++++++++++++++ 3 files changed, 29 insertions(+), 1 deletion(-) create mode 100644 src/smeagol/include.clj create mode 100644 test/smeagol/test/include.clj diff --git a/project.clj b/project.clj index 38c96f5..86806dd 100644 --- a/project.clj +++ b/project.clj @@ -29,7 +29,8 @@ [prone "1.1.4"] [ring/ring-anti-forgery "1.1.0"] [ring-server "0.4.0"] - [selmer "1.11.0"]] + [selmer "1.11.0"] + [com.stuartsierra/component "0.3.2"]] :repl-options {:init-ns smeagol.repl} diff --git a/src/smeagol/include.clj b/src/smeagol/include.clj new file mode 100644 index 0000000..adc361f --- /dev/null +++ b/src/smeagol/include.clj @@ -0,0 +1,11 @@ +(ns smeagol.include + (:require + [com.stuartsierra.component :as component])) + +(defrecord Resolver [resolver-fn]) + +(defn new-resolver [resolver-fn] + (map->Resolver {:resolver-fn resolver-fn})) + +(defn resolve-include [resolver uri] + (apply (:resolver-fn resolver) [uri])) diff --git a/test/smeagol/test/include.clj b/test/smeagol/test/include.clj new file mode 100644 index 0000000..143eb61 --- /dev/null +++ b/test/smeagol/test/include.clj @@ -0,0 +1,16 @@ +(ns smeagol.test.include + (:require [clojure.test :refer :all] + [com.stuartsierra.component :as component] + [smeagol.include :as sut])) + +(defn test-include-resolver [uri] + (cond + (= uri "./simple.md") "Simple content.")) + +(def system-under-test + (component/system-map + :resolver (sut/new-resolver test-include-resolver))) + +(deftest test-local-links + (testing "Rewriting of local links" + (is (= "Simple content." (sut/resolve-include (:resolver system-under-test) "./simple.md"))))) From 9607657cc12558f3ba1d49a26ad15fb0bc5d4699 Mon Sep 17 00:00:00 2001 From: jem Date: Wed, 16 May 2018 18:41:54 +0200 Subject: [PATCH 03/17] added schema & use separated resolver & includer component. --- project.clj | 3 +- src/smeagol/include.clj | 27 ++++++++++++++---- src/smeagol/include/resolver.clj | 38 ++++++++++++++++++++++++++ test/smeagol/test/include.clj | 24 +++++++++++++--- test/smeagol/test/include/resolver.clj | 8 ++++++ 5 files changed, 89 insertions(+), 11 deletions(-) create mode 100644 src/smeagol/include/resolver.clj create mode 100644 test/smeagol/test/include/resolver.clj 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"))))) From 6918ba27e8198cb069b5212b0d252469f436285b Mon Sep 17 00:00:00 2001 From: jem Date: Thu, 17 May 2018 09:08:09 +0200 Subject: [PATCH 04/17] implemented simple parsing --- doc/include.md | 3 ++- src/smeagol/include.clj | 16 +++++++++++ test/smeagol/test/include.clj | 50 ++++++++++++++++++++++++++++++++--- 3 files changed, 64 insertions(+), 5 deletions(-) diff --git a/doc/include.md b/doc/include.md index 8614fc9..f8b115c 100644 --- a/doc/include.md +++ b/doc/include.md @@ -4,7 +4,8 @@ The user can include page title, abstract or the whole content in a given page. ## Thoughts & Questions * Which include syntax should be used? - * page include can be definde alongsite of image includes - sth. like `#[indent-level](relative or absolute url)` + * page include can be definde alongsite of image includes - sth. like + `&[:indent-heading s/Num :indent-list s/Num](relative or absolute url s/Str)` * Which kind of urls should we accept for page includes? * relative local urls (we will need some care to prohibit directory traversal ...) * absolute github / gitlab / gitblit urls without authentication. diff --git a/src/smeagol/include.clj b/src/smeagol/include.clj index 80d9640..6052ff6 100644 --- a/src/smeagol/include.clj +++ b/src/smeagol/include.clj @@ -24,3 +24,19 @@ new-includer [] (map->Includer {})) + +(def IncludeLink + {:uri s/Str + :indent-heading s/Num + :indent-list s/Num}) + +(s/defn + parse-include-md :- [IncludeLink] + [md-src :- s/Str] + (vec + (map + (fn [parse-element] + {:uri (nth parse-element 5) + :indent-heading 0 + :indent-list 0}) + (re-seq #"&\[(:indent-heading (d*))?w*(:indent-list (d*))?\]\((.*)\)" md-src)))) diff --git a/test/smeagol/test/include.clj b/test/smeagol/test/include.clj index 749482b..99ee31d 100644 --- a/test/smeagol/test/include.clj +++ b/test/smeagol/test/include.clj @@ -5,6 +5,49 @@ [smeagol.include.resolver :as resolver] [smeagol.include :as sut])) +(def include-simple + "# Heading1 +&[](./simple.md)") + +(def include-surounding-simple + "# Heading1 +Some surounding &[](./simple.md) text") + +(def include-heading-0 + "# Heading1 +&[:indent-heading 0](./with-heading.md)") + +(def include-heading-list-1 + "# Heading1 +&[:indent-heading 1 :indent-list 1](./with-heading-and-list.md)") + +(def include-heading-list-0 + "# Heading1 +&[:indent-heading 0 :indent-list 0](./with-heading-and-list.md)") + +(def include-invalid-indent + "# Heading1 +&[ invalid input should default to indent 0 ](./simple.md)") + +(def include-spaced-indent + "# Heading1 +&[ :indent-heading 0 :indent-list 0 ](./with-heading-and-list.md)") + + +(deftest test-parse-include-md + (testing "parse include links" + (is + (= [] + (sut/parse-include-md "# Heading"))) + (is + (= [{:uri "./simple.md", :indent-heading 0, :indent-list 0}] + (sut/parse-include-md + include-simple))) + (is + (= [{:uri "./simple.md", :indent-heading 1, :indent-list 1}] + (sut/parse-include-md + include-heading-list-1))))) + (s/defmethod resolver/do-resolve-md :test-mock [resolver uri :- s/Str] @@ -19,14 +62,13 @@ {:resolver :resolver}))) (deftest test-expand-include-md - (testing "Rewriting of local links" + (testing "The whole integration of include" (is (= "# Heading" (sut/expand-include-md (:includer system-under-test) "# Heading"))) (is (= "# Heading 1 - Simple content." +Simple content." (sut/expand-include-md (:includer system-under-test) - "# Heading1 -#[](.simple.md)"))))) + include-simple))))) From 4025b1e29caf8bb7d1146503ee8b59941d981cb0 Mon Sep 17 00:00:00 2001 From: jem Date: Fri, 18 May 2018 12:05:13 +0200 Subject: [PATCH 05/17] include link parsing now works --- src/smeagol/include.clj | 32 ++++++++++++++++++++++++++++---- test/smeagol/test/include.clj | 28 ++++++++++++++++++++++++---- 2 files changed, 52 insertions(+), 8 deletions(-) diff --git a/src/smeagol/include.clj b/src/smeagol/include.clj index 6052ff6..74e8cdb 100644 --- a/src/smeagol/include.clj +++ b/src/smeagol/include.clj @@ -30,13 +30,37 @@ :indent-heading s/Num :indent-list s/Num}) +(s/defn + convert-indent-to-int :- s/Num + [indents :- [s/Str]] + (if (some? indents) + (Integer/valueOf (nth indents 2)) + 0)) + +(s/defn + parse-indent-list + [md-src :- s/Str] + (re-matches #".*(:indent-list (\d)).*" md-src)) + +(s/defn + parse-indent-heading + [md-src :- s/Str] + (re-matches #".*(:indent-heading (\d)).*" md-src)) + +(s/defn + parse-include-link + [md-src :- s/Str] + (re-seq #".*&\[\w*(.*)\w*\]\((.*)\).*" md-src)) + (s/defn parse-include-md :- [IncludeLink] [md-src :- s/Str] (vec (map (fn [parse-element] - {:uri (nth parse-element 5) - :indent-heading 0 - :indent-list 0}) - (re-seq #"&\[(:indent-heading (d*))?w*(:indent-list (d*))?\]\((.*)\)" md-src)))) + (let [uri (nth parse-element 2) + indents-text (nth parse-element 1)] + {:uri uri + :indent-heading (convert-indent-to-int (parse-indent-heading indents-text)) + :indent-list (convert-indent-to-int (parse-indent-list indents-text))})) + (parse-include-link md-src)))) diff --git a/test/smeagol/test/include.clj b/test/smeagol/test/include.clj index 99ee31d..ae602b2 100644 --- a/test/smeagol/test/include.clj +++ b/test/smeagol/test/include.clj @@ -23,7 +23,7 @@ Some surounding &[](./simple.md) text") (def include-heading-list-0 "# Heading1 -&[:indent-heading 0 :indent-list 0](./with-heading-and-list.md)") +&[:indent-list 0 :indent-heading 0](./with-heading-and-list.md)") (def include-invalid-indent "# Heading1 @@ -31,7 +31,7 @@ Some surounding &[](./simple.md) text") (def include-spaced-indent "# Heading1 -&[ :indent-heading 0 :indent-list 0 ](./with-heading-and-list.md)") +&[ :indent-heading 2 :indent-list 33 ](./with-heading-and-list.md)") (deftest test-parse-include-md @@ -44,9 +44,29 @@ Some surounding &[](./simple.md) text") (sut/parse-include-md include-simple))) (is - (= [{:uri "./simple.md", :indent-heading 1, :indent-list 1}] + (= [{:uri "./simple.md", :indent-heading 0, :indent-list 0}] (sut/parse-include-md - include-heading-list-1))))) + include-surounding-simple))) + (is + (= [{:uri "./with-heading.md", :indent-heading 0, :indent-list 0}] + (sut/parse-include-md + include-heading-0))) + (is + (= [{:uri "./with-heading-and-list.md", :indent-heading 1, :indent-list 1}] + (sut/parse-include-md + include-heading-list-1))) + (is + (= [{:uri "./with-heading-and-list.md", :indent-heading 0, :indent-list 0}] + (sut/parse-include-md + include-heading-list-0))) + (is + (= [{:uri "./simple.md", :indent-heading 0, :indent-list 0}] + (sut/parse-include-md + include-invalid-indent))) + (is + (= [{:uri "./with-heading-and-list.md", :indent-heading 2, :indent-list 0}] + (sut/parse-include-md + include-spaced-indent))))) (s/defmethod resolver/do-resolve-md :test-mock [resolver From 7d479e95b16a9fcca6b1af49f62799c0847be690 Mon Sep 17 00:00:00 2001 From: jem Date: Fri, 18 May 2018 12:09:16 +0200 Subject: [PATCH 06/17] add one more parsing testcase --- test/smeagol/test/include.clj | 18 ++++++++++++++++-- 1 file changed, 16 insertions(+), 2 deletions(-) diff --git a/test/smeagol/test/include.clj b/test/smeagol/test/include.clj index ae602b2..860fcf6 100644 --- a/test/smeagol/test/include.clj +++ b/test/smeagol/test/include.clj @@ -33,6 +33,13 @@ Some surounding &[](./simple.md) text") "# Heading1 &[ :indent-heading 2 :indent-list 33 ](./with-heading-and-list.md)") +(def multi + "# Heading1 +&[ :indent-heading 2 :indent-list 33 ](./with-heading-and-list.md) +some text +&[](./simple.md) +more text.") + (deftest test-parse-include-md (testing "parse include links" @@ -64,9 +71,16 @@ Some surounding &[](./simple.md) text") (sut/parse-include-md include-invalid-indent))) (is - (= [{:uri "./with-heading-and-list.md", :indent-heading 2, :indent-list 0}] + (= [{:uri "./with-heading-and-list.md", :indent-heading 2, :indent-list 3}] (sut/parse-include-md - include-spaced-indent))))) + include-spaced-indent))) + (is + (= [{:uri "./with-heading-and-list.md", + :indent-heading 2, + :indent-list 3} + {:uri "./simple.md", :indent-heading 0, :indent-list 0}] + (sut/parse-include-md + multi))))) (s/defmethod resolver/do-resolve-md :test-mock [resolver From 4a4269d2022945ea64ad612c72a5685d63fe162e Mon Sep 17 00:00:00 2001 From: jem Date: Fri, 18 May 2018 12:32:49 +0200 Subject: [PATCH 07/17] renamed resolver -> resolve --- src/smeagol/include/{resolver.clj => resolve.clj} | 2 +- test/smeagol/test/include/{resolver.clj => resolve.clj} | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) rename src/smeagol/include/{resolver.clj => resolve.clj} (97%) rename test/smeagol/test/include/{resolver.clj => resolve.clj} (71%) diff --git a/src/smeagol/include/resolver.clj b/src/smeagol/include/resolve.clj similarity index 97% rename from src/smeagol/include/resolver.clj rename to src/smeagol/include/resolve.clj index cca0934..13a67ce 100644 --- a/src/smeagol/include/resolver.clj +++ b/src/smeagol/include/resolve.clj @@ -1,4 +1,4 @@ -(ns smeagol.include.resolver +(ns smeagol.include.resolve (:require [schema.core :as s] [com.stuartsierra.component :as component])) diff --git a/test/smeagol/test/include/resolver.clj b/test/smeagol/test/include/resolve.clj similarity index 71% rename from test/smeagol/test/include/resolver.clj rename to test/smeagol/test/include/resolve.clj index fd080d9..4da32ed 100644 --- a/test/smeagol/test/include/resolver.clj +++ b/test/smeagol/test/include/resolve.clj @@ -1,6 +1,6 @@ -(ns smeagol.test.include.resolver +(ns smeagol.test.include.resolve (:require [clojure.test :refer :all] - [smeagol.include.resolver :as sut])) + [smeagol.include.resolve :as sut])) (deftest test-local-links (testing "Rewriting of local links" From 6714dc04bfcb0f1041b8677949abe6abc2e1324e Mon Sep 17 00:00:00 2001 From: jem Date: Fri, 18 May 2018 12:33:07 +0200 Subject: [PATCH 08/17] refactor parse out of include ns --- src/smeagol/include.clj | 51 +++--------------- src/smeagol/include/parse.clj | 43 +++++++++++++++ test/smeagol/test/include.clj | 48 ++--------------- test/smeagol/test/include/parse.clj | 81 +++++++++++++++++++++++++++++ 4 files changed, 133 insertions(+), 90 deletions(-) create mode 100644 src/smeagol/include/parse.clj create mode 100644 test/smeagol/test/include/parse.clj diff --git a/src/smeagol/include.clj b/src/smeagol/include.clj index 74e8cdb..14a97da 100644 --- a/src/smeagol/include.clj +++ b/src/smeagol/include.clj @@ -2,7 +2,8 @@ (:require [schema.core :as s] [com.stuartsierra.component :as component] - [smeagol.include.resolver :as resolver])) + [smeagol.include.parse :as parse] + [smeagol.include.resolve :as resolve])) (s/defrecord Includer [resolver]) @@ -15,52 +16,12 @@ (extend-type Includer IncludeMd (expand-include-md [includer md-src] - ;parse md-src - ;resolve found includes - ;indent & integrate - md-src)) + (let [includes (parse/parse-include-md md-src)] + ;resolve found includes + ;indent & integrate + md-src))) (s/defn new-includer [] (map->Includer {})) - -(def IncludeLink - {:uri s/Str - :indent-heading s/Num - :indent-list s/Num}) - -(s/defn - convert-indent-to-int :- s/Num - [indents :- [s/Str]] - (if (some? indents) - (Integer/valueOf (nth indents 2)) - 0)) - -(s/defn - parse-indent-list - [md-src :- s/Str] - (re-matches #".*(:indent-list (\d)).*" md-src)) - -(s/defn - parse-indent-heading - [md-src :- s/Str] - (re-matches #".*(:indent-heading (\d)).*" md-src)) - -(s/defn - parse-include-link - [md-src :- s/Str] - (re-seq #".*&\[\w*(.*)\w*\]\((.*)\).*" md-src)) - -(s/defn - parse-include-md :- [IncludeLink] - [md-src :- s/Str] - (vec - (map - (fn [parse-element] - (let [uri (nth parse-element 2) - indents-text (nth parse-element 1)] - {:uri uri - :indent-heading (convert-indent-to-int (parse-indent-heading indents-text)) - :indent-list (convert-indent-to-int (parse-indent-list indents-text))})) - (parse-include-link md-src)))) diff --git a/src/smeagol/include/parse.clj b/src/smeagol/include/parse.clj new file mode 100644 index 0000000..0c4dbae --- /dev/null +++ b/src/smeagol/include/parse.clj @@ -0,0 +1,43 @@ +(ns smeagol.include.parse + (:require + [schema.core :as s])) + +(def IncludeLink + {:uri s/Str + :indent-heading s/Num + :indent-list s/Num}) + +(s/defn + convert-indent-to-int :- s/Num + [indents :- [s/Str]] + (if (some? indents) + (Integer/valueOf (nth indents 2)) + 0)) + +(s/defn + parse-indent-list + [md-src :- s/Str] + (re-matches #".*(:indent-list (\d)).*" md-src)) + +(s/defn + parse-indent-heading + [md-src :- s/Str] + (re-matches #".*(:indent-heading (\d)).*" md-src)) + +(s/defn + parse-include-link + [md-src :- s/Str] + (re-seq #".*&\[\w*(.*)\w*\]\((.*)\).*" md-src)) + +(s/defn + parse-include-md :- [IncludeLink] + [md-src :- s/Str] + (vec + (map + (fn [parse-element] + (let [uri (nth parse-element 2) + indents-text (nth parse-element 1)] + {:uri uri + :indent-heading (convert-indent-to-int (parse-indent-heading indents-text)) + :indent-list (convert-indent-to-int (parse-indent-list indents-text))})) + (parse-include-link md-src)))) diff --git a/test/smeagol/test/include.clj b/test/smeagol/test/include.clj index 860fcf6..45219e1 100644 --- a/test/smeagol/test/include.clj +++ b/test/smeagol/test/include.clj @@ -2,7 +2,7 @@ (:require [clojure.test :refer :all] [schema.core :as s] [com.stuartsierra.component :as component] - [smeagol.include.resolver :as resolver] + [smeagol.include.resolve :as resolve] [smeagol.include :as sut])) (def include-simple @@ -40,49 +40,7 @@ some text &[](./simple.md) more text.") - -(deftest test-parse-include-md - (testing "parse include links" - (is - (= [] - (sut/parse-include-md "# Heading"))) - (is - (= [{:uri "./simple.md", :indent-heading 0, :indent-list 0}] - (sut/parse-include-md - include-simple))) - (is - (= [{:uri "./simple.md", :indent-heading 0, :indent-list 0}] - (sut/parse-include-md - include-surounding-simple))) - (is - (= [{:uri "./with-heading.md", :indent-heading 0, :indent-list 0}] - (sut/parse-include-md - include-heading-0))) - (is - (= [{:uri "./with-heading-and-list.md", :indent-heading 1, :indent-list 1}] - (sut/parse-include-md - include-heading-list-1))) - (is - (= [{:uri "./with-heading-and-list.md", :indent-heading 0, :indent-list 0}] - (sut/parse-include-md - include-heading-list-0))) - (is - (= [{:uri "./simple.md", :indent-heading 0, :indent-list 0}] - (sut/parse-include-md - include-invalid-indent))) - (is - (= [{:uri "./with-heading-and-list.md", :indent-heading 2, :indent-list 3}] - (sut/parse-include-md - include-spaced-indent))) - (is - (= [{:uri "./with-heading-and-list.md", - :indent-heading 2, - :indent-list 3} - {:uri "./simple.md", :indent-heading 0, :indent-list 0}] - (sut/parse-include-md - multi))))) - -(s/defmethod resolver/do-resolve-md :test-mock +(s/defmethod resolve/do-resolve-md :test-mock [resolver uri :- s/Str] (cond @@ -90,7 +48,7 @@ more text.") (def system-under-test (component/system-map - :resolver (resolver/new-resolver :test-mock) + :resolver (resolve/new-resolver :test-mock) :includer (component/using (sut/new-includer) {:resolver :resolver}))) diff --git a/test/smeagol/test/include/parse.clj b/test/smeagol/test/include/parse.clj new file mode 100644 index 0000000..60a22bf --- /dev/null +++ b/test/smeagol/test/include/parse.clj @@ -0,0 +1,81 @@ +(ns smeagol.test.include.parse + (:require [clojure.test :refer :all] + [schema.core :as s] + [smeagol.include.parse :as sut])) + +(def include-simple + "# Heading1 +&[](./simple.md)") + +(def include-surounding-simple + "# Heading1 +Some surounding &[](./simple.md) text") + +(def include-heading-0 + "# Heading1 +&[:indent-heading 0](./with-heading.md)") + +(def include-heading-list-1 + "# Heading1 +&[:indent-heading 1 :indent-list 1](./with-heading-and-list.md)") + +(def include-heading-list-0 + "# Heading1 +&[:indent-list 0 :indent-heading 0](./with-heading-and-list.md)") + +(def include-invalid-indent + "# Heading1 +&[ invalid input should default to indent 0 ](./simple.md)") + +(def include-spaced-indent + "# Heading1 +&[ :indent-heading 2 :indent-list 33 ](./with-heading-and-list.md)") + +(def multi + "# Heading1 +&[ :indent-heading 2 :indent-list 33 ](./with-heading-and-list.md) +some text +&[](./simple.md) +more text.") + + +(deftest test-parse-include-md + (testing "parse include links" + (is + (= [] + (sut/parse-include-md "# Heading"))) + (is + (= [{:uri "./simple.md", :indent-heading 0, :indent-list 0}] + (sut/parse-include-md + include-simple))) + (is + (= [{:uri "./simple.md", :indent-heading 0, :indent-list 0}] + (sut/parse-include-md + include-surounding-simple))) + (is + (= [{:uri "./with-heading.md", :indent-heading 0, :indent-list 0}] + (sut/parse-include-md + include-heading-0))) + (is + (= [{:uri "./with-heading-and-list.md", :indent-heading 1, :indent-list 1}] + (sut/parse-include-md + include-heading-list-1))) + (is + (= [{:uri "./with-heading-and-list.md", :indent-heading 0, :indent-list 0}] + (sut/parse-include-md + include-heading-list-0))) + (is + (= [{:uri "./simple.md", :indent-heading 0, :indent-list 0}] + (sut/parse-include-md + include-invalid-indent))) + (is + (= [{:uri "./with-heading-and-list.md", :indent-heading 2, :indent-list 3}] + (sut/parse-include-md + include-spaced-indent))) + (is + (= [{:uri "./with-heading-and-list.md", + :indent-heading 2, + :indent-list 3} + {:uri "./simple.md", :indent-heading 0, :indent-list 0}] + (sut/parse-include-md + multi))))) From 78a534349b047c8695ecfeee432199960410e557 Mon Sep 17 00:00:00 2001 From: jem Date: Fri, 18 May 2018 14:31:32 +0200 Subject: [PATCH 09/17] add the replacement parameter --- src/smeagol/include/parse.clj | 13 ++++++++----- test/smeagol/test/include/parse.clj | 28 +++++++++++++++++++--------- 2 files changed, 27 insertions(+), 14 deletions(-) diff --git a/src/smeagol/include/parse.clj b/src/smeagol/include/parse.clj index 0c4dbae..2212e0d 100644 --- a/src/smeagol/include/parse.clj +++ b/src/smeagol/include/parse.clj @@ -3,7 +3,8 @@ [schema.core :as s])) (def IncludeLink - {:uri s/Str + {:replace s/Str + :uri s/Str :indent-heading s/Num :indent-list s/Num}) @@ -27,7 +28,7 @@ (s/defn parse-include-link [md-src :- s/Str] - (re-seq #".*&\[\w*(.*)\w*\]\((.*)\).*" md-src)) + (re-seq #".*(&\[\w*(.*)\w*\]\((.*)\)).*" md-src)) (s/defn parse-include-md :- [IncludeLink] @@ -35,9 +36,11 @@ (vec (map (fn [parse-element] - (let [uri (nth parse-element 2) - indents-text (nth parse-element 1)] - {:uri uri + (let [replace (nth parse-element 1) + uri (nth parse-element 3) + indents-text (nth parse-element 2)] + {:replace replace + :uri uri :indent-heading (convert-indent-to-int (parse-indent-heading indents-text)) :indent-list (convert-indent-to-int (parse-indent-list indents-text))})) (parse-include-link md-src)))) diff --git a/test/smeagol/test/include/parse.clj b/test/smeagol/test/include/parse.clj index 60a22bf..af27abf 100644 --- a/test/smeagol/test/include/parse.clj +++ b/test/smeagol/test/include/parse.clj @@ -45,37 +45,47 @@ more text.") (= [] (sut/parse-include-md "# Heading"))) (is - (= [{:uri "./simple.md", :indent-heading 0, :indent-list 0}] + (= [{:replace "&[](./simple.md)" :uri "./simple.md", :indent-heading 0, :indent-list 0}] (sut/parse-include-md include-simple))) (is - (= [{:uri "./simple.md", :indent-heading 0, :indent-list 0}] + (= [{:replace "&[](./simple.md)" :uri "./simple.md", :indent-heading 0, :indent-list 0}] (sut/parse-include-md include-surounding-simple))) (is - (= [{:uri "./with-heading.md", :indent-heading 0, :indent-list 0}] + (= [{:replace "&[:indent-heading 0](./with-heading.md)" :uri "./with-heading.md", :indent-heading 0, :indent-list 0}] (sut/parse-include-md include-heading-0))) (is - (= [{:uri "./with-heading-and-list.md", :indent-heading 1, :indent-list 1}] + (= [{:replace + "&[:indent-heading 1 :indent-list 1](./with-heading-and-list.md)" + :uri "./with-heading-and-list.md", :indent-heading 1, :indent-list 1}] (sut/parse-include-md include-heading-list-1))) (is - (= [{:uri "./with-heading-and-list.md", :indent-heading 0, :indent-list 0}] + (= [{:replace + "&[:indent-list 0 :indent-heading 0](./with-heading-and-list.md)" + :uri "./with-heading-and-list.md", :indent-heading 0, :indent-list 0}] (sut/parse-include-md include-heading-list-0))) (is - (= [{:uri "./simple.md", :indent-heading 0, :indent-list 0}] + (= [{:replace + "&[ invalid input should default to indent 0 ](./simple.md)" + :uri "./simple.md", :indent-heading 0, :indent-list 0}] (sut/parse-include-md include-invalid-indent))) (is - (= [{:uri "./with-heading-and-list.md", :indent-heading 2, :indent-list 3}] + (= [{:replace + "&[ :indent-heading 2 :indent-list 33 ](./with-heading-and-list.md)" + :uri "./with-heading-and-list.md", :indent-heading 2, :indent-list 3}] (sut/parse-include-md include-spaced-indent))) (is - (= [{:uri "./with-heading-and-list.md", + (= [{:replace + "&[ :indent-heading 2 :indent-list 33 ](./with-heading-and-list.md)" + :uri "./with-heading-and-list.md", :indent-heading 2, :indent-list 3} - {:uri "./simple.md", :indent-heading 0, :indent-list 0}] + {:replace "&[](./simple.md)" :uri "./simple.md", :indent-heading 0, :indent-list 0}] (sut/parse-include-md multi))))) From 6768d71429e53aae58e26ed2e6a3db820e9e4d39 Mon Sep 17 00:00:00 2001 From: jem Date: Fri, 18 May 2018 14:31:46 +0200 Subject: [PATCH 10/17] add replacement --- src/smeagol/include.clj | 38 ++++++++++++++++++++++++++++++----- test/smeagol/test/include.clj | 13 ++++++------ 2 files changed, 40 insertions(+), 11 deletions(-) diff --git a/src/smeagol/include.clj b/src/smeagol/include.clj index 14a97da..440f1ab 100644 --- a/src/smeagol/include.clj +++ b/src/smeagol/include.clj @@ -1,5 +1,6 @@ (ns smeagol.include (:require + [clojure.string :as cs] [schema.core :as s] [com.stuartsierra.component :as component] [smeagol.include.parse :as parse] @@ -11,15 +12,42 @@ (defprotocol IncludeMd (expand-include-md [includer md-src] - "return a markfown file content for given uri.")) + "return a markdown containing resolved includes")) + +(s/defn + do-expand-one-include :- s/Str + [includer :- Includer + include :- parse/IncludeLink + md-src :- s/Str] + (let [{:keys [uri replace]} include] + (cs/replace + md-src + (re-pattern (cs/escape + replace + {\[ "\\[" + \] "\\]" + \( "\\(" + \) "\\)"})) + (resolve/resolve-md (:resolver includer) uri)))) + ;indent + +(s/defn + do-expand-includes :- s/Str + [includer :- Includer + includes :- [parse/IncludeLink] + md-src :- s/Str] + (loop [loop-includes includes + result md-src] + (if (empty? loop-includes) + result + (recur + (rest loop-includes) + (do-expand-one-include includer (first loop-includes) result))))) (extend-type Includer IncludeMd (expand-include-md [includer md-src] - (let [includes (parse/parse-include-md md-src)] - ;resolve found includes - ;indent & integrate - md-src))) + (do-expand-includes includer (parse/parse-include-md md-src) md-src))) (s/defn new-includer diff --git a/test/smeagol/test/include.clj b/test/smeagol/test/include.clj index 45219e1..628ad75 100644 --- a/test/smeagol/test/include.clj +++ b/test/smeagol/test/include.clj @@ -47,11 +47,12 @@ more text.") (= uri "./simple.md") "Simple content.")) (def system-under-test - (component/system-map - :resolver (resolve/new-resolver :test-mock) - :includer (component/using - (sut/new-includer) - {:resolver :resolver}))) + (component/start + (component/system-map + :resolver (resolve/new-resolver :test-mock) + :includer (component/using + (sut/new-includer) + [:resolver])))) (deftest test-expand-include-md (testing "The whole integration of include" @@ -59,7 +60,7 @@ more text.") (= "# Heading" (sut/expand-include-md (:includer system-under-test) "# Heading"))) (is - (= "# Heading 1 + (= "# Heading1 Simple content." (sut/expand-include-md (:includer system-under-test) From 07342b5ac4387584097caecee7d05107cf9d3fa8 Mon Sep 17 00:00:00 2001 From: jem Date: Fri, 18 May 2018 17:13:33 +0200 Subject: [PATCH 11/17] implemented includes-resolving for tests --- test/smeagol/test/include.clj | 29 +++++++++++++++++++++++++++-- 1 file changed, 27 insertions(+), 2 deletions(-) diff --git a/test/smeagol/test/include.clj b/test/smeagol/test/include.clj index 628ad75..dc477c9 100644 --- a/test/smeagol/test/include.clj +++ b/test/smeagol/test/include.clj @@ -44,7 +44,15 @@ more text.") [resolver uri :- s/Str] (cond - (= uri "./simple.md") "Simple content.")) + (= uri "./simple.md") "Simple content." + (= uri "./with-heading-and-list.md") "# Heading2 +some text +* List + +## Heading 3 +more text")) + + (def system-under-test (component/start @@ -64,4 +72,21 @@ more text.") Simple content." (sut/expand-include-md (:includer system-under-test) - include-simple))))) + include-simple))) + (is + (= "# Heading1 +Some surounding Simple content. text" + (sut/expand-include-md + (:includer system-under-test) + include-surounding-simple))) + (is + (= "# Heading1 +# Heading2 +some text +* List + +## Heading 3 +more text" + (sut/expand-include-md + (:includer system-under-test) + include-heading-list-0))))) From 12d4661db9844492d65847ffdc652da24f9178b4 Mon Sep 17 00:00:00 2001 From: jem Date: Fri, 18 May 2018 17:17:15 +0200 Subject: [PATCH 12/17] expectation for header & list indent --- test/smeagol/test/include.clj | 16 +++++++++++++++- 1 file changed, 15 insertions(+), 1 deletion(-) diff --git a/test/smeagol/test/include.clj b/test/smeagol/test/include.clj index dc477c9..ff3e8e6 100644 --- a/test/smeagol/test/include.clj +++ b/test/smeagol/test/include.clj @@ -89,4 +89,18 @@ some text more text" (sut/expand-include-md (:includer system-under-test) - include-heading-list-0))))) + include-heading-list-0))) + (is + (= "# Heading1 +### Heading2 +some text + * List + +## Heading 3 +more text +some text +Simple content. +more text." + (sut/expand-include-md + (:includer system-under-test) + multi))))) From 535465c362ace052d311c64d1f3455aec0ecc0f6 Mon Sep 17 00:00:00 2001 From: jem Date: Fri, 18 May 2018 20:47:15 +0200 Subject: [PATCH 13/17] implement indention --- src/smeagol/include.clj | 14 +++++--- src/smeagol/include/indent.clj | 54 ++++++++++++++++++++++++++++ test/smeagol/test/include.clj | 2 +- test/smeagol/test/include/indent.clj | 35 ++++++++++++++++++ 4 files changed, 99 insertions(+), 6 deletions(-) create mode 100644 src/smeagol/include/indent.clj create mode 100644 test/smeagol/test/include/indent.clj diff --git a/src/smeagol/include.clj b/src/smeagol/include.clj index 440f1ab..41aaf99 100644 --- a/src/smeagol/include.clj +++ b/src/smeagol/include.clj @@ -4,7 +4,8 @@ [schema.core :as s] [com.stuartsierra.component :as component] [smeagol.include.parse :as parse] - [smeagol.include.resolve :as resolve])) + [smeagol.include.resolve :as resolve] + [smeagol.include.indent :as indent])) (s/defrecord Includer [resolver]) @@ -19,8 +20,8 @@ [includer :- Includer include :- parse/IncludeLink md-src :- s/Str] - (let [{:keys [uri replace]} include] - (cs/replace + (let [{:keys [uri replace indent-heading indent-list]} include] + (cs/replace-first md-src (re-pattern (cs/escape replace @@ -28,8 +29,11 @@ \] "\\]" \( "\\(" \) "\\)"})) - (resolve/resolve-md (:resolver includer) uri)))) - ;indent + (indent/do-indent-list + indent-list + (indent/do-indent-heading + indent-heading + (resolve/resolve-md (:resolver includer) uri)))))) (s/defn do-expand-includes :- s/Str diff --git a/src/smeagol/include/indent.clj b/src/smeagol/include/indent.clj new file mode 100644 index 0000000..6967d19 --- /dev/null +++ b/src/smeagol/include/indent.clj @@ -0,0 +1,54 @@ +(ns smeagol.include.indent + (:require + [clojure.string :as cs] + [schema.core :as s])) + +(s/defn + parse-list + [md-resolved :- s/Str] + (distinct + (into + (re-seq #"((^|\R? *)([\*\+-] ))" md-resolved) + (re-seq #"((^|\R? *)([0-9]+\. ))" md-resolved)))) + +(s/defn + parse-heading + [md-resolved :- s/Str] + (distinct + (re-seq #"((^|\R?)(#+ ))" md-resolved))) + +(s/defn + do-indent :- s/Str + [indent :- s/Num + indentor :- s/Str + elements + md-resolved :- s/Str] + (loop [result md-resolved + elements elements] + (if (empty? elements) + result + (let [element (first elements) + replace (nth element 1) + start (nth element 2) + end (nth element 3)] + (recur + (cs/replace + result + (re-pattern (cs/escape + replace + {\* "\\*" + \n "\\n"})) + (str start (apply str (repeat indent indentor)) end)) + (rest elements)))))) + +(s/defn + do-indent-heading :- s/Str + [indent :- s/Num + md-resolved :- s/Str] + (do-indent indent "#" (parse-heading md-resolved) md-resolved)) + +(s/defn + do-indent-list :- s/Str + [indent :- s/Num + md-resolved :- s/Str] + (do-indent indent " " (parse-list md-resolved) md-resolved)) diff --git a/test/smeagol/test/include.clj b/test/smeagol/test/include.clj index ff3e8e6..3a037f1 100644 --- a/test/smeagol/test/include.clj +++ b/test/smeagol/test/include.clj @@ -96,7 +96,7 @@ more text" some text * List -## Heading 3 +#### Heading 3 more text some text Simple content. diff --git a/test/smeagol/test/include/indent.clj b/test/smeagol/test/include/indent.clj new file mode 100644 index 0000000..b4ca363 --- /dev/null +++ b/test/smeagol/test/include/indent.clj @@ -0,0 +1,35 @@ +(ns smeagol.test.include.indent + (:require [clojure.test :refer :all] + [smeagol.include.indent :as sut])) + +(deftest test-parse-heading + (testing + (is (= '(["# " "# " "" "# "]) + (sut/parse-heading "# h1"))) + (is (= '(["\n# " "\n# " "\n" "# "]) + (sut/parse-heading "\n# h1"))))) + +(deftest test-indent-heading + (testing + (is (= "# h1" + (sut/do-indent-heading 0 "# h1"))) + (is (= "### h1" + (sut/do-indent-heading 2 "# h1"))) + (is (= "\n### h1" + (sut/do-indent-heading 2 "\n# h1"))))) + +(deftest test-parse-list + (testing + (is (= '([" * " " * " " " "* "]) + (sut/parse-list " * list"))) + (is (= '(["\n * " "\n * " "\n " "* "]) + (sut/parse-list "\n * list"))))) + +(deftest test-indent-list + (testing + (is (= " * list" + (sut/do-indent-list 0 " * list"))) + (is (= " * list" + (sut/do-indent-list 2 " * list"))) + (is (= "\n * list" + (sut/do-indent-list 2 "\n * list"))))) From 3668b26df13c5907dbbb1dac2cb160ea003514cd Mon Sep 17 00:00:00 2001 From: jem Date: Tue, 22 May 2018 16:59:43 +0200 Subject: [PATCH 14/17] add doc to namespaces --- src/smeagol/include.clj | 4 +++- src/smeagol/include/indent.clj | 6 +++++- src/smeagol/include/parse.clj | 6 +++++- src/smeagol/include/resolve.clj | 6 +++++- 4 files changed, 18 insertions(+), 4 deletions(-) diff --git a/src/smeagol/include.clj b/src/smeagol/include.clj index 41aaf99..8f8a017 100644 --- a/src/smeagol/include.clj +++ b/src/smeagol/include.clj @@ -1,4 +1,6 @@ -(ns smeagol.include +(ns ^{:doc "Functions related to the include of markdown-paged in a given markdown." + :author "Michael Jerger"} + smeagol.include (:require [clojure.string :as cs] [schema.core :as s] diff --git a/src/smeagol/include/indent.clj b/src/smeagol/include/indent.clj index 6967d19..f92a69c 100644 --- a/src/smeagol/include/indent.clj +++ b/src/smeagol/include/indent.clj @@ -1,4 +1,8 @@ -(ns smeagol.include.indent +(ns ^{:doc "Functions related to the include of markdown-paged - handling the +list & heading indents of includes. This namespaces is implementation detail for +smeagol.include and not inteded for direct usage." + :author "Michael Jerger"} + smeagol.include.indent (:require [clojure.string :as cs] [schema.core :as s])) diff --git a/src/smeagol/include/parse.clj b/src/smeagol/include/parse.clj index 2212e0d..0016252 100644 --- a/src/smeagol/include/parse.clj +++ b/src/smeagol/include/parse.clj @@ -1,4 +1,8 @@ -(ns smeagol.include.parse +(ns ^{:doc "Functions related to the include of markdown-paged - parsing of +include links. This namespaces is implementation detail for +smeagol.include and not inteded for direct usage." + :author "Michael Jerger"} + smeagol.include.parse (:require [schema.core :as s])) diff --git a/src/smeagol/include/resolve.clj b/src/smeagol/include/resolve.clj index 13a67ce..95b0ec2 100644 --- a/src/smeagol/include/resolve.clj +++ b/src/smeagol/include/resolve.clj @@ -1,4 +1,8 @@ -(ns smeagol.include.resolve +(ns ^{:doc "Functions related to the include of markdown-paged - providing +a plugable load-content componet. This namespaces is implementation detail for +smeagol.include and not inteded for direct usage." + :author "Michael Jerger"} + smeagol.include.resolve (:require [schema.core :as s] [com.stuartsierra.component :as component])) From 7674a4c30593d86007ec2dd0961b6a6f3da6a8ba Mon Sep 17 00:00:00 2001 From: jem Date: Tue, 22 May 2018 18:01:22 +0200 Subject: [PATCH 15/17] stick system together --- src/smeagol/include/resolve.clj | 12 ++++++---- src/smeagol/include/resolve_local_file.clj | 27 ++++++++++++++++++++++ src/smeagol/routes/wiki.clj | 18 +++++++++++++-- 3 files changed, 51 insertions(+), 6 deletions(-) create mode 100644 src/smeagol/include/resolve_local_file.clj diff --git a/src/smeagol/include/resolve.clj b/src/smeagol/include/resolve.clj index 95b0ec2..7a2b3b1 100644 --- a/src/smeagol/include/resolve.clj +++ b/src/smeagol/include/resolve.clj @@ -1,5 +1,5 @@ (ns ^{:doc "Functions related to the include of markdown-paged - providing -a plugable load-content componet. This namespaces is implementation detail for +a plugable load-content componet. This namespaces is implementation detail for smeagol.include and not inteded for direct usage." :author "Michael Jerger"} smeagol.include.resolve @@ -8,7 +8,8 @@ smeagol.include and not inteded for direct usage." [com.stuartsierra.component :as component])) (s/defrecord Resolver - [type :- s/Keyword]) + [type :- s/Keyword + local-base-dir :- s/Str]) ;As schema does'nt support s/defprotocol we use the dispatcher for annotation & validation. (s/defn dispatch-by-resolver-type :- s/Keyword @@ -38,5 +39,8 @@ smeagol.include and not inteded for direct usage." (s/defn new-resolver - [type :- s/Keyword] - (map->Resolver {:type type})) + ([type :- s/Keyword] + (map->Resolver {:type type :local-base-dir nil})) + ([type :- s/Keyword + local-base-dir :- s/Str] + (map->Resolver {:type type :local-base-dir local-base-dir}))) diff --git a/src/smeagol/include/resolve_local_file.clj b/src/smeagol/include/resolve_local_file.clj new file mode 100644 index 0000000..4daaac2 --- /dev/null +++ b/src/smeagol/include/resolve_local_file.clj @@ -0,0 +1,27 @@ +(ns ^{:doc "Functions related to the include of markdown-paged - providing +a plugable load-local-include-links componet. This namespaces is implementation detail for +smeagol.include and not inteded for direct usage." + :author "Michael Jerger"} + smeagol.include.resolve-local-file + (:require + [schema.core :as s] + [smeagol.include.resolve :as resolve] + [com.stuartsierra.component :as component] + [clojure.java.io :as cjio] + [taoensso.timbre :as timbre])) + +(s/defmethod resolve/do-resolve-md :local-file + [resolver + uri :- s/Str] + (let [file-name (uri) + file-path (cjio/file (:local-base-dir resolver) file-name) + exists? (.exists (clojure.java.io/as-file file-path))] + (cond exists? + (do + (timbre/info (format "Including page '%s' from file '%s'" uri file-path)) + (slurp file-path))))) + +(s/defn + new-resolver + [local-base-dir :- s/Str] + (resolve/new-resolver :local-file local-base-dir)) diff --git a/src/smeagol/routes/wiki.clj b/src/smeagol/routes/wiki.clj index fe80349..109a2cc 100644 --- a/src/smeagol/routes/wiki.clj +++ b/src/smeagol/routes/wiki.clj @@ -20,7 +20,10 @@ [smeagol.sanity :refer [show-sanity-check-error]] [smeagol.util :as util] [smeagol.uploads :as ul] - [taoensso.timbre :as timbre])) + [taoensso.timbre :as timbre] + [com.stuartsierra.component :as component] + [smeagol.include.resolve-local-file :as resolve] + [smeagol.include :as include])) ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;;;; @@ -108,6 +111,14 @@ (edit-page request "stylesheet" ".css" "edit-css.html" "_edit-side-bar.md")) +(def md-include-system + (component/start + (component/system-map + :resolver (resolve/new-resolver util/content-dir) + :includer (component/using + (include/new-includer) + [:resolver])))) + (defn wiki-page "Render the markdown page specified in this `request`, if any. If none found, redirect to edit-page" [request] @@ -125,7 +136,10 @@ (merge (util/standard-params request) {:title page :page page - :content (md->html (slurp file-path)) + :content (md->html + (include/expand-include-md + (:includer md-include-system) + (slurp file-path))) :editable true}))) true (response/redirect (str "/edit?page=" page)))))) From 01c954fc2f1e404b6ce14e4777f43a97c0058193 Mon Sep 17 00:00:00 2001 From: jem Date: Tue, 22 May 2018 21:22:58 +0200 Subject: [PATCH 16/17] fix uri resolving --- src/smeagol/include/resolve_local_file.clj | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/smeagol/include/resolve_local_file.clj b/src/smeagol/include/resolve_local_file.clj index 4daaac2..c35e3e5 100644 --- a/src/smeagol/include/resolve_local_file.clj +++ b/src/smeagol/include/resolve_local_file.clj @@ -13,7 +13,7 @@ smeagol.include and not inteded for direct usage." (s/defmethod resolve/do-resolve-md :local-file [resolver uri :- s/Str] - (let [file-name (uri) + (let [file-name uri file-path (cjio/file (:local-base-dir resolver) file-name) exists? (.exists (clojure.java.io/as-file file-path))] (cond exists? From 05eafe603ff29a8144def4cb6a9111173cc457e7 Mon Sep 17 00:00:00 2001 From: Simon Brooke Date: Thu, 24 May 2018 08:26:37 +0100 Subject: [PATCH 17/17] Minor: alphorder requirements, documentation spelling. --- project.clj | 6 +++--- src/smeagol/include/resolve.clj | 6 +++--- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/project.clj b/project.clj index 375538d..8769cba 100644 --- a/project.clj +++ b/project.clj @@ -7,6 +7,7 @@ [clj-yaml "0.4.0"] [com.cemerick/url "0.1.1"] [com.fzakaria/slf4j-timbre "0.3.7"] + [com.stuartsierra/component "0.3.2"] [com.taoensso/encore "2.92.0"] [com.taoensso/timbre "4.10.0"] [com.taoensso/tower "3.0.2" :exclusions [com.taoensso/encore]] @@ -26,12 +27,11 @@ [org.slf4j/log4j-over-slf4j "1.7.25"] [org.slf4j/jul-to-slf4j "1.7.25"] [org.slf4j/jcl-over-slf4j "1.7.25"] + [prismatic/schema "1.1.9"] [prone "1.1.4"] [ring/ring-anti-forgery "1.1.0"] [ring-server "0.4.0"] - [selmer "1.11.0"] - [com.stuartsierra/component "0.3.2"] - [prismatic/schema "1.1.9"]] + [selmer "1.11.0"]] :repl-options {:init-ns smeagol.repl} diff --git a/src/smeagol/include/resolve.clj b/src/smeagol/include/resolve.clj index 7a2b3b1..266a276 100644 --- a/src/smeagol/include/resolve.clj +++ b/src/smeagol/include/resolve.clj @@ -11,7 +11,7 @@ smeagol.include and not inteded for direct usage." [type :- s/Keyword local-base-dir :- s/Str]) -;As schema does'nt support s/defprotocol we use the dispatcher for annotation & validation. +;As schema doesn't 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 @@ -19,7 +19,7 @@ smeagol.include and not inteded for direct usage." (:type resolver)) (defmulti do-resolve-md - "Multimethod return a markfown file content for given uri." + "Multimethod return a markdown file content for given uri." dispatch-by-resolver-type) (s/defmethod do-resolve-md :default [resolver :- Resolver @@ -29,7 +29,7 @@ smeagol.include and not inteded for direct usage." (defprotocol ResolveMd (resolve-md [resolver uri] - "return a markfown file content for given uru.")) + "return a markfown file content for given uri.")) (extend-type Resolver ResolveMd