aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--README.md43
-rw-r--r--common.go143
-rw-r--r--compiled.go43
-rw-r--r--context.go97
-rw-r--r--dynamic.go82
-rw-r--r--interactive.go131
-rw-r--r--main.go221
7 files changed, 228 insertions, 532 deletions
diff --git a/README.md b/README.md
index 1df51f5..6d737a0 100644
--- a/README.md
+++ b/README.md
@@ -1,4 +1,45 @@
1FoldaWeb 1FoldaWeb
2======== 2========
3 3
4A tree structure based website generator. 4### Description
5
6FoldaWeb is a "keep last legacy" website generator: the program generates a page from parts of pages that are presents inside a directory and directly inside its parents. If multiple parts have the same name, it uses the last one (the one located the deepest in the directories before the current included).
7
8This behaviour makes particularly easy to create well-organized websites with many subpages of different types with associated layouts for each.
9
10___
11
12### Features
13
14- Unique "keep last legacy" generation (no pun intended)
15- Mustache templating: FoldaWeb uses [Mustache](http://mustache.github.io/mustache.5.html) as template engine and adds several handy contextual variables
16- Markdown compatible: pages can be written using the [Markdown syntax](http://daringfireball.net/projects/markdown/syntax)
17
18Moreover, because FoldaWeb generates static files, generated websites are:
19
20- **Portable**: any host and web server software can serve flat files.
21- **Fast**: no server-side scripting is required everytime someone loads a page
22- **Secure**: no CMS security flaws
23
24___
25
26### Example
27
28[Multiverse Inc. Global Website](http://multiverse.pacien.net) is an example of website generated using FoldaWeb.
29
30Its sources are available on GitHub at [Pacien/FoldaWeb-example](https://github.com/Pacien/FoldaWeb-example)
31
32___
33
34### Usage
35
36Simply put the binary inside a directory containing a `source` folder with the website's sources inside and run the program (simply open the executable). Another folder named `out` containing the generated website will be created instantly.
37
38You can also pass custom settings via command line arguments:
39
40 -sourceDir="./source": Path to the source directory.
41 -outputDir="./out": Path to the output directory.
42 -parsableExts="html, txt, md": Parsable file extensions separated by commas.
43 -saveAs="index.html": Save compiled files as named.
44 -startWith="index": Name without extension of the first file that will by parsed.
45 -wordSeparator="-": Word separator used to replace spaces in URLs.
diff --git a/common.go b/common.go
deleted file mode 100644
index 3203945..0000000
--- a/common.go
+++ /dev/null
@@ -1,143 +0,0 @@
1/*
2
3 This file is part of FoldaWeb <https://github.com/Pacien/FoldaWeb>
4
5 FoldaWeb 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 FoldaWeb 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 FoldaWeb. If not, see <http://www.gnu.org/licenses/>.
17
18*/
19
20package main
21
22import (
23 "bytes"
24 "fmt"
25 "github.com/Pacien/fcmd"
26 "github.com/drbawb/mustache"
27 "github.com/russross/blackfriday"
28 "io/ioutil"
29 "path"
30 "strings"
31 "sync"
32)
33
34var wait sync.WaitGroup
35
36// Common templating
37
38func isParsable(fileName string, exts []string) bool {
39 for _, ext := range exts {
40 if path.Ext(fileName) == ext {
41 return true
42 }
43 }
44 return false
45}
46
47func read(fileName string) ([]byte, error) {
48 fileBody, err := ioutil.ReadFile(fileName)
49 if err != nil {
50 return nil, err
51 }
52 if path.Ext(fileName) == ".md" {
53 fileBody = blackfriday.MarkdownCommon(fileBody)
54 }
55 return fileBody, nil
56}
57
58func merge(files map[string][]byte) (merged []byte) {
59 merged = files["index"]
60 for pass := 0; bytes.Contains(merged, []byte("{{> ")) && pass < 4000; pass++ {
61 for fileName, fileBody := range files {
62 merged = bytes.Replace(merged, []byte("{{> "+fileName+"}}"), fileBody, -1)
63 }
64 }
65 return
66}
67
68// COMPILED and INTERACTIVE modes
69
70func parse(dirPath string, elements map[string][]byte, exts []string, overwrite bool) (map[string][]byte, bool) {
71 parsed := false
72 _, filesList := fcmd.Ls(dirPath)
73 for _, fileName := range filesList {
74 if isParsable(fileName, exts) && (overwrite || elements[fileName[:len(fileName)-len(path.Ext(fileName))]] == nil) {
75 var err error
76 elements[fileName[:len(fileName)-len(path.Ext(fileName))]], err = read(path.Join(dirPath, fileName))
77 if err != nil {
78 fmt.Println(err)
79 }
80 parsed = true
81 }
82 }
83 return elements, parsed
84}
85
86func compile(dirPath string, elements map[string][]byte, sourceDir, outputDir, saveAs string, exts []string, recursive bool) {
87 defer wait.Done()
88
89 if strings.HasPrefix(dirPath, outputDir) {
90 return
91 }
92
93 parsed := false
94 elements, parsed = parse(dirPath, elements, exts, true)
95
96 if recursive {
97 dirs, _ := fcmd.Ls(dirPath)
98 for _, dir := range dirs {
99 wait.Add(1)
100 go compile(path.Join(dirPath, dir), elements, sourceDir, outputDir, saveAs, exts, recursive)
101 }
102 }
103
104 if !parsed {
105 return
106 }
107
108 pagePath := strings.TrimPrefix(dirPath, sourceDir)
109
110 template := merge(elements)
111 page := mustache.Render(string(template), makeContext(pagePath, sourceDir, exts))
112
113 err := fcmd.WriteFile(path.Join(outputDir, pagePath, saveAs), []byte(page))
114 if err != nil {
115 fmt.Println(err)
116 return
117 }
118}
119
120func copyFiles(dirPath, sourceDir, outputDir string, exts []string, recursive bool) {
121 defer wait.Done()
122
123 if strings.HasPrefix(dirPath, outputDir) {
124 return
125 }
126
127 dirs, files := fcmd.Ls(dirPath)
128 for _, file := range files {
129 if !isParsable(file, exts) {
130 err := fcmd.Cp(path.Join(dirPath, file), path.Join(outputDir, strings.TrimPrefix(dirPath, sourceDir), file))
131 if err != nil {
132 fmt.Println(err)
133 }
134 }
135 }
136
137 if recursive {
138 for _, dir := range dirs {
139 wait.Add(1)
140 go copyFiles(path.Join(dirPath, dir), sourceDir, outputDir, exts, recursive)
141 }
142 }
143}
diff --git a/compiled.go b/compiled.go
deleted file mode 100644
index 7a3bd67..0000000
--- a/compiled.go
+++ /dev/null
@@ -1,43 +0,0 @@
1/*
2
3 This file is part of FoldaWeb <https://github.com/Pacien/FoldaWeb>
4
5 FoldaWeb 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 FoldaWeb 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 FoldaWeb. If not, see <http://www.gnu.org/licenses/>.
17
18*/
19
20package main
21
22import (
23 "fmt"
24 "os"
25)
26
27func compiled(sourceDir, outputDir string, exts []string, saveAs string) {
28 // remove previously compiled site
29 err := os.RemoveAll(outputDir)
30 if err != nil {
31 fmt.Println(err)
32 return
33 }
34
35 // compile everything
36 wait.Add(2)
37 go compile(sourceDir, make(map[string][]byte), sourceDir, outputDir, saveAs, exts, true)
38 go copyFiles(sourceDir, sourceDir, outputDir, exts, true)
39
40 // wait until all tasks are completed
41 wait.Wait()
42 fmt.Println("Compilation done.")
43}
diff --git a/context.go b/context.go
deleted file mode 100644
index 27a8c4a..0000000
--- a/context.go
+++ /dev/null
@@ -1,97 +0,0 @@
1/*
2
3 This file is part of FoldaWeb <https://github.com/Pacien/FoldaWeb>
4
5 FoldaWeb 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 FoldaWeb 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