attachment.ts 1.3 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455
  1. import path from 'path';
  2. import type { Schema as SanitizeOption } from 'hast-util-sanitize';
  3. import type { Link } from 'mdast';
  4. import type { Plugin } from 'unified';
  5. import { visit } from 'unist-util-visit';
  6. declare module 'mdast' {
  7. interface LinkData {
  8. hName?: string,
  9. hProperties?: {
  10. attachmentId?: string,
  11. url?: string,
  12. attachmentName?: PhrasingContent,
  13. }
  14. }
  15. }
  16. const SUPPORTED_ATTRIBUTES = ['attachmentId', 'url', 'attachmentName'];
  17. const isAttachmentLink = (url: string): boolean => {
  18. // https://regex101.com/r/9qZhiK/1
  19. const attachmentUrlFormat = new RegExp(/^\/(attachment)\/([^/^\n]+)$/);
  20. return attachmentUrlFormat.test(url);
  21. };
  22. const rewriteNode = (node: Link) => {
  23. const attachmentId = path.basename(node.url);
  24. const data = node.data ?? (node.data = {});
  25. data.hName = 'attachment';
  26. data.hProperties = {
  27. attachmentId,
  28. url: node.url,
  29. attachmentName: node.children[0] ?? '',
  30. };
  31. };
  32. export const remarkPlugin: Plugin = () => {
  33. return (tree) => {
  34. visit(tree, 'link', (node: Link) => {
  35. if (isAttachmentLink(node.url)) {
  36. rewriteNode(node);
  37. }
  38. });
  39. };
  40. };
  41. export const sanitizeOption: SanitizeOption = {
  42. tagNames: ['attachment'],
  43. attributes: {
  44. attachment: SUPPORTED_ATTRIBUTES,
  45. },
  46. };