List all highlights in document(s) — without community plugins

I use highlights and comments to mark parts of draft documents that need attention, and I’ve been wanting a plugin to list them in a sidebar overview where I could click them to go to the text (similar to the highlight/comment functionality in word processors, but hopefully less clunky).

The closest community plugin I found was Extract Highlights, which copies a note’s highlights into the clipboard. I’d have to rerun it every time the highlights changed, and it doesn’t link to them, but I could get an overview when I wanted one. I discovered the plugin during a writing dry spell, so I haven’t used it much yet — and I’m not going to, because I can get what I want from an embedded search.

An embedded search that lists highlights

This embedded search lists all of the highlights, and comments that immediately follow highlights, in a note named Hyalite Manor:

```query
/==[^(==)]*==( *(%%[^(%%)]+%%)|(<!--[^(\-\->)]+-->))?/ file:/^Hyalite Manor.md$/
```

I explain the regular expressions in the last section of this post.

As far as I know the results previews should always display the whole highlight (and comment, if any) because that’s what the pattern matches.

If 2 highlights are close together they’ll appear in the same preview. This can make the second one harder to notice, but I can live with it (the second one will become more obvious after I clear up the first one).

Clicking any result preview conveniently takes you to the highlight’s location in the document.

I’m so happy about this! :smiley:

Variants

To avoid duplicate filenames, use path: instead of file: (for example, path:Projects/Fiction/Hyalite Manor.md/).

You could easily modify the search to collect highlights from multiple files.

If you put your comments inside the highlights instead of after them, you could remove more than half of the regular expression (this part: ( *(%%[^(%%)]+%%)|(<!--[^(\-\->)]+-->))?).

If you only use 1 syntax for comments, you can remove the pattern that matches the other (see “Regular expression details”).

You could also collect comments that don’t immediately follow highlights. I didn’t because I use comments to summarize sections and I don’t want those summaries in my list of highlights. I’m planning to precede stand-alone comments with empty highlights (====), which is why the search matches those, but I could use some other convention instead. EDIT: Empty highlights are awkward; I’m using highlighted punctuation (==+==) instead to make it visible without affecting word count.

Speed the process with a template

The fastest way to set this up for a file would probably be to make a template for QuickAdd and/or Templater, to do something like “create a new file using this one’s name with ‘.highlights’ appended, and put in it the embedded query for this file’s highlights”.

I don’t use either of those (yet?), so I’ll set up a template that either:

  • makes the query with a placeholder for the filename (to be replaced manually), or
  • uses the current file’s name to create the link and search together (after which I’d cut the search, follow the link, and paste it into the new file).

Regular expression details

Here is a breakdown of the regular expressions used, because regular expressions are hard to read. (This is the last section, so if you don’t care about this then you’re done. :blush:)

The regular expression /==[^(==)]*==( *(%%[^(%%)]+%%)|(<!--[^(\-\->)]+-->))?/

matches a highlight ==[^(==)]*==

optionally followed by a comment ( *(%%[^(%%)]+%%)|(<!--[^(\-\->)]+-->))?.

The parentheses group things together so it works right. The question mark at the end makes the whole thing optional.

The comment can use Obsidian syntax %%[^(%%)]+%%

or |

HTML <!--[^(\-\->)]+-->

EDIT: The hyphens need to have backslashes in front of them to turn off the special meaning they have inside brackets.

The comment may be separated from the highlight by 0 or more spaces * (that’s a space followed by an asterisk). I didn’t bother to make it handle tabs as well as spaces, but you could.

The expressions for each of the 3 syntaxes (highlight, Obsidian comment, HTML comment) follow the same pattern:

opening marker ==

followed by 0 or more characters that don’t form the closing marker [^(==)]*.

The brackets there let me use the caret (^), which means “match anything except the following”. The parentheses make that apply to the pair of characters instead of just the first one — I think. I’m not sure they’re actually needed, but I don’t feel like looking it up yet. The asterisk at the end means to match the bracket expression 0 or more times.

I also use a regular expression to match the exact filename: file:/^Hylit Manor.md$/.

The caret means “beginning” and the dollar sign means “end”, so we only match the exact filename and not also, for example, Sequel to Hylit Manor.md.

28 Likes

Could you please show some screenshots? Or even better - a screencast. It’s really difficult to imagine what this is all about from the description.

2 Likes

Will do when I get a chance.

The community plugin Comments adds a sidebar display of comments but uses its own HTML format instead of the existing syntaxes.

2 Likes

Can we exclude “==” from the results? There must be regex that is searching them, but exclude them from result string.

You could probably do that with lookahead and/or lookbehind — see those terms at Assertions - JavaScript | MDN

So you might be able to replace ==[^(==)]*== with (?<=(==))==[^(==)]*==(?=(==)) (if I haven’t made a mistake). This probably works best (or perhaps only) if you put the comments inside the highlights instead if after them.

There is some mistake it doesn’t work

Sorry, try (?<=(==))[^(==)]+(?=(==)). I’ve also changed the * to + to guarantee at least 1 character between the highlight symbols.

I think you should get rid of the parentheses, otherwise your search will be broken if the highlighted text contains parentheses.

They’re meant to group the paired equals signs. Does that not work inside brackets?