initial commit
This commit is contained in:
commit
e157883c90
12
Containerfile
Normal file
12
Containerfile
Normal file
@ -0,0 +1,12 @@
|
||||
FROM docker.io/golang:1.21-alpine3.19 AS builder
|
||||
|
||||
ADD md2gmi.go /md2gmi.go
|
||||
RUN go build -o /md2gmi /md2gmi.go
|
||||
|
||||
|
||||
FROM scratch
|
||||
|
||||
COPY --from=builder /md2gmi /md2gmi
|
||||
|
||||
ENTRYPOINT ["/md2gmi"]
|
||||
CMD ["${INPUT_DIR}", "${OUTPUT_DIR}"]
|
12
action.yml
Normal file
12
action.yml
Normal file
@ -0,0 +1,12 @@
|
||||
name: "Markdown2Gemini"
|
||||
description: "Simple conversion of a tree of markdown files to the gemini format."
|
||||
inputs:
|
||||
input-dir:
|
||||
description: "Path to the input directory"
|
||||
required: true
|
||||
output-dir:
|
||||
description: "Path to the output directory"
|
||||
required: true
|
||||
runs:
|
||||
using: "docker"
|
||||
image: "Containerfile"
|
197
md2gmi.go
Normal file
197
md2gmi.go
Normal file
@ -0,0 +1,197 @@
|
||||
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)
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue
Block a user