diff --git a/content/roam-test.md b/content/roam-test.md
deleted file mode 100644
index ddc9a03b8..000000000
--- a/content/roam-test.md
+++ /dev/null
@@ -1,43 +0,0 @@
-### OR
-
-{{or:ONE|TWO|THREE}}
-
-### Tasks
-
-- {{[[TODO]]}} unchecked
-- {{TODO}} unchecked
-- {{[[DONE]]}} checked
-- {{DONE}} checked
-
-### Text Styling
-
-- **Bold**
-- __Italics__
-- Highlights ^^of some^^ words
-- this one, ~~not this one~~
-- Blockquotes
- - [[>]] Regulare quote using page brackets
- - > bare quote without brackets
-
-### Uploaded Files
-
-- image
- - 
-- video
- - {{[[video]]: https://firebasestorage.googleapis.com/v0/b/firescript-577a2.appspot.com/o/imgs%2Fapp%2FMattVogel%2FBY1tSter6R.mp4?alt=media&token=07031095-4736-4b0b-899a-26852adbf245}}
- - youtube
- - {{[[video]]: https://www.youtube.com/watch?v=y1f6bfiSH94}}
-- gif
- - 
-- pdf
- - {{[[pdf]]: https://firebasestorage.googleapis.com/v0/b/firescript-577a2.appspot.com/o/imgs%2Fapp%2FMattVogel%2F6FtyOTB3mx.pdf?alt=media&token=0736266f-54d2-46dc-99a8-08f7e7874210}}
-- audio
- - This is being selected
- - {{[[audio]]: this_works_and_is_selected}}
- - This is not for some reason
- - {{[[audio]]: https://firebasestorage.googleapis.com/v0/b/firescript-577a2.appspot.com/o/imgs%2Fapp%2FMattVogel%2FZ37C1oBWmW.mp3?alt=media&token=433c0926-dbea-47f5-ab4f-3ec4659ba815}}
-- binary files
- - regular file
- - https://firebasestorage.googleapis.com/v0/b/firescript-577a2.appspot.com/o/imgs%2Fapp%2FMattVogel%2FkQXZxVL_6G.txt?alt=media&token=f35c8688-0ff4-4d59-845a-3bcaa53fc1ea
- - .zip file
- - https://firebasestorage.googleapis.com/v0/b/firescript-577a2.appspot.com/o/imgs%2Fapp%2FMattVogel%2FEzyEq4p2Zn.zip?alt=media&token=0697c12e-654d-46a6-943e-fe13293870ba
diff --git a/quartz/plugins/transformers/roam.ts b/quartz/plugins/transformers/roam.ts
index e2f2a8967..b3be8f542 100644
--- a/quartz/plugins/transformers/roam.ts
+++ b/quartz/plugins/transformers/roam.ts
@@ -1,9 +1,11 @@
import { QuartzTransformerPlugin } from "../types"
import { PluggableList } from "unified"
import { SKIP, visit } from "unist-util-visit"
-import { Root, Html, BlockContent, DefinitionContent, Paragraph, Code } from "mdast"
-import { FilePath, pathToRoot, slugTag, slugifyFilePath } from "../../util/path"
import { ReplaceFunction, findAndReplace as mdastFindReplace } from "mdast-util-find-and-replace"
+import { Root, Html, Paragraph, Text, Link, Parent } from "mdast"
+import { Node } from "unist"
+import { VFile } from "vfile"
+import { BuildVisitor } from "unist-util-visit"
export interface Options {
orComponent: boolean
@@ -32,20 +34,96 @@ const defaultOptions: Options = {
const orRegex = new RegExp(/{{or:(.*?)}}/, "g")
const TODORegex = new RegExp(/{{.*?\bTODO\b.*?}}/, "g")
const DONERegex = new RegExp(/{{.*?\bDONE\b.*?}}/, "g")
-const videoRegex = new RegExp(/{{.*?\bvideo\b.*?\:(.*?)}}/, "g")
-const youtubeRegex = new RegExp(/{{.*?\bvideo\b.*?(\bhttp.*?\byoutu.*?)watch\?v=(.*?)}}/, "g")
+const videoRegex = new RegExp(/{{.*?\[\[video\]\].*?\:(.*?)}}/, "g")
+const youtubeRegex = new RegExp(
+ /{{.*?\[\[video\]\].*?(https?:\/\/(?:www\.)?youtu(?:be\.com\/watch\?v=|\.be\/)([\w\-\_]*)(&(amp;)?[\w\?=]*)?)}}/,
+ "g",
+)
// const multimediaRegex = new RegExp(/{{.*?\b(video|audio)\b.*?\:(.*?)}}/, "g")
-
-const audioRegex = new RegExp(/{{.*?\baudio\b.*?\:(.*?)}}/, "g")
-const pdfRegex = new RegExp(/{{.*?\bpdf\b.*?\:(.*?)}}/, "g")
-const blockquoteRegex = new RegExp(/(\[\[>\]\])\s*(.*)/, "g");
+const audioRegex = new RegExp(/{{.*?\[\[audio\]\].*?\:(.*?)}}/, "g")
+const pdfRegex = new RegExp(/{{.*?\[\[pdf\]\].*?\:(.*?)}}/, "g")
+const blockquoteRegex = new RegExp(/(\[\[>\]\])\s*(.*)/, "g")
const roamHighlightRegex = new RegExp(/\^\^(.+)\^\^/, "g")
const roamItalicRegex = new RegExp(/__(.+)__/, "g")
const tableRegex = new RegExp(/- {{.*?\btable\b.*?}}/, "g") /* TODO */
const attributeRegex = new RegExp(/\b\w+(?:\s+\w+)*::/, "g") /* TODO */
+function isSpecialEmbed(node: Paragraph): boolean {
+ if (node.children.length !== 2) return false
+
+ const [textNode, linkNode] = node.children
+ return (
+ textNode.type === "text" &&
+ textNode.value.startsWith("{{[[") &&
+ linkNode.type === "link" &&
+ linkNode.children[0].type === "text" &&
+ linkNode.children[0].value.endsWith("}}")
+ )
+}
+
+function transformSpecialEmbed(node: Paragraph, opts: Options): Html | null {
+ const [textNode, linkNode] = node.children as [Text, Link]
+ const embedType = textNode.value.match(/\{\{\[\[(.*?)\]\]:/)?.[1]?.toLowerCase()
+ const url = linkNode.url.slice(0, -2) // Remove the trailing '}}'
+
+ switch (embedType) {
+ case "audio":
+ return opts.audioComponent
+ ? {
+ type: "html",
+ value: ``,
+ }
+ : null
+ case "video":
+ if (!opts.videoComponent) return null
+ // Check if it's a YouTube video
+ const youtubeMatch = url.match(
+ /(?:https?:\/\/)?(?:www\.)?(?:youtube\.com|youtu\.be)\/(?:watch\?v=)?(.+)/,
+ )
+ if (youtubeMatch) {
+ const videoId = youtubeMatch[1].split("&")[0] // Remove additional parameters
+ const playlistMatch = url.match(/[?&]list=([^#\&\?]*)/)
+ const playlistId = playlistMatch ? playlistMatch[1] : null
+
+ return {
+ type: "html",
+ value: ``,
+ }
+ } else {
+ return {
+ type: "html",
+ value: ``,
+ }
+ }
+ case "pdf":
+ return opts.pdfComponent
+ ? {
+ type: "html",
+ value: ``,
+ }
+ : null
+ default:
+ return null
+ }
+}
+
export const RoamFlavoredMarkdown: QuartzTransformerPlugin | undefined> = (
userOpts,
) => {
@@ -53,167 +131,93 @@ export const RoamFlavoredMarkdown: QuartzTransformerPlugin | un
return {
name: "RoamFlavoredMarkdown",
- textTransform(_ctx, src) {
- // if (opts.videoComponent) {
- // //youtube first then regular video links
- // src = src.toString()
- // src = src.replaceAll(youtubeRegex, (value, ...capture) => {
- // const [match, text] = capture
- // const video = ``
- // return video
- // })
- // src = src.replaceAll(videoRegex, (value, ...capture) => {
- // const [match, text] = capture
- // const video = ``
- // return video
- // })
- // }
- // if (opts.audioComponent) {
- // src = src.toString()
- // src = src.replaceAll(audioRegex, (value, ...capture) => {
- // const [match, text] = capture
- // const audio = ``
- // return audio
- // })
- // }
- // if (opts.pdfComponent) {
- // src = src.toString()
- // src = src.replaceAll(pdfRegex, (value, ...capture) => {
- // const [match, text] = capture
- // const pdf = `