diff --git a/plugs/markdown/markdown_render.ts b/plugs/markdown/markdown_render.ts index 3340209f..6626e400 100644 --- a/plugs/markdown/markdown_render.ts +++ b/plugs/markdown/markdown_render.ts @@ -16,7 +16,7 @@ export type MarkdownRenderOptions = { attachmentUrlPrefix?: string; preserveAttributes?: true; // When defined, use to inline images as data: urls - translateUrls?: (url: string) => string; + translateUrls?: (url: string, type: "link" | "image") => string; }; function cleanTags(values: (Tag | null)[], cleanWhitespace = false): Tag[] { @@ -466,11 +466,11 @@ export function renderMarkdownToHtml( return; } if (t.name === "img") { - t.attrs!.src = options.translateUrls!(t.attrs!.src!); + t.attrs!.src = options.translateUrls!(t.attrs!.src!, "image"); } if (t.name === "a" && t.attrs!.href) { - t.attrs!.href = options.translateUrls!(t.attrs!.href); + t.attrs!.href = options.translateUrls!(t.attrs!.href, "link"); } }); } diff --git a/plugs/markdown/preview.ts b/plugs/markdown/preview.ts index fe54cae9..10207509 100644 --- a/plugs/markdown/preview.ts +++ b/plugs/markdown/preview.ts @@ -2,6 +2,7 @@ import { asset, clientStore, editor, markdown, system } from "$sb/syscalls.ts"; import { renderMarkdownToHtml } from "./markdown_render.ts"; import { resolvePath } from "$sb/lib/resolve.ts"; import { expandCodeWidgets } from "./api.ts"; +import { folderName, resolve } from "../../common/path.ts"; export async function updateMarkdownPreview() { if (!(await clientStore.get("enableMarkdownPreview"))) { @@ -18,9 +19,14 @@ export async function updateMarkdownPreview() { const html = renderMarkdownToHtml(mdTree, { smartHardBreak: true, annotationPositions: true, - translateUrls: (url) => { + translateUrls: (url, type) => { if (!url.includes("://")) { - url = resolvePath(currentPage, decodeURI(url), true); + if (type === "image" && !url.startsWith("/")) { + // Make relative to current folder + url = resolve(folderName(currentPage), decodeURI(url)); + } else if (type === "link") { // link + url = resolvePath(currentPage, decodeURI(url), true); + } } return url; }, diff --git a/web/cm_plugins/inline_image.ts b/web/cm_plugins/inline_image.ts index 33abe0fe..d87791e5 100644 --- a/web/cm_plugins/inline_image.ts +++ b/web/cm_plugins/inline_image.ts @@ -9,6 +9,7 @@ import { decoratorStateField } from "./util.ts"; import type { Client } from "../client.ts"; import { resolvePath } from "$sb/lib/resolve.ts"; +import { folderName, resolve } from "../../common/path.ts"; class InlineImageWidget extends WidgetType { constructor( @@ -34,7 +35,6 @@ class InlineImageWidget extends WidgetType { const img = document.createElement("img"); let url = this.url; url = resolvePath(this.client.currentPage!, url, true); - console.log("Resolving image to", url); // console.log("Creating DOM", this.url); const cachedImageHeight = this.client.space.getCachedImageHeight(url); img.onload = () => { @@ -76,8 +76,12 @@ export function inlineImagesPlugin(client: Client) { let url = imageRexexResult.groups.url; const title = imageRexexResult.groups.title; - if (url.indexOf("://") === -1) { - url = decodeURI(url); + + const currentPage = client.currentPage!; + const currentFolder = folderName(currentPage); + + if (url.indexOf("://") === -1 && !url.startsWith("/")) { + url = resolve(currentFolder, decodeURI(url)); } widgets.push( Decoration.widget({ diff --git a/web/cm_plugins/table.ts b/web/cm_plugins/table.ts index b85c047a..492049ec 100644 --- a/web/cm_plugins/table.ts +++ b/web/cm_plugins/table.ts @@ -10,6 +10,7 @@ import { ParseTree } from "$sb/lib/tree.ts"; import { lezerToParseTree } from "../../common/markdown_parser/parse_tree.ts"; import type { Client } from "../client.ts"; import { resolvePath } from "$sb/lib/resolve.ts"; +import { folderName, resolve } from "../../common/path.ts"; class TableViewWidget extends WidgetType { constructor( @@ -38,10 +39,16 @@ class TableViewWidget extends WidgetType { // Annotate every element with its position so we can use it to put // the cursor there when the user clicks on the table. annotationPositions: true, - translateUrls: (url) => { + translateUrls: (url, type) => { if (!url.includes("://")) { - url = resolvePath(this.editor.currentPage!, decodeURI(url), true); + if (type === "image" && !url.startsWith("/")) { + // Make relative to current folder + url = resolve(folderName(this.editor.currentPage!), decodeURI(url)); + } else if (type === "link") { // link + url = resolvePath(this.editor.currentPage!, decodeURI(url), true); + } } + return url; }, preserveAttributes: true, diff --git a/web/reducer.ts b/web/reducer.ts index 4fbb2fe2..7efee626 100644 --- a/web/reducer.ts +++ b/web/reducer.ts @@ -11,6 +11,12 @@ export default function reducer( ...state, isLoading: true, currentPage: action.name, + panels: { + ...state.panels, + // Hide these by default to avoid flickering + top: {}, + bottom: {}, + }, }; case "page-loaded": return { diff --git a/website/Tags.md b/website/Tags.md index 74660245..3866be98 100644 --- a/website/Tags.md +++ b/website/Tags.md @@ -1,4 +1,4 @@ Tags in SilverBullet are used to encode types of [[Objects]]. -See [[Objects@tags]] for more information. +See [[Objects$tags]] for more information.