aboutsummaryrefslogtreecommitdiff
path: root/common.go
diff options
context:
space:
mode:
Diffstat (limited to 'common.go')
-rw-r--r--common.go134
1 files changed, 134 insertions, 0 deletions
diff --git a/common.go b/common.go
new file mode 100644
index 0000000..0cf2655
--- /dev/null
+++ b/common.go
@@ -0,0 +1,134 @@
1/*
2
3 This file is part of CompileTree (https://github.com/Pacien/CompileTree)
4
5 CompileTree is free software: you can redistribute it and/or modify
6 it under the terms of the GNU Affero General Public License as published by
7 the Free Software Foundation, either version 3 of the License, or
8 (at your option) any later version.
9
10 CompileTree is distributed in the hope that it will be useful,
11 but WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 GNU Affero General Public License for more details.
14
15 You should have received a copy of the GNU Affero General Public License
16 along with CompileTree. If not, see <http://www.gnu.org/licenses/>.
17
18*/
19
20package main
21
22import (
23 "bytes"
24 "fmt"
25 "github.com/hoisie/mustache"
26 "github.com/russross/blackfriday"
27 "io/ioutil"
28 "path"
29 "strings"
30 "sync"
31)
32
33var wait sync.WaitGroup
34
35// Common templating
36
37func isParsable(fileName string) bool {
38 switch path.Ext(fileName) {
39 case ".md", ".html", ".txt":
40 return true
41 }
42 return false
43}
44
45func read(fileName string) ([]byte, error) {
46 fileBody, err := ioutil.ReadFile(fileName)
47 if err != nil {
48 return nil, err
49 }
50 if path.Ext(fileName) == ".md" {
51 fileBody = blackfriday.MarkdownCommon(fileBody)
52 }
53 return fileBody, nil
54}
55
56func merge(files map[string][]byte) (merged []byte) {
57 merged = files["index"]
58 for pass := 0; bytes.Contains(merged, []byte("{{> ")) && pass < 4000; pass++ {
59 for fileName, fileBody := range files {
60 merged = bytes.Replace(merged, []byte("{{> "+fileName+"}}"), fileBody, -1)
61 }
62 }
63 return
64}
65
66// COMPILED and INTERACTIVE modes
67
68// render and write everything inside
69
70func parse(dirPath string, elements map[string][]byte, overwrite bool) map[string][]byte {
71 _, filesList := ls(dirPath)
72 for _, fileName := range filesList {
73 if isParsable(fileName) && (overwrite || elements[fileName[:len(fileName)-len(path.Ext(fileName))]] == nil) {
74 var err error
75 elements[fileName[:len(fileName)-len(path.Ext(fileName))]], err = read(path.Join(dirPath, fileName))
76 if err != nil {
77 fmt.Println(err)
78 }
79 }
80 }
81 return elements
82}
83
84func compile(dirPath string, elements map[string][]byte, sourceDir, outputDir string, recursive bool) {
85 wait.Add(1)
86 defer wait.Done()
87
88 if strings.HasPrefix(dirPath, outputDir) {
89 return
90 }
91
92 elements = parse(dirPath, elements, true)
93
94 if recursive {
95 dirs, _ := ls(dirPath)
96 for _, dir := range dirs {
97 go compile(path.Join(dirPath, dir), elements, sourceDir, outputDir, recursive)
98 }
99 }
100
101 template := merge(elements)
102 page := mustache.Render(string(template), nil /* TODO: generate contextual variables */)
103
104 err := writeFile(path.Join(outputDir, strings.TrimPrefix(dirPath, sourceDir), "index.html"), []byte(page))
105 if err != nil {
106 fmt.Println(err)
107 return
108 }
109}
110
111func copyFiles(dirPath, sourceDir, outputDir string, recursive bool) {
112 wait.Add(1)
113 defer wait.Done()
114
115 if strings.HasPrefix(dirPath, outputDir) {
116 return
117 }
118
119 dirs, files := ls(dirPath)
120 for _, file := range files {
121 if !isParsable(file) {
122 err := cp(path.Join(dirPath, file), path.Join(outputDir, strings.TrimPrefix(dirPath, sourceDir), file))
123 if err != nil {
124 fmt.Println(err)
125 }
126 }
127 }
128
129 if recursive {
130 for _, dir := range dirs {
131 go copyFiles(path.Join(dirPath, dir), sourceDir, outputDir, recursive)
132 }
133 }
134}