Skip to content

Commit 40e6bf9

Browse files
committed
fix: unescape H1 markdown
1 parent 7693128 commit 40e6bf9

File tree

3 files changed

+45
-13
lines changed

3 files changed

+45
-13
lines changed

__tests__/yaml-title.test.ts

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -374,5 +374,17 @@ ruleTest({
374374
# Hello world
375375
`,
376376
},
377+
{ // accounts for https://github.com/platers/obsidian-linter/issues/1428
378+
testName: 'Unescapes H1 markdown special characters',
379+
before: dedent`
380+
# Escape \\[\\_\\]
381+
`,
382+
after: dedent`
383+
---
384+
title: Escape [_]
385+
---
386+
# Escape \\[\\_\\]
387+
`,
388+
},
377389
],
378390
});

src/utils/regex.ts

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
import {getAllTablesInText} from './mdast';
2-
import {makeSureContentHasEmptyLinesAddedBeforeAndAfter} from './strings';
2+
import {makeSureContentHasEmptyLinesAddedBeforeAndAfter, unescapeMarkdownSpecialCharacters} from './strings';
33

44
// Useful regexes
55
export const allHeadersRegex = /^([ \t]*)(#+)([ \t]+)([^\n\r]*?)([ \t]+#+)?$/gm;
@@ -123,7 +123,8 @@ export function getFirstHeaderOneText(text: string): string {
123123
return $2;
124124
});
125125

126-
return headerText.replaceAll(genericLinkRegex, '$2');
126+
headerText = headerText.replaceAll(genericLinkRegex, '$2');
127+
return unescapeMarkdownSpecialCharacters(headerText);
127128
}
128129

129130
return '';

src/utils/strings.ts

Lines changed: 30 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
1-
import {calloutRegex, codeBlockBlockquoteRegex} from './regex';
2-
import {getTextInLanguage} from '../lang/helpers';
3-
import {logWarn} from './logger';
4-
import {getAllTablesInText} from './mdast';
1+
import { calloutRegex, codeBlockBlockquoteRegex } from './regex';
2+
import { getTextInLanguage } from '../lang/helpers';
3+
import { logWarn } from './logger';
4+
import { getAllTablesInText } from './mdast';
55
/**
66
* Inserts a string at the given position in a string.
77
* @param {string} str - The string to insert into
@@ -163,7 +163,7 @@ function makeSureContentHasASingleEmptyLineBeforeItUnlessItStartsAFileForBlockqu
163163
}
164164

165165
let firstLineOfBlockquote: string;
166-
const indexOfEndOfFirstLine = text.indexOf('\n', startOfContent+1);
166+
const indexOfEndOfFirstLine = text.indexOf('\n', startOfContent + 1);
167167
if (indexOfEndOfFirstLine === -1) {
168168
firstLineOfBlockquote = text.substring(startOfContent);
169169
} else {
@@ -289,11 +289,11 @@ function makeSureContentHasASingleEmptyLineAfterItUnlessItEndsAFileForBlockquote
289289
}
290290

291291
let lastLineOfBlockquote: string;
292-
const indexOfEndOfLastLine = text.lastIndexOf('\n', endOfContent-1);
292+
const indexOfEndOfLastLine = text.lastIndexOf('\n', endOfContent - 1);
293293
if (indexOfEndOfLastLine === -1) {
294294
lastLineOfBlockquote = text.substring(0, endOfNewContent);
295295
} else {
296-
lastLineOfBlockquote = text.substring(indexOfEndOfLastLine+1, endOfContent);
296+
lastLineOfBlockquote = text.substring(indexOfEndOfLastLine + 1, endOfContent);
297297
}
298298

299299
let emptyLine: string;
@@ -408,7 +408,7 @@ export function replaceAt(text: string, search: string, replace: string, start:
408408
}
409409

410410
return text.slice(0, start) +
411-
text.slice(start, text.length).replace(search, replace);
411+
text.slice(start, text.length).replace(search, replace);
412412
}
413413

414414
// based on https://stackoverflow.com/a/21730166/8353749
@@ -432,7 +432,7 @@ export function isNumeric(str: string) {
432432
const type = typeof str;
433433
if (type != 'string') return type === 'number'; // we only process strings so if the value is not already a number the result is false
434434
return !isNaN(str as unknown as number) && // use type coercion to parse the _entirety_ of the string (`parseFloat` alone does not do this)...
435-
!isNaN(parseFloat(str)); // ...and ensure strings of whitespace fail
435+
!isNaN(parseFloat(str)); // ...and ensure strings of whitespace fail
436436
}
437437

438438
export function getSubstringIndex(substring: string, text: string): number[] {
@@ -447,7 +447,7 @@ export function getSubstringIndex(substring: string, text: string): number[] {
447447

448448
function getIndexOfStartOfFirstNonEmptyLine(text: string, currentStartOfBlockquote: number, blockquoteLevel: number): number {
449449
let actualStartOfBlockquote = currentStartOfBlockquote;
450-
let blockquoteIndex = currentStartOfBlockquote+1;
450+
let blockquoteIndex = currentStartOfBlockquote + 1;
451451
let currentChar = '';
452452
let foundNewStart = false;
453453
let level = 0;
@@ -479,7 +479,7 @@ function getIndexOfStartOfFirstNonEmptyLine(text: string, currentStartOfBlockquo
479479

480480
function getIndexOfEndOfLastNonEmptyLine(text: string, currentEndOfBlockquote: number, blockquoteLevel: number): number {
481481
let actualEndOfBlockquote = currentEndOfBlockquote;
482-
let blockquoteIndex = currentEndOfBlockquote-1;
482+
let blockquoteIndex = currentEndOfBlockquote - 1;
483483
let currentChar = '';
484484
let foundNewEnd = false;
485485
let level = 0;
@@ -535,3 +535,22 @@ export function parseCustomReplacements(text: string): Map<string, string> {
535535

536536
return customReplacements;
537537
}
538+
539+
/**
540+
* Unescapes the markdown special characters in the provided text.
541+
*
542+
* @param {string} text - The text to unescape the markdown special characters in.
543+
* @return {string} The text with the markdown special characters unescaped.
544+
*
545+
* @example
546+
* ```ts
547+
* unescapeMarkdownSpecialCharacters('Escape \\[\\_\\]'); // Escape [_]
548+
* ```
549+
*/
550+
export function unescapeMarkdownSpecialCharacters(text: string): string {
551+
return text.replace(/(\\+)([!"#$%&'()*+,-./:;<=>?@\[\\\]^_`{|}~])/g, (_, backslashes, specialChar) => {
552+
const backslashCount = backslashes.length;
553+
const keepCount = Math.floor(backslashCount / 2);
554+
return '\\'.repeat(keepCount) + specialChar;
555+
});
556+
}

0 commit comments

Comments
 (0)