hugo-action/md2gmi.go

198 lines
4.4 KiB
Go

package main
import (
"fmt"
"io/ioutil"
"log"
"os"
"path/filepath"
"regexp"
"strings"
)
type link struct {
full string
title string
url string
}
func procAudio(fileContent string, audioRegex *regexp.Regexp) string {
audios := audioRegex.FindAllStringSubmatch(fileContent, -1)
if audios != nil {
for i := range audios {
full := audios[i][0]
url := audios[i][1]
link := link{full, "audio", url}
replacement := fmt.Sprintf("=> %s", link.url)
fileContent = strings.Replace(fileContent, link.full, replacement, 1)
}
}
return fileContent
}
func procVideos(fileContent string, videoRegex *regexp.Regexp) string {
videos := videoRegex.FindAllStringSubmatch(fileContent, -1)
if videos != nil {
for i := range videos {
full := videos[i][0]
url := videos[i][1]
url = fmt.Sprintf("%s.webm", url)
link := link{full, "video", url}
replacement := fmt.Sprintf("=> %s", link.url)
fileContent = strings.Replace(fileContent, link.full, replacement, 1)
}
}
return fileContent
}
func procImages(fileContent string, imgRegex *regexp.Regexp) string {
images := imgRegex.FindAllStringSubmatch(fileContent, -1)
if images != nil {
for i := range images {
full := images[i][1]
title := images[i][2]
url := images[i][3]
urlParts := strings.Split(url, " ")
link := link{full, title, urlParts[0]}
replacement := fmt.Sprintf("%s\n=> %s", link.title, link.url)
fileContent = strings.Replace(fileContent, link.full, replacement, 1)
}
}
return fileContent
}
func procLinks(fileContent string, linkRegex *regexp.Regexp) string {
links := linkRegex.FindAllStringSubmatch(fileContent, -1)
linkUrls := make([]link, len(links))
if links != nil {
for i := range links {
full := links[i][1]
title := links[i][2]
url := links[i][3]
link := link{full, title, url}
replacement := fmt.Sprintf("*%s*", link.title)
fileContent = strings.Replace(fileContent, link.full, replacement, 1)
linkUrls[i] = link
}
}
var sb strings.Builder
for _, link := range linkUrls {
fmtLink := fmt.Sprintf("=> %s %s\n", link.url, link.title)
sb.WriteString(fmtLink)
}
fmtLinks := sb.String()
fileContent += fmt.Sprintf("\n%s", fmtLinks)
return fileContent
}
func procFile(src string, linkRegex *regexp.Regexp, imgRegex *regexp.Regexp, videoRegex *regexp.Regexp, audioRegex *regexp.Regexp) (string, error) {
fileData, err := ioutil.ReadFile(src)
if err != nil {
return "", err
}
fileContent := string(fileData)
fileContent = procLinks(fileContent, linkRegex)
fileContent = procImages(fileContent, imgRegex)
fileContent = procVideos(fileContent, videoRegex)
fileContent = procAudio(fileContent, audioRegex)
return fileContent, nil
}
func procFiles(srcDir string, destDir string) error {
libRegex := regexp.MustCompile("^.+\\.(md)$")
linkRegex := regexp.MustCompile("[^!](\\[(.+?)\\]\\((.+?)\\))")
imgRegex := regexp.MustCompile("([!]\\[(.+?)\\]\\((.+?)\\))")
videoRegex := regexp.MustCompile("{{< video src=\"(.*)\" >}}")
audioRegex := regexp.MustCompile("{{< audio src=\"(.*)\" >}}")
srcDir, err := filepath.Abs(srcDir)
if err != nil {
return err
}
destDir, err = filepath.Abs(destDir)
if err != nil {
return err
}
err = filepath.Walk(srcDir, func(path string, info os.FileInfo, err error) error {
if err == nil && libRegex.MatchString(info.Name()) {
processedFile, err := procFile(path, linkRegex, imgRegex, videoRegex, audioRegex)
if err != nil {
return err
}
path, err = filepath.Abs(path)
if err != nil {
return err
}
srcFile := strings.Replace(path, srcDir, "", 1)
destFile := filepath.Join(destDir, srcFile)
destDir := filepath.Dir(destFile)
err = os.MkdirAll(destDir, os.ModePerm)
if err != nil {
return err
}
err = ioutil.WriteFile(destFile, []byte(processedFile), 0644)
if err != nil {
return err
}
log.Printf("processed %s", path)
}
return nil
})
return err
}
func main() {
if len(os.Args) < 2 {
log.Fatal("no source directory specified")
os.Exit(1)
}
if len(os.Args) < 3 {
log.Fatal("no dest directory specified")
os.Exit(1)
}
srcDir := os.Args[1]
srcInfo, err := os.Stat(srcDir)
if os.IsNotExist(err) {
log.Fatalf("source directory %s does not exist", srcDir)
os.Exit(1)
}
if !srcInfo.IsDir() {
log.Fatalf("%s is not a directory", srcDir)
os.Exit(1)
}
destDir := os.Args[2]
err = procFiles(srcDir, destDir)
if err != nil {
log.Fatal(err)
os.Exit(1)
}
}