Skip to content

Commit

Permalink
remark: generate youtube embed markup from obsidian youtube image links
Browse files Browse the repository at this point in the history
  • Loading branch information
ooloth committed Dec 23, 2024
1 parent caf69e4 commit 8f0a42c
Show file tree
Hide file tree
Showing 2 changed files with 42 additions and 0 deletions.
2 changes: 2 additions & 0 deletions lib/remark/plugins.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ import remarkWikiLink from '@portaljs/remark-wiki-link'

import remarkLastModified from './last-modified'
import remarkRemoveTags from './remove-tags'
import remarkYouTubeEmbedFromImageLink from './youtube-embed-from-image-link'

export default [
remarkLastModified,
Expand All @@ -17,4 +18,5 @@ export default [
wikiLinkResolver: (slug: string): string[] => [`${slug}/`], // expects all pages to have root-level paths
},
],
remarkYouTubeEmbedFromImageLink,
]
40 changes: 40 additions & 0 deletions lib/remark/youtube-embed-from-image-link.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
// Obsidian uses ![](<video link>) for embedding videos responsively, so I need to convert those to YouTube embeds.
// see: https://www.ryanfiller.com/blog/remark-and-rehype-plugins
// see: https://github.com/syntax-tree/mdast

import type { RemarkPlugin } from '@astrojs/markdown-remark'
import type { Data, Image } from 'mdast'
import { visit } from 'unist-util-visit'
import type { Node } from 'unist'

/**
* Convert markdown image link containing a YouTube video link to a YouTube iFrame embed.
*/
const convertImageLinkToIframe = (url: string): string => {
const videoId = url.split('v=')[1]
const embedUrl = `https://www.youtube.com/embed/${videoId}`
return `<iframe width="560" height="315" src="${embedUrl}" title="YouTube video player" frameborder="0" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share" referrerpolicy="strict-origin-when-cross-origin" allowfullscreen></iframe>`
}

type Transformer = (tree: Node<Data>) => Promise<void>

/**
* Convert markdown image links containing Youtube video links to YouTube embeds.
*/
const remarkYouTubeEmbedFromImageLink: RemarkPlugin =
(): Transformer =>
async (tree: Node<Data>): Promise<void> => {
// Identify the type of node I want to modify ("text" in this case) here: https://astexplorer.net
visit(tree, 'image', (node: Image) => {
if (!node.url.includes('youtube.com')) return

// Use Object.assign to replace the exact same object instead of triggering an infinite loop by creating new objects
Object.assign(node, {
type: 'html',
value: convertImageLinkToIframe(node.url),
position: node.position,
})
})
}

export default remarkYouTubeEmbedFromImageLink

0 comments on commit 8f0a42c

Please sign in to comment.