Overview†
misaki allows you to develop your own compiler. There are 3 function to construct misaki's compiler.
-extension
- REQUIRED
-config
- OPTIONAL
-compile
- REQUIRED
Start to develop†
You can use misaki-compiler-template as a template for misaki compiler.
misaki-compiler-template need to install lein-newnew.
$ lein new misaki-compiler YOUR_COMPILER_NAME $ cd YOUR_COMPILER_NAME
Namespace of core.clj must be misaki.compiler.YOUR-COMPIER-NAME.core
$ vi src/misaki/compiler/YOUR_COMPILER_NAME/core.clj
Then, edit core.clj as follows!
Simplest compiler sample†
Following compiler append (:text config)
to head of template file.
(ns misaki.compiler.YOUR_COMPILER_NAME.core "Namespace must be misaki.compiler.***.core '***' is a compiler name." (:require [misaki.server :as srv])) (defn -extension "Specify file extensions to watch in misaki." [] (list :txt)) (defn -config "If your compiler handles custom configuration, you can set original data in this function." [config] (assoc config :message "hello YOUR_COMPILER_NAME")) (defn -compiler "Called when watched files are updated. If you returns... * string : Write string to file named as same as template file. * boolean: Do nothing(true = success, false = fail). * symbol : Do nothing(skip) * map : Write file with detailed setting. `:status` -> Compile result(true(success), false(fail) or something else(skip)) `:filename` -> Filename to write `:body` -> Compiled body text. if body is nil, only status is checked `:stop-compile?` -> Flag(true/false) to stop all compilation `:all-compile?` -> Flag(true/false) to force compiling all templates" [config file] (str (:message config) " " (slurp file))) (defn -main "You can run misaki using this compiler with `lein run`." [& args] (apply srv/-main args))
-extension†
Return file extension list to watch template file. This function is REQUIRED.
-config†
Basic config data is passed, and return customized config data. This function is OPTIONAL.
-compile†
Updated file(java.io.File) is passed, and return compile result. This function is REQUIRED.
Return value specification is following.
- string
Write string to file which is named as same as template file.
(defn -compile [file] (str "hello " (slurp file))) ; foo.txt whose body is "world" is passed, ; result file is *public-dir*/foo.txt whose body is "hello world"
- boolean
misaki.core does not write file, only check compile result.
(defn -compile [file] (compile-in-compiler file) true) ; true => compile success ; false => compile failed
- symbol
misaki.core skip the file.
(defn -compile [file] (if-not (valid-file? file) 'skip)) ; Skip to compile file
- map
Write file with detailed setting.
(defn -compile [file] {; compile result :status true ; output filename :filename (str (.getName file) ".html") ; output body :body (str "hello " (slurp file)) ; flag to stop compilation :stop-compile? false ; flat to force compiling all templates :all-compile? false})
Test your compiler†
misaki provides utilities to test your own compiler.
(ns misaki.compiler.YOUR_COMPILER_NAME.core-test (:use clojure.test misaki.compiler.YOUR_COMPILER_NAME.core misaki.tester) (:require [clojure.string :as str] [clojure.java.io :as io])) ; set base directory which include _config.clj ; default testing base directory is "test" (set-base-dir! "test") ; define test wrapping config data as *config* ; ; This code is same as following: ; (deftest foo-test ; (binding [*base-dir* "test" ; *config* (get-config)] ; (is (= "hello" (:template-dir *config*))))) (deftest* -config-test ; get compiler's config which is customized by `-config` (is (= "hello" (:message (get-config))))) (deftest* -compile-test (let [in (template-file "foo.txt") out (public-file "foo.txt")] ; call `-compile` to test your compling (is (test-compile in)) (is (= "hello world" (str/trim (slurp out)))) (.delete out)))
Check misaki.tester to get detailed document.
Another compiler sample†
You can use misaki-clostache and misaki API as reference of developing misaki compiler.