module.exports = { settings: { name: 'Convert Dataview Inline YAML to YAML', author: 'AmericanBagel', options: { 'Excluded Files': { type: 'text', defaultValue: '.git', placeholder: 'A ":" seperated list of strings or regex', }, }, }, entry: async (params, settings) => { const { quickAddApi: { inputPrompt, suggester }, } = params; const metaedit = app.plugins.plugins['metaedit'].api; const vault = app.vault; const fs = app.vault.adapter; function clearFormattingCharacters(string) { return string.replace(/[*_~]/g, ''); } function getDataviewInlineYamlLines(string) { const lines = string.split('\n'); const matches = []; lines.forEach((line) => { // (?!`(\$=|=).*`) to exclude inline dataview code if ( line.match( /^[*_~]{0,3}[a-zA-Z-_]+[*_~]{0,3}::.*$(?!`(\$=|=).*`)/g ) && line.match(/^[*_~]{0,3}[a-zA-Z-_]+[*_~]{0,3}:: (?!`(\$=|=).*`)/gm) ) { matches.push(line); } }); return matches; } function removeDataviewInlineYamlLines(string) { const lines = string.split('\n'); let output = []; lines.forEach((line) => { // (?!`(\$=|=).*`) to exclude inline dataview code if ( !line.match( /^[*_~]{0,3}[a-zA-Z-_]+[*_~]{0,3}::.*$/g ) ) { output.push(line); } }); output = output.join('\n'); output = output.replace(/%%\s%%/g, ''); return output; } function convertToKebabCase(string) { return string .replace(/([a-z])([A-Z])/g, '$1-$2') .replace(/[\s_]+/g, '-') .toLowerCase(); } function parseAndAddProperty(obj, line) { const arr = line.split(':: '); obj[convertToKebabCase(clearFormattingCharacters(arr[0]))] = arr[1]; } function isTag(string) { // if (string.match(/(#[^\s]+)+/g)) if (string.startsWith('#')) { return true; } } function isLink(string) { if (string.match(/(\[\[[^\s]+\]\])[ ]*/g)) { return true; } } function getLinkFrontmatter(key, value) { console.log(value); console.log(typeof value); // This regex makes it only split when outside double brackets return listToFrontmatter(key, value.match(/(\[\[[^\]]*\]\]|\S)+/g)); } function getTagFrontmatter(key, value) { console.log(value); console.log(typeof value); return listToFrontmatter( key, value.split(' ').map((tag) => tag.replace(/^#/g, '')) ); } function listToFrontmatter(key, _value) { console.log('listToFrontmatter'); console.log('_value: ' + _value); let value = _value; if (typeof _value === 'string') { value = _value.replace(/[ \t]+$/g, '').split(' '); } console.log(value); let out = `${key}:\n`; for (element of value) { out += ` - "${element}"\n`; } return out; } function propertyToFrontmatter(key, value) { return `${key}: ${value}\n`; } async function convertNote(note) { let contents = await vault.read(note); const inlineLines = getDataviewInlineYamlLines(contents); inlineLines.forEach( (line) => (line = clearFormattingCharacters(line)) ); if (inlineLines.length > 0) { const inlineProperties = {}; inlineLines.forEach((line) => parseAndAddProperty(inlineProperties, line) ); let frontmatter = ''; for (const [key, value] of Object.entries(inlineProperties)) { if (isLink(value)) { console.log('isLink'); frontmatter += getLinkFrontmatter(key, value); } else if (isTag(value)) { console.log('isTag'); frontmatter += getTagFrontmatter(key, value); } else { frontmatter += propertyToFrontmatter(key, value); } } contents = removeDataviewInlineYamlLines(contents); let sections = contents.split('---\n'); if (sections.length === 1) { contents = `---\n${frontmatter}---\n\n` + contents; } else { sections[1] = sections[1].replace(/(?<=\n|^)\s/g, '') + frontmatter; contents = sections.join('---\n'); } await fs.write(note.path, contents); } } // Start const excluded = settings['Excluded Files']?.split(':'); let files = await app.vault.getMarkdownFiles(); console.log(files); files = files.filter((file) => { // Check if any excluded substring is present in the file name return !excluded.some((substring) => file.path.includes(substring)); }); const shouldContinue = await params.quickAddApi.yesNoPrompt( 'Are you sure you want to continue?', 'This will format ALL notes in your vault that are not excluded by the settings. This will effect ' + files.length + ' files.' ); files.forEach(async (file) => { convertNote(file); }); }, };