slides.ts 2.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293
  1. import type { Schema as SanitizeOption } from 'hast-util-sanitize';
  2. import type { Root } from 'mdast';
  3. import { frontmatterToMarkdown } from 'mdast-util-frontmatter';
  4. import { gfmToMarkdown } from 'mdast-util-gfm';
  5. import { toMarkdown } from 'mdast-util-to-markdown';
  6. import type { Plugin } from 'unified';
  7. import type { Node } from 'unist';
  8. import { visit } from 'unist-util-visit';
  9. const SUPPORTED_ATTRIBUTES = ['children', 'marp'];
  10. const rewriteNode = (tree: Node, node: Node) => {
  11. let slide = false;
  12. let marp = false;
  13. const lines = (node.value as string).split('\n');
  14. lines.forEach((line) => {
  15. const [key, value] = line.split(':').map(part => part.trim());
  16. if (key === 'slide' && value === 'true') {
  17. slide = true;
  18. }
  19. else if (key === 'marp' && value === 'true') {
  20. marp = true;
  21. }
  22. });
  23. if (marp || slide) {
  24. let markdown = '';
  25. const createMarkdownParent = new Set<Node>([tree]);
  26. visit(tree, (node, index, parent: Node) => {
  27. try {
  28. if (createMarkdownParent.has(parent)) {
  29. const tmp = toMarkdown(node as Root, {
  30. extensions: [
  31. frontmatterToMarkdown(['yaml']),
  32. gfmToMarkdown(),
  33. ],
  34. });
  35. if (node.type === 'heading') {
  36. markdown += '\n';
  37. }
  38. markdown += tmp;
  39. }
  40. }
  41. catch (err) {
  42. createMarkdownParent.add(node);
  43. if (node?.children == null) {
  44. markdown += ' ';
  45. }
  46. }
  47. });
  48. console.log(markdown);
  49. console.log(createMarkdownParent);
  50. const newNode: Node = {
  51. type: 'root',
  52. data: {},
  53. position: tree.position,
  54. children: tree.children,
  55. };
  56. const data = newNode.data ?? (newNode.data = {});
  57. tree.children = [newNode];
  58. data.hName = 'slide';
  59. data.hProperties = {
  60. marp: marp ? 'marp' : '',
  61. children: markdown,
  62. };
  63. }
  64. };
  65. export const remarkPlugin: Plugin = function() {
  66. return (tree) => {
  67. visit(tree, (node) => {
  68. if (node.type === 'yaml' && node.value != null) {
  69. rewriteNode(tree, node);
  70. }
  71. });
  72. };
  73. };
  74. export const sanitizeOption: SanitizeOption = {
  75. tagNames: ['slide'],
  76. attributes: {
  77. slide: SUPPORTED_ATTRIBUTES,
  78. },
  79. };