bearnotes

package module
v0.0.0-...-0aa85c9 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Nov 25, 2021 License: MIT Imports: 16 Imported by: 0

README

Migrate your notes from Bear to Zettlr!

Background

I recently switch from Bear to Zettlr to manage my notes. However, I was sad to discover that Bear exports notes in a non-standard way:

  • File attachments are HTML links that don't even point to the correct file
  • All notes are stored in the same directory, regardless of your tag hierarchy
  • The tag format used by Bear (#foo/bar) is incompatible with Zettlr format (#bar)
  • Bonus: some file attachment were missing...

So, I decided to write this tool in order to save my hundreds of notes!

Usage

First, export all your notes from Bear.

  • Go to Notes
  • Hit Cmd+A to select all your notes
  • Go to File > Export Notes...
  • Select Markdown and check Export attachments
  • Select a directory to store your exported notes
  • Click Export notes

Then, install git and go.

brew install git golang

Checkout this repository.

git clone https://github.com/nmasse-itix/bearnotes.git
cd bearnotes/cli

Start a discovery of your notes.

go run main.go discover --from /path/to/bear-notes --tag-file /tmp/tags.yaml

If everything goes well, it should display a count of your exported notes along with the discovered tag list.

You can review the generated tag configuration file.

open /tmp/tags.yaml

Finally, launch the proper migration phase.

go run main.go migrate --from /path/to/bear-notes --to /path/to/zettlr-notes --tag-file /tmp/tags.yaml

Review the migrated notes.

If you want to change the default folder hierarchy, read the next section.

Configuration

You can configure how the migration tool stores your notes, in which folder and even rewrite the tags to match Zettlr's format.

The default configuration for a tag is:

foo/bar:
    ignore: false
    handling_strategy: same-folder
    target_directory: foo/bar
    target_tag_name: bar

It defines that any note having this tag will go to the foo/bar directory. The #foo/bar tag will be rewritten as #bar. All the notes having the #foo/bar tag, will be stored in the same directory, along with their embedded images and file attachments.

If you think the migration tool wrongly identified a tag, you can switch the ignore option to true.

foo/bar:
    ignore: true

If you want to rewrite the #foo/bar tag as #foo-bar, you can change the target_tag_name.

foo/bar:
    ignore: false
    handling_strategy: same-folder
    target_directory: foo/bar
    target_tag_name: foo-bar

Note: If you want to remove the tag from the migrated note, use target_tag_name: "".

The target_directory option is straightforward: it defines where to store the notes having this tag.

The handling_strategy option specifies how notes will be saved on the filesystem

  • same-folder: all notes having this tag are stored in the target_directory along with their embedded images and file attachments.
  • one-note-per-folder: each note will get a sub-folder in the target_directory

Note: given that a document can have multiple tags, it is perfectly valid for a tag to specify no target directory or no handling strategy if you know that another tag will provide them.

If by any chance, for a note the tool cannot determine a target directory or an handling strategy, the note will be stored in the root of the target directory.

And if a note receives different configurations by two different tags, the first one wins (by order of tag appearance in the document).

Filename encoding Between Mac and Linux

If you took your exported notes from a Mac and migrated them on a Linux box, you might encounter some filename encoding issue. Hopefully, convmv can fix filenames for you!

sudo dnf install convmv
convmv -f utf-8 -t utf-8 --nfc -r --notest /path/to/bear-notes

License

MIT

Documentation

Overview

Package bearnotes provides tools to read Markdown files generated by the Bear app. It can also convert those files to a format suitable for Zettlr.

It handles notes, embedded images and file attachments.

Note: there are some Unicode normalization issues between the filenames in the filesystem and paths in the Markdown file. It is up to the caller to normalize strings when required.

Index

Constants

This section is empty.

Variables

This section is empty.

Functions

func DiscoverNotes

func DiscoverNotes(notesDir string, tagFile string) error

DiscoverNotes walk through recursively the Bear notes directory to find notes. It generates a tag configuration file, suitable for migration.

func MigrateNotes

func MigrateNotes(from string, to string, tagFile string) error

MigrateNotes takes a source directory (from), a destination directory (to), a tag configuration file (tagFile) and performs a Bear to Zettlr migration.

Types

type File

type File struct {
	Location string // The path to the file attachment
	Name     string // The name of the file
	// contains filtered or unexported fields
}

File represents a file attachment in a note.

func NewFile

func NewFile(content string, position []int) File

NewFile creates a File from the Markdown content and position in file.

func (*File) String

func (file *File) String() string

String converts a file attachment back to Markdown syntax suitable for Zettlr.

type Image

type Image struct {
	Location    string // The path to the embedded image
	Description string // The alternative text for the image
	// contains filtered or unexported fields
}

Image represents an embedded image in a note.

func NewImage

func NewImage(content string, position []int) Image

NewImage creates an Image from the Markdown content and position in file.

func (*Image) String

func (image *Image) String() string

String converts an image back to Markdown syntax suitable for Zettlr.

type Note

type Note struct {
	Tags   []Tag   // All the tags
	Files  []File  // All the file attachments
	Images []Image // All the embedded images
	// contains filtered or unexported fields
}

Note represents a Bear note with its tags, file attachments and embedded images.

func LoadNote

func LoadNote(content string) *Note

LoadNote parses a Bear note in Markdown format and returns a Note object.

func (*Note) WriteNote

func (note *Note) WriteNote() string

WriteNote converts the note back into a format suitable for Zettlr.

type Tag

type Tag struct {
	// The name of the tag (without the leading hashtag)
	Name string
	// contains filtered or unexported fields
}

Tag represents a Bear tag (#foo)

func NewTag

func NewTag(content string, position []int) Tag

NewTag creates a Tag from its content (including leading and trailing characters) and position in file.

func (*Tag) String

func (tag *Tag) String() string

String converts the Tag back to string.

type TagOptions

type TagOptions struct {

	// When true, Ignore specifies that this tag is not relevant.
	// It can be useful when a tag is wrongly identified.
	Ignore bool `yaml:"ignore"`

	// HandlingStrategy specifies how notes will be saved on the filesystem
	// - same-folder:         all notes having this tag are stored in the TargetDirectory
	//                        along with their embedded images and file attachments.
	// - one-note-per-folder: each note will get a sub-folder in the TargetDirectory
	// - "" (empty string):   no handling specified for this tag
	HandlingStrategy string `yaml:"handling_strategy"`

	// TargetDirectory specifies where to store notes, along with their images and files
	TargetDirectory string `yaml:"target_directory"`

	// TargetTagName specifies the new tag name. Since Bear supports nested tags (#foo/bar)
	// but Zettlr does not, by default the target is the last component of the Bear tag (#bar).
	//
	// If TargetTagName is the empty string, the tag is removed from the note.
	TargetTagName string `yaml:"target_tag_name"`
	// contains filtered or unexported fields
}

TagOptions specifies how to convert notes having this tag.

func NewTagOptions

func NewTagOptions(tag Tag) TagOptions

NewTagOptions initializes a new TagOptions from a Tag object, with sane defaults and counter == 1

Directories

Path Synopsis
cli
cmd

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL