Repository: platers/obsidian-linter (ts)

Issue:
Bug: `Proper Ellipsis` rule breaks transcluded links
## Describe the Bug

`Proper Ellipsis` rule breaks transcluded links

## How to Reproduce

``` markdown
![title](a...b.md)

![](c...d.png)
```

Apply `Proper Ellipsis` rule

## Expected Behavior

The note is unchanged

## Actual behavior Behavior

The three consecutive dots `...` were replaced with a single Unicode character `…`, breaking the links

``` markdown
![title](a…b.md)

![](c…d.png)
```

Pull request:
Skip images together with links
Fixes #611 

Patch:
diff --git a/src/main.ts b/src/main.ts
index 3ae9f65..2fb6511 100644
--- a/src/main.ts
+++ b/src/main.ts
@@ -56,7 +56,6 @@ const DEFAULT_SETTINGS: Partial<LinterSettings> = {
     tagArrayStyle: NormalArrayFormats.SingleLine,
     minimumNumberOfDollarSignsToBeAMathBlock: 2,
     escapeCharacter: '"',
-    removeUnnecessaryEscapeCharsForMultiLineArrays: false,
   },
 };
 
diff --git a/src/rules-runner.ts b/src/rules-runner.ts
index b65891e..903992b 100644
--- a/src/rules-runner.ts
+++ b/src/rules-runner.ts
@@ -64,7 +64,6 @@ export class RulesRunner {
         aliasArrayStyle: runOptions.settings.commonStyles.aliasArrayStyle,
         tagArrayStyle: runOptions.settings.commonStyles.tagArrayStyle,
         defaultEscapeCharacter: runOptions.settings.commonStyles.escapeCharacter,
-        removeUnnecessaryEscapeCharsForMultiLineArrays: runOptions.settings.commonStyles.removeUnnecessaryEscapeCharsForMultiLineArrays,
       });
       timingEnd(rule.alias());
     }
diff --git a/src/rules.ts b/src/rules.ts
index 6b1b217..cd3ffa8 100644
--- a/src/rules.ts
+++ b/src/rules.ts
@@ -23,7 +23,6 @@ export type CommonStyles = {
   tagArrayStyle: TagSpecificArrayFormats | NormalArrayFormats | SpecialArrayFormats;
   minimumNumberOfDollarSignsToBeAMathBlock: number;
   escapeCharacter: string;
-  removeUnnecessaryEscapeCharsForMultiLineArrays: boolean;
 }
 
 export type Options = { [optionName: string]: any};
diff --git a/src/rules/format-yaml-arrays.ts b/src/rules/format-yaml-arrays.ts
index d469e99..d266091 100644
--- a/src/rules/format-yaml-arrays.ts
+++ b/src/rules/format-yaml-arrays.ts
@@ -26,10 +26,6 @@ class FormatYamlArrayOptions implements Options {
   formatArrayKeys?: boolean = true;
   forceSingleLineArrayStyle?: string[] = [];
   forceMultiLineArrayStyle?: string[] = [];
-  @RuleBuilder.noSettingControl()
-    defaultEscapeCharacter?: string = '"';
-  @RuleBuilder.noSettingControl()
-    removeUnnecessaryEscapeCharsForMultiLineArrays?: boolean = false;
 }
 
 @RuleBuilder.register
@@ -55,15 +51,7 @@ export default class RuleTemplate extends RuleBuilder<FormatYamlArrayOptions> {
 
       for (const aliasKey of OBSIDIAN_ALIASES_KEYS) {
         if (options.formatAliasKey && Object.keys(yaml).includes(aliasKey)) {
-          text = setYamlSection(text,
-              aliasKey,
-              formatYamlArrayValue(
-                  convertAliasValueToStringOrStringArray(splitValueIfSingleOrMultilineArray(getYamlSectionValue(text, aliasKey))),
-                  options.aliasArrayStyle,
-                  options.defaultEscapeCharacter,
-                  options.removeUnnecessaryEscapeCharsForMultiLineArrays,
-              ),
-          );
+          text = setYamlSection(text, aliasKey, formatYamlArrayValue(convertAliasValueToStringOrStringArray(splitValueIfSingleOrMultilineArray(getYamlSectionValue(text, aliasKey))), options.aliasArrayStyle));
 
           break;
         }
@@ -71,15 +59,7 @@ export default class RuleTemplate extends RuleBuilder<FormatYamlArrayOptions> {
 
       for (const tagKey of OBSIDIAN_TAG_KEYS) {
         if (options.formatTagKey && Object.keys(yaml).includes(tagKey)) {
-          text = setYamlSection(text,
-              tagKey,
-              formatYamlArrayValue(
-                  convertTagValueToStringOrStringArray(splitValueIfSingleOrMultilineArray(getYamlSectionValue(text, tagKey))),
-                  options.tagArrayStyle,
-                  options.defaultEscapeCharacter,
-                  options.removeUnnecessaryEscapeCharsForMultiLineArrays,
-              ),
-          );
+          text = setYamlSection(text, tagKey, formatYamlArrayValue(convertTagValueToStringOrStringArray(splitValueIfSingleOrMultilineArray(getYamlSectionValue(text, tagKey))), options.tagArrayStyle));
 
           break;
         }
@@ -94,15 +74,7 @@ export default class RuleTemplate extends RuleBuilder<FormatYamlArrayOptions> {
             continue;
           }
 
-          text = setYamlSection(text,
-              key,
-              formatYamlArrayValue(
-                  splitValueIfSingleOrMultilineArray(getYamlSectionValue(text, key)),
-                  options.defaultArrayStyle,
-                  options.defaultEscapeCharacter,
-                  options.removeUnnecessaryEscapeCharsForMultiLineArrays,
-              ),
-          );
+          text = setYamlSection(text, key, formatYamlArrayValue(splitValueIfSingleOrMultilineArray(getYamlSectionValue(text, key)), options.defaultArrayStyle));
         }
       }
 
@@ -111,15 +83,7 @@ export default class RuleTemplate extends RuleBuilder<FormatYamlArrayOptions> {
           continue;
         }
 
-        text = setYamlSection(text,
-            singleLineArrayKey,
-            formatYamlArrayValue(
-                splitValueIfSingleOrMultilineArray(getYamlSectionValue(text, singleLineArrayKey)),
-                NormalArrayFormats.SingleLine,
-                options.defaultEscapeCharacter,
-                options.removeUnnecessaryEscapeCharsForMultiLineArrays,
-            ),
-        );
+        text = setYamlSection(text, singleLineArrayKey, formatYamlArrayValue(splitValueIfSingleOrMultilineArray(getYamlSectionValue(text, singleLineArrayKey)), NormalArrayFormats.SingleLine));
       }
 
       for (const multiLineArrayKey of options.forceMultiLineArrayStyle) {
@@ -127,15 +91,7 @@ export default class RuleTemplate extends RuleBuilder<FormatYamlArrayOptions> {
           continue;
         }
 
-        text = setYamlSection(text,
-            multiLineArrayKey,
-            formatYamlArrayValue(
-                splitValueIfSingleOrMultilineArray(getYamlSectionValue(text, multiLineArrayKey)),
-                NormalArrayFormats.MultiLine,
-                options.defaultEscapeCharacter,
-                options.removeUnnecessaryEscapeCharsForMultiLineArrays,
-            ),
-        );
+        text = setYamlSection(text, multiLineArrayKey, formatYamlArrayValue(splitValueIfSingleOrMultilineArray(getYamlSectionValue(text, multiLineArrayKey)), NormalArrayFormats.MultiLine));
       }
 
       return text;
diff --git a/src/rules/move-tags-to-yaml.ts b/src/rules/move-tags-to-yaml.ts
index a3176f5..b4eea4a 100644
--- a/src/rules/move-tags-to-yaml.ts
+++ b/src/rules/move-tags-to-yaml.ts
@@ -25,10 +25,6 @@ class MoveTagsToYamlOptions implements Options {
     tagArrayStyle? : TagSpecificArrayFormats | NormalArrayFormats | SpecialArrayFormats = NormalArrayFormats.SingleLine;
   howToHandleExistingTags?: tagOperations = 'Nothing';
   tagsToIgnore?: string[] = [];
-  @RuleBuilder.noSettingControl()
-    defaultEscapeCharacter?: string = '"';
-  @RuleBuilder.noSettingControl()
-    removeUnnecessaryEscapeCharsForMultiLineArrays?: boolean = false;
 }
 
 @RuleBuilder.register
@@ -89,7 +85,7 @@ export default class MoveTagsToYaml extends RuleBuilder<MoveTagsToYamlOptions> {
           }
         }
 
-        const newYaml = setYamlSection(text, existingTagKey, formatYamlArrayValue(tagValue, options.tagArrayStyle, options.defaultEscapeCharacter, options.removeUnnecessaryEscapeCharsForMultiLineArrays));
+        const newYaml = setYamlSection(text, existingTagKey, formatYamlArrayValue(tagValue, options.tagArrayStyle));
 
         return `---\n${newYaml}---`;
       });
diff --git a/src/rules/proper-ellipsis.ts b/src/rules/proper-ellipsis.ts
index 8434393..b6abe23 100644
--- a/src/rules/proper-ellipsis.ts
+++ b/src/rules/proper-ellipsis.ts
@@ -22,7 +22,7 @@ export default class ProperEllipsis extends RuleBuilder<ProperEllipsisOptions> {
     return RuleType.CONTENT;
   }
   apply(text: string, options: ProperEllipsisOptions): string {
-    return ignoreListOfTypes([IgnoreTypes.code, IgnoreTypes.math, IgnoreTypes.yaml, IgnoreTypes.link, IgnoreTypes.wikiLink, IgnoreTypes.tag], text, (text) => {
+    return ignoreListOfTypes([IgnoreTypes.code, IgnoreTypes.math, IgnoreTypes.yaml, IgnoreTypes.link, IgnoreTypes.wikiLink, IgnoreTypes.tag, IgnoreTypes.image], text, (text) => {
       return text.replaceAll(ellipsisRegex, '…');
     });
   }
diff --git a/src/rules/yaml-title-alias.ts b/src/rules/yaml-title-alias.ts
index a54a904..6a5f83d 100644
--- a/src/rules/yaml-title-alias.ts
+++ b/src/rules/yaml-title-alias.ts
@@ -19,9 +19,6 @@ class YamlTitleAliasOptions implements Options {
 
   @RuleBuilder.noSettingControl()
     defaultEscapeCharacter?: string = '"';
-
-  @RuleBuilder.noSettingControl()
-    removeUnnecessaryEscapeCharsForMultiLineArrays?: boolean = false;
 }
 
 @RuleBuilder.register
@@ -132,15 +129,15 @@ export default class YamlTitleAlias extends RuleBuilder<YamlTitleAliasOptions> {
         newYaml = removeYamlSection(newYaml, aliasKeyForFile);
       } else if (options.preserveExistingAliasesSectionStyle) {
         if (!isEmpty && ((isSingleString && title == newAliasValue) || !isSingleString || currentAliasValue == newAliasValue)) {
-          newYaml = setYamlSection(newYaml, aliasKeyForFile, formatYamlArrayValue(newAliasValue, currentAliasStyle, options.defaultEscapeCharacter, options.removeUnnecessaryEscapeCharsForMultiLineArrays));
+          newYaml = setYamlSection(newYaml, aliasKeyForFile, formatYamlArrayValue(newAliasValue, currentAliasStyle));
         } else {
-          newYaml = setYamlSection(newYaml, aliasKeyForFile, formatYamlArrayValue(newAliasValue, options.aliasArrayStyle, options.defaultEscapeCharacter, options.removeUnnecessaryEscapeCharsForMultiLineArrays));
+          newYaml = setYamlSection(newYaml, aliasKeyForFile, formatYamlArrayValue(newAliasValue, options.aliasArrayStyle));
         }
       } else {
-        newYaml = setYamlSection(newYaml, aliasKeyForFile, formatYamlArrayValue(newAliasValue, options.aliasArrayStyle, options.defaultEscapeCharacter, options.removeUnnecessaryEscapeCharsForMultiLineArrays));
+        newYaml = setYamlSection(newYaml, aliasKeyForFile, formatYamlArrayValue(newAliasValue, options.aliasArrayStyle));
       }
     } else if (!shouldRemoveTitleAlias) {
-      newYaml = setYamlSection(newYaml, OBSIDIAN_ALIAS_KEY_PLURAL, formatYamlArrayValue(title, options.aliasArrayStyle, options.defaultEscapeCharacter, options.removeUnnecessaryEscapeCharsForMultiLineArrays));
+      newYaml = setYamlSection(newYaml, OBSIDIAN_ALIAS_KEY_PLURAL, formatYamlArrayValue(title, options.aliasArrayStyle));
     }
 
     if (!options.useYamlKeyToKeepTrackOfOldFilenameOrHeading || shouldRemoveTitleAlias) {
diff --git a/src/ui/linter-components/tab-components/general-tab.ts b/src/ui/linter-components/tab-components/general-tab.ts
index 074016a..09137ad 100644
--- a/src/ui/linter-components/tab-components/general-tab.ts
+++ b/src/ui/linter-components/tab-components/general-tab.ts
@@ -165,23 +165,6 @@ export class GeneralTab extends Tab {
 
     this.addSettingSearchInfo(tempDiv, settingName, settingDesc);
 
-    tempDiv = this.contentEl.createDiv();
-    settingName = 'Remove Unnecessary Escape Characters when in Multi-Line Array Format';
-    settingDesc = 'Escape characters for multi-line YAML arrays don\'t need the same escaping as single-line arrays, so when in multi-line format remove extra escapes that are not necessary';
-    new Setting(tempDiv)
-        .setName(settingName)
-        .setDesc(settingDesc)
-        .addToggle((toggle) => {
-          toggle
-              .setValue(this.plugin.settings.commonStyles.removeUnnecessaryEscapeCharsForMultiLineArrays)
-              .onChange(async (value) => {
-                this.plugin.settings.commonStyles.removeUnnecessaryEscapeCharsForMultiLineArrays = value;
-                await this.plugin.saveSettings();
-              });
-        });
-
-    this.addSettingSearchInfo(tempDiv, settingName, settingDesc);
-
     tempDiv = this.contentEl.createDiv();
     settingName = 'Number of Dollar Signs to Indicate Math Block';
     settingDesc = 'The amount of dollar signs to consider the math content to be a math block instead of inline math';
diff --git a/src/utils/yaml.ts b/src/utils/yaml.ts
index b4a98bb..3fd1d33 100644
--- a/src/utils/yaml.ts
+++ b/src/utils/yaml.ts
@@ -97,11 +97,9 @@ export enum NormalArrayFormats {
  * Formats the yaml array value passed in with the specified format.
  * @param {string | string[]} value The value(s) that will be used as the parts of the array that is assumed to already be broken down into the appropriate format to be put in the array.
  * @param {NormalArrayFormats | SpecialArrayFormats | TagSpecificArrayFormats} format The format that the array should be converted into.
- * @param {string} defaultEscapeCharacter The character escape to use around the value if a specific escape character is not needed.
- * @param {boolean} removeEscapeCharactersIfPossibleWhenGoingToMultiLine Whether or not to remove no longer needed escape values when converting to a multi-line format.
  * @return {string} The formatted array in the specified yaml/obsidian yaml format.
  */
-export function formatYamlArrayValue(value: string | string[], format: NormalArrayFormats | SpecialArrayFormats | TagSpecificArrayFormats, defaultEscapeCharacter: string, removeEscapeCharactersIfPossibleWhenGoingToMultiLine: boolean): string {
+export function formatYamlArrayValue(value: string | string[], format: NormalArrayFormats | SpecialArrayFormats | TagSpecificArrayFormats): string {
   if (typeof value === 'string') {
     value = [value];
   }
@@ -117,16 +115,6 @@ export function formatYamlArrayValue(value: string | string[], format: NormalArr
       if (value == null || value.length === 0) {
         return '\n  - ';
       }
-
-      if (removeEscapeCharactersIfPossibleWhenGoingToMultiLine) {
-        for (let i = 0; i < value.length; i++) {
-          const currentValue = value[i];
-          if (isValueEscapedAlready(currentValue)) {
-            value[i] = escapeStringIfNecessaryAndPossible(currentValue.substring(1, currentValue.length - 1), defaultEscapeCharacter);
-          }
-        }
-      }
-
       return '\n  - ' + value.join('\n  - ');
     case SpecialArrayFormats.SingleStringToSingleLine:
       if (value == null || value.length === 0) {


Test patch:
diff --git a/__tests__/format-yaml-arrays.test.ts b/__tests__/format-yaml-arrays.test.ts
index 78b6aa6..f1f9c9a 100644
--- a/__tests__/format-yaml-arrays.test.ts
+++ b/__tests__/format-yaml-arrays.test.ts
@@ -237,47 +237,6 @@ ruleTest({
         tagArrayStyle: NormalArrayFormats.MultiLine,
       },
     },
-    {
-      testName: 'Convert tags from single-line array to multi-line array with no changes removes unnecessary escape values when `removeUnnecessaryEscapeCharsForMultiLineArrays = true`',
-      before: dedent`
-        ---
-        tag: ["tag1", tag2, tag3, tag4]
-        ---
-      `,
-      after: dedent`
-        ---
-        tag:
-          - tag1
-          - tag2
-          - tag3
-          - tag4
-        ---
-      `,
-      options: {
-        tagArrayStyle: NormalArrayFormats.MultiLine,
-        removeUnnecessaryEscapeCharsForMultiLineArrays: true,
-      },
-    },
-    {
-      testName: 'Convert tags from single-line array to multi-line array with no changes doesn\'t remove unnecessary escape values when `removeUnnecessaryEscapeCharsForMultiLineArrays = false`',
-      before: dedent`
-        ---
-        tag: ["tag1", tag2, tag3, tag4]
-        ---
-      `,
-      after: dedent`
-        ---
-        tag:
-          - "tag1"
-          - tag2
-          - tag3
-          - tag4
-        ---
-      `,
-      options: {
-        tagArrayStyle: NormalArrayFormats.MultiLine,
-      },
-    },
 
     // aliases
     {
@@ -428,47 +387,6 @@ ruleTest({
         formatAliasKey: false,
       },
     },
-    {
-      testName: 'Convert aliases from single-line array to multi-line array with no changes removes unnecessary escape values when `removeUnnecessaryEscapeCharsForMultiLineArrays = true`',
-      before: dedent`
-        ---
-        aliases: ["alias1", alias2, alias3, alias4]
-        ---
-      `,
-      after: dedent`
-        ---
-        aliases:
-          - alias1
-          - alias2
-          - alias3
-          - alias4
-        ---
-      `,
-      options: {
-        aliasArrayStyle: NormalArrayFormats.MultiLine,
-        removeUnnecessaryEscapeCharsForMultiLineArrays: true,
-      },
-    },
-    {
-      testName: 'Convert aliases from single-line array to multi-line array with no changes doesn\'t remove unnecessary escape values when `removeUnnecessaryEscapeCharsForMultiLineArrays = false`',
-      before: dedent`
-        ---
-        aliases: ["alias1", alias2, alias3, alias4]
-        ---
-      `,
-      after: dedent`
-        ---
-        aliases:
-          - "alias1"
-          - alias2
-          - alias3
-          - alias4
-        ---
-      `,
-      options: {
-        aliasArrayStyle: NormalArrayFormats.MultiLine,
-      },
-    },
 
     // default array style
     {
@@ -580,43 +498,6 @@ ruleTest({
         defaultArrayStyle: NormalArrayFormats.MultiLine,
       },
     },
-    {
-      testName: 'Convert single-line to multi-line for regular yaml arrays doesn\'t remove unnecessary escape values when `removeUnnecessaryEscapeCharsForMultiLineArrays = false`',
-      before: dedent`
-        ---
-        key: [val1, "other val"]
-        ---
-      `,
-      after: dedent`
-        ---
-        key:
-          - val1
-          - "other val"
-        ---
-      `,
-      options: {
-        defaultArrayStyle: NormalArrayFormats.MultiLine,
-      },
-    },
-    {
-      testName: 'Convert single-line to multi-line for regular yaml arrays removes unnecessary escape values when `removeUnnecessaryEscapeCharsForMultiLineArrays = true`',
-      before: dedent`
-        ---
-        key: [val1, "other val"]
-        ---
-      `,
-      after: dedent`
-        ---
-        key:
-          - val1
-          - other val
-        ---
-      `,
-      options: {
-        defaultArrayStyle: NormalArrayFormats.MultiLine,
-        removeUnnecessaryEscapeCharsForMultiLineArrays: true,
-      },
-    },
 
     // force single-line
     {
@@ -749,45 +630,6 @@ ruleTest({
         forceMultiLineArrayStyle: ['key'],
       },
     },
-    {
-      testName: 'Forcing multi-line on a single-line array results in a multi-line array with existing unnecessary escape values when `removeUnnecessaryEscapeCharsForMultiLineArrays = false`',
-      before: dedent`
-        ---
-        key: [val1, "other val"]
-        ---
-      `,
-      after: dedent`
-        ---
-        key:
-          - val1
-          - "other val"
-        ---
-      `,
-      options: {
-        defaultArrayStyle: NormalArrayFormats.SingleLine,
-        forceMultiLineArrayStyle: ['key'],
-      },
-    },
-    {
-      testName: 'Forcing multi-line on a single-line array results in a multi-line array without existing unnecessary escape values when `removeUnnecessaryEscapeCharsForMultiLineArrays = true`',
-      before: dedent`
-        ---
-        key: [val1, "other val"]
-        ---
-      `,
-      after: dedent`
-        ---
-        key:
-          - val1
-          - other val
-        ---
-      `,
-      options: {
-        defaultArrayStyle: NormalArrayFormats.SingleLine,
-        forceMultiLineArrayStyle: ['key'],
-        removeUnnecessaryEscapeCharsForMultiLineArrays: true,
-      },
-    },
 
     // edge cases
     {
diff --git a/__tests__/proper-ellipsis.tests.ts b/__tests__/proper-ellipsis.tests.ts
new file mode 100644
index 0000000..a105155
--- /dev/null
+++ b/__tests__/proper-ellipsis.tests.ts
@@ -0,0 +1,20 @@
+import dedent from 'ts-dedent';
+import {ruleTest} from './common';
+import ProperEllipsis from '../src/rules/proper-ellipsis';
+
+ruleTest({
+  RuleBuilderClass: ProperEllipsis,
+  testCases: [
+    {
+      testName: 'Does not modify embedded links',
+      before: dedent`
+        ![title](a...b.md)
+        ![](c...d.png)
+      `,
+      after: dedent`
+        ![title](a...b.md)
+        ![](c...d.png)
+      `,
+    },
+  ],
+});