Annotate text inline using the syntax
{={identifier}text }
Then view and navigate all annotations from a unified sidebar. Annotations can be styled with custom colors and font sizes, and are exposed to Dataview as structured metadata.
- Inline annotations — wrap any text in
{={parent/child}your note=}to tag it with an identifier - Live Preview rendering — delimiters and identifier are hidden; only the annotated text is shown (optionally styled)
- Annotations sidebar — collects all annotations vault-wide, grouped by identifier, with one-click navigation to each source location
- Custom styling — assign font color, background color, and font size to any identifier or wildcard pattern
- Dataview integration — annotations are exposed as a
ccfield on each note's page object - Config file support — define identifier styles in a Markdown table in your vault instead of the settings UI
{={identifier}annotated text=}
{={parent/child}annotated text=}
identifier— a plain parent identifier, e.g.{={note}this is important=}parent/child— a two-level identifier, e.g.{={math/hot}key formula=}- Wildcards in style config:
math/*matches anymath/childannotation
[!info] Do not leave a space between the identifier and the text!
Examples
The function {={note}converges in O(n log n)=} for all inputs.
This approach {={math/hot}maximizes the posterior=} under the prior.
The sample statistic {={stats}is an unbiased estimator=} of the mean.
Note: Do not place annotations inside inline code
`...`or fenced code blocks — the plugin skips those regions.
Open Settings → Annotation Manager to configure the plugin.
| Option | Description |
|---|---|
| Settings UI | Define identifier styles directly in the settings panel |
| Config file | Read styles from a Markdown table in your vault |
When Config file is selected, specify a vault-relative path (default: OccConfig.md) and use the Create / update config file button to generate the file from your current settings. The plugin auto-reloads styles whenever the file is saved.
| Identifier | Font Color | Background Color | Font Size | Example |
| ---------- | ---------- | ---------------- | --------- | ------- |
| math/hot | ff6b6b | fff0f0 | 1.1em | <span style="color: #ff6b6b; background-color: #fff0f0; font-size: 1.1em">Example</span> |
| math/* | 4ecdc4 | | | <span style="color: #4ecdc4">Example</span> |
| stats | ffd93d | fffbe6 | | <span style="color: #ffd93d; background-color: #fffbe6">Example</span> |- Column order must match: Identifier, Font Color, Background Color, Font Size, Example
- Do not use the
#prefix for hex colors (i.e. onlyff6b6bis accepted) - Leave a cell blank to inherit the default value
- Font size accepts any CSS value:
1.1em,14px,0.9rem, etc. - The Example column is auto-generated when you use Create / update config file — it renders a styled preview of each identifier directly in the table
- Open Settings → Annotation Manager
- Under Add Identifier, enter the identifier name (e.g.
math/hotorstats) and click Add - Set the desired Font color, Background color, and/or Font size
- Changes apply immediately to all open editors and Reading View panes
Wildcard styles — enter math/* to style all math/child annotations that don't have their own specific style. Specific identifiers always take precedence over wildcards.
Open the sidebar via:
- The message-square ribbon icon on the left (or right) sidebar
- The command Show annotations sidebar
The sidebar lists every annotation in the vault, grouped by identifier. Each entry shows a preview of the annotation text and the file + line number where it appears. Click any entry to open that file and jump to the annotation.
Use Expand All / Collapse All to show or hide all groups at once. Individual groups can be toggled by clicking their header row. Collapse state is preserved across re-renders within a session.
| Command | Description |
|---|---|
| Show annotations sidebar | Toggle the CC annotations sidebar open/closed |
| Apply identifier to selection | Open a picker to wrap selected text (or insert a blank annotation at cursor) with a chosen identifier |
| Toggle bracket/identifier visibility | Show or hide the {={id} and =} delimiters in Live Preview and Reading View |
| Toggle bracket/identifier formatting | Enable or disable custom colors on the bracket and identifier portion (visible in Source Mode) |
| Toggle text formatting | Enable or disable custom colors on the annotation text content |
When the Dataview plugin is enabled, each note gets a cc field containing an array of annotation objects — one per annotation found in that note.
Each object has four properties:
parent— the parent part of the identifier (e.g.math)child— the child part (e.g.hot), or an empty string if nonetext— the annotation contentline— the 1-based line number where the annotation appears in the file
Show all math/hot and stats annotations across the vault as a table:
dataview
TABLE rows.c.parent AS Parent, rows.c.child AS Child, rows.c.text AS "Annotation"
FROM ""
FLATTEN cc AS c
WHERE (c.parent = "math" AND c.child = "hot") OR c.parent = "stats"
GROUP BY file.link AS File
Show all math/hot and stats annotations across the vault as a table, with a header, clickable line numbers, and sorted by Note → Identifier → Line → Annotation:
dataviewjs
const targets = [
{ parent: 'math', child: 'hot' },
{ parent: 'stats', child: '' },
];
function matches(ann, t) {
return ann.parent === t.parent && ann.child === t.child;
}
const terms = targets.map(t => t.child ? `${t.parent}/${t.child}` : t.parent);
dv.header(2, 'Annotations for ' + terms.join(' and '));
function lineLink(filePath, line) {
const el = document.createElement('a');
el.textContent = String(line);
el.href = '#';
el.classList.add('internal-link');
el.addEventListener('click', async (e) => {
e.preventDefault();
const file = app.vault.getAbstractFileByPath(filePath);
if (!file) return;
const leaf = app.workspace.getLeaf(false);
await leaf.openFile(file);
const view = leaf.view;
if (view?.editor) {
const pos = { line: line - 1, ch: 0 };
view.editor.setCursor(pos);
view.editor.scrollIntoView({ from: pos, to: pos }, true);
}
});
return el;
}
const rows = [];
for (const page of dv.pages().where(p => p.cc)) {
for (const ann of page.cc) {
if (targets.some(t => matches(ann, t))) {
const id = ann.child ? `${ann.parent}/${ann.child}` : ann.parent;
rows.push({
note: page.file.name,
link: page.file.link,
filePath: page.file.path,
id,
line: ann.line,
text: ann.text,
});
}
}
}
rows.sort((a, b) => {
if (a.note !== b.note) return a.note.localeCompare(b.note);
if (a.id !== b.id) return a.id.localeCompare(b.id);
if (a.line !== b.line) {
if (a.line == null) return 1;
if (b.line == null) return -1;
return a.line - b.line;
}
return String(a.text).localeCompare(String(b.text));
});
dv.table(
['Note', 'Identifier', 'Line', 'Annotation'],
rows.map(r => [r.link, r.id, r.line ? lineLink(r.filePath, r.line) : '', r.text])
);- This plugin has been tested with the built-in and Minimal themes only.
- Annotations are parsed from raw Markdown, so they work in both Live Preview and Source Mode
- The
{= and =}delimiters are hidden only in Live Preview and Reading View; they are always visible in Source Mode - When bracket visibility is toggled off, annotations display as raw text in Reading View and are not styled
- Avoid =} in annotation content — the lazy match will truncate the annotation at the first
=}it finds - Custom colors are applied via inline styles, which override CM6 syntax highlighting
Written by Claude!


