-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
60 changed files
with
3,094 additions
and
24 deletions.
There are no files selected for viewing
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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,5 @@ | ||
temp/ | ||
docs/* | ||
src/url/static/css/styles.css | ||
!docs/.nojekyll | ||
*.exe |
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
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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,10 +1,14 @@ | ||
@echo off | ||
Set root_dir=%~dp0 | ||
Set target_dir=%root_dir%\docs\static\sass | ||
Set output_dir=%root_dir%\docs\static\css | ||
Set target_dir=%root_dir%\src\url\static\sass | ||
:: 這是讓go server可以找到該css | ||
Set output_src_dir=%root_dir%\src\url\static\css | ||
Set output_docs_dir=%root_dir%\docs\static\css | ||
|
||
cd %target_dir% | ||
:: echo %cd% | ||
sass main.sass:%output_dir%\styles.css --no-source-map --style compressed | ||
:: sass main.sass:%output_dir%\styles.css --no-source-map | ||
:: start %output_dir% | ||
sass main.sass:%output_src_dir%\styles.css --no-source-map --style compressed | ||
sass main.sass:%output_docs_dir%\styles.css --no-source-map | ||
start %output_src_dir% | ||
:: start %output_docs_dir% | ||
echo all done & pause > nul |
This file was deleted.
Oops, something went wrong.
This file was deleted.
Oops, something went wrong.
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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,92 @@ | ||
package main | ||
|
||
import ( | ||
"bufio" | ||
flag2 "carson.io/pkg/flag" | ||
"errors" | ||
"flag" | ||
"fmt" | ||
"os" | ||
"os/exec" | ||
"runtime" | ||
"strings" | ||
) | ||
|
||
func initBuildCmd() *flag2.Command { | ||
cmd := flag2.NewCommand(flag.NewFlagSet("build", flag.ContinueOnError), | ||
map[string][]flag2.CmdField{ | ||
"bool": { | ||
{"all", true, "create gh-pages: src -> docs"}, | ||
}, | ||
}) | ||
cmd.MainFunc = func(args []string) error { | ||
return build() | ||
} | ||
return cmd | ||
} | ||
|
||
type msgFunc func(args []string) error | ||
|
||
func startCMD(quitChan *chan error) { | ||
cmdBuild := initBuildCmd() | ||
var flagSetAll []*flag.FlagSet | ||
for _, curCmd := range []*flag2.Command{cmdBuild} { | ||
flagSetAll = append(flagSetAll, curCmd.FlagSet) | ||
} | ||
|
||
menuHelp := func(args []string) error { | ||
for _, curFlagSet := range flagSetAll { | ||
curFlagSet.Usage() | ||
} | ||
return nil | ||
} | ||
msgMap := map[string]msgFunc{ | ||
"help": menuHelp, | ||
"-help": menuHelp, | ||
"-h": menuHelp, | ||
"quit": func(args []string) error { | ||
*quitChan <- errors.New("terminal close") | ||
return nil | ||
}, | ||
"cls": func(args []string) error { | ||
var clearMap map[string]func() error | ||
clearMap = make(map[string]func() error) | ||
clearMap["linux"] = func() error { | ||
cmd := exec.Command("clear") | ||
cmd.Stdout = os.Stdout | ||
return cmd.Run() | ||
} | ||
clearMap["windows"] = func() error { | ||
cmd := exec.Command("cmd", "/c", "cls") // /c: Close | ||
cmd.Stdout = os.Stdout | ||
return cmd.Run() | ||
} | ||
clearFunc, ok := clearMap[runtime.GOOS] | ||
if !ok { | ||
return errors.New("your platform is unsupported! i can't clear terminal screen :(") | ||
|
||
} | ||
return clearFunc() | ||
}, | ||
"build": cmdBuild.MainFunc, | ||
"run": func(args []string) error { | ||
go func() { | ||
_ = run() | ||
}() | ||
return nil | ||
}, | ||
} | ||
|
||
scanner := bufio.NewScanner(os.Stdin) | ||
for { | ||
fmt.Println("Enter CMD: ") | ||
scanner.Scan() | ||
text := scanner.Text() | ||
args := strings.Split(text, " ") | ||
if handleFunc, exists := msgMap[args[0]]; exists { | ||
if err := handleFunc(args[1:]); err != nil { | ||
_, _ = fmt.Fprintln(os.Stderr, err.Error()) | ||
} | ||
} | ||
} | ||
} |
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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,3 @@ | ||
module carson.io | ||
|
||
go 1.17 |
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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,240 @@ | ||
package main | ||
|
||
import ( | ||
io2 "carson.io/pkg/io" | ||
"carson.io/pkg/tpl/funcs" | ||
"errors" | ||
"fmt" | ||
htmlTemplate "html/template" | ||
"log" | ||
"net/http" | ||
"os" | ||
"path/filepath" | ||
"regexp" | ||
"strings" | ||
textTemplate "text/template" | ||
"time" | ||
) | ||
|
||
type Config struct { | ||
*Server | ||
excludeFiles []string | ||
} | ||
|
||
type Server struct { | ||
Port int | ||
} | ||
|
||
var ( | ||
config *Config | ||
chanQuit chan error | ||
) | ||
|
||
func init() { | ||
config = &Config{ | ||
&Server{8888}, | ||
[]string{ | ||
`url\\static\\css\\.*\.md`, | ||
`url\\static\\img\\.*\.md`, | ||
`url\\static\\img\\.*\.md`, | ||
`url\\static\\js\\.*\.md`, | ||
`url\\static\\sass\\.*`, | ||
`url\\tmpl\\.*`, // 樣版在release不需要再給,已經遷入到source之中 | ||
}, | ||
} | ||
chanQuit = make(chan error) | ||
} | ||
|
||
func render(src, dst string) error { | ||
dstFile, err := os.Create(dst) | ||
if err != nil { | ||
return err | ||
} | ||
|
||
tmplDir := "url/tmpl" | ||
parseFiles := []string{src} | ||
for _, filename := range []string{"head", "navbar"} { | ||
parseFiles = append(parseFiles, filepath.Join(tmplDir, filename+".gohtml")) | ||
} | ||
|
||
t := textTemplate.Must( | ||
textTemplate.New(filepath.Base(src)). | ||
Funcs(funcs.GetUtilsFuncMap()). | ||
ParseFiles(parseFiles...), | ||
) | ||
now := time.Now() | ||
context := struct { | ||
Version string | ||
LastModTime string | ||
}{ | ||
"0.0.0", | ||
now.Format("2006-01-02 15:04"), | ||
} | ||
return t.Execute(dstFile, context) | ||
} | ||
|
||
func build() error { | ||
mirrorDir := func(rootSrc string, dst string, excludeList []string) error { | ||
return filepath.Walk(rootSrc, func(path string, info os.FileInfo, err error) error { | ||
if info.IsDir() && ( | ||
path != rootSrc && | ||
func(curPath string) bool { // filter | ||
for _, excludeItem := range excludeList { | ||
if strings.HasPrefix(curPath, excludeItem) { | ||
return false | ||
} | ||
} | ||
return true | ||
}(path)) { | ||
|
||
dstPath := filepath.Join(dst, strings.Replace(path, rootSrc, "", 1)) | ||
// fmt.Println(dstPath) | ||
if err = os.MkdirAll(dstPath, os.FileMode(666)); err != nil { | ||
return err | ||
} | ||
} | ||
return nil | ||
}) | ||
} | ||
|
||
collectFiles := func(dir string, excludeList []string) (fileList []string, err error) { | ||
err = filepath.Walk(dir, func(path string, info os.FileInfo, err error) error { | ||
if info.IsDir() { | ||
return nil | ||
} | ||
|
||
if regexp.MustCompile(strings.Join(excludeList, "|")).Match([]byte(path)) { | ||
// fmt.Printf("%s\n", path) | ||
return nil | ||
} | ||
|
||
// fmt.Println(path) | ||
fileList = append(fileList, path) | ||
return nil | ||
}) | ||
if err != nil { | ||
log.Fatalf("walk error [%v]\n", err) | ||
return nil, err | ||
} | ||
return fileList, nil | ||
} | ||
|
||
var err error | ||
{ // Copy Dir only | ||
if err = mirrorDir("url\\", "..\\docs\\", []string{ | ||
"url\\pkg", | ||
"url\\static\\sass", | ||
}); err != nil { | ||
panic(err) | ||
} | ||
} | ||
|
||
{ // and then copy file | ||
filePathList, _ := collectFiles("url\\", config.excludeFiles) | ||
for _, src := range filePathList { | ||
dst := filepath.Join("../docs/", strings.Replace(src, "url\\", "", 1)) | ||
// fmt.Println(dst) | ||
if filepath.Ext(dst) == ".gohtml" { | ||
dst = dst[:len(dst)-6] + "html" | ||
if err = render(src, dst); err != nil { | ||
return err | ||
} | ||
continue | ||
} | ||
|
||
if err = io2.CopyFile(src, dst); err != nil { | ||
return err | ||
} | ||
} | ||
} | ||
return nil | ||
} | ||
|
||
type RootDir struct { | ||
http.Dir | ||
} | ||
|
||
func (dir *RootDir) Open(name string) (http.File, error) { | ||
if filepath.Ext(name) == ".sass" { | ||
return nil, errors.New(fmt.Sprintf("%d", http.StatusForbidden)) | ||
} | ||
return dir.Dir.Open(name) | ||
} | ||
|
||
type RootHandler struct { | ||
http.HandlerFunc | ||
} | ||
|
||
func (handler *RootHandler) ServeHTTP(w http.ResponseWriter, r *http.Request) { | ||
// https://developer.mozilla.org/en-US/docs/Web/HTTP/Basics_of_HTTP/MIME_types/Common_types | ||
switch filepath.Ext(r.URL.Path) { | ||
case ".html": | ||
r.URL.Path = r.URL.Path[:len(r.URL.Path)-4] + "gohtml" // treat all of html as gohtml | ||
fallthrough | ||
case ".gohtml": | ||
w.Header().Set("Content-Type", "text/html; charset=utf-8") | ||
src := filepath.Join("./url" + r.URL.Path) | ||
tmplDir := "url/tmpl" | ||
parseFiles := []string{src} | ||
for _, filename := range []string{"head", "navbar"} { | ||
parseFiles = append(parseFiles, filepath.Join(tmplDir, filename+".gohtml")) | ||
} | ||
|
||
t := htmlTemplate.Must( | ||
htmlTemplate.New(filepath.Base(src)). | ||
Funcs(htmlTemplate.FuncMap(funcs.GetUtilsFuncMap())). | ||
ParseFiles(parseFiles...), | ||
) | ||
now := time.Now() | ||
context := struct { | ||
Version string | ||
LastModTime string | ||
}{ | ||
"0.0.0", | ||
now.Format("2006-01-02 15:04"), | ||
} | ||
|
||
if err := t.Execute(w, context); err != nil { | ||
_ = fmt.Errorf("%s\n", err.Error()) | ||
} | ||
return | ||
/* // 交給http.FileServer(http.Dir()).ServeHTTP(w, r)已經會自行處理MIME_types | ||
case ".js": | ||
// w.Header().Set("Content-Type", "text/javascript; charset=utf-8") // Expected a JavaScript module script but the server responded with a MIME type of " | ||
case ".css": | ||
w.Header().Set("Content-Type", "text/css; charset=utf-8") | ||
*/ | ||
} | ||
handler.HandlerFunc(w, r) | ||
} | ||
|
||
func run() error { | ||
mux := http.NewServeMux() | ||
rootDir := &RootDir{http.Dir("./url/")} | ||
rootHandler := &RootHandler{func(w http.ResponseWriter, r *http.Request) { | ||
http.FileServer(rootDir).ServeHTTP(w, r) | ||
}} | ||
|
||
mux.Handle("/", rootHandler) | ||
server := http.Server{Addr: fmt.Sprintf(":%d", config.Server.Port), Handler: mux} | ||
|
||
fmt.Printf("http://localhost:%d\n", config.Server.Port) | ||
if err := server.ListenAndServe(); err != nil { | ||
chanQuit <- err | ||
return err | ||
} | ||
return nil | ||
} | ||
|
||
func main() { | ||
go startCMD(&chanQuit) | ||
for { | ||
select { | ||
// case <-chanQuit: | ||
case err := <-chanQuit: | ||
log.Printf("Close App. %+v\n", err) | ||
close(chanQuit) | ||
return | ||
} | ||
} | ||
} |
Oops, something went wrong.