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 }