@ -0,0 +1,4 @@ |
|||||
|
*.html |
||||
|
input |
||||
|
css |
||||
|
js |
@ -0,0 +1,81 @@ |
|||||
|
# Blogo |
||||
|
Static blog generator, templating engine from markdown and html templates |
||||
|
|
||||
|
Types of blogo tags: |
||||
|
- index.html |
||||
|
``` |
||||
|
[blogo-title] |
||||
|
[blogo-index] |
||||
|
``` |
||||
|
- postTemplate.html |
||||
|
``` |
||||
|
[blogo-post-title] |
||||
|
[blogo-post-md] |
||||
|
``` |
||||
|
|
||||
|
|
||||
|
Example of config.json: |
||||
|
```json |
||||
|
{ |
||||
|
"title": "my blog", |
||||
|
"indexTemplate": "index.html", |
||||
|
"indexPostTemplate": "indexPostTemplate.html", |
||||
|
"postTemplate": "postTemplate.html", |
||||
|
"posts": [ |
||||
|
{ |
||||
|
"title": "Post 01", |
||||
|
"thumb": "post01thumb.md", |
||||
|
"md": "post01.md" |
||||
|
}, |
||||
|
{ |
||||
|
"title": "Post 02", |
||||
|
"thumb": "post02thumb.md", |
||||
|
"md": "post02.md" |
||||
|
} |
||||
|
] |
||||
|
} |
||||
|
|
||||
|
``` |
||||
|
|
||||
|
|
||||
|
Example of input files: |
||||
|
- index.html |
||||
|
|
||||
|
```html |
||||
|
<!DOCTYPE html> |
||||
|
<html> |
||||
|
<head> |
||||
|
<title>[blogo-title]</title> |
||||
|
</head> |
||||
|
<body> |
||||
|
|
||||
|
[blogo-index] |
||||
|
|
||||
|
</body> |
||||
|
</html> |
||||
|
``` |
||||
|
|
||||
|
- indexPostTemplate.html |
||||
|
|
||||
|
```html |
||||
|
<div class="col-md-3"> |
||||
|
[blogo-index-post-template] |
||||
|
</div> |
||||
|
|
||||
|
``` |
||||
|
|
||||
|
- postTemplate.html |
||||
|
|
||||
|
```html |
||||
|
<!DOCTYPE html> |
||||
|
<html> |
||||
|
<head> |
||||
|
<title>[blogo-post-title]</title> |
||||
|
</head> |
||||
|
<body> |
||||
|
|
||||
|
[blogo-post-content] |
||||
|
|
||||
|
</body> |
||||
|
</html> |
||||
|
``` |
@ -0,0 +1,15 @@ |
|||||
|
package main |
||||
|
|
||||
|
import ( |
||||
|
"log" |
||||
|
"runtime" |
||||
|
) |
||||
|
|
||||
|
func check(err error) { |
||||
|
if err != nil { |
||||
|
_, fn, line, _ := runtime.Caller(1) |
||||
|
log.Println(line) |
||||
|
log.Println(fn) |
||||
|
log.Println(err) |
||||
|
} |
||||
|
} |
@ -0,0 +1,45 @@ |
|||||
|
package main |
||||
|
|
||||
|
import ( |
||||
|
"io/ioutil" |
||||
|
"os/exec" |
||||
|
"strings" |
||||
|
|
||||
|
"github.com/fatih/color" |
||||
|
) |
||||
|
|
||||
|
func readFile(path string) string { |
||||
|
dat, err := ioutil.ReadFile(path) |
||||
|
if err != nil { |
||||
|
color.Red(path) |
||||
|
} |
||||
|
check(err) |
||||
|
return string(dat) |
||||
|
} |
||||
|
|
||||
|
func writeFile(path string, newContent string) { |
||||
|
err := ioutil.WriteFile(path, []byte(newContent), 0644) |
||||
|
check(err) |
||||
|
|
||||
|
color.Green(path) |
||||
|
//color.Blue(newContent)
|
||||
|
} |
||||
|
|
||||
|
func getLines(text string) []string { |
||||
|
lines := strings.Split(text, "\n") |
||||
|
return lines |
||||
|
} |
||||
|
|
||||
|
func concatStringsWithJumps(lines []string) string { |
||||
|
var r string |
||||
|
for _, l := range lines { |
||||
|
r = r + l + "\n" |
||||
|
} |
||||
|
return r |
||||
|
} |
||||
|
|
||||
|
func copyRaw(original string, destination string) { |
||||
|
color.Green(destination) |
||||
|
_, err := exec.Command("cp", "-r", original, destination).Output() |
||||
|
check(err) |
||||
|
} |
@ -0,0 +1,80 @@ |
|||||
|
package main |
||||
|
|
||||
|
import ( |
||||
|
"fmt" |
||||
|
"strings" |
||||
|
|
||||
|
blackfriday "gopkg.in/russross/blackfriday.v2" |
||||
|
) |
||||
|
|
||||
|
const directory = "input" |
||||
|
|
||||
|
func main() { |
||||
|
readConfig("input/config.json") |
||||
|
fmt.Println(config) |
||||
|
|
||||
|
// generate index page
|
||||
|
indexTemplate := readFile(directory + "/" + config.IndexTemplate) |
||||
|
indexPostTemplate := readFile(directory + "/" + config.IndexPostTemplate) |
||||
|
var blogoIndex string |
||||
|
blogoIndex = "" |
||||
|
for _, post := range config.Posts { |
||||
|
mdpostthumb := readFile(directory + "/" + post.Thumb) |
||||
|
htmlpostthumb := string(blackfriday.Run([]byte(mdpostthumb))) |
||||
|
|
||||
|
//put the htmlpostthumb in the blogo-index-post-template
|
||||
|
m := make(map[string]string) |
||||
|
m["blogo-index-post-template"] = htmlpostthumb |
||||
|
r := putHTMLToTemplate(indexPostTemplate, m) |
||||
|
blogoIndex = blogoIndex + r |
||||
|
} |
||||
|
//put the blogoIndex in the index.html
|
||||
|
m := make(map[string]string) |
||||
|
m["blogo-title"] = config.Title |
||||
|
m["blogo-index"] = blogoIndex |
||||
|
r := putHTMLToTemplate(indexTemplate, m) |
||||
|
writeFile("index.html", r) |
||||
|
|
||||
|
// generate posts pages
|
||||
|
postTemplate := readFile(directory + "/" + config.PostTemplate) |
||||
|
|
||||
|
for _, post := range config.Posts { |
||||
|
mdcontent := readFile(directory + "/" + post.Md) |
||||
|
htmlcontent := string(blackfriday.Run([]byte(mdcontent))) |
||||
|
|
||||
|
m := make(map[string]string) |
||||
|
m["blogo-post-title"] = post.Title |
||||
|
m["blogo-post-content"] = htmlcontent |
||||
|
|
||||
|
r := putHTMLToTemplate(postTemplate, m) |
||||
|
//fmt.Println(r)
|
||||
|
|
||||
|
filename := strings.Split(post.Md, ".")[0] |
||||
|
writeFile(filename+".html", r) |
||||
|
} |
||||
|
|
||||
|
//copy raw
|
||||
|
fmt.Println("copying raw:") |
||||
|
for _, dir := range config.CopyRaw { |
||||
|
copyRaw(directory+"/"+dir, dir) |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
func putHTMLToTemplate(template string, m map[string]string) string { |
||||
|
lines := getLines(template) |
||||
|
var resultL []string |
||||
|
for _, line := range lines { |
||||
|
inserted := false |
||||
|
for k, v := range m { |
||||
|
if strings.Contains(line, k) { |
||||
|
resultL = append(resultL, v) |
||||
|
inserted = true |
||||
|
} |
||||
|
} |
||||
|
if inserted == false { |
||||
|
resultL = append(resultL, line) |
||||
|
} |
||||
|
} |
||||
|
result := concatStringsWithJumps(resultL) |
||||
|
return result |
||||
|
} |
@ -0,0 +1,29 @@ |
|||||
|
package main |
||||
|
|
||||
|
import ( |
||||
|
"encoding/json" |
||||
|
"io/ioutil" |
||||
|
) |
||||
|
|
||||
|
type Post struct { |
||||
|
Title string `json:"title"` |
||||
|
Thumb string `json:"thumb"` |
||||
|
Md string `json:"md"` |
||||
|
} |
||||
|
type Config struct { |
||||
|
Title string `json:"title"` |
||||
|
IndexTemplate string `json:"indexTemplate"` |
||||
|
IndexPostTemplate string `json:"indexPostTemplate"` |
||||
|
PostTemplate string `json:"postTemplate"` |
||||
|
Posts []Post `json:"posts"` |
||||
|
CopyRaw []string `json:"copyRaw"` |
||||
|
} |
||||
|
|
||||
|
var config Config |
||||
|
|
||||
|
func readConfig(path string) { |
||||
|
file, err := ioutil.ReadFile(path) |
||||
|
check(err) |
||||
|
content := string(file) |
||||
|
json.Unmarshal([]byte(content), &config) |
||||
|
} |