attachment.ts 1.2 KB

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