mbp-oskar.lan 2025-5-10:18:42:56
This commit is contained in:
177
quickadd_scripts/convert_ALL_inline_to_yaml.js
Normal file
177
quickadd_scripts/convert_ALL_inline_to_yaml.js
Normal file
@@ -0,0 +1,177 @@
|
||||
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);
|
||||
});
|
||||
},
|
||||
};
|
Reference in New Issue
Block a user