|
|
@@ -4,18 +4,17 @@ import type { Parent, Root } from 'mdast';
|
|
|
import type { Processor } from 'unified';
|
|
|
|
|
|
type ParseResult = {
|
|
|
- marp: boolean | undefined,
|
|
|
- slide: boolean | undefined,
|
|
|
-}
|
|
|
+ marp: boolean | undefined;
|
|
|
+ slide: boolean | undefined;
|
|
|
+};
|
|
|
|
|
|
const parseSlideFrontmatter = (frontmatter: string): ParseResult => {
|
|
|
-
|
|
|
let marp;
|
|
|
let slide;
|
|
|
|
|
|
const lines = frontmatter.split('\n');
|
|
|
lines.forEach((line) => {
|
|
|
- const [key, value] = line.split(':').map(part => part.trim());
|
|
|
+ const [key, value] = line.split(':').map((part) => part.trim());
|
|
|
if (key === 'marp' && value === 'true') {
|
|
|
marp = true;
|
|
|
}
|
|
|
@@ -27,56 +26,58 @@ const parseSlideFrontmatter = (frontmatter: string): ParseResult => {
|
|
|
return { marp, slide };
|
|
|
};
|
|
|
|
|
|
-
|
|
|
type ProcessorOpts = {
|
|
|
- onParsed?: (result: ParseResult) => void,
|
|
|
- onSkipped?: () => void,
|
|
|
+ onParsed?: (result: ParseResult) => void;
|
|
|
+ onSkipped?: () => void;
|
|
|
};
|
|
|
|
|
|
-const generateFrontmatterProcessor = async(opts?: ProcessorOpts) => {
|
|
|
-
|
|
|
+const generateFrontmatterProcessor = async (opts?: ProcessorOpts) => {
|
|
|
const remarkFrontmatter = (await import('remark-frontmatter')).default;
|
|
|
const remarkParse = (await import('remark-parse')).default;
|
|
|
const remarkStringify = (await import('remark-stringify')).default;
|
|
|
const unified = (await import('unified')).unified;
|
|
|
|
|
|
- return (unified()
|
|
|
+ return unified()
|
|
|
.use(remarkParse)
|
|
|
.use(remarkStringify)
|
|
|
.use(remarkFrontmatter, ['yaml'])
|
|
|
- .use(() => ((obj: Parent) => {
|
|
|
+ .use(() => (obj: Parent) => {
|
|
|
if (obj.children[0]?.type === 'yaml') {
|
|
|
const result = parseSlideFrontmatter(obj.children[0]?.value);
|
|
|
opts?.onParsed?.(result);
|
|
|
- }
|
|
|
- else {
|
|
|
+ } else {
|
|
|
opts?.onSkipped?.();
|
|
|
}
|
|
|
- })));
|
|
|
+ });
|
|
|
};
|
|
|
|
|
|
export type UseSlide = {
|
|
|
- marp?: boolean,
|
|
|
-}
|
|
|
+ marp?: boolean;
|
|
|
+};
|
|
|
|
|
|
/**
|
|
|
* Frontmatter parser for slide
|
|
|
* @param markdown Markdwon document
|
|
|
* @returns An UseSlide instance. If the markdown does not contain neither "marp" or "slide" attribute in frontmatter, it returns undefined.
|
|
|
*/
|
|
|
-export const useSlidesByFrontmatter = (markdown?: string, isEnabledMarp?: boolean): UseSlide | undefined => {
|
|
|
-
|
|
|
- const [processor, setProcessor] = useState<Processor<Root, undefined, undefined, Root, string>|undefined>();
|
|
|
- const [parseResult, setParseResult] = useState<UseSlide|undefined>();
|
|
|
+export const useSlidesByFrontmatter = (
|
|
|
+ markdown?: string,
|
|
|
+ isEnabledMarp?: boolean,
|
|
|
+): UseSlide | undefined => {
|
|
|
+ const [processor, setProcessor] = useState<
|
|
|
+ Processor<Root, undefined, undefined, Root, string> | undefined
|
|
|
+ >();
|
|
|
+ const [parseResult, setParseResult] = useState<UseSlide | undefined>();
|
|
|
|
|
|
useEffect(() => {
|
|
|
if (processor != null) {
|
|
|
return;
|
|
|
}
|
|
|
|
|
|
- (async() => {
|
|
|
+ (async () => {
|
|
|
const p = await generateFrontmatterProcessor({
|
|
|
- onParsed: result => setParseResult(result.marp || result.slide ? result : undefined),
|
|
|
+ onParsed: (result) =>
|
|
|
+ setParseResult(result.marp || result.slide ? result : undefined),
|
|
|
onSkipped: () => setParseResult(undefined),
|
|
|
});
|
|
|
setProcessor(p);
|
|
|
@@ -94,5 +95,4 @@ export const useSlidesByFrontmatter = (markdown?: string, isEnabledMarp?: boolea
|
|
|
return parseResult != null
|
|
|
? { marp: isEnabledMarp && parseResult?.marp }
|
|
|
: undefined;
|
|
|
-
|
|
|
};
|