Changeset 18 in code
- Timestamp:
- Aug 29, 2015, 3:47:16 PM (10 years ago)
- Location:
- trunk
- Files:
-
- 6 added
- 2 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/zs.go
r16 r18 14 14 "time" 15 15 16 "github.com/eknkc/amber" 16 17 "github.com/russross/blackfriday" 18 "github.com/yosssi/gcss" 17 19 ) 18 20 … … 22 24 ) 23 25 24 type EvalFn func(args []string, vars map[string]string) (string, error) 25 26 type Vars map[string]string 27 28 type EvalFn func(args []string, vars Vars) (string, error) 29 30 // Splits a string in exactly two parts by delimiter 31 // If no delimiter is found - the second string is be empty 26 32 func split2(s, delim string) (string, string) { 27 33 parts := strings.SplitN(s, delim, 2) … … 33 39 } 34 40 35 func md(path, s string) (map[string]string, string) { 41 // Parses markdown content. Returns parsed header variables and content 42 func md(path string) (Vars, string, error) { 43 b, err := ioutil.ReadFile(path) 44 if err != nil { 45 return nil, "", err 46 } 47 s := string(b) 36 48 url := path[:len(path)-len(filepath.Ext(path))] + ".html" 37 v := map[string]string{49 v := Vars{ 38 50 "file": path, 39 51 "url": url, … … 42 54 } 43 55 if strings.Index(s, "\n\n") == -1 { 44 return map[string]string{}, s56 return Vars{}, s, nil 45 57 } 46 58 header, body := split2(s, "\n\n") … … 52 64 v["url"] = v["url"][2:] 53 65 } 54 return v, body 55 } 56 57 func render(s string, vars map[string]string, eval EvalFn) (string, error) {66 return v, body, nil 67 } 68 69 func render(s string, vars Vars, eval EvalFn) (string, error) { 58 70 delim_open := "{{" 59 71 delim_close := "}}" … … 88 100 } 89 101 90 func env(vars map[string]string) []string { 102 // Converts zs markdown variables into environment variables 103 func env(vars Vars) []string { 91 104 env := []string{"ZS=" + os.Args[0], "ZS_OUTDIR=" + PUBDIR} 92 105 env = append(env, os.Environ()...) … … 99 112 } 100 113 101 func run(cmd string, args []string, vars map[string]string, output io.Writer) error { 114 // Runs command with given arguments and variables, intercepts stderr and 115 // redirects stdout into the given writer 116 func run(cmd string, args []string, vars Vars, output io.Writer) error { 102 117 var errbuf bytes.Buffer 103 118 c := exec.Command(cmd, args...) … … 118 133 } 119 134 120 func eval(cmd []string, vars map[string]string) (string, error) {135 func eval(cmd []string, vars Vars) (string, error) { 121 136 outbuf := bytes.NewBuffer(nil) 122 137 err := run(path.Join(ZSDIR, cmd[0]), cmd[1:], vars, outbuf) … … 136 151 137 152 func buildMarkdown(path string) error { 138 b, err := ioutil.ReadFile(path) 139 if err != nil { 140 return err 141 } 142 v, body := md(path, string(b)) 153 v, body, err := md(path) 154 if err != nil { 155 return err 156 } 143 157 content, err := render(body, v, eval) 144 158 if err != nil { … … 149 163 } 150 164 151 func buildPlain(path string, vars map[string]string) error {165 func buildPlain(path string, vars Vars) error { 152 166 b, err := ioutil.ReadFile(path) 153 167 if err != nil { … … 167 181 } 168 182 return nil 183 } 184 185 func buildGCSS(path string) error { 186 f, err := os.Open(path) 187 if err != nil { 188 return err 189 } 190 s := strings.TrimSuffix(path, ".gcss") + ".css" 191 log.Println(s) 192 css, err := os.Create(filepath.Join(PUBDIR, s)) 193 if err != nil { 194 return err 195 } 196 197 defer f.Close() 198 defer css.Close() 199 200 _, err = gcss.Compile(css, f) 201 return err 202 } 203 204 func buildAmber(path string, vars Vars) error { 205 a := amber.New() 206 err := a.ParseFile(path) 207 if err != nil { 208 return err 209 } 210 t, err := a.Compile() 211 if err != nil { 212 return err 213 } 214 //amber.FuncMap = amber.FuncMap 215 s := strings.TrimSuffix(path, ".amber") + ".html" 216 f, err := os.Create(filepath.Join(PUBDIR, s)) 217 if err != nil { 218 return err 219 } 220 defer f.Close() 221 return t.Execute(f, vars) 169 222 } 170 223 … … 203 256 ext := filepath.Ext(path) 204 257 if ext == ".md" || ext == ".mkd" { 205 log.Println("m kd: ", path)258 log.Println("md: ", path) 206 259 return buildMarkdown(path) 207 260 } else if ext == ".html" || ext == ".xml" { 208 return buildPlain(path, map[string]string{}) 261 log.Println("html: ", path) 262 return buildPlain(path, Vars{}) 263 } else if ext == ".amber" { 264 log.Println("html: ", path) 265 return buildAmber(path, Vars{}) 266 } else if ext == ".gcss" { 267 log.Println("css: ", path) 268 return buildGCSS(path) 209 269 } else { 210 270 log.Println("raw: ", path) … … 247 307 return 248 308 } 249 if b, err := ioutil.ReadFile(args[0]); err == nil { 250 vars, _ := md(args[0], string(b)) 309 if vars, _, err := md(args[0]); err == nil { 251 310 if len(args) > 1 { 252 311 for _, a := range args[1:] { … … 262 321 } 263 322 default: 264 err := run(path.Join(ZSDIR, cmd), args, map[string]string{}, os.Stdout)323 err := run(path.Join(ZSDIR, cmd), args, Vars{}, os.Stdout) 265 324 if err != nil { 266 325 log.Println(err) -
trunk/zs_test.go
r7 r18 4 4 "bytes" 5 5 "fmt" 6 "io/ioutil" 6 7 "log" 7 8 "os" … … 32 33 } 33 34 35 func tmpfile(path, s string) string { 36 ioutil.WriteFile(path, []byte(s), 0644) 37 return path 38 } 39 34 40 func TestMD(t *testing.T) { 35 v, body := md("foo.md", ` 41 defer os.Remove("foo.md") 42 v, body, _ := md(tmpfile("foo.md", ` 36 43 title: Hello, world! 37 44 keywords: foo, bar, baz … … 39 46 bayan: [:|||:] 40 47 41 this: is a content`) 48 this: is a content`)) 42 49 if v["title"] != "Hello, world!" { 43 50 t.Error() … … 57 64 58 65 // Test empty md 59 v, body = md("foo.md", "")66 v, body, _ = md(tmpfile("foo.md", "")) 60 67 if len(v) != 0 || len(body) != 0 { 61 68 t.Error(v, body) … … 63 70 64 71 // Test empty header 65 v, body = md("foo.md", "Hello")72 v, body, _ = md(tmpfile("foo.md", "Hello")) 66 73 if len(v) != 0 || body != "Hello" { 67 74 t.Error(v, body) … … 70 77 71 78 func TestRender(t *testing.T) { 72 eval := func(a []string, vars map[string]string) (string, error) {79 eval := func(a []string, vars Vars) (string, error) { 73 80 return "hello", nil 74 81 }
Note:
See TracChangeset
for help on using the changeset viewer.