chhoumann / MetaEdit

MetaEdit for Obsidian
https://bagerbach.com
GNU General Public License v3.0
393 stars 15 forks source link

Metaedit doesn't edit arrays of tags properly. #94

Open Smitty010 opened 1 year ago

Smitty010 commented 1 year ago

Not sure whether I'm looking for a bug fix or an enhancement.

I tried to update my tags in the frontmatter using the frontmatter editor:

tags: 
- state/inprogress
- course-flash/writing-obsidian-plugins

I edited the string and ended up with:

tags: state/finished,course-flash/writing-obsidian-plugins
- state/inprogress
- course-flash/writing-obsidian-plugins

Not what I was expecting. I'm not sure how you are getting the original value of the tags ("state/inprogress,course-flash/writing-obsidian-plugins"), but either you should display a warning saying you don't edit arrays or it should work. Just my 2 cents. I should probably mention I did this via the metaedit command in the command palette, not the api

vorpalvorpal commented 11 months ago

I had the same problem. The issue is that metaedit splits the file content by "/n", searches for the key in each line, and then replaces the line when it finds the appropriate key. I edited the "updatePropertyInFile" function to instead split the file content into frontmatter and body content. It then uses obsidian's inbuilt parseYaml and stringifyYaml functions on the frontmatter, and uses the existing approach on the body content.

     async updatePropertyInFile(property, newValue, file) {
        const YAMLregex = /((^---\s)([\s\S]*?[\r\n])(---\s)){0,1}([\s\S]*)/;
        const rawContent = await this.app.vault.read(file);
        const fileContent = rawContent.match(YAMLregex);
        var parsedYaml = obsidian.parseYaml(fileContent[3]);
          parsedYaml[property.key] = newValue
        const newBody = fileContent[5].split("\n").map(line => {
            if (this.lineMatch(property, line)) {
                return this.updatePropertyLine(property, newValue, line);
            }
            return line;
        }).join("\n");
        const newFileContent = fileContent[2] + obsidian.stringifyYaml(parsedYaml) + fileContent[4] + newBody
        await this.app.vault.modify(file, newFileContent);
    }

Arrays in the frontmatter work correctly for me now.