attachment.ts 1.3 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849
  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', 'isSharedPage'];
  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, isSharedPage?: boolean) => {
  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. isSharedPage,
  21. };
  22. };
  23. type AttachmentPluginParams = {
  24. isSharedPage?: boolean,
  25. }
  26. export const remarkPlugin: Plugin<[AttachmentPluginParams]> = (options) => {
  27. return (tree) => {
  28. visit(tree, (node) => {
  29. if (node.type === 'link') {
  30. if (isAttachmentLink(node.url as string)) {
  31. rewriteNode(node, options.isSharedPage);
  32. }
  33. }
  34. });
  35. };
  36. };
  37. export const sanitizeOption: SanitizeOption = {
  38. tagNames: ['attachment'],
  39. attributes: {
  40. attachment: SUPPORTED_ATTRIBUTES,
  41. },
  42. };