Skip to content

Public API

David edited this page May 31, 2026 · 1 revision

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.

Stability promise

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.

Surface

sr.version: string

Mirrors manifest.json.

sr.queries

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
}

sr.parse

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.

sr.cards

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

sr.domains

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.

sr.onIndexChange(cb: () => void): () => void

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();

Example: Templater concept inserter

<%*
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');
%>

Example: Dataview JS — "questions that touch concept X"

```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,
]));
```

Example: react to index changes

// Inside another plugin's onload():
this.register(
  app.plugins.plugins['semantic-reading'].api.onIndexChange(() => {
    this.recomputeMyOwnState();
  })
);

See also

Clone this wiki locally