diff --git a/main.ts b/main.ts index 3faf473..4d086ad 100644 --- a/main.ts +++ b/main.ts @@ -122,14 +122,27 @@ export default class TagPagePlugin extends Plugin { tagOfInterest, ); + if (!activeLeaf.file) { + return; + } + + this.app.fileManager.processFrontMatter(activeLeaf.file, frontMatter => { + frontMatter[this.settings.frontmatterQueryProperty] = tagOfInterest + frontMatter.tags ??= []; + frontMatter.tags = [...new Set(frontMatter.tags).add('tag-page-md').add(tagOfInterest.slice(1) /* Omit the leading # */)] + }) + + const baseContent = await this.app.vault.read(activeLeaf.file); const tagPageContentString = await generateTagPageContent( this.app, this.settings, tagsInfo, tagOfInterest, + baseContent, ); swapPageContent(activeLeaf, tagPageContentString); + activeLeaf.save(); } /** diff --git a/src/utils/pageContent.ts b/src/utils/pageContent.ts index 808388f..bc762e7 100644 --- a/src/utils/pageContent.ts +++ b/src/utils/pageContent.ts @@ -10,6 +10,7 @@ import { getIsWildCard } from './tagSearch'; * @param {PluginSettings} settings - The plugin settings. * @param {TagInfo[]} tagsInfo - Information about tags. * @param {string} tagOfInterest - The tag for which the page is being generated. + * @param {string} baseContent - The original content of the page * @returns {Promise} - The content to be set in the tag page. */ export type GenerateTagPageContentFn = ( @@ -17,8 +18,24 @@ export type GenerateTagPageContentFn = ( settings: PluginSettings, tagsInfo: TagInfo, tagOfInterest: string, + baseContent?: string, ) => Promise; +const _parseContent = ( + baseContent: string, +) => { + const match = baseContent.match( + /^(?---\n.*?\n---\n)?(?:(?.*?)\n)?(?%%\ntag-page-md.*?tag-page-md end\n%%)(?:\n(?.*?))?$/s, + ); + if (!match || !match.groups) { + return { frontmatter: '', before: '', after: '' }; + } + return { + frontmatter: match.groups.frontmatter ?? '', + before: match.groups.before ?? '', + after: match.groups.after ?? '', + }; +}; /** * Generates the content for a tag page. * @@ -26,6 +43,7 @@ export type GenerateTagPageContentFn = ( * @param {PluginSettings} settings - The plugin settings. * @param {TagInfo[]} tagsInfo - Information about tags. * @param {string} tagOfInterest - The tag for which the page is being generated. + * @param {string} baseContent - The original content of the page * @returns {Promise} - The content to be set in the tag page. */ export const generateTagPageContent: GenerateTagPageContentFn = async ( @@ -33,12 +51,23 @@ export const generateTagPageContent: GenerateTagPageContentFn = async ( settings: PluginSettings, tagsInfo: TagInfo, tagOfInterest: string, + baseContent = '', ): Promise => { // Generate list of links to files with this tag const tagPageContent: string[] = []; - tagPageContent.push( - `---\n${settings.frontmatterQueryProperty}: "${tagOfInterest}"\n---`, - ); + + // Try to extract comments from the page to spot injection placeholder + const { frontmatter, before, after } = _parseContent(baseContent); + + if(frontmatter){ + tagPageContent.push(frontmatter); + } + + if (before) { + tagPageContent.push(before); + } + tagPageContent.push('%%\ntag-page-md\n%%\n'); + tagPageContent.push(`## Tag Content for ${tagOfInterest.replace('*', '')}`); // Check if we have more than one baseTag across all tagInfos @@ -85,6 +114,11 @@ export const generateTagPageContent: GenerateTagPageContentFn = async ( tagPageContent.push(`## Files with ${cleanedTag} in frontmatter`); tagPageContent.push(...filesWithFrontmatterTag); } + + tagPageContent.push('\n%%\ntag-page-md end\n%%'); + if (after) { + tagPageContent.push(after); + } return tagPageContent.join('\n'); }; @@ -103,8 +137,9 @@ export const extractFrontMatterTagValue = ( ): string | undefined => { if (view.file) { try { - const metaMatter = app.metadataCache.getFileCache(view.file) - ?.frontmatter; + const metaMatter = app.metadataCache.getFileCache( + view.file, + )?.frontmatter; return metaMatter?.[frontMatterTag]; } catch (err) {