mw-ui0.1.5Web-based user interface for MicroWorld dependencies
| (this space intentionally left almost blank) | ||||||||||||||||||||||||||||||||||||
Set up and tear down the request handler. | (ns ^{:doc
:author "Simon Brooke"}
mw-ui.handler
(:require [compojure.core :refer [defroutes]]
[mw-ui.routes.home :refer [home-routes]]
[mw-ui.middleware :refer [load-middleware]]
[noir.response :refer [redirect]]
[noir.util.middleware :refer [app-handler]]
[compojure.route :as route]
[taoensso.timbre :as timbre]
[taoensso.timbre.appenders.rotor :as rotor]
[selmer.parser :as parser]
[environ.core :refer [env]])) | ||||||||||||||||||||||||||||||||||||
mw-ui: a servlet user/visualisation interface for MicroWorld. 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) 2014 Simon Brooke | |||||||||||||||||||||||||||||||||||||
(defroutes app-routes (route/resources "/") (route/not-found "Not Found")) | |||||||||||||||||||||||||||||||||||||
init will be called once when app is deployed as a servlet on an app server such as Tomcat put any initialization code here | (defn init
[]
(timbre/set-config!
[:appenders :rotor]
{:min-level :info
:enabled? true
:async? false ; should be always false for rotor
:max-message-per-msecs nil
:fn rotor/appender-fn})
(timbre/set-config!
[:shared-appender-config :rotor]
{:path "mw_ui.log" :max-size (* 512 1024) :backlog 10})
(if (env :dev) (parser/cache-off!))
(timbre/info "mw-ui started successfully")) | ||||||||||||||||||||||||||||||||||||
destroy will be called when your application shuts down, put any clean up code here | (defn destroy [] (timbre/info "mw-ui is shutting down...")) | ||||||||||||||||||||||||||||||||||||
(def app (app-handler
;; add your application routes here
[home-routes app-routes]
;; add custom middleware here
:middleware (load-middleware)
;; timeout sessions after 30 minutes
:session-options {:timeout (* 60 30)
:timeout-response (redirect "/")}
;; add access rules here
:access-rules []
;; serialize/deserialize the following data formats
;; available formats:
;; :json :json-kw :yaml :yaml-kw :edn :yaml-in-html
:formats [:json-kw :edn])) | |||||||||||||||||||||||||||||||||||||
Layout content as HTML. | (ns ^{:doc
:author "Simon Brooke"}
mw-ui.layout
(:require [selmer.parser :as parser]
[clojure.string :as s]
[ring.util.response :refer [content-type response]]
[compojure.response :refer [Renderable]])) | ||||||||||||||||||||||||||||||||||||
mw-ui: a servlet user/visualisation interface for MicroWorld. 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) 2014 Simon Brooke | |||||||||||||||||||||||||||||||||||||
(def template-path "templates/") | |||||||||||||||||||||||||||||||||||||
(deftype RenderableTemplate [template params]
Renderable
(render [this request]
(content-type
(->> (assoc (merge params {:version (System/getProperty "mw-ui.version")})
(keyword (s/replace template #".html" "-selected")) "active"
:servlet-context
(if-let [context (:servlet-context request)]
(.getContextPath context)))
(parser/render-file (str template-path template))
response)
"text/html; charset=utf-8"))) | |||||||||||||||||||||||||||||||||||||
(defn render [template & [params]] (RenderableTemplate. template params)) | |||||||||||||||||||||||||||||||||||||
In truth, boilerplate from Luminus. | (ns ^{:doc
:author "Simon Brooke"}
mw-ui.middleware
(:require [taoensso.timbre :as timbre]
[selmer.parser :as parser]
[environ.core :refer [env]]
[selmer.middleware :refer [wrap-error-page]]
[noir-exception.core
:refer [wrap-internal-error wrap-exceptions]])) | ||||||||||||||||||||||||||||||||||||
mw-ui: a servlet user/visualisation interface for MicroWorld. 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) 2014 Simon Brooke | |||||||||||||||||||||||||||||||||||||
(defn log-request [handler]
(fn [req]
(timbre/debug req)
(handler req))) | |||||||||||||||||||||||||||||||||||||
(def development-middleware [log-request wrap-error-page wrap-exceptions]) | |||||||||||||||||||||||||||||||||||||
(def production-middleware [#(wrap-internal-error % :log (fn [e] (timbre/error e)))]) | |||||||||||||||||||||||||||||||||||||
(defn load-middleware []
(concat (when (env :dev) development-middleware)
production-middleware)) | |||||||||||||||||||||||||||||||||||||
Render the state of the world as an HTML table. | (ns ^{:doc
:author "Simon Brooke"}
mw-ui.render-world
(:require [clojure.java.io :as jio]
[mw-engine.core :as engine]
[mw-engine.world :as world]
[mw-engine.heightmap :as heightmap]
[mw-parser.bulk :as compiler]
[hiccup.core :refer [html]]
[noir.io :as io]
[noir.session :as session])) | ||||||||||||||||||||||||||||||||||||
mw-ui: a servlet user/visualisation interface for MicroWorld. 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) 2014 Simon Brooke | |||||||||||||||||||||||||||||||||||||
(defn format-css-class [statekey] "Format this statekey, assumed to be a keyword indicating a state in the world, into a CSS class" (subs (str statekey) 1)) | |||||||||||||||||||||||||||||||||||||
Render this statekey, assumed to be a keyword indicating a state in the world, into a path which should recover the corresponding image file. | (defn format-image-path [statekey] (format "img/tiles/%s.png" (format-css-class statekey))) | ||||||||||||||||||||||||||||||||||||
(defn format-mouseover [cell] (str cell)) | |||||||||||||||||||||||||||||||||||||
Render this world cell as a Hiccup table cell. | (defn render-cell
[cell]
(let [state (:state cell)]
[:td {:class (format-css-class state) :title (format-mouseover cell)}
[:a {:href (format "inspect?x=%d&y=%d" (:x cell) (:y cell))}
[:img {:alt (:state cell) :src (format-image-path state)}]]])) | ||||||||||||||||||||||||||||||||||||
Render this world row as a Hiccup table row. | (defn render-world-row [row] (apply vector (cons :tr (map render-cell row)))) | ||||||||||||||||||||||||||||||||||||
Render the world implied by the current session as a complete HTML table in a DIV. | (defn render-world-table
[]
(let [world (or (session/get :world)
(heightmap/apply-heightmap
(io/get-resource "/img/heightmaps/small_hill.png")))
rules (or (session/get :rules)
(do (session/put! :rules
(compiler/compile-file
(io/get-resource "/rulesets/basic.txt")))
(session/get :rules)))
generation (inc (or (session/get :generation) 0))
w2 (engine/transform-world world rules)
]
(session/put! :world w2)
(session/put! :generation generation)
[:div {:class "world"}
(apply vector
(cons :table
(map render-world-row w2)))
[:p
(str "Generation " generation)]])) | ||||||||||||||||||||||||||||||||||||
Render in Hiccup format the HTML content of an inspector on this cell. | (defn render-inspector
[cell table]
[:table {:class "music-ruled"}
[:tr
[:td {:colspan 2 :style "text-align: center;"}
[:img {:src (str "img/tiles/" (name (:state cell)) ".png")
:width 64
:height 64}]]]
[:tr [:th "Key"][:th "Value"]]
(map #(vector :tr (vector :th %)(vector :td (cell %))) (keys cell))]) | ||||||||||||||||||||||||||||||||||||
In truth, boilerplate from Luminus. | (ns ^{:doc
:author "Simon Brooke"}
mw-ui.repl
(:use mw-ui.handler
ring.server.standalone
[ring.middleware file-info file])
(:gen-class)) | ||||||||||||||||||||||||||||||||||||
mw-ui: a servlet user/visualisation interface for MicroWorld. 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) 2014 Simon Brooke | |||||||||||||||||||||||||||||||||||||
(defonce server (atom nil)) | |||||||||||||||||||||||||||||||||||||
(defn get-handler []
;; #'app expands to (var app) so that when we reload our code,
;; the server is forced to re-resolve the symbol in the var
;; rather than having its own copy. When the root binding
;; changes, the server picks it up without having to restart.
(-> #'app
; Makes static assets in $PROJECT_DIR/resources/public/ available.
(wrap-file "resources")
; Content-Type, Content-Length, and Last Modified headers for files in body
(wrap-file-info))) | |||||||||||||||||||||||||||||||||||||
used for starting the server in development mode from REPL | (defn start-server
[& [port]]
(let [port (if port (Integer/parseInt port) 3000)]
(reset! server
(serve (get-handler)
{:port port
:init init
:auto-reload? true
:destroy destroy
:join? false}))
(println (str "You can view the site at http://localhost:" port)))) | ||||||||||||||||||||||||||||||||||||
(defn stop-server [] (.stop @server) (reset! server nil)) | |||||||||||||||||||||||||||||||||||||
(defn -main [] (start-server)) | |||||||||||||||||||||||||||||||||||||
Routes which serve the main pages of the application. | (ns ^{:doc
:author "Simon Brooke"}
mw-ui.routes.home
(:use clojure.walk
compojure.core)
(:require [clojure.pprint :only [pprint]]
[hiccup.core :refer [html]]
[mw-engine.utils :as engine-utils]
[mw-ui.layout :as layout]
[mw-ui.render-world :as world]
[mw-ui.routes.load :as load]
[mw-ui.routes.rules :as rules]
[mw-ui.routes.params :as params]
[mw-ui.routes.save :as save]
[mw-ui.util :as util]
[noir.io :as io]
[noir.session :as session]
[ring.util.response :as response])) | ||||||||||||||||||||||||||||||||||||
mw-ui: a servlet user/visualisation interface for MicroWorld. 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) 2014 Simon Brooke | |||||||||||||||||||||||||||||||||||||
(defn list-states []
(sort
(filter #(not (nil? %))
(map #(first (rest (re-matches #"([0-9a-z-]+).png" (.getName %))))
(file-seq (clojure.java.io/file "resources/public/img/tiles")))))) | |||||||||||||||||||||||||||||||||||||
(defn about-page []
(layout/render "trusted-content.html"
{:title "About MicroWorld"
:about-selected "active"
:content (util/md->html "/md/about.md")
:version (System/getProperty "mw-ui.version")})) | |||||||||||||||||||||||||||||||||||||
(defn docs-page []
(layout/render "docs.html" {:title "Documentation"
:parser (util/md->html "/md/mw-parser.md" )
:states (util/list-resources "/img/tiles" #"([0-9a-z-_]+).png")
:lessons (util/list-resources "/md/lesson-plans" #"([0-9a-z-_]+).md")
:components ["mw-engine" "mw-parser" "mw-ui"]
:version (System/getProperty "mw-ui.version")})) | |||||||||||||||||||||||||||||||||||||
(defn home-page []
"Render the home page."
(layout/render "trusted-content.html" {:title "Welcome to MicroWorld"
:content (util/md->html "/md/mw-ui.md")
:version (System/getProperty "mw-ui.version")})) | |||||||||||||||||||||||||||||||||||||
(defn inspect-page [request]
"Open an inspector on the cell at the co-ordinates specified in this request"
(let [params (keywordize-keys (:params request))
xs (:x params)
ys (:y params)
x (if (seq xs) (read-string xs) 0)
y (if (seq ys) (read-string ys) 0)
world (session/get :world)
cell (engine-utils/get-cell world x y)
state (:state params)]
(cond state
(do
(session/put! :world (engine-utils/set-property world cell :state (keyword state)))
(response/redirect "world"))
true
(layout/render "inspector.html"
{:title (format "Inspect cell at %d, %d" x y)
:content (html (world/render-inspector cell world))
:cell cell
:x (:x cell)
:y (:y cell)
:states (util/list-resources
"/img/tiles" #"([0-9a-z-_]+).png")})))) | |||||||||||||||||||||||||||||||||||||
Render the markdown page specified in this request, if any. Probably undesirable, should be removed. | (defn md-page
[request]
(let [params (keywordize-keys (:params request))
content (or (:content params) "missing.md")]
(layout/render "trusted-content.html"
{:title "Welcome to MicroWorld"
:content (util/md->html (str "/md/" content))}))) | ||||||||||||||||||||||||||||||||||||
(defn world-page []
"Render the world in the current session (or a default one if none)."
(layout/render "trusted-content.html"
{:title "Watch your world grow"
:world-selected "active"
:content (html (world/render-world-table))
:pause (or (session/get :pause) 5)
:maybe-refresh "refresh"})) | |||||||||||||||||||||||||||||||||||||
(defroutes home-routes (GET "/" [] (home-page)) (GET "/about" [] (about-page)) (GET "/docs" [] (docs-page)) (GET "/inspect" request (inspect-page request)) (POST "/inspect" request (inspect-page request)) (GET "/load" [] (load/load-page)) (POST "/load" request (load/load-page request)) (GET "/md" request (md-page request)) (GET "/params" [] (params/params-page)) (POST "/params" request (params/params-page request)) (GET "/rules" request (rules/rules-page request)) (POST "/rules" request (rules/rules-page request)) (GET "/saved-map.mwm" [] (save/save-page)) (GET "/world" [] (world-page))) | |||||||||||||||||||||||||||||||||||||
Route which handles the upload of worlds/rules from the client. | (ns ^{:doc
:author "Simon Brooke"}
mw-ui.routes.load
(:use clojure.walk
compojure.core)
(:require [hiccup.core :refer [html]]
[noir.io :as io]
[noir.session :as session]
[ring.util.response :as response]
[mw-ui.layout :as layout])) | ||||||||||||||||||||||||||||||||||||
mw-ui: a servlet user/visualisation interface for MicroWorld. 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) 2014 Simon Brooke | |||||||||||||||||||||||||||||||||||||
(defn- upload [file]
(io/upload-file "/tmp/" file)
(cond
(session/put! :world
(with-open [eddi (java.io.FileReader. (:tempfile file))] (read)))
(str "Successfully loaded your world from " (:filename file)))) | |||||||||||||||||||||||||||||||||||||
If no args, show the load form; with args, load a world file from the client. NOTE that this reads a Clojure form from an untrusted client and should almost certainly NOT be enabled on a public-facing site, especially not on the Internet. TODO doesn't work yet. | (defn load-page
([]
(load-page nil))
([request]
(let [params (keywordize-keys (:params request))
file (:file request)]
(try
(layout/render "load.html"
{:title "Load World"
:message (upload file)})
(catch Exception any
(layout/render "load.html"
{:title "Load World"
:message "Failed to load your world"
:error (str (.getName (.getClass any)) ": " (.getMessage any))})))))) | ||||||||||||||||||||||||||||||||||||
Route which serves and handles the parameters page. | (ns ^{:doc
:author "Simon Brooke"}
mw-ui.routes.params
(:use clojure.walk
clojure.java.io
compojure.core)
(:require [hiccup.core :refer [html]]
[mw-engine.heightmap :as heightmap]
[mw-parser.bulk :as compiler]
[mw-ui.layout :as layout]
[mw-ui.util :as util]
[mw-ui.render-world :as world]
[noir.io :as io]
[noir.session :as session])) | ||||||||||||||||||||||||||||||||||||
mw-ui: a servlet user/visualisation interface for MicroWorld. 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) 2014 Simon Brooke | |||||||||||||||||||||||||||||||||||||
(defn- send-params []
{:title "Choose your world"
:heightmaps (util/list-resources "/img/heightmaps" #"([0-9a-z-_]+).png")
:pause (or (session/get :pause) 5)
:rulesets (util/list-resources "/rulesets" #"([0-9a-z-_]+).txt")
}) | |||||||||||||||||||||||||||||||||||||
Handler for params request. If no | (defn params-page
([]
(layout/render "params.html" (send-params)))
([request]
(try
(let [params (keywordize-keys (:form-params request))
map (:heightmap params)
pause (:pause params)
rulefile (:ruleset params)
rulepath (str "/rulesets/" rulefile ".txt")]
(if (not= map "")
(session/put! :world
(heightmap/apply-heightmap
(io/get-resource (str "/img/heightmaps/" map ".png")))))
(when (not= rulefile "")
(session/put! :rule-text (io/slurp-resource rulepath))
(session/put! :rules (compiler/compile-file (io/get-resource rulepath))))
(if (not= pause "")
(session/put! :pause pause))
(layout/render "params.html"
(merge (send-params)
{:r rulefile
:h map
:message "Your parameters are saved, now look at your world"})))
(catch Exception e
(let [params (keywordize-keys (:form-params request))]
(layout/render "params.html"
(merge (send-params)
{:title "Choose your world"
:r (:ruleset params)
:h (:heightmap params)
:message "Your paramters are not saved"
:error (str (.getName (.getClass e)) ": " (.getMessage e) "; " params)}))))))) | ||||||||||||||||||||||||||||||||||||
Route which serves and handles the rules page. | (ns ^{:doc
:author "Simon Brooke"}
mw-ui.routes.rules
(:use clojure.walk
compojure.core)
(:require [hiccup.core :refer [html]]
[mw-parser.bulk :as compiler]
[mw-ui.layout :as layout]
[mw-ui.util :as util]
[mw-ui.render-world :as world]
[noir.io :as io]
[noir.session :as session]
[ring.util.response :as response])) | ||||||||||||||||||||||||||||||||||||
mw-ui: a servlet user/visualisation interface for MicroWorld. 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) 2014 Simon Brooke | |||||||||||||||||||||||||||||||||||||
(defn process-rules-request
[request]
(let [src (:src (keywordize-keys (:form-params request)))]
(try
(cond src
(let [rules (compiler/compile-string src)]
{:rule-text src
:rules rules
:message (str "Successfully compiled "
(count rules)
" rules") })
true {:rule-text (or
(session/get :rule-text)
(io/slurp-resource "/rulesets/basic.txt"))
:message "No rules found in request; loading defaults"})
(catch Exception e
{:rule-text src
:message "An error occurred during compilation"
:error (str (.getName (.getClass e)) ": " (.getMessage e))})))) | |||||||||||||||||||||||||||||||||||||
Request handler for the If | (defn rules-page
([request]
(let [processed (process-rules-request request)]
(if (:rules processed)
(session/put! :rules (:rules processed)))
(if (:rule-text processed)
(session/put! :rule-text (:rule-text processed)))
(layout/render "rules.html"
(merge {:title "Edit Rules"} processed))))
([]
(rules-page nil))) | ||||||||||||||||||||||||||||||||||||
Route which handles the saving of world state the client. | (ns ^{:doc
:author "Simon Brooke"}
mw-ui.routes.save
(:require [clojure.pprint :as pretty :only [pprint]]
[noir.session :as session]
[noir.response :as response])) | ||||||||||||||||||||||||||||||||||||
mw-ui: a servlet user/visualisation interface for MicroWorld. 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) 2014 Simon Brooke | |||||||||||||||||||||||||||||||||||||
(defn save-page []
"Save the current world to the browser, using our own custom mime-type in
an attempt to prevent the browser trying to do anything clever with it.
Note that it is saved as a raw Clojure data structure, not as XML or
any proprietary format."
(response/content-type
"application/journeyman-mwm; charset=utf-8"
(with-out-str (pretty/pprint (session/get :world))))) | |||||||||||||||||||||||||||||||||||||
Utility functions used by other namespaces in this package. | (ns ^{:doc
:author "Simon Brooke"}
mw-ui.util
(:require [noir.io :as io]
[noir.session :as session]
[markdown.core :as md])) | ||||||||||||||||||||||||||||||||||||
mw-ui: a servlet user/visualisation interface for MicroWorld. 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) 2014 Simon Brooke | |||||||||||||||||||||||||||||||||||||
reads a markdown file from public/md and returns an HTML string | (defn md->html
[filename]
(->>
(io/slurp-resource filename)
(md/md-to-html-string))) | ||||||||||||||||||||||||||||||||||||
(defn list-resources [directory pattern]
"List resource files matching `pattern` in `directory`."
(let
[path (str (io/resource-path) directory)]
(session/put! :list-resources-path path)
(sort
(remove nil?
(map #(first (rest (re-matches pattern (.getName %))))
(file-seq (clojure.java.io/file path))))))) | |||||||||||||||||||||||||||||||||||||