Repository: platers/obsidian-linter (ts)

Issue:
Bug Capitalize Headings: bug with accented letters
Hi ! Here is a but with  the "Capitalize Headings" fonction.

## Describe the Bug
When Capitalize Headings is enabled, and a title begins with an accented letter, the first two letters of the title will be capitalized instead of just the first letter.



## How to Reproduce

Steps to reproduce the behavior:

1. Just write a title starting with an accented letter
2. lint the file with Capitalize Headings a/ enabled ; b/ Style set to "First letter"


## Unexpected Behavior

E.g
```
## état  
```
will be replaced by 
```
## ÉTat
```
and
```
## équilibre
```
will be replaced by 
```
## ÉQuilibre
```

## Expected Behavior
```
## état  
```
should be replaced by 
```
## État
```
and
```
## équilibre
```
will be replaced by 
```
## Équilibre
```


Thanks for your work !
Michaël


Pull request description:
Fix Issue with Capitalization in Headers Ignoring Non-English Letters
Fixes #321 

Changes Made:
- Swapped out the English letter check for the unicode letter check
- Added test for First Letter and Title Case capitalization styles
- Added an example for fenced code blocks that shows how nested code blocks get empty lines added around them

Patch:
diff --git a/docs/rules.md b/docs/rules.md
index 3495fe9..4812ed9 100644
--- a/docs/rules.md
+++ b/docs/rules.md
@@ -1743,6 +1743,32 @@ After:
 > > var other text = 'this is more text';
 > > ```
 ``````
+Example: Nested fenced code blocks get empty lines added around them
+
+Before:
+
+``````markdown
+```markdown
+# Header
+
+````JavaScript
+var text = 'some string';
+````
+```
+``````
+
+After:
+
+``````markdown
+```markdown
+# Header
+
+````JavaScript
+var text = 'some string';
+````
+
+```
+``````
 
 ### Empty Line Around Tables
 
diff --git a/src/rules/capitalize-headings.ts b/src/rules/capitalize-headings.ts
index 06761c8..1f6e37e 100644
--- a/src/rules/capitalize-headings.ts
+++ b/src/rules/capitalize-headings.ts
@@ -81,7 +81,7 @@ export default class CapitalizeHeadings extends RuleBuilder<CapitalizeHeadingsOp
             const ignoreShortWords = options.lowercaseWords;
             let firstWord = true;
             for (let j = 1; j < headerWords.length; j++) {
-              const isWord = headerWords[j].match(/^[A-Za-z'-]+[.?!,:;]?$/);
+              const isWord = headerWords[j].match(/^[\p{L}'-]+[.?!,:;]?$/u);
               if (!isWord) {
                 continue;
               }
@@ -114,9 +114,10 @@ export default class CapitalizeHeadings extends RuleBuilder<CapitalizeHeadingsOp
             lines[i] = lines[i].toUpperCase(); // convert full heading to uppercase
             break;
           case 'First letter':
+            // based on https://stackoverflow.com/a/62032796 "/\p{L}/u" accounts for all unicode letters across languages
             lines[i] = lines[i]
                 .toLowerCase()
-                .replace(/^#*\s+([^a-z])*([a-z])/, (string) => string.toUpperCase()); // capitalize first letter of heading
+                .replace(/^#*\s+([^\p{L}])*([\p{L}])/u, (string) => string.toUpperCase()); // capitalize first letter of heading
             break;
         }
       }
diff --git a/src/rules/empty-line-around-code-fences.ts b/src/rules/empty-line-around-code-fences.ts
index e805f80..1489770 100644
--- a/src/rules/empty-line-around-code-fences.ts
+++ b/src/rules/empty-line-around-code-fences.ts
@@ -102,6 +102,28 @@ export default class EmptyLineAroundCodeFences extends RuleBuilder<EmptyLineArou
           > > \`\`\`
         `,
       }),
+      new ExampleBuilder({
+        description: 'Nested fenced code blocks get empty lines added around them',
+        before: dedent`
+          \`\`\`markdown
+          # Header
+          ${''}
+          \`\`\`\`JavaScript
+          var text = 'some string';
+          \`\`\`\`
+          \`\`\`
+        `,
+        after: dedent`
+          \`\`\`markdown
+          # Header
+          ${''}
+          \`\`\`\`JavaScript
+          var text = 'some string';
+          \`\`\`\`
+          ${''}
+          \`\`\`
+        `,
+      }),
     ];
   }
   get optionBuilders(): OptionBuilderBase<EmptyLineAroundCodeFencesOptions>[] {
diff --git a/src/rules/empty-line-around-tables.ts b/src/rules/empty-line-around-tables.ts
index 916e179..01f8672 100644
--- a/src/rules/empty-line-around-tables.ts
+++ b/src/rules/empty-line-around-tables.ts
@@ -1,7 +1,6 @@
 import {Options, RuleType} from '../rules';
 import RuleBuilder, {ExampleBuilder, OptionBuilderBase} from './rule-builder';
 import dedent from 'ts-dedent';
-// import {ensureEmptyLinesAroundRegexMatches, tableRegex} from '../utils/regex';
 import {IgnoreTypes, ignoreListOfTypes} from '../utils/ignore-types';
 import {ensureEmptyLinesAroundTables} from '../utils/mdast';
 


Test patch:
diff --git a/src/test/capitalize-headings.test.ts b/src/test/capitalize-headings.test.ts
index 35f41f5..50b1de1 100644
--- a/src/test/capitalize-headings.test.ts
+++ b/src/test/capitalize-headings.test.ts
@@ -14,6 +14,8 @@ ruleTest({
         ## I can't do this
         ## comma, comma, comma
         ## 1.1 the Header
+        ## état
+        ## this état
       `,
       after: dedent`
         # h1
@@ -22,6 +24,8 @@ ruleTest({
         ## I Can't Do This
         ## Comma, Comma, Comma
         ## 1.1 The Header
+        ## État
+        ## This État
       `,
       options: {
         style: 'Title Case',
@@ -93,5 +97,18 @@ ruleTest({
         style: 'First letter',
       },
     },
+    {
+      // accounts for https://github.com/platers/obsidian-linter/issues/321
+      testName: 'Make sure non-english letters get capitalized when they are the first letter and the rule is set to capitalize the first letter',
+      before: dedent`
+        # état
+      `,
+      after: dedent`
+        # État
+      `,
+      options: {
+        style: 'First letter',
+      },
+    },
   ],
 });