134 lines
3.8 KiB
Go
Executable File
134 lines
3.8 KiB
Go
Executable File
package notes
|
|
|
|
import (
|
|
"bytes"
|
|
"encoding/base64"
|
|
"errors"
|
|
"fmt"
|
|
"io"
|
|
"io/ioutil"
|
|
"gitea.inhome.blapointe.com/local/notes-server/filetree"
|
|
"gitea.inhome.blapointe.com/local/notes-server/notes/md"
|
|
"path"
|
|
"regexp"
|
|
"strings"
|
|
|
|
"github.com/fairlyblank/md2min"
|
|
"github.com/gomarkdown/markdown/ast"
|
|
"github.com/gomarkdown/markdown/html"
|
|
blackfriday "github.com/russross/blackfriday/v2"
|
|
"github.com/yuin/goldmark"
|
|
)
|
|
|
|
func (n *Notes) File(urlPath string) (string, error) {
|
|
p := filetree.NewPathFromURL(urlPath)
|
|
if p.IsDir() {
|
|
return "", errors.New("path is dir")
|
|
}
|
|
b, _ := ioutil.ReadFile(p.Local)
|
|
return n.gomarkdown(urlPath, b)
|
|
return n.blackfriday(urlPath, b)
|
|
return n.goldmark(urlPath, b)
|
|
return n.md2min(urlPath, b)
|
|
}
|
|
|
|
func (n *Notes) blackfriday(urlPath string, b []byte) (string, error) {
|
|
renderer := blackfriday.NewHTMLRenderer(blackfriday.HTMLRendererParameters{
|
|
Flags: blackfriday.TOC | blackfriday.Smartypants | blackfriday.SmartypantsFractions | blackfriday.SmartypantsDashes | blackfriday.SmartypantsQuotesNBSP | blackfriday.CompletePage,
|
|
})
|
|
return string(blackfriday.Run(
|
|
b,
|
|
blackfriday.WithRenderer(renderer),
|
|
)), nil
|
|
}
|
|
|
|
func (n *Notes) goldmark(urlPath string, b []byte) (string, error) {
|
|
buff := bytes.NewBuffer(nil)
|
|
err := goldmark.Convert(b, buff)
|
|
return string(buff.Bytes()), err
|
|
}
|
|
|
|
func (n *Notes) md2min(urlPath string, b []byte) (string, error) {
|
|
mdc := md2min.New("h1")
|
|
buff := bytes.NewBuffer(nil)
|
|
err := mdc.Parse(b, buff)
|
|
return string(buff.Bytes()), err
|
|
}
|
|
|
|
func (n *Notes) gomarkdown(urlPath string, b []byte) (string, error) {
|
|
return md.Gomarkdown(b, n.commentFormer(urlPath, b))
|
|
}
|
|
|
|
func (n *Notes) commentFormer(urlPath string, md []byte) html.RenderNodeFunc {
|
|
urlPath = strings.TrimPrefix(urlPath, "/")
|
|
urlPath = strings.TrimPrefix(urlPath, strings.Split(urlPath, "/")[0])
|
|
lines := bytes.Split(md, []byte("\n"))
|
|
cur := -1
|
|
nextHeader := func() {
|
|
cur++
|
|
for cur < len(lines) {
|
|
for _, opener_closer := range [][]string{{"```", "```"}, {`<summary>`, `</summary>`}} {
|
|
if cur < len(lines) && bytes.Contains(lines[cur], []byte(opener_closer[0])) {
|
|
cur++
|
|
for cur < len(lines) && !bytes.Contains(lines[cur], []byte(opener_closer[1])) {
|
|
cur++
|
|
}
|
|
cur++
|
|
}
|
|
}
|
|
if cur >= len(lines) {
|
|
break
|
|
}
|
|
line := lines[cur]
|
|
ok, err := regexp.Match(`^\s*#+\s*.+$`, line)
|
|
if err != nil {
|
|
panic(err)
|
|
} else if ok {
|
|
return
|
|
}
|
|
cur++
|
|
}
|
|
}
|
|
return func(w io.Writer, node ast.Node, entering bool) (ast.WalkStatus, bool) {
|
|
if heading, ok := node.(*ast.Heading); !n.RO && ok && !entering {
|
|
nextHeader()
|
|
fmt.Fprintf(w, `
|
|
<form method="POST" action=%q class="comment">
|
|
<input name="lineno" type="number" style="display:none" value="%d"/>
|
|
<input autocomplete="off" name="content" type="text"/>
|
|
<input type="submit"/>
|
|
</form>
|
|
`, path.Join("/comment", urlPath)+"#"+heading.HeadingID, cur)
|
|
}
|
|
return ast.GoToNext, false
|
|
}
|
|
}
|
|
|
|
func (n *Notes) commentFormerOld() html.RenderNodeFunc {
|
|
return func(w io.Writer, node ast.Node, entering bool) (ast.WalkStatus, bool) {
|
|
if heading, ok := node.(*ast.Heading); ok {
|
|
if !entering {
|
|
literal := ""
|
|
ast.WalkFunc(heading, func(n ast.Node, e bool) ast.WalkStatus {
|
|
if leaf := n.AsLeaf(); e && leaf != nil {
|
|
if literal != "" {
|
|
literal += ".*"
|
|
}
|
|
literal += string(leaf.Literal)
|
|
}
|
|
return ast.GoToNext
|
|
})
|
|
level := heading.Level
|
|
id := base64.URLEncoding.EncodeToString([]byte(fmt.Sprintf(`^[ \t]*%s\s*%s(].*)?\s*$`, strings.Repeat("#", level), literal)))
|
|
fmt.Fprintf(w, `
|
|
<form method="POST" target="/comment" name="%s" class="comment">
|
|
<input autocomplete="off" name="content" type="text"/>
|
|
<input type="submit"/>
|
|
</form>
|
|
`, id)
|
|
}
|
|
}
|
|
return ast.GoToNext, false
|
|
}
|
|
}
|