Repository: platers/obsidian-linter (ts)

Issue:
Bug: Remove Multiple Spaces removes indentation from nested bullet points INSIDE a nested callout
- [X] I have verified that I am on the latest version of the Linter

## Describe the Bug

A clear and concise description of what the bug is.

## How to Reproduce

``` markdown
> [!goal]+ Two goals of object-oriented design
>
> > [!def]- Cohesion
> > - How strongly related the parts are inside a class
> > - About a class
> > - A class is *cohesive* if the data and behaviour of these objects makes sense
> > - **High cohesion**:
> >     - A class does one job, and does it well
> > - **Low cohesion**:
> >     - Class has parts that do not relate to each other
> > - e.g., `Customer` class might have `getName`, `getAddress`, but also `sendEmail` that sends an email to the customer → Weird; not a major responsibility of the customer → ==not cohesive
```

## Expected Behavior

`> >     - A class does one job, and does it well` and `> >     - Class has parts that do not relate to each other` are expected to keep their spaces since it is a nested list inside a nested callout, but the remove multiple spaces setting removes the spaces between `>` and `-`.

## Device

- [X] Desktop
- [ ] Mobile


Pull request:
Fix `Remove Multiple Spaces` Removing Proceeding Spaces when Nested/Indented List Items Are Present in a Nested Blockquote/Callout
Fixes #1203 

There was an issue with removing multiple spaces inside of a nested callout/blockquote. It would remove proceeding space from a callout/blockquote.

Changes Made:
- Remove Multiples Spaces takes two passes: 1 for regular text and one for list item text
- Added a test for the scenario in question

Patch:
diff --git a/src/rules/remove-multiple-spaces.ts b/src/rules/remove-multiple-spaces.ts
index cc17378..d446a3e 100644
--- a/src/rules/remove-multiple-spaces.ts
+++ b/src/rules/remove-multiple-spaces.ts
@@ -1,7 +1,8 @@
 import {Options, RuleType} from '../rules';
 import RuleBuilder, {ExampleBuilder, OptionBuilderBase} from './rule-builder';
 import dedent from 'ts-dedent';
-import {IgnoreTypes} from '../utils/ignore-types';
+import {ignoreListOfTypes, IgnoreTypes} from '../utils/ignore-types';
+import {updateListItemText} from '../utils/mdast';
 
 class RemoveMultipleSpacesOptions implements Options {}
 
@@ -19,7 +20,13 @@ export default class RemoveMultipleSpaces extends RuleBuilder<RemoveMultipleSpac
     return RemoveMultipleSpacesOptions;
   }
   apply(text: string, options: RemoveMultipleSpacesOptions): string {
-    text = text.replace(/(?!^>)([^\s])( ){2,}([^\s])/gm, '$1 $3');
+    text = ignoreListOfTypes([IgnoreTypes.list], text, (text: string): string => {
+      return text.replace(/(?!^>)([^\s])( ){2,}([^\s])/gm, '$1 $3');
+    });
+
+    text = updateListItemText(text, (text: string): string => {
+      return text.replace(/([^\s])( ){2,}([^\s])/gm, '$1 $3');
+    });
 
     return text;
   }


Test patch:
diff --git a/__tests__/remove-multiple-spaces.test.ts b/__tests__/remove-multiple-spaces.test.ts
index 917fd6a..32bbc8a 100644
--- a/__tests__/remove-multiple-spaces.test.ts
+++ b/__tests__/remove-multiple-spaces.test.ts
@@ -210,6 +210,35 @@ ruleTest({
         $ x =  2y $
       `,
     },
+    { // accounts for https://github.com/platers/obsidian-linter/issues/1203
+      testName: 'A nested callout/blockquote should not have list item proceeding space removed',
+      before: dedent`
+        > [!goal]+ Two goals of object-oriented design
+        >
+        > > [!def]- Cohesion
+        > > - How strongly related the parts are inside a class
+        > > - About a class
+        > > - A class is *cohesive* if the data and behaviour of these objects makes sense
+        > > - **High cohesion**:
+        > >     - A class does one job, and does it well
+        > > - **Low cohesion**:
+        > >     - Class has parts that do not relate to each other
+        > > - e.g., \`Customer\` class might have \`getName\`, \`getAddress\`, but also \`sendEmail\` that sends an email to the customer → Weird; not a major responsibility of the customer → ==not cohesive
+      `,
+      after: dedent`
+        > [!goal]+ Two goals of object-oriented design
+        >
+        > > [!def]- Cohesion
+        > > - How strongly related the parts are inside a class
+        > > - About a class
+        > > - A class is *cohesive* if the data and behaviour of these objects makes sense
+        > > - **High cohesion**:
+        > >     - A class does one job, and does it well
+        > > - **Low cohesion**:
+        > >     - Class has parts that do not relate to each other
+        > > - e.g., \`Customer\` class might have \`getName\`, \`getAddress\`, but also \`sendEmail\` that sends an email to the customer → Weird; not a major responsibility of the customer → ==not cohesive
+      `,
+    },
   ],
 });