From d3cbc9030d03f059d4191bd29b35910b838437b5 Mon Sep 17 00:00:00 2001 From: Adnaan Badr Date: Sun, 18 Jun 2023 02:20:49 +0200 Subject: [PATCH] markdown func --- controller.go | 8 ++++ find.go => file.go | 35 +++++++++++++---- funcs.go | 13 +++++++ go.mod | 23 +++++++++-- go.sum | 34 +++++++++++++++++ markdown.go | 95 ++++++++++++++++++++++++++++++++++++++++++++++ parse.go | 24 ++---------- 7 files changed, 200 insertions(+), 32 deletions(-) rename find.go => file.go (71%) create mode 100644 markdown.go diff --git a/controller.go b/controller.go index cf3d933..e22aca3 100644 --- a/controller.go +++ b/controller.go @@ -43,6 +43,7 @@ type opt struct { embedFS embed.FS hasEmbedFS bool readFile readFileFunc + existFile existFileFunc pubsub pubsub.Adapter appName string formDecoder *schema.Decoder @@ -242,11 +243,18 @@ func NewController(name string, options ...ControllerOption) Controller { if c.hasEmbedFS { c.readFile = readFileFS(c.embedFS) + c.existFile = existFileFS(c.embedFS) log.Println("read template files embedded in the binary") } else { c.readFile = readFileOS + c.existFile = existFileOS log.Println("read template files from disk") } + + md := markdown(c.readFile, c.existFile) + c.funcMap["markdown"] = md + c.funcMap["md"] = md + return c } diff --git a/find.go b/file.go similarity index 71% rename from find.go rename to file.go index 8aca6da..4c6cc85 100644 --- a/find.go +++ b/file.go @@ -3,12 +3,16 @@ package fir import ( "io/fs" "os" + "path" "path/filepath" "golang.org/x/exp/slices" "k8s.io/klog/v2" ) +type readFileFunc func(string) (string, []byte, error) +type existFileFunc func(string) bool + func find(opt routeOpt, path string, extensions []string) []string { var files []string var fi fs.FileInfo @@ -90,15 +94,32 @@ func isDir(path string, opt routeOpt) bool { return fileInfo.IsDir() } -func isFileOrString(path string, opt routeOpt) bool { - if opt.hasEmbedFS { - if _, err := fs.Stat(opt.embedFS, path); err != nil { - return true - } - return false +func readFileOS(file string) (name string, b []byte, err error) { + name = filepath.Base(file) + b, err = os.ReadFile(file) + return +} + +func readFileFS(fsys fs.FS) func(string) (string, []byte, error) { + return func(file string) (name string, b []byte, err error) { + name = path.Base(file) + b, err = fs.ReadFile(fsys, file) + return } +} + +func existFileOS(path string) bool { if _, err := os.Stat(path); err != nil { + return false + } + return true +} + +func existFileFS(fsys fs.FS) func(string) bool { + return func(path string) bool { + if _, err := fs.Stat(fsys, path); err != nil { + return false + } return true } - return false } diff --git a/funcs.go b/funcs.go index 8d18f4d..5a59245 100644 --- a/funcs.go +++ b/funcs.go @@ -7,6 +7,7 @@ import ( "fmt" "html/template" "io" + "strings" "github.com/alecthomas/chroma/formatters/html" @@ -28,9 +29,21 @@ func defaultFuncMap() template.FuncMap { allFuncs["bytesToString"] = bytesToString allFuncs["dump"] = dump allFuncs["toJsonb64"] = toJsonb64 + allFuncs["textAreaRows"] = textAreaRows return allFuncs } +func textAreaRows(s string) int { + l := len(strings.Split(s, "\n")) + 1 + if l < 2 { + return 2 + } + if l > 15 { + return 15 + } + return l +} + func toJsonb64(data interface{}) (string, error) { jsonData, err := json.Marshal(data) if err != nil { diff --git a/go.mod b/go.mod index 3690cd9..b4a7dee 100644 --- a/go.mod +++ b/go.mod @@ -4,6 +4,7 @@ go 1.20 require ( entgo.io/ent v0.11.4 + github.com/13rac1/goldmark-embed v0.0.0-20201220231550-e6806f2de66a github.com/Masterminds/sprig/v3 v3.2.3 github.com/alecthomas/chroma v0.10.0 github.com/chromedp/chromedp v0.9.1 @@ -30,8 +31,9 @@ require ( github.com/timshannon/bolthold v0.0.0-20210913165410-232392fc8a6a github.com/valyala/bytebufferpool v1.0.0 github.com/yosssi/gohtml v0.0.0-20201013000340-ee4748c638f4 + github.com/yuin/goldmark v1.4.13 golang.org/x/exp v0.0.0-20221204150635-6dcec336b2bb - golang.org/x/net v0.2.0 + golang.org/x/net v0.10.0 k8s.io/klog/v2 v2.100.1 ) @@ -41,6 +43,7 @@ require ( github.com/Masterminds/semver/v3 v3.2.0 // indirect github.com/agext/levenshtein v1.2.1 // indirect github.com/apparentlymart/go-textseg/v13 v13.0.0 // indirect + github.com/aymerick/douceur v0.2.0 // indirect github.com/cespare/xxhash/v2 v2.2.0 // indirect github.com/chromedp/cdproto v0.0.0-20230220211738-2b1ec77315c9 // indirect github.com/chromedp/sysutil v1.0.0 // indirect @@ -57,6 +60,7 @@ require ( github.com/golang/gddo v0.0.0-20180823221919-9d8ff1c67be5 // indirect github.com/golang/protobuf v1.5.2 // indirect github.com/google/go-cmp v0.5.9 // indirect + github.com/gorilla/css v1.0.0 // indirect github.com/hashicorp/hcl/v2 v2.13.0 // indirect github.com/huandu/xstrings v1.4.0 // indirect github.com/imdario/mergo v0.3.13 // indirect @@ -64,10 +68,21 @@ require ( github.com/josharian/intern v1.0.0 // indirect github.com/leodido/go-urn v1.2.1 // indirect github.com/mailru/easyjson v0.7.7 // indirect + github.com/microcosm-cc/bluemonday v1.0.24 // indirect github.com/mitchellh/copystructure v1.2.0 // indirect github.com/mitchellh/go-wordwrap v0.0.0-20150314170334-ad45545899c7 // indirect github.com/mitchellh/reflectwalk v1.0.2 // indirect + github.com/russross/blackfriday v1.5.2 // indirect + github.com/russross/blackfriday/v2 v2.1.0 // indirect + github.com/sergi/go-diff v1.0.0 // indirect github.com/shopspring/decimal v1.3.1 // indirect + github.com/shurcooL/github_flavored_markdown v0.0.0-20210228213109-c3a9aa474629 // indirect + github.com/shurcooL/highlight_diff v0.0.0-20181222201841-111da2e7d480 // indirect + github.com/shurcooL/highlight_go v0.0.0-20191220051317-782971ddf21b // indirect + github.com/shurcooL/octicon v0.0.0-20191102190552-cbb32d6a785c // indirect + github.com/shurcooL/sanitized_anchor_name v1.0.0 // indirect + github.com/sourcegraph/annotate v0.0.0-20160123013949-f4cad6c6324d // indirect + github.com/sourcegraph/syntaxhighlight v0.0.0-20170531221838-bd320f5d308e // indirect github.com/spf13/cast v1.5.0 // indirect github.com/spf13/pflag v1.0.5 // indirect github.com/stretchr/testify v1.8.2 // indirect @@ -79,10 +94,10 @@ require ( go.uber.org/atomic v1.7.0 // indirect go.uber.org/multierr v1.9.0 // indirect golang.org/x/crypto v0.3.0 // indirect - golang.org/x/mod v0.6.0 // indirect + golang.org/x/mod v0.8.0 // indirect golang.org/x/oauth2 v0.2.0 // indirect - golang.org/x/sys v0.6.0 // indirect - golang.org/x/text v0.5.0 // indirect + golang.org/x/sys v0.8.0 // indirect + golang.org/x/text v0.9.0 // indirect google.golang.org/appengine v1.6.7 // indirect google.golang.org/protobuf v1.28.1 // indirect ) diff --git a/go.sum b/go.sum index afd1b44..8434795 100644 --- a/go.sum +++ b/go.sum @@ -2,6 +2,8 @@ ariga.io/atlas v0.7.3-0.20221011160332-3ca609863edd h1:c3F2jvvEZzsoH/KUpDNhTsCVe ariga.io/atlas v0.7.3-0.20221011160332-3ca609863edd/go.mod h1:ft47uSh5hWGDCmQC9DsztZg6Xk+KagM5Ts/mZYKb9JE= entgo.io/ent v0.11.4 h1:grwVY0fp31BZ6oEo3YrXenAuv8VJmEw7F/Bi6WqeH3Q= entgo.io/ent v0.11.4/go.mod h1:fnQIXL36RYnCk/9nvG4aE7YHBFZhCycfh7wMjY5p7SE= +github.com/13rac1/goldmark-embed v0.0.0-20201220231550-e6806f2de66a h1:97tpPJ82VuexbkbPLIzF4BrPy/4XalKF1CKyMFc1fs0= +github.com/13rac1/goldmark-embed v0.0.0-20201220231550-e6806f2de66a/go.mod h1:dxt3ggQZ3euHiXGfETfZPfA5OUpKgJn1s4vS+YT1MEU= github.com/DATA-DOG/go-sqlmock v1.5.0 h1:Shsta01QNfFxHCfpW6YH2STWB0MudeXXEWMr20OEh60= github.com/Masterminds/goutils v1.1.1 h1:5nUrii3FMTL5diU80unEVvNevw1nH4+ZV4DSLVJLSYI= github.com/Masterminds/goutils v1.1.1/go.mod h1:8cTjp+g8YejhMuvIA5y2vz3BpJxksy863GQaJW2MFNU= @@ -16,6 +18,8 @@ github.com/alecthomas/chroma v0.10.0/go.mod h1:jtJATyUxlIORhUOFNA9NZDWGAQ8wpxQQq github.com/apparentlymart/go-dump v0.0.0-20180507223929-23540a00eaa3 h1:ZSTrOEhiM5J5RFxEaFvMZVEAM1KvT1YzbEOwB2EAGjA= github.com/apparentlymart/go-textseg/v13 v13.0.0 h1:Y+KvPE1NYz0xl601PVImeQfFyEy6iT90AvPUL1NNfNw= github.com/apparentlymart/go-textseg/v13 v13.0.0/go.mod h1:ZK2fH7c4NqDTLtiYLvIkEghdlcqw7yxLeM89kiTRPUo= +github.com/aymerick/douceur v0.2.0 h1:Mv+mAeH1Q+n9Fr+oyamOlAkUNPWPlA8PPGR0QAaYuPk= +github.com/aymerick/douceur v0.2.0/go.mod h1:wlT5vV2O3h55X9m7iVYN0TBM0NH/MmbLnd30/FjWUq4= github.com/cespare/xxhash/v2 v2.2.0 h1:DC2CZ1Ep5Y4k3ZQ899DldepgrayRUGE6BBZ/cd9Cj44= github.com/cespare/xxhash/v2 v2.2.0/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs= github.com/cheekybits/is v0.0.0-20150225183255-68e9c0620927/go.mod h1:h/aW8ynjgkuj+NQRlZcDbAbM1ORAbXjXX77sX7T289U= @@ -83,6 +87,8 @@ github.com/google/go-cmp v0.5.9/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeN github.com/google/uuid v1.1.1/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= github.com/google/uuid v1.3.0 h1:t6JiXgmwXMjEs8VusXIJk2BXHsn+wx8BZdTaoZ5fu7I= github.com/google/uuid v1.3.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= +github.com/gorilla/css v1.0.0 h1:BQqNyPTi50JCFMTw/b67hByjMVXZRwGha6wxVGkeihY= +github.com/gorilla/css v1.0.0/go.mod h1:Dn721qIggHpt4+EFCcTLTU/vk5ySda2ReITrtgBl60c= github.com/gorilla/schema v1.2.0 h1:YufUaxZYCKGFuAq3c96BOhjgd5nmXiOY9NGzF247Tsc= github.com/gorilla/schema v1.2.0/go.mod h1:kgLaKoK1FELgZqMAVxx/5cbj0kT+57qxUrAlIO2eleU= github.com/gorilla/securecookie v1.1.1 h1:miw7JPhV+b/lAHSXz4qd/nN9jRiAFV5FwjeKyCS8BvQ= @@ -122,6 +128,8 @@ github.com/mailru/easyjson v0.7.7/go.mod h1:xzfreul335JAWq5oZzymOObrkdz5UnU4kGfJ github.com/matryer/try v0.0.0-20161228173917-9ac251b645a2/go.mod h1:0KeJpeMD6o+O4hW7qJOT7vyQPKrWmj26uf5wMc/IiIs= github.com/mattn/go-sqlite3 v1.14.16 h1:yOQRA0RpS5PFz/oikGwBEqvAWhWg5ufRz4ETLjwpU1Y= github.com/mattn/go-sqlite3 v1.14.16/go.mod h1:2eHXhiwb8IkHr+BDWZGa96P6+rkvnG63S2DGjv9HUNg= +github.com/microcosm-cc/bluemonday v1.0.24 h1:NGQoPtwGVcbGkKfvyYk1yRqknzBuoMiUrO6R7uFTPlw= +github.com/microcosm-cc/bluemonday v1.0.24/go.mod h1:ArQySAMps0790cHSkdPEJ7bGkF2VePWH773hsJNSHf8= github.com/mitchellh/copystructure v1.0.0/go.mod h1:SNtv71yrdKgLRyLFxmLdkAbkKEFWgYaq1OVrnRcwhnw= github.com/mitchellh/copystructure v1.2.0 h1:vpKXTN4ewci03Vljg/q9QvCGUDttBOGBIa15WveJJGw= github.com/mitchellh/copystructure v1.2.0/go.mod h1:qLl+cE2AmVv+CoeAwDPye/v+N2HKCj9FbZEVFJRxO9s= @@ -147,15 +155,33 @@ github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZN github.com/rogpeppe/go-internal v1.6.1/go.mod h1:xXDCJY+GAPziupqXw64V24skbSoqbTEfhy4qGm1nDQc= github.com/rogpeppe/go-internal v1.8.0/go.mod h1:WmiCO8CzOY8rg0OYDC4/i/2WRWAB6poM+XZ2dLUbcbE= github.com/rogpeppe/go-internal v1.9.0 h1:73kH8U+JUqXU8lRuOHeVHaa/SZPifC7BkcraZVejAe8= +github.com/russross/blackfriday v1.5.2 h1:HyvC0ARfnZBqnXwABFeSZHpKvJHJJfPz81GNueLj0oo= +github.com/russross/blackfriday v1.5.2/go.mod h1:JO/DiYxRf+HjHt06OyowR9PTA263kcR/rfWxYHBV53g= +github.com/russross/blackfriday/v2 v2.1.0 h1:JIOH55/0cWyOuilr9/qlrm0BSXldqnqwMsf35Ld67mk= github.com/russross/blackfriday/v2 v2.1.0/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM= github.com/sabhiram/go-gitignore v0.0.0-20210923224102-525f6e181f06 h1:OkMGxebDjyw0ULyrTYWeN0UNCCkmCWfjPnIA2W6oviI= github.com/sabhiram/go-gitignore v0.0.0-20210923224102-525f6e181f06/go.mod h1:+ePHsJ1keEjQtpvf9HHw0f4ZeJ0TLRsxhunSI2hYJSs= github.com/sergi/go-diff v1.0.0 h1:Kpca3qRNrduNnOQeazBd0ysaKrUJiIuISHxogkT9RPQ= +github.com/sergi/go-diff v1.0.0/go.mod h1:0CfEIISq7TuYL3j771MWULgwwjU+GofnZX9QAmXWZgo= github.com/shopspring/decimal v1.2.0/go.mod h1:DKyhrW/HYNuLGql+MJL6WCR6knT2jwCFRcu2hWCYk4o= github.com/shopspring/decimal v1.3.1 h1:2Usl1nmF/WZucqkFZhnfFYxxxu8LG21F6nPQBE5gKV8= github.com/shopspring/decimal v1.3.1/go.mod h1:DKyhrW/HYNuLGql+MJL6WCR6knT2jwCFRcu2hWCYk4o= +github.com/shurcooL/github_flavored_markdown v0.0.0-20210228213109-c3a9aa474629 h1:86e54L0i3pH3dAIA8OxBbfLrVyhoGpnNk1iJCigAWYs= +github.com/shurcooL/github_flavored_markdown v0.0.0-20210228213109-c3a9aa474629/go.mod h1:2dOwnU2uBioM+SGy2aZoq1f/Sd1l9OkAeAUvjSyvgU0= +github.com/shurcooL/highlight_diff v0.0.0-20181222201841-111da2e7d480 h1:KaKXZldeYH73dpQL+Nr38j1r5BgpAYQjYvENOUpIZDQ= +github.com/shurcooL/highlight_diff v0.0.0-20181222201841-111da2e7d480/go.mod h1:ZpfEhSmds4ytuByIcDnOLkTHGUI6KNqRNPDLHDk+mUU= +github.com/shurcooL/highlight_go v0.0.0-20191220051317-782971ddf21b h1:rBIwpb5ggtqf0uZZY5BPs1sL7njUMM7I8qD2jiou70E= +github.com/shurcooL/highlight_go v0.0.0-20191220051317-782971ddf21b/go.mod h1:UDKB5a1T23gOMUJrI+uSuH0VRDStOiUVSjBTRDVBVag= +github.com/shurcooL/octicon v0.0.0-20191102190552-cbb32d6a785c h1:p3w+lTqXulfa3aDeycxmcLJDNxyUB89gf2/XqqK3eO0= +github.com/shurcooL/octicon v0.0.0-20191102190552-cbb32d6a785c/go.mod h1:eWdoE5JD4R5UVWDucdOPg1g2fqQRq78IQa9zlOV1vpQ= +github.com/shurcooL/sanitized_anchor_name v1.0.0 h1:PdmoCO6wvbs+7yrJyMORt4/BmY5IYyJwS/kOiWx8mHo= +github.com/shurcooL/sanitized_anchor_name v1.0.0/go.mod h1:1NzhyTcUVG4SuEtjjoZeVRXNmyL/1OwPU0+IJeTBvfc= +github.com/sourcegraph/annotate v0.0.0-20160123013949-f4cad6c6324d h1:yKm7XZV6j9Ev6lojP2XaIshpT4ymkqhMeSghO5Ps00E= +github.com/sourcegraph/annotate v0.0.0-20160123013949-f4cad6c6324d/go.mod h1:UdhH50NIW0fCiwBSr0co2m7BnFLdv4fQTgdqdJTHFeE= github.com/sourcegraph/conc v0.3.0 h1:OQTbbt6P72L20UqAkXXuLOj79LfEanQ+YQFNpLA9ySo= github.com/sourcegraph/conc v0.3.0/go.mod h1:Sdozi7LEKbFPqYX2/J+iBAM6HpqSLTASQIKqDmF7Mt0= +github.com/sourcegraph/syntaxhighlight v0.0.0-20170531221838-bd320f5d308e h1:qpG93cPwA5f7s/ZPBJnGOYQNK/vKsaDaseuKT5Asee8= +github.com/sourcegraph/syntaxhighlight v0.0.0-20170531221838-bd320f5d308e/go.mod h1:HuIsMU8RRBOtsCgI77wP899iHVBQpCmg4ErYMZB+2IA= github.com/spf13/cast v1.3.1/go.mod h1:Qx5cxh0v+4UWYiBimWS+eyWzqEqokIECu5etghLkUJE= github.com/spf13/cast v1.5.0 h1:rj3WzYc11XZaIZMPKmwP96zkFEnnAmV8s6XbB2aY32w= github.com/spf13/cast v1.5.0/go.mod h1:SpXXQ5YoyJw6s3/6cMTQuxvgRl3PCJiyaX9p6b155UU= @@ -196,6 +222,8 @@ github.com/vmihailenco/msgpack/v4 v4.3.12/go.mod h1:gborTTJjAo/GWTqqRjrLCn9pgNN+ github.com/vmihailenco/tagparser v0.1.1/go.mod h1:OeAg3pn3UbLjkWt+rN9oFYB6u/cQgqMEUPoW2WPyhdI= github.com/yosssi/gohtml v0.0.0-20201013000340-ee4748c638f4 h1:0sw0nJM544SpsihWx1bkXdYLQDlzRflMgFJQ4Yih9ts= github.com/yosssi/gohtml v0.0.0-20201013000340-ee4748c638f4/go.mod h1:+ccdNT0xMY1dtc5XBxumbYfOUhmduiGudqaDgD2rVRE= +github.com/yuin/goldmark v1.2.1/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= +github.com/yuin/goldmark v1.4.13 h1:fVcFKWvrslecOb/tg+Cc05dkeYx540o0FuFt3nUVDoE= github.com/yuin/goldmark v1.4.13/go.mod h1:6yULJ656Px+3vBD8DxQVa3kxgyrAnzto9xy5taEt/CY= github.com/zclconf/go-cty v1.8.0 h1:s4AvqaeQzJIu3ndv4gVIhplVD0krU+bgrcLSVUnaWuA= github.com/zclconf/go-cty v1.8.0/go.mod h1:vVKLxnk3puL4qRAv72AO+W99LUD4da90g3uUAzyuvAk= @@ -215,6 +243,8 @@ golang.org/x/exp v0.0.0-20221204150635-6dcec336b2bb/go.mod h1:CxIveKay+FTh1D0yPZ golang.org/x/mod v0.6.0-dev.0.20220419223038-86c51ed26bb4/go.mod h1:jJ57K6gSWd91VN4djpZkiMVwK6gcyfeH4XE8wZrZaV4= golang.org/x/mod v0.6.0 h1:b9gGHsz9/HhJ3HF5DHQytPpuwocVTChQJK3AvoLRD5I= golang.org/x/mod v0.6.0/go.mod h1:4mET923SAdbXp2ki8ey+zGs1SLqsuM2Y0uvdZR/fUNI= +golang.org/x/mod v0.8.0 h1:LUYupSeNrTNCGzR/hVBk2NHZO4hXcVaW1k4Qx7rjPx8= +golang.org/x/mod v0.8.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs= golang.org/x/net v0.0.0-20190603091049-60506f45cf65/go.mod h1:HSz+uSET+XFnRR8LxR5pz3Of3rY3CfYBVs4xY44aLks= golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= golang.org/x/net v0.0.0-20200301022130-244492dfa37a/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= @@ -223,6 +253,8 @@ golang.org/x/net v0.0.0-20211112202133-69e39bad7dc2/go.mod h1:9nx3DQGgdP8bBQD5qx golang.org/x/net v0.0.0-20220722155237-a158d28d115b/go.mod h1:XRhObCWvk6IyKnWLug+ECip1KBveYUHfp+8e9klMJ9c= golang.org/x/net v0.2.0 h1:sZfSu1wtKLGlWI4ZZayP0ck9Y73K1ynO6gqzTdBVdPU= golang.org/x/net v0.2.0/go.mod h1:KqCZLdyyvdV855qA2rE3GC2aiw5xGR5TEjj8smXukLY= +golang.org/x/net v0.10.0 h1:X2//UzNDwYmtCLn7To6G58Wr6f5ahEAQgKNzv9Y951M= +golang.org/x/net v0.10.0/go.mod h1:0qNGK6F8kojg2nk9dLZ2mShWaEBan6FAoqfSigmmuDg= golang.org/x/oauth2 v0.2.0 h1:GtQkldQ9m7yvzCL1V+LrYow3Khe0eJH0w7RbX/VbaIU= golang.org/x/oauth2 v0.2.0/go.mod h1:Cwn6afJ8jrQwYMxQDTpISoXmXW9I6qF6vDeuuoX3Ibs= golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= @@ -241,6 +273,7 @@ golang.org/x/sys v0.0.0-20220908164124-27713097b956/go.mod h1:oPkhp1MJrh7nUepCBc golang.org/x/sys v0.2.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.6.0 h1:MVltZSvRTcU2ljQOhs94SXPftV6DCNnZViHeQps87pQ= golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.8.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8= golang.org/x/term v0.2.0/go.mod h1:TVmDHMZPmdnySmBfhjOoOdhjzdE1h4u1VwSiw2l1Nuc= @@ -253,6 +286,7 @@ golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ= golang.org/x/text v0.4.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8= golang.org/x/text v0.5.0 h1:OLmvp0KP+FVG99Ct/qFiL/Fhk4zp4QQnZ7b2U+5piUM= golang.org/x/text v0.5.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8= +golang.org/x/text v0.9.0/go.mod h1:e1OnstbJyHTd6l/uOt8jFFHp6TRDWZR/bV3emEE/zU8= golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= golang.org/x/tools v0.1.12/go.mod h1:hNGJHUnrk76NpqgfD5Aqm5Crs+Hm0VOH/i9J2+nxYbc= diff --git a/markdown.go b/markdown.go new file mode 100644 index 0000000..0e3649f --- /dev/null +++ b/markdown.go @@ -0,0 +1,95 @@ +package fir + +import ( + "bytes" + "html/template" + + embed "github.com/13rac1/goldmark-embed" + "github.com/yuin/goldmark" + "github.com/yuin/goldmark/extension" + "github.com/yuin/goldmark/parser" + "github.com/yuin/goldmark/renderer" + "github.com/yuin/goldmark/renderer/html" + "k8s.io/klog/v2" +) + +var mdparser = markdownParser() + +func markdown(readFile readFileFunc, existFile existFileFunc) func(in string, linenum ...int) template.HTML { + return func(in string, linenum ...int) template.HTML { + var indata []byte + if existFile(in) { + _, data, err := readFile(in) + if err != nil { + klog.Errorln(err) + return "" + } + indata = data + } else { + indata = []byte(in) + } + + if len(linenum) > 0 { + min := linenum[0] + var max int + if len(linenum) > 1 { + max = linenum[1] + } + + parts := bytes.SplitN(indata, []byte("\n"), -1) + if max > len(parts) || max == 0 { + max = len(parts) + } + + chunk := parts[min:max] + indata = bytes.Join(chunk, []byte("\n")) + } + + var buf bytes.Buffer + if err := mdparser.Convert(indata, &buf); err != nil { + klog.Errorln(err) + return "" + } + return template.HTML(buf.String()) + } +} + +func markdownParser() goldmark.Markdown { + var ( + extensions []goldmark.Extender + parserOptions []parser.Option + rendererOptions []renderer.Option + ) + + rendererOptions = append(rendererOptions, html.WithHardWraps()) + rendererOptions = append(rendererOptions, html.WithXHTML()) + rendererOptions = append(rendererOptions, html.WithUnsafe()) + + extensions = append(extensions, extension.Table) + extensions = append(extensions, extension.Strikethrough) + extensions = append(extensions, extension.Linkify) + extensions = append(extensions, extension.TaskList) + extensions = append(extensions, extension.Typographer) + extensions = append(extensions, extension.DefinitionList) + extensions = append(extensions, extension.Footnote) + extensions = append(extensions, extension.GFM) + extensions = append(extensions, extension.CJK) + extensions = append(extensions, embed.New()) + + parserOptions = append(parserOptions, parser.WithAutoHeadingID()) + parserOptions = append(parserOptions, parser.WithAttribute()) + + md := goldmark.New( + goldmark.WithExtensions( + extensions..., + ), + goldmark.WithParserOptions( + parserOptions..., + ), + goldmark.WithRendererOptions( + rendererOptions..., + ), + ) + + return md +} diff --git a/parse.go b/parse.go index 0b6f1a3..5929eb4 100644 --- a/parse.go +++ b/parse.go @@ -3,9 +3,6 @@ package fir import ( "fmt" "html/template" - "io/fs" - "os" - "path" "path/filepath" "regexp" @@ -14,12 +11,11 @@ import ( type eventTemplate map[string]struct{} type eventTemplates map[string]eventTemplate -type readFileFunc func(string) (string, []byte, error) func layoutEmptyContentSet(opt routeOpt, content, layoutContentName string) (*template.Template, eventTemplates, error) { // is content html content or a file/directory pageContentPath := filepath.Join(opt.publicDir, content) - if isFileOrString(pageContentPath, opt) { + if !opt.existFile(pageContentPath) { return parseString( template.New( layoutContentName). @@ -37,7 +33,7 @@ func layoutSetContentEmpty(opt routeOpt, layout string) (*template.Template, eve pageLayoutPath := filepath.Join(opt.publicDir, layout) evt := make(eventTemplates) // is layout html content or a file/directory - if isFileOrString(pageLayoutPath, opt) { + if !opt.existFile(pageLayoutPath) { return parseString(template.New("").Funcs(opt.funcMap), layout) } @@ -68,7 +64,7 @@ func layoutSetContentSet(opt routeOpt, content, layout, layoutContentName string // check if content is a not a file or directory pageContentPath := filepath.Join(opt.publicDir, content) - if isFileOrString(pageContentPath, opt) { + if !opt.existFile(pageContentPath) { pageTemplate, currEvt, err := parseString(layoutTemplate, content) if err != nil { panic(err) @@ -220,20 +216,6 @@ func parseFiles(t *template.Template, readFile func(string) (string, []byte, err return t, evt, nil } -func readFileOS(file string) (name string, b []byte, err error) { - name = filepath.Base(file) - b, err = os.ReadFile(file) - return -} - -func readFileFS(fsys fs.FS) func(string) (string, []byte, error) { - return func(file string) (name string, b []byte, err error) { - name = path.Base(file) - b, err = fs.ReadFile(fsys, file) - return - } -} - func deepMergeEventTemplates(evt1, evt2 eventTemplates) eventTemplates { merged := make(eventTemplates) for eventID, templatesMap := range evt1 {