Created
October 30, 2021 12:23
-
-
Save flysand7/3f8b7d35c85eb65bfc194b0f07623eb9 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
package main; | |
import ( | |
"fmt" | |
"net/http" | |
"io" | |
"os" | |
"path" | |
"path/filepath" | |
"github.com/fsnotify/fsnotify" | |
"strings" | |
"io/ioutil" | |
"github.com/gomarkdown/markdown" | |
"github.com/gomarkdown/markdown/parser") | |
const sourcePath = "root"; | |
const watchPath = sourcePath; | |
const prodStartPath = "prod"; | |
var data_changed = false; | |
const script=` | |
<script>setInterval(()=>{var http=new XMLHttpRequest();http.open("GET","http://localhost:8000/~");http.send();http.onreadystatechange=(e)=>{var u=http.responseText;if(u=="1"){location.reload();}};},100);</script> | |
` | |
const template=`<!DOCTYPE html><html><head></head><body>{TEXT}</body></html>` | |
func repositionPath(fn string) string { | |
i := 0; | |
for fn[i]!='/'&&fn[i]!='\\'{i++;} | |
rem := fn[i:]; | |
return prodStartPath+rem; | |
} | |
func processSourceFile(fn string) { | |
ext := path.Ext(fn); | |
if ext==".md" { | |
data, err := os.ReadFile(fn); | |
if err == nil { | |
target := repositionPath(fn); | |
target = target[:len(target)-len(ext)]+".html"; | |
/* | |
func renderHookDropCodeBlock(w io.Writer, node ast.Node, entering bool) (ast.WalkStatus, bool) { | |
// skip all nodes that are not CodeBlock nodes | |
if _, ok := node.(*ast.CodeBlock); !ok { | |
return ast.GoToNext, false | |
} | |
// custom rendering logic for ast.CodeBlock. By doing nothing it won't be | |
// present in the output | |
return ast.GoToNext, true | |
}*/ | |
p = parser.NewWithExtensions(extensions); | |
html:=markdown.ToHTML(data,p,nil); | |
res := strings.Replace(template, "{TEXT}", string(html), 1); | |
ioutil.WriteFile(target, []byte(res), 0644) | |
} else {fmt.Println(err);} | |
}else { | |
target := repositionPath(fn); | |
in, err := os.Open(fn) | |
if err != nil { | |
return | |
} | |
defer in.Close() | |
out, err := os.Create(target) | |
if err != nil { | |
return | |
} | |
defer func() { | |
cerr := out.Close() | |
if err == nil { | |
err = cerr | |
} | |
}() | |
if _, err = io.Copy(out, in); err != nil { | |
return | |
} | |
err = out.Sync() | |
return | |
} | |
} | |
func requestHandler(w http.ResponseWriter, r *http.Request) { | |
requestedPath := prodStartPath + r.URL.Path; | |
// Handle the js input query | |
if len(r.URL.Path) == 2 && r.URL.Path[1] == '~' { | |
if data_changed { | |
fmt.Fprintf(w, "1"); | |
data_changed=false; | |
}else { | |
fmt.Fprintf(w, "0"); | |
} | |
// Handle normal request | |
} else { | |
fi, err := os.Stat(requestedPath); | |
if err == nil { | |
if fi.Mode().IsDir() { | |
requestedPath = requestedPath + "/index.html"; | |
} | |
} else { | |
fmt.Println(err); | |
} | |
data, err := os.ReadFile(requestedPath); | |
if err!=nil { | |
message := "Requested resource (" + r.URL.Path + ") not found." | |
http.Error(w, message, 404); | |
} else { | |
replaced:=strings.Replace(string(data), "<head>", "<head>"+script, 1); | |
fmt.Fprintf(w, "%s", replaced); | |
} | |
} | |
} | |
var watcher *fsnotify.Watcher | |
var extensions parser.Extensions; | |
var p *parser.Parser; | |
func main() { | |
extensions=parser.CommonExtensions; | |
var err error; | |
watcher, err = fsnotify.NewWatcher() | |
if err != nil { | |
fmt.Println("ERROR", err) | |
} | |
defer watcher.Close() | |
if err := filepath.Walk( | |
watchPath, | |
func (path string, fi os.FileInfo, err error) error { | |
if fi.Mode().IsDir() {return watcher.Add(path)};return nil | |
}); | |
err != nil{ | |
fmt.Println(err) | |
} | |
done := make(chan bool) | |
go func() { | |
for { | |
select { | |
case event, ok := <-watcher.Events: | |
if !ok { | |
return | |
} | |
if event.Op&fsnotify.Write == fsnotify.Write { | |
processSourceFile(event.Name); | |
data_changed=true | |
} | |
case err := <-watcher.Errors: | |
fmt.Println("watcher err", err) | |
} | |
} | |
}() | |
go func() { | |
fmt.Println("Serving on http://localhost:8000!\n"); | |
http.HandleFunc("/", requestHandler); | |
http.ListenAndServe(":8000", nil); | |
}() | |
<-done | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment