I have found the following guide for getting the content of the current file:
const noteFile = this.app.workspace.getActiveFile(); // Currently Open Note
if(!noteFile.name) return; // Nothing Open
// Read the currently open note file. We are reading it off the HDD - we are NOT accessing the editor to do this.
let text = await this.app.vault.read(noteFile);
How can I remove YAML frontmatter from this? Or is there another way to get the file content so that YAML is already filtered out?
In theory, I could try to come up with a regular expression that would strip away everything that is between two --- lines (with the first --- line being the very first thing in the file). I just don’t think it’s a good idea to do this kind of thing myself, as it can be errorprone, and I would guess Obsidian already does a split like this. I just don’t know if there is API access for it.
I’ve been able to use the cached frontmatter information to do that
This is the relevant code (note that error checking is not present):
const file = app.workspace.getActiveFile();
let text = editor.getDoc().getValue()
let fmc = app.metadataCache.getFileCache(file)?.frontmatter;
let end = fmc.position.end.line + 1 // accont for ending ---
body = text.split("\n").slice(end).join("\n")
Thank you @endorama ! It took quite some time before I finally tried this. It’s working perfectly!
If it’s ok to you, I’ll use this in my Shell commands plugin, where I’ll create a new variable named {{note_content}} that allows users to pass current note’s content (without YAML) as input to system commands they execute.
const file = app.workspace.getActiveFile();
let text = editor.getDoc().getValue()
let position = app.metadataCache.getFileCache(file)?.frontmatterPosition;
let end = position.end.line + 1 // accont for ending ---
body = text.split("\n").slice(end).join("\n")
MetadataCache can be slightly outdated (especially when editing yaml using source mode), so I’d use @pellucid’s approach. But be careful, that pattern will also match 'before --- middle --- after' for example.
After all, all you have to do is just split the content into lines, check if the first line’s content is ---, and find the next --- line.
@ush the .replace() function only replaces the first instance of the match, and since frontmatter always occurs at the very beginning of the note there’s not any danger of extra stuff being replaced.
Also, off topic, but I think your plugins are really cool
the .replace() function only replaces the first instance of the match, and since frontmatter always occurs at the very beginning of the note there’s not any danger of extra stuff being replaced.
The problem is that --- can be a horizontal rule, not a front matter.
In the example below, the “I’m interested in Obsidian” section is removed.
You could also utilise the metadataCache and check which ones a potential frontmatter occupies, and then skip these lines when reading the other content.
This would ensure a proper check against what Obsidian considers the frontmatter or not. I.e. if it’s considered a legal frontmatter or not.
let { contentStart } = getFrontMatterInfo(fileContents);
// removing the frontmatter from a file
let withoutFrontmatter = fileContents.slice(contentStart);
// swapping the frontmatter
let replacedFrontmatter = '---\nfoo: bar\n---\n' + fileContents.slice(contentStart);
// prepending text to file without breaking frontmatter
let withPrependedText = fileContents.slice(0, contentStart) + 'hello' + fileContents.slice(contentStart);
If I understood correctly, getFrontMatterInfo() doesn’t have any caching? Just by looking at the parameter it gets, looks like it doesn’t know from which file the content is coming from, and therefore can’t do a per-file based caching?
If a single file’s content will be parsed multiple times during the same session (without the file’s content changing in between), would it still be better for performance (at least if the file is big) to use this older method that reads content from cache:
Yes, if you are not planning on modifying the file and do not need to latest version of the file contents, then getting the frontmatter info from the metadataCache is a better option.