-
Notifications
You must be signed in to change notification settings - Fork 1
/
article.go
90 lines (79 loc) · 1.82 KB
/
article.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
package qiisync
import (
"fmt"
"io/ioutil"
"log"
"os"
"regexp"
"strings"
"gopkg.in/yaml.v2"
)
var delimReg = regexp.MustCompile(`---\n+`)
// ArticleHeader is a structure that represents the metadata of a Article.
type ArticleHeader struct {
ID string `yaml:"ID"`
Title string `yaml:"Title"`
Tags string `yaml:"Tags"`
Author string `yaml:"Author"`
Private bool `yaml:"Private"`
}
// Article is a structure that holds the metadata of a file and the contents of an article.
type Article struct {
*ArticleHeader
Item *Item
FilePath string
}
func (a *Article) headerString() (string, error) {
d, err := yaml.Marshal(a.ArticleHeader)
if err != nil {
log.Fatalf("error: %v", err)
}
headers := []string{
"---",
string(d),
}
return strings.Join(headers, "\n") + "---\n\n", nil
}
func (a *Article) fullContent() (string, error) {
header, err := a.headerString()
if err != nil {
return "", nil
}
c := header + a.Item.Body
if !strings.HasSuffix(c, "\n") {
// fill newline for suppressing diff "No newline at end of file"
c += "\n"
}
return c, nil
}
// ArticleFromFile extracts an article from local filesysytem.
func ArticleFromFile(filepath string) (*Article, error) {
b, err := ioutil.ReadFile(filepath)
if err != nil {
return nil, err
}
content := string(b)
isNew := !strings.HasPrefix(content, "---\n")
ah := ArticleHeader{}
if !isNew {
c := delimReg.Split(content, 3)
if len(c) != 3 || c[0] != "" {
return nil, fmt.Errorf("article format is invalid")
}
if err := yaml.Unmarshal([]byte(c[1]), &ah); err != nil {
return nil, err
}
content = c[2]
}
a := &Article{
ArticleHeader: &ah,
Item: &Item{Body: content},
FilePath: filepath,
}
fi, err := os.Stat(filepath)
if err != nil {
return nil, err
}
a.Item.UpdatedAt = fi.ModTime()
return a, nil
}