Просмотр исходного кода

Merge branch 'imprv/115672-presentation-preview' into imprv/115672-125680-beautiful-slidestyle-in-preview

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

+ 5 - 1
apps/app/src/components/PagePresentationModal.tsx

@@ -8,6 +8,7 @@ import {
   Modal, ModalBody,
 } from 'reactstrap';
 
+import { useIsEnabledMarp } from '~/stores/context';
 import { usePagePresentationModal } from '~/stores/modal';
 import { useSWRxCurrentPage } from '~/stores/page';
 import { usePresentationViewOptions } from '~/stores/renderer';
@@ -35,6 +36,8 @@ const PagePresentationModal = (): JSX.Element => {
   const { data: currentPage } = useSWRxCurrentPage();
   const { data: rendererOptions } = usePresentationViewOptions();
 
+  const { data: isEnabledMarp } = useIsEnabledMarp();
+
   const toggleFullscreenHandler = useCallback(() => {
     if (fullscreen.active) {
       fullscreen.exit();
@@ -75,7 +78,7 @@ const PagePresentationModal = (): JSX.Element => {
         </button>
       </div>
       <ModalBody className="modal-body d-flex justify-content-center align-items-center">
-        { rendererOptions != null && (
+        { rendererOptions != null && isEnabledMarp != null && (
           <Presentation
             options={{
               rendererOptions: rendererOptions as ReactMarkdownOptions,
@@ -85,6 +88,7 @@ const PagePresentationModal = (): JSX.Element => {
               },
               isDarkMode,
             }}
+            isEnabledMarp = {isEnabledMarp}
           >
             {markdown}
           </Presentation>

+ 9 - 2
packages/presentation/src/components/Presentation.tsx

@@ -3,6 +3,7 @@ import React, { useEffect } from 'react';
 import Reveal from 'reveal.js';
 
 import type { PresentationOptions } from '../consts';
+import { parseSlideFrontmatterInMarkdown } from '../services/parse-slide-frontmatter';
 
 import { Slides } from './Slides';
 
@@ -33,13 +34,19 @@ const removeAllHiddenElements = () => {
 
 export type PresentationProps = {
   options: PresentationOptions,
+  isEnabledMarp: boolean,
   children?: string,
 }
 
 export const Presentation = (props: PresentationProps): JSX.Element => {
-  const { options, children } = props;
+  const { options, isEnabledMarp, children } = props;
   const { revealOptions } = options;
 
+  let marp = false;
+  if (isEnabledMarp) {
+    [marp] = parseSlideFrontmatterInMarkdown(children);
+  }
+
   useEffect(() => {
     let deck: Reveal.Api;
     if (children != null) {
@@ -59,7 +66,7 @@ export const Presentation = (props: PresentationProps): JSX.Element => {
 
   return (
     <div className={`grw-presentation ${styles['grw-presentation']} reveal`}>
-      <Slides options={options} presentation>{children}</Slides>
+      <Slides options={options} hasMarpFlag={marp}>{children}</Slides>
     </div>
   );
 };

+ 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];
+};

+ 4 - 19
packages/presentation/src/services/renderer/slides.ts

@@ -7,6 +7,8 @@ import type { Plugin } from 'unified';
 import type { Node } from 'unist';
 import { visit } from 'unist-util-visit';
 
+import { parseSlideFrontmatter } from '../parse-slide-frontmatter';
+
 const SUPPORTED_ATTRIBUTES = ['children', 'marp'];
 
 const nodeToMakrdown = (node: Node) => {
@@ -39,27 +41,10 @@ const removeCustomType = (tree: Node) => {
 };
 
 const rewriteNode = (tree: Node, node: Node, isEnabledMarp: boolean) => {
-  let slide = false;
-  let marp = false;
-
-  const lines = (node.value as string).split('\n');
-
-  lines.forEach((line) => {
-    const [key, value] = line.split(':').map(part => part.trim());
-
-    if (key === 'slide' && value === 'true') {
-      slide = true;
-    }
-    else if (key === 'marp' && value === 'true') {
-      marp = true;
-    }
-  });
 
-  if (isEnabledMarp === false) {
-    marp = false;
-  }
+  const [marp, slide] = parseSlideFrontmatter(node.value as string);
 
-  if (marp || slide) {
+  if ((marp && isEnabledMarp) || slide) {
 
     removeCustomType(tree);