Attempt to implement checkbox shitter
This commit is contained in:
parent
0f2400435f
commit
4aa09ce502
6 changed files with 143 additions and 13 deletions
|
|
@ -12,8 +12,14 @@ import (
|
|||
"path/filepath"
|
||||
|
||||
"forgejo.gwairfelin.com/max/gonotes/internal/conf"
|
||||
markdown "github.com/teekennedy/goldmark-markdown"
|
||||
"github.com/yuin/goldmark"
|
||||
"github.com/yuin/goldmark/ast"
|
||||
"github.com/yuin/goldmark/extension"
|
||||
astext "github.com/yuin/goldmark/extension/ast"
|
||||
"github.com/yuin/goldmark/parser"
|
||||
"github.com/yuin/goldmark/text"
|
||||
"github.com/yuin/goldmark/util"
|
||||
)
|
||||
|
||||
// Note is the central data structure. It can be Saved, Rendered and Loaded
|
||||
|
|
@ -50,7 +56,7 @@ func (n *Note) Render() {
|
|||
n.BodyRendered = template.HTML(buf.String())
|
||||
}
|
||||
|
||||
// Load a note from the disk. The path is derived from the title
|
||||
// LoadNote from the disk. The path is derived from the title
|
||||
func LoadNote(encodedTitle string) (*Note, error) {
|
||||
filename := filepath.Join(conf.Conf.NotesDir, fmtPath(encodedTitle))
|
||||
body, err := os.ReadFile(filename)
|
||||
|
|
@ -70,6 +76,79 @@ func (n *Note) EncodedTitle() string {
|
|||
return base64.StdEncoding.EncodeToString([]byte(n.Title))
|
||||
}
|
||||
|
||||
type toggleCheckboxTransformer struct{ nthBox int }
|
||||
|
||||
func (t *toggleCheckboxTransformer) Transform(node *ast.Document, reader text.Reader, pc parser.Context) {
|
||||
boxesFound := 0
|
||||
|
||||
// Walk to find checkbox, toggle checked status
|
||||
ast.Walk(node, func(n ast.Node, entering bool) (ast.WalkStatus, error) {
|
||||
if !entering {
|
||||
return ast.WalkContinue, nil
|
||||
}
|
||||
|
||||
box, ok := n.(*astext.TaskCheckBox)
|
||||
if !ok {
|
||||
return ast.WalkContinue, nil
|
||||
}
|
||||
|
||||
if boxesFound < t.nthBox {
|
||||
boxesFound += 1
|
||||
return ast.WalkContinue, nil
|
||||
}
|
||||
|
||||
box.IsChecked = !box.IsChecked
|
||||
return ast.WalkStop, nil
|
||||
})
|
||||
}
|
||||
|
||||
func (r *markdown.Renderer) renderTaskCheckBox(node ast.Node, entering bool) ast.WalkStatus {
|
||||
if entering {
|
||||
var itemPrefix []byte
|
||||
l := r.rc.lists[len(r.rc.lists)-1]
|
||||
|
||||
if l.list.IsOrdered() {
|
||||
itemPrefix = append(itemPrefix, []byte(fmt.Sprint(l.num))...)
|
||||
r.rc.lists[len(r.rc.lists)-1].num += 1
|
||||
}
|
||||
itemPrefix = append(itemPrefix, l.list.Marker, ' ')
|
||||
// Prefix the current line with the item prefix
|
||||
r.rc.writer.PushPrefix(itemPrefix, 0, 0)
|
||||
// Prefix subsequent lines with padding the same length as the item prefix
|
||||
indentLen := int(max(r.config.NestedListLength, NestedListLengthMinimum))
|
||||
indent := bytes.Repeat([]byte{' '}, indentLen)
|
||||
r.rc.writer.PushPrefix(bytes.Repeat(indent, len(itemPrefix)), 1)
|
||||
} else {
|
||||
r.rc.writer.PopPrefix()
|
||||
r.rc.writer.PopPrefix()
|
||||
}
|
||||
return ast.WalkContinue
|
||||
}
|
||||
|
||||
func (n *Note) ToggleBox(nthBox int) {
|
||||
log.Printf("Toggling %dth box", nthBox)
|
||||
|
||||
checkboxTransformer := toggleCheckboxTransformer{nthBox: nthBox}
|
||||
transformer := util.Prioritized(&checkboxTransformer, 0)
|
||||
|
||||
renderer := markdown.NewRenderer()
|
||||
renderer.Register(astext.KindTaskCheckBox, func(writer util.BufWriter, source []byte, n ast.Node, entering bool) (ast.WalkStatus, error) {
|
||||
})
|
||||
|
||||
var buf bytes.Buffer
|
||||
md := goldmark.New(
|
||||
goldmark.WithExtensions(
|
||||
extension.TaskList,
|
||||
),
|
||||
goldmark.WithRenderer(markdown.NewRenderer()),
|
||||
goldmark.WithParserOptions(parser.WithASTTransformers(transformer)),
|
||||
)
|
||||
|
||||
md.Convert(n.Body, &buf)
|
||||
n.Body = buf.Bytes()
|
||||
n.Save()
|
||||
}
|
||||
|
||||
func DecodeTitle(encodedTitle string) string {
|
||||
title, err := base64.StdEncoding.DecodeString(encodedTitle)
|
||||
if err != nil {
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue