Merge branch 'main' into avm99963-monorail

Merged commit 9b72c743236c5333af241ea6eaf89dd7de15777c.

Also, removed files module-*.yaml, since before we excluded them in the
Makefile, but now they are included by default, and we don't want them.

GitOrigin-RevId: de032b6e562c3c0cb63464bf536f7a020f82f663
diff --git a/static_src/shared/md-helper.js b/static_src/shared/md-helper.js
index 8559778..2a0fb46 100644
--- a/static_src/shared/md-helper.js
+++ b/static_src/shared/md-helper.js
@@ -5,7 +5,10 @@
 export const DEFAULT_MD_PROJECTS = new Set(['vulnz', 'vulnz-old', 'twpowertools', 'translateselectedtext', 'misc']);
 
 /** @type {Set} Projects that allow users to opt into Markdown rendering. */
-export const AVAILABLE_MD_PROJECTS = new Set([...DEFAULT_MD_PROJECTS, 'pigweed']);
+export const AVAILABLE_MD_PROJECTS = new Set([...DEFAULT_MD_PROJECTS]);
+
+const EMAIL_REGEX = /^mailto:[-a-zA-Z0-9!#$%&'*+\/=?^_`{|}~]+(?:[.][-a-zA-Z0-9!#$%&'*+\/=?^_`{|}~]+)*@(?:(?:[0-9a-zA-Z](?:[-]*[0-9a-zA-Z]+)*)(?:\.[0-9a-zA-Z](?:[-]*[0-9a-zA-Z]+)*)*)\.(?:[a-zA-Z]{2,9})$/;
+const MONORAIL_USER_REGEX = /\/u\/[-a-zA-Z0-9!#$%&'*+\/=?^_`{|}~]+(?:[.][-a-zA-Z0-9!#$%&'*+\/=?^_`{|}~]+)*@(?:(?:[0-9a-zA-Z](?:[-]*[0-9a-zA-Z]+)*)(?:\.[0-9a-zA-Z](?:[-]*[0-9a-zA-Z]+)*)*)\.(?:[a-zA-Z]{2,9})$/;
 
 /** @type {Set} Authors whose comments will not be rendered as Markdown. */
 const BLOCKLIST = new Set(['sheriffbot@sheriffbot-1182.iam.gserviceaccount.com',
@@ -98,6 +101,15 @@
 };
 
 /**
+* Checks to see if input string matches a href generated by Monorail's autolinking code.
+ * @param {string} string
+ * @return {boolean} Whether input string is an email address.
+ */
+const isEmailLink = (string) => {
+  return EMAIL_REGEX.test(string) || MONORAIL_USER_REGEX.test(string)
+}
+
+/**
  * Renderer option for Marked.
  * See https://marked.js.org/using_pro#renderer on how to use renderer.
  * @type {Object}
@@ -113,7 +125,7 @@
     // components that consume the markdown renderer.
     let linkIcon;
     let tooltipText;
-    if (isValidHttpUrl(href)) {
+    if (isValidHttpUrl(href) || isEmailLink(href)) {
       linkIcon = `<span class="material-icons link">link</span>`;
       tooltipText = `Link destination: ${href}`;
     } else {
diff --git a/static_src/shared/md-helper.test.js b/static_src/shared/md-helper.test.js
index 9f7dba1..cd77d55 100644
--- a/static_src/shared/md-helper.test.js
+++ b/static_src/shared/md-helper.test.js
@@ -69,6 +69,25 @@
           `google.com</span></span></p>\n`;
       assert.equal(actual, expected);
     });
+
+    it('correctly renders emails', () => {
+      const actual = renderMarkdown('[person@google.com](mailto:person@google.com)');
+      const expected = `<p><span class="annotated-link"><a title="" ` +
+      `href="mailto:person@google.com"><span class="material-icons link">` +
+      `link</span>person@google.com</a><span class="tooltip">Link destination: ` +
+      `mailto:person@google.com</span></span></p>\n`;
+      assert.equal(actual, expected);
+    });
+
+    it('correctly renders monorail user links', () => {
+      const actual = renderMarkdown('[person@google.com](/u/person@google.com)');
+      const expected = `<p><span class="annotated-link"><a title="" ` +
+      `href="/u/person@google.com"><span class="material-icons ` +
+      `link">link</span>person@google.com</a><span class="tooltip">Link destination: ` +
+      `/u/person@google.com</span></span></p>\n`
+      assert.equal(actual, expected)
+    });
+
   });
 
   it('preserves bolding from description templates', () => {