Dynamic Text Highlighting

approved

by Philipp Reichelt

Highlight text with custom search terms, regular expressions and badges in the editor, reading view and PDF export, and highlight all matches of the selected word. - This plugin has not been manually reviewed by Obsidian staff.

48 downloadsUpdated 4d agoMIT

Dynamic Text Highlighting

Highlight text in your notes with your own search terms and regular expressions, turn placeholders such as =TODO= into badges, and see every occurrence of the word under the cursor.

Highlighters work in the editor, and optionally in reading view and exported PDFs.

Features

  • Highlighters: define search terms or regular expressions and choose how matches look: background, badge, text color, wavy underline or only a CSS class.
  • Badges for placeholders: show only the first capture group of a match, e.g. =(TODO)= renders as a TODO badge without the equals signs. In live preview the equals signs reappear while the cursor is inside.
  • Reading view and PDF export: highlighters can also apply to rendered notes, so badges and highlights end up in printed documents.
  • Selection highlighting: highlight all occurrences of the word under the cursor or of the selected text, with a minimum length, a match limit, a delay and a list of ignored words.
  • Import and export: share highlighters as JSON. Configurations of the Dynamic Highlights plugin can be imported, including its custom CSS.
  • Commands: toggle highlighters and selection highlighting from the command palette or a hotkey.

Code blocks, inline code, math and front matter are never highlighted.

Highlighters

Open Settings → Dynamic Text Highlighting and add a highlighter with the plus button. Each highlighter has these options:

OptionDescription
NameShown in the list of highlighters.
EnabledTurn a single highlighter on or off.
SearchText to find, or a regular expression.
Regular expressionTreat the search as a JavaScript regular expression.
Case sensitiveMatch upper and lower case exactly.
StyleBackground, badge, text color, wavy underline, or none (CSS class only).
ColorColor of the highlight. Text on backgrounds and badges switches between dark and light automatically.
Show only the first capture groupRegular expressions only. Hide the rest of the match.
Named groups as CSS classesRegular expressions only. In the editor, a named group (?<name>...) gets its name as CSS class.
Highlight whole lineTint the entire line of a match in the editor.
Reading view and PDF exportAlso highlight in rendered notes.
CSS classExtra class on every match, for styling with a CSS snippet.

Drag highlighters to reorder them. When matches overlap in reading view, the highlighter higher in the list wins.

Default highlighters

New installations start with three badge highlighters as an example:

NameSearchStyleColor
TODO badge=(TODO)=BadgeYellow
FIXME badge=(FIXME)=BadgeOrange
DONE badge=(DONE)=BadgeGreen
Chapter 3 =TODO= add sources
The formula is not correct yet =FIXME=

Examples

PurposeSearchSettings
Priority badges=(P[1-3])=Regex, badge, first capture group, reading view
Filler words\b(basically|actually|very)\bRegex, wavy underline
Repeated spaces {2,}Regex, background
Dates in ISO format\d{4}-\d{2}-\d{2}Regex, text color
A name you want to spotJane DoeBackground

Regular expressions with lookbehind, such as (?<=x), do not work on iOS versions older than 16.4.

Styling with CSS snippets

Every match has the classes dth-match and dth-style-<style> and, if set, the highlighter's CSS class. Set --dth-background and --dth-foreground to override the colors, for example with a gradient badge:

.priority-high {
  --dth-background: linear-gradient(135deg, #ff2d87 0%, #7b2ff7 100%);
  --dth-foreground: #ffffff;
  text-shadow: 0 1px 1px rgba(0, 0, 0, 0.35);
}

With Highlight whole line, the line gets dth-line and <css class>-line. Selection matches use dth-selection-match and, for the occurrence at the cursor, dth-selection-match-main.

Migrating from Dynamic Highlights

  1. Keep Dynamic Highlights installed and open Settings → Dynamic Text Highlighting.
  2. Under Import and export, select Import from Dynamic Highlights. All persistent highlighters are added with their names, search terms, colors and CSS classes.
  3. Custom CSS of those highlighters is saved as the CSS snippet dynamic-highlights-import. Enable it under Settings → Appearance → CSS snippets.
  4. Disable Dynamic Highlights to avoid double highlighting.

Selection settings are not imported. Dynamic Highlights applied the highlighter color through generated CSS; the imported highlighters use the style Background with the same color instead.

Limitations

  • In reading view and PDF export, a match must lie within one piece of formatted text. A search for a b does not match a **b**.
  • Named groups as CSS classes and whole line highlighting only apply in the editor.

Privacy

The plugin works entirely offline. It makes no network requests and collects no data. It only reads files inside your vault configuration folder when you import from Dynamic Highlights, and only writes a CSS snippet there during that import.

Installation

From the community plugins directory

  1. Open Settings → Community plugins and turn off restricted mode.
  2. Select Browse, search for Dynamic Text Highlighting and select Install.
  3. Select Enable.

Manual installation

  1. Download main.js, manifest.json and styles.css from the latest release.
  2. Copy them into <your vault>/.obsidian/plugins/dynamic-text-highlighting/.
  3. Reload Obsidian and enable Dynamic Text Highlighting under Settings → Community plugins.

Requires Obsidian 1.13.0 or later.

Development

Requires Node.js 22 or later.

npm install
npm run dev     # rebuild main.js on every change
npm run build   # type check and production build
npm run lint    # lint with eslint-plugin-obsidianmd

To test changes, copy main.js, manifest.json and styles.css into <your vault>/.obsidian/plugins/dynamic-text-highlighting/ after building, or clone the repository into that folder.

Releasing a new version

  1. Run npm version patch, npm version minor or npm version major. This updates package.json, manifest.json and versions.json and creates a Git tag without a v prefix.
  2. Push the commit and the tag: git push --follow-tags.
  3. The release workflow lints and builds the plugin and creates a draft release with main.js, manifest.json and styles.css. Review and publish it on GitHub.

Acknowledgements

Inspired by Dynamic Highlights by NothingIsLost, which is no longer listed in the community plugins directory. This plugin is a separate implementation and does not contain its code.

License

MIT

For plugin developers

Search results and similarity scores are powered by semantic analysis of your plugin's README. If your plugin isn't appearing for searches you'd expect, try updating your README to clearly describe your plugin's purpose, features, and use cases.