Repository: platers/obsidian-linter (ts)

Issue:
Bug: Move tags from body also moves "tags" from other YAML attributes
## Describe the Bug

When enabling move tag to YAML, other attributes in YAML which uses the format `#.*` also gets moved to tags

## How to Reproduce

Steps to reproduce the behavior:

1. Enable `Breadcrumbs` plugin
2. Enable `dataview` plugin
3. Then create a file with the code below

``` markdown
---
BC-dataview-note: "#tag1 and #tag2"
BC-dataview-note-field: parent
---

# Title 

#tag-body
```

`after linting`:
``` markdown
---
tags:
- tag2"
- tag-body
BC-dataview-note: "#tag1 and
BC-dataview-note-field: parent
---

# Title 

```

`config` extract
```json
    "Move Tags to Yaml": {
      "Move all tags to Yaml frontmatter of the document.": true,
      "Body tag operation": "Remove whole tag",
      "Tags to ignore": ""
    }
```

## Expected Behavior

A clear and concise description of what you expected to happen.

Expected output if applicable:
``` markdown
---
tags:
- tag-body
BC-dataview-note: "#tag1 and #tag2"
BC-dataview-note-field: parent
---

# Title 

```

## Screenshots

`Before linting`
<img width="739" alt="image" src="https://user-images.githubusercontent.com/56354081/227102430-c33959bd-f4c4-4480-a87f-c9e11b231f90.png">

`After Linting`
<img width="787" alt="image" src="https://user-images.githubusercontent.com/56354081/227102479-6ab56e65-c4ba-4dda-a4f0-917b86f7fe15.png">

`Lint again outputs error`
<img width="1248" alt="image" src="https://user-images.githubusercontent.com/56354081/227102526-fde59b35-095d-4ca5-b0b5-be319c7a849b.png">


## Device

- [X] Desktop
- [ ] Mobile

## Additional Context

Add any other context about the problem here.


Pull request description:
Fixes Removing/Affecting Tag Regex Matches in YAML
Fixes #661 

Changes Made: 
- Updated logic in order to avoid having regex matches erroneously remove YAML values
- Added a UT that should hopefully help us avoid this scenario in the future

Patch:
diff --git a/src/rules/move-tags-to-yaml.ts b/src/rules/move-tags-to-yaml.ts
index 10fc8eb..29dbd5b 100644
--- a/src/rules/move-tags-to-yaml.ts
+++ b/src/rules/move-tags-to-yaml.ts
@@ -45,7 +45,16 @@ export default class MoveTagsToYaml extends RuleBuilder<MoveTagsToYamlOptions> {
   }
   apply(text: string, options: MoveTagsToYamlOptions): string {
     return ignoreListOfTypes([IgnoreTypes.code, IgnoreTypes.inlineCode, IgnoreTypes.math, IgnoreTypes.html, IgnoreTypes.wikiLink, IgnoreTypes.link], text, (text) => {
-      const tags = matchTagRegex(text);
+      let tags: string[];
+
+      // need to ignore YAML when getting regex matches to avoid improper matches with YAML contents
+      // https://github.com/platers/obsidian-linter/issues/661
+      ignoreListOfTypes([IgnoreTypes.yaml], text, (text) => {
+        tags = matchTagRegex(text);
+
+        return text;
+      });
+
       if (tags.length === 0) {
         return text;
       }
@@ -92,22 +101,26 @@ export default class MoveTagsToYaml extends RuleBuilder<MoveTagsToYamlOptions> {
         return `---\n${newYaml}---`;
       });
 
-      if (options.howToHandleExistingTags !== 'Nothing') {
-        text = text.replace(tagWithLeadingWhitespaceRegex, (tag: string) => {
-          const hashtagIndex = tag.indexOf('#');
+      text = ignoreListOfTypes([IgnoreTypes.yaml], text, (text) => {
+        if (options.howToHandleExistingTags !== 'Nothing') {
+          text = text.replace(tagWithLeadingWhitespaceRegex, (tag: string) => {
+            const hashtagIndex = tag.indexOf('#');
 
-          const tagContents = tag.substring(hashtagIndex+1);
-          if (options.tagsToIgnore.includes(tagContents)) {
-            return tag;
-          }
+            const tagContents = tag.substring(hashtagIndex+1);
+            if (options.tagsToIgnore.includes(tagContents)) {
+              return tag;
+            }
 
-          if (options.howToHandleExistingTags === 'Remove hashtag') {
-            return tag.substring(0, hashtagIndex) + tagContents;
-          }
+            if (options.howToHandleExistingTags === 'Remove hashtag') {
+              return tag.substring(0, hashtagIndex) + tagContents;
+            }
 
-          return '';
-        });
-      }
+            return '';
+          });
+        }
+
+        return text;
+      });
 
       // Make sure that the yaml frontmatter does not have whitespace added after the end of the yaml frontmatter.
       // This accounts for https://github.com/platers/obsidian-linter/issues/573


Test patch:
diff --git a/__tests__/move-tags-to-yaml.test.ts b/__tests__/move-tags-to-yaml.test.ts
index 76e40a8..f684a3e 100644
--- a/__tests__/move-tags-to-yaml.test.ts
+++ b/__tests__/move-tags-to-yaml.test.ts
@@ -220,5 +220,33 @@ ruleTest({
         howToHandleExistingTags: 'Remove whole tag',
       },
     },
+    { // accounts for https://github.com/platers/obsidian-linter/issues/661
+      testName: 'Make sure that moving tags to YAML does not affect values in the YAML beyond the tag values',
+      before: dedent`
+        ---
+        BC-dataview-note: "#tag1 and #tag2"
+        BC-dataview-note-field: parent
+        ---
+        ${''}
+        # Title
+        ${''}
+        #tag-body
+      `,
+      after: dedent`
+        ---
+        BC-dataview-note: "#tag1 and #tag2"
+        BC-dataview-note-field: parent
+        tags: tag-body
+        ---
+        ${''}
+        # Title
+        ${''}
+      `,
+      options: {
+        tagArrayStyle: TagSpecificArrayFormats.SingleStringSpaceDelimited,
+        howToHandleExistingTags: 'Remove whole tag',
+      },
+    },
+
   ],
 });