Refactor note creation

pull/6/head
Mickaël Menu 4 years ago
parent 8bb9f83eef
commit fdf6718317
No known key found for this signature in database
GPG Key ID: 53D73664CD359895

@ -46,19 +46,7 @@ func Create(zk *zk.Zk, opts CreateOpts, renderer Renderer) (string, error) {
return "", wrap(fmt.Errorf("directory not found at %v", opts.Dir.Path))
}
extra := zk.Extra(opts.Dir)
for k, v := range opts.Extra {
extra[k] = v
}
context := renderContext{
// FIXME Customize default title in config
Title: opts.Title.OrDefault("Untitled"),
Content: opts.Content.Unwrap(),
Extra: extra,
}
file, err := genFilepath(zk, opts.Dir, renderer, &context)
context, err := newRenderContext(zk, opts, renderer)
if err != nil {
return "", wrap(err)
}
@ -71,54 +59,92 @@ func Create(zk *zk.Zk, opts CreateOpts, renderer Renderer) (string, error) {
if err != nil {
return "", wrap(err)
}
err = paths.WriteString(path, content)
err = paths.WriteString(context.Path, content)
if err != nil {
return "", wrap(err)
}
fmt.Printf("<<<\n%v\n<<<\n", content)
}
return file, nil
return context.Path, nil
}
// renderContext holds the placeholder values which will be expanded in the templates.
type renderContext struct {
Title string
Content string
Path string
Filename string
FilenameStem string `handlebars:"filename-stem"`
RandomID string `handlebars:"random-id"`
Extra map[string]string
}
func genFilepath(zk *zk.Zk, dir zk.Dir, renderer Renderer, context *renderContext) (string, error) {
template := zk.FilenameTemplate(dir)
isRandom := strings.Contains(template, "random-id")
func newRenderContext(zk *zk.Zk, opts CreateOpts, renderer Renderer) (renderContext, error) {
if opts.Extra == nil {
opts.Extra = make(map[string]string)
}
for k, v := range zk.Extra(opts.Dir) {
if _, ok := opts.Extra[k]; !ok {
opts.Extra[k] = v
}
}
i := 0
template := zk.FilenameTemplate(opts.Dir)
idGenerator := rand.NewIDGenerator(zk.RandIDOpts(opts.Dir))
contextGenerator := newRenderContextGenerator(template, opts, renderer)
for {
context.RandomID = rand.GenID(zk.RandIDOpts(dir))
filename, err := renderer.Render(template, context)
context, err := contextGenerator(idGenerator())
if err != nil {
return "", err
return context, err
}
// FIXME Customize extension in config
path := filepath.Join(dir.Path, filename+".md")
exists, err := paths.Exists(path)
exists, err := paths.Exists(context.Path)
if err != nil {
return "", err
return context, err
}
if !exists {
context.Filename = filepath.Base(path)
context.FilenameStem = paths.FilenameStem(path)
return path, nil
} else if !isRandom || i > 50 { // Attempts 50 tries if the filename template contains a random ID before failing.
return "", fmt.Errorf("%v: file already exists", path)
return context, nil
}
}
}
type renderContextGenerator func(randomID string) (renderContext, error)
func newRenderContextGenerator(
filenameTemplate string,
opts CreateOpts,
renderer Renderer,
) renderContextGenerator {
context := renderContext{
// FIXME Customize default title in config
Title: opts.Title.OrDefault("Untitled"),
Content: opts.Content.Unwrap(),
Extra: opts.Extra,
}
isRandom := strings.Contains(filenameTemplate, "random-id")
i := 0
return func(randomID string) (renderContext, error) {
// Attempts 50ish tries if the filename template contains a random ID before failing.
if i > 0 && !isRandom || i >= 50 {
return context, fmt.Errorf("%v: file already exists", context.Path)
}
i++
context.RandomID = randomID
filename, err := renderer.Render(filenameTemplate, context)
if err != nil {
return context, err
}
// FIXME Customize extension in config
path := filepath.Join(opts.Dir.Path, filename+".md")
context.Path = path
context.Filename = filepath.Base(path)
context.FilenameStem = paths.FilenameStem(path)
return context, nil
}
}

@ -33,9 +33,9 @@ type IDOpts struct {
Case Case
}
// GenID creates a new random string ID using the given options.
// NewIDGenerator returns a function generating string IDs using the given options.
// Inspired by https://www.calhoun.io/creating-random-strings-in-go/
func GenID(options IDOpts) string {
func NewIDGenerator(options IDOpts) func() string {
if options.Length < 1 {
panic("IDOpts.Length must be at least 1")
}
@ -56,10 +56,13 @@ func GenID(options IDOpts) string {
}
rand := rand.New(rand.NewSource(time.Now().UnixNano()))
buf := make([]rune, options.Length)
for i := range buf {
buf[i] = charset[rand.Intn(len(charset))]
}
return string(buf)
return func() string {
buf := make([]rune, options.Length)
for i := range buf {
buf[i] = charset[rand.Intn(len(charset))]
}
return string(buf)
}
}

Loading…
Cancel
Save