Repository: platers/obsidian-linter (ts)

Issue:
FR: Obsidian Comment %% Has Empty Lines Added Around It
I have the following section:

```
%%
due-date:: [[2022-06-10]]
%%
```

which gets linted as follows -- the result is not expected or wanted:

```
%%

due-date:: [[2022-06-10]]

%%
```

It would be great if ` Linter ` would respect the comments' styling.

Thank you for considering.

Pull request description:
Ignore Multiline Obsidian Comments for Paragraph Modifications
Fixes #223 

Made sure that multiline obsidian comments are treated as such for purposes of paragraph rules, specifically two spaces at the end of lines with content around it and blank lines around each paragraph.

Changes Made:
- Added a function for ignoring multiline obsidian comments
- Updated the two paragraph rules to ignore multiline obsidian comments
- Added tests for multiline comments
- Fixed tests pointed out by #264 to use the proper values

Patch:
diff --git a/src/rules.ts b/src/rules.ts
index 74b3b50..e4735f9 100644
--- a/src/rules.ts
+++ b/src/rules.ts
@@ -19,6 +19,7 @@ import {
   setYamlSection,
   getYamlSectionValue,
   removeYamlSection,
+  ignoreObsidianMultilineComments,
 } from './utils';
 import {
   Option,
@@ -305,7 +306,7 @@ export const rules: Rule[] = [
       'All paragraphs should have exactly one blank line both before and after.',
       RuleType.SPACING,
       (text: string) => {
-        return makeSureThereIsOnlyOneBlankLineBeforeAndAfterParagraphs(text);
+        return ignoreObsidianMultilineComments(text, makeSureThereIsOnlyOneBlankLineBeforeAndAfterParagraphs);
       },
       [
         new Example(
@@ -1188,7 +1189,7 @@ export const rules: Rule[] = [
       'Makes sure that two spaces are added to the ends of lines with content continued on the next line for paragraphs, blockquotes, and list items',
       RuleType.CONTENT,
       (text: string) => {
-        return addTwoSpacesAtEndOfLinesFollowedByAnotherLineOfTextContent(text);
+        return ignoreObsidianMultilineComments(text, addTwoSpacesAtEndOfLinesFollowedByAnotherLineOfTextContent);
       },
       [
         new Example(
diff --git a/src/utils.ts b/src/utils.ts
index ad1cb9a..01c526d 100644
--- a/src/utils.ts
+++ b/src/utils.ts
@@ -15,6 +15,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;
 
 // Reused placeholders
 
@@ -106,6 +107,22 @@ function replaceLinks(text: string, regularLinkPlaceholder: string, wikiLinkPlac
   return {text, replacedRegularLinks, replacedWikiLinks};
 }
 
+export function ignoreObsidianMultilineComments(text: string, func: (text: string) => string): string {
+  const obsidianMultilineCommentMatches = text.match(obsidianMultilineCommentRegex);
+  const obsidianCommentPlaceholder = '{OBSIDIAN COMMENT PLACEHOLDER}';
+  text = text.replaceAll(obsidianMultilineCommentRegex, obsidianCommentPlaceholder);
+
+  text = func(text);
+
+  if (obsidianMultilineCommentMatches) {
+    for (const obsidianMultilineComment of obsidianMultilineCommentMatches) {
+      text = text.replace(obsidianCommentPlaceholder, obsidianMultilineComment);
+    }
+  }
+
+  return text;
+}
+
 /**
  * Makes sure that the style of either strong or emphasis is consistent.
  * @param {string} text The text to style either the strong or emphasis in a consistent manner


Test patch:
diff --git a/src/test/paragraph-blank-lines.test.ts b/src/test/paragraph-blank-lines.test.ts
index e4aec46..54e8cc5 100644
--- a/src/test/paragraph-blank-lines.test.ts
+++ b/src/test/paragraph-blank-lines.test.ts
@@ -169,6 +169,30 @@ describe('Paragraph blank lines', () => {
     paragraph final line
     `;
 
+    expect(rulesDict['paragraph-blank-lines'].apply(before)).toBe(after);
+  });
+  it('Make sure obsidian multiline comments are not affected', () => {
+    const before = dedent`
+    Here is some inline comments: %%You can't see this text%% (Can't see it)
+
+    Here is a block comment:
+    %%
+    It can span
+    multiple lines
+    %%
+    `;
+
+    const after = dedent`
+    Here is some inline comments: %%You can't see this text%% (Can't see it)
+
+    Here is a block comment:
+
+    %%
+    It can span
+    multiple lines
+    %%
+    `;
+
     expect(rulesDict['paragraph-blank-lines'].apply(before)).toBe(after);
   });
 });
diff --git a/src/test/trailing-spaces.test.ts b/src/test/trailing-spaces.test.ts
index a4d97b2..84902f5 100644
--- a/src/test/trailing-spaces.test.ts
+++ b/src/test/trailing-spaces.test.ts
@@ -36,7 +36,7 @@ describe('Trailing spaces', () => {
         line with trailing tab and spaces
         
     `;
-    expect(rulesDict['trailing-spaces'].apply(before, {'Style': 'Two Space Linebreak'})).toBe(after);
+    expect(rulesDict['trailing-spaces'].apply(before, {'Two Space Linebreak': true})).toBe(after);
   });
   /* eslint-enable no-mixed-spaces-and-tabs, no-tabs */
   it('Two Space Linebreak not removed', () => {
@@ -50,7 +50,7 @@ describe('Trailing spaces', () => {
           line with one trailing spaces  
   
         `;
-    expect(rulesDict['trailing-spaces'].apply(before, {'Style': 'Two Space Linebreak'})).toBe(after);
+    expect(rulesDict['trailing-spaces'].apply(before, {'Two Space Linebreak': true})).toBe(after);
   });
   it('Regular link with spaces stays the same', () => {
     const before = dedent`
diff --git a/src/test/two-spaces-between-lines-with-content.test.ts b/src/test/two-spaces-between-lines-with-content.test.ts
new file mode 100644
index 0000000..09824b4
--- /dev/null
+++ b/src/test/two-spaces-between-lines-with-content.test.ts
@@ -0,0 +1,28 @@
+import dedent from 'ts-dedent';
+import {rulesDict} from '../rules';
+
+describe('Paragraph blank lines', () => {
+  it('Make sure obsidian multiline comments are not affected', () => {
+    const before = dedent`
+    Here is some inline comments: %%You can't see this text%% (Can't see it)
+
+    Here is a block comment:
+    %%
+    It can span
+    multiple lines
+    %%
+    `;
+
+    const after = dedent`
+    Here is some inline comments: %%You can't see this text%% (Can't see it)
+
+    Here is a block comment:  
+    %%
+    It can span
+    multiple lines
+    %%
+    `;
+
+    expect(rulesDict['two-spaces-between-lines-with-content'].apply(before)).toBe(after);
+  });
+});