Tidy up and delete various things in your NotePlan notes
This plugin provides commands to help tidy up your notes:
' —) and invalid path characters (e.g. \\ / :) from note filenames in a chosen folder and its subfolders.
(See more details below.)
[[note links]] (aka "wikilinks") that don't lead to other notes in NotePlan.![image] / ![file] links whose file is missing, and {note}_attachments folders that exist but have no working link. The plugin cannot list files inside a folder, so an empty folder and a folder of unlinked files are one row. Buttons are provided to "Remove link", "Remove all links", "Remove folder", "Show in Finder" where appropriate.`---` (this can happen when frontmatter is invalid).title: field does not match the H1 on the first line of the body, when that H1 is present. An H1 that contains a template tag (for example <%- prompt('Where are we going?') %>) is skipped. Each mismatch is two bullets, with a "Use title" or "Use H1" button that copies that value onto the other field.|. This character is allowed, but in a note link it starts an alternative title, so can cause confusion. Each of those notes has "Open note" and "Fix" buttons, and the section has a "Fix all" button. Fix replaces each | with -. For a `---` title, the note includes the first 12 lines of the file. The results note is time-stamped and has a refresh button.folderToStart parameter for template/callback. Teamspace notes are skipped. Useful after importing notes from other tools.Most can be used with parameters from a Template, or via an x-callback call.
There's also the /Tidy Up (alias "tua"), which runs as many of the other commands in this plugin as you have configured in its Settings.
(If these commands are useful to you, you'll probably find the Note Helpers plugin helpful too. It's rather arbitrary which commands live in which plugin.)
Note: don't run the Remove ... commands by typing /Remove ... in the editor. The plugin command will work, but the app tends to over-write the changes with the previous version again. Instead, use them from the menu bar or the command bar.
This command exists to work around a limitation of my separate Repeat Extensions plugin, because the NotePlan API doesn't fire a change trigger when a task is completed from a search result list or from the Reference area.
This command catches any such completed repeats that haven't had the next repeat generated from them. It will work on all notes changed over the number of days you set the 'recently changed' setting to be.
It can use the "concrete dates" feature added to Repeat Extensions plugin in v1.2.
The /Remove empty blocks command intelligently cleans up your notes while preserving important structure:
* or + with no further content)- or * with no content)> with no content)# with no text)noteplan://x-callback-url/runPlugin?pluginID=np.Tidy&command=Remove%20empty%20elements&arg0=Editor&arg1=true
noteplan://x-callback-url/runPlugin?pluginID=np.Tidy&command=Remove%20empty%20elements&arg0=Editor&arg1=false&arg2=true
Important notes:
If these commands are valuable to you, then you probably want to be running them regularly. NotePlan doesn't yet allow fully automatic running of commands, but you can get close by either including the commands in a frequently-used Template, or from a third-party utility that can invoke x-callback commands. Each are described below.
You can include Tidy Up commands in your Daily Note Template that you run each day (e.g. via the separate /dayStart command from my Daily Journal plugin).
To call all the checked commands in settings inside your template:
<% await DataStore.invokePluginCommandByName("Tidy Up","np.Tidy",[]) %>
To call one of these commands from a Template use this Templating command:
<% await DataStore.invokePluginCommandByName("<command name>","np.Tidy",['<parameters>']) %>
The parameters are passed as "key":"value" pairs separated by commas, and surrounded by curly brackets {...} (JSON encoding). Note the parameters then need to be surrounded by square brackets and single quotes.
For example, this will remove sections with the heading 'Habit Progress' from notes changed in the last 2 days, running silently:
<% await DataStore.invokePluginCommandByName("Remove section from notes","np.Tidy",['{"numDays":2, "sectionHeading":"Habit progress", "runSilently": true}']) %>
And this generates any needed new @repeat() lines from finished ones, that use the Extended Repeat syntax, over all notes changed in the last 4 days:
<% await DataStore.invokePluginCommandByName("Generate @repeats in recent notes","np.Tidy",['{"numDays":4}']) %>
Tip: as these are complicated and fiddly to create, I suggest you use @dwertheimer's excellent Link Creator plugin command "/Get X-Callback-URL" which makes it much simpler.
It's possible to call these commands from outside NotePlan using the x-callback mechanism. The URL calls all take the same form:
noteplan://x-callback-url/runPlugin?pluginID=np.Tidy&command=<encoded command name>&arg0=<encoded parameters>
Notes:
"key":"value" pairs separated by commas, and surrounded by curly brackets {...}. (This is JSON encoding.)This is an example of a fully URL-encoded call:
| un-encoded call | URL-encoded call |
|---|---|
noteplan://x-callback-url/runPlugin?pluginID=np.Tidy&command=Remove section from notes&arg0={"numDays":20, "sectionHeading":"Test Delete Me"} | noteplan://x-callback-url/runPlugin?pluginID=np.Tidy&command=Remove%20section%20from%20notes&arg0=%7B%22numDays%22%3A%202%2C%20%22sectionHeading%22%3A%22Test%20Delete%20Me%22%7D |
Some commands have parameters that can be passed:
| command name | parameter 1 | parameter 2 | parameter 3 |
|---|---|---|---|
| List conflicted notes | runSilently | ||
| List duplicate notes | runSilently | ||
| List title problems | runSilently | ||
| Move top-level tasks in Editor to heading | Heading name to place the tasks under | runSilently | return content (true) rather than insert (false) |
| Remove blank notes | runSilently | ||
| Remove @done() markers | parameters (JSON) | ||
| Remove empty elements | filename (or 'Editor') | stripAllEmptyLines | preserveHeadingStructure |
| Remove empty elements from recent notes | filename (or 'Editor') | ||
| Remove empty lines | filename (or 'Editor') | ||
| Remove orphaned blockIDs | parameters (JSON) | ||
| Remove section from all notes | parameters (JSON) | ||
| Remove section from recent notes | parameters (JSON) | ||
| Remove time parts from @done() dates | parameters (JSON) | ||
| Remove >today tags from completed todos | runSilently | ||
| Remove triggers from recent calendar notes | parameters (JSON) | ||
| Cancel incomplete tasks in a past year | year (YYYY) to process | ||
| Cancel incomplete tasks in a folder | parameters (JSON with optional folderToStart) |
Note: where it just says 'parameters (JSON)' this means you can pass in any relevant setting names which will override what's in your settings for the plugin:
Tip: as these are complicated and fiddly to create, I strongly suggest you use @dwertheimer's excellent Link Creator plugin command "/Get X-Callback-URL" which makes it vastly easier.
This command rewrites the current document in the Editor, moving tasks from the top to underneath a specified heading. It cannot run like the other commands by itself or as part of TidyUp in a template, because the template processor is rewriting the document in parallel, and you will get duplicate headings.
However, there is a way to include this in your daily note. If you include some code like the following in your daily note template, it will run the command and include the output in the flow of writing the template, and so the document will not be getting written twice in parallel.
## Tasks
*
<% const tasks = await DataStore.invokePluginCommandByName("Move top-level tasks in Editor to heading","np.Tidy",["Tasks",true,true]); -%>
<% if (tasks?.length) { -%>
<%- tasks %>
<% } -%>
This piece of my daily note template:
NOTE: If you also run the
Tidy Upcommand in your template, you should uncheck this command in the TidyUp settings.
Or you can use this x-callback link, placed in your daily note template, to move all top-level tasks in the current note to a heading, in this example "Tasks":
[Top-level->Tasks](noteplan://x-callback-url/runPlugin?pluginID=np.Tidy&command=Move%20top-level%20tasks%20in%20Editor%20to%20heading&arg0=Tasks&arg1=false&arg2=false)
On macOS, click the gear button on the '🧹 Tidy Up' line in the Plugin Preferences panel, and fill in the settings accordingly. Defaults and descriptions are given for each one.
On iOS/iPadOS, use the "/Update plugin settings" command for this plugin, which will guide you through the options in turn.
@dwertheimer wrote one of the functions used in this plugin, and helped beta test much of the plugin.
If you find an issue with this plugin, or would like to suggest new features for it, please raise a Bug or Feature 'Issue' in GitHub.
If you would like to support my late-night work extending NotePlan through writing these plugins, you can through:
Thanks!
Please see the CHANGELOG.