all repos

anpi @ b372e68afef31d6eecd1a33b53fe6f85993b1a4d

yaml to anki importer

anpi/main.go (view raw)

Oleksandr Smirnov Oleksandr Smirnov
olexsmir@gmail.com
remove \n in the end of sting if there's one, 1 year ago
1
package main
2
3
import (
4
	"fmt"
5
	"log/slog"
6
	"os"
7
	"path/filepath"
8
	"strings"
9
10
	"github.com/alecthomas/kong"
11
	"github.com/gomarkdown/markdown"
12
	"github.com/gomarkdown/markdown/html"
13
	mdParser "github.com/gomarkdown/markdown/parser"
14
	"github.com/olexsmir/anpi/anki"
15
	"github.com/olexsmir/anpi/parser"
16
)
17
18
//nolint:gochecknoglobals // comment to make linter happy
19
var cli struct {
20
	File string `help:"path to import file" name:"file" type:"path"`
21
}
22
23
func main() {
24
	_ = kong.Parse(&cli)
25
	if err := run(cli.File); err != nil {
26
		fmt.Fprintf(os.Stderr, "error: %v\n", err)
27
		os.Exit(1)
28
	}
29
}
30
31
func run(fpath string) error {
32
	ac := anki.NewAnkiClient()
33
34
	f, err := os.ReadFile(filepath.Clean(fpath))
35
	if err != nil {
36
		return err
37
	}
38
39
	data, err := parser.Parse(f)
40
	if err != nil {
41
		return err
42
	}
43
44
	for _, deck := range data {
45
		for _, note := range deck.Notes {
46
			fields := make(map[string]string)
47
			for k, v := range note.Fields {
48
				fields[deck.FieldLookUp(k)] = fromMarkdown(v)
49
			}
50
51
			slog.Info("gotten fields", "fields", fields)
52
53
			tags := mergeTags(deck.Tags, note.Tags)
54
			nid, err := ac.AddNote(anki.Note{
55
				DeckName:  deck.Deck,
56
				ModelName: deck.Type,
57
				Fields:    fields,
58
				Tags:      tags,
59
			})
60
			if err != nil {
61
				return err
62
			}
63
64
			slog.Info("note added", "id", nid, "fields", fields)
65
		}
66
	}
67
68
	return nil
69
}
70
71
func mergeTags(global, local []string) []string {
72
	unique := make(map[string]struct{})
73
74
	for _, tag := range global {
75
		unique[tag] = struct{}{}
76
	}
77
	for _, tag := range local {
78
		unique[tag] = struct{}{}
79
	}
80
81
	result := make([]string, 0, len(unique))
82
	for tag := range unique {
83
		result = append(result, tag)
84
	}
85
86
	return result
87
}
88
89
func fromMarkdown(inp string) string {
90
	htmlFlags := html.CommonFlags | html.HrefTargetBlank
91
	opts := html.RendererOptions{Flags: htmlFlags}
92
93
	p := mdParser.New()
94
	doc := p.Parse([]byte(inp))
95
96
	str := string(markdown.Render(doc, html.NewRenderer(opts)))
97
	str = strings.ReplaceAll(str, "<p>", "")
98
	str = strings.ReplaceAll(str, "</p>", "")
99
	str = strings.TrimSuffix(str, "\n")
100
101
	return str
102
}