From 6be21214b0267c18d203bef0c44768804e25bb0b Mon Sep 17 00:00:00 2001 From: jem Date: Tue, 15 May 2018 18:50:54 +0200 Subject: [PATCH 01/25] 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/25] 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/25] 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/25] 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/25] 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/25] 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/25] 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/25] 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/25] 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/25] 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/25] 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/25] 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/25] 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/25] 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/25] 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/25] 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 778c0a84e24a94a29802c8e5957e9dadddde85af Mon Sep 17 00:00:00 2001 From: Simon Brooke Date: Thu, 24 May 2018 07:23:11 +0100 Subject: [PATCH 17/25] i18n --- resources/i18n/de-DE.edn | 143 ++++++++++++++++++++++++++++++++++++ resources/i18n/de.edn | 1 + resources/i18n/en-GB.edn | 2 +- resources/i18n/lt.edn | 1 + resources/i18n/lt_LT.edn | 143 ++++++++++++++++++++++++++++++++++++ resources/i18n/ru.edn | 1 + resources/i18n/ru_RU.edn | 144 +++++++++++++++++++++++++++++++++++++ resources/translations.edn | 0 8 files changed, 434 insertions(+), 1 deletion(-) create mode 100644 resources/i18n/de-DE.edn create mode 120000 resources/i18n/de.edn create mode 120000 resources/i18n/lt.edn create mode 100644 resources/i18n/lt_LT.edn create mode 120000 resources/i18n/ru.edn create mode 100644 resources/i18n/ru_RU.edn create mode 100644 resources/translations.edn diff --git a/resources/i18n/de-DE.edn b/resources/i18n/de-DE.edn new file mode 100644 index 0000000..a7b8789 --- /dev/null +++ b/resources/i18n/de-DE.edn @@ -0,0 +1,143 @@ +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;;; +;;;; Smeagol: a very simple Wiki engine. +;;;; +;;;; This program is free software; you can redistribute it and/or +;;;; modify it under the terms of the GNU General Public License +;;;; as published by the Free Software Foundation; either version 2 +;;;; of the License, or (at your option) any later version. +;;;; +;;;; This program is distributed in the hope that it will be useful, +;;;; but WITHOUT ANY WARRANTY; without even the implied warranty of +;;;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +;;;; GNU General Public License for more details. +;;;; +;;;; You should have received a copy of the GNU General Public License +;;;; along with this program; if not, write to the Free Software +;;;; Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, +;;;; USA. +;;;; +;;;; Copyright (C) 2017 Simon Brooke +;;;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + +;;; en-GB.edn: English-language messages. +;;; This is essentially all the text in the chrome - that which isn't editable +;;; through the wiki itself; and the test in the sanity check report. + +;; ; ; ; ; ; ; ; ; ; +{:add-user-label "Add new user" ;; label for the add user link on edit users page + :change-pass-label "Change password!" + ;; text of the change password widget itself on the + ;; change password page + :change-pass-link "Change password" + ;; text of the change password link on the menu + :change-pass-prompt "To change your password" + ;; text of the change password widget prompt on the + ;; change password page + :change-col-hdr "Changes" ;; header for the changes column in history + :chpass-bad-match "Your proposed passwords don't match" + ;; error text if proposed passwords don't match + :chpass-fail "Your password was not changed" + ;; error text on fail other htan too short or bad match + :chpass-success "Your password was changed" + ;; confirmation text on password change + :chpass-too-short "You proposed password wasn't long enough: eight characters required" + ;; error text if proposed password is too short + :chpass-title-prefix "Change password for" + ;; prefix for title of change password page + :content-dir "The content directory" + ;; used in sanity check report + :content-dir-exists "The content directory exists" + ;; used in sanity check report + :content-dir-is-dir "The content directory is a directory" + ;; used in sanity check report + :cookies-about "About cookies" ;; about cookies text + :cookies-more "This website stores session information as a 'cookie' on your browser. This helps us show you the content you want to see. This cookie does not identify you, and cannot be read by other websites. It is deleted by your browser as soon as you leave this site. This website does not use any third party cookies, so your visit here cannot be tracked by other websites." + ;; more about cookies text + :default-page-title "Introduction" ;; title of the default page in this wiki + :del-col-hdr "Delete" ;; header for delete column on edit users page + :del-user-fail "Could not delete user" + ;; error message on failure to delete user + :del-user-success "Successfully deleted user" + ;; confirmation message on deletion of user + :diff-title-prefix "Changes since version" + ;; prefix for the header of the changes page + :does-not-exist "does not exist" + ;; (of a file or directory); used in sanity check report + :edit-col-hdr "Edit" ;; header for edit column on edit users page + :edit-page-link "Edit this page" + ;; text of the edit page link on the content frame + :edit-title-prefix "Edit" ;; prefix for title of edit content page + :edit-users-link "Edit users" ;; text of the edit users link on the menu + :edit-users-title "Select user to edit" + ;; title of edit users page + :email-prompt "Email address" ;; text of the email widget prompt on edit user page + :file-or-directory "File or directory" + ;; used in sanity check report + :file-summary-prompt "Description/what's changed" + ;; prompt for the file upload summary input + :file-upload-link-text "You may link to this file using a link of the form" + ;; Text introducing the link to an uploaded file + :file-upload-prompt "File to upload" ;; prompt string for the file upload widget + :file-upload-title "Upload a file" ;; title for the file upload page + :is-admin-prompt "Is administrator?" + :here "here" ;; used in sanity check report + :home-link "Home" ;; text of the home link on the menu + :is-not-directory "is not a directory" + ;; (of a file or directory) used in sanity check report + :is-not-readable "is not readable" + ;; (of a file or directory) used in sanity check report + :is-not-writable "is not writable" + ;; (of a file or directory) used in sanity check report + :login-label "Log in!" ;; text of the login widget on the login page + :login-link "Log in" ;; text of the login link on the menu + :login-prompt "To edit this wiki" + ;; text of the action widget prompt on the login page + :logout-label "Log out!" ;; text of the logout widget on the logout page + :logout-link "Log out" ;; text of the logout link on the menu + :logged-in-as "You are logged in as" + ;; text of the 'logged in as' label on the menu + :history-link "History" ;; text of the history link on the content frame + :history-title-prefix "History of" ;; prefix of the title on the history page + :new-pass-prompt "New password" ;; text of the new password widget prompt on the change + ;; password and edit user pages + :no-admin-users "There are no users in the 'passwd' file with administrative privileges" + ;; used in sanity check report + :old-pass-prompt "Your password" + ;; text of the old password widget prompt on the change + ;; password page, and password widget on login page + :password-file "the password ('passwd') file" + ;; used in sanity check report + :problems-found "problems were found" + ;; used in sanity check report + :rpt-pass-prompt "And again" ;; text of the new password widget prompt on the change + ;; password and edit user pages + :save-prompt "When you have finished editing" + ;; text of the save widget label on edit content + ;; and edit user page + :save-label "Save!" ;; text of the save widget itself + :save-user-fail "Failed to store user" + :save-user-success "Successfully stored user" + :see-documentation "For more information please see documentation " + ;; used in sanity check report + :smeagol-not-initialised + "Smeagol is not initialised correctly" + ;; title of the sanity check report + :smeagol-misconfiguration + "Smeagol has been unable to find some of the resources on which it depends, + possibly because of misconfiguration or missing environment variables." + ;; used in sanity check report + :user-lacks-field "User record in the passwd file lacks a field" + ;; used in sanity check report + :username-prompt "Username" ;; text of the username widget prompt on edit user page + ;; text of the is admin widget prompt on edit user page + :user-title-prefix "Edit user" ;; prefix for title of edit user page + :vers-col-hdr "Version" ;; header for the version column in history + :what-col-hdr "What" ;; header for the what column in history + :what-changed-prompt "What have you changed?" + ;; text of the summary widget prompt on edit + ;; content page + :when-col-hdr "When" ;; header for the when column in history + :your-uname-prompt "Your username" ;; text of the username widget prompt on the login page + } diff --git a/resources/i18n/de.edn b/resources/i18n/de.edn new file mode 120000 index 0000000..d74964e --- /dev/null +++ b/resources/i18n/de.edn @@ -0,0 +1 @@ +de-DE.edn \ No newline at end of file diff --git a/resources/i18n/en-GB.edn b/resources/i18n/en-GB.edn index a7b8789..64c164c 100644 --- a/resources/i18n/en-GB.edn +++ b/resources/i18n/en-GB.edn @@ -42,7 +42,7 @@ ;; error text on fail other htan too short or bad match :chpass-success "Your password was changed" ;; confirmation text on password change - :chpass-too-short "You proposed password wasn't long enough: eight characters required" + :chpass-too-short "Your proposed password wasn't long enough: eight characters required" ;; error text if proposed password is too short :chpass-title-prefix "Change password for" ;; prefix for title of change password page diff --git a/resources/i18n/lt.edn b/resources/i18n/lt.edn new file mode 120000 index 0000000..ef91fe5 --- /dev/null +++ b/resources/i18n/lt.edn @@ -0,0 +1 @@ +lt_LT.edn \ No newline at end of file diff --git a/resources/i18n/lt_LT.edn b/resources/i18n/lt_LT.edn new file mode 100644 index 0000000..13185d0 --- /dev/null +++ b/resources/i18n/lt_LT.edn @@ -0,0 +1,143 @@ +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;;; +;;;; Smeagol: a very simple Wiki engine. +;;;; +;;;; This program is free software; you can redistribute it and/or +;;;; modify it under the terms of the GNU General Public License +;;;; as published by the Free Software Foundation; either version 2 +;;;; of the License, or (at your option) any later version. +;;;; +;;;; This program is distributed in the hope that it will be useful, +;;;; but WITHOUT ANY WARRANTY; without even the implied warranty of +;;;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +;;;; GNU General Public License for more details. +;;;; +;;;; You should have received a copy of the GNU General Public License +;;;; along with this program; if not, write to the Free Software +;;;; Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, +;;;; USA. +;;;; +;;;; Lithuanian language translation contributed by and +;;;; Copyright (C) 2017 Soukyan Blackwood +;;;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + +;;; en-GB.edn: English-language messages. +;;; This is essentially all the text in the chrome - that which isn't editable +;;; through the wiki itself; and the test in the sanity check report. + +;; ; ; ; ; ; ; ; ; ; +{:add-user-label "Pridėti naują naudotoją" ;; label for the add user link on edit users page + :change-pass-label "Pakeiskite slaptažodį!" + ;; text of the change password widget itself on the + ;; change password page + :change-pass-link "Pakeiskite slaptažodį" + ;; text of the change password link on the menu + :change-pass-prompt "Pakeisti slaptažodį" + ;; text of the change password widget prompt on the + ;; change password page + :change-col-hdr "Pakeitimai" ;; header for the changes column in history + :chpass-bad-match "Jūsų siūlomi slaptažodžiai - nesutampa" + ;; error text if proposed passwords don't match + :chpass-fail "Jūsų slaptažodis nebuvo pakeistas" + ;; error text on fail other htan too short or bad match + :chpass-success "Jūsų slaptažodis buvo pakeistas" + ;; confirmation text on password change + :chpass-too-short "Jūsų siūlomas slaptožodis – per trumpas: reikia bent aštuonių ženklų" + ;; error text if proposed password is too short + :chpass-title-prefix "Pakeisti slaptažodį, dėl" + ;; prefix for title of change password page + :content-dir "Turinio katalogas" + ;; used in sanity check report + :content-dir-exists "Turinio katalogas egzistuoja" + ;; used in sanity check report + :content-dir-is-dir "Turinio katalogas yra katalogas" + ;; used in sanity check report + :cookies-about "Apie slapukus" ;; about cookies text + :cookies-more "Šis puslapis saugo jūsų sesijų informaciją jūsų naršyklėje “slapukų” forma. Tai mums leidžia jums rodyti tik tai, ką norite matyti. Slapukai neturi jokių jūsų identifikavimo duomenų ir kiti puslapiai negali jų “perskaityti”. Šie slapukai ištrinami iš karto, vos jūs išjungiate šį puslapį. Šis puslapis nenaudoja jokių trečiųjų asmenų slapukų, ir jūsų apsilankymas čia negali būti atsektas jokio kito puslapio." + ;; more about cookies text + :default-page-title "Pristatymas" ;; title of the default page in this wiki + :del-col-hdr "Ištrinti" ;; header for delete column on edit users page + :del-user-fail "Naudotojas negalėjo būti ištrintas" + ;; error message on failure to delete user + :del-user-success "Naudotojas sėkmingai ištrintas" + ;; confirmation message on deletion of user + :diff-title-prefix "Pakeitimai nuo versijos" + ;; prefix for the header of the changes page + :does-not-exist "neegzsituoja" + ;; (of a file or directory); used in sanity check report + :edit-col-hdr "Keisti" ;; header for edit column on edit users page + :edit-page-link "Keisti šį puslapį" + ;; text of the edit page link on the content frame + :edit-title-prefix "Keisti" ;; prefix for title of edit content page + :edit-users-link "Keisti naudotojus" ;; text of the edit users link on the menu + :edit-users-title "Pasirinkti naudotojus keitimui" + ;; title of edit users page + :email-prompt "el. Paštas" ;; text of the email widget prompt on edit user page + :file-or-directory "Failas ar katalogas" + ;; used in sanity check report + :file-summary-prompt "Aprašymas/kas pakeista" + ;; prompt for the file upload summary input + :file-upload-link-text "Galite nukreipti į šį failą naudodami formos nuorodą" + ;; Text introducing the link to an uploaded file + :file-upload-prompt "Failas įkėlimui" ;; prompt string for the file upload widget + :file-upload-title "Įkelti failą" ;; title for the file upload page + :is-admin-prompt "Administratorius?" + :here "čia" ;; used in sanity check report + :home-link "Pradinis" ;; text of the home link on the menu + :is-not-directory "ne katalogas" + ;; (of a file or directory) used in sanity check report + :is-not-readable "neperskaitomas" + ;; (of a file or directory) used in sanity check report + :is-not-writable "nerašomas" + ;; (of a file or directory) used in sanity check report + :login-label "Prisijunkite!" ;; text of the login widget on the login page + :login-link "Prisijunkite" ;; text of the login link on the menu + :login-prompt "Pakeisti šį viki" + ;; text of the action widget prompt on the login page + :logout-label "Atsijunkite!" ;; text of the logout widget on the logout page + :logout-link "Atsijunkite" ;; text of the logout link on the menu + :logged-in-as "Jūs prisijungęs, kaip" + ;; text of the 'logged in as' label on the menu + :history-link "Istorija" ;; text of the history link on the content frame + :history-title-prefix "Istorija apie" ;; prefix of the title on the history page + :new-pass-prompt "Naujas slaptažodis" ;; text of the new password widget prompt on the change + ;; password and edit user pages + :no-admin-users "Naudotojų ‘passwd’ faile su administatoriaus privilegijomis nėra" + ;; used in sanity check report + :old-pass-prompt "Jūsų slaptažodis" + ;; text of the old password widget prompt on the change + ;; password page, and password widget on login page + :password-file "slaptažodžio (‘passwd’) failas" + ;; used in sanity check report + :problems-found "rasta problemų" + ;; used in sanity check report + :rpt-pass-prompt "Ir dar kartą" ;; text of the new password widget prompt on the change + ;; password and edit user pages + :save-prompt "Kai baigsite redaguoti" + ;; text of the save widget label on edit content + ;; and edit user page + :save-label "Išsaugokite!" ;; text of the save widget itself + :save-user-fail "Nepavyko išsaugoti naudotojo" + :save-user-success "Naudotojas sėkmingai išsaugotas" + :see-documentation "Daugiau informacijos ieškokite dokumentacijoje " + ;; used in sanity check report + :smeagol-not-initialised + "Smygolas buvo blogai paleistas" + ;; title of the sanity check report + :smeagol-misconfiguration + "Smygolas nerado kai kurių jam reikalingų resursų, taip nutikti galėjo dėl neteisingų nustatymų, arba trūkstamų aplinkos kintamųjų" + ;; used in sanity check report + :user-lacks-field "Naudotojo passwd failo įraše trūksta laukelio" + ;; used in sanity check report + :username-prompt "Naudotojo vardas" ;; text of the username widget prompt on edit user page + ;; text of the is admin widget prompt on edit user page + :user-title-prefix "Pakeisti naudotoją" ;; prefix for title of edit user page + :vers-col-hdr "Versija" ;; header for the version column in history + :what-col-hdr "Kas" ;; header for the what column in history + :what-changed-prompt "Ką pakeitėte?" + ;; text of the summary widget prompt on edit + ;; content page + :when-col-hdr "Kada" ;; header for the when column in history + :your-uname-prompt "Jūsų naudotojo vardas" ;; text of the username widget prompt on the login page + } diff --git a/resources/i18n/ru.edn b/resources/i18n/ru.edn new file mode 120000 index 0000000..4a740ce --- /dev/null +++ b/resources/i18n/ru.edn @@ -0,0 +1 @@ +ru_RU.edn \ No newline at end of file diff --git a/resources/i18n/ru_RU.edn b/resources/i18n/ru_RU.edn new file mode 100644 index 0000000..73400d6 --- /dev/null +++ b/resources/i18n/ru_RU.edn @@ -0,0 +1,144 @@ +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;;; +;;;; Smeagol: a very simple Wiki engine. +;;;; +;;;; This program is free software; you can redistribute it and/or +;;;; modify it under the terms of the GNU General Public License +;;;; as published by the Free Software Foundation; either version 2 +;;;; of the License, or (at your option) any later version. +;;;; +;;;; This program is distributed in the hope that it will be useful, +;;;; but WITHOUT ANY WARRANTY; without even the implied warranty of +;;;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +;;;; GNU General Public License for more details. +;;;; +;;;; You should have received a copy of the GNU General Public License +;;;; along with this program; if not, write to the Free Software +;;;; Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, +;;;; USA. +;;;; +;;;; Russian language translation contributed by and +;;;; Copyright (C) 2017 Soukyan Blackwood +;;;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + +;;; en-GB.edn: English-language messages. +;;; This is essentially all the text in the chrome - that which isn't editable +;;; through the wiki itself; and the test in the sanity check report. + +;; ; ; ; ; ; ; ; ; ; +{:add-user-label "добавить нового пользователя" ;; label for the add user link on edit users page + :change-pass-label "изменить пароль!" + ;; text of the change password widget itself on the + ;; change password page + :change-pass-link "изменить пароль" + ;; text of the change password link on the menu + :change-pass-prompt "Чтобы изменить пароль" + ;; text of the change password widget prompt on the + ;; change password page + :change-col-hdr "изменения" ;; header for the changes column in history + :chpass-bad-match "Ваши предложенные пароли не совпадают" + ;; error text if proposed passwords don't match + :chpass-fail "Ваш пароль не был изменён" + ;; error text on fail other htan too short or bad match + :chpass-success "Ваш пароль был изменён" + ;; confirmation text on password change + :chpass-too-short "Вы предложили пароль недостаточно длины: требуется восемь символов" + ;; error text if proposed password is too short + :chpass-title-prefix "Изменить пароль для" + ;; prefix for title of change password page + :content-dir "Каталог содержимого" + ;; used in sanity check report + :content-dir-exists "Каталог содержимого существуе" + ;; used in sanity check report + :content-dir-is-dir "Каталог содержимого - это каталог" + ;; used in sanity check report + :cookies-about "Об кукисах" ;; about cookies text + :cookies-more "Этот сайт хранит информацию о сеансе как «cookie» в вашем браузере. Это поможет нам показать вам контент, который вы хотите увидеть. Этот файл cookie не идентифицирует вас и не может быть прочитан другими веб-сайтами. Он удаляется браузером, как только вы покидаете этот сайт. Этот веб-сайт не использует сторонние файлы cookie, поэтому ваш визит здесь не может быть отслежен другими веб-сайтами" + ;; more about cookies text + :default-page-title "представление" ;; title of the default page in this wiki + :del-col-hdr "Удалить" ;; header for delete column on edit users page + :del-user-fail "Не удалось удалить пользователя" + ;; error message on failure to delete user + :del-user-success "успешно удалён пользователь" + ;; confirmation message on deletion of user + :diff-title-prefix "Изменения с версии" + ;; prefix for the header of the changes page + :does-not-exist "не существует" + ;; (of a file or directory); used in sanity check report + :edit-col-hdr "редактировать" ;; header for edit column on edit users page + :edit-page-link "Редактировать эту страницу" + ;; text of the edit page link on the content frame + :edit-title-prefix "редактировать" ;; prefix for title of edit content page + :edit-users-link "Редактировать пользователей" ;; text of the edit users link on the menu + :edit-users-title "Выберите пользователя для редактирования" + ;; title of edit users page + :email-prompt "Адрес электронной почты" ;; text of the email widget prompt on edit user page + :file-or-directory "Файл или каталог" + ;; used in sanity check report + :file-summary-prompt "Описание / что изменилось" + ;; prompt for the file upload summary input + :file-upload-link-text "Вы можете ссылать этот файл, используя ссылку формы" + ;; Text introducing the link to an uploaded file + :file-upload-prompt "Файл для загрузки" ;; prompt string for the file upload widget + :file-upload-title "Загрузить файл" ;; title for the file upload page + :is-admin-prompt "Администратор?" + :here "здесь" ;; used in sanity check report + :home-link "Главная" ;; text of the home link on the menu + :is-not-directory "не является каталогом" + ;; (of a file or directory) used in sanity check report + :is-not-readable "не читаемый" + ;; (of a file or directory) used in sanity check report + :is-not-writable "недоступен для записи" + ;; (of a file or directory) used in sanity check report + :login-label "Вход!" ;; text of the login widget on the login page + :login-link "Вход" ;; text of the login link on the menu + :login-prompt "Чтобы отредактировать эту вики" + ;; text of the action widget prompt on the login page + :logout-label "Выйти!" ;; text of the logout widget on the logout page + :logout-link "Выйти" ;; text of the logout link on the menu + :logged-in-as "Вы вошли как" + ;; text of the 'logged in as' label on the menu + :history-link "история" ;; text of the history link on the content frame + :history-title-prefix "История об" ;; prefix of the title on the history page + :new-pass-prompt "Новый пароль" ;; text of the new password widget prompt on the change + ;; password and edit user pages + :no-admin-users "В файле 'passwd' нет пользователей с правами администратора" + ;; used in sanity check report + :old-pass-prompt "Ваш пароль" + ;; text of the old password widget prompt on the change + ;; password page, and password widget on login page + :password-file "файл пароля ('passwd')" + ;; used in sanity check report + :problems-found "проблемы были найдены" + ;; used in sanity check report + :rpt-pass-prompt "И опять" ;; text of the new password widget prompt on the change + ;; password and edit user pages + :save-prompt "Когда вы закончили редактирование" + ;; text of the save widget label on edit content + ;; and edit user page + :save-label "Сохранить!" ;; text of the save widget itself + :save-user-fail "Не удалось сохранить пользователя" + :save-user-success "Успешно сохранённый пользователь" + :see-documentation "для получения дополнительной информации смотрите документацию " + ;; used in sanity check report + :smeagol-not-initialised + "Смеаголь неправильно инициализирован" + ;; title of the sanity check report + :smeagol-misconfiguration + "Смеаголь не смог найти некоторые ресурсы, от которых это зависит, + возможно, из-за неправильной конфигурации или отсутствующих переменных среды." + ;; used in sanity check report + :user-lacks-field "В пользовательской записи в файле passwd отсутствует поле" + ;; used in sanity check report + :username-prompt "Имя пользователя" ;; text of the username widget prompt on edit user page + ;; text of the is admin widget prompt on edit user page + :user-title-prefix "Изменить пользователя" ;; prefix for title of edit user page + :vers-col-hdr "Версия" ;; header for the version column in history + :what-col-hdr "Что" ;; header for the what column in history + :what-changed-prompt "Что вы изменили?" + ;; text of the summary widget prompt on edit + ;; content page + :when-col-hdr "когда" ;; header for the when column in history + :your-uname-prompt "Ваш логин" ;; text of the username widget prompt on the login page + } diff --git a/resources/translations.edn b/resources/translations.edn new file mode 100644 index 0000000..e69de29 From 40f299b43d7c05a870a3848f508887ab4bb2c810 Mon Sep 17 00:00:00 2001 From: Simon Brooke Date: Thu, 24 May 2018 07:26:39 +0100 Subject: [PATCH 18/25] Version 1.0.1 --- project.clj | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/project.clj b/project.clj index efd7bc2..7e86d29 100644 --- a/project.clj +++ b/project.clj @@ -1,4 +1,4 @@ -(defproject smeagol "1.0.1-SNAPSHOT" +(defproject smeagol "1.0.1" :description "A simple Git-backed Wiki inspired by Gollum" :url "https://github.com/simon-brooke/smeagol" :license {:name "GNU General Public License,version 2.0 or (at your option) any later version" From 05eafe603ff29a8144def4cb6a9111173cc457e7 Mon Sep 17 00:00:00 2001 From: Simon Brooke Date: Thu, 24 May 2018 08:26:37 +0100 Subject: [PATCH 19/25] 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 From f3456d819cbcd65ab8d1091539e31ffda8d55434 Mon Sep 17 00:00:00 2001 From: Simon Brooke Date: Thu, 24 May 2018 08:28:37 +0100 Subject: [PATCH 20/25] Upversion to 1.0.2-SNAPSHOT --- project.clj | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/project.clj b/project.clj index 8769cba..1de6005 100644 --- a/project.clj +++ b/project.clj @@ -1,4 +1,4 @@ -(defproject smeagol "1.0.1" +(defproject smeagol "1.0.2-SNAPSHOT" :description "A simple Git-backed Wiki inspired by Gollum" :url "https://github.com/simon-brooke/smeagol" :license {:name "GNU General Public License,version 2.0 or (at your option) any later version" From 7b284eb13fd95dd2a96b6cbb8a5be2ac808d2ae0 Mon Sep 17 00:00:00 2001 From: jem Date: Fri, 25 May 2018 17:15:46 +0200 Subject: [PATCH 21/25] Added include doc --- README.md | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/README.md b/README.md index 03cd9d1..46d38e1 100644 --- a/README.md +++ b/README.md @@ -98,6 +98,17 @@ You can (if you're logged in) upload files, including images, using the **Upload ![Smeagol](http://vignette3.wikia.nocookie.net/lotr/images/e/e1/Gollum_Render.png/revision/latest?cb=20141218075509) +## Includes +You can include pages into the current page youre working on. To do so, you can add a include link: + +`&[:indent-heading s/Num :indent-list s/Num](relative or absolute uri s/Str)` + +Parameters semantics: + * uri: The page to include. At the moment only pages of the current wiki are allowed. A page called "PageToBeIncluded" will result in a uri "PageToBeIncluded.md". + * indent-heading: You can indent headings of included page to adjust the included content to your surrounding structure. Indents 0-9 are supported. + * indent-list: In Same manner you can indent lists of included page to adjust the included content to your surrounding structure. Indents 0-9 are supported. + Security warning: At the moment there is no check against directory traversal attack. So include feature may expose files outside of your wiki. + ## Advertisement If you like what you see here, I am available for work on open source Clojure projects. From 7e5b3d74dac2e0c675dcec024c544a6f36a2cbb0 Mon Sep 17 00:00:00 2001 From: jem Date: Fri, 25 May 2018 17:19:33 +0200 Subject: [PATCH 22/25] spelling & format fixes for README --- README.md | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index 46d38e1..2dfc62b 100644 --- a/README.md +++ b/README.md @@ -99,14 +99,15 @@ You can (if you're logged in) upload files, including images, using the **Upload ![Smeagol](http://vignette3.wikia.nocookie.net/lotr/images/e/e1/Gollum_Render.png/revision/latest?cb=20141218075509) ## Includes -You can include pages into the current page youre working on. To do so, you can add a include link: +You can include pages into the current page you're working on. To do so, you can add a include link: `&[:indent-heading s/Num :indent-list s/Num](relative or absolute uri s/Str)` Parameters semantics: - * uri: The page to include. At the moment only pages of the current wiki are allowed. A page called "PageToBeIncluded" will result in a uri "PageToBeIncluded.md". + * uri: The page to include. At the moment only pages from the current wiki are allowed. A page called "PageToBeIncluded" will result in a uri "PageToBeIncluded.md". * indent-heading: You can indent headings of included page to adjust the included content to your surrounding structure. Indents 0-9 are supported. * indent-list: In Same manner you can indent lists of included page to adjust the included content to your surrounding structure. Indents 0-9 are supported. + Security warning: At the moment there is no check against directory traversal attack. So include feature may expose files outside of your wiki. ## Advertisement From 77d77ed3343ccfd65f57576728b1c2e1af69a082 Mon Sep 17 00:00:00 2001 From: jem Date: Fri, 25 May 2018 17:21:32 +0200 Subject: [PATCH 23/25] minor doc add in README --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 2dfc62b..6cc0691 100644 --- a/README.md +++ b/README.md @@ -108,7 +108,7 @@ Parameters semantics: * indent-heading: You can indent headings of included page to adjust the included content to your surrounding structure. Indents 0-9 are supported. * indent-list: In Same manner you can indent lists of included page to adjust the included content to your surrounding structure. Indents 0-9 are supported. - Security warning: At the moment there is no check against directory traversal attack. So include feature may expose files outside of your wiki. + Security warning: At the moment there is no check against directory traversal attack. So include feature may expose files outside of your wiki content-dir. ## Advertisement If you like what you see here, I am available for work on open source Clojure projects. From fad1fcfea5b1f0ad4dfff7473afeb3c2981854d7 Mon Sep 17 00:00:00 2001 From: jem Date: Tue, 8 Jan 2019 19:59:16 +0100 Subject: [PATCH 24/25] make start page configurable --- resources/config.edn | 4 ++-- src/smeagol/routes/wiki.clj | 2 +- src/smeagol/util.clj | 3 +++ 3 files changed, 6 insertions(+), 3 deletions(-) diff --git a/resources/config.edn b/resources/config.edn index 0fcb152..80d0738 100644 --- a/resources/config.edn +++ b/resources/config.edn @@ -28,6 +28,7 @@ ;; ; ; ; ; ; ; ; ; ; { :content-dir "resources/public/content" + :start-page "README" ;; where content is served from. :default-locale "en-GB" ;; default language used for messages :formatters {"vega" smeagol.formatting/process-vega @@ -38,6 +39,5 @@ ;; :trace :debug :info :warn :error :fatal :passwd "resources/passwd" ;; where the password file is stored - :site-title "Smeagol" ;; overall title of the site, used in + :site-title "Smeagol"} ;; overall title of the site, used in ;; page headings -} diff --git a/src/smeagol/routes/wiki.clj b/src/smeagol/routes/wiki.clj index 467275d..91174b2 100644 --- a/src/smeagol/routes/wiki.clj +++ b/src/smeagol/routes/wiki.clj @@ -125,7 +125,7 @@ (or (show-sanity-check-error) (let [params (keywordize-keys (:params request)) - page (or (:page params) (util/get-message :default-page-title "Introduction" request)) + page (or (:page params) util/start-page (util/get-message :default-page-title "Introduction" request)) file-name (str page ".md") file-path (cjio/file util/content-dir file-name) exists? (.exists (clojure.java.io/as-file file-path))] diff --git a/src/smeagol/util.clj b/src/smeagol/util.clj index 015a5db..8ab537d 100644 --- a/src/smeagol/util.clj +++ b/src/smeagol/util.clj @@ -35,6 +35,9 @@ ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +(def start-page + (:start-page config)) + (def content-dir (or (:content-dir config) From 4f8c4b8925d3596ff42c2906958cbf21efbd1992 Mon Sep 17 00:00:00 2001 From: jem Date: Fri, 18 Jan 2019 15:06:33 +0100 Subject: [PATCH 25/25] fixed test - Now we are getting a 200 response again. --- resources/config.edn | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/resources/config.edn b/resources/config.edn index 80d0738..d5f7017 100644 --- a/resources/config.edn +++ b/resources/config.edn @@ -28,7 +28,7 @@ ;; ; ; ; ; ; ; ; ; ; { :content-dir "resources/public/content" - :start-page "README" + :start-page "Introduction" ;; where content is served from. :default-locale "en-GB" ;; default language used for messages :formatters {"vega" smeagol.formatting/process-vega