Implemented proper conversion of links to local markdown files into html links
This commit is contained in:
parent
46e4f483f6
commit
7915a4bb09
7 changed files with 92 additions and 28 deletions
|
@ -9,11 +9,11 @@ import (
|
||||||
"github.com/ficcdaf/zona/internal/util"
|
"github.com/ficcdaf/zona/internal/util"
|
||||||
)
|
)
|
||||||
|
|
||||||
// validateFile checks whether a given path
|
// // validateFile checks whether a given path
|
||||||
// is a valid file && matches an expected extension
|
// // is a valid file && matches an expected extension
|
||||||
func validateFile(path, ext string) bool {
|
// func validateFile(path, ext string) bool {
|
||||||
return (util.CheckExtension(path, ext) == nil) && (util.PathIsValid(path, true))
|
// return (util.CheckExtension(path, ext) == nil) && (util.PathIsValid(path, true))
|
||||||
}
|
// }
|
||||||
|
|
||||||
func main() {
|
func main() {
|
||||||
mdPath := flag.String("file", "", "Path to the markdown file.")
|
mdPath := flag.String("file", "", "Path to the markdown file.")
|
||||||
|
@ -41,11 +41,6 @@ func main() {
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
// if !validateFile(*mdPath, ".md") {
|
|
||||||
// fmt.Println("File validation failed!")
|
|
||||||
// os.Exit(1)
|
|
||||||
// }
|
|
||||||
// convert.ConvertFile(*mdPath, "test/test.html")
|
|
||||||
err := util.Traverse(*mdPath, "foobar")
|
err := util.Traverse(*mdPath, "foobar")
|
||||||
if err != nil {
|
if err != nil {
|
||||||
fmt.Printf("Error: %s\n", err.Error())
|
fmt.Printf("Error: %s\n", err.Error())
|
||||||
|
|
|
@ -1,12 +1,14 @@
|
||||||
package convert
|
package convert
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"fmt"
|
||||||
"io"
|
"io"
|
||||||
"os"
|
"os"
|
||||||
"path/filepath"
|
"path/filepath"
|
||||||
"strings"
|
"strings"
|
||||||
|
|
||||||
"github.com/gomarkdown/markdown"
|
"github.com/gomarkdown/markdown"
|
||||||
|
"github.com/gomarkdown/markdown/ast"
|
||||||
"github.com/gomarkdown/markdown/html"
|
"github.com/gomarkdown/markdown/html"
|
||||||
"github.com/gomarkdown/markdown/parser"
|
"github.com/gomarkdown/markdown/parser"
|
||||||
)
|
)
|
||||||
|
@ -19,13 +21,64 @@ func MdToHTML(md []byte) ([]byte, error) {
|
||||||
doc := p.Parse(md)
|
doc := p.Parse(md)
|
||||||
|
|
||||||
// build HTML renderer
|
// build HTML renderer
|
||||||
htmlFlags := html.CommonFlags | html.HrefTargetBlank
|
htmlFlags := html.CommonFlags | html.HrefTargetBlank | html.CompletePage
|
||||||
opts := html.RendererOptions{Flags: htmlFlags}
|
opts := html.RendererOptions{Flags: htmlFlags}
|
||||||
renderer := html.NewRenderer(opts)
|
renderer := newZonaRenderer(opts)
|
||||||
|
|
||||||
return markdown.Render(doc, renderer), nil
|
return markdown.Render(doc, renderer), nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// PathIsValid checks if a path is valid.
|
||||||
|
// If requireFile is set, directories are not considered valid.
|
||||||
|
func PathIsValid(path string, requireFile bool) bool {
|
||||||
|
s, err := os.Stat(path)
|
||||||
|
if os.IsNotExist(err) {
|
||||||
|
return false
|
||||||
|
} else if requireFile {
|
||||||
|
// fmt.Printf("Directory status: %s\n", strconv.FormatBool(s.IsDir()))
|
||||||
|
return !s.IsDir()
|
||||||
|
}
|
||||||
|
return err == nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func processLink(p string) string {
|
||||||
|
fmt.Println("Processing link...")
|
||||||
|
ext := filepath.Ext(p)
|
||||||
|
// Only process if it points to an existing, local markdown file
|
||||||
|
if ext == ".md" && filepath.IsLocal(p) {
|
||||||
|
fmt.Println("Markdown link detected...")
|
||||||
|
return ChangeExtension(p, ".html")
|
||||||
|
} else {
|
||||||
|
return p
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func renderLink(w io.Writer, l *ast.Link, entering bool) {
|
||||||
|
if entering {
|
||||||
|
destPath := processLink(string(l.Destination))
|
||||||
|
fmt.Fprintf(w, `<a href="%s"`, destPath)
|
||||||
|
for _, attr := range html.BlockAttrs(l) {
|
||||||
|
fmt.Fprintf(w, ` %s`, attr)
|
||||||
|
}
|
||||||
|
io.WriteString(w, ">")
|
||||||
|
} else {
|
||||||
|
io.WriteString(w, "</a>")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func htmlRenderHook(w io.Writer, node ast.Node, entering bool) (ast.WalkStatus, bool) {
|
||||||
|
if link, ok := node.(*ast.Link); ok {
|
||||||
|
renderLink(w, link, entering)
|
||||||
|
return ast.GoToNext, true
|
||||||
|
}
|
||||||
|
return ast.GoToNext, false
|
||||||
|
}
|
||||||
|
|
||||||
|
func newZonaRenderer(opts html.RendererOptions) *html.Renderer {
|
||||||
|
opts.RenderNodeHook = htmlRenderHook
|
||||||
|
return html.NewRenderer(opts)
|
||||||
|
}
|
||||||
|
|
||||||
// WriteFile writes a given byte array to the given path.
|
// WriteFile writes a given byte array to the given path.
|
||||||
func WriteFile(b []byte, p string) error {
|
func WriteFile(b []byte, p string) error {
|
||||||
f, err := os.Create(p)
|
f, err := os.Create(p)
|
||||||
|
|
|
@ -22,19 +22,6 @@ func CheckExtension(path, ext string) error {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// PathIsValid checks if a path is valid.
|
|
||||||
// If requireFile is set, directories are not considered valid.
|
|
||||||
func PathIsValid(path string, requireFile bool) bool {
|
|
||||||
s, err := os.Stat(path)
|
|
||||||
if os.IsNotExist(err) {
|
|
||||||
return false
|
|
||||||
} else if requireFile {
|
|
||||||
// fmt.Printf("Directory status: %s\n", strconv.FormatBool(s.IsDir()))
|
|
||||||
return !s.IsDir()
|
|
||||||
}
|
|
||||||
return err == nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func getRoot(path string) string {
|
func getRoot(path string) string {
|
||||||
for {
|
for {
|
||||||
parent := filepath.Dir(path)
|
parent := filepath.Dir(path)
|
||||||
|
@ -43,7 +30,7 @@ func getRoot(path string) string {
|
||||||
}
|
}
|
||||||
path = parent
|
path = parent
|
||||||
}
|
}
|
||||||
fmt.Println("getRoot: ", path)
|
// fmt.Println("getRoot: ", path)
|
||||||
return path
|
return path
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -73,7 +60,7 @@ func processFile(inPath string, entry fs.DirEntry, err error, outRoot string) er
|
||||||
if !entry.IsDir() {
|
if !entry.IsDir() {
|
||||||
ext := filepath.Ext(inPath)
|
ext := filepath.Ext(inPath)
|
||||||
outPath := replaceRoot(inPath, outRoot)
|
outPath := replaceRoot(inPath, outRoot)
|
||||||
fmt.Println("NewRoot: ", outPath)
|
// fmt.Println("NewRoot: ", outPath)
|
||||||
switch ext {
|
switch ext {
|
||||||
case ".md":
|
case ".md":
|
||||||
fmt.Println("Processing markdown...")
|
fmt.Println("Processing markdown...")
|
||||||
|
@ -99,7 +86,7 @@ func processFile(inPath string, entry fs.DirEntry, err error, outRoot string) er
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
fmt.Printf("Visited: %s\n", inPath)
|
// fmt.Printf("Visited: %s\n", inPath)
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
15
internal/util/util.go
Normal file
15
internal/util/util.go
Normal file
|
@ -0,0 +1,15 @@
|
||||||
|
package util
|
||||||
|
|
||||||
|
import "strings"
|
||||||
|
|
||||||
|
func NormalizeContent(content string) string {
|
||||||
|
var normalized []string
|
||||||
|
lines := strings.Split(content, "\n")
|
||||||
|
for _, line := range lines {
|
||||||
|
line = strings.TrimSpace(line)
|
||||||
|
if line != "" {
|
||||||
|
normalized = append(normalized, line)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return strings.Join(normalized, "\n")
|
||||||
|
}
|
8
runtest.sh
Executable file
8
runtest.sh
Executable file
|
@ -0,0 +1,8 @@
|
||||||
|
#!/bin/bash
|
||||||
|
if [ -e foobar ]; then
|
||||||
|
rm -rf foobar
|
||||||
|
fi
|
||||||
|
|
||||||
|
go run cmd/zona/main.go test
|
||||||
|
|
||||||
|
bat foobar/in.html
|
|
@ -1,3 +1,6 @@
|
||||||
# My amazing markdown file!
|
# My amazing markdown file!
|
||||||
|
|
||||||
I can _even_ do **this**!
|
I can _even_ do **this**!
|
||||||
|
|
||||||
|
- Or, I could...
|
||||||
|
- [Link](page.md) to this file
|
||||||
|
|
3
test/page.md
Normal file
3
test/page.md
Normal file
|
@ -0,0 +1,3 @@
|
||||||
|
# My amazing markdown filez 2!
|
||||||
|
|
||||||
|
This file gets linked to...
|
Loading…
Add table
Add a link
Reference in a new issue