Access frontmatter in MarkdownCodeBlockProcessor

Hi, I’m trying to develop a plugin, which needs to access frontmatter to read user per-file default configurations.

I found that MarkdownPostProcessorContext has the frontmatter member, but when I access it, it is empty.

I also found I can access the last frontmatter from app.workspace.activeEditor.lastFrontmatter, which is an undocumented member.

I wonder for the first case, how to correctly get the frontmatter, and for the second case, is it a safe and backward-compatible implementation?

Thanks!

I’m using gray-matter. I’ve not found a way to reliably get the current (rather than a few seconds old) frontmatter, without external dependencies.

MarkdownPostProcessorContext.getSectionInfo() gives you the first and last line numbers of the code block.

MarkdownView.editor gives you an Editor instance for the file in that View. (WorkspaceLeaf.view.editor)

import GrayMatter from "gray-matter"

const EditorLine = (line: number): EditorPosition => ({ line, ch: 0 })
function codeBlockHandler(markdown: string, containerEl: HTMLDivElement, ctx: MarkdownPostProcessorContext) {
  const leaf: WorkspaceLeaf = app.workspace.rootSplit.children[0].children[0]
  const view: MarkdownView = leaf.view
  const editor: Editor = view.editor

  const sectionInfo: MarkdownSectionInformation = ctx.getSectionInfo()
  const lineStart = EditorLine(sectionInfo.lineStart + 1)
  const lineEnd   = EditorLine(sectionInfo.lineEnd  )

  const text = editor.getRange(lineStart, lineEnd)
  const gm = GrayMatter(text)
  const frontmatter = gm.data
}

Finding the associated WorkspaceLeaf is another non-trivial problem.
You need to iterate through all leaves to find one where leaf.containerEl.contains(codeBlock.containerEl). When the leaf is first created, the codeBlock handler is executed first, so you have to wait until after this function has finished executing and the leaf has been constructed, before you can find a leaf that matches that condition.

Got it, thanks for your quick reply.

And if you want to update the frontmatter:

  update(gm.data)

  editor.replaceRange(
    GrayMatter.stringify(gm.content, gm.data),
    lineStart, lineEnd
  )