Repository: platers/obsidian-linter (ts)

Issue:
Bug: Header increment breaks when tags are used in the header
## Describe the Bug
In a document with properly-incremented headers, when a tag (i.e. `#`) is added onto one of the headers, the sub-headers gets bumped up to the same level as the header with the tag.

## How to Reproduce

Example to reproduce issue with

``` markdown
# Page Title
## Foo #tag
### Bar
### Baz
```

Linter Config for incrementing header:
```
 "Header Increment": {
      "Heading levels should only increment by one level at a time": true,
      "Start Header Increment at Heading Level 2": false
    },
```

## Expected Behavior

Expected output:


``` markdown
# Page Title
## Foo #tag
### Bar
### Baz
```

The actual output:

``` markdown
# Page Title
## Foo #tag
## Bar
## Baz
```

## Device

- [x] Desktop
- [ ] Mobile

Reproducible in both v1.10.1 and v1.10.2
Bug: Header capitalization capitalizes words after words that contain numbers
## Describe the Bug

When header capitalization is selected ("first letter" style) and there's an acronym or word that contains a number the next word will be capitalized

## How to Reproduce

Examples to reproduce issue with

``` markdown
# EC2 instance
## EC2 lab05 load balancer
### lab07 bread maker
```

The result of the above markdown is:

```markdown
# EC2 Instance

## EC2 lab05 Load balancer

### lab07 Bread maker
```

(Instance, Load, and Bread are incorrectly capitalized)


Expected output if applicable:

``` markdown
# EC2 instance

## EC2 lab05 load balancer

### Lab07 bread maker
```

## Screenshots

If applicable, add screenshots to help explain your problem.

## Device

- [x] Desktop
- [ ] Mobile



Pull request:
Fix A First Letter Capitalization Issue and Tags in Headers Breaking Header Increment
Fixes #598 
Fixes #601 

Changes Made:
- Added UTs for the issues in question and fixed another UT that was related to the change
- Allowed words that end in a mix of some types of punctuation and numbers to be considered to be a word in header capitalization
- Updated the header regex to allow a tag-like value in the header

Patch:
diff --git a/src/rules/capitalize-headings.ts b/src/rules/capitalize-headings.ts
index 0adb4e8..fc4f0d2 100644
--- a/src/rules/capitalize-headings.ts
+++ b/src/rules/capitalize-headings.ts
@@ -425,7 +425,7 @@ export default class CapitalizeHeadings extends RuleBuilder<CapitalizeHeadingsOp
         let firstWord = true;
         for (let j = 1; j < headerWords.length; j++) {
           // based on https://stackoverflow.com/a/62032796 "/\p{L}/u" accounts for all unicode letters across languages
-          const isWord = headerWords[j].match(/^[\p{L}'-]{1,}[.?!,:;]?$/u);
+          const isWord = headerWords[j].match(/^[\p{L}'-]{1,}[.?!,:;\d]*$/u);
           if (!isWord) {
             continue;
           }
diff --git a/src/utils/regex.ts b/src/utils/regex.ts
index 23664d9..a87492b 100644
--- a/src/utils/regex.ts
+++ b/src/utils/regex.ts
@@ -2,7 +2,7 @@
 import {makeSureContentHasEmptyLinesAddedBeforeAndAfter} from './strings';
 
 // Useful regexes
-export const allHeadersRegex = /^([ \t]*)(#+)([ \t]+)([^#\n\r]*)([ \t]+#+)?$/gm;
+export const allHeadersRegex = /^([ \t]*)(#+)([ \t]+)([^\n\r]*?)([ \t]+#+)?$/gm;
 export const fencedRegexTemplate = '^XXX\\.*?\n(?:((?:.|\n)*?)\n)?XXX(?=\\s|$)$';
 export const yamlRegex = /^---\n((?:(((?!---)(?:.|\n)*?)\n)?))---(?=\n|$)/;
 export const backtickBlockRegexTemplate = fencedRegexTemplate.replaceAll('X', '`');


Test patch:
diff --git a/__tests__/capitalize-headings.test.ts b/__tests__/capitalize-headings.test.ts
index f87b5f6..aa11b6f 100644
--- a/__tests__/capitalize-headings.test.ts
+++ b/__tests__/capitalize-headings.test.ts
@@ -18,7 +18,7 @@ ruleTest({
         ## this état
       `,
       after: dedent`
-        # h1
+        # H1
         ## A c++ Lan
         ## This is a Sentence.
         ## I Can't Do This
@@ -111,7 +111,7 @@ ruleTest({
       },
     },
     { // accounts for https://github.com/platers/obsidian-linter/issues/484
-      testName: 'Make sure that first letter ot be capitalized by `First Letter` is preceded by a space or tab',
+      testName: 'Make sure that first letter to be capitalized by `First Letter` is preceded by a space or tab',
       before: dedent`
         ### 1.0.0-b.4
         ### b
@@ -165,5 +165,22 @@ ruleTest({
         ignoreCasedWords: true,
       },
     },
+    { // accounts for https://github.com/platers/obsidian-linter/issues/601
+      testName: `Make sure that if the 1st word has a number in it, it will still be considered to be a word and have its first letter capitalized`,
+      before: dedent`
+        # EC2 instance
+        ## EC2 lab05 load balancer
+        ### lab07 bread maker
+      `,
+      after: dedent`
+        # EC2 instance
+        ## EC2 lab05 load balancer
+        ### Lab07 bread maker
+      `,
+      options: {
+        style: 'First letter',
+        ignoreCasedWords: true,
+      },
+    },
   ],
 });
diff --git a/__tests__/header-increment.test.ts b/__tests__/header-increment.test.ts
index 14e2849..926ae3a 100644
--- a/__tests__/header-increment.test.ts
+++ b/__tests__/header-increment.test.ts
@@ -189,5 +189,20 @@ ruleTest({
         startAtH2: true,
       },
     },
+    { // accounts for https://github.com/platers/obsidian-linter/issues/598
+      testName: 'Make sure that headers with tags in them are incremented like normal',
+      before: dedent`
+        # Page Title
+        ## Foo #tag
+        ### Bar
+        ### Baz
+      `,
+      after: dedent`
+        # Page Title
+        ## Foo #tag
+        ### Bar
+        ### Baz
+      `,
+    },
   ],
 });