178 lines
		
	
	
		
			6.0 KiB
		
	
	
	
		
			JavaScript
		
	
	
	
	
	
			
		
		
	
	
			178 lines
		
	
	
		
			6.0 KiB
		
	
	
	
		
			JavaScript
		
	
	
	
	
	
| 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);
 | |
|         });
 | |
|     },
 | |
| };
 |