import { remark } from 'remark'; import gfm from 'remark-gfm'; import type { Options as RemarkGithubOptions } from 'remark-github'; import github from 'remark-github'; import { regEx } from './regex.ts'; // Generic replacements/link-breakers export function sanitizeMarkdown(markdown: string): string { let res = markdown; // Put a zero width space after every # followed by a digit res = res.replace( regEx(/(?
\W)#(?\d)/gi),
    '$
#​$',
  );
  // Put a zero width space after every @ symbol to prevent unintended hyperlinking,
  // but leave URLs, code blocks (triple backticks), and inline code spans untouched
  res = res
    .split(regEx(/(?```[\s\S]*?```|`[^`\n]*?`|https?:\/\/[^\s<]+)/gi))
    .map((part) =>
      part.startsWith('`') || regEx(/^https?:\/\//i).test(part)
        ? part
        : part.replace(regEx(/@/g), '@​'),
    )
    .join('');
  res = res.replace(regEx(/(?
[a-z]@)​/gi), '$
');
  res = res.replace(regEx(/\/compare\/@​/g), '/compare/@');
  res = res.replace(
    regEx(/(?
\(https:\/\/[^)]*?)\.\.\.@​/g),
    '$
...@',
  );
  res = res.replace(
    regEx(/(?
[\s(])#(?\d+)(?[)\s]?)/g),
    '$
#​$$',
  );
  // convert escaped backticks back to `
  const backTickRe = regEx(/`(?[^/]*?)`/g);
  res = res.replace(backTickRe, '`$`');
  res = res.replace(regEx(/`#​(?\d+)`/g), '`#$`');
  res = res.replace(
    regEx(/(?[^\n]\n)(?#.*)/g),
    '$<before>\n$<title>',
  );
  return res;
}

/**
 *
 * @param content content to process
 * @param options github options
 * @returns linkified content
 */
export async function linkify(
  content: string,
  options: RemarkGithubOptions,
): Promise<string> {
  // https://github.com/syntax-tree/mdast-util-to-markdown#optionsbullet
  const output = await remark()
    .use({ settings: { bullet: '-' } })
    .use(gfm)
    .use(github, { mentionStrong: false, ...options })
    .process(content);
  return output.toString();
}