diff --git a/plugs/editor/editor.plug.yaml b/plugs/editor/editor.plug.yaml index ed06dc30..fe76702b 100644 --- a/plugs/editor/editor.plug.yaml +++ b/plugs/editor/editor.plug.yaml @@ -178,19 +178,31 @@ functions: key: "Ctrl-Shift-u" mac: "Cmd-Shift-u" requireMode: rw - contexts: - - NakedURL # Title-based link unfurl titleUnfurlOptions: path: ./link.ts:titleUnfurlOptions events: - unfurl:options + titleUnfurl: path: ./link.ts:titleUnfurl events: - unfurl:title-unfurl + + # Title-based link unfurl + youtubeUnfurlOptions: + path: ./link.ts:youtubeUnfurlOptions + events: + - unfurl:options + + youtubeUnfurl: + path: ./link.ts:youtubeUnfurl + events: + - unfurl:youtube-unfurl + + embedWidget: path: ./embed.ts:embedWidget codeWidget: embed diff --git a/plugs/editor/embed.ts b/plugs/editor/embed.ts index 494c0581..f7090d8b 100644 --- a/plugs/editor/embed.ts +++ b/plugs/editor/embed.ts @@ -7,7 +7,7 @@ type EmbedConfig = { width?: number; }; -function extractYoutubeVideoId(url: string) { +export function extractYoutubeVideoId(url: string) { let match = url.match(/youtube\.com\/watch\?v=([^&]+)/); if (match) { return match[1]; diff --git a/plugs/editor/link.ts b/plugs/editor/link.ts index 2f18860a..27129b4e 100644 --- a/plugs/editor/link.ts +++ b/plugs/editor/link.ts @@ -1,5 +1,6 @@ import { nodeAtPos } from "$lib/tree.ts"; import { editor, events, markdown } from "$sb/syscalls.ts"; +import { extractYoutubeVideoId } from "./embed.ts"; type UnfurlOption = { id: string; @@ -8,7 +9,15 @@ type UnfurlOption = { export async function unfurlCommand() { const mdTree = await markdown.parseMarkdown(await editor.getText()); - const nakedUrlNode = nodeAtPos(mdTree, await editor.getCursor()); + const cursorPos = await editor.getCursor(); + let nakedUrlNode = nodeAtPos(mdTree, cursorPos); + if (nakedUrlNode?.type !== "NakedURL") { + nakedUrlNode = nodeAtPos(mdTree, cursorPos - 1); + } + if (nakedUrlNode?.type !== "NakedURL") { + await editor.flashNotification("No URL found under cursor", "error"); + return; + } const url = nakedUrlNode!.children![0].text!; console.log("Got URL to unfurl", url); const optionResponses = await events.dispatchEvent("unfurl:options", url); @@ -67,3 +76,20 @@ export async function titleUnfurl(url: string): Promise { throw new Error("No title found"); } } + +export function youtubeUnfurlOptions(url: string): UnfurlOption[] { + if (extractYoutubeVideoId(url)) { + return [ + { + id: "youtube-unfurl", + name: "Embed video", + }, + ]; + } else { + return []; + } +} + +export function youtubeUnfurl(url: string): string { + return "```embed\nurl: " + url + "\n```"; +} diff --git a/website/CHANGELOG.md b/website/CHANGELOG.md index 2a807877..53addde3 100644 --- a/website/CHANGELOG.md +++ b/website/CHANGELOG.md @@ -24,7 +24,8 @@ _These features are not yet properly released, you need to use [the edge builds] * [[Space Script]] is now indexed in templates too (so you can put space script in template tagged pages) * Changed the signature of `silverbullet.registerFunction` to make the first argument an object, see [[Space Script#Custom functions]]. Old string-based scripts still work, for backwards compatibility. * The [[Functions#replace(str, match, replacement)]] function now supports multiple replacements -* You can now use backticks (`) around identifiers in [[Expression Language]], to e.g. use names with spaces or other weird characters as attribute names. +* You can now use backticks (`) around identifiers in [[Expression Language]], to e.g. use names with spaces or other weird characters as attribute names. +* [[Link Unfurl]] now supports unfurling youtube videos * Fixed edit button on code widgets after they have shifted * Fixed page completion in template blocks * Giant code reorganization (hopefully resulting in 0 regressions) diff --git a/website/Link Unfurl.md b/website/Link Unfurl.md index 52ed9e57..260fe569 100644 --- a/website/Link Unfurl.md +++ b/website/Link Unfurl.md @@ -1,5 +1,7 @@ -SilverBullet has infrastructure to “unfurl” — that is: replace with something nice — various types of URLs. Unfurling can be triggered by putting your cursor on any “naked” URL, and running the {[Link: Unfurl]} command. +SilverBullet has infrastructure to “unfurl” — that is: to replace links with something nicer. Unfurling can be triggered by putting your cursor on any “naked” URL (such as https://silverbullet.md), and running the {[Link: Unfurl]} command. -Plugs can provide custom unfurls for specific URL patterns. For instance the [[Plugs/Twitter]] plug provides the ability to unfurl tweets, and pull in their content. +Plugs can provide custom unfurls for specific URL patterns. -[[Plugs/Editor]] provides a generic URL unfurl, adding a title for a url. \ No newline at end of file +Two supported out of the box are: +* A generic URL unfurl, adding a title for a url so `https://silverbullet.md` becomes `[SilverBullet](https://silverbullet.md)`. +* A youtube URL unfurl, replacing a Youtube link with an [[Live Embeds]] of that video.