Repository: platers/obsidian-linter (ts)

Issue:
Bug: regex problem
In Custeom Regex Replacement section I'm trying to convert HTML links to markdown links with that regex:

find: `<a.*?href=["']([^"']*)["'][^>]*>([^<]*)<\/a>` `igm` `[$2]($1)`

Generally it works, but sometimes it fails, for example in this case:

```
Wycinek utworzono z: <a href="https://www.tygodnikpowszechny.pl/zycie-pod-mikroskopem-151274" class="tc-tiddlylink-external" rel="noopener noreferrer" target="_blank">https://www.tygodnikpowszechny.pl/zycie-pod-mikroskopem-151274</a>
```
the link is converted to:

```
Wycinek utworzono z: <a href="https://www.tygodnikpowszechny.pl/zycie-pod-mikroskopem-151274" class="tc-tiddlylink-external" rel="noopener noreferrer" target="_blank"><https://www.tygodnikpowszechny.pl/zycie-pod-mikroskopem-151274</a>>
```

When testing in [https://regexr.com/](https://regexr.com/), my regex works fine.

Pull request description:
Ignore Anchor Tags in `No Bare URLs`
Fixes #588 

Changes Made:
- Added a UT
- Made it so that No Bare URLs now ignores anchor tags to not erroneously add `<` and `>` around the anchor text
- Added anchor tag regex and the ignore type for anchor tags


Patch:
diff --git a/src/rules/no-bare-urls.ts b/src/rules/no-bare-urls.ts
index 52d7cca..df3ac23 100644
--- a/src/rules/no-bare-urls.ts
+++ b/src/rules/no-bare-urls.ts
@@ -25,7 +25,7 @@ export default class NoBareUrls extends RuleBuilder<NoBareUrlsOptions> {
     return RuleType.CONTENT;
   }
   apply(text: string, options: NoBareUrlsOptions): string {
-    return ignoreListOfTypes([IgnoreTypes.code, IgnoreTypes.math, IgnoreTypes.yaml, IgnoreTypes.link, IgnoreTypes.wikiLink, IgnoreTypes.tag, IgnoreTypes.image, IgnoreTypes.inlineCode], text, (text) => {
+    return ignoreListOfTypes([IgnoreTypes.code, IgnoreTypes.math, IgnoreTypes.yaml, IgnoreTypes.link, IgnoreTypes.wikiLink, IgnoreTypes.tag, IgnoreTypes.image, IgnoreTypes.inlineCode, IgnoreTypes.anchorTag], text, (text) => {
       const URLMatches = text.match(urlRegex);
 
       if (!URLMatches) {
diff --git a/src/utils/ignore-types.ts b/src/utils/ignore-types.ts
index 718666e..9cbb111 100644
--- a/src/utils/ignore-types.ts
+++ b/src/utils/ignore-types.ts
@@ -1,4 +1,4 @@
-import {obsidianMultilineCommentRegex, tagWithLeadingWhitespaceRegex, wikiLinkRegex, yamlRegex, escapeDollarSigns, genericLinkRegex, tableRegex, urlRegex} from './regex';
+import {obsidianMultilineCommentRegex, tagWithLeadingWhitespaceRegex, wikiLinkRegex, yamlRegex, escapeDollarSigns, genericLinkRegex, tableRegex, urlRegex, anchorTagRegex} from './regex';
 import {getPositions, MDAstTypes} from './mdast';
 import type {Position} from 'unist';
 import {replaceTextBetweenStartAndEndWithNewValue} from './strings';
@@ -29,6 +29,7 @@ export const IgnoreTypes: Record<string, IgnoreType> = {
   footnoteAtStartOfLine: {replaceAction: /^(\[\^\w+\]) ?([,.;!:?])/gm, placeholder: '{FOOTNOTE_AT_START_OF_LINE_PLACEHOLDER}'},
   footnoteAfterATask: {replaceAction: /- \[.] (\[\^\w+\]) ?([,.;!:?])/gm, placeholder: '{FOOTNOTE_AFTER_A_TASK_PLACEHOLDER}'},
   url: {replaceAction: urlRegex, placeholder: '{URL_PLACEHOLDER}'},
+  anchorTag: {replaceAction: anchorTagRegex, placeholder: '{ANCHOR_PLACEHOLDER}'},
   // custom functions
   link: {replaceAction: replaceMarkdownLinks, placeholder: '{REGULAR_LINK_PLACEHOLDER}'},
 } as const;
diff --git a/src/utils/regex.ts b/src/utils/regex.ts
index 3ea3b75..0b3b84b 100644
--- a/src/utils/regex.ts
+++ b/src/utils/regex.ts
@@ -22,6 +22,7 @@ export const lineStartingWithWhitespaceOrBlockquoteTemplate = `\\s*(>\\s*)*`;
 // if this becomes an issue, we can address it then
 export const tableRegex = /^((((>[ ]?)*)|([ ]{0,3}))\[.*?\][ \t]*\n)?((((>[ ]?)*)|([ ]{0,3}))\S+.*?\|.*?\n([^\n]*?\|[^\n]*?\n)*?)?(((>[ ]?)*)|([ ]{0,3}))[|\-+:.][ \-+|:.]*?\|[ \-+|:.]*(?:\n?[^\n]*?\|([^\n]*?)*)+/gm;
 export const urlRegex = /(https?:\/\/(?:www\.|(?!www))[a-zA-Z0-9][a-zA-Z0-9-]+[a-zA-Z0-9]\.[^\s`\]'"‘’“”>]{2,}|www\.[a-zA-Z0-9][a-zA-Z0-9-]+[a-zA-Z0-9]\.[^\s`\]'"‘’“”>]{2,}|https?:\/\/(?:www\.|(?!www))[a-zA-Z0-9]+\.[^\s`\]'"‘’“”>]{2,}|www\.[a-zA-Z0-9]+\.[^\s`\]'"‘’“”>]{2,})/gi;
+export const anchorTagRegex = /<a[\s]+([^>]+)>((?:.(?!<\/a>))*.)<\/a>/g;
 
 // https://stackoverflow.com/questions/38866071/javascript-replace-method-dollar-signs
 // Important to use this for any regex replacements where the replacement string


Test patch:
diff --git a/__tests__/no-bare-urls.test.ts b/__tests__/no-bare-urls.test.ts
index 4c7cab0..40e9d05 100644
--- a/__tests__/no-bare-urls.test.ts
+++ b/__tests__/no-bare-urls.test.ts
@@ -47,5 +47,14 @@ ruleTest({
         \`http --headers --follow --all https://google.com\`
       `,
     },
+    {// https://github.com/platers/obsidian-linter/issues/588
+      testName: 'Make sure that anchor tags are not affected by the rule',
+      before: dedent`
+        <a href="https://www.google.com" class="tc-tiddlylink-external" rel="noopener noreferrer" target="_blank">https://www.google.com</a>
+      `,
+      after: dedent`
+        <a href="https://www.google.com" class="tc-tiddlylink-external" rel="noopener noreferrer" target="_blank">https://www.google.com</a>
+      `,
+    },
   ],
 });