reiji-h 2 лет назад
Родитель
Сommit
ba9326f146

+ 2 - 2
apps/app/src/components/Page/RevisionRenderer.tsx

@@ -1,6 +1,6 @@
 import React from 'react';
 
-import { hasEnabledSlideTypes } from '@growi/presentation/src/services';
+import { parseSlideFrontmatterInMarkdown } from '@growi/presentation';
 import type { FallbackProps } from 'react-error-boundary';
 import { ErrorBoundary } from 'react-error-boundary';
 import ReactMarkdown from 'react-markdown';
@@ -42,7 +42,7 @@ const RevisionRenderer = React.memo((props: Props): JSX.Element => {
   } = props;
 
   const { data: isEnabledMarp } = useIsEnabledMarp();
-  const [, marp, useSlide] = hasEnabledSlideTypes(markdown);
+  const [, marp, useSlide] = parseSlideFrontmatterInMarkdown(markdown);
   const useMarp = !!isEnabledMarp && marp;
 
   return (

+ 0 - 2
packages/presentation/src/components/index.ts

@@ -1,2 +0,0 @@
-export * from './Slides';
-export * from './Presentation';

+ 3 - 2
packages/presentation/src/index.ts

@@ -1,2 +1,3 @@
-export * from './components';
-export * from './services';
+export * from './components/Presentation';
+export * from './components/Slides';
+export * from './services/parse-slide-frontmatter';

+ 0 - 25
packages/presentation/src/services/has-enabled-slide-types.ts

@@ -1,25 +0,0 @@
-export const hasEnabledSlideTypes = (markdown?: string): [boolean, boolean, boolean] => {
-
-  if (markdown == null) {
-    return [false, false, false];
-  }
-
-  const text = markdown.slice(0, 300);
-
-  const reStartFrontmatter = /^---\s*\n/g;
-  const reEndFrontmatter = /\n---\s*\n/g;
-
-  if (!reStartFrontmatter.test(text) || !reEndFrontmatter.test(text)) {
-    return [false, false, false];
-  }
-
-  const reEnableMarp = /\nmarp\s*:\s+true\n/g;
-  const reEnableSlide = /\nslide\s*:\s+true\n/g;
-
-  const marp = reEnableMarp.test(text) && reEnableMarp.lastIndex < reEndFrontmatter.lastIndex;
-  const slide = reEnableSlide.test(text) && reEnableSlide.lastIndex < reEndFrontmatter.lastIndex;
-
-  const enable = marp || slide;
-
-  return [enable, marp, slide];
-};

+ 0 - 1
packages/presentation/src/services/index.ts

@@ -1 +0,0 @@
-export * from './has-enabled-slide-types';

+ 43 - 0
packages/presentation/src/services/parse-slide-frontmatter.ts

@@ -0,0 +1,43 @@
+import remarkFrontmatter from 'remark-frontmatter';
+import remarkParse from 'remark-parse';
+import remarkStringify from 'remark-stringify';
+import { unified } from 'unified';
+
+
+export const parseSlideFrontmatter = (frontmatter: string): [boolean, boolean] => {
+
+  let marp = false;
+  let slide = false;
+
+  const lines = frontmatter.split('\n');
+  lines.forEach((line) => {
+    const [key, value] = line.split(':').map(part => part.trim());
+    if (key === 'marp' && value === 'true') {
+      marp = true;
+    }
+    if (key === 'slide' && value === 'true') {
+      slide = true;
+    }
+  });
+
+  return [marp, slide];
+};
+
+export const parseSlideFrontmatterInMarkdown = (markdown?: string): [boolean, boolean] => {
+
+  let marp = false;
+  let slide = false;
+
+  unified()
+    .use(remarkParse)
+    .use(remarkStringify)
+    .use(remarkFrontmatter, ['yaml'])
+    .use(() => ((obj) => {
+      if (obj.children[0]?.type === 'yaml') {
+        [marp, slide] = parseSlideFrontmatter(obj.children[0]?.value as string);
+      }
+    }))
+    .process(markdown as string);
+
+  return [marp, slide];
+};