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

+ 23 - 25
apps/app/src/components/Page/RevisionRenderer.tsx

@@ -1,5 +1,6 @@
 import React, { useEffect, useState } from 'react';
 import React, { useEffect, useState } from 'react';
 
 
+import type { presentationSlideStyle } from '@growi/presentation';
 import dynamic from 'next/dynamic';
 import dynamic from 'next/dynamic';
 import { ErrorBoundary, FallbackProps } from 'react-error-boundary';
 import { ErrorBoundary, FallbackProps } from 'react-error-boundary';
 import ReactMarkdown from 'react-markdown';
 import ReactMarkdown from 'react-markdown';
@@ -46,38 +47,35 @@ const RevisionRenderer = React.memo((props: Props): JSX.Element => {
     rendererOptions, markdown, additionalClassName, isSlidesOverviewEnabled,
     rendererOptions, markdown, additionalClassName, isSlidesOverviewEnabled,
   } = props;
   } = props;
 
 
-  type presentationSlideStyle = 'marp' | 'true' | null;
   const [slideStyle, setSlideStyle] = useState<presentationSlideStyle>(null);
   const [slideStyle, setSlideStyle] = useState<presentationSlideStyle>(null);
 
 
+  // useEffect avoid ssr
   useEffect(() => {
   useEffect(() => {
+    const processMarkdown = () => (tree) => {
+      setSlideStyle(null);
+      visit(tree, 'yaml', (node) => {
+        if (node.value != null) {
+          const lines = node.value.split('\n');
+
+          lines.forEach((line) => {
+            const [key, value] = line.split(':').map(part => part.trim());
+
+            if (key === 'presentation') {
+              setSlideStyle(value === 'marp' || value === 'true' ? value : null);
+            }
+            else if (key === 'marp' && value === 'true') {
+              setSlideStyle('marp');
+            }
+          });
+        }
+      });
+    };
+
     unified()
     unified()
       .use(remarkParse)
       .use(remarkParse)
       .use(remarkStringify)
       .use(remarkStringify)
       .use(remarkFrontmatter, ['yaml'])
       .use(remarkFrontmatter, ['yaml'])
-      .use(() => (tree) => {
-        setSlideStyle(null);
-        visit(tree, (node) => {
-          if (node.type === 'yaml') {
-            for (const line of node.value?.split('\n')) {
-            // node.value is "presentation:true\ntitle: hoge\nclass: fuga" etc..
-              const parts = line.split(':');
-              if (parts.length !== 2) {
-                continue;
-              }
-              const key = parts[0].trim();
-              const value = parts[1].trim();
-              if (key === 'presentation') {
-                setSlideStyle(
-                  value === 'marp' || value === 'true' ? value : null,
-                );
-              }
-              else if (key === 'marp' && value === 'true') {
-                setSlideStyle('marp');
-              }
-            }
-          }
-        });
-      })
+      .use(processMarkdown)
       .process(markdown);
       .process(markdown);
   }, [markdown, setSlideStyle]);
   }, [markdown, setSlideStyle]);
 
 

+ 13 - 2
packages/presentation/src/components/Slides.tsx

@@ -9,10 +9,10 @@ import type { PresentationOptions } from '../consts';
 import * as extractSections from '../services/renderer/extract-sections';
 import * as extractSections from '../services/renderer/extract-sections';
 
 
 import './Slides.global.scss';
 import './Slides.global.scss';
-import { string } from 'yargs';
 
 
 export const MARP_CONTAINER_CLASS_NAME = 'marpit';
 export const MARP_CONTAINER_CLASS_NAME = 'marpit';
 
 
+export type presentationSlideStyle = 'true' | 'marp' | null;
 
 
 const marp = new Marp({
 const marp = new Marp({
   container: [
   container: [
@@ -25,6 +25,8 @@ const marp = new Marp({
   math: false,
   math: false,
 });
 });
 
 
+// TODO: スライド表示したときのスタイルを整える
+// https://redmine.weseek.co.jp/issues/125680
 const marpDefaultTheme = marp.themeSet.default;
 const marpDefaultTheme = marp.themeSet.default;
 const marpSlideTheme = marp.themeSet.add(`
 const marpSlideTheme = marp.themeSet.add(`
     /*!
     /*!
@@ -39,7 +41,7 @@ const marpSlideTheme = marp.themeSet.add(`
 type Props = {
 type Props = {
   options: PresentationOptions,
   options: PresentationOptions,
   children?: string,
   children?: string,
-  slideStyle?: 'true' | 'marp' | null,
+  slideStyle?: presentationSlideStyle,
 }
 }
 
 
 export const Slides = (props: Props): JSX.Element => {
 export const Slides = (props: Props): JSX.Element => {
@@ -58,6 +60,11 @@ export const Slides = (props: Props): JSX.Element => {
 
 
 
 
   if (slideStyle === 'true') {
   if (slideStyle === 'true') {
+    // TODO: スライド表示したときのスタイルを整える
+    // https://redmine.weseek.co.jp/issues/125680
+    // Presentation と違い RevisionRenderer が Dynamic import ではなく、
+    // classname = marpit とできない。
+    // RevisionRenderer 内に Slides でスライドを表示するための条件分岐
     marp.themeSet.default = marpSlideTheme;
     marp.themeSet.default = marpSlideTheme;
     const { css } = marp.render('', { htmlAsArray: true });
     const { css } = marp.render('', { htmlAsArray: true });
     return (
     return (
@@ -76,6 +83,8 @@ export const Slides = (props: Props): JSX.Element => {
     );
     );
   }
   }
 
 
+  // TODO: Marp でレンダリングできる
+  // https://redmine.weseek.co.jp/issues/115673
   if (slideStyle === 'marp') {
   if (slideStyle === 'marp') {
     return (
     return (
       <></>
       <></>
@@ -95,4 +104,6 @@ export const Slides = (props: Props): JSX.Element => {
       </ReactMarkdown>
       </ReactMarkdown>
     </>
     </>
   );
   );
+
+
 };
 };