import type { MentionMap } from "./mentions";
const NAME = "[A-Za-z0-9](?:[A-Za-z0-9-]{0,38})";
const REPO = "[A-Za-z0-9._-]{1,100}";
const TEAM = "[A-Za-z0-9][A-Za-z0-9_-]{0,99}";
const SHA = "[0-9a-f]{7,40}";
const SHORT_SHA = 7;
/** One pass over plain text so inserted anchors are never re-scanned by a later pattern. */
const REFERENCE = new RegExp(
`(?<prefix>^|[\\s(])(?:${[
`@(?<teamOrg>${NAME})\\/(?<team>${TEAM})`,
`@(?<user>${NAME})`,
`(?<issueOwner>${NAME})\\/(?<issueRepo>${REPO})#(?<issueNumber>\\d+)`,
`(?<commitOwner>${NAME})\\/(?<commitRepo>${REPO})@(?<commitSha>${SHA})`,
`#(?<localNumber>\\d+)`,
`(?<localSha>${SHA})`,
].join("|")})\\b`,
"g",
);
type Groups = Partial<Record<string, string>>;
function escapeHtml(value: string): string {
return value.replace(/[&<>"']/g, (char) => `&#${char.charCodeAt(0)};`);
}
function anchor(href: string, text: string, kind: string, ref: string, className = ""): string {
const classAttr = className ? ` class="${className}"` : "";
return `<a href="${escapeHtml(href)}"${classAttr} data-hovercard="${kind}" data-ref="${escapeHtml(ref)}">${escapeHtml(text)}</a>`;
}
/**
* Links `@user`, `@org/team`, `#123`, `owner/repo#123`, `owner/repo@sha` and bare commit SHAs in a text
* segment of rendered HTML. Anchors carry `data-hovercard` so the client can show previews.
*/
export function linkTextReferences(
text: string,
context: { owner: string; repo: string } | null,
mentions: MentionMap | null = null,