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.
