Procházet zdrojové kódy

Merge branch 'imprv/115672-115674-presentation-preview' into feat/115673-marp

reiji-h před 2 roky
rodič
revize
7bbe1a6276

+ 1 - 1
apps/app/src/components/Page/PageView.tsx

@@ -132,7 +132,7 @@ export const PageView = (props: Props): JSX.Element => {
     return (
       <>
         <PageContentsUtilities />
-        <RevisionRenderer rendererOptions={rendererOptions} markdown={markdown} />
+        <RevisionRenderer rendererOptions={rendererOptions} markdown={markdown} isSlidesOverviewEnabled/>
       </>
     );
   };

+ 32 - 30
apps/app/src/components/Page/RevisionRenderer.tsx

@@ -46,51 +46,53 @@ const RevisionRenderer = React.memo((props: Props): JSX.Element => {
     rendererOptions, markdown, additionalClassName, isSlidesOverviewEnabled,
   } = props;
 
-  type presentationSlideStyle = 'marp' | 'true' | null;
-  const [slideStyle, setSlideStyle] = useState<presentationSlideStyle>(null);
+  const [hasSlideFlag, setHasSlideFlag] = useState<boolean>();
+  const [hasMarpFlag, setHasMarpFlag] = useState<boolean>();
 
+  // use useEffect to avoid ssr
   useEffect(() => {
-    unified()
-      .use(remarkParse)
-      .use(remarkStringify)
-      .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,
-                );
+    if (isSlidesOverviewEnabled) {
+      const processMarkdown = () => (tree) => {
+        setHasSlideFlag(false);
+        setHasMarpFlag(false);
+        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 === 'slide' && value === 'true') {
+                setHasSlideFlag(true);
               }
               else if (key === 'marp' && value === 'true') {
-                setSlideStyle('marp');
+                setHasMarpFlag(true);
               }
-            }
+            });
           }
         });
-      })
-      .process(markdown);
-  }, [markdown, setSlideStyle]);
-
-  if (slideStyle != null) {
+      };
+
+      unified()
+        .use(remarkParse)
+        .use(remarkStringify)
+        .use(remarkFrontmatter, ['yaml'])
+        .use(processMarkdown)
+        .process(markdown);
+    }
+  }, [markdown, setHasSlideFlag, setHasMarpFlag, isSlidesOverviewEnabled]);
+
+  if (isSlidesOverviewEnabled && (hasSlideFlag || hasMarpFlag)) {
     const options = {
       rendererOptions: rendererOptions as ReactMarkdownOptions,
       isDarkMode: false,
       disableSeparationsByHeader: false,
+      hasMarpFlag,
     };
     return (
       <Slides
         options={options}
-        slideStyle={slideStyle}
+        hasMarpFlag={hasMarpFlag}
       >{markdown}</Slides>
     );
   }

+ 1 - 1
apps/app/src/components/PageEditor/Preview.tsx

@@ -32,7 +32,7 @@ const Preview = React.forwardRef((props: Props, ref: RefObject<HTMLDivElement>):
       }}
     >
       { markdown != null && (
-        <RevisionRenderer rendererOptions={rendererOptions} markdown={markdown}></RevisionRenderer>
+        <RevisionRenderer rendererOptions={rendererOptions} markdown={markdown} isSlidesOverviewEnabled></RevisionRenderer>
       ) }
     </div>
   );

+ 30 - 32
packages/presentation/src/components/Slides.tsx

@@ -37,48 +37,35 @@ const marpSlide = new Marp({
   html: false,
   math: false,
 });
+// TODO: to change better slide style
+// https://redmine.weseek.co.jp/issues/125680
+const marpSlideTheme = marp.themeSet.add(`
+    /*!
+     * @theme slide_preview
+     */
+    section {
+      max-width: 90%;
+    }
+`);
+marp.themeSet.default = marpSlideTheme;
 
 
 type Props = {
   options: PresentationOptions,
   children?: string,
-  slideStyle?: 'true' | 'marp' | null,
+  hasMarpFlag?: boolean,
 }
 
 export const Slides = (props: Props): JSX.Element => {
-  const { options, children, slideStyle } = props;
+  const { options, children, hasMarpFlag } = props;
   const {
     rendererOptions, isDarkMode, disableSeparationByHeader,
   } = options;
 
-  rendererOptions.remarkPlugins?.push([
-    extractSections.remarkPlugin,
-    {
-      isDarkMode,
-      disableSeparationByHeader,
-    },
-  ]);
-
-
-  if (slideStyle === 'true') {
-    const { css } = marp.render('', { htmlAsArray: true });
-    return (
-      <>
-        <Head>
-          <style>{css}</style>
-        </Head>
-        <div className={`${MARP_CONTAINER_CLASS_NAME}`}>
-          <div className="slides">
-            <ReactMarkdown {...rendererOptions}>
-              { children ?? '## No Contents' }
-            </ReactMarkdown>
-          </div>
-        </div>
-      </>
-    );
-  }
 
-  if (slideStyle === 'marp') {
+  // TODO: can Marp rendering
+  // https://redmine.weseek.co.jp/issues/115673
+  if (hasMarpFlag) {
     const { html, css } = marpSlide.render(children ?? '');
     return (
       <>
@@ -96,6 +83,13 @@ export const Slides = (props: Props): JSX.Element => {
     );
   }
 
+  rendererOptions.remarkPlugins?.push([
+    extractSections.remarkPlugin,
+    {
+      isDarkMode,
+      disableSeparationByHeader,
+    },
+  ]);
 
   const { css } = marp.render('', { htmlAsArray: true });
   return (
@@ -103,9 +97,13 @@ export const Slides = (props: Props): JSX.Element => {
       <Head>
         <style>{css}</style>
       </Head>
-      <ReactMarkdown {...rendererOptions}>
-        { children ?? '## No Contents' }
-      </ReactMarkdown>
+      <div className={`${MARP_CONTAINER_CLASS_NAME}`}>
+        <div className="slides">
+          <ReactMarkdown {...rendererOptions}>
+            { children ?? '## No Contents' }
+          </ReactMarkdown>
+        </div>
+      </div>
     </>
   );
 };