attachment.ts 1.1 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344
  1. import path from 'path';
  2. import { Schema as SanitizeOption } from 'hast-util-sanitize';
  3. import { Plugin } from 'unified';
  4. import { Node } from 'unist';
  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: Node) => {
  13. const attachmentId = path.basename(node.url as string);
  14. const data = node.data ?? (node.data = {});
  15. data.hName = 'attachment';
  16. data.hProperties = {
  17. attachmentId,
  18. url: node.url,
  19. attachmentName: (node.children as any)[0]?.value,
  20. };
  21. };
  22. export const remarkPlugin: Plugin = () => {
  23. return (tree) => {
  24. visit(tree, (node) => {
  25. if (node.type === 'link') {
  26. if (isAttachmentLink(node.url as string)) {
  27. rewriteNode(node);
  28. }
  29. }
  30. });
  31. };
  32. };
  33. export const sanitizeOption: SanitizeOption = {
  34. tagNames: ['attachment'],
  35. attributes: {
  36. attachment: SUPPORTED_ATTRIBUTES,
  37. },
  38. };