This script is designed for people who want to sync a flat folder of notes (a la nvALT) to a more organized system of nested folders. It serves as a system for creating a structure that’s easier to navigate in iOS note apps, or for separating notes that might be compiled into different books or projects.

Installation

First, back up the files in your main folder. I make no guarantees and take no responsibility for lost data.

To use Folderize, save this script as folderize.rb to disk (you can right click the link and Save).

Make it executable with chmod a+x /path/to/folderize.rb. A sample configuration file is generated at this location the first time you run folderize.rb. Run it once, and then edit ~/.folderize to define your configuration.

Configuration

Folderize works off a configuration file that’s written to your Mac user’s home folder the first time it’s run. The file contains paths for your “flat” folder, and the root folder for your nested hierarchy. Most importantly, it lets you define the prefix-to-folder-name conversion, allowing you to sync notes with simple title prefixes into more intuitively-named container folders.

Only notes with defined prefix/folder pairs will be synced.

The configuration file (~/.folderize) looks like this:

---
flat_folder: ~/Dropbox/nvALT2.2
nested_folder: ~/Dropbox/Notes/nvALT
prefixes:
  xxx: Ideas
  GitLogger: Git Logs
  Systematic: Systematic

The prefixes, such as ‘xxx’ above, denote the first word/characters of a note title that will be filed into folders. Thus, if I had a note called ‘xxx Ideas for nvALT.md’, it would be synced with the file ~/Dropbox/Notes/nvALT/Ideas/Ideas for nvALT.md based on the above configuration.

Running folderize.rb after configuration will automatically set up the initial structure, creating folders for defined prefixes and syncing matching notes.

Usage

After setup, Folderize can be run two ways:

Running at intervals

Running the script directly with no arguments will simply parse all of your files in both your flat folder and your nested directory, looking for files that match any of your defined prefixes. If a version of the file in one folder has a newer modified date than its parallel version, the newer file is copied over the older one. Note that if you make changes to both files before running the script, only the changes in the most recently-edited file will be preserved. This method can be run on a schedule using launchd or cron.

Running with Hazel (et al)

The second method is to run with specific files as arguments. This method works well with something like Hazel (or anything that can watch both folders for file changes). Just set up a trigger that runs /path/to/folderize.rb [filename] any time it detects a changed file. This method is more likely to prevent accidental overwrites as it will update both versions immediately when one changes.

Caveats

  1. Folders are created automatically for any configured prefix
  2. Files that don’t match a configured prefix are ignored
  3. Changing a file/note name will create additional copies when synced
  4. Modifying both versions (flat and nested) of a file before a sync takes place will overwrite the oldest changes

A note about nvALT development

Many, many people have asked for direct folder support in nvALT (along with myriad other requests). This isn’t going to happen. The Notational Velocity codebase that nvALT is built on has aged to a point where it’s nearly impossible to continue development for modern versions of OS X. I’m working on a rewrite (well, really a new app) that will incorporate some of the most common nvALT feature requests, but don’t expect any major changes to nvALT in the meantime.

Hopefully this script will satisfy some of the valid use cases I’ve heard for sub-folder support. I know that running background scripts and Hazel tasks isn’t for everyone. For those with the background knowledge to make it work, though, this should provide a pretty good solution. Let me know if you run into issues.