Repository: platers/obsidian-linter
Pull request #818 (2023-07-25 00:41:20)

Fix Moving Math Block Indicators to Their Own Line Breaking Math Blocks when Malformed with Content Between Them
Relates to #813 

Changes Made:
- Made the moving of math blocks run before most other regular rules in order to prevent paragraph blank lines or other rules from formatting a math block before the rule to move the indicators to their own line got to run
- Added a test for a scenario that was having problems
- Updated the logic to handle scenarios where there are 1, 2, and 3 math block indicators present (1 should not be formatted, 2 should be the whole match, and 3 should just be the first 2 math block indicators)
  - This may require linting 2 times to fix some messed up math blocks as it may not get all math indicators on their own lines the first time it runs


Patch:
diff --git a/src/rules-runner.ts b/src/rules-runner.ts
index 824a23b..814e161 100644
--- a/src/rules-runner.ts
+++ b/src/rules-runner.ts
@@ -23,6 +23,7 @@ import {getTextInLanguage} from './lang/helpers';
 import CapitalizeHeadings from './rules/capitalize-headings';
 import BlockquoteStyle from './rules/blockquote-style';
 import {IgnoreTypes, ignoreListOfTypes} from './utils/ignore-types';
+import MoveMathBlockIndicatorsToOwnLine from './rules/move-math-block-indicators-to-own-line';
 
 export type RunLinterRulesOptions = {
   oldText: string,
@@ -100,6 +101,10 @@ export class RulesRunner {
       defaultEscapeCharacter: runOptions.settings.commonStyles.escapeCharacter,
     });
 
+    [newText] = MoveMathBlockIndicatorsToOwnLine.applyIfEnabled(newText, runOptions.settings, this.disabledRules, {
+      minimumNumberOfDollarSignsToBeAMathBlock: runOptions.settings.commonStyles.minimumNumberOfDollarSignsToBeAMathBlock,
+    });
+
     return newText;
   }
 
diff --git a/src/rules/move-math-block-indicators-to-own-line.ts b/src/rules/move-math-block-indicators-to-own-line.ts
index ffd3229..f759e92 100644
--- a/src/rules/move-math-block-indicators-to-own-line.ts
+++ b/src/rules/move-math-block-indicators-to-own-line.ts
@@ -17,6 +17,7 @@ export default class MoveMathBlockIndicatorsToOwnLine extends RuleBuilder<MoveMa
       descriptionKey: 'rules.move-math-block-indicators-to-their-own-line.description',
       type: RuleType.SPACING,
       ruleIgnoreTypes: [IgnoreTypes.code, IgnoreTypes.inlineCode],
+      hasSpecialExecutionOrder: true,
     });
   }
   get OptionsClass(): new () => MoveMathBlockIndicatorsToOwnLineOptions {
diff --git a/src/utils/mdast.ts b/src/utils/mdast.ts
index 53f2351..9fa400d 100644
--- a/src/utils/mdast.ts
+++ b/src/utils/mdast.ts
@@ -777,13 +777,20 @@ function breakMathBlockIntoMultipleBlocksIfNeedBe(mathBlock: string, numberOfDol
   const mathBlockIndexes = [] as {startIndex: number, endIndex: number}[];
 
   let matchCount = countInstances(mathBlock, mathBlockIndicator);
-  if (matchCount <= 3) {
+  if (matchCount <= 1) {
+    return [];
+  } else if (matchCount === 2) {
     mathBlockIndexes.unshift({
       startIndex: startIndexOfMathBlock,
       endIndex: startIndexOfMathBlock + mathBlock.length,
     });
 
     return mathBlockIndexes;
+  } else if (matchCount === 3) {
+    mathBlockIndexes.unshift({
+      startIndex: startIndexOfMathBlock,
+      endIndex: startIndexOfMathBlock + mathBlock.indexOf(mathBlockIndicator, mathBlockIndicator.length) + mathBlockIndicator.length,
+    });
   }
 
   // if there is an odd amount of matches, remove one from the list so it is even
@@ -794,7 +801,7 @@ function breakMathBlockIntoMultipleBlocksIfNeedBe(mathBlock: string, numberOfDol
   // pair the earliest matches together until there are no more pairs
   let startIndex = startIndexOfMathBlock;
   let startSearch = mathBlockIndicator.length;
-  while (matchCount > 2 ) {
+  while (matchCount > 2) {
     const endOfIndex = mathBlock.indexOf(mathBlockIndicator, startSearch) + mathBlockIndicator.length;
     mathBlockIndexes.unshift({
       startIndex: startIndex,


Test patch:
diff --git a/__tests__/move-math-block-indicators-to-own-line.test.ts b/__tests__/move-math-block-indicators-to-own-line.test.ts
index 9ffb575..42ff54b 100644
--- a/__tests__/move-math-block-indicators-to-own-line.test.ts
+++ b/__tests__/move-math-block-indicators-to-own-line.test.ts
@@ -84,5 +84,31 @@ ruleTest({
         $$
       `,
     },
+    { // accounts for https://github.com/platers/obsidian-linter/issues/813
+      testName: 'Math indicators that are malformed with content between them should be properly formatted without messing up the content of the other math blocks',
+      before: dedent`
+        $$
+        \\sqrt{(x_1-x_2)^2+(y_1-y_2)^2+\cdots+(n_1-n_2)^2}$$
+        - here is some text
+        $$
+        \\begin{aligned}
+        \\frac{n*(n+1)}{2}=\\frac{1000*1001}{2}=500500
+        \\end{aligned}
+        $$
+        text
+      `,
+      after: dedent`
+        $$
+        \\sqrt{(x_1-x_2)^2+(y_1-y_2)^2+\cdots+(n_1-n_2)^2}
+        $$
+        - here is some text
+        $$
+        \\begin{aligned}
+        \\frac{n*(n+1)}{2}=\\frac{1000*1001}{2}=500500
+        \\end{aligned}
+        $$
+        text
+      `,
+    },
   ],
 });