-
Notifications
You must be signed in to change notification settings - Fork 0
Public API
Other plugins, Templater snippets, Dataview JS blocks, QuickAdd templates, and any code running inside Obsidian can query Semantic Reading directly:
const sr = app.plugins.plugins['semantic-reading']?.api;
if (sr) {
const questions = sr.queries.openQuestions();
console.log(`${questions.length} open questions across the vault`);
}Always guard against undefined — plugin disabled / not installed / not yet loaded.
Methods on sr will not be removed or have their signatures narrowed within a major version. New methods may be added. Read sr.version to branch on plugin version if you need to.
Mirrors manifest.json.
Read-only queries against the live vault tag index. Cheap — the index is in memory.
| Method | Returns |
|---|---|
byTag(tag: string) |
Mention[] — every mention of a sigil across the vault |
concepts() |
ConceptEntry[] — every Def hub entry |
concept(canonical: string) |
ConceptEntry | undefined — one concept by canonical slug |
openQuestions() |
Mention[] — every Q
|
actions() |
Mention[] — every A
|
tagCounts() |
Record<string, number> — sigil → mention count |
rev() |
number — monotonic index revision (bumps means index changed) |
raw() |
VaultIndex — the raw underlying index (read-only) |
interface Mention {
notePath: string;
paraIndex: number; // 0-based
blockId: string; // canonical block id we assign per paragraph
text: string;
note?: string;
wikilink?: string;
}
interface ConceptEntry {
canonical: string; // slug e.g. "cognition"
display: string; // first-seen display text
mentions: Mention[];
coOccurs: Record<string, number>; // other concept canonical → co-occurrence count
}Pure parsing & serialization helpers. No side effects.
| Method | Purpose |
|---|---|
body(body: string) |
parse a markdown body into Paragraph[]
|
serializeParagraph(segs: Segment[]) |
round-trip a paragraph back to {{Tag|text}} syntax |
canonicalize(text: string) |
convert display text into the canonical slug ("Cognition" → "cognition") |
type Paragraph = Segment[];
interface Segment {
text: string;
tag?: string;
note?: string;
wikilink?: string;
}Useful for: building your own custom views, validating tags before writing them, transforming notes outside the plugin's own commands.
Card scheduling (FSRS) data.
| Method | Returns |
|---|---|
all() |
Card[] — every card derivable from the index |
due() |
Card[] — cards due now per FSRS |
state(cardId: string) |
CardState | undefined — persisted FSRS state for a card |
Per-note tag toolkits — see Domain Profiles for the conceptual model.
| Method | Returns |
|---|---|
list() |
DomainProfile[] — every configured profile (incl. disabled) |
forNote(notePath: string) |
DomainProfile | null — the active profile for a note |
tagsFor(notePath: string) |
Record<string, TagDef> — effective TAGS dictionary for that note (respects mergeMode) |
interface DomainProfile {
name: string; // matches semantic_domain frontmatter
label: string;
mergeMode: 'add' | 'replace' | 'subset';
keepBuiltins?: string[]; // for 'subset' — which builtin sigils survive
tags: CustomTagDef[]; // tags this profile adds
defaultMode?: number; // optional 1..5 tagbar default
disabled?: boolean;
}tagsFor() is the right entry point if you want to know "what tags can this note actually use" without mutating the global registries.
Subscribe to vault-index changes. Returns an unsubscribe function. Fired after each incremental rebuild.
const unsub = sr.onIndexChange(() => {
console.log('Index updated. Total concepts now:', sr.queries.concepts().length);
});
// Later:
unsub();<%*
const sr = app.plugins.plugins['semantic-reading']?.api;
if (!sr) { tR += 'plugin not loaded'; return; }
const concepts = sr.queries.concepts()
.filter(c => c.mentions.length >= 3)
.sort((a, b) => b.mentions.length - a.mentions.length)
.slice(0, 10);
tR += concepts.map(c => `- [[Concepts/${c.canonical}]] (${c.mentions.length})`).join('\n');
%>```dataviewjs
const sr = app.plugins.plugins['semantic-reading']?.api;
if (!sr) { dv.paragraph('plugin not loaded'); return; }
const target = 'cognition';
const qs = sr.queries.openQuestions().filter(q =>
q.text.toLowerCase().includes(target)
);
dv.table(['Note', '¶', 'Question'], qs.map(q => [
dv.fileLink(q.notePath.replace(/\.md$/, '')),
q.paraIndex + 1,
q.text,
]));
```// Inside another plugin's onload():
this.register(
app.plugins.plugins['semantic-reading'].api.onIndexChange(() => {
this.recomputeMyOwnState();
})
);- MCP Server — same data, exposed over JSON-RPC for out-of-process clients
-
Tag Taxonomy — what each
tagstring means -
Domain Profiles — what
sr.domains.tagsFor()actually resolves - Settings Reference — where the plugin reads its own settings from