Mercurial > yakumo_izuru > aya
annotate zs.go @ 33:e3c902a7380d draft
rewritten using zs templates, allowing go templates using <% %> delimiters
author | zaitsev.serge |
---|---|
date | Wed, 02 Sep 2015 17:05:09 +0000 |
parents | 75822e38c3e0 |
children | ed40ca93db1e |
rev | line source |
---|---|
0 | 1 package main |
2 | |
3 import ( | |
4 "bytes" | |
5 "fmt" | |
6 "io" | |
7 "io/ioutil" | |
8 "log" | |
9 "os" | |
32 | 10 "os/exec" |
0 | 11 "path/filepath" |
12 "strings" | |
18 | 13 "text/template" |
0 | 14 "time" |
15 | |
22
f5627d4212a3
restored the original amber since my issue has been fixed
zaitsev.serge
parents:
20
diff
changeset
|
16 "github.com/eknkc/amber" |
0 | 17 "github.com/russross/blackfriday" |
17 | 18 "github.com/yosssi/gcss" |
33
e3c902a7380d
rewritten using zs templates, allowing go templates using <% %> delimiters
zaitsev.serge
parents:
32
diff
changeset
|
19 "gopkg.in/yaml.v1" |
0 | 20 ) |
21 | |
22 const ( | |
23 ZSDIR = ".zs" | |
24 PUBDIR = ".pub" | |
25 ) | |
26 | |
17 | 27 type Vars map[string]string |
32 | 28 |
33
e3c902a7380d
rewritten using zs templates, allowing go templates using <% %> delimiters
zaitsev.serge
parents:
32
diff
changeset
|
29 // renameExt renames extension (if any) from oldext to newext |
e3c902a7380d
rewritten using zs templates, allowing go templates using <% %> delimiters
zaitsev.serge
parents:
32
diff
changeset
|
30 // If oldext is an empty string - extension is extracted automatically. |
e3c902a7380d
rewritten using zs templates, allowing go templates using <% %> delimiters
zaitsev.serge
parents:
32
diff
changeset
|
31 // If path has no extension - new extension is appended |
e3c902a7380d
rewritten using zs templates, allowing go templates using <% %> delimiters
zaitsev.serge
parents:
32
diff
changeset
|
32 func renameExt(path, oldext, newext string) string { |
e3c902a7380d
rewritten using zs templates, allowing go templates using <% %> delimiters
zaitsev.serge
parents:
32
diff
changeset
|
33 if oldext == "" { |
e3c902a7380d
rewritten using zs templates, allowing go templates using <% %> delimiters
zaitsev.serge
parents:
32
diff
changeset
|
34 oldext = filepath.Ext(path) |
32 | 35 } |
33
e3c902a7380d
rewritten using zs templates, allowing go templates using <% %> delimiters
zaitsev.serge
parents:
32
diff
changeset
|
36 if oldext == "" || strings.HasSuffix(path, oldext) { |
e3c902a7380d
rewritten using zs templates, allowing go templates using <% %> delimiters
zaitsev.serge
parents:
32
diff
changeset
|
37 return strings.TrimSuffix(path, oldext) + newext |
32 | 38 } else { |
39 return path | |
40 } | |
41 } | |
42 | |
33
e3c902a7380d
rewritten using zs templates, allowing go templates using <% %> delimiters
zaitsev.serge
parents:
32
diff
changeset
|
43 // globals returns list of global OS environment variables that start |
e3c902a7380d
rewritten using zs templates, allowing go templates using <% %> delimiters
zaitsev.serge
parents:
32
diff
changeset
|
44 // with ZS_ prefix as Vars, so the values can be used inside templates |
32 | 45 func globals() Vars { |
46 vars := Vars{} | |
47 for _, e := range os.Environ() { | |
48 pair := strings.Split(e, "=") | |
49 if strings.HasPrefix(pair[0], "ZS_") { | |
50 vars[strings.ToLower(pair[0][3:])] = pair[1] | |
51 } | |
52 } | |
53 return vars | |
54 } | |
55 | |
33
e3c902a7380d
rewritten using zs templates, allowing go templates using <% %> delimiters
zaitsev.serge
parents:
32
diff
changeset
|
56 // run executes a command or a script. Vars define the command environment, |
e3c902a7380d
rewritten using zs templates, allowing go templates using <% %> delimiters
zaitsev.serge
parents:
32
diff
changeset
|
57 // each zs var is converted into OS environemnt variable with ZS_ prefix |
e3c902a7380d
rewritten using zs templates, allowing go templates using <% %> delimiters
zaitsev.serge
parents:
32
diff
changeset
|
58 // prepended. Additional variable $ZS contains path to the zs binary. Command |
e3c902a7380d
rewritten using zs templates, allowing go templates using <% %> delimiters
zaitsev.serge
parents:
32
diff
changeset
|
59 // stderr is printed to zs stderr, command output is returned as a string. |
e3c902a7380d
rewritten using zs templates, allowing go templates using <% %> delimiters
zaitsev.serge
parents:
32
diff
changeset
|
60 func run(vars Vars, cmd string, args ...string) (string, error) { |
e3c902a7380d
rewritten using zs templates, allowing go templates using <% %> delimiters
zaitsev.serge
parents:
32
diff
changeset
|
61 // First check if partial exists (.amber or .html) |
e3c902a7380d
rewritten using zs templates, allowing go templates using <% %> delimiters
zaitsev.serge
parents:
32
diff
changeset
|
62 if b, err := ioutil.ReadFile(filepath.Join(ZSDIR, cmd+".amber")); err == nil { |
e3c902a7380d
rewritten using zs templates, allowing go templates using <% %> delimiters
zaitsev.serge
parents:
32
diff
changeset
|
63 return string(b), nil |
e3c902a7380d
rewritten using zs templates, allowing go templates using <% %> delimiters
zaitsev.serge
parents:
32
diff
changeset
|
64 } |
e3c902a7380d
rewritten using zs templates, allowing go templates using <% %> delimiters
zaitsev.serge
parents:
32
diff
changeset
|
65 if b, err := ioutil.ReadFile(filepath.Join(ZSDIR, cmd+".html")); err == nil { |
e3c902a7380d
rewritten using zs templates, allowing go templates using <% %> delimiters
zaitsev.serge
parents:
32
diff
changeset
|
66 return string(b), nil |
e3c902a7380d
rewritten using zs templates, allowing go templates using <% %> delimiters
zaitsev.serge
parents:
32
diff
changeset
|
67 } |
e3c902a7380d
rewritten using zs templates, allowing go templates using <% %> delimiters
zaitsev.serge
parents:
32
diff
changeset
|
68 |
e3c902a7380d
rewritten using zs templates, allowing go templates using <% %> delimiters
zaitsev.serge
parents:
32
diff
changeset
|
69 var errbuf, outbuf bytes.Buffer |
e3c902a7380d
rewritten using zs templates, allowing go templates using <% %> delimiters
zaitsev.serge
parents:
32
diff
changeset
|
70 c := exec.Command(cmd, args...) |
32 | 71 env := []string{"ZS=" + os.Args[0], "ZS_OUTDIR=" + PUBDIR} |
72 env = append(env, os.Environ()...) | |
33
e3c902a7380d
rewritten using zs templates, allowing go templates using <% %> delimiters
zaitsev.serge
parents:
32
diff
changeset
|
73 for k, v := range vars { |
e3c902a7380d
rewritten using zs templates, allowing go templates using <% %> delimiters
zaitsev.serge
parents:
32
diff
changeset
|
74 env = append(env, "ZS_"+strings.ToUpper(k)+"="+v) |
32 | 75 } |
33
e3c902a7380d
rewritten using zs templates, allowing go templates using <% %> delimiters
zaitsev.serge
parents:
32
diff
changeset
|
76 c.Env = env |
e3c902a7380d
rewritten using zs templates, allowing go templates using <% %> delimiters
zaitsev.serge
parents:
32
diff
changeset
|
77 c.Stdout = &outbuf |
32 | 78 c.Stderr = &errbuf |
79 | |
80 err := c.Run() | |
81 | |
82 if errbuf.Len() > 0 { | |
83 log.Println("ERROR:", errbuf.String()) | |
84 } | |
85 if err != nil { | |
33
e3c902a7380d
rewritten using zs templates, allowing go templates using <% %> delimiters
zaitsev.serge
parents:
32
diff
changeset
|
86 return "", err |
32 | 87 } |
33
e3c902a7380d
rewritten using zs templates, allowing go templates using <% %> delimiters
zaitsev.serge
parents:
32
diff
changeset
|
88 return string(outbuf.Bytes()), nil |
32 | 89 } |
90 | |
33
e3c902a7380d
rewritten using zs templates, allowing go templates using <% %> delimiters
zaitsev.serge
parents:
32
diff
changeset
|
91 // getVars returns list of variables defined in a text file and actual file |
e3c902a7380d
rewritten using zs templates, allowing go templates using <% %> delimiters
zaitsev.serge
parents:
32
diff
changeset
|
92 // content following the variables declaration. Header is separated from |
e3c902a7380d
rewritten using zs templates, allowing go templates using <% %> delimiters
zaitsev.serge
parents:
32
diff
changeset
|
93 // content by an empty line. Header can be either YAML or JSON. |
e3c902a7380d
rewritten using zs templates, allowing go templates using <% %> delimiters
zaitsev.serge
parents:
32
diff
changeset
|
94 // If no empty newline is found - file is treated as content-only. |
e3c902a7380d
rewritten using zs templates, allowing go templates using <% %> delimiters
zaitsev.serge
parents:
32
diff
changeset
|
95 func getVars(path string, globals Vars) (Vars, string, error) { |
17 | 96 b, err := ioutil.ReadFile(path) |
97 if err != nil { | |
98 return nil, "", err | |
99 } | |
100 s := string(b) | |
33
e3c902a7380d
rewritten using zs templates, allowing go templates using <% %> delimiters
zaitsev.serge
parents:
32
diff
changeset
|
101 |
e3c902a7380d
rewritten using zs templates, allowing go templates using <% %> delimiters
zaitsev.serge
parents:
32
diff
changeset
|
102 // Copy globals first |
e3c902a7380d
rewritten using zs templates, allowing go templates using <% %> delimiters
zaitsev.serge
parents:
32
diff
changeset
|
103 v := Vars{} |
29
dd669a7e582f
file, url and output should not be overridden by globals
zaitsev.serge
parents:
28
diff
changeset
|
104 for name, value := range globals { |
dd669a7e582f
file, url and output should not be overridden by globals
zaitsev.serge
parents:
28
diff
changeset
|
105 v[name] = value |
6 | 106 } |
33
e3c902a7380d
rewritten using zs templates, allowing go templates using <% %> delimiters
zaitsev.serge
parents:
32
diff
changeset
|
107 |
e3c902a7380d
rewritten using zs templates, allowing go templates using <% %> delimiters
zaitsev.serge
parents:
32
diff
changeset
|
108 // Override them by default values extracted from file name/path |
20
f8373c23a3ff
replaced amber with my own fork, fixed file paths for amber and html
zaitsev.serge
parents:
19
diff
changeset
|
109 if _, err := os.Stat(filepath.Join(ZSDIR, "layout.amber")); err == nil { |
f8373c23a3ff
replaced amber with my own fork, fixed file paths for amber and html
zaitsev.serge
parents:
19
diff
changeset
|
110 v["layout"] = "layout.amber" |
f8373c23a3ff
replaced amber with my own fork, fixed file paths for amber and html
zaitsev.serge
parents:
19
diff
changeset
|
111 } else { |
f8373c23a3ff
replaced amber with my own fork, fixed file paths for amber and html
zaitsev.serge
parents:
19
diff
changeset
|
112 v["layout"] = "layout.html" |
f8373c23a3ff
replaced amber with my own fork, fixed file paths for amber and html
zaitsev.serge
parents:
19
diff
changeset
|
113 } |
29
dd669a7e582f
file, url and output should not be overridden by globals
zaitsev.serge
parents:
28
diff
changeset
|
114 v["file"] = path |
33
e3c902a7380d
rewritten using zs templates, allowing go templates using <% %> delimiters
zaitsev.serge
parents:
32
diff
changeset
|
115 v["url"] = path[:len(path)-len(filepath.Ext(path))] + ".html" |
e3c902a7380d
rewritten using zs templates, allowing go templates using <% %> delimiters
zaitsev.serge
parents:
32
diff
changeset
|
116 v["output"] = filepath.Join(PUBDIR, v["url"]) |
20
f8373c23a3ff
replaced amber with my own fork, fixed file paths for amber and html
zaitsev.serge
parents:
19
diff
changeset
|
117 |
33
e3c902a7380d
rewritten using zs templates, allowing go templates using <% %> delimiters
zaitsev.serge
parents:
32
diff
changeset
|
118 if sep := strings.Index(s, "\n\n"); sep == -1 { |
19
802b96e67bae
added global variables, added default date for markdown
zaitsev.serge
parents:
18
diff
changeset
|
119 return v, s, nil |
33
e3c902a7380d
rewritten using zs templates, allowing go templates using <% %> delimiters
zaitsev.serge
parents:
32
diff
changeset
|
120 } else { |
e3c902a7380d
rewritten using zs templates, allowing go templates using <% %> delimiters
zaitsev.serge
parents:
32
diff
changeset
|
121 header := s[:sep] |
e3c902a7380d
rewritten using zs templates, allowing go templates using <% %> delimiters
zaitsev.serge
parents:
32
diff
changeset
|
122 body := s[sep+len("\n\n"):] |
e3c902a7380d
rewritten using zs templates, allowing go templates using <% %> delimiters
zaitsev.serge
parents:
32
diff
changeset
|
123 vars := Vars{} |
e3c902a7380d
rewritten using zs templates, allowing go templates using <% %> delimiters
zaitsev.serge
parents:
32
diff
changeset
|
124 if err := yaml.Unmarshal([]byte(header), &vars); err != nil { |
e3c902a7380d
rewritten using zs templates, allowing go templates using <% %> delimiters
zaitsev.serge
parents:
32
diff
changeset
|
125 fmt.Println("ERROR: failed to parse header", err) |
e3c902a7380d
rewritten using zs templates, allowing go templates using <% %> delimiters
zaitsev.serge
parents:
32
diff
changeset
|
126 } else { |
e3c902a7380d
rewritten using zs templates, allowing go templates using <% %> delimiters
zaitsev.serge
parents:
32
diff
changeset
|
127 for key, value := range vars { |
e3c902a7380d
rewritten using zs templates, allowing go templates using <% %> delimiters
zaitsev.serge
parents:
32
diff
changeset
|
128 v[key] = value |
e3c902a7380d
rewritten using zs templates, allowing go templates using <% %> delimiters
zaitsev.serge
parents:
32
diff
changeset
|
129 } |
e3c902a7380d
rewritten using zs templates, allowing go templates using <% %> delimiters
zaitsev.serge
parents:
32
diff
changeset
|
130 } |
e3c902a7380d
rewritten using zs templates, allowing go templates using <% %> delimiters
zaitsev.serge
parents:
32
diff
changeset
|
131 if strings.HasPrefix(v["url"], "./") { |
e3c902a7380d
rewritten using zs templates, allowing go templates using <% %> delimiters
zaitsev.serge
parents:
32
diff
changeset
|
132 v["url"] = v["url"][2:] |
e3c902a7380d
rewritten using zs templates, allowing go templates using <% %> delimiters
zaitsev.serge
parents:
32
diff
changeset
|
133 } |
e3c902a7380d
rewritten using zs templates, allowing go templates using <% %> delimiters
zaitsev.serge
parents:
32
diff
changeset
|
134 return v, body, nil |
2 | 135 } |
0 | 136 } |
137 | |
33
e3c902a7380d
rewritten using zs templates, allowing go templates using <% %> delimiters
zaitsev.serge
parents:
32
diff
changeset
|
138 // Render expanding zs plugins and variables |
32 | 139 func render(s string, vars Vars) (string, error) { |
33
e3c902a7380d
rewritten using zs templates, allowing go templates using <% %> delimiters
zaitsev.serge
parents:
32
diff
changeset
|
140 delim_open := "{{" |
e3c902a7380d
rewritten using zs templates, allowing go templates using <% %> delimiters
zaitsev.serge
parents:
32
diff
changeset
|
141 delim_close := "}}" |
e3c902a7380d
rewritten using zs templates, allowing go templates using <% %> delimiters
zaitsev.serge
parents:
32
diff
changeset
|
142 |
e3c902a7380d
rewritten using zs templates, allowing go templates using <% %> delimiters
zaitsev.serge
parents:
32
diff
changeset
|
143 out := &bytes.Buffer{} |
e3c902a7380d
rewritten using zs templates, allowing go templates using <% %> delimiters
zaitsev.serge
parents:
32
diff
changeset
|
144 for { |
e3c902a7380d
rewritten using zs templates, allowing go templates using <% %> delimiters
zaitsev.serge
parents:
32
diff
changeset
|
145 if from := strings.Index(s, delim_open); from == -1 { |
e3c902a7380d
rewritten using zs templates, allowing go templates using <% %> delimiters
zaitsev.serge
parents:
32
diff
changeset
|
146 out.WriteString(s) |
e3c902a7380d
rewritten using zs templates, allowing go templates using <% %> delimiters
zaitsev.serge
parents:
32
diff
changeset
|
147 return out.String(), nil |
e3c902a7380d
rewritten using zs templates, allowing go templates using <% %> delimiters
zaitsev.serge
parents:
32
diff
changeset
|
148 } else { |
e3c902a7380d
rewritten using zs templates, allowing go templates using <% %> delimiters
zaitsev.serge
parents:
32
diff
changeset
|
149 if to := strings.Index(s, delim_close); to == -1 { |
e3c902a7380d
rewritten using zs templates, allowing go templates using <% %> delimiters
zaitsev.serge
parents:
32
diff
changeset
|
150 return "", fmt.Errorf("Close delim not found") |
e3c902a7380d
rewritten using zs templates, allowing go templates using <% %> delimiters
zaitsev.serge
parents:
32
diff
changeset
|
151 } else { |
e3c902a7380d
rewritten using zs templates, allowing go templates using <% %> delimiters
zaitsev.serge
parents:
32
diff
changeset
|
152 out.WriteString(s[:from]) |
e3c902a7380d
rewritten using zs templates, allowing go templates using <% %> delimiters
zaitsev.serge
parents:
32
diff
changeset
|
153 cmd := s[from+len(delim_open) : to] |
e3c902a7380d
rewritten using zs templates, allowing go templates using <% %> delimiters
zaitsev.serge
parents:
32
diff
changeset
|
154 s = s[to+len(delim_close):] |
e3c902a7380d
rewritten using zs templates, allowing go templates using <% %> delimiters
zaitsev.serge
parents:
32
diff
changeset
|
155 m := strings.Fields(cmd) |
e3c902a7380d
rewritten using zs templates, allowing go templates using <% %> delimiters
zaitsev.serge
parents:
32
diff
changeset
|
156 if len(m) == 1 { |
e3c902a7380d
rewritten using zs templates, allowing go templates using <% %> delimiters
zaitsev.serge
parents:
32
diff
changeset
|
157 if v, ok := vars[m[0]]; ok { |
e3c902a7380d
rewritten using zs templates, allowing go templates using <% %> delimiters
zaitsev.serge
parents:
32
diff
changeset
|
158 out.WriteString(v) |
e3c902a7380d
rewritten using zs templates, allowing go templates using <% %> delimiters
zaitsev.serge
parents:
32
diff
changeset
|
159 continue |
e3c902a7380d
rewritten using zs templates, allowing go templates using <% %> delimiters
zaitsev.serge
parents:
32
diff
changeset
|
160 } |
e3c902a7380d
rewritten using zs templates, allowing go templates using <% %> delimiters
zaitsev.serge
parents:
32
diff
changeset
|
161 } |
e3c902a7380d
rewritten using zs templates, allowing go templates using <% %> delimiters
zaitsev.serge
parents:
32
diff
changeset
|
162 if res, err := run(vars, m[0], m[1:]...); err == nil { |
e3c902a7380d
rewritten using zs templates, allowing go templates using <% %> delimiters
zaitsev.serge
parents:
32
diff
changeset
|
163 out.WriteString(res) |
e3c902a7380d
rewritten using zs templates, allowing go templates using <% %> delimiters
zaitsev.serge
parents:
32
diff
changeset
|
164 } else { |
e3c902a7380d
rewritten using zs templates, allowing go templates using <% %> delimiters
zaitsev.serge
parents:
32
diff
changeset
|
165 fmt.Println(err) |
e3c902a7380d
rewritten using zs templates, allowing go templates using <% %> delimiters
zaitsev.serge
parents:
32
diff
changeset
|
166 } |
e3c902a7380d
rewritten using zs templates, allowing go templates using <% %> delimiters
zaitsev.serge
parents:
32
diff
changeset
|
167 } |
e3c902a7380d
rewritten using zs templates, allowing go templates using <% %> delimiters
zaitsev.serge
parents:
32
diff
changeset
|
168 } |
18 | 169 } |
33
e3c902a7380d
rewritten using zs templates, allowing go templates using <% %> delimiters
zaitsev.serge
parents:
32
diff
changeset
|
170 return s, nil |
0 | 171 } |
172 | |
18 | 173 // Renders markdown with the given layout into html expanding all the macros |
32 | 174 func buildMarkdown(path string, w io.Writer, vars Vars) error { |
33
e3c902a7380d
rewritten using zs templates, allowing go templates using <% %> delimiters
zaitsev.serge
parents:
32
diff
changeset
|
175 v, body, err := getVars(path, vars) |
0 | 176 if err != nil { |
177 return err | |
178 } | |
32 | 179 content, err := render(body, v) |
0 | 180 if err != nil { |
181 return err | |
182 } | |
31 | 183 v["content"] = string(blackfriday.MarkdownCommon([]byte(content))) |
23
40f55059fbfa
fixed output file names in html pages, fixed amber function bindings, replaced print command with build, fixed plugin functions, implemented zs and exec functions
zaitsev.serge
parents:
22
diff
changeset
|
184 if w == nil { |
40f55059fbfa
fixed output file names in html pages, fixed amber function bindings, replaced print command with build, fixed plugin functions, implemented zs and exec functions
zaitsev.serge
parents:
22
diff
changeset
|
185 out, err := os.Create(filepath.Join(PUBDIR, renameExt(path, "", ".html"))) |
40f55059fbfa
fixed output file names in html pages, fixed amber function bindings, replaced print command with build, fixed plugin functions, implemented zs and exec functions
zaitsev.serge
parents:
22
diff
changeset
|
186 if err != nil { |
40f55059fbfa
fixed output file names in html pages, fixed amber function bindings, replaced print command with build, fixed plugin functions, implemented zs and exec functions
zaitsev.serge
parents:
22
diff
changeset
|
187 return err |
40f55059fbfa
fixed output file names in html pages, fixed amber function bindings, replaced print command with build, fixed plugin functions, implemented zs and exec functions
zaitsev.serge
parents:
22
diff
changeset
|
188 } |
40f55059fbfa
fixed output file names in html pages, fixed amber function bindings, replaced print command with build, fixed plugin functions, implemented zs and exec functions
zaitsev.serge
parents:
22
diff
changeset
|
189 defer out.Close() |
40f55059fbfa
fixed output file names in html pages, fixed amber function bindings, replaced print command with build, fixed plugin functions, implemented zs and exec functions
zaitsev.serge
parents:
22
diff
changeset
|
190 w = out |
40f55059fbfa
fixed output file names in html pages, fixed amber function bindings, replaced print command with build, fixed plugin functions, implemented zs and exec functions
zaitsev.serge
parents:
22
diff
changeset
|
191 } |
18 | 192 if strings.HasSuffix(v["layout"], ".amber") { |
32 | 193 return buildAmber(filepath.Join(ZSDIR, v["layout"]), w, v) |
18 | 194 } else { |
32 | 195 return buildHTML(filepath.Join(ZSDIR, v["layout"]), w, v) |
18 | 196 } |
14 | 197 } |
198 | |
18 | 199 // Renders text file expanding all variable macros inside it |
32 | 200 func buildHTML(path string, w io.Writer, vars Vars) error { |
33
e3c902a7380d
rewritten using zs templates, allowing go templates using <% %> delimiters
zaitsev.serge
parents:
32
diff
changeset
|
201 v, body, err := getVars(path, vars) |
0 | 202 if err != nil { |
203 return err | |
204 } | |
33
e3c902a7380d
rewritten using zs templates, allowing go templates using <% %> delimiters
zaitsev.serge
parents:
32
diff
changeset
|
205 if body, err = render(body, v); err != nil { |
e3c902a7380d
rewritten using zs templates, allowing go templates using <% %> delimiters
zaitsev.serge
parents:
32
diff
changeset
|
206 return err |
e3c902a7380d
rewritten using zs templates, allowing go templates using <% %> delimiters
zaitsev.serge
parents:
32
diff
changeset
|
207 } |
e3c902a7380d
rewritten using zs templates, allowing go templates using <% %> delimiters
zaitsev.serge
parents:
32
diff
changeset
|
208 tmpl, err := template.New("").Delims("<%", "%>").Parse(body) |
0 | 209 if err != nil { |
210 return err | |
211 } | |
24
d052f3a44195
fixed output file names in html pages, fixed amber function bindings, replaced print command with build, fixed plugin functions, implemented zs and exec functions
zaitsev.serge
parents:
23
diff
changeset
|
212 if w == nil { |
d052f3a44195
fixed output file names in html pages, fixed amber function bindings, replaced print command with build, fixed plugin functions, implemented zs and exec functions
zaitsev.serge
parents:
23
diff
changeset
|
213 f, err := os.Create(filepath.Join(PUBDIR, path)) |
d052f3a44195
fixed output file names in html pages, fixed amber function bindings, replaced print command with build, fixed plugin functions, implemented zs and exec functions
zaitsev.serge
parents:
23
diff
changeset
|
214 if err != nil { |
d052f3a44195
fixed output file names in html pages, fixed amber function bindings, replaced print command with build, fixed plugin functions, implemented zs and exec functions
zaitsev.serge
parents:
23
diff
changeset
|
215 return err |
d052f3a44195
fixed output file names in html pages, fixed amber function bindings, replaced print command with build, fixed plugin functions, implemented zs and exec functions
zaitsev.serge
parents:
23
diff
changeset
|
216 } |
d052f3a44195
fixed output file names in html pages, fixed amber function bindings, replaced print command with build, fixed plugin functions, implemented zs and exec functions
zaitsev.serge
parents:
23
diff
changeset
|
217 defer f.Close() |
d052f3a44195
fixed output file names in html pages, fixed amber function bindings, replaced print command with build, fixed plugin functions, implemented zs and exec functions
zaitsev.serge
parents:
23
diff
changeset
|
218 w = f |
14 | 219 } |
33
e3c902a7380d
rewritten using zs templates, allowing go templates using <% %> delimiters
zaitsev.serge
parents:
32
diff
changeset
|
220 return tmpl.Execute(w, vars) |
0 | 221 } |
222 | |
18 | 223 // Renders .amber file into .html |
32 | 224 func buildAmber(path string, w io.Writer, vars Vars) error { |
33
e3c902a7380d
rewritten using zs templates, allowing go templates using <% %> delimiters
zaitsev.serge
parents:
32
diff
changeset
|
225 v, body, err := getVars(path, vars) |
17 | 226 if err != nil { |
227 return err | |
228 } | |
33
e3c902a7380d
rewritten using zs templates, allowing go templates using <% %> delimiters
zaitsev.serge
parents:
32
diff
changeset
|
229 if body, err = render(body, v); err != nil { |
e3c902a7380d
rewritten using zs templates, allowing go templates using <% %> delimiters
zaitsev.serge
parents:
32
diff
changeset
|
230 return err |
e3c902a7380d
rewritten using zs templates, allowing go templates using <% %> delimiters
zaitsev.serge
parents:
32
diff
changeset
|
231 } |
24
d052f3a44195
fixed output file names in html pages, fixed amber function bindings, replaced print command with build, fixed plugin functions, implemented zs and exec functions
zaitsev.serge
parents:
23
diff
changeset
|
232 |
33
e3c902a7380d
rewritten using zs templates, allowing go templates using <% %> delimiters
zaitsev.serge
parents:
32
diff
changeset
|
233 a := amber.New() |
e3c902a7380d
rewritten using zs templates, allowing go templates using <% %> delimiters
zaitsev.serge
parents:
32
diff
changeset
|
234 if err := a.Parse(body); err != nil { |
e3c902a7380d
rewritten using zs templates, allowing go templates using <% %> delimiters
zaitsev.serge
parents:
32
diff
changeset
|
235 return err |
24
d052f3a44195
fixed output file names in html pages, fixed amber function bindings, replaced print command with build, fixed plugin functions, implemented zs and exec functions
zaitsev.serge
parents:
23
diff
changeset
|
236 } |
d052f3a44195
fixed output file names in html pages, fixed amber function bindings, replaced print command with build, fixed plugin functions, implemented zs and exec functions
zaitsev.serge
parents:
23
diff
changeset
|
237 |
17 | 238 t, err := a.Compile() |
239 if err != nil { | |
240 return err | |
241 } | |
23
40f55059fbfa
fixed output file names in html pages, fixed amber function bindings, replaced print command with build, fixed plugin functions, implemented zs and exec functions
zaitsev.serge
parents:
22
diff
changeset
|
242 if w == nil { |
40f55059fbfa
fixed output file names in html pages, fixed amber function bindings, replaced print command with build, fixed plugin functions, implemented zs and exec functions
zaitsev.serge
parents:
22
diff
changeset
|
243 f, err := os.Create(filepath.Join(PUBDIR, renameExt(path, ".amber", ".html"))) |
40f55059fbfa
fixed output file names in html pages, fixed amber function bindings, replaced print command with build, fixed plugin functions, implemented zs and exec functions
zaitsev.serge
parents:
22
diff
changeset
|
244 if err != nil { |
40f55059fbfa
fixed output file names in html pages, fixed amber function bindings, replaced print command with build, fixed plugin functions, implemented zs and exec functions
zaitsev.serge
parents:
22
diff
changeset
|
245 return err |
40f55059fbfa
fixed output file names in html pages, fixed amber function bindings, replaced print command with build, fixed plugin functions, implemented zs and exec functions
zaitsev.serge
parents:
22
diff
changeset
|
246 } |
40f55059fbfa
fixed output file names in html pages, fixed amber function bindings, replaced print command with build, fixed plugin functions, implemented zs and exec functions
zaitsev.serge
parents:
22
diff
changeset
|
247 defer f.Close() |
40f55059fbfa
fixed output file names in html pages, fixed amber function bindings, replaced print command with build, fixed plugin functions, implemented zs and exec functions
zaitsev.serge
parents:
22
diff
changeset
|
248 w = f |
17 | 249 } |
33
e3c902a7380d
rewritten using zs templates, allowing go templates using <% %> delimiters
zaitsev.serge
parents:
32
diff
changeset
|
250 return t.Execute(w, vars) |
17 | 251 } |
252 | |
18 | 253 // Compiles .gcss into .css |
23
40f55059fbfa
fixed output file names in html pages, fixed amber function bindings, replaced print command with build, fixed plugin functions, implemented zs and exec functions
zaitsev.serge
parents:
22
diff
changeset
|
254 func buildGCSS(path string, w io.Writer) error { |
18 | 255 f, err := os.Open(path) |
256 if err != nil { | |
257 return err | |
258 } | |
23
40f55059fbfa
fixed output file names in html pages, fixed amber function bindings, replaced print command with build, fixed plugin functions, implemented zs and exec functions
zaitsev.serge
parents:
22
diff
changeset
|
259 defer f.Close() |
40f55059fbfa
fixed output file names in html pages, fixed amber function bindings, replaced print command with build, fixed plugin functions, implemented zs and exec functions
zaitsev.serge
parents:
22
diff
changeset
|
260 |
40f55059fbfa
fixed output file names in html pages, fixed amber function bindings, replaced print command with build, fixed plugin functions, implemented zs and exec functions
zaitsev.serge
parents:
22
diff
changeset
|
261 if w == nil { |
40f55059fbfa
fixed output file names in html pages, fixed amber function bindings, replaced print command with build, fixed plugin functions, implemented zs and exec functions
zaitsev.serge
parents:
22
diff
changeset
|
262 s := strings.TrimSuffix(path, ".gcss") + ".css" |
40f55059fbfa
fixed output file names in html pages, fixed amber function bindings, replaced print command with build, fixed plugin functions, implemented zs and exec functions
zaitsev.serge
parents:
22
diff
changeset
|
263 css, err := os.Create(filepath.Join(PUBDIR, s)) |
40f55059fbfa
fixed output file names in html pages, fixed amber function bindings, replaced print command with build, fixed plugin functions, implemented zs and exec functions
zaitsev.serge
parents:
22
diff
changeset
|
264 if err != nil { |
40f55059fbfa
fixed output file names in html pages, fixed amber function bindings, replaced print command with build, fixed plugin functions, implemented zs and exec functions
zaitsev.serge
parents:
22
diff
changeset
|
265 return err |
40f55059fbfa
fixed output file names in html pages, fixed amber function bindings, replaced print command with build, fixed plugin functions, implemented zs and exec functions
zaitsev.serge
parents:
22
diff
changeset
|
266 } |
40f55059fbfa
fixed output file names in html pages, fixed amber function bindings, replaced print command with build, fixed plugin functions, implemented zs and exec functions
zaitsev.serge
parents:
22
diff
changeset
|
267 defer css.Close() |
40f55059fbfa
fixed output file names in html pages, fixed amber function bindings, replaced print command with build, fixed plugin functions, implemented zs and exec functions
zaitsev.serge
parents:
22
diff
changeset
|
268 w = css |
18 | 269 } |
23
40f55059fbfa
fixed output file names in html pages, fixed amber function bindings, replaced print command with build, fixed plugin functions, implemented zs and exec functions
zaitsev.serge
parents:
22
diff
changeset
|
270 _, err = gcss.Compile(w, f) |
18 | 271 return err |
272 } | |
273 | |
23
40f55059fbfa
fixed output file names in html pages, fixed amber function bindings, replaced print command with build, fixed plugin functions, implemented zs and exec functions
zaitsev.serge
parents:
22
diff
changeset
|
274 // Copies file as is from path to writer |
40f55059fbfa
fixed output file names in html pages, fixed amber function bindings, replaced print command with build, fixed plugin functions, implemented zs and exec functions
zaitsev.serge
parents:
22
diff
changeset
|
275 func buildRaw(path string, w io.Writer) error { |
40f55059fbfa
fixed output file names in html pages, fixed amber function bindings, replaced print command with build, fixed plugin functions, implemented zs and exec functions
zaitsev.serge
parents:
22
diff
changeset
|
276 in, err := os.Open(path) |
40f55059fbfa
fixed output file names in html pages, fixed amber function bindings, replaced print command with build, fixed plugin functions, implemented zs and exec functions
zaitsev.serge
parents:
22
diff
changeset
|
277 if err != nil { |
40f55059fbfa
fixed output file names in html pages, fixed amber function bindings, replaced print command with build, fixed plugin functions, implemented zs and exec functions
zaitsev.serge
parents:
22
diff
changeset
|
278 return err |
40f55059fbfa
fixed output file names in html pages, fixed amber function bindings, replaced print command with build, fixed plugin functions, implemented zs and exec functions
zaitsev.serge
parents:
22
diff
changeset
|
279 } |
40f55059fbfa
fixed output file names in html pages, fixed amber function bindings, replaced print command with build, fixed plugin functions, implemented zs and exec functions
zaitsev.serge
parents:
22
diff
changeset
|
280 defer in.Close() |
40f55059fbfa
fixed output file names in html pages, fixed amber function bindings, replaced print command with build, fixed plugin functions, implemented zs and exec functions
zaitsev.serge
parents:
22
diff
changeset
|
281 if w == nil { |
40f55059fbfa
fixed output file names in html pages, fixed amber function bindings, replaced print command with build, fixed plugin functions, implemented zs and exec functions
zaitsev.serge
parents:
22
diff
changeset
|
282 if out, err := os.Create(filepath.Join(PUBDIR, path)); err != nil { |
40f55059fbfa
fixed output file names in html pages, fixed amber function bindings, replaced print command with build, fixed plugin functions, implemented zs and exec functions
zaitsev.serge
parents:
22
diff
changeset
|
283 return err |
40f55059fbfa
fixed output file names in html pages, fixed amber function bindings, replaced print command with build, fixed plugin functions, implemented zs and exec functions
zaitsev.serge
parents:
22
diff
changeset
|
284 } else { |
0 | 285 defer out.Close() |
23
40f55059fbfa
fixed output file names in html pages, fixed amber function bindings, replaced print command with build, fixed plugin functions, implemented zs and exec functions
zaitsev.serge
parents:
22
diff
changeset
|
286 w = out |
0 | 287 } |
288 } | |
23
40f55059fbfa
fixed output file names in html pages, fixed amber function bindings, replaced print command with build, fixed plugin functions, implemented zs and exec functions
zaitsev.serge
parents:
22
diff
changeset
|
289 _, err = io.Copy(w, in) |
7
11073a30f71f
simplified build process, added pre and post build hooks
zaitsev.serge
parents:
6
diff
changeset
|
290 return err |
0 | 291 } |
292 | |
32 | 293 func build(path string, w io.Writer, vars Vars) error { |
23
40f55059fbfa
fixed output file names in html pages, fixed amber function bindings, replaced print command with build, fixed plugin functions, implemented zs and exec functions
zaitsev.serge
parents:
22
diff
changeset
|
294 ext := filepath.Ext(path) |
40f55059fbfa
fixed output file names in html pages, fixed amber function bindings, replaced print command with build, fixed plugin functions, implemented zs and exec functions
zaitsev.serge
parents:
22
diff
changeset
|
295 if ext == ".md" || ext == ".mkd" { |
32 | 296 return buildMarkdown(path, w, vars) |
23
40f55059fbfa
fixed output file names in html pages, fixed amber function bindings, replaced print command with build, fixed plugin functions, implemented zs and exec functions
zaitsev.serge
parents:
22
diff
changeset
|
297 } else if ext == ".html" || ext == ".xml" { |
32 | 298 return buildHTML(path, w, vars) |
23
40f55059fbfa
fixed output file names in html pages, fixed amber function bindings, replaced print command with build, fixed plugin functions, implemented zs and exec functions
zaitsev.serge
parents:
22
diff
changeset
|
299 } else if ext == ".amber" { |
32 | 300 return buildAmber(path, w, vars) |
23
40f55059fbfa
fixed output file names in html pages, fixed amber function bindings, replaced print command with build, fixed plugin functions, implemented zs and exec functions
zaitsev.serge
parents:
22
diff
changeset
|
301 } else if ext == ".gcss" { |
40f55059fbfa
fixed output file names in html pages, fixed amber function bindings, replaced print command with build, fixed plugin functions, implemented zs and exec functions
zaitsev.serge
parents:
22
diff
changeset
|
302 return buildGCSS(path, w) |
40f55059fbfa
fixed output file names in html pages, fixed amber function bindings, replaced print command with build, fixed plugin functions, implemented zs and exec functions
zaitsev.serge
parents:
22
diff
changeset
|
303 } else { |
40f55059fbfa
fixed output file names in html pages, fixed amber function bindings, replaced print command with build, fixed plugin functions, implemented zs and exec functions
zaitsev.serge
parents:
22
diff
changeset
|
304 return buildRaw(path, w) |
18 | 305 } |
306 } | |
307 | |
23
40f55059fbfa
fixed output file names in html pages, fixed amber function bindings, replaced print command with build, fixed plugin functions, implemented zs and exec functions
zaitsev.serge
parents:
22
diff
changeset
|
308 func buildAll(watch bool) { |
0 | 309 lastModified := time.Unix(0, 0) |
7
11073a30f71f
simplified build process, added pre and post build hooks
zaitsev.serge
parents:
6
diff
changeset
|
310 modified := false |
19
802b96e67bae
added global variables, added default date for markdown
zaitsev.serge
parents:
18
diff
changeset
|
311 |
802b96e67bae
added global variables, added default date for markdown
zaitsev.serge
parents:
18
diff
changeset
|
312 vars := globals() |
0 | 313 for { |
314 os.Mkdir(PUBDIR, 0755) | |
315 err := filepath.Walk(".", func(path string, info os.FileInfo, err error) error { | |
316 // ignore hidden files and directories | |
317 if filepath.Base(path)[0] == '.' || strings.HasPrefix(path, ".") { | |
318 return nil | |
319 } | |
30 | 320 // inform user about fs walk errors, but continue iteration |
321 if err != nil { | |
322 log.Println("ERROR:", err) | |
323 return nil | |
324 } | |
0 | 325 |
7
11073a30f71f
simplified build process, added pre and post build hooks
zaitsev.serge
parents:
6
diff
changeset
|
326 if info.IsDir() { |
11073a30f71f
simplified build process, added pre and post build hooks
zaitsev.serge
parents:
6
diff
changeset
|
327 os.Mkdir(filepath.Join(PUBDIR, path), 0755) |
11073a30f71f
simplified build process, added pre and post build hooks
zaitsev.serge
parents:
6
diff
changeset
|
328 return nil |
11073a30f71f
simplified build process, added pre and post build hooks
zaitsev.serge
parents:
6
diff
changeset
|
329 } else if info.ModTime().After(lastModified) { |
11073a30f71f
simplified build process, added pre and post build hooks
zaitsev.serge
parents:
6
diff
changeset
|
330 if !modified { |
33
e3c902a7380d
rewritten using zs templates, allowing go templates using <% %> delimiters
zaitsev.serge
parents:
32
diff
changeset
|
331 // First file in this build cycle is about to be modified |
e3c902a7380d
rewritten using zs templates, allowing go templates using <% %> delimiters
zaitsev.serge
parents:
32
diff
changeset
|
332 run(vars, "prehook") |
7
11073a30f71f
simplified build process, added pre and post build hooks
zaitsev.serge
parents:
6
diff
changeset
|
333 modified = true |
11073a30f71f
simplified build process, added pre and post build hooks
zaitsev.serge
parents:
6
diff
changeset
|
334 } |
33
e3c902a7380d
rewritten using zs templates, allowing go templates using <% %> delimiters
zaitsev.serge
parents:
32
diff
changeset
|
335 log.Println("build:", path) |
32 | 336 return build(path, nil, vars) |
0 | 337 } |
338 return nil | |
339 }) | |
340 if err != nil { | |
341 log.Println("ERROR:", err) | |
342 } | |
7
11073a30f71f
simplified build process, added pre and post build hooks
zaitsev.serge
parents:
6
diff
changeset
|
343 if modified { |
33
e3c902a7380d
rewritten using zs templates, allowing go templates using <% %> delimiters
zaitsev.serge
parents:
32
diff
changeset
|
344 // At least one file in this build cycle has been modified |
e3c902a7380d
rewritten using zs templates, allowing go templates using <% %> delimiters
zaitsev.serge
parents:
32
diff
changeset
|
345 run(vars, "posthook") |
7
11073a30f71f
simplified build process, added pre and post build hooks
zaitsev.serge
parents:
6
diff
changeset
|
346 modified = false |
11073a30f71f
simplified build process, added pre and post build hooks
zaitsev.serge
parents:
6
diff
changeset
|
347 } |
23
40f55059fbfa
fixed output file names in html pages, fixed amber function bindings, replaced print command with build, fixed plugin functions, implemented zs and exec functions
zaitsev.serge
parents:
22
diff
changeset
|
348 if !watch { |
0 | 349 break |
350 } | |
23
40f55059fbfa
fixed output file names in html pages, fixed amber function bindings, replaced print command with build, fixed plugin functions, implemented zs and exec functions
zaitsev.serge
parents:
22
diff
changeset
|
351 lastModified = time.Now() |
0 | 352 time.Sleep(1 * time.Second) |
353 } | |
354 } | |
355 | |
33
e3c902a7380d
rewritten using zs templates, allowing go templates using <% %> delimiters
zaitsev.serge
parents:
32
diff
changeset
|
356 func init() { |
e3c902a7380d
rewritten using zs templates, allowing go templates using <% %> delimiters
zaitsev.serge
parents:
32
diff
changeset
|
357 // prepend .zs to $PATH, so plugins will be found before OS commands |
e3c902a7380d
rewritten using zs templates, allowing go templates using <% %> delimiters
zaitsev.serge
parents:
32
diff
changeset
|
358 p := os.Getenv("PATH") |
e3c902a7380d
rewritten using zs templates, allowing go templates using <% %> delimiters
zaitsev.serge
parents:
32
diff
changeset
|
359 p = ZSDIR + ":" + p |
e3c902a7380d
rewritten using zs templates, allowing go templates using <% %> delimiters
zaitsev.serge
parents:
32
diff
changeset
|
360 os.Setenv("PATH", p) |
e3c902a7380d
rewritten using zs templates, allowing go templates using <% %> delimiters
zaitsev.serge
parents:
32
diff
changeset
|
361 } |
e3c902a7380d
rewritten using zs templates, allowing go templates using <% %> delimiters
zaitsev.serge
parents:
32
diff
changeset
|
362 |
0 | 363 func main() { |
364 if len(os.Args) == 1 { | |
365 fmt.Println(os.Args[0], "<command> [args]") | |
366 return | |
367 } | |
368 cmd := os.Args[1] | |
369 args := os.Args[2:] | |
370 switch cmd { | |
371 case "build": | |
24
d052f3a44195
fixed output file names in html pages, fixed amber function bindings, replaced print command with build, fixed plugin functions, implemented zs and exec functions
zaitsev.serge
parents:
23
diff
changeset
|
372 if len(args) == 0 { |
d052f3a44195
fixed output file names in html pages, fixed amber function bindings, replaced print command with build, fixed plugin functions, implemented zs and exec functions
zaitsev.serge
parents:
23
diff
changeset
|
373 buildAll(false) |
d052f3a44195
fixed output file names in html pages, fixed amber function bindings, replaced print command with build, fixed plugin functions, implemented zs and exec functions
zaitsev.serge
parents:
23
diff
changeset
|
374 } else if len(args) == 1 { |
32 | 375 if err := build(args[0], os.Stdout, globals()); err != nil { |
24
d052f3a44195
fixed output file names in html pages, fixed amber function bindings, replaced print command with build, fixed plugin functions, implemented zs and exec functions
zaitsev.serge
parents:
23
diff
changeset
|
376 fmt.Println("ERROR: " + err.Error()) |
d052f3a44195
fixed output file names in html pages, fixed amber function bindings, replaced print command with build, fixed plugin functions, implemented zs and exec functions
zaitsev.serge
parents:
23
diff
changeset
|
377 } |
d052f3a44195
fixed output file names in html pages, fixed amber function bindings, replaced print command with build, fixed plugin functions, implemented zs and exec functions
zaitsev.serge
parents:
23
diff
changeset
|
378 } else { |
d052f3a44195
fixed output file names in html pages, fixed amber function bindings, replaced print command with build, fixed plugin functions, implemented zs and exec functions
zaitsev.serge
parents:
23
diff
changeset
|
379 fmt.Println("ERROR: too many arguments") |
d052f3a44195
fixed output file names in html pages, fixed amber function bindings, replaced print command with build, fixed plugin functions, implemented zs and exec functions
zaitsev.serge
parents:
23
diff
changeset
|
380 } |
0 | 381 case "watch": |
23
40f55059fbfa
fixed output file names in html pages, fixed amber function bindings, replaced print command with build, fixed plugin functions, implemented zs and exec functions
zaitsev.serge
parents:
22
diff
changeset
|
382 buildAll(true) |
40f55059fbfa
fixed output file names in html pages, fixed amber function bindings, replaced print command with build, fixed plugin functions, implemented zs and exec functions
zaitsev.serge
parents:
22
diff
changeset
|
383 case "var": |
32 | 384 if len(args) == 0 { |
385 fmt.Println("var: filename expected") | |
386 } else { | |
387 s := "" | |
33
e3c902a7380d
rewritten using zs templates, allowing go templates using <% %> delimiters
zaitsev.serge
parents:
32
diff
changeset
|
388 if vars, _, err := getVars(args[0], globals()); err != nil { |
32 | 389 fmt.Println("var: " + err.Error()) |
390 } else { | |
391 if len(args) > 1 { | |
392 for _, a := range args[1:] { | |
393 s = s + vars[a] + "\n" | |
394 } | |
395 } else { | |
396 for k, v := range vars { | |
397 s = s + k + ":" + v + "\n" | |
398 } | |
399 } | |
400 } | |
401 fmt.Println(strings.TrimSpace(s)) | |
402 } | |
0 | 403 default: |
33
e3c902a7380d
rewritten using zs templates, allowing go templates using <% %> delimiters
zaitsev.serge
parents:
32
diff
changeset
|
404 if s, err := run(globals(), cmd, args...); err != nil { |
e3c902a7380d
rewritten using zs templates, allowing go templates using <% %> delimiters
zaitsev.serge
parents:
32
diff
changeset
|
405 fmt.Println(err) |
e3c902a7380d
rewritten using zs templates, allowing go templates using <% %> delimiters
zaitsev.serge
parents:
32
diff
changeset
|
406 } else { |
e3c902a7380d
rewritten using zs templates, allowing go templates using <% %> delimiters
zaitsev.serge
parents:
32
diff
changeset
|
407 fmt.Println(s) |
0 | 408 } |
409 } | |
410 } |