-
Notifications
You must be signed in to change notification settings - Fork 0
/
read.go
126 lines (112 loc) · 2.87 KB
/
read.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
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
package markdown
import (
"bufio"
"os"
"path/filepath"
"strings"
"gopkg.in/yaml.v3"
)
func (md *MarkdownFile) readFrontMatter(filename string) (err error) {
file, err := os.Open(filename)
if err != nil {
return err
}
defer file.Close()
scanner := bufio.NewScanner(file)
scanner.Scan()
line := scanner.Text()
frontMatterLines := ""
if line == "---" { // Front Matter
for scanner.Scan() {
line = scanner.Text()
if line == "---" { // End of Front Matter
break
}
frontMatterLines += line + "\n"
}
} else { // No Front Matter
md.FrontMatter = nil
return
}
// Parse Front Matter
m := make(map[interface{}]interface{})
err = yaml.Unmarshal([]byte(frontMatterLines), &m)
if err != nil {
return err
}
md.FrontMatter = m
return
}
// Read reads the markdown file and parses it into sections (also reads the Front Matter)
func (md *MarkdownFile) Read() (err error) {
directory := filepath.Dir(md.Path)
filename := filepath.Base(md.Path)
currentDir := os.Getenv("PWD")
err = os.Chdir(directory)
if err != nil {
return err
}
file, err := os.Open(filename)
if err != nil {
_ = os.Chdir(currentDir)
return err
}
defer file.Close()
var currentLines []Line = []Line{}
var currentSection Section = Section{SectionType: NullSection}
var isFirstLine bool = true
err = md.readFrontMatter(filename)
scanner := bufio.NewScanner(file)
for scanner.Scan() {
line := scanner.Text()
// Skip the FrontMatter
if line == "---" && isFirstLine {
for {
scanner.Scan()
line = scanner.Text()
if line == "---" {
scanner.Scan()
line = scanner.Text()
break
}
}
}
if isFirstLine && line == "" {
isFirstLine = false
continue
}
isFirstLine = false
trimmedLine := strings.TrimSpace(line)
// if the line start with #, it's a new section
if strings.HasPrefix(trimmedLine, "#") {
sectionType := getSectionType(trimmedLine)
trimmedLine = strings.TrimSuffix(trimmedLine, "\n")
if sectionType == H1 && md.Title == "" {
md.Title = trimmedLine[strings.Index(trimmedLine, " ")+1:]
}
sectionText := trimmedLine[strings.Index(trimmedLine, " ")+1:] // The text after the first space
if currentSection.SectionType != NullSection || len(currentLines) > 0 {
md.Sections = append(md.Sections, currentSection)
}
currentSection = Section{
SectionType: sectionType,
Text: sectionText,
originalText: line,
}
currentLines = []Line{}
} else { // Add to current section
lineType := getLineType(trimmedLine)
currentLines = append(currentLines, Line{Text: line, LineType: lineType, originalText: line})
currentSection.Lines = currentLines
}
}
if currentSection.SectionType != NullSection || len(currentLines) > 0 {
md.Sections = append(md.Sections, currentSection)
}
// Go back to the original directory
err = os.Chdir(currentDir)
if err != nil {
return err
}
return nil
}