Repository: platers/obsidian-linter (ts)

Issue:
Bug: can't insert space between Chinese and math equation correctly
I turn on the function "Space between Chinese and English or numbers" and try to lint the file.

But I found it can only insert a space before a math equation but can't insert a space between the equation.

Sample:

- Before:

```markdown
这是一个数学公式$f(x)=x^2$这是一个数学公式
```

- After：

```markdown
这是一个数学公式 $f(x)=x^2$这是一个数学公式
```
Bug: Inline comment ending a line prevents ignoring of multiline comment later in file
## Describe the Bug

This is related to #223 and #269 and is a minimal repro of the issue I was commenting on at the bottom of #223. Multiline comments are not successfully ignored if an inline comment earlier in the file ends a line. Putting a space between inline comment and linebreak does not fix this, putting text between does.

## How to Reproduce
Set "paragraph blank lines" rule on OR set "two spaces between lines with content" on. (Not both.)

``` markdown
%% fold %%

## R

%%
HW:: --
T:: 0
%%

```


## Expected Behavior
Linter output for the bottom of the file (starting `## R`) should be the same as if the input was:


``` markdown
%% fold %% notComment

## R

%%
HW:: --
T:: 0
%%

```

## Device

- [x] Desktop

Note: The file initially had a second multiline block comment above the inline comment which was successfully ignored by both "paragraph blank lines" and "two spaces between lines with content" rules.
Bug: disabled rules: [all] does not disable YAML Timestamp.
## Describe the Bug

`disabled rules: [all]` does not disable YAML Timestamp.

## How to Reproduce

Steps to reproduce the behavior:

1. Set up the YAML Timestamp like this ![](https://user-images.githubusercontent.com/48207708/180135592-00880f1d-a08f-4b2c-bd71-676d4d803c7a.png)
2. In a note, write `disabled rules: [all]` in the YAML
3. Excute the command `lint current file`
4. The YAML timestamp is still inserted

## Expected Behavior

The YAML timestamp should not be inserted when `disabled rules: [all]` is there.

## Device

- [x] Desktop (macOS)



Pull request:
Fix for a Couple of Regex Issues and Respecting Disabled Rules for Special Rules
Fixes #306 
Fixes #303 
Fixes #300 

Changes Made:
- Updated the running of special rules to make sure they check if the rule is disabled before trying to run it
- Updated regex for tail of English to Chinese to make sure a dollar sign is listed as something that needs a space after it
- Updated regex for multiline comments to make sure it starts a line in order to be counted as something to escape to prevent single line comments from getting caught in the regex
- Added tests to make sure we hopefully will avoid reintroducing the above problems (checking disabled rules did not have any UTs added)

Patch:
diff --git a/src/main.ts b/src/main.ts
index 78e36c4..22152eb 100644
--- a/src/main.ts
+++ b/src/main.ts
@@ -240,13 +240,14 @@ export default class LinterPlugin extends Plugin {
     lintText(oldText: string, file: TFile) {
       let newText = oldText;
 
+      const disabledRules = getDisabledRules(newText);
       // escape YAML where possible before parsing yaml
-      [newText] = EscapeYamlSpecialCharacters.applyIfEnabled(newText, this.settings);
+      [newText] = EscapeYamlSpecialCharacters.applyIfEnabled(newText, this.settings, disabledRules);
+
 
       // remove hashtags from tags before parsing yaml
-      [newText] = FormatTagsInYaml.applyIfEnabled(newText, this.settings);
+      [newText] = FormatTagsInYaml.applyIfEnabled(newText, this.settings, disabledRules);
 
-      const disabledRules = getDisabledRules(newText);
       const modifiedAtTime = moment(file.stat.mtime).format();
       const createdAtTime = moment(file.stat.ctime).format();
 
@@ -266,7 +267,7 @@ export default class LinterPlugin extends Plugin {
 
       // run yaml timestamp at the end to help determine if something has changed
       let isYamlTimestampEnabled;
-      [newText, isYamlTimestampEnabled] = YamlTimestamp.applyIfEnabled(newText, this.settings, {
+      [newText, isYamlTimestampEnabled] = YamlTimestamp.applyIfEnabled(newText, this.settings, disabledRules, {
         fileCreatedTime: createdAtTime,
         fileModifiedTime: modifiedAtTime,
         currentTime: moment(),
@@ -276,7 +277,7 @@ export default class LinterPlugin extends Plugin {
 
       const yamlTimestampOptions = YamlTimestamp.getRuleOptions(this.settings);
 
-      [newText] = YamlKeySort.applyIfEnabled(newText, this.settings, {
+      [newText] = YamlKeySort.applyIfEnabled(newText, this.settings, disabledRules, {
         currentTimeFormatted: moment().format(yamlTimestampOptions.format),
         yamlTimestampDateModifiedEnabled: isYamlTimestampEnabled && yamlTimestampOptions.dateModified,
         dateModifiedKey: yamlTimestampOptions.dateModifiedKey,
diff --git a/src/rules/rule-builder.ts b/src/rules/rule-builder.ts
index 6e761c5..aa997c4 100644
--- a/src/rules/rule-builder.ts
+++ b/src/rules/rule-builder.ts
@@ -61,8 +61,12 @@ export default abstract class RuleBuilder<TOptions extends Options> extends Rule
     return false;
   }
 
-  static applyIfEnabled<TOptions extends Options>(this: typeof RuleBuilderBase & (new() => RuleBuilder<TOptions>), text: string, settings: LinterSettings, extraOptions?: TOptions): [result: string, isEnabled: boolean] {
+  static applyIfEnabled<TOptions extends Options>(this: typeof RuleBuilderBase & (new() => RuleBuilder<TOptions>), text: string, settings: LinterSettings, disabledRules: string[], extraOptions?: TOptions): [result: string, isEnabled: boolean] {
     const rule = this.getRule();
+    if (disabledRules.includes(rule.alias())) {
+      return [text, false];
+    }
+
     return RuleBuilderBase.applyIfEnabledBase(rule, text, settings, extraOptions);
   }
 
diff --git a/src/rules/space-between-chinese-and-english-or-numbers.ts b/src/rules/space-between-chinese-and-english-or-numbers.ts
index 2701333..3c940ce 100644
--- a/src/rules/space-between-chinese-and-english-or-numbers.ts
+++ b/src/rules/space-between-chinese-and-english-or-numbers.ts
@@ -23,7 +23,7 @@ export default class SpaceBetweenChineseAndEnglishOrNumbers extends RuleBuilder<
   apply(text: string, options: SpaceBetweenChineseAndEnglishOrNumbersOptions): string {
     return ignoreListOfTypes([IgnoreTypes.code, IgnoreTypes.yaml, IgnoreTypes.link, IgnoreTypes.wikiLink, IgnoreTypes.tag], text, (text) => {
       const head = /([\u4e00-\u9fa5])( *)(\[[^[]*\]\(.*\)|`[^`]*`|\w+|[-+'"([{¥$]|\*[^*])/gm;
-      const tail = /(\[[^[]*\]\(.*\)|`[^`]*`|\w+|[-+;:'"°%)\]}]|[^*]\*)( *)([\u4e00-\u9fa5])/gm;
+      const tail = /(\[[^[]*\]\(.*\)|`[^`]*`|\w+|[-+;:'"°%$)\]}]|[^*]\*)( *)([\u4e00-\u9fa5])/gm;
       return text.replace(head, '$1 $3').replace(tail, '$1 $3');
     });
   }
diff --git a/src/utils/regex.ts b/src/utils/regex.ts
index 3601a81..d03668d 100644
--- a/src/utils/regex.ts
+++ b/src/utils/regex.ts
@@ -10,7 +10,7 @@ export const indentedBlockRegex = '^((\t|( {4})).*\n)+';
 export const codeBlockRegex = new RegExp(`${backtickBlockRegexTemplate}|${tildeBlockRegexTemplate}|${indentedBlockRegex}`, 'gm');
 export const wikiLinkRegex = /(!?)(\[{2}[^[\n\]]*\]{2})/g;
 export const tagRegex = /#[^\s#]{1,}/g;
-export const obsidianMultilineCommentRegex = /%%\n[^%]*\n%%/g;
+export const obsidianMultilineCommentRegex = /^%%\n[^%]*\n%%/gm;
 export const tableRegex = /([ ]{0,3}\[.*?\][ \t]*\n)?([ ]{0,3}\S+.*?\|.*?\n([^\n]*?\|[^\n]*?\n)*?)?[ ]{0,3}[|\-+:.][ \-+|:.]*?\|[ \-+|:.]*(?:\n?[^\n]*?\|([^\n]*?)*(\n)?)+/g;
 export const wordSplitterRegex = /[,\s]+/;
 


Test patch:
diff --git a/src/test/paragraph-blank-lines.test.ts b/src/test/paragraph-blank-lines.test.ts
index e881668..00905d7 100644
--- a/src/test/paragraph-blank-lines.test.ts
+++ b/src/test/paragraph-blank-lines.test.ts
@@ -205,5 +205,65 @@ ruleTest({
         Line not followed by line break
       `,
     },
+    {
+      // accounts for https://github.com/platers/obsidian-linter/issues/300
+      testName: 'Make sure obsidian multiline comments with single line comment prior is not affected',
+      before: dedent`
+      %% fold %%
+
+      ## R
+      
+      %%
+      HW:: --
+      T:: 0
+      %%
+
+      # A %% fold %%
+
+      ## R
+
+      %%
+      HW:: --
+      T:: 0
+      %%
+
+      # A %% fold %% nocomment
+
+      ## R
+
+      %%
+      HW:: --
+      T:: 0
+      %%
+      `,
+      after: dedent`
+      %% fold %%
+
+      ## R
+      
+      %%
+      HW:: --
+      T:: 0
+      %%
+
+      # A %% fold %%
+
+      ## R
+
+      %%
+      HW:: --
+      T:: 0
+      %%
+
+      # A %% fold %% nocomment
+
+      ## R
+
+      %%
+      HW:: --
+      T:: 0
+      %%
+      `,
+    },
   ],
 });
diff --git a/src/test/space-between-chinese-and-english-or-numbers.test.ts b/src/test/space-between-chinese-and-english-or-numbers.test.ts
new file mode 100644
index 0000000..0cdf872
--- /dev/null
+++ b/src/test/space-between-chinese-and-english-or-numbers.test.ts
@@ -0,0 +1,19 @@
+import SpaceBetweenChineseAndEnglishOrNumbers from '../rules/space-between-chinese-and-english-or-numbers';
+import dedent from 'ts-dedent';
+import {ruleTest} from './common';
+
+ruleTest({
+  RuleBuilderClass: SpaceBetweenChineseAndEnglishOrNumbers,
+  testCases: [
+    {
+      // accounts for https://github.com/platers/obsidian-linter/issues/303
+      testName: 'Make sure that spaces are added after a dollar sign if followed by Chinese characters',
+      before: dedent`
+      这是一个数学公式$f(x)=x^2$这是一个数学公式
+      `,
+      after: dedent`
+      这是一个数学公式 $f(x)=x^2$ 这是一个数学公式
+      `,
+    },
+  ],
+});
diff --git a/src/test/two-spaces-between-lines-with-content.test.ts b/src/test/two-spaces-between-lines-with-content.test.ts
index adecaab..17cf95a 100644
--- a/src/test/two-spaces-between-lines-with-content.test.ts
+++ b/src/test/two-spaces-between-lines-with-content.test.ts
@@ -26,5 +26,65 @@ ruleTest({
         %%
       `,
     },
+    {
+      // accounts for https://github.com/platers/obsidian-linter/issues/300
+      testName: 'Make sure obsidian multiline comments with single line comment prior is not affected',
+      before: dedent`
+      %% fold %%
+
+      ## R
+      
+      %%
+      HW:: --
+      T:: 0
+      %%
+
+      # A %% fold %%
+
+      ## R
+
+      %%
+      HW:: --
+      T:: 0
+      %%
+
+      # A %% fold %% nocomment
+
+      ## R
+
+      %%
+      HW:: --
+      T:: 0
+      %%
+      `,
+      after: dedent`
+      %% fold %%
+
+      ## R
+      
+      %%
+      HW:: --
+      T:: 0
+      %%
+
+      # A %% fold %%
+
+      ## R
+
+      %%
+      HW:: --
+      T:: 0
+      %%
+
+      # A %% fold %% nocomment
+
+      ## R
+
+      %%
+      HW:: --
+      T:: 0
+      %%
+      `,
+    },
   ],
 });