hanayo/modules/doc/loader.go

138 lines
2.5 KiB
Go

// Package doc handles documentation.
package doc
import (
"bufio"
"bytes"
"crypto/md5"
"fmt"
"io/ioutil"
"os"
"strings"
"gopkg.in/yaml.v2"
)
func init() {
// When we start the program, we should load the documentation files.
err := loadDocFiles()
if err != nil {
fmt.Println("error while loading documentation:", err)
}
}
// rawFile represents the data that may be provided at the top of files.
type rawFile struct {
Title string `yaml:"title"`
OldID int `yaml:"old_id"`
ReferenceVersion string `yaml:"reference_version"`
}
func loadDocFiles() error {
langs, err := loadLanguagesAvailable()
if err != nil {
return err
}
files, err := ioutil.ReadDir("website-docs/" + referenceLanguage)
if err != nil {
return err
}
for _, file := range files {
data, err := ioutil.ReadFile("website-docs/" + referenceLanguage + "/" + file.Name())
if err != nil {
return err
}
header := loadHeader(data)
md5sum := fmt.Sprintf("%x", md5.Sum(data))
doc := Document{
OldID: header.OldID,
Slug: strings.TrimSuffix(file.Name(), ".md"),
}
doc.Languages, err = loadLanguages(langs, file.Name(), md5sum)
if err != nil {
return err
}
docFiles = append(docFiles, doc)
}
return nil
}
func loadHeader(b []byte) rawFile {
s := bufio.NewScanner(bytes.NewReader(b))
var (
isConf bool
conf string
)
for s.Scan() {
line := s.Text()
if !isConf {
if line == "---" {
isConf = true
}
continue
}
if line == "---" {
break
}
conf += line + "\n"
}
var f rawFile
err := yaml.Unmarshal([]byte(conf), &f)
if err != nil {
fmt.Println("Error unmarshaling yaml:", err)
return rawFile{}
}
return f
}
func loadLanguagesAvailable() ([]string, error) {
files, err := ioutil.ReadDir("website-docs")
if err != nil {
return nil, err
}
langs := make([]string, 0, len(files))
for _, f := range files {
if !f.IsDir() {
continue
}
langs = append(langs, f.Name())
}
return langs, nil
}
func loadLanguages(langs []string, fname string, referenceMD5 string) (map[string]File, error) {
m := make(map[string]File, len(langs))
for _, lang := range langs {
data, err := ioutil.ReadFile("website-docs/" + lang + "/" + fname)
if err != nil {
if os.IsNotExist(err) {
continue
}
return nil, err
}
header := loadHeader(data)
m[lang] = File{
IsUpdated: lang == referenceLanguage || header.ReferenceVersion == referenceMD5,
Title: header.Title,
referencesFile: "website-docs/" + lang + "/" + fname,
}
}
return m, nil
}