Add markdown utils
This commit is contained in:
parent
410f50f716
commit
28ffc9c77b
133
utils/markdown.go
Normal file
133
utils/markdown.go
Normal file
@ -0,0 +1,133 @@
|
|||||||
|
package utils
|
||||||
|
|
||||||
|
import (
|
||||||
|
"bufio"
|
||||||
|
"bytes"
|
||||||
|
"fmt"
|
||||||
|
"io/ioutil"
|
||||||
|
"os"
|
||||||
|
"regexp"
|
||||||
|
"strings"
|
||||||
|
"text/template"
|
||||||
|
|
||||||
|
"gopkg.in/yaml.v2"
|
||||||
|
)
|
||||||
|
|
||||||
|
type FrontMatter struct {
|
||||||
|
Title string `yaml:"title"`
|
||||||
|
Rate float64 `yaml:"rate"`
|
||||||
|
Progress string `yaml:"progress"`
|
||||||
|
Date string `yaml:"date"`
|
||||||
|
}
|
||||||
|
|
||||||
|
func GenerateMarkdown(templatePath string, outputPath string, data map[string]interface{}) error {
|
||||||
|
tmpl, err := template.ParseFiles(templatePath)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
var output bytes.Buffer
|
||||||
|
err = tmpl.Execute(&output, data)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
return os.WriteFile(outputPath, output.Bytes(), 0644)
|
||||||
|
}
|
||||||
|
|
||||||
|
// LoadMarkdown loads the frontmatter and content from an existing markdown file
|
||||||
|
func LoadMarkdown(filepath string) (FrontMatter, string, error) {
|
||||||
|
var frontmatter FrontMatter
|
||||||
|
var contentBuilder strings.Builder
|
||||||
|
inFrontmatter := false
|
||||||
|
frontmatterComplete := false
|
||||||
|
|
||||||
|
file, err := os.Open(filepath)
|
||||||
|
if err != nil {
|
||||||
|
return frontmatter, "", err
|
||||||
|
}
|
||||||
|
defer file.Close()
|
||||||
|
|
||||||
|
scanner := bufio.NewScanner(file)
|
||||||
|
for scanner.Scan() {
|
||||||
|
line := scanner.Text()
|
||||||
|
|
||||||
|
// Detect the start and end of the frontmatter block
|
||||||
|
if line == "---" && !inFrontmatter {
|
||||||
|
inFrontmatter = true
|
||||||
|
continue
|
||||||
|
} else if line == "---" && inFrontmatter {
|
||||||
|
frontmatterComplete = true
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
|
||||||
|
if inFrontmatter && !frontmatterComplete {
|
||||||
|
// Continue reading the frontmatter
|
||||||
|
contentBuilder.WriteString(line + "\n")
|
||||||
|
} else if frontmatterComplete {
|
||||||
|
// Read the rest of the markdown content
|
||||||
|
contentBuilder.WriteString(line + "\n")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Unmarshal frontmatter into the struct
|
||||||
|
if err := yaml.Unmarshal([]byte(contentBuilder.String()), &frontmatter); err != nil {
|
||||||
|
return frontmatter, "", fmt.Errorf("error unmarshalling frontmatter: %v", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Read the markdown content
|
||||||
|
contentBytes, err := ioutil.ReadAll(file)
|
||||||
|
if err != nil {
|
||||||
|
return frontmatter, "", err
|
||||||
|
}
|
||||||
|
|
||||||
|
return frontmatter, string(contentBytes), nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// SaveUpdatedMarkdown updates only the specific fields in the frontmatter without altering the content
|
||||||
|
func SaveUpdatedMarkdown(filepath string, frontmatter FrontMatter, content string) error {
|
||||||
|
// Read the entire file as a string
|
||||||
|
fileBytes, err := ioutil.ReadFile(filepath)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
// Convert file content to string
|
||||||
|
fileContent := string(fileBytes)
|
||||||
|
|
||||||
|
// Define regex patterns to match specific fields in the frontmatter
|
||||||
|
fieldPatterns := map[string]string{
|
||||||
|
"title": fmt.Sprintf(`(?m)^title: "(.*)"`),
|
||||||
|
"progress": fmt.Sprintf(`(?m)^progress: "(.*)"`),
|
||||||
|
"date": fmt.Sprintf(`(?m)^date: (\d+)$`),
|
||||||
|
"rate": fmt.Sprintf(`(?m)^rate: (\d+\.?\d*)$`),
|
||||||
|
}
|
||||||
|
|
||||||
|
// Replace the relevant fields in the frontmatter using regex substitution
|
||||||
|
fileContent = updateFieldInFrontmatter(fileContent, "title", frontmatter.Title, fieldPatterns["title"])
|
||||||
|
fileContent = updateFieldInFrontmatter(fileContent, "progress", frontmatter.Progress, fieldPatterns["progress"])
|
||||||
|
fileContent = updateFieldInFrontmatter(fileContent, "date", fmt.Sprintf("%d", frontmatter.Date), fieldPatterns["date"])
|
||||||
|
fileContent = updateFieldInFrontmatterFloat(fileContent, "rate", frontmatter.Rate, fieldPatterns["rate"])
|
||||||
|
|
||||||
|
// Write the updated content back to the file
|
||||||
|
err = ioutil.WriteFile(filepath, []byte(fileContent), 0644)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// Helper function to update a specific field in the frontmatter
|
||||||
|
func updateFieldInFrontmatter(fileContent, field, newValue, pattern string) string {
|
||||||
|
re := regexp.MustCompile(pattern)
|
||||||
|
updatedContent := re.ReplaceAllString(fileContent, fmt.Sprintf("%s: \"%s\"", field, newValue))
|
||||||
|
return updatedContent
|
||||||
|
}
|
||||||
|
|
||||||
|
// Helper function to update a float64 field in the frontmatter (for numerical values like rate)
|
||||||
|
func updateFieldInFrontmatterFloat(fileContent string, field string, newValue float64, pattern string) string {
|
||||||
|
re := regexp.MustCompile(pattern)
|
||||||
|
updatedContent := re.ReplaceAllString(fileContent, fmt.Sprintf("%s: %.1f", field, newValue))
|
||||||
|
return updatedContent
|
||||||
|
}
|
@ -1,13 +1,11 @@
|
|||||||
package utils
|
package utils
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"bytes"
|
|
||||||
"encoding/json"
|
"encoding/json"
|
||||||
"fmt"
|
"fmt"
|
||||||
"os"
|
"os"
|
||||||
"regexp"
|
"regexp"
|
||||||
"strings"
|
"strings"
|
||||||
"text/template"
|
|
||||||
"unicode"
|
"unicode"
|
||||||
)
|
)
|
||||||
|
|
||||||
@ -18,21 +16,6 @@ func CreateDirIfNotExists(dir string) error {
|
|||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func GenerateMarkdown(templatePath string, outputPath string, data map[string]interface{}) error {
|
|
||||||
tmpl, err := template.ParseFiles(templatePath)
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
var output bytes.Buffer
|
|
||||||
err = tmpl.Execute(&output, data)
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
return os.WriteFile(outputPath, output.Bytes(), 0644)
|
|
||||||
}
|
|
||||||
|
|
||||||
func Debug(v interface{}, args ...string) {
|
func Debug(v interface{}, args ...string) {
|
||||||
// utils.Debug(variable)
|
// utils.Debug(variable)
|
||||||
debug, err := json.MarshalIndent(v, "", " ")
|
debug, err := json.MarshalIndent(v, "", " ")
|
||||||
|
Loading…
Reference in New Issue
Block a user