UNPKG

lexical-remark

Version:

This package contains Markdown helpers and functionality for Lexical using remark-parse.

79 lines (78 loc) 2.46 kB
import { visit } from 'unist-util-visit'; /** * A regular expression to detect a YouTube url and parse out the video id as the sixth capture group * * @example * function getVideoId(value: string) { * const match = value.match(YOUTUBE_URL_REGEX); * return !!match ? match[6] : null; * } */ export const YOUTUBE_URL_REGEX = /^((?:https?:)?\/\/)?((?:www|m)\.)?((?:youtube(-nocookie)?\.com|youtu.be))(\/(?:watch\?v=|embed\/|shorts\/|v\/)?)([\w\-]+)(\S+)?$/; /** * A remark plugin to enrich an mdast node tree by converting paragraph nodes containing only a YouTube url into YouTube nodes */ export const remarkYoutube = () => { return convertYoutubeParagraphs; }; function convertYoutubeParagraphs(tree) { const videoId = isYoutubeParagraphNode(tree); if (videoId) { tree.children = [ { type: 'youtube', videoId, }, ]; } visit(tree, function (node) { const visitedVideoId = isYoutubeParagraphNode(node); if (visitedVideoId) { node.children = [ { type: 'youtube', videoId: visitedVideoId, }, ]; } }); } function isYoutubeParagraphNode(node) { if (node.type === 'paragraph' && node.children.length === 1 && node.children[0].type === 'text') { const match = node.children[0].value.match(YOUTUBE_URL_REGEX); return !!match && match[6]; } return false; } /** * A remark plugin to simplify an mdast node tree by converting YouTube nodes back to paragraph nodes */ export function youtubeRemark() { return convertToYoutubeParagraphs; } function convertToYoutubeParagraphs(tree) { if (tree.type === 'youtube') { tree.type = 'paragraph'; tree.children = [ { type: 'text', value: `https://www.youtube.com/watch?v=${tree.videoId}`, }, ]; // @ts-expect-error casting to Youtube delete tree.videoId; } visit(tree, function (node) { if (node.type === 'youtube') { node.type = 'paragraph'; node.children = [ { type: 'text', value: `https://www.youtube.com/watch?v=${node.videoId}`, }, ]; // @ts-expect-error casting to Youtube delete node.videoId; } }); }