Mercurial > yakumo_izuru > aya
comparison zs.go @ 32:75822e38c3e0 draft
removed funcs, ext and utils
author | zaitsev.serge |
---|---|
date | Wed, 02 Sep 2015 15:00:14 +0000 |
parents | b2f491299cee |
children | e3c902a7380d |
comparison
equal
deleted
inserted
replaced
31:b2f491299cee | 32:75822e38c3e0 |
---|---|
5 "fmt" | 5 "fmt" |
6 "io" | 6 "io" |
7 "io/ioutil" | 7 "io/ioutil" |
8 "log" | 8 "log" |
9 "os" | 9 "os" |
10 "os/exec" | |
10 "path" | 11 "path" |
11 "path/filepath" | 12 "path/filepath" |
12 "strings" | 13 "strings" |
13 "text/template" | 14 "text/template" |
14 "time" | 15 "time" |
22 ZSDIR = ".zs" | 23 ZSDIR = ".zs" |
23 PUBDIR = ".pub" | 24 PUBDIR = ".pub" |
24 ) | 25 ) |
25 | 26 |
26 type Vars map[string]string | 27 type Vars map[string]string |
27 type Funcs template.FuncMap | 28 |
29 func renameExt(path, from, to string) string { | |
30 if from == "" { | |
31 from = filepath.Ext(path) | |
32 } | |
33 if strings.HasSuffix(path, from) { | |
34 return strings.TrimSuffix(path, from) + to | |
35 } else { | |
36 return path | |
37 } | |
38 } | |
39 | |
40 func globals() Vars { | |
41 vars := Vars{} | |
42 for _, e := range os.Environ() { | |
43 pair := strings.Split(e, "=") | |
44 if strings.HasPrefix(pair[0], "ZS_") { | |
45 vars[strings.ToLower(pair[0][3:])] = pair[1] | |
46 } | |
47 } | |
48 return vars | |
49 } | |
50 | |
51 // Converts zs markdown variables into environment variables | |
52 func env(vars Vars) []string { | |
53 env := []string{"ZS=" + os.Args[0], "ZS_OUTDIR=" + PUBDIR} | |
54 env = append(env, os.Environ()...) | |
55 if vars != nil { | |
56 for k, v := range vars { | |
57 env = append(env, "ZS_"+strings.ToUpper(k)+"="+v) | |
58 } | |
59 } | |
60 return env | |
61 } | |
62 | |
63 // Runs command with given arguments and variables, intercepts stderr and | |
64 // redirects stdout into the given writer | |
65 func run(cmd string, args []string, vars Vars, output io.Writer) error { | |
66 var errbuf bytes.Buffer | |
67 c := exec.Command(cmd, args...) | |
68 c.Env = env(vars) | |
69 c.Stdout = output | |
70 c.Stderr = &errbuf | |
71 | |
72 err := c.Run() | |
73 | |
74 if errbuf.Len() > 0 { | |
75 log.Println("ERROR:", errbuf.String()) | |
76 } | |
77 | |
78 if err != nil { | |
79 return err | |
80 } | |
81 return nil | |
82 } | |
83 | |
84 // Splits a string in exactly two parts by delimiter | |
85 // If no delimiter is found - the second string is be empty | |
86 func split2(s, delim string) (string, string) { | |
87 parts := strings.SplitN(s, delim, 2) | |
88 if len(parts) == 2 { | |
89 return parts[0], parts[1] | |
90 } else { | |
91 return parts[0], "" | |
92 } | |
93 } | |
28 | 94 |
29 // Parses markdown content. Returns parsed header variables and content | 95 // Parses markdown content. Returns parsed header variables and content |
30 func md(path string, globals Vars) (Vars, string, error) { | 96 func md(path string, globals Vars) (Vars, string, error) { |
31 b, err := ioutil.ReadFile(path) | 97 b, err := ioutil.ReadFile(path) |
32 if err != nil { | 98 if err != nil { |
64 } | 130 } |
65 return v, body, nil | 131 return v, body, nil |
66 } | 132 } |
67 | 133 |
68 // Use standard Go templates | 134 // Use standard Go templates |
69 func render(s string, funcs Funcs, vars Vars) (string, error) { | 135 func render(s string, vars Vars) (string, error) { |
70 f := makeFuncs(funcs, vars) | 136 tmpl, err := template.New("").Parse(s) |
71 tmpl, err := template.New("").Funcs(template.FuncMap(f)).Parse(s) | |
72 if err != nil { | 137 if err != nil { |
73 return "", err | 138 return "", err |
74 } | 139 } |
75 out := &bytes.Buffer{} | 140 out := &bytes.Buffer{} |
76 if err := tmpl.Execute(out, vars); err != nil { | 141 if err := tmpl.Execute(out, vars); err != nil { |
78 } | 143 } |
79 return string(out.Bytes()), nil | 144 return string(out.Bytes()), nil |
80 } | 145 } |
81 | 146 |
82 // Renders markdown with the given layout into html expanding all the macros | 147 // Renders markdown with the given layout into html expanding all the macros |
83 func buildMarkdown(path string, w io.Writer, funcs Funcs, vars Vars) error { | 148 func buildMarkdown(path string, w io.Writer, vars Vars) error { |
84 v, body, err := md(path, vars) | 149 v, body, err := md(path, vars) |
85 if err != nil { | 150 if err != nil { |
86 return err | 151 return err |
87 } | 152 } |
88 content, err := render(body, funcs, v) | 153 content, err := render(body, v) |
89 if err != nil { | 154 if err != nil { |
90 return err | 155 return err |
91 } | 156 } |
92 v["content"] = string(blackfriday.MarkdownCommon([]byte(content))) | 157 v["content"] = string(blackfriday.MarkdownCommon([]byte(content))) |
93 if w == nil { | 158 if w == nil { |
97 } | 162 } |
98 defer out.Close() | 163 defer out.Close() |
99 w = out | 164 w = out |
100 } | 165 } |
101 if strings.HasSuffix(v["layout"], ".amber") { | 166 if strings.HasSuffix(v["layout"], ".amber") { |
102 return buildAmber(filepath.Join(ZSDIR, v["layout"]), w, funcs, v) | 167 return buildAmber(filepath.Join(ZSDIR, v["layout"]), w, v) |
103 } else { | 168 } else { |
104 return buildHTML(filepath.Join(ZSDIR, v["layout"]), w, funcs, v) | 169 return buildHTML(filepath.Join(ZSDIR, v["layout"]), w, v) |
105 } | 170 } |
106 } | 171 } |
107 | 172 |
108 // Renders text file expanding all variable macros inside it | 173 // Renders text file expanding all variable macros inside it |
109 func buildHTML(path string, w io.Writer, funcs Funcs, vars Vars) error { | 174 func buildHTML(path string, w io.Writer, vars Vars) error { |
110 b, err := ioutil.ReadFile(path) | 175 b, err := ioutil.ReadFile(path) |
111 if err != nil { | 176 if err != nil { |
112 return err | 177 return err |
113 } | 178 } |
114 content, err := render(string(b), funcs, vars) | 179 content, err := render(string(b), vars) |
115 if err != nil { | 180 if err != nil { |
116 return err | 181 return err |
117 } | 182 } |
118 if w == nil { | 183 if w == nil { |
119 f, err := os.Create(filepath.Join(PUBDIR, path)) | 184 f, err := os.Create(filepath.Join(PUBDIR, path)) |
126 _, err = io.WriteString(w, content) | 191 _, err = io.WriteString(w, content) |
127 return err | 192 return err |
128 } | 193 } |
129 | 194 |
130 // Renders .amber file into .html | 195 // Renders .amber file into .html |
131 func buildAmber(path string, w io.Writer, funcs Funcs, vars Vars) error { | 196 func buildAmber(path string, w io.Writer, vars Vars) error { |
132 a := amber.New() | 197 a := amber.New() |
133 err := a.ParseFile(path) | 198 err := a.ParseFile(path) |
134 if err != nil { | 199 if err != nil { |
135 return err | 200 return err |
136 } | 201 } |
137 | 202 |
138 data := map[string]interface{}{} | 203 data := map[string]interface{}{} |
139 for k, v := range vars { | 204 for k, v := range vars { |
140 data[k] = v | 205 data[k] = v |
141 } | 206 } |
142 for k, v := range makeFuncs(funcs, Vars{}) { | |
143 data[k] = v | |
144 } | |
145 | 207 |
146 t, err := a.Compile() | 208 t, err := a.Compile() |
147 if err != nil { | 209 if err != nil { |
148 return err | 210 return err |
149 } | 211 } |
196 } | 258 } |
197 _, err = io.Copy(w, in) | 259 _, err = io.Copy(w, in) |
198 return err | 260 return err |
199 } | 261 } |
200 | 262 |
201 func build(path string, w io.Writer, funcs Funcs, vars Vars) error { | 263 func build(path string, w io.Writer, vars Vars) error { |
202 ext := filepath.Ext(path) | 264 ext := filepath.Ext(path) |
203 if ext == ".md" || ext == ".mkd" { | 265 if ext == ".md" || ext == ".mkd" { |
204 return buildMarkdown(path, w, funcs, vars) | 266 return buildMarkdown(path, w, vars) |
205 } else if ext == ".html" || ext == ".xml" { | 267 } else if ext == ".html" || ext == ".xml" { |
206 return buildHTML(path, w, funcs, vars) | 268 return buildHTML(path, w, vars) |
207 } else if ext == ".amber" { | 269 } else if ext == ".amber" { |
208 return buildAmber(path, w, funcs, vars) | 270 return buildAmber(path, w, vars) |
209 } else if ext == ".gcss" { | 271 } else if ext == ".gcss" { |
210 return buildGCSS(path, w) | 272 return buildGCSS(path, w) |
211 } else { | 273 } else { |
212 return buildRaw(path, w) | 274 return buildRaw(path, w) |
213 } | 275 } |
218 modified := false | 280 modified := false |
219 | 281 |
220 vars := globals() | 282 vars := globals() |
221 for { | 283 for { |
222 os.Mkdir(PUBDIR, 0755) | 284 os.Mkdir(PUBDIR, 0755) |
223 funcs := builtins() | |
224 err := filepath.Walk(".", func(path string, info os.FileInfo, err error) error { | 285 err := filepath.Walk(".", func(path string, info os.FileInfo, err error) error { |
225 // ignore hidden files and directories | 286 // ignore hidden files and directories |
226 if filepath.Base(path)[0] == '.' || strings.HasPrefix(path, ".") { | 287 if filepath.Base(path)[0] == '.' || strings.HasPrefix(path, ".") { |
227 return nil | 288 return nil |
228 } | 289 } |
241 // FIXME on windows it might not work well | 302 // FIXME on windows it might not work well |
242 run(filepath.Join(ZSDIR, "pre"), []string{}, nil, nil) | 303 run(filepath.Join(ZSDIR, "pre"), []string{}, nil, nil) |
243 modified = true | 304 modified = true |
244 } | 305 } |
245 log.Println("build: ", path) | 306 log.Println("build: ", path) |
246 return build(path, nil, funcs, vars) | 307 return build(path, nil, vars) |
247 } | 308 } |
248 return nil | 309 return nil |
249 }) | 310 }) |
250 if err != nil { | 311 if err != nil { |
251 log.Println("ERROR:", err) | 312 log.Println("ERROR:", err) |
274 switch cmd { | 335 switch cmd { |
275 case "build": | 336 case "build": |
276 if len(args) == 0 { | 337 if len(args) == 0 { |
277 buildAll(false) | 338 buildAll(false) |
278 } else if len(args) == 1 { | 339 } else if len(args) == 1 { |
279 if err := build(args[0], os.Stdout, builtins(), globals()); err != nil { | 340 if err := build(args[0], os.Stdout, globals()); err != nil { |
280 fmt.Println("ERROR: " + err.Error()) | 341 fmt.Println("ERROR: " + err.Error()) |
281 } | 342 } |
282 } else { | 343 } else { |
283 fmt.Println("ERROR: too many arguments") | 344 fmt.Println("ERROR: too many arguments") |
284 } | 345 } |
285 case "watch": | 346 case "watch": |
286 buildAll(true) | 347 buildAll(true) |
287 case "var": | 348 case "var": |
288 fmt.Println(Var(args...)) | 349 if len(args) == 0 { |
289 case "lorem": | 350 fmt.Println("var: filename expected") |
290 fmt.Println(Lorem(args...)) | 351 } else { |
291 case "dateparse": | 352 s := "" |
292 fmt.Println(DateParse(args...)) | 353 if vars, _, err := md(args[0], globals()); err != nil { |
293 case "datefmt": | 354 fmt.Println("var: " + err.Error()) |
294 fmt.Println(DateFmt(args...)) | 355 } else { |
295 case "wc": | 356 if len(args) > 1 { |
296 fmt.Println(WordCount(args...)) | 357 for _, a := range args[1:] { |
297 case "ttr": | 358 s = s + vars[a] + "\n" |
298 fmt.Println(TimeToRead(args...)) | 359 } |
299 case "ls": | 360 } else { |
300 fmt.Println(strings.Join(List(args...), "\n")) | 361 for k, v := range vars { |
301 case "sort": | 362 s = s + k + ":" + v + "\n" |
302 fmt.Println(strings.Join(Sort(args...), "\n")) | 363 } |
303 case "exec": | 364 } |
304 // TODO | 365 } |
366 fmt.Println(strings.TrimSpace(s)) | |
367 } | |
305 default: | 368 default: |
306 err := run(path.Join(ZSDIR, cmd), args, globals(), os.Stdout) | 369 err := run(path.Join(ZSDIR, cmd), args, globals(), os.Stdout) |
307 if err != nil { | 370 if err != nil { |
308 log.Println("ERROR:", err) | 371 log.Println("ERROR:", err) |
309 } | 372 } |